408 |
} |
} |
409 |
|
|
410 |
} |
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
/* |
|
|
get_pmvdata2: get_pmvdata with bounding |
|
|
*/ |
|
|
#define OFFSET(x,y,stride) ((x)+((y)*(stride))) |
|
|
|
|
|
int |
|
|
get_pmvdata2(const MACROBLOCK * const pMBs, |
|
|
const uint32_t x, |
|
|
const uint32_t y, |
|
|
const uint32_t x_dim, |
|
|
const uint32_t block, |
|
|
VECTOR * const pmv, |
|
|
int32_t * const psad, |
|
|
const int bound) |
|
|
{ |
|
|
const int mbpos = OFFSET(x, y ,x_dim); |
|
|
|
|
|
/* |
|
|
* pmv are filled with: |
|
|
* [0]: Median (or whatever is correct in a special case) |
|
|
* [1]: left neighbour |
|
|
* [2]: top neighbour |
|
|
* [3]: topright neighbour |
|
|
* psad are filled with: |
|
|
* [0]: minimum of [1] to [3] |
|
|
* [1]: left neighbour's SAD (NB:[1] to [3] are actually not needed) |
|
|
* [2]: top neighbour's SAD |
|
|
* [3]: topright neighbour's SAD |
|
|
*/ |
|
|
|
|
|
int xin1, xin2, xin3; |
|
|
int yin1, yin2, yin3; |
|
|
int vec1, vec2, vec3; |
|
|
|
|
|
int pos1, pos2, pos3; |
|
|
int num_cand = 0; // number of candidates |
|
|
int last_cand; // last candidate |
|
|
|
|
|
uint32_t index = x + y * x_dim; |
|
|
const VECTOR zeroMV = { 0, 0 }; |
|
|
|
|
|
/* |
|
|
* MODE_INTER, vm18 page 48 |
|
|
* MODE_INTER4V vm18 page 51 |
|
|
* |
|
|
* (x,y-1) (x+1,y-1) |
|
|
* [ | ] [ | ] |
|
|
* [ 2 | 3 ] [ 2 | ] |
|
|
* |
|
|
* (x-1,y) (x,y) (x+1,y) |
|
|
* [ | 1 ] [ 0 | 1 ] [ 0 | ] |
|
|
* [ | 3 ] [ 2 | 3 ] [ | ] |
|
|
*/ |
|
|
|
|
|
switch (block) { |
|
|
case 0: |
|
|
xin1 = x - 1; |
|
|
yin1 = y; |
|
|
vec1 = 1; /* left */ |
|
|
xin2 = x; |
|
|
yin2 = y - 1; |
|
|
vec2 = 2; /* top */ |
|
|
xin3 = x + 1; |
|
|
yin3 = y - 1; |
|
|
vec3 = 2; /* top right */ |
|
|
break; |
|
|
case 1: |
|
|
xin1 = x; |
|
|
yin1 = y; |
|
|
vec1 = 0; |
|
|
xin2 = x; |
|
|
yin2 = y - 1; |
|
|
vec2 = 3; |
|
|
xin3 = x + 1; |
|
|
yin3 = y - 1; |
|
|
vec3 = 2; |
|
|
break; |
|
|
case 2: |
|
|
xin1 = x - 1; |
|
|
yin1 = y; |
|
|
vec1 = 3; |
|
|
xin2 = x; |
|
|
yin2 = y; |
|
|
vec2 = 0; |
|
|
xin3 = x; |
|
|
yin3 = y; |
|
|
vec3 = 1; |
|
|
break; |
|
|
default: |
|
|
xin1 = x; |
|
|
yin1 = y; |
|
|
vec1 = 2; |
|
|
xin2 = x; |
|
|
yin2 = y; |
|
|
vec2 = 0; |
|
|
xin3 = x; |
|
|
yin3 = y; |
|
|
vec3 = 1; |
|
|
} |
|
|
|
|
|
pos1 = OFFSET(xin1, yin1, x_dim); |
|
|
pos2 = OFFSET(xin2, yin2, x_dim); |
|
|
pos3 = OFFSET(xin3, yin3, x_dim); |
|
|
|
|
|
// left |
|
|
if (xin1 < 0 || pos1 < bound) { |
|
|
pmv[1] = zeroMV; |
|
|
psad[1] = MV_MAX_ERROR; |
|
|
} else { |
|
|
pmv[1] = pMBs[xin1 + yin1 * x_dim].mvs[vec1]; |
|
|
psad[1] = pMBs[xin1 + yin1 * x_dim].sad8[vec1]; |
|
|
num_cand++; |
|
|
last_cand = 1; |
|
|
} |
|
|
|
|
|
// top |
|
|
if (yin2 < 0 || pos2 < bound) { |
|
|
pmv[2] = zeroMV; |
|
|
psad[2] = MV_MAX_ERROR; |
|
|
} else { |
|
|
pmv[2] = pMBs[xin2 + yin2 * x_dim].mvs[vec2]; |
|
|
psad[2] = pMBs[xin2 + yin2 * x_dim].sad8[vec2]; |
|
|
num_cand++; |
|
|
last_cand = 2; |
|
|
} |
|
|
|
|
|
|
|
|
// top right |
|
|
if (yin3 < 0 || pos3 < bound || xin3 >= (int)x_dim) { |
|
|
pmv[3] = zeroMV; |
|
|
psad[3] = MV_MAX_ERROR; |
|
|
//DPRINTF(DPRINTF_MV, "top-right"); |
|
|
} else { |
|
|
pmv[3] = pMBs[xin3 + yin3 * x_dim].mvs[vec3]; |
|
|
psad[3] = pMBs[xin2 + yin2 * x_dim].sad8[vec3]; |
|
|
num_cand++; |
|
|
last_cand = 3; |
|
|
} |
|
|
|
|
|
if (num_cand == 1) |
|
|
{ |
|
|
/* DPRINTF(DPRINTF_MV,"cand0=(%i,%i), cand1=(%i,%i) cand2=(%i,%i) last=%i", |
|
|
pmv[1].x, pmv[1].y, |
|
|
pmv[2].x, pmv[2].y, |
|
|
pmv[3].x, pmv[3].y, last_cand - 1); |
|
|
*/ |
|
|
|
|
|
pmv[0] = pmv[last_cand]; |
|
|
psad[0] = psad[last_cand]; |
|
|
return 0; |
|
|
} |
|
|
|
|
|
/* DPRINTF(DPRINTF_MV,"cand0=(%i,%i), cand1=(%i,%i) cand2=(%i,%i)", |
|
|
pmv[1].x, pmv[1].y, |
|
|
pmv[2].x, pmv[2].y, |
|
|
pmv[3].x, pmv[3].y);*/ |
|
|
|
|
|
if ((MVequal(pmv[1], pmv[2])) && (MVequal(pmv[1], pmv[3]))) { |
|
|
pmv[0] = pmv[1]; |
|
|
psad[0] = MIN(MIN(psad[1], psad[2]), psad[3]); |
|
|
return 1; |
|
|
} |
|
|
|
|
|
/* median,minimum */ |
|
|
|
|
|
pmv[0].x = |
|
|
MIN(MAX(pmv[1].x, pmv[2].x), |
|
|
MIN(MAX(pmv[2].x, pmv[3].x), MAX(pmv[1].x, pmv[3].x))); |
|
|
pmv[0].y = |
|
|
MIN(MAX(pmv[1].y, pmv[2].y), |
|
|
MIN(MAX(pmv[2].y, pmv[3].y), MAX(pmv[1].y, pmv[3].y))); |
|
|
psad[0] = MIN(MIN(psad[1], psad[2]), psad[3]); |
|
|
|
|
|
return 0; |
|
|
} |
|