📄 mv-search.c
字号:
mcost += distortion8x8(diff64);
}
}
return mcost;
}
/*!
************************************************************************
* \brief
* Get cost for skip mode for an macroblock
************************************************************************
*/
int GetSkipCostMB (void)
{
int block_y, block_x, pic_pix_y, pic_pix_x, i, j, k;
int cost = 0;
int curr_diff[8][8];
int mb_x, mb_y;
int block;
for(block=0;block<4;block++)
{
mb_y = (block/2)<<3;
mb_x = (block%2)<<3;
for (block_y=mb_y; block_y<mb_y+8; block_y+=4)
{
pic_pix_y = img->opix_y + block_y;
for (block_x=mb_x; block_x<mb_x+8; block_x+=4)
{
pic_pix_x = img->opix_x + block_x;
//===== prediction of 4x4 block =====
LumaPrediction4x4 (block_x, block_y, 0, 0, 0, 0, 0);
//===== get displaced frame difference ======
for (k=j=0; j<4; j++)
for (i=0; i<4; i++, k++)
{
diff[k] = curr_diff[block_y-mb_y+j][block_x-mb_x+i] = imgY_org[pic_pix_y+j][pic_pix_x+i] - img->mpr[j+block_y][i+block_x];
}
if(!((input->rdopt==0)&&(input->Transform8x8Mode)))
cost += distortion4x4 (diff);
}
}
if((input->rdopt==0)&&(input->Transform8x8Mode))
{
for(k=j=0; j<8; j++, k+=8)
memcpy(&diff64[k], &(curr_diff[j]), 8 * sizeof(int));
cost += distortion8x8 (diff64);
}
}
return cost;
}
/*!
************************************************************************
* \brief
* Find motion vector for the Skip mode
************************************************************************
*/
void FindSkipModeMotionVector ()
{
int bx, by;
short ******all_mv = img->all_mv;
short pmv[2];
int zeroMotionAbove;
int zeroMotionLeft;
PixelPos mb_a, mb_b;
int a_mv_y = 0;
int a_ref_idx = 0;
int b_mv_y = 0;
int b_ref_idx = 0;
short ***mv = enc_picture->mv[LIST_0];
Macroblock *currMB = &img->mb_data[img->current_mb_nr];
getLuma4x4Neighbour(img->current_mb_nr,-1, 0, &mb_a);
getLuma4x4Neighbour(img->current_mb_nr, 0,-1, &mb_b);
if (mb_a.available)
{
a_mv_y = mv[mb_a.pos_y][mb_a.pos_x][1];
a_ref_idx = enc_picture->ref_idx[LIST_0][mb_a.pos_y][mb_a.pos_x];
if (currMB->mb_field && !img->mb_data[mb_a.mb_addr].mb_field)
{
a_mv_y /=2;
a_ref_idx *=2;
}
if (!currMB->mb_field && img->mb_data[mb_a.mb_addr].mb_field)
{
a_mv_y *=2;
a_ref_idx >>=1;
}
}
if (mb_b.available)
{
b_mv_y = mv[mb_b.pos_y][mb_b.pos_x][1];
b_ref_idx = enc_picture->ref_idx[LIST_0][mb_b.pos_y][mb_b.pos_x];
if (currMB->mb_field && !img->mb_data[mb_b.mb_addr].mb_field)
{
b_mv_y /=2;
b_ref_idx *=2;
}
if (!currMB->mb_field && img->mb_data[mb_b.mb_addr].mb_field)
{
b_mv_y *=2;
b_ref_idx >>=1;
}
}
zeroMotionLeft = !mb_a.available ? 1 : a_ref_idx==0 && mv[mb_a.pos_y][mb_a.pos_x][0]==0 && a_mv_y==0 ? 1 : 0;
zeroMotionAbove = !mb_b.available ? 1 : b_ref_idx==0 && mv[mb_b.pos_y][mb_b.pos_x][0]==0 && b_mv_y==0 ? 1 : 0;
if (zeroMotionAbove || zeroMotionLeft)
{
for (by = 0;by < 4;by++)
for (bx = 0;bx < 4;bx++)
{
memset(all_mv [by][bx][0][0][0], 0, 2* sizeof(short));
//all_mv [by][bx][0][0][0][0] = 0;
//all_mv [by][bx][0][0][0][1] = 0;
}
}
else
{
SetMotionVectorPredictor (pmv, enc_picture->ref_idx[LIST_0], mv, 0, LIST_0, 0, 0, 16, 16);
for (by = 0;by < 4;by++)
for (bx = 0;bx < 4;bx++)
{
memcpy(all_mv [by][bx][0][0][0], pmv, 2* sizeof(short));
}
}
}
/*!
************************************************************************
* \brief
* Get cost for direct mode for an 8x8 block
************************************************************************
*/
int GetDirectCost8x8 (int block, int *cost8x8)
{
int block_y, block_x, pic_pix_y, pic_pix_x, i, j, k;
int curr_diff[8][8];
int cost = 0;
int mb_y = (block/2)<<3;
int mb_x = (block%2)<<3;
for (block_y=mb_y; block_y<mb_y+8; block_y+=4)
{
pic_pix_y = img->opix_y + block_y;
for (block_x=mb_x; block_x<mb_x+8; block_x+=4)
{
pic_pix_x = img->opix_x + block_x;
if (direct_pdir[pic_pix_y>>2][pic_pix_x>>2]<0)
{
*cost8x8=INT_MAX;
return INT_MAX; //mode not allowed
}
//===== prediction of 4x4 block =====
LumaPrediction4x4 (block_x, block_y, direct_pdir[pic_pix_y>>2][pic_pix_x>>2], 0, 0,
direct_ref_idx[LIST_0][pic_pix_y>>2][pic_pix_x>>2],
direct_ref_idx[LIST_1][pic_pix_y>>2][pic_pix_x>>2]);
//===== get displaced frame difference ======
for (k=j=0; j<4; j++)
for (i=0; i<4; i++, k++)
{
diff[k] = curr_diff[block_y-mb_y+j][block_x-mb_x+i] =
imgY_org[pic_pix_y+j][pic_pix_x+i] - img->mpr[j+block_y][i+block_x];
}
cost += distortion4x4 (diff);
}
}
if((input->rdopt==0)&&(input->Transform8x8Mode))
{
k=0;
for(j=0; j<8; j++, k+=8)
memcpy(&diff64[k], &(curr_diff[j]), 8 * sizeof(int));
*cost8x8 += distortion8x8 (diff64);
}
return cost;
}
/*!
************************************************************************
* \brief
* Get cost for direct mode for an macroblock
************************************************************************
*/
int GetDirectCostMB (void)
{
int i;
int cost = 0;
int cost8x8 = 0;
for (i=0; i<4; i++)
{
cost += GetDirectCost8x8 (i, &cost8x8);
if (cost8x8 == INT_MAX) return INT_MAX;
}
switch(input->Transform8x8Mode)
{
case 1: // Mixture of 8x8 & 4x4 transform
if((cost8x8 < cost)||
!(input->InterSearch8x4 &&
input->InterSearch4x8 &&
input->InterSearch4x4)
)
{
cost = cost8x8; //return 8x8 cost
}
break;
case 2: // 8x8 Transform only
cost = cost8x8;
break;
default: // 4x4 Transform only
break;
}
return cost;
// T.Nishi(MEI ACC) 04-28-2004 end
}
/*!
************************************************************************
* \brief
* Motion search for a partition
************************************************************************
*/
void
PartitionMotionSearch (int blocktype,
int block8x8,
int *lambda_factor)
{
static int bx0[5][4] = {{0,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,2,0,0}, {0,2,0,2}};
static int by0[5][4] = {{0,0,0,0}, {0,0,0,0}, {0,2,0,0}, {0,0,0,0}, {0,0,2,2}};
char **ref_array;
short ***mv_array;
short *all_mv;
short ref;
int v, h, mcost, search_range, i, j;
int pic_block_x, pic_block_y;
int bslice = (img->type==B_SLICE);
int parttype = (blocktype<4?blocktype:4);
int step_h0 = (input->part_size[ parttype][0]);
int step_v0 = (input->part_size[ parttype][1]);
int step_h = (input->part_size[blocktype][0]);
int step_v = (input->part_size[blocktype][1]);
int list;
int numlists = bslice ? 2 : 1;
int list_offset = img->mb_data[img->current_mb_nr].list_offset;
int *m_cost;
int by = by0[parttype][block8x8];
int bx = bx0[parttype][block8x8];
//===== LOOP OVER REFERENCE FRAMES =====
for (list=0; list<numlists;list++)
{
for (ref=0; ref < listXsize[list+list_offset]; ref++)
{
m_cost = &motion_cost[blocktype][list][ref][block8x8];
//----- set search range ---
if (input->full_search == 2)
search_range = input->search_range;
else if (input->full_search == 1)
search_range = input->search_range / (imin(ref,1)+1);
else
search_range = input->search_range / ((imin(ref,1)+1) * imin(2,blocktype));
//----- set arrays -----
ref_array = enc_picture->ref_idx[list];
mv_array = enc_picture->mv[list];
//----- init motion cost -----
//motion_cost[blocktype][list][ref][block8x8] = 0;
*m_cost = 0;
//===== LOOP OVER SUB MACRO BLOCK partitions
for (v=by; v<by + step_v0; v += step_v)
{
pic_block_y = img->block_y + v;
for (h=bx; h<bx+step_h0; h+=step_h)
{
all_mv = img->all_mv[v][h][list][ref][blocktype];
pic_block_x = img->block_x + h;
//--- motion search for block ---
mcost = BlockMotionSearch (ref, list, h<<2, v<<2, blocktype, search_range, lambda_factor);
*m_cost += mcost;
//--- set motion vectors and reference frame (for motion vector prediction) ---
for (j=pic_block_y; j<pic_block_y + step_v; j++)
{
memset(&ref_array [j][pic_block_x], ref, step_h * sizeof(char));
for (i=pic_block_x; i<pic_block_x + step_h; i++)
{
memcpy(mv_array [j][i], all_mv, 2* sizeof(short));
}
}
}
}
}
}
}
/*!
************************************************************************
* \brief
* Calculate Direct Motion Vectors *****
************************************************************************
*/
void Get_Direct_Motion_Vectors ()
{
int block_x, block_y, pic_block_x, pic_block_y, opic_block_x, opic_block_y;
short ****all_mvs;
int mv_scale;
int refList;
int ref_idx;
byte ** moving_block;
short **** co_located_mv;
char *** co_located_ref_idx;
int64 *** co_located_ref_id;
char ** ref_pic_l0 = enc_picture->ref_idx[LIST_0];
char ** ref_pic_l1 = enc_picture->ref_idx[LIST_1];
Macroblock *currMB = &img->mb_data[img->current_mb_nr];
if (currMB->list_offset)
{
if(img->current_mb_nr%2)
{
moving_block = Co_located->bottom_moving_block;
co_located_mv = Co_located->bottom_mv;
co_located_ref_idx = Co_located->bottom_ref_idx;
co_located_ref_id = Co_located->bottom_ref_pic_id;
}
else
{
moving_block = Co_located->top_moving_block;
co_located_mv = Co_located->top_mv;
co_located_ref_idx = Co_located->top_ref_idx;
co_located_ref_id = Co_located->top_ref_pic_id;
}
}
else
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -