📄 mv_competition.c
字号:
colocated_MV_y = mv_previous_B_frame[LIST_1][y*4+block_y][x*4+block_x][1];
*pmv_x = -((b_frame_to_code + 1))*colocated_MV_x / (successive_Bframe+1-((b_frame_to_code + 1)-1));
*pmv_y = -((b_frame_to_code + 1))*colocated_MV_y / (successive_Bframe+1-((b_frame_to_code + 1)-1));
if ((collocated_mv_available(y, x, LIST_1) == TRUE) && (ref_frame != 0))
{
*pmv_x = *pmv_x + (ref_frame*listX[LIST_1][0]->mv[LIST_0][y*4+block_y][x*4+block_x][0] / (listX[LIST_1][0]->ref_idx[0][y*4+block_y][x*4+block_x] + 1));
*pmv_y = *pmv_y + (ref_frame*listX[LIST_1][0]->mv[LIST_0][y*4+block_y][x*4+block_x][1] / (listX[LIST_1][0]->ref_idx[0][y*4+block_y][x*4+block_x] + 1));
}
}
else
{
if (collocated_mv_available_previous_B_frame(y, x, LIST_0) == TRUE)
{
colocated_MV_x = ((b_frame_to_code + 1)-1) * mv_previous_B_frame[LIST_0][y*4+block_y][x*4+block_x][0] / (ref_idx_previous_B_frame[LIST_0][y*4+block_y][x*4+block_x] * (successive_Bframe+1) + ((b_frame_to_code + 1)-1));
colocated_MV_y = ((b_frame_to_code + 1)-1) * mv_previous_B_frame[LIST_0][y*4+block_y][x*4+block_x][1] / (ref_idx_previous_B_frame[LIST_0][y*4+block_y][x*4+block_x] * (successive_Bframe+1) + ((b_frame_to_code + 1)-1));
*pmv_x = ((b_frame_to_code + 1))*colocated_MV_x / ((b_frame_to_code + 1)-1);
*pmv_y = ((b_frame_to_code + 1))*colocated_MV_y / ((b_frame_to_code + 1)-1);
if ((collocated_mv_available(y, x, LIST_1) == TRUE) && (ref_frame != 0))
{
*pmv_x = *pmv_x + (ref_frame*listX[LIST_1][0]->mv[LIST_0][y*4+block_y][x*4+block_x][0] / (listX[LIST_1][0]->ref_idx[0][y*4+block_y][x*4+block_x] + 1));
*pmv_y = *pmv_y + (ref_frame*listX[LIST_1][0]->mv[LIST_0][y*4+block_y][x*4+block_x][1] / (listX[LIST_1][0]->ref_idx[0][y*4+block_y][x*4+block_x] + 1));
}
}
else
{
*pmv_x = 0;
*pmv_y = 0;
}
}
}
}
else
{//LIST_1
if((b_frame_to_code)==0)//if this B_frame is the first B_frame of the GOP
{
if (collocated_mv_available(y, x, LIST_1) == TRUE)
{
colocated_MV_x = listX[LIST_1][0]->mv[LIST_0][y*4+block_y][x*4+block_x][0] * (ref_frame+1) / (listX[LIST_1][0]->ref_idx[0][y*4+block_y][x*4+block_x] + 1);
colocated_MV_y = listX[LIST_1][0]->mv[LIST_0][y*4+block_y][x*4+block_x][1] * (ref_frame+1) / (listX[LIST_1][0]->ref_idx[0][y*4+block_y][x*4+block_x] + 1);
*pmv_x = -successive_Bframe*colocated_MV_x/(successive_Bframe+1);
*pmv_y = -successive_Bframe*colocated_MV_y/(successive_Bframe+1);
}
else
{
*pmv_x = 0;
*pmv_y = 0;
}
}
else
{
if (collocated_mv_available_previous_B_frame(y, x, LIST_1) == TRUE)
{
colocated_MV_x = mv_previous_B_frame[LIST_1][y*4+block_y][x*4+block_x][0];
colocated_MV_y = mv_previous_B_frame[LIST_1][y*4+block_y][x*4+block_x][1];
*pmv_x = (successive_Bframe+1-(b_frame_to_code + 1))*colocated_MV_x / (successive_Bframe+1-((b_frame_to_code + 1)-1));
*pmv_y = (successive_Bframe+1-(b_frame_to_code + 1))*colocated_MV_y / (successive_Bframe+1-((b_frame_to_code + 1)-1));
}
else
{
if (collocated_mv_available_previous_B_frame(y, x, LIST_0) == TRUE)
{
colocated_MV_x = ((b_frame_to_code + 1)-1) * mv_previous_B_frame[LIST_0][y*4+block_y][x*4+block_x][0] / (ref_idx_previous_B_frame[LIST_0][y*4+block_y][x*4+block_x] * (successive_Bframe+1) + ((b_frame_to_code + 1)-1));
colocated_MV_y = ((b_frame_to_code + 1)-1) * mv_previous_B_frame[LIST_0][y*4+block_y][x*4+block_x][1] / (ref_idx_previous_B_frame[LIST_0][y*4+block_y][x*4+block_x] * (successive_Bframe+1) + ((b_frame_to_code + 1)-1));
*pmv_x = -(successive_Bframe+1-(b_frame_to_code + 1))*colocated_MV_x / ((b_frame_to_code + 1)-1);
*pmv_y = -(successive_Bframe+1-(b_frame_to_code + 1))*colocated_MV_y / ((b_frame_to_code + 1)-1);
}
else
{
*pmv_x = 0;
*pmv_y = 0;
}
}
}
}
}
void Copy_MV_B_frame(short **** mv, char *** ref_idx)
{
int i, j;
for(i=0;i<img->height/4;i+=1)
{
for(j=0;j<img->width/4;j+=1)
{
mv_previous_B_frame[LIST_0][i][j][0] = mv[LIST_0][i][j][0];
mv_previous_B_frame[LIST_0][i][j][1] = mv[LIST_0][i][j][1];
ref_idx_previous_B_frame[LIST_0][i][j] = ref_idx[LIST_0][i][j];
mv_previous_B_frame[LIST_1][i][j][0] = mv[LIST_1][i][j][0];
mv_previous_B_frame[LIST_1][i][j][1] = mv[LIST_1][i][j][1];
ref_idx_previous_B_frame[LIST_1][i][j] = ref_idx[LIST_1][i][j];
}
}
}
/*!
************************************************************************
* \brief
* Set motion vector predictor
************************************************************************
*/
void SetMotionVectorPredictor_Skip (short *pmv_x, short *pmv_y, char ***refPic, short ****tmp_mv, short ref_frame,
int list, int block_x, int block_y, int blockshape_x, int blockshape_y,
short mode_skip)
{
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;
// int i=(int)img->current_mb_nr/(img->width/16);
// int j=(int)img->current_mb_nr%(img->width/16);
Macroblock *currMB = &img->mb_data[img->current_mb_nr];
PixelPos block_a, block_b, block_c, block_d;
int mb_nr = img->current_mb_nr;
getLuma4x4Neighbour(mb_nr, block_x, block_y, -1, 0, &block_a);
getLuma4x4Neighbour(mb_nr, block_x, block_y, 0, -1, &block_b);
getLuma4x4Neighbour(mb_nr, block_x, block_y, blockshape_x, -1, &block_c);
getLuma4x4Neighbour(mb_nr, block_x, block_y, -1, -1, &block_d);
// Same as in the original JM... might not be optimal
if (mv_comp.predictor_for_skip[mode_skip] == PRED_H264_MEDIAN)
{
if (block_a.available)
{
a_mv_y = dec_picture->mv[LIST_0][block_a.pos_y][block_a.pos_x][1];
a_ref_idx = dec_picture->ref_idx[LIST_0][block_a.pos_y][block_a.pos_x];
if (currMB->mb_field && !img->mb_data[block_a.mb_addr].mb_field)
{
a_mv_y /=2;
a_ref_idx *=2;
}
if (!currMB->mb_field && img->mb_data[block_a.mb_addr].mb_field)
{
a_mv_y *=2;
a_ref_idx >>=1;
}
}
if (block_b.available)
{
b_mv_y = dec_picture->mv[LIST_0][block_b.pos_y][block_b.pos_x][1];
b_ref_idx = dec_picture->ref_idx[LIST_0][block_b.pos_y][block_b.pos_x];
if (currMB->mb_field && !img->mb_data[block_b.mb_addr].mb_field)
{
b_mv_y /=2;
b_ref_idx *=2;
}
if (!currMB->mb_field && img->mb_data[block_b.mb_addr].mb_field)
{
b_mv_y *=2;
b_ref_idx >>=1;
}
}
zeroMotionLeft = !block_a.available ? 1 : a_ref_idx==0 && dec_picture->mv[LIST_0][block_a.pos_y][block_a.pos_x][0]==0 && a_mv_y==0 ? 1 : 0;
zeroMotionAbove = !block_b.available ? 1 : b_ref_idx==0 && dec_picture->mv[LIST_0][block_b.pos_y][block_b.pos_x][0]==0 && b_mv_y==0 ? 1 : 0;
if (zeroMotionAbove || zeroMotionLeft)
{
*pmv_x = 0;
*pmv_y = 0;
}
else
{
SetMotionVectorPredictor (img, pmv_x, pmv_y, 0, LIST_0, dec_picture->ref_idx, dec_picture->mv, 0, 0, 16, 16);
}
}
else if (mv_comp.predictor_for_skip[mode_skip] == PRED_A)
{
if (block_a.available) /*&& (img->mb_data[img->current_mb_nr-1].mb_type<9))*/
{
*pmv_x = dec_picture->mv[LIST_0][block_a.pos_y][block_a.pos_x][0];
*pmv_y = dec_picture->mv[LIST_0][block_a.pos_y][block_a.pos_x][1];
}
else
{
*pmv_x = NOT_AVAILABLE;
*pmv_y = NOT_AVAILABLE;
}
}
else if (mv_comp.predictor_for_skip[mode_skip] == PRED_B)
{
if (block_b.available) /*&& (img->mb_data[img->current_mb_nr-1].mb_type<9))*/
{
*pmv_x = dec_picture->mv[LIST_0][block_b.pos_y][block_b.pos_x][0];
*pmv_y = dec_picture->mv[LIST_0][block_b.pos_y][block_b.pos_x][1];
}
else
{
*pmv_x = NOT_AVAILABLE;
*pmv_y = NOT_AVAILABLE;
}
}
else if (mv_comp.predictor_for_skip[mode_skip] == PRED_C)
{
if (block_c.available) /*&& (img->mb_data[img->current_mb_nr-1].mb_type<9))*/
{
*pmv_x = dec_picture->mv[LIST_0][block_c.pos_y][block_c.pos_x][0];
*pmv_y = dec_picture->mv[LIST_0][block_c.pos_y][block_c.pos_x][1];
}
else
{
*pmv_x = NOT_AVAILABLE;
*pmv_y = NOT_AVAILABLE;
}
}
else if (mv_comp.predictor_for_skip[mode_skip] == PRED_ZERO)
{
*pmv_x = 0;
*pmv_y = 0;
}
else if (mv_comp.predictor_for_skip[mode_skip] == PRED_COLOCATED)
{
int y=(int)img->current_mb_nr/(img->width/16); // Vertical
int x=(int)img->current_mb_nr%(img->width/16); // Horizontal
if (collocated_mv_available(y, x, LIST_0) == TRUE)
{
*pmv_x = listX[0][0]->mv[LIST_0][y*4][x*4][0] / (listX[0][0]->ref_idx[0][y*4][x*4] + 1);
*pmv_y = listX[0][0]->mv[LIST_0][y*4][x*4][1] / (listX[0][0]->ref_idx[0][y*4][x*4] + 1);
}
else
{
*pmv_x = NOT_AVAILABLE;
*pmv_y = NOT_AVAILABLE;
}
}
else if (mv_comp.predictor_for_skip[mode_skip] == PRED_EXTENDEDSPATIAL)
{
int mv_a, mv_b, mv_c;
if ((block_a.available) && (block_b.available) && (block_c.available))
{
mv_a = dec_picture->mv[LIST_0][block_a.pos_y][block_a.pos_x][0];
mv_b = dec_picture->mv[LIST_0][block_b.pos_y][block_b.pos_x][0];
mv_c = dec_picture->mv[LIST_0][block_c.pos_y][block_c.pos_x][0];
*pmv_x = mv_a+mv_b+mv_c-min(mv_a,min(mv_b,mv_c))-max(mv_a,max(mv_b,mv_c));
mv_a = dec_picture->mv[LIST_0][block_a.pos_y][block_a.pos_x][1];
mv_b = dec_picture->mv[LIST_0][block_b.pos_y][block_b.pos_x][1];
mv_c = dec_picture->mv[LIST_0][block_c.pos_y][block_c.pos_x][1];
*pmv_y = mv_a+mv_b+mv_c-min(mv_a,min(mv_b,mv_c))-max(mv_a,max(mv_b,mv_c));
}
else if (block_a.available)
{
*pmv_x = dec_picture->mv[LIST_0][block_a.pos_y][block_a.pos_x][0];
*pmv_y = dec_picture->mv[LIST_0][block_a.pos_y][block_a.pos_x][1];
}
else if (block_b.available)
{
*pmv_x = dec_picture->mv[LIST_0][block_b.pos_y][block_b.pos_x][0];
*pmv_y = dec_picture->mv[LIST_0][block_b.pos_y][block_b.pos_x][1];
}
else if (block_c.available)
{
*pmv_x = dec_picture->mv[LIST_0][block_c.pos_y][block_c.pos_x][0];
*pmv_y = dec_picture->mv[LIST_0][block_c.pos_y][block_c.pos_x][1];
}
else
{
*pmv_x = 0;
*pmv_y = 0;
}
}
}
// <FTRD : Compatibility with hierarchical B frames
void init_mvscale_hb()
{
int i, j, k, l;
int iTRb = 0 ; int iTRp = 0;
int prescale = 0;
int num_ref_max = 0;
//printf("Encoding picture : %d\n",dec_picture->poc/2);
//printf("[point_list_cur_B] [ref_num_B] [point_list_coloc] [ref_num_coloc] [mv_scale]\n");
// Mv in current B frame points to LIST_0 or LIST_1
for(i = 0 ; i < 2 ; i++)
{
for(k = 0 ; k <listXsize[i] ; k++)
{
iTRb = Clip3(-128, 127, dec_picture->poc - listX[i][k]->poc);
// The colocated vector points to LIST_0 or LIST_1
for(j=0;j<2;j++)
{
if(listX[LIST_1][0]->slice_type == B_SLICE)
{
if(j==0) num_ref_max = img->num_ref_idx_l0_active;
if(j==1) num_ref_max = img->num_ref_idx_l0_active;
}
if(listX[LIST_1][0]->slice_type == P_SLICE)
{
num_ref_max = dpb.num_ref_frames;
}
for(l = 0 ; l < num_ref_max ; l++)
{
iTRp = (int)Clip3(-128, 127, listX[LIST_1][0]->poc - (listX[LIST_1][0]->ref_pic_num[0][j][l]/2));
if(iTRp==0) img->mvscale_hb[i][j][k][l]=9999;
else
{
prescale=(16384 + absm(iTRp/2))/iTRp;
//printf("B = %d , ref_B = %d , colc = %d , ref_col = %d\n",enc_picture->poc/2,
img->mvscale_hb[i][j][k][l] = Clip3(-2048, 2047,(iTRb*prescale + 32) >> 6);
//printf("LIST_%d %d LIST_%d %d %f\n",i,k,j,l,(float)iTRb/(float)iTRp);
}
}
}
}
}
}
// FTRD>
// <FTRD : Compatibility with hierarchical B frames
void SetMotionVectorPredictor_collocated_HB_SLICE (short *pmv_x,short *pmv_y,int y,int x,int list,int ref_frame,int block_y,int block_x)
{
int colocated_MV_x = 0, colocated_MV_y = 0;
int ref_frame_coloc = 0;
*pmv_x = 0;
*pmv_y = 0;
// printf("%d, %d\n",listX[LIST_1][0]->ref_idx[LIST_0][y*4+block_y][x*4+block_x],listX[LIST_1][0]->ref_idx[LIST_1][y*4+block_y][x*4+block_x]);
// B frame mv points to LIST_0
if(list == LIST_0)
{
// If colocated mv points to LIST_0
if(listX[LIST_1][0]->ref_idx[LIST_0][y*4+block_y][x*4+block_x] != -1)
{
colocated_MV_x = listX[LIST_1][0]->mv[LIST_0][y*4+block_y][x*4+block_x][0];
colocated_MV_y = listX[LIST_1][0]->mv[LIST_0][y*4+block_y][x*4+block_x][1];
ref_frame_coloc = listX[LIST_1][0]->ref_idx[LIST_0][y*4+block_y][x*4+block_x];
// Scaling
*pmv_x = (img->mvscale_hb[LIST_0][LIST_0][ref_frame][ref_frame_coloc] * colocated_MV_x + 128) >> 8;
*pmv_y = (img->mvscale_hb[LIST_0][LIST_0][ref_frame][ref_frame_coloc] * colocated_MV_y + 128) >> 8;
}
else
{
// If colocated mv points to LIST_1
if(listX[LIST_1][0]->ref_idx[LIST_1][y*4+block_y][x*4+block_x] != -1)
{
colocated_MV_x = listX[LIST_1][0]->mv[LIST_1][y*4+block_y][x*4+block_x][0];
colocated_MV_y = listX[LIST_1][0]->mv[LIST_1][y*4+block_y][x*4+block_x][1];
ref_frame_coloc = listX[LIST_1][0]->ref_idx[LIST_1][y*4+block_y][x*4+block_x];
// Scaling
*pmv_x = (img->mvscale_hb[LIST_0][LIST_1][ref_frame][ref_frame_coloc] * colocated_MV_x + 128) >> 8;
*pmv_y = (img->mvscale_hb[LIST_0][LIST_1][ref_frame][ref_frame_coloc] * colocated_MV_y + 128) >> 8;
}
// No colocated mv is available.
else
{
*pmv_x = 0;
*pmv_y = 0;
}
}
}
// B frame mv points to LIST_1
else
{
// If colocated mv points to LIST_0
if(listX[LIST_1][0]->ref_idx[LIST_0][y*4+block_y][x*4+block_x] != -1)
{
colocated_MV_x = listX[LIST_1][0]->mv[LIST_0][y*4+block_y][x*4+block_x][0];
colocated_MV_y = listX[LIST_1][0]->mv[LIST_0][y*4+block_y][x*4+block_x][1];
ref_frame_coloc = listX[LIST_1][0]->ref_idx[LIST_0][y*4+block_y][x*4+block_x];
// Scaling
*pmv_x = (img->mvscale_hb[LIST_1][LIST_0][ref_frame][ref_frame_coloc] * colocated_MV_x + 128) >> 8;
*pmv_y = (img->mvscale_hb[LIST_1][LIST_0][ref_frame][ref_frame_coloc] * colocated_MV_y + 128) >> 8;
}
else
{
// If colocated mv points to LIST_1
if(listX[LIST_1][0]->ref_idx[LIST_1][y*4+block_y][x*4+block_x] != -1)
{
colocated_MV_x = listX[LIST_1][0]->mv[LIST_1][y*4+block_y][x*4+block_x][0];
colocated_MV_y = listX[LIST_1][0]->mv[LIST_1][y*4+block_y][x*4+block_x][1];
ref_frame_coloc = listX[LIST_1][0]->ref_idx[LIST_1][y*4+block_y][x*4+block_x];
// Scaling
*pmv_x = (img->mvscale_hb[LIST_1][LIST_1][ref_frame][ref_frame_coloc] * colocated_MV_x + 128) >> 8;
*pmv_y = (img->mvscale_hb[LIST_1][LIST_1][ref_frame][ref_frame_coloc] * colocated_MV_y + 128) >> 8;
}
// No colocated mv is available.
else
{
*pmv_x = 0;
*pmv_y = 0;
}
}
}
}
// FTRD>
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -