58 |
int xb, yb; |
int xb, yb; |
59 |
if (qpel) { x *= 2; y *= 2;} |
if (qpel) { x *= 2; y *= 2;} |
60 |
else if (rrv) { x = RRV_MV_SCALEDOWN(x); y = RRV_MV_SCALEDOWN(y); } |
else if (rrv) { x = RRV_MV_SCALEDOWN(x); y = RRV_MV_SCALEDOWN(y); } |
61 |
x = pred.x - x; |
x -= pred.x; |
62 |
y = pred.y - y; |
y -= pred.y; |
63 |
|
|
64 |
if (x == 0) xb = 1; |
if (x) { |
|
else { |
|
65 |
if (x < 0) x = -x; |
if (x < 0) x = -x; |
66 |
x += (1 << (iFcode - 1)) - 1; |
x += (1 << (iFcode - 1)) - 1; |
67 |
x >>= (iFcode - 1); |
x >>= (iFcode - 1); |
68 |
if (x > 32) x = 32; |
if (x > 32) x = 32; |
69 |
xb = mvtab[x] + iFcode; |
xb = mvtab[x] + iFcode; |
70 |
} |
} else xb = 1; |
71 |
|
|
72 |
if (y == 0) yb = 1; |
if (y) { |
|
else { |
|
73 |
if (y < 0) y = -y; |
if (y < 0) y = -y; |
74 |
y += (1 << (iFcode - 1)) - 1; |
y += (1 << (iFcode - 1)) - 1; |
75 |
y >>= (iFcode - 1); |
y >>= (iFcode - 1); |
76 |
if (y > 32) y = 32; |
if (y > 32) y = 32; |
77 |
yb = mvtab[y] + iFcode; |
yb = mvtab[y] + iFcode; |
78 |
} |
} else yb = 1; |
79 |
return xb + yb; |
return xb + yb; |
80 |
} |
} |
81 |
|
|
83 |
ChromaSAD(int dx, int dy, const SearchData * const data) |
ChromaSAD(int dx, int dy, const SearchData * const data) |
84 |
{ |
{ |
85 |
int sad; |
int sad; |
86 |
dx = (dx >> 1) + roundtab_79[dx & 0x3]; |
const uint32_t stride = data->iEdgedWidth/2; |
|
dy = (dy >> 1) + roundtab_79[dy & 0x3]; |
|
87 |
|
|
88 |
if (dx == data->temp[5] && dy == data->temp[6]) return data->temp[7]; //it has been checked recently |
if (dx == data->temp[5] && dy == data->temp[6]) return data->temp[7]; //it has been checked recently |
89 |
|
data->temp[5] = dx; data->temp[6] = dy; // backup |
90 |
|
|
91 |
switch (((dx & 1) << 1) | (dy & 1)) { |
switch (((dx & 1) << 1) | (dy & 1)) { |
92 |
case 0: |
case 0: |
93 |
sad = sad8(data->CurU, data->RefCU + (dy/2) * (data->iEdgedWidth/2) + dx/2, data->iEdgedWidth/2); |
dx = dx / 2; dy = dy / 2; |
94 |
sad += sad8(data->CurV, data->RefCV + (dy/2) * (data->iEdgedWidth/2) + dx/2, data->iEdgedWidth/2); |
sad = sad8(data->CurU, data->RefCU + dy * stride + dx, stride); |
95 |
|
sad += sad8(data->CurV, data->RefCV + dy * stride + dx, stride); |
96 |
break; |
break; |
97 |
case 1: |
case 1: |
98 |
dx = dx / 2; dy = (dy - 1) / 2; |
dx = dx / 2; dy = (dy - 1) / 2; |
99 |
sad = sad8bi(data->CurU, data->RefCU + dy * (data->iEdgedWidth/2) + dx, data->RefCU + (dy+1) * (data->iEdgedWidth/2) + dx, data->iEdgedWidth/2); |
sad = sad8bi(data->CurU, data->RefCU + dy * stride + dx, data->RefCU + (dy+1) * stride + dx, stride); |
100 |
sad += sad8bi(data->CurV, data->RefCV + dy * (data->iEdgedWidth/2) + dx, data->RefCV + (dy+1) * (data->iEdgedWidth/2) + dx, data->iEdgedWidth/2); |
sad += sad8bi(data->CurV, data->RefCV + dy * stride + dx, data->RefCV + (dy+1) * stride + dx, stride); |
101 |
break; |
break; |
102 |
case 2: |
case 2: |
103 |
dx = (dx - 1) / 2; dy = dy / 2; |
dx = (dx - 1) / 2; dy = dy / 2; |
104 |
sad = sad8bi(data->CurU, data->RefCU + dy * (data->iEdgedWidth/2) + dx, data->RefCU + dy * (data->iEdgedWidth/2) + dx+1, data->iEdgedWidth/2); |
sad = sad8bi(data->CurU, data->RefCU + dy * stride + dx, data->RefCU + dy * stride + dx+1, stride); |
105 |
sad += sad8bi(data->CurV, data->RefCV + dy * (data->iEdgedWidth/2) + dx, data->RefCV + dy * (data->iEdgedWidth/2) + dx+1, data->iEdgedWidth/2); |
sad += sad8bi(data->CurV, data->RefCV + dy * stride + dx, data->RefCV + dy * stride + dx+1, stride); |
106 |
break; |
break; |
107 |
default: |
default: |
108 |
dx = (dx - 1) / 2; dy = (dy - 1) / 2; |
dx = (dx - 1) / 2; dy = (dy - 1) / 2; |
109 |
interpolate8x8_halfpel_hv(data->RefQ, |
interpolate8x8_halfpel_hv(data->RefQ, data->RefCU + dy * stride + dx, stride, data->rounding); |
110 |
data->RefCU + dy * (data->iEdgedWidth/2) + dx, data->iEdgedWidth/2, |
sad = sad8(data->CurU, data->RefQ, stride); |
111 |
data->rounding); |
|
112 |
sad = sad8(data->CurU, data->RefQ, data->iEdgedWidth/2); |
interpolate8x8_halfpel_hv(data->RefQ, data->RefCV + dy * stride + dx, stride, data->rounding); |
113 |
interpolate8x8_halfpel_hv(data->RefQ, |
sad += sad8(data->CurV, data->RefQ, stride); |
|
data->RefCV + dy * (data->iEdgedWidth/2) + dx, data->iEdgedWidth/2, |
|
|
data->rounding); |
|
|
sad += sad8(data->CurV, data->RefQ, data->iEdgedWidth/2); |
|
114 |
break; |
break; |
115 |
} |
} |
116 |
data->temp[5] = dx; data->temp[6] = dy; data->temp[7] = sad; //backup |
data->temp[7] = sad; //backup, part 2 |
117 |
return sad; |
return sad; |
118 |
} |
} |
119 |
|
|
120 |
static __inline const uint8_t * |
static __inline const uint8_t * |
121 |
GetReference(const int x, const int y, const int dir, const SearchData * const data) |
GetReferenceB(const int x, const int y, const int dir, const SearchData * const data) |
122 |
{ |
{ |
123 |
// dir : 0 = forward, 1 = backward |
// dir : 0 = forward, 1 = backward |
124 |
switch ( (dir << 2) | ((x&1)<<1) | (y&1) ) { |
switch ( (dir << 2) | ((x&1)<<1) | (y&1) ) { |
133 |
} |
} |
134 |
} |
} |
135 |
|
|
136 |
|
// this is a simpler copy of GetReferenceB, but as it's __inline anyway, we can keep the two separate |
137 |
|
static __inline const uint8_t * |
138 |
|
GetReference(const int x, const int y, const SearchData * const data) |
139 |
|
{ |
140 |
|
switch ( ((x&1)<<1) | (y&1) ) { |
141 |
|
case 0 : return data->Ref + x/2 + (y/2)*(data->iEdgedWidth); |
142 |
|
case 1 : return data->RefV + x/2 + ((y-1)/2)*(data->iEdgedWidth); |
143 |
|
case 2 : return data->RefH + (x-1)/2 + (y/2)*(data->iEdgedWidth); |
144 |
|
default : return data->RefHV + (x-1)/2 + ((y-1)/2)*(data->iEdgedWidth); |
145 |
|
} |
146 |
|
} |
147 |
|
|
148 |
static uint8_t * |
static uint8_t * |
149 |
Interpolate8x8qpel(const int x, const int y, const int block, const int dir, const SearchData * const data) |
Interpolate8x8qpel(const int x, const int y, const int block, const int dir, const SearchData * const data) |
150 |
{ |
{ |
156 |
const int halfpel_y = y/2; |
const int halfpel_y = y/2; |
157 |
const uint8_t *ref1, *ref2, *ref3, *ref4; |
const uint8_t *ref1, *ref2, *ref3, *ref4; |
158 |
|
|
159 |
ref1 = GetReference(halfpel_x, halfpel_y, dir, data); |
ref1 = GetReferenceB(halfpel_x, halfpel_y, dir, data); |
160 |
ref1 += 8 * (block&1) + 8 * (block>>1) * iEdgedWidth; |
ref1 += 8 * (block&1) + 8 * (block>>1) * iEdgedWidth; |
161 |
switch( ((x&1)<<1) + (y&1) ) { |
switch( ((x&1)<<1) + (y&1) ) { |
162 |
case 0: // pure halfpel position |
case 0: // pure halfpel position |
164 |
break; |
break; |
165 |
|
|
166 |
case 1: // x halfpel, y qpel - top or bottom during qpel refinement |
case 1: // x halfpel, y qpel - top or bottom during qpel refinement |
167 |
ref2 = GetReference(halfpel_x, y - halfpel_y, dir, data); |
ref2 = GetReferenceB(halfpel_x, y - halfpel_y, dir, data); |
168 |
ref2 += 8 * (block&1) + 8 * (block>>1) * iEdgedWidth; |
ref2 += 8 * (block&1) + 8 * (block>>1) * iEdgedWidth; |
169 |
interpolate8x8_avg2(Reference, ref1, ref2, iEdgedWidth, rounding, 8); |
interpolate8x8_avg2(Reference, ref1, ref2, iEdgedWidth, rounding, 8); |
170 |
break; |
break; |
171 |
|
|
172 |
case 2: // x qpel, y halfpel - left or right during qpel refinement |
case 2: // x qpel, y halfpel - left or right during qpel refinement |
173 |
ref2 = GetReference(x - halfpel_x, halfpel_y, dir, data); |
ref2 = GetReferenceB(x - halfpel_x, halfpel_y, dir, data); |
174 |
ref2 += 8 * (block&1) + 8 * (block>>1) * iEdgedWidth; |
ref2 += 8 * (block&1) + 8 * (block>>1) * iEdgedWidth; |
175 |
interpolate8x8_avg2(Reference, ref1, ref2, iEdgedWidth, rounding, 8); |
interpolate8x8_avg2(Reference, ref1, ref2, iEdgedWidth, rounding, 8); |
176 |
break; |
break; |
177 |
|
|
178 |
default: // x and y in qpel resolution - the "corners" (top left/right and |
default: // x and y in qpel resolution - the "corners" (top left/right and |
179 |
// bottom left/right) during qpel refinement |
// bottom left/right) during qpel refinement |
180 |
ref2 = GetReference(halfpel_x, y - halfpel_y, dir, data); |
ref2 = GetReferenceB(halfpel_x, y - halfpel_y, dir, data); |
181 |
ref3 = GetReference(x - halfpel_x, halfpel_y, dir, data); |
ref3 = GetReferenceB(x - halfpel_x, halfpel_y, dir, data); |
182 |
ref4 = GetReference(x - halfpel_x, y - halfpel_y, dir, data); |
ref4 = GetReferenceB(x - halfpel_x, y - halfpel_y, dir, data); |
183 |
ref2 += 8 * (block&1) + 8 * (block>>1) * iEdgedWidth; |
ref2 += 8 * (block&1) + 8 * (block>>1) * iEdgedWidth; |
184 |
ref3 += 8 * (block&1) + 8 * (block>>1) * iEdgedWidth; |
ref3 += 8 * (block&1) + 8 * (block>>1) * iEdgedWidth; |
185 |
ref4 += 8 * (block&1) + 8 * (block>>1) * iEdgedWidth; |
ref4 += 8 * (block&1) + 8 * (block>>1) * iEdgedWidth; |
200 |
const int halfpel_y = y/2; |
const int halfpel_y = y/2; |
201 |
const uint8_t *ref1, *ref2, *ref3, *ref4; |
const uint8_t *ref1, *ref2, *ref3, *ref4; |
202 |
|
|
203 |
ref1 = GetReference(halfpel_x, halfpel_y, dir, data); |
ref1 = GetReferenceB(halfpel_x, halfpel_y, dir, data); |
204 |
switch( ((x&1)<<1) + (y&1) ) { |
switch( ((x&1)<<1) + (y&1) ) { |
205 |
case 0: // pure halfpel position |
case 0: // pure halfpel position |
206 |
return (uint8_t *) ref1; |
return (uint8_t *) ref1; |
207 |
case 1: // x halfpel, y qpel - top or bottom during qpel refinement |
case 1: // x halfpel, y qpel - top or bottom during qpel refinement |
208 |
ref2 = GetReference(halfpel_x, y - halfpel_y, dir, data); |
ref2 = GetReferenceB(halfpel_x, y - halfpel_y, dir, data); |
209 |
interpolate8x8_avg2(Reference, ref1, ref2, iEdgedWidth, rounding, 8); |
interpolate8x8_avg2(Reference, ref1, ref2, iEdgedWidth, rounding, 8); |
210 |
interpolate8x8_avg2(Reference+8, ref1+8, ref2+8, iEdgedWidth, rounding, 8); |
interpolate8x8_avg2(Reference+8, ref1+8, ref2+8, iEdgedWidth, rounding, 8); |
211 |
interpolate8x8_avg2(Reference+8*iEdgedWidth, ref1+8*iEdgedWidth, ref2+8*iEdgedWidth, iEdgedWidth, rounding, 8); |
interpolate8x8_avg2(Reference+8*iEdgedWidth, ref1+8*iEdgedWidth, ref2+8*iEdgedWidth, iEdgedWidth, rounding, 8); |
213 |
break; |
break; |
214 |
|
|
215 |
case 2: // x qpel, y halfpel - left or right during qpel refinement |
case 2: // x qpel, y halfpel - left or right during qpel refinement |
216 |
ref2 = GetReference(x - halfpel_x, halfpel_y, dir, data); |
ref2 = GetReferenceB(x - halfpel_x, halfpel_y, dir, data); |
217 |
interpolate8x8_avg2(Reference, ref1, ref2, iEdgedWidth, rounding, 8); |
interpolate8x8_avg2(Reference, ref1, ref2, iEdgedWidth, rounding, 8); |
218 |
interpolate8x8_avg2(Reference+8, ref1+8, ref2+8, iEdgedWidth, rounding, 8); |
interpolate8x8_avg2(Reference+8, ref1+8, ref2+8, iEdgedWidth, rounding, 8); |
219 |
interpolate8x8_avg2(Reference+8*iEdgedWidth, ref1+8*iEdgedWidth, ref2+8*iEdgedWidth, iEdgedWidth, rounding, 8); |
interpolate8x8_avg2(Reference+8*iEdgedWidth, ref1+8*iEdgedWidth, ref2+8*iEdgedWidth, iEdgedWidth, rounding, 8); |
222 |
|
|
223 |
default: // x and y in qpel resolution - the "corners" (top left/right and |
default: // x and y in qpel resolution - the "corners" (top left/right and |
224 |
// bottom left/right) during qpel refinement |
// bottom left/right) during qpel refinement |
225 |
ref2 = GetReference(halfpel_x, y - halfpel_y, dir, data); |
ref2 = GetReferenceB(halfpel_x, y - halfpel_y, dir, data); |
226 |
ref3 = GetReference(x - halfpel_x, halfpel_y, dir, data); |
ref3 = GetReferenceB(x - halfpel_x, halfpel_y, dir, data); |
227 |
ref4 = GetReference(x - halfpel_x, y - halfpel_y, dir, data); |
ref4 = GetReferenceB(x - halfpel_x, y - halfpel_y, dir, data); |
228 |
interpolate8x8_avg4(Reference, ref1, ref2, ref3, ref4, iEdgedWidth, rounding); |
interpolate8x8_avg4(Reference, ref1, ref2, ref3, ref4, iEdgedWidth, rounding); |
229 |
interpolate8x8_avg4(Reference+8, ref1+8, ref2+8, ref3+8, ref4+8, iEdgedWidth, rounding); |
interpolate8x8_avg4(Reference+8, ref1+8, ref2+8, ref3+8, ref4+8, iEdgedWidth, rounding); |
230 |
interpolate8x8_avg4(Reference+8*iEdgedWidth, ref1+8*iEdgedWidth, ref2+8*iEdgedWidth, ref3+8*iEdgedWidth, ref4+8*iEdgedWidth, iEdgedWidth, rounding); |
interpolate8x8_avg4(Reference+8*iEdgedWidth, ref1+8*iEdgedWidth, ref2+8*iEdgedWidth, ref3+8*iEdgedWidth, ref4+8*iEdgedWidth, iEdgedWidth, rounding); |
251 |
xc = x/2; yc = y/2; //for chroma sad |
xc = x/2; yc = y/2; //for chroma sad |
252 |
current = data->currentQMV; |
current = data->currentQMV; |
253 |
} else { |
} else { |
254 |
Reference = GetReference(x, y, 0, data); |
Reference = GetReference(x, y, data); |
255 |
current = data->currentMV; |
current = data->currentMV; |
256 |
xc = x; yc = y; |
xc = x; yc = y; |
257 |
} |
} |
262 |
data->temp[0] += (data->lambda16 * t * data->temp[0])/1000; |
data->temp[0] += (data->lambda16 * t * data->temp[0])/1000; |
263 |
data->temp[1] += (data->lambda8 * t * (data->temp[1] + NEIGH_8X8_BIAS))/100; |
data->temp[1] += (data->lambda8 * t * (data->temp[1] + NEIGH_8X8_BIAS))/100; |
264 |
|
|
265 |
if (data->chroma) data->temp[0] += ChromaSAD(xc, yc, data); |
if (data->chroma) data->temp[0] += ChromaSAD((xc >> 1) + roundtab_79[xc & 0x3], |
266 |
|
(yc >> 1) + roundtab_79[yc & 0x3], data); |
267 |
|
|
268 |
if (data->temp[0] < data->iMinSAD[0]) { |
if (data->temp[0] < data->iMinSAD[0]) { |
269 |
data->iMinSAD[0] = data->temp[0]; |
data->iMinSAD[0] = data->temp[0]; |
291 |
( x > data->max_dx) || ( x < data->min_dx) |
( x > data->max_dx) || ( x < data->min_dx) |
292 |
|| ( y > data->max_dy) || (y < data->min_dy)) return; |
|| ( y > data->max_dy) || (y < data->min_dy)) return; |
293 |
|
|
294 |
Reference = GetReference(x, y, 0, data); |
Reference = GetReference(x, y, data); |
295 |
t = d_mv_bits(x, y, data->predMV, data->iFcode, 0, 1); |
t = d_mv_bits(x, y, data->predMV, data->iFcode, 0, 1); |
296 |
|
|
297 |
data->temp[0] = sad32v_c(data->Cur, Reference, data->iEdgedWidth, data->temp + 1); |
data->temp[0] = sad32v_c(data->Cur, Reference, data->iEdgedWidth, data->temp + 1); |
332 |
Reference = Interpolate16x16qpel(x, y, 0, data); |
Reference = Interpolate16x16qpel(x, y, 0, data); |
333 |
current = data->currentQMV; |
current = data->currentQMV; |
334 |
} else { |
} else { |
335 |
Reference = GetReference(x, y, 0, data); |
Reference = GetReference(x, y, data); |
336 |
current = data->currentMV; |
current = data->currentMV; |
337 |
} |
} |
338 |
t = d_mv_bits(x, y, data->predMV, data->iFcode, |
t = d_mv_bits(x, y, data->predMV, data->iFcode, |
339 |
data->qpel && !data->qpel_precision && !data->rrv, data->rrv); |
data->qpel && !data->qpel_precision, data->rrv); |
340 |
|
|
341 |
sad = sad16(data->Cur, Reference, data->iEdgedWidth, 256*4096); |
sad = sad16(data->Cur, Reference, data->iEdgedWidth, 256*4096); |
342 |
sad += (data->lambda16 * t * sad)/1000; |
sad += (data->lambda16 * t * sad)/1000; |
372 |
|
|
373 |
} |
} |
374 |
|
|
|
|
|
375 |
static void |
static void |
376 |
CheckCandidateInt(const int xf, const int yf, const int Direction, int * const dir, const SearchData * const data) |
CheckCandidateInt(const int xf, const int yf, const int Direction, int * const dir, const SearchData * const data) |
377 |
{ |
{ |
389 |
current = data->currentQMV; |
current = data->currentQMV; |
390 |
ReferenceB = Interpolate16x16qpel(xb, yb, 1, data); |
ReferenceB = Interpolate16x16qpel(xb, yb, 1, data); |
391 |
} else { |
} else { |
392 |
ReferenceF = GetReference(xf, yf, 0, data); |
ReferenceF = GetReference(xf, yf, data); |
393 |
xb = data->currentMV[1].x; yb = data->currentMV[1].y; |
xb = data->currentMV[1].x; yb = data->currentMV[1].y; |
394 |
ReferenceB = GetReference(xb, yb, 1, data); |
ReferenceB = GetReferenceB(xb, yb, 1, data); |
395 |
current = data->currentMV; |
current = data->currentMV; |
396 |
} |
} |
397 |
|
|
508 |
|| ( y > data->max_dy) || (y < data->min_dy)) return; |
|| ( y > data->max_dy) || (y < data->min_dy)) return; |
509 |
|
|
510 |
if (data->qpel) Reference = Interpolate16x16qpel(x, y, 0, data); |
if (data->qpel) Reference = Interpolate16x16qpel(x, y, 0, data); |
511 |
else Reference = GetReference(x, y, 0, data); |
else Reference = GetReference(x, y, data); |
512 |
|
|
513 |
sad = sad8(data->Cur, Reference, data->iEdgedWidth); |
sad = sad8(data->Cur, Reference, data->iEdgedWidth); |
514 |
t = d_mv_bits(x, y, data->predMV, data->iFcode, data->qpel && !data->qpel_precision, 0); |
t = d_mv_bits(x, y, data->predMV, data->iFcode, data->qpel && !data->qpel_precision, 0); |
681 |
backupMV = *(data->currentQMV); |
backupMV = *(data->currentQMV); |
682 |
else backupMV = *(data->currentMV); |
else backupMV = *(data->currentMV); |
683 |
|
|
684 |
CHECK_CANDIDATE(backupMV.x - 1, backupMV.y - 1, 0); |
CHECK_CANDIDATE(backupMV.x, backupMV.y - 1, 0); |
685 |
CHECK_CANDIDATE(backupMV.x + 1, backupMV.y - 1, 0); |
CHECK_CANDIDATE(backupMV.x + 1, backupMV.y - 1, 0); |
|
CHECK_CANDIDATE(backupMV.x - 1, backupMV.y + 1, 0); |
|
|
CHECK_CANDIDATE(backupMV.x + 1, backupMV.y + 1, 0); |
|
|
|
|
|
CHECK_CANDIDATE(backupMV.x - 1, backupMV.y, 0); |
|
686 |
CHECK_CANDIDATE(backupMV.x + 1, backupMV.y, 0); |
CHECK_CANDIDATE(backupMV.x + 1, backupMV.y, 0); |
687 |
|
CHECK_CANDIDATE(backupMV.x + 1, backupMV.y + 1, 0); |
688 |
CHECK_CANDIDATE(backupMV.x, backupMV.y + 1, 0); |
CHECK_CANDIDATE(backupMV.x, backupMV.y + 1, 0); |
689 |
CHECK_CANDIDATE(backupMV.x, backupMV.y - 1, 0); |
CHECK_CANDIDATE(backupMV.x - 1, backupMV.y + 1, 0); |
690 |
|
CHECK_CANDIDATE(backupMV.x - 1, backupMV.y, 0); |
691 |
|
CHECK_CANDIDATE(backupMV.x - 1, backupMV.y - 1, 0); |
692 |
} |
} |
693 |
|
|
694 |
static __inline int |
static __inline int |
1099 |
Data->currentQMV[i].y = 2 * Data->currentMV[i].y; |
Data->currentQMV[i].y = 2 * Data->currentMV[i].y; |
1100 |
} |
} |
1101 |
|
|
1102 |
if((!Data->rrv) && (pParam->m_quarterpel) && (MotionFlags & PMV_QUARTERPELREFINE16)) { |
if((Data->qpel) && (MotionFlags & PMV_QUARTERPELREFINE16)) { |
1103 |
|
|
1104 |
Data->qpel_precision = 1; |
Data->qpel_precision = 1; |
1105 |
get_range(&Data->min_dx, &Data->max_dx, &Data->min_dy, &Data->max_dy, x, y, 16, |
get_range(&Data->min_dx, &Data->max_dx, &Data->min_dy, &Data->max_dy, x, y, 16, |
1123 |
Search8(Data, 2*x + 1, 2*y + 1, MotionFlags, pParam, pMB, pMBs, 3, &Data8); |
Search8(Data, 2*x + 1, 2*y + 1, MotionFlags, pParam, pMB, pMBs, 3, &Data8); |
1124 |
|
|
1125 |
if (Data->chroma) { |
if (Data->chroma) { |
1126 |
int sumx, sumy, dx, dy; |
int sumx, sumy; |
1127 |
|
|
1128 |
if(pParam->m_quarterpel) { |
if(pParam->m_quarterpel) { |
1129 |
sumx= pMB->qmvs[0].x/2 + pMB->qmvs[1].x/2 + pMB->qmvs[2].x/2 + pMB->qmvs[3].x/2; |
sumx= pMB->qmvs[0].x/2 + pMB->qmvs[1].x/2 + pMB->qmvs[2].x/2 + pMB->qmvs[3].x/2; |
1132 |
sumx = pMB->mvs[0].x + pMB->mvs[1].x + pMB->mvs[2].x + pMB->mvs[3].x; |
sumx = pMB->mvs[0].x + pMB->mvs[1].x + pMB->mvs[2].x + pMB->mvs[3].x; |
1133 |
sumy = pMB->mvs[0].y + pMB->mvs[1].y + pMB->mvs[2].y + pMB->mvs[3].y; |
sumy = pMB->mvs[0].y + pMB->mvs[1].y + pMB->mvs[2].y + pMB->mvs[3].y; |
1134 |
} |
} |
|
dx = (sumx >> 3) + roundtab_76[sumx & 0xf]; |
|
|
dy = (sumy >> 3) + roundtab_76[sumy & 0xf]; |
|
1135 |
|
|
1136 |
Data->iMinSAD[1] += ChromaSAD(dx, dy, Data); |
Data->iMinSAD[1] += ChromaSAD( (sumx >> 3) + roundtab_76[sumx & 0xf], |
1137 |
|
(sumy >> 3) + roundtab_76[sumy & 0xf], Data); |
1138 |
} |
} |
1139 |
} |
} |
1140 |
|
|
1245 |
} |
} |
1246 |
} |
} |
1247 |
|
|
1248 |
if(!Data->rrv && Data->qpel) { |
if(Data->qpel) { |
1249 |
if((!(Data->currentQMV->x & 1)) && (!(Data->currentQMV->y & 1)) && |
if((!(Data->currentQMV->x & 1)) && (!(Data->currentQMV->y & 1)) && |
1250 |
(MotionFlags & PMV_QUARTERPELREFINE8)) { |
(MotionFlags & PMV_QUARTERPELREFINE8)) { |
1251 |
Data->qpel_precision = 1; |
Data->qpel_precision = 1; |
1576 |
|
|
1577 |
*best_sad = *Data->iMinSAD; |
*best_sad = *Data->iMinSAD; |
1578 |
|
|
1579 |
if (b_mb->mode == MODE_INTER4V) pMB->mode = MODE_DIRECT; |
if (b_mb->mode == MODE_INTER4V || Data->qpel) pMB->mode = MODE_DIRECT; |
1580 |
else pMB->mode = MODE_DIRECT_NO4V; //for faster compensation |
else pMB->mode = MODE_DIRECT_NO4V; //for faster compensation |
1581 |
|
|
1582 |
pMB->pmvs[3] = *Data->currentMV; |
pMB->pmvs[3] = *Data->currentMV; |
2077 |
max_x = gmc.x + step; |
max_x = gmc.x + step; |
2078 |
min_y = gmc.y - step; |
min_y = gmc.y - step; |
2079 |
max_y = gmc.y + step; |
max_y = gmc.y + step; |
|
|
|
2080 |
} |
} |
2081 |
|
|
2082 |
if (bestcount < (pParam->mb_height-2)*(pParam->mb_width-2)/10) |
if (bestcount < (pParam->mb_height-2)*(pParam->mb_width-2)/10) |
2083 |
gmc.x = gmc.y = 0; //no camara pan, no GMC |
gmc.x = gmc.y = 0; //no camara pan, no GMC |
2084 |
|
|
2085 |
// step2: let's refine camera panning using gradiend-descent approach. |
// step2: let's refine camera panning using gradiend-descent approach |
2086 |
// TODO: more warping points may be evaluated here (like in interpolate mode search - two vectors in one diamond) |
// TODO: more warping points may be evaluated here (like in interpolate mode search - two vectors in one diamond) |
2087 |
bestcount = 0; |
bestcount = 0; |
2088 |
CheckGMC(gmc.x, gmc.y, 255, &iDirection, pMBs, &bestcount, &gmc, pParam); |
CheckGMC(gmc.x, gmc.y, 255, &iDirection, pMBs, &bestcount, &gmc, pParam); |