📄 macroblock.c
字号:
/* Set loop filter strength depending on mode decision */
SetLoopfilterStrength_P();
/* Set reference frame information for motion vector prediction of future MBs */
SetRefFrameInfo_P();
/* Check if a MB is skipped (no coeffs. only 0-vectors and prediction from the most recent frame) */
if (img->mb_mode==M16x16_MB && currMB->intraOrInter == INTER_MB && (currMB->cbp == 0)
&& tmp_mv[0][img->block_y][img->block_x+4]==0 && tmp_mv[1][img->block_y][img->block_x+4]==0
&& (currMB->ref_frame == 0))
img->mb_mode=COPY_MB;
}
/* Set 16x16 intra mode and make "intra CBP" */
if (img->imod==INTRA_MB_NEW)
{
img->mb_mode += intra_pred_mode_2 + 4*cr_cbp + 12*img->kac;
currMB->cbp += 15*img->kac; /*GB*/
}
if (((img->type == INTER_IMG) && ((img->imod==INTRA_MB_NEW) || (img->imod==INTRA_MB_OLD)))
|| (img->type == B_IMG && (img->imod==B_Backward || img->imod==B_Direct || img->imod==INTRA_MB_NEW || img->imod==INTRA_MB_OLD)))// gb b-frames too
currMB->ref_frame = 0;
#ifdef _RD_OPT_
}
#endif
}
/************************************************************************
*
* Name : write_one_macroblock()
*
* Description: Passes the chosen syntax elements to the NAL
*
************************************************************************/
void write_one_macroblock()
{
int i;
int mb_nr = img->current_mb_nr;
SyntaxElement *currSE = img->MB_SyntaxElements;
Macroblock *currMB = &img->mb_data[mb_nr];
int *bitCount = currMB->bitcounter;
Slice *currSlice = img->currentSlice;
DataPartition *dataPart;
int *partMap = assignSE2partition[input->partition_mode];
/* Store imod for further use */
currMB->mb_imode = img->imod;
/* Store mb_mode for further use */
currMB->mb_type = (currSE->value1 = img->mb_mode);
/* Bits for mode */
if (input->symbol_mode == UVLC)
currSE->mapping = n_linfo2;
else
currSE->writing = writeMB_typeInfo2Buffer_CABAC;
currSE->type = SE_MBTYPE;
/* choose the appropriate data partition */
if (img->type != B_IMG)
{
#if TRACE
sprintf(currSE->tracestring, "MB mode(%2d,%2d) = %3d",img->mb_x, img->mb_y,img->mb_mode);
#endif
dataPart = &(currSlice->partArr[partMap[SE_MBTYPE]]);
}
else
{
#if TRACE
sprintf(currSE->tracestring, "B_MB mode(%2d,%2d) = %3d",img->mb_x, img->mb_y, img->mb_mode);
#endif
dataPart = &(currSlice->partArr[partMap[SE_BFRAME]]);
}
dataPart->writeSyntaxElement( currSE, dataPart);
bitCount[BITS_HEADER_MB]+=currSE->len;
/* proceed to next SE */
currSE++;
currMB->currSEnr++;
/* Do nothing more if copy and inter mode */
if (img->mb_mode != COPY_MB || currMB->intraOrInter != INTER_MB || img->type == B_IMG)
{
/* Bits for intra prediction modes*/
if (img->imod == INTRA_MB_OLD)
{
for (i=0; i < MB_BLOCK_SIZE/2; i++)
{
currSE->value1 = currMB->intra_pred_modes[2*i];
currSE->value2 = currMB->intra_pred_modes[2*i+1];
if (input->symbol_mode == UVLC)
currSE->mapping = intrapred_linfo;
else
currSE->writing = writeIntraPredMode2Buffer_CABAC;
currSE->type = SE_INTRAPREDMODE;
/* choose the appropriate data partition */
if (img->type != B_IMG)
{
#if TRACE
sprintf(currSE->tracestring, "Intra mode = %3d",IPRED_ORDER[currSE->value1][currSE->value2]);
#endif
dataPart = &(currSlice->partArr[partMap[SE_INTRAPREDMODE]]);
}
else
{
#if TRACE
sprintf(currSE->tracestring, "B_Intra mode = %3d\t",IPRED_ORDER[currSE->value1][currSE->value2]);
#endif
dataPart = &(currSlice->partArr[partMap[SE_BFRAME]]);
}
dataPart->writeSyntaxElement( currSE, dataPart);
bitCount[BITS_COEFF_Y_MB]+=currSE->len;
/* proceed to next SE */
currSE++;
currMB->currSEnr++;
}
}
/* Bits for vector data*/
if (img->type != B_IMG)
{
if (currMB->intraOrInter == INTER_MB) /* inter */
writeMotionInfo2NAL_Pframe();
}
else
{
if(img->imod != B_Direct)
writeMotionInfo2NAL_Bframe();
}
/* Bits for CBP and Coefficients */
writeCBPandCoeffs2NAL();
}
bitCount[BITS_TOTAL_MB] = bitCount[BITS_HEADER_MB] + bitCount[BITS_COEFF_Y_MB] + bitCount[BITS_INTER_MB]
+ bitCount[BITS_CBP_MB] + bitCount[BITS_COEFF_UV_MB];
stat->bit_slice += bitCount[BITS_TOTAL_MB];
}
/************************************************************************
*
* Name : writeMotionInfo2NAL_Pframe()
*
* Description: Passes for a given MB of a P picture the reference frame
* parameter and the motion vectors to the NAL
*
************************************************************************/
#ifdef _RD_OPT_
int
#else
void
#endif
writeMotionInfo2NAL_Pframe()
{
int i,j,k,l,m;
int step_h,step_v;
int curr_mvd;
int mb_nr = img->current_mb_nr;
Macroblock *currMB = &img->mb_data[mb_nr];
SyntaxElement *currSE = &img->MB_SyntaxElements[currMB->currSEnr];
int *bitCount = currMB->bitcounter;
Slice *currSlice = img->currentSlice;
DataPartition *dataPart;
int *partMap = assignSE2partition[input->partition_mode];
#ifdef _RD_OPT_
int no_bits = 0;
#endif
/* If multiple ref. frames, write reference frame for the MB */
#ifdef _ADDITIONAL_REFERENCE_FRAME_
if (input->no_multpred > 1 || input->add_ref_frame > 0)
#else
if (input->no_multpred > 1)
#endif
{
currSE->value1 = currMB->ref_frame ;
currSE->type = SE_REFFRAME;
if (input->symbol_mode == UVLC)
currSE->mapping = n_linfo2;
else
currSE->writing = writeRefFrame2Buffer_CABAC;
dataPart = &(currSlice->partArr[partMap[currSE->type]]);
dataPart->writeSyntaxElement( currSE, dataPart);
bitCount[BITS_INTER_MB]+=currSE->len;
#ifdef _RD_OPT_
no_bits += currSE->len;
#endif
#if TRACE
sprintf(currSE->tracestring, "Reference frame no %d", currMB->ref_frame);
#endif
/* proceed to next SE */
currSE++;
currMB->currSEnr++;
}
/* Write motion vectors */
step_h=img->blc_size_h/BLOCK_SIZE; /* horizontal stepsize */
step_v=img->blc_size_v/BLOCK_SIZE; /* vertical stepsize */
for (j=0; j < BLOCK_SIZE; j += step_v)
{
for (i=0;i < BLOCK_SIZE; i += step_h)
{
for (k=0; k < 2; k++)
{
curr_mvd = tmp_mv[k][img->block_y+j][img->block_x+i+4]-img->mv[i][j][currMB->ref_frame][img->mb_mode][k];
img->subblock_x = i; // position used for context determination
img->subblock_y = j; // position used for context determination
currSE->value1 = curr_mvd;
/* store (oversampled) mvd */
for (l=0; l < step_v; l++)
for (m=0; m < step_h; m++)
currMB->mvd[0][j+l][i+m][k] = curr_mvd;
currSE->value2 = k; // identifies the component; only used for context determination
currSE->type = SE_MVD;
if (input->symbol_mode == UVLC)
currSE->mapping = mvd_linfo2;
else
currSE->writing = writeMVD2Buffer_CABAC;
dataPart = &(currSlice->partArr[partMap[currSE->type]]);
dataPart->writeSyntaxElement( currSE, dataPart);
bitCount[BITS_INTER_MB]+=currSE->len;
#ifdef _RD_OPT_
no_bits += currSE->len;
#endif
#if TRACE
sprintf(currSE->tracestring, " MVD(%d) = %3d",k, curr_mvd);
#endif
/* proceed to next SE */
currSE++;
currMB->currSEnr++;
}
}
}
#ifdef _RD_OPT_
return no_bits;
#endif
}
/************************************************************************
*
* Name : writeCBPandCoeffs2NAL()
*
* Description: Passes coded block pattern and coefficients (run/level)
* to the NAL
*
************************************************************************/
void
writeCBPandCoeffs2NAL ()
{
if (img->imod != INTRA_MB_NEW)
{
/* Bits for CBP */
writeMB_bits_for_CBP ();
/* Bits for luma coefficients */
writeMB_bits_for_luma (1);
}
else /* 16x16 based intra modes */
{
writeMB_bits_for_16x16_luma ();
}
/* Bits for chroma 2x2 DC transform coefficients */
writeMB_bits_for_DC_chroma (1);
/* Bits for chroma AC-coeffs. */
writeMB_bits_for_AC_chroma (1);
}
int
writeMB_bits_for_CBP ()
{
int no_bits = 0;
Macroblock *currMB = &img->mb_data[img->current_mb_nr];
SyntaxElement *currSE = &img->MB_SyntaxElements[currMB->currSEnr];
int *bitCount = currMB->bitcounter;
DataPartition *dataPart;
int *partMap = assignSE2partition[input->partition_mode];
currSE->value1 = currMB->cbp;
#if TRACE
sprintf(currSE->tracestring, "CBP (%2d,%2d) = %3d",img->mb_x, img->mb_y, currMB->cbp);
#endif
if (img->imod == INTRA_MB_OLD)
{
if (input->symbol_mode == UVLC)
currSE->mapping = cbp_linfo_intra;
currSE->type = SE_CBP_INTRA;
}
else
{
if (input->symbol_mode == UVLC)
currSE->mapping = cbp_linfo_inter;
currSE->type = SE_CBP_INTER;
}
if (input->symbol_mode == CABAC)
currSE->writing = writeCBP2Buffer_CABAC;
/* choose the appropriate data partition */
if (img->type != B_IMG)
dataPart = &(img->currentSlice->partArr[partMap[currSE->type]]);
else
dataPart = &(img->currentSlice->partArr[partMap[SE_BFRAME]]);
dataPart->writeSyntaxElement(currSE, dataPart);
bitCount[BITS_CBP_MB]+=currSE->len;
no_bits +=currSE->len;
/* proceed to next SE */
currSE++;
currMB->currSEnr++;
return no_bits;
}
int
writeMB_bits_for_luma (int filtering)
{
int no_bits = 0;
int cbp = img->mb_data [img->current_mb_nr].cbp;
int mb_y, mb_x, i, j, ii, jj, bits;
for (mb_y=0; mb_y < 4; mb_y += 2)
{
for (mb_x=0; mb_x < 4; mb_x += 2)
{
for (j=mb_y; j < mb_y+2; j++)
{
jj=j/2;
for (i=mb_x; i < mb_x+2; i++)
{
ii=i/2;
if ((cbp & (1<<(ii+jj*2))) != 0) /* check for any coefficients */
{
no_bits += (bits = writeMB_bits_for_4x4_luma (i, j, filtering));
}
else bits = 0;
#ifdef _RD_DEBUG_I4MODE_
rcdebug_set_luma_rate_4x4 (i, j, bits);
#endif
}
}
}
}
return no_bits;
}
int
writeMB_bits_for_4x4_luma (int i, int j, int filtering)
{
int no_bits = 0;
Macroblock *currMB = &img->mb_data[img->current_mb_nr];
SyntaxElement *currSE = &img->MB_SyntaxElements[currMB->currSEnr];
int *bitCount = currMB->bitcounter;
Slice *currSlice = img->currentSlice;
DataPartition *dataPart;
int *partMap = assignSE2partition[input->partition_mode];
int kk,kbeg,kend;
int level, run;
int k;
if (img->imod == INTRA_MB_OLD && img->qp < 24) /* double scan */
{
for(kk=0;kk<2;kk++)
{
kbeg=kk*9;
kend=kbeg+8;
level=1; /* get inside loop */
for(k=kbeg;k <= kend && level !=0; k++)
{
level = currSE->value1 = img->cof[i][j][k][0][DOUBLE_SCAN]; // level
run = currSE->value2 = img->cof[i][j][k][1][DOUBLE_SCAN]; // run
if (input->symbol_mode == UVLC)
currSE->mapping = levrun_linfo_intra;
else
{
currSE->context = 0; // for choosing context model
currSE->writing = writeRunLevel2Buffer_CABAC;
}
if (k == kbeg)
{
currSE->type = SE_LUM_DC_INTRA; /* element is of type DC */
/* choose the appropriate data partition */
if (img->type != B_IMG)
dataPart = &(currSlice->partArr[partMap[SE_LUM_DC_INTRA]]);
else
dataPart = &(currSlice->partArr[partMap[SE_BFRAME]]);
}
else
{
currSE->type = SE_LUM_AC_INTRA; /* element is of type AC */
/* choose the appropriate data partition */
if (img->type != B_IMG)
dataPart = &(currSlice->partArr[partMap[SE_LUM_AC_INTRA]]);
else
dataPart = &(currSlice->partArr[partMap[SE_BFRAME]]);
}
dataPart->writeSyntaxElement (currSE, dataPart);
bitCount[BITS_COEFF_Y_MB]+=currSE->len;
no_bits +=currSE->len;
#if TRACE
sprintf(currSE->tracestring, "Luma dbl(%2d,%2d) level=%3d Run=%2d",kk,k,level,run);
#endif
/* proceed to next SE */
currSE++;
currMB->currSEnr++;
if (level!=0 && filtering)
{
loopb[img->block_x+i+1][img->block_y+j+1]=max(loopb[img->block_x+i+1][img->block_y+j+1],2);
loopb[img->block_x+i ][img->block_y+j+1]=max(loopb[img->block_x+i ][img->block_y+j+1],1);
loopb[img->block_x+i+1][img->block_y+j ]=max(loopb[img->block_x+i+1][img->block_y+j ],1);
loopb[img->block_x+i+2][img->block_y+j+1]=max(loopb[img->block_x+i+2][img->block_y+j+1],1);
loopb[img->block_x+i+1][img->block_y+j+2]=max(loopb[img->block_x+i+1][img->block_y+j+2],1);
}
}
}
}
else /* single scan */
{
level=1; /* get inside loop */
for(k=0;k<=16 && level !=0; k++)
{
level = currSE->value1 = img->cof[i][j][k][0][SINGLE_SCAN]; // level
run = currSE->value2 = img->cof[i][j][k][1][SINGLE_SCAN]; // run
if (input->symbol_mode == UVLC)
currSE->mapping = levrun_linfo_inter;
else
currSE->writing = writeRunLevel2Buffer_CABAC;
if (k == 0)
{
if (img->imod == INTRA_MB_OLD || img->imod == INTRA_MB_NEW)
{
currSE->context = 2; // for choosing context model
currSE->type = SE_LUM_DC_INTRA;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -