1 |
/************************************************************************** |
/***************************************************************************** |
2 |
* |
* |
3 |
* XVID MPEG-4 VIDEO CODEC |
* XVID MPEG-4 VIDEO CODEC |
4 |
* GMC interpolation module |
* - GMC interpolation module - |
5 |
|
* |
6 |
|
* Copyright(C) 2002-2003 Pascal Massimino <skal@planet-d.net> |
7 |
* |
* |
8 |
* This program is free software; you can redistribute it and/or modify |
* This program is free software; you can redistribute it and/or modify |
9 |
* it under the terms of the GNU General Public License as published by |
* it under the terms of the GNU General Public License as published by |
17 |
* |
* |
18 |
* You should have received a copy of the GNU General Public License |
* You should have received a copy of the GNU General Public License |
19 |
* along with this program; if not, write to the Free Software |
* along with this program; if not, write to the Free Software |
20 |
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
21 |
|
* |
22 |
|
* $Id: gmc.c,v 1.1.2.4 2003-09-10 22:18:59 edgomez Exp $ |
23 |
* |
* |
24 |
*************************************************************************/ |
****************************************************************************/ |
25 |
|
|
26 |
#include "../portab.h" |
#include "../portab.h" |
27 |
#include "../global.h" |
#include "../global.h" |
28 |
#include "../encoder.h" |
#include "../encoder.h" |
29 |
#include "gmc.h" |
#include "gmc.h" |
|
#include "motion_est.h" |
|
30 |
|
|
31 |
#include <stdio.h> |
#include <stdio.h> |
32 |
|
|
39 |
// of pixel 0,0), not the macroblock one. |
// of pixel 0,0), not the macroblock one. |
40 |
// Conversely, *dst is the macroblock top-left adress. |
// Conversely, *dst is the macroblock top-left adress. |
41 |
|
|
|
|
|
42 |
void Predict_16x16_C(const NEW_GMC_DATA * const This, |
void Predict_16x16_C(const NEW_GMC_DATA * const This, |
43 |
uint8_t *dst, const uint8_t *src, |
uint8_t *dst, const uint8_t *src, |
44 |
int dststride, int srcstride, int x, int y, int rounding) |
int dststride, int srcstride, int x, int y, int rounding) |
59 |
int i, j; |
int i, j; |
60 |
|
|
61 |
dst += 16; |
dst += 16; |
62 |
for (j=16; j>0; --j) |
for (j=16; j>0; --j) { |
|
{ |
|
63 |
int U = Uo, V = Vo; |
int U = Uo, V = Vo; |
64 |
Uo += dUy; Vo += dVy; |
Uo += dUy; Vo += dVy; |
65 |
for (i=-16; i<0; ++i) |
for (i=-16; i<0; ++i) { |
66 |
{ |
unsigned int f0, f1, ri = 16, rj = 16; |
|
unsigned int f0, f1, ri, rj; |
|
67 |
int Offset; |
int Offset; |
|
|
|
68 |
int u = ( U >> 16 ) << rho; |
int u = ( U >> 16 ) << rho; |
69 |
int v = ( V >> 16 ) << rho; |
int v = ( V >> 16 ) << rho; |
70 |
|
|
71 |
U += dUx; V += dVx; |
U += dUx; V += dVx; |
72 |
|
|
73 |
ri = 16; |
if (u > 0 && u <= W) { ri = MTab[u&15]; Offset = u>>4; } |
|
if ((uint32_t)u<=(uint32_t)W) { ri = MTab[u&15]; Offset = u>>4; } |
|
74 |
else if (u>W) Offset = W>>4; |
else if (u>W) Offset = W>>4; |
75 |
else Offset = -1; |
else Offset = -1; |
76 |
|
|
77 |
rj = 16; |
if (v > 0 && v <= H) { rj = MTab[v&15]; Offset += (v>>4)*srcstride; } |
|
if ((uint32_t)v<=(uint32_t)H) { rj = MTab[v&15]; Offset += (v>>4)*srcstride; } |
|
78 |
else if (v>H) Offset += (H>>4)*srcstride; |
else if (v>H) Offset += (H>>4)*srcstride; |
79 |
else Offset -= srcstride; |
else Offset -= srcstride; |
80 |
|
|
93 |
} |
} |
94 |
} |
} |
95 |
|
|
|
|
|
96 |
void Predict_8x8_C(const NEW_GMC_DATA * const This, |
void Predict_8x8_C(const NEW_GMC_DATA * const This, |
97 |
uint8_t *uDst, const uint8_t *uSrc, |
uint8_t *uDst, const uint8_t *uSrc, |
98 |
uint8_t *vDst, const uint8_t *vSrc, |
uint8_t *vDst, const uint8_t *vSrc, |
115 |
|
|
116 |
uDst += 8; |
uDst += 8; |
117 |
vDst += 8; |
vDst += 8; |
118 |
for (j=8; j>0; --j) |
for (j=8; j>0; --j) { |
|
{ |
|
119 |
int32_t U = Uo, V = Vo; |
int32_t U = Uo, V = Vo; |
120 |
Uo += dUy; Vo += dVy; |
Uo += dUy; Vo += dVy; |
121 |
|
|
122 |
for (i=-8; i<0; ++i) |
for (i=-8; i<0; ++i) { |
|
{ |
|
123 |
int Offset; |
int Offset; |
124 |
uint32_t f0, f1, ri, rj; |
uint32_t f0, f1, ri, rj; |
125 |
int32_t u, v; |
int32_t u, v; |
128 |
v = ( V >> 16 ) << rho; |
v = ( V >> 16 ) << rho; |
129 |
U += dUx; V += dVx; |
U += dUx; V += dVx; |
130 |
|
|
131 |
if ((uint32_t)u<=(uint32_t)W) { |
if (u > 0 && u <= W) { |
132 |
ri = MTab[u&15]; |
ri = MTab[u&15]; |
133 |
Offset = u>>4; |
Offset = u>>4; |
134 |
} |
} else { |
|
else { |
|
135 |
ri = 16; |
ri = 16; |
136 |
if (u>W) Offset = W>>4; |
if (u>W) Offset = W>>4; |
137 |
else Offset = -1; |
else Offset = -1; |
138 |
} |
} |
139 |
if ((uint32_t)v<=(uint32_t)H) { |
|
140 |
|
if (v > 0 && v <= H) { |
141 |
rj = MTab[v&15]; |
rj = MTab[v&15]; |
142 |
Offset += (v>>4)*srcstride; |
Offset += (v>>4)*srcstride; |
143 |
} |
} else { |
|
else { |
|
144 |
rj = 16; |
rj = 16; |
145 |
if (v>H) Offset += (H>>4)*srcstride; |
if (v>H) Offset += (H>>4)*srcstride; |
146 |
else Offset -= srcstride; |
else Offset -= srcstride; |
173 |
} |
} |
174 |
} |
} |
175 |
|
|
176 |
|
void get_average_mv_C(const NEW_GMC_DATA * const Dsp, VECTOR * const mv, |
|
void get_average_mv_C(NEW_GMC_DATA *Dsp, VECTOR * const mv, |
|
177 |
int x, int y, int qpel) |
int x, int y, int qpel) |
178 |
{ |
{ |
179 |
int i, j; |
int i, j; |
202 |
////////////////////////////////////////////////////////// |
////////////////////////////////////////////////////////// |
203 |
// simplified version for 1 warp point |
// simplified version for 1 warp point |
204 |
|
|
|
|
|
205 |
void Predict_1pt_16x16_C(const NEW_GMC_DATA * const This, |
void Predict_1pt_16x16_C(const NEW_GMC_DATA * const This, |
206 |
uint8_t *Dst, const uint8_t *Src, |
uint8_t *Dst, const uint8_t *Src, |
207 |
int dststride, int srcstride, int x, int y, int rounding) |
int dststride, int srcstride, int x, int y, int rounding) |
247 |
} |
} |
248 |
} |
} |
249 |
|
|
|
|
|
250 |
void Predict_1pt_8x8_C(const NEW_GMC_DATA * const This, |
void Predict_1pt_8x8_C(const NEW_GMC_DATA * const This, |
251 |
uint8_t *uDst, const uint8_t *uSrc, |
uint8_t *uDst, const uint8_t *uSrc, |
252 |
uint8_t *vDst, const uint8_t *vSrc, |
uint8_t *vDst, const uint8_t *vSrc, |
303 |
} |
} |
304 |
} |
} |
305 |
|
|
306 |
|
void get_average_mv_1pt_C(const NEW_GMC_DATA * const Dsp, VECTOR * const mv, |
|
void get_average_mv_1pt_C(NEW_GMC_DATA *Dsp, VECTOR * const mv, |
|
307 |
int x, int y, int qpel) |
int x, int y, int qpel) |
308 |
{ |
{ |
309 |
mv->x = RSHIFT(Dsp->Uo<<qpel, 3); |
mv->x = RSHIFT(Dsp->Uo<<qpel, 3); |
409 |
|
|
410 |
////////////////////////////////////////////////////////// |
////////////////////////////////////////////////////////// |
411 |
|
|
|
|
|
412 |
/* quick and dirty routine to generate the full warped image (pGMC != NULL) |
/* quick and dirty routine to generate the full warped image (pGMC != NULL) |
413 |
or just all average Motion Vectors (pGMC == NULL) */ |
or just all average Motion Vectors (pGMC == NULL) */ |
414 |
|
|