📄 mv-search.c
字号:
{
moving_block = Co_located->moving_block;
co_located_mv = Co_located->mv;
co_located_ref_idx = Co_located->ref_idx;
co_located_ref_id = Co_located->ref_pic_id;
}
if (img->direct_spatial_mv_pred_flag) //spatial direct mode copy from decoder
{
short l0_refA, l0_refB, l0_refD, l0_refC;
short l1_refA, l1_refB, l1_refD, l1_refC;
short l0_refX,l1_refX;
short pmvfw[2]={0,0},pmvbw[2]={0,0};
PixelPos mb_a, mb_b, mb_d, mb_c;
getLuma4x4Neighbour(img->current_mb_nr, -1, 0,&mb_a);
getLuma4x4Neighbour(img->current_mb_nr, 0, -1,&mb_b);
getLuma4x4Neighbour(img->current_mb_nr, 16, -1,&mb_c);
getLuma4x4Neighbour(img->current_mb_nr, -1, -1,&mb_d);
if (!img->MbaffFrameFlag)
{
l0_refA = mb_a.available ? ref_pic_l0[mb_a.pos_y][mb_a.pos_x] : -1;
l0_refB = mb_b.available ? ref_pic_l0[mb_b.pos_y][mb_b.pos_x] : -1;
l0_refD = mb_d.available ? ref_pic_l0[mb_d.pos_y][mb_d.pos_x] : -1;
l0_refC = mb_c.available ? ref_pic_l0[mb_c.pos_y][mb_c.pos_x] : l0_refD;
l1_refA = mb_a.available ? ref_pic_l1[mb_a.pos_y][mb_a.pos_x] : -1;
l1_refB = mb_b.available ? ref_pic_l1[mb_b.pos_y][mb_b.pos_x] : -1;
l1_refD = mb_d.available ? ref_pic_l1[mb_d.pos_y][mb_d.pos_x] : -1;
l1_refC = mb_c.available ? ref_pic_l1[mb_c.pos_y][mb_c.pos_x] : l1_refD;
}
else
{
if (currMB->mb_field)
{
l0_refA = mb_a.available
? (img->mb_data[mb_a.mb_addr].mb_field || ref_pic_l0[mb_a.pos_y][mb_a.pos_x] < 0
? ref_pic_l0[mb_a.pos_y][mb_a.pos_x]
: ref_pic_l0[mb_a.pos_y][mb_a.pos_x] * 2) : -1;
l0_refB = mb_b.available
? (img->mb_data[mb_b.mb_addr].mb_field || ref_pic_l0[mb_b.pos_y][mb_b.pos_x] < 0
? ref_pic_l0[mb_b.pos_y][mb_b.pos_x]
: ref_pic_l0[mb_b.pos_y][mb_b.pos_x] * 2) : -1;
l0_refD = mb_d.available
? (img->mb_data[mb_d.mb_addr].mb_field || ref_pic_l0[mb_d.pos_y][mb_d.pos_x] < 0
? ref_pic_l0[mb_d.pos_y][mb_d.pos_x]
: ref_pic_l0[mb_d.pos_y][mb_d.pos_x] * 2) : -1;
l0_refC = mb_c.available
? (img->mb_data[mb_c.mb_addr].mb_field || ref_pic_l0[mb_c.pos_y][mb_c.pos_x] < 0
? ref_pic_l0[mb_c.pos_y][mb_c.pos_x]
: ref_pic_l0[mb_c.pos_y][mb_c.pos_x] * 2) : l0_refD;
l1_refA = mb_a.available
? (img->mb_data[mb_a.mb_addr].mb_field || ref_pic_l1[mb_a.pos_y][mb_a.pos_x] < 0
? ref_pic_l1[mb_a.pos_y][mb_a.pos_x]
: ref_pic_l1[mb_a.pos_y][mb_a.pos_x] * 2) : -1;
l1_refB = mb_b.available
? (img->mb_data[mb_b.mb_addr].mb_field || ref_pic_l1[mb_b.pos_y][mb_b.pos_x] < 0
? ref_pic_l1[mb_b.pos_y][mb_b.pos_x]
: ref_pic_l1[mb_b.pos_y][mb_b.pos_x] * 2) : -1;
l1_refD = mb_d.available
? (img->mb_data[mb_d.mb_addr].mb_field || ref_pic_l1[mb_d.pos_y][mb_d.pos_x] < 0
? ref_pic_l1[mb_d.pos_y][mb_d.pos_x]
: ref_pic_l1[mb_d.pos_y][mb_d.pos_x] * 2) : -1;
l1_refC = mb_c.available
? (img->mb_data[mb_c.mb_addr].mb_field || ref_pic_l1[mb_c.pos_y][mb_c.pos_x] < 0
? ref_pic_l1[mb_c.pos_y][mb_c.pos_x]
: ref_pic_l1[mb_c.pos_y][mb_c.pos_x] * 2) : l1_refD;
}
else
{
l0_refA = mb_a.available
? (img->mb_data[mb_a.mb_addr].mb_field || ref_pic_l0[mb_a.pos_y][mb_a.pos_x] < 0
? ref_pic_l0[mb_a.pos_y][mb_a.pos_x] >> 1
: ref_pic_l0[mb_a.pos_y][mb_a.pos_x]) : -1;
l0_refB = mb_b.available
? (img->mb_data[mb_b.mb_addr].mb_field || ref_pic_l0[mb_b.pos_y][mb_b.pos_x] < 0
? ref_pic_l0[mb_b.pos_y][mb_b.pos_x] >> 1
: ref_pic_l0[mb_b.pos_y][mb_b.pos_x]) : -1;
l0_refD = mb_d.available
? (img->mb_data[mb_d.mb_addr].mb_field || ref_pic_l0[mb_d.pos_y][mb_d.pos_x] < 0
? ref_pic_l0[mb_d.pos_y][mb_d.pos_x] >> 1
: ref_pic_l0[mb_d.pos_y][mb_d.pos_x]) : -1;
l0_refC = mb_c.available
? (img->mb_data[mb_c.mb_addr].mb_field || ref_pic_l0[mb_c.pos_y][mb_c.pos_x] < 0
? ref_pic_l0[mb_c.pos_y][mb_c.pos_x] >> 1
: ref_pic_l0[mb_c.pos_y][mb_c.pos_x]) : l0_refD;
l1_refA = mb_a.available
? (img->mb_data[mb_a.mb_addr].mb_field || ref_pic_l1[mb_a.pos_y][mb_a.pos_x] < 0
? ref_pic_l1[mb_a.pos_y][mb_a.pos_x] >> 1
: ref_pic_l1[mb_a.pos_y][mb_a.pos_x]) : -1;
l1_refB = mb_b.available
? (img->mb_data[mb_b.mb_addr].mb_field || ref_pic_l1[mb_b.pos_y][mb_b.pos_x] < 0
? ref_pic_l1[mb_b.pos_y][mb_b.pos_x] >> 1
: ref_pic_l1[mb_b.pos_y][mb_b.pos_x]) : -1;
l1_refD = mb_d.available
? (img->mb_data[mb_d.mb_addr].mb_field || ref_pic_l1[mb_d.pos_y][mb_d.pos_x] < 0
? ref_pic_l1[mb_d.pos_y][mb_d.pos_x] >> 1
: ref_pic_l1[mb_d.pos_y][mb_d.pos_x]) : -1;
l1_refC = mb_c.available
? (img->mb_data[mb_c.mb_addr].mb_field || ref_pic_l1[mb_c.pos_y][mb_c.pos_x] < 0
? ref_pic_l1[mb_c.pos_y][mb_c.pos_x] >> 1
: ref_pic_l1[mb_c.pos_y][mb_c.pos_x]) : l1_refD;
}
}
l0_refX = (l0_refA >= 0 && l0_refB >= 0) ? imin(l0_refA,l0_refB): imax(l0_refA,l0_refB);
l0_refX = (l0_refX >= 0 && l0_refC >= 0) ? imin(l0_refX,l0_refC): imax(l0_refX,l0_refC);
l1_refX = (l1_refA >= 0 && l1_refB >= 0) ? imin(l1_refA,l1_refB): imax(l1_refA,l1_refB);
l1_refX = (l1_refX >= 0 && l1_refC >= 0) ? imin(l1_refX,l1_refC): imax(l1_refX,l1_refC);
if (l0_refX >=0)
SetMotionVectorPredictor (pmvfw, enc_picture->ref_idx[LIST_0], enc_picture->mv[LIST_0], l0_refX, LIST_0, 0, 0, 16, 16);
if (l1_refX >=0)
SetMotionVectorPredictor (pmvbw, enc_picture->ref_idx[LIST_1], enc_picture->mv[LIST_1], l1_refX, LIST_1, 0, 0, 16, 16);
for (block_y=0; block_y<4; block_y++)
{
pic_block_y = (img->pix_y >> 2) + block_y;
opic_block_y = (img->opix_y >> 2) + block_y;
for (block_x=0; block_x<4; block_x++)
{
pic_block_x = (img->pix_x >> 2) + block_x;
opic_block_x = (img->opix_x >> 2) + block_x;
all_mvs = img->all_mv[block_y][block_x];
if (l0_refX >=0)
{
if (!l0_refX && !moving_block[opic_block_y][opic_block_x])
{
memset(all_mvs[LIST_0][0][0], 0, 2* sizeof(short));
direct_ref_idx[LIST_0][pic_block_y][pic_block_x]=0;
}
else
{
all_mvs[LIST_0][l0_refX][0][0] = pmvfw[0];
all_mvs[LIST_0][l0_refX][0][1] = pmvfw[1];
direct_ref_idx[LIST_0][pic_block_y][pic_block_x]= (char)l0_refX;
}
}
else
{
all_mvs[LIST_0][0][0][0] = 0;
all_mvs[LIST_0][0][0][1] = 0;
direct_ref_idx[LIST_0][pic_block_y][pic_block_x]=-1;
}
if (l1_refX >=0)
{
if(l1_refX==0 && !moving_block[opic_block_y][opic_block_x])
{
all_mvs[LIST_1][0][0][0] = 0;
all_mvs[LIST_1][0][0][1] = 0;
direct_ref_idx[LIST_1][pic_block_y][pic_block_x]= (char)l1_refX;
}
else
{
all_mvs[LIST_1][l1_refX][0][0] = pmvbw[0];
all_mvs[LIST_1][l1_refX][0][1] = pmvbw[1];
direct_ref_idx[LIST_1][pic_block_y][pic_block_x]= (char)l1_refX;
}
}
else
{
direct_ref_idx[LIST_1][pic_block_y][pic_block_x]=-1;
all_mvs[LIST_1][0][0][0] = 0;
all_mvs[LIST_1][0][0][1] = 0;
}
// Test Level Limits if satisfied.
if (img->MbaffFrameFlag
&& (all_mvs[LIST_0][l0_refX < 0? 0 : l0_refX][0][0] < -8192
|| all_mvs[LIST_0][l0_refX < 0? 0 : l0_refX][0][0] > 8191
|| all_mvs[LIST_0][l0_refX < 0? 0 : l0_refX][0][1] < LEVELMVLIMIT[img->LevelIndex][4]
|| all_mvs[LIST_0][l0_refX < 0? 0 : l0_refX][0][1] > LEVELMVLIMIT[img->LevelIndex][5]
|| all_mvs[LIST_1][l1_refX < 0? 0 : l1_refX][0][0] < -8192
|| all_mvs[LIST_1][l1_refX < 0? 0 : l1_refX][0][0] > 8191
|| all_mvs[LIST_1][l1_refX < 0? 0 : l1_refX][0][1] < LEVELMVLIMIT[img->LevelIndex][4]
|| all_mvs[LIST_1][l1_refX < 0? 0 : l1_refX][0][1] > LEVELMVLIMIT[img->LevelIndex][5]))
{
direct_ref_idx[LIST_0][pic_block_y][pic_block_x] = -1;
direct_ref_idx[LIST_1][pic_block_y][pic_block_x] = -1;
direct_pdir [pic_block_y][pic_block_x] = -1;
}
else
{
if (l0_refX < 0 && l1_refX < 0)
{
direct_ref_idx[LIST_0][pic_block_y][pic_block_x] =
direct_ref_idx[LIST_1][pic_block_y][pic_block_x] = 0;
l0_refX = 0;
l1_refX = 0;
}
if (direct_ref_idx[LIST_1][pic_block_y][pic_block_x] == -1)
direct_pdir[pic_block_y][pic_block_x] = 0;
else if (direct_ref_idx[LIST_0][pic_block_y][pic_block_x] == -1)
direct_pdir[pic_block_y][pic_block_x] = 1;
else if (active_pps->weighted_bipred_idc == 1)
{
int weight_sum, i;
Boolean invalid_wp = FALSE;
for (i=0;i< (active_sps->chroma_format_idc == YUV400 ? 1 : 3); i++)
{
weight_sum = wbp_weight[0][l0_refX][l1_refX][i] + wbp_weight[1][l0_refX][l1_refX][i];
if (weight_sum < -128 || weight_sum > 127)
{
invalid_wp = TRUE;
break;
}
}
if (invalid_wp == FALSE)
direct_pdir[pic_block_y][pic_block_x] = 2;
else
{
direct_ref_idx[LIST_0][pic_block_y][pic_block_x] = -1;
direct_ref_idx[LIST_1][pic_block_y][pic_block_x] = -1;
direct_pdir [pic_block_y][pic_block_x] = -1;
}
}
else
direct_pdir[pic_block_y][pic_block_x] = 2;
}
}
}
}
else
{
int64 *refpic = enc_picture->ref_pic_num[LIST_0 +currMB->list_offset];
//temporal direct mode copy from decoder
for (block_y = 0; block_y < 4; block_y++)
{
pic_block_y = (img->pix_y >> 2) + block_y;
opic_block_y = (img->opix_y >> 2) + block_y;
for (block_x = 0; block_x < 4; block_x++)
{
pic_block_x = (img->pix_x>>2) + block_x;
opic_block_x = (img->opix_x>>2) + block_x;
all_mvs = img->all_mv[block_y][block_x];
refList = (co_located_ref_idx[LIST_0][opic_block_y][opic_block_x]== -1 ? LIST_1 : LIST_0);
ref_idx = co_located_ref_idx[refList][opic_block_y][opic_block_x];
// next P is intra mode
if (ref_idx==-1)
{
all_mvs[LIST_0][0][0][0] = 0;
all_mvs[LIST_0][0][0][1] = 0;
all_mvs[LIST_1][0][0][0] = 0;
all_mvs[LIST_1][0][0][1] = 0;
direct_ref_idx[LIST_0][pic_block_y][pic_block_x] = 0;
direct_ref_idx[LIST_1][pic_block_y][pic_block_x] = 0;
direct_pdir[pic_block_y][pic_block_x] = 2;
}
// next P is skip or inter mode
else
{
int mapped_idx=INVALIDINDEX;
int iref;
for (iref=0;iref<imin(img->num_ref_idx_l0_active,listXsize[LIST_0+currMB->list_offset]);iref++)
{
if (refpic[iref]==co_located_ref_id[refList ][opic_block_y][opic_block_x])
{
mapped_idx=iref;
break;
}
else //! invalid index. Default to zero even though this case should not happen
{
mapped_idx=INVALIDINDEX;
}
}
if (mapped_idx !=INVALIDINDEX)
{
mv_scale = img->mvscale[LIST_0+currMB->list_offset][mapped_idx];
if (mv_scale==9999)
{
// forward
all_mvs[LIST_0][0][0][0] = co_located_mv[refList][opic_block_y][opic_block_x][0];
all_mvs[LIST_0][0][0][1] = co_located_mv[refList][opic_block_y][opic_block_x][1];
// backward
all_mvs[LIST_1][0][0][0] = 0;
all_mvs[LIST_1][0][0][1] = 0;
}
else
{
// forward
all_mvs[LIST_0][mapped_idx][0][0] = (mv_scale * co_located_mv[refList][opic_block_y][opic_block_x][0] + 128) >> 8;
all_mvs[LIST_0][mapped_idx][0][1] = (mv_scale * co_located_mv[refList][opic_block_y][opic_block_x][1] + 128) >> 8;
// backward
all_mvs[LIST_1][ 0][0][0] = ((mv_scale - 256)* co_located_mv[refList][opic_block_y][opic_block_x][0] + 128) >> 8;
all_mvs[LIST_1][ 0][0][1] = ((mv_scale - 256)* co_located_mv[refList][opic_block_y][opic_block_x][1] + 128) >> 8;
}
// Test Level Limits if satisfied.
if ( all_mvs[LIST_0][mapped_idx][0][0] < -8192
|| all_mvs[LIST_0][mapped_idx][0][0] > 8191
|| all_mvs[LIST_0][mapped_idx][0][1] < LEVELMVLIMIT[img->LevelIndex][4]
|| all_mvs[LIST_0][mapped_idx][0][1] > LEVELMVLIMIT[img->LevelIndex][5]
|| all_mvs[LIST_1][0][0][0] < -8192
|| all_mvs[LIST_1][0][0][0] > 8191
|| all_mvs[LIST_1][0][0][1] < LEVELMVLIMIT[img->LevelIndex][4]
|| all_mvs[LIST_1][0][0][1] > LEVELMVLIMIT[img->LevelIndex][5])
{
direct_ref_idx[LIST_0][pic_block_y][pic_block_x] = -1;
direct_ref_idx[LIST_1][pic_block_y][pic_block_x] = -1;
direct_pdir[pic_block_y][pic_block_x] = -1;
}
else
{
direct_ref_idx[LIST_0][pic_block_y][pic_block_x] = mapped_idx;
direct_ref_idx[LIST_1][pic_block_y][pic_block_x] = 0;
direct_pdir[pic_block_y][pic_block_x] = 2;
}
}
else
{
direct_ref_idx[LIST_0][pic_block_y][pic_block_x] = -1;
direct_ref_idx[LIST_1][pic_block_y][pic_block_x] = -1;
direct_pdir[pic_block_y][pic_block_x] = -1;
}
}
if (active_pps->weighted_bipred_idc == 1 && direct_pdir[pic_block_y][pic_block_x] == 2)
{
int weight_sum, i;
short l0_refX = direct_ref_idx[LIST_0][pic_block_y][pic_block_x];
short l1_refX = direct_ref_idx[LIST_1][pic_block_y][pic_block_x];
for (i=0;i< (active_sps->chroma_format_idc == YUV400 ? 1 : 3); i++)
{
weight_sum = wbp_weight[0][l0_refX][l1_refX][i] + wbp_weight[1][l0_refX][l1_refX][i];
if (weight_sum < -128 || weight_sum > 127)
{
direct_ref_idx[LIST_0][pic_block_y][pic_block_x] = -1;
direct_ref_idx[LIST_1][pic_block_y][pic_block_x] = -1;
direct_pdir [pic_block_y][pic_block_x] = -1;
break;
}
}
}
}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -