mv-search.c
来自「包含了从MPEG4的视频解码到H.264的视频编码部分的源代码」· C语言 代码 · 共 1,913 行 · 第 1/5 页
C
1,913 行
int // ==> minimum motion cost after search
FastFullPelBlockMotionSearch (pel_t** orig_pic, // <-- not used
int ref, // <-- reference frame (0... or -1 (backward))
int pic_pix_x, // <-- absolute x-coordinate of regarded AxB block
int pic_pix_y, // <-- absolute y-coordinate of regarded AxB block
int blocktype, // <-- block type (1-16x16 ... 7-4x4)
int pred_mv_x, // <-- motion vector predictor (x) in sub-pel units
int pred_mv_y, // <-- motion vector predictor (y) in sub-pel units
int* mv_x, // --> motion vector (x) - in pel units
int* mv_y, // --> motion vector (y) - in pel units
int search_range, // <-- 1-d search range in pel units
int min_mcost, // <-- minimum motion cost (cost for center or huge value)
double lambda) // <-- lagrangian parameter for determining motion cost
{
int pos, offset_x, offset_y, cand_x, cand_y, mcost;
int refindex = (ref!=-1 ? ref : img->buf_cycle); // reference frame index (array entry)
int max_pos = (2*search_range+1)*(2*search_range+1); // number of search positions
int lambda_factor = LAMBDA_FACTOR (lambda); // factor for determining lagragian motion cost
int best_pos = 0; // position with minimum motion cost
int block_index; // block index for indexing SAD array
int* block_sad; // pointer to SAD array
int pix_y;
if(input->InterlaceCodingOption >= MB_CODING && mb_adaptive && img->field_mode)
{
pix_y = img->field_pix_y;
block_index = (pic_pix_y-pix_y)+((pic_pix_x-img->pix_x)>>2);
block_sad = BlockSAD[refindex][blocktype][block_index];
}
else
{
block_index = (pic_pix_y-img->pix_y)+((pic_pix_x-img->pix_x)>>2); // block index for indexing SAD array
block_sad = BlockSAD[refindex][blocktype][block_index]; // pointer to SAD array
pix_y = img->pix_y;
}
//===== set up fast full integer search if needed / set search center =====
if (!search_setup_done[refindex])
{
SetupFastFullPelSearch (ref);
}
offset_x = search_center_x[refindex] - img->pix_x;
offset_y = search_center_y[refindex] - pix_y;
//===== cost for (0,0)-vector: it is done before, because MVCost can be negative =====
if (!input->rdopt)
{
mcost = block_sad[pos_00[refindex]] + MV_COST (lambda_factor, 2, 0, 0, pred_mv_x, pred_mv_y);
if (mcost < min_mcost)
{
min_mcost = mcost;
best_pos = pos_00[refindex];
}
}
//===== loop over all search positions =====
for (pos=0; pos<max_pos; pos++, block_sad++)
{
//--- check residual cost ---
if (*block_sad < min_mcost)
{
//--- get motion vector cost ---
cand_x = offset_x + spiral_search_x[pos];
cand_y = offset_y + spiral_search_y[pos];
mcost = *block_sad;
mcost += MV_COST (lambda_factor, 2, cand_x, cand_y, pred_mv_x, pred_mv_y);
//--- check motion cost ---
if (mcost < min_mcost)
{
min_mcost = mcost;
best_pos = pos;
}
}
}
//===== set best motion vector and return minimum motion cost =====
*mv_x = offset_x + spiral_search_x[best_pos];
*mv_y = offset_y + spiral_search_y[best_pos];
return min_mcost;
}
#endif
/*!
***********************************************************************
* \brief
* Calculate SA(T)D
***********************************************************************
*/
/*
int
SATD (_int16* diff, int use_hadamard)
{
_int16 k, satd = 0, m[16], dd, *d=diff;
if (use_hadamard)
{
//===== hadamard transform =====//
m[ 0] = d[ 0] + d[12];
m[ 4] = d[ 4] + d[ 8];
m[ 8] = d[ 4] - d[ 8];
m[12] = d[ 0] - d[12];
m[ 1] = d[ 1] + d[13];
m[ 5] = d[ 5] + d[ 9];
m[ 9] = d[ 5] - d[ 9];
m[13] = d[ 1] - d[13];
m[ 2] = d[ 2] + d[14];
m[ 6] = d[ 6] + d[10];
m[10] = d[ 6] - d[10];
m[14] = d[ 2] - d[14];
m[ 3] = d[ 3] + d[15];
m[ 7] = d[ 7] + d[11];
m[11] = d[ 7] - d[11];
m[15] = d[ 3] - d[15];
d[ 0] = m[ 0] + m[ 4];
d[ 8] = m[ 0] - m[ 4];
d[ 4] = m[ 8] + m[12];
d[12] = m[12] - m[ 8];
d[ 1] = m[ 1] + m[ 5];
d[ 9] = m[ 1] - m[ 5];
d[ 5] = m[ 9] + m[13];
d[13] = m[13] - m[ 9];
d[ 2] = m[ 2] + m[ 6];
d[10] = m[ 2] - m[ 6];
d[ 6] = m[10] + m[14];
d[14] = m[14] - m[10];
d[ 3] = m[ 3] + m[ 7];
d[11] = m[ 3] - m[ 7];
d[ 7] = m[11] + m[15];
d[15] = m[15] - m[11];
m[ 0] = d[ 0] + d[ 3];
m[ 1] = d[ 1] + d[ 2];
m[ 2] = d[ 1] - d[ 2];
m[ 3] = d[ 0] - d[ 3];
m[ 4] = d[ 4] + d[ 7];
m[ 5] = d[ 5] + d[ 6];
m[ 6] = d[ 5] - d[ 6];
m[ 7] = d[ 4] - d[ 7];
m[ 8] = d[ 8] + d[11];
m[ 9] = d[ 9] + d[10];
m[10] = d[ 9] - d[10];
m[11] = d[ 8] - d[11];
m[12] = d[12] + d[15];
m[13] = d[13] + d[14];
m[14] = d[13] - d[14];
m[15] = d[12] - d[15];
d[ 0] = m[ 0] + m[ 1];
d[ 1] = m[ 0] - m[ 1];
d[ 2] = m[ 2] + m[ 3];
d[ 3] = m[ 3] - m[ 2];
d[ 4] = m[ 4] + m[ 5];
d[ 5] = m[ 4] - m[ 5];
d[ 6] = m[ 6] + m[ 7];
d[ 7] = m[ 7] - m[ 6];
d[ 8] = m[ 8] + m[ 9];
d[ 9] = m[ 8] - m[ 9];
d[10] = m[10] + m[11];
d[11] = m[11] - m[10];
d[12] = m[12] + m[13];
d[13] = m[12] - m[13];
d[14] = m[14] + m[15];
d[15] = m[15] - m[14];
//===== sum up =====//
for (dd=diff[k=0]; k<16; dd=diff[++k])
{
satd += (dd < 0 ? -dd : dd);
}
satd >>= 1;
}
else
{
//===== sum up =====//
for (k = 0; k < 16; k++)
{
satd += byte_abs [diff [k]];
}
}
return satd;
}
*/
//zdd
int
SATD (_int16* diff, int use_hadamard)
{
_int16 *pt1=diff;
_int32 satd = 0,ret;
int k;
if (use_hadamard)
{
_asm
{
mov eax,pt1
movq mm0,[eax]
movq mm1,[eax+8]
movq mm2,[eax+16]
movq mm3,[eax+24]
movq mm4,mm0
paddw mm4,mm1 //a0+a1
movq mm6,mm2
paddw mm6,mm3 //a2+a3
movq mm5,mm4
paddw mm4,mm6 //a0+a1+a2+a3
psubw mm5,mm6 //a0+a1-a2-a3
movq mm6,mm0
movq mm7,mm0
paddw mm6,mm3
psubw mm6,mm1
psubw mm6,mm2 //a0-a1-a2+a3
paddw mm7,mm2
psubw mm7,mm1
psubw mm7,mm3 //a0-a1+a2-a3
//转秩
movq mm0,mm4
movq mm1,mm5
movq mm2,mm6
movq mm3,mm7
PUNPCKLWD mm0,mm1
PUNPCKLWD mm2,mm3
movq mm1,mm0
PUNPCKLDQ mm0,mm2
PUNPCKHDQ mm1,mm2
PUNPCKHWD mm4,mm5
PUNPCKHWD mm6,mm3
movq mm3,mm4
PUNPCKLDQ mm4,mm6
PUNPCKHDQ mm3,mm6
movq mm2,mm4
//计算第二遍
movq mm4,mm0
paddw mm4,mm1 //a0+a1
movq mm6,mm2
paddw mm6,mm3 //a2+a3
movq mm5,mm4
paddw mm4,mm6 //a0+a1+a2+a3
psubw mm5,mm6 //a0+a1-a2-a3
movq mm6,mm0
movq mm7,mm0
paddw mm6,mm3
psubw mm6,mm1
psubw mm6,mm2 //a0-a1-a2+a3
paddw mm7,mm2
psubw mm7,mm1
psubw mm7,mm3 //a0-a1+a2-a3
movq mm0,mm4
movq mm1,mm5
movq mm2,mm6
movq mm3,mm7
//求绝对值
MOVQ MM4, MM0
PSRAW MM4, 15
PXOR MM0, MM4
PSUBW MM0, MM4
MOVQ MM5, MM1
PSRAW MM5, 15
PXOR MM1, MM5
PSUBW MM1, MM5
MOVQ MM6, MM2
PSRAW MM6, 15
PXOR MM2, MM6
PSUBW MM2, MM6
MOVQ MM7, MM3
PSRAW MM7, 15
PXOR MM3, MM7
PSUBW MM3, MM7
paddw mm0,mm1
paddw mm0,mm2
paddw mm0,mm3
PEXTRW eax,mm0,0
PEXTRW ebx,mm0,1
PEXTRW ecx,mm0,2
PEXTRW edx,mm0,3
add eax,ebx
add eax,ecx
add eax,edx
SAR eax,1
mov satd,eax
emms
}
}
else
{
//===== sum up =====//
for (k = 0; k < 16; k++)
{
satd += byte_abs [diff [k]];
}
}
return satd;
}
/*!
***********************************************************************
* \brief
* Sub pixel block motion search
***********************************************************************
*/
int // ==> minimum motion cost after search
SubPelBlockMotionSearch (pel_t** orig_pic, // <-- original pixel values for the AxB block
int ref, // <-- reference frame (0... or -1 (backward))
int pic_pix_x, // <-- absolute x-coordinate of regarded AxB block
int pic_pix_y, // <-- absolute y-coordinate of regarded AxB block
int blocktype, // <-- block type (1-16x16 ... 7-4x4)
int pred_mv_x, // <-- motion vector predictor (x) in sub-pel units
int pred_mv_y, // <-- motion vector predictor (y) in sub-pel units
int* mv_x, // <--> in: search center (x) / out: motion vector (x) - in pel units
int* mv_y, // <--> in: search center (y) / out: motion vector (y) - in pel units
int search_pos2, // <-- search positions for half-pel search (default: 9)
int search_pos4, // <-- search positions for quarter-pel search (default: 9)
int min_mcost, // <-- minimum motion cost (cost for center or huge value)
double lambda // <-- lagrangian parameter for determining motion cost
)
{
_int16 diff[16], *d;
int pos, best_pos, mcost, abort_search;
int y0, x0, ry0, rx0, ry;
int cand_mv_x, cand_mv_y;
pel_t *orig_line;
int incr = ref==-1 ? ((!img->fld_type)&&(mref==mref_fld)&&(img->type==B_IMG)) : (mref==mref_fld)&&(img->type==B_IMG) ;
pel_t **ref_pic;
int lambda_factor = LAMBDA_FACTOR (lambda);
int mv_shift = 0;
int check_position0 = (blocktype==1 && *mv_x==0 && *mv_y==0 && input->hadamard && !input->rdopt && img->type!=B_IMG && ref==0);
int blocksize_x = input->blc_size[blocktype][0];
int blocksize_y = input->blc_size[blocktype][1];
int pic4_pix_x = (pic_pix_x << 2);
int pic4_pix_y = (pic_pix_y << 2);
int max_pos_x4 = ((img->width -blocksize_x+1)<<2);
int max_pos_y4 = ((img->height-blocksize_y+1)<<2);
int min_pos2 = (input->hadamard ? 0 : 1);
int max_pos2 = (input->hadamard ? max(1,search_pos2) : search_pos2);
int apply_weights = ( (input->WeightedPrediction && img->type == INTER_IMG) ||
(input->WeightedBiprediction && (img->type == B_IMG || img->type == BS_IMG)));
if (apply_weights)
ref_pic = img->type==B_IMG? mref_w [ref+1+incr] : mref_w [ref];
else
ref_pic = img->type==B_IMG? mref [ref+1+incr] : mref [ref];
if(input->InterlaceCodingOption >= MB_CODING && mb_adaptive && img->field_mode && img->type == B_IMG)
{
incr = ref == -1 ? (img->top_field && img->field_mode):(img->field_mode);
if (input->WeightedPrediction || input->WeightedBiprediction)
ref_pic = mref_w[ref+1+incr];
else
ref_pic = mref[ref+1+incr];
}
/*********************************
***** *****
***** HALF-PEL REFINEMENT *****
***** *****
*********************************/
//===== convert search center to quarter-pel units =====
*mv_x <<= 2;
*mv_y <<= 2;
//===== set function for getting pixel values =====
if ((pic4_pix_x + *mv_x > 1) && (pic4_pix_x + *mv_x < max_pos_x4 - 2) &&
(pic4_pix_y + *mv_y > 1) && (pic4_pix_y + *mv_y < max_pos_y4 - 2) )
{
PelY_14 = FastPelY_14;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?