📄 b_frame.c
字号:
{
block_available_up = mb_available_up || (j > 0);
j4=img->block_y+j;
for(i=0;i<4;i=i+BLOCK_STEP[blocktype][0]) // X position in 4-pel resolution
{
i4=img->block_x+i;
block_available_left = mb_available_left || (i > 0);
if (j > 0)
block_available_upright = i != ie ? 1 : 0;
else if (i != ie)
block_available_upright = block_available_up;
else
block_available_upright = mb_available_upright;
if (i > 0)
block_available_upleft = j > 0 ? 1 : block_available_up;
else if (j > 0)
block_available_upleft = block_available_left;
else
block_available_upleft = mb_available_upleft;
mvPredType = MVPRED_MEDIAN;
rFrameL = block_available_left ? img->fw_refFrArr[j4][i4-1] : -1;
rFrameU = block_available_up ? img->fw_refFrArr[j4-1][i4] : -1;
rFrameUR = block_available_upright ? img->fw_refFrArr[j4-1][i4+BLOCK_STEP[blocktype][0]] :
block_available_upleft ? img->fw_refFrArr[j4-1][i4-1] : -1;
// Prediction if only one of the neighbors uses the selected reference frame
if(rFrameL == fw_predframe_no && rFrameU != fw_predframe_no && rFrameUR != fw_predframe_no)
mvPredType = MVPRED_L;
else if(rFrameL != fw_predframe_no && rFrameU == fw_predframe_no && rFrameUR != fw_predframe_no)
mvPredType = MVPRED_U;
else if(rFrameL != fw_predframe_no && rFrameU != fw_predframe_no && rFrameUR == fw_predframe_no)
mvPredType = MVPRED_UR;
// Directional predictions
else if(blocktype == 3)
{
if(i == 0)
{
if(rFrameL == fw_predframe_no)
mvPredType = MVPRED_L;
}
else
{
if(rFrameUR == fw_predframe_no)
mvPredType = MVPRED_UR;
}
}
else if(blocktype == 2)
{
if(j == 0)
{
if(rFrameU == fw_predframe_no)
mvPredType = MVPRED_U;
}
else
{
if(rFrameL == fw_predframe_no)
mvPredType = MVPRED_L;
}
}
else if(blocktype == 5 && i == 2)
mvPredType = MVPRED_L;
else if(blocktype == 6 && j == 2)
mvPredType = MVPRED_U;
for (k=0;k<2;k++) // vector prediction. find first koordinate set for pred
{
mv_a = block_available_left ? img->fw_mv[i4-1+BLOCK_SIZE][j4][k] : 0;
mv_b = block_available_up ? img->fw_mv[i4+BLOCK_SIZE][j4-1][k] : 0;
mv_d = block_available_upleft ? img->fw_mv[i4-1+BLOCK_SIZE][j4-1][k] : 0;
mv_c = block_available_upright ? img->fw_mv[i4+BLOCK_STEP[blocktype][0]+BLOCK_SIZE][j4-1][k] : mv_d;
switch (mvPredType)
{
case MVPRED_MEDIAN:
if(!(block_available_upleft || block_available_up || block_available_upright))
pred_vec = mv_a;
else
pred_vec =mv_a+mv_b+mv_c-min(mv_a,min(mv_b,mv_c))-max(mv_a,max(mv_b,mv_c));
break;
case MVPRED_L:
pred_vec = mv_a;
break;
case MVPRED_U:
pred_vec = mv_b;
break;
case MVPRED_UR:
pred_vec = mv_c;
break;
default:
break;
}
#if TRACE
snprintf(currSE->tracestring, TRACESTRING_SIZE, " MVD(%d) ",k);
#endif
currSE->type = SE_MVD;
dp = &(currSlice->partArr[partMap[SE_BFRAME]]);
if (inp->symbol_mode == UVLC)
currSE->mapping = linfo_mvd; // linfo_2
else
{
img->subblock_x = i; // position used for context determination
img->subblock_y = j; // position used for context determination
currSE->value2 = 2*k; // identifies the component and the direction; only used for context determination
currSE->reading = readBiMVD2Buffer_CABAC;
}
dp->readSyntaxElement( currSE, img, inp, dp);
vec = currSE->value1;
for (l=0; l < BLOCK_STEP[blocktype][1]; l++)
for (m=0; m < BLOCK_STEP[blocktype][0]; m++)
currMB->mvd[0][j+l][i+m][k] = vec;
vec=vec+pred_vec;
for(ii=0;ii<BLOCK_STEP[blocktype][0];ii++)
{
for(jj=0;jj<BLOCK_STEP[blocktype][1];jj++)
{
img->fw_mv[i4+ii+BLOCK_SIZE][j4+jj][k]=vec;
}
}
}
}
}
}
// /////////////////////////////////////////////////////////////
// find MVDBW
// /////////////////////////////////////////////////////////////
if(img->imod==B_Backward || img->imod==B_Bidirect)
{
// backward : note realtion between blocktype and img->mb_mode
// bidirect : after reading bw_blk_size, bw_pmv is obtained
if(img->mb_mode==2)
blocktype=1;
else if(img->mb_mode>4)
blocktype=(img->mb_mode-1)/2;
else if(img->mb_mode==3)
blocktype=bw_blocktype;
img->bw_blc_size_h = BLOCK_STEP[blocktype][0]*4;
img->bw_blc_size_v = BLOCK_STEP[blocktype][1]*4;
ie=4-BLOCK_STEP[blocktype][0];
for(j=0;j<4;j=j+BLOCK_STEP[blocktype][1]) // Y position in 4-pel resolution
{
block_available_up = mb_available_up || (j > 0);
j4=img->block_y+j;
for(i=0;i<4;i=i+BLOCK_STEP[blocktype][0]) // X position in 4-pel resolution
{
i4=img->block_x+i;
block_available_left = mb_available_left || (i > 0);
if (j > 0)
block_available_upright = i != ie ? 1 : 0;
else if (i != ie)
block_available_upright = block_available_up;
else
block_available_upright = mb_available_upright;
if (i > 0)
block_available_upleft = j > 0 ? 1 : block_available_up;
else if (j > 0)
block_available_upleft = block_available_left;
else
block_available_upleft = mb_available_upleft;
mvPredType = MVPRED_MEDIAN;
rFrameL = block_available_left ? img->bw_refFrArr[j4][i4-1] : -1;
rFrameU = block_available_up ? img->bw_refFrArr[j4-1][i4] : -1;
rFrameUR = block_available_upright ? img->bw_refFrArr[j4-1][i4+BLOCK_STEP[blocktype][0]] :
block_available_upleft ? img->bw_refFrArr[j4-1][i4-1] : -1;
// Prediction if only one of the neighbors uses the selected reference frame
if(rFrameL == bw_predframe_no && rFrameU != bw_predframe_no && rFrameUR != bw_predframe_no)
mvPredType = MVPRED_L;
else if(rFrameL != bw_predframe_no && rFrameU == bw_predframe_no && rFrameUR != bw_predframe_no)
mvPredType = MVPRED_U;
else if(rFrameL != bw_predframe_no && rFrameU != bw_predframe_no && rFrameUR == bw_predframe_no)
mvPredType = MVPRED_UR;
// Directional predictions
else if(blocktype == 3)
{
if(i == 0)
{
if(rFrameL == bw_predframe_no)
mvPredType = MVPRED_L;
}
else
{
if(rFrameUR == bw_predframe_no)
mvPredType = MVPRED_UR;
}
}
else if(blocktype == 2)
{
if(j == 0)
{
if(rFrameU == bw_predframe_no)
mvPredType = MVPRED_U;
}
else
{
if(rFrameL == bw_predframe_no)
mvPredType = MVPRED_L;
}
}
else if(blocktype == 5 && i == 2)
mvPredType = MVPRED_L;
else if(blocktype == 6 && j == 2)
mvPredType = MVPRED_U;
for (k=0;k<2;k++) // vector prediction. find first koordinate set for pred
{
mv_a = block_available_left ? img->bw_mv[i4-1+BLOCK_SIZE][j4][k] : 0;
mv_b = block_available_up ? img->bw_mv[i4+BLOCK_SIZE][j4-1][k] : 0;
mv_d = block_available_upleft ? img->bw_mv[i4-1+BLOCK_SIZE][j4-1][k] : 0;
mv_c = block_available_upright ? img->bw_mv[i4+BLOCK_STEP[blocktype][0]+BLOCK_SIZE][j4-1][k] : mv_d;
switch (mvPredType)
{
case MVPRED_MEDIAN:
if(!(block_available_upleft || block_available_up || block_available_upright))
pred_vec = mv_a;
else
pred_vec =mv_a+mv_b+mv_c-min(mv_a,min(mv_b,mv_c))-max(mv_a,max(mv_b,mv_c));
break;
case MVPRED_L:
pred_vec = mv_a;
break;
case MVPRED_U:
pred_vec = mv_b;
break;
case MVPRED_UR:
pred_vec = mv_c;
break;
default:
break;
}
#if TRACE
snprintf(currSE->tracestring, TRACESTRING_SIZE, " MVD(%d) ",k);
#endif
currSE->type = SE_MVD;
dp = &(currSlice->partArr[partMap[SE_BFRAME]]);
if (inp->symbol_mode == UVLC)
currSE->mapping = linfo_mvd; // linfo_2
else
{
img->subblock_x = i; // position used for context determination
img->subblock_y = j; // position used for context determination
currSE->value2 = 2*k+1; // identifies the component and the direction; only used for context determination
currSE->reading = readBiMVD2Buffer_CABAC;
}
dp->readSyntaxElement( currSE, img, inp, dp);
vec = currSE->value1;
for (l=0; l < BLOCK_STEP[blocktype][1]; l++)
for (m=0; m < BLOCK_STEP[blocktype][0]; m++)
currMB->mvd[1][j+l][i+m][k] = vec;
vec=vec+pred_vec;
for(ii=0;ii<BLOCK_STEP[blocktype][0];ii++)
{
for(jj=0;jj<BLOCK_STEP[blocktype][1];jj++)
{
img->bw_mv[i4+ii+BLOCK_SIZE][j4+jj][k]=vec;
}
}
}
}
}
}
}
/*!
************************************************************************
* \brief
* decode one macroblock for a B frame
************************************************************************
*/
int decode_one_macroblock_Bframe(struct img_par *img)
{
int tmp_block[BLOCK_SIZE][BLOCK_SIZE];
int tmp_blockbw[BLOCK_SIZE][BLOCK_SIZE];
int js[2][2];
int i,j,ii,jj,i1,j1,j4,i4;
int js0,js1,js2,js3,jf,ifx;
int uv;
int vec1_x,vec1_y,vec2_x,vec2_y, vec1_xx, vec1_yy;
int fw_pred, bw_pred;
int ioff,joff;
int ii0,jj0,ii1,jj1,if1,jf1,if0,jf0;
int hv;
byte refP_tr, TRb, TRp;
// keep track of neighbouring macroblocks available for prediction
int mb_nr = img->current_mb_nr;
int mb_width = img->width/16;
int mb_available_up = (img->mb_y == 0) ? 0 : (img->mb_data[mb_nr].slice_nr == img->mb_data[mb_nr-mb_width].slice_nr);
int mb_available_left = (img->mb_x == 0) ? 0 : (img->mb_data[mb_nr].slice_nr == img->mb_data[mb_nr-1].slice_nr);
Macroblock *currMB = &img->mb_data[img->current_mb_nr];
int ref_frame_bw = 0;
int ref_frame_fw = currMB->ref_frame+1;
int ref_frame = ref_frame_fw;
int mv_mul, f1, f2, f3, f4;
#ifdef _ADAPT_LAST_GROUP_
extern int *last_P_no;
#endif
#if POS
int color;
if( mb_nr == 122)
color = 0;
else
color = 0xff;
#endif
// set variables depending on mv_res
if(img->mv_res)
{
mv_mul=8;
f1=16;
f2=15;
}
else
{
mv_mul=4;
f1=8;
f2=7;
}
f3=f1*f1;
f4=f3/2;
// ////////////////////////////////////////////////////////////
// start_scan decoding
// ////////////////////////////////////////////////////////////
/**********************************
* luma *
*********************************/
if (img->imod==INTRA_MB_NEW)
intrapred_luma_2( img, currMB->intra_pred_modes[0]);
for(j=0;j<MB_BLOCK_SIZE/BLOCK_SIZE;j++)
{
joff=j*4;
j4=img->block_y+j;
for(i=0;i<MB_BLOCK_SIZE/BLOCK_SIZE;i++)
{
ioff=i*4;
i4=img->block_x+i;
if(img->imod==INTRA_MB_OLD)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -