📄 macroblock.c
字号:
}
// Do nothing more if copy and inter mode
if (img->mb_mode != COPY_MB || currMB->intraOrInter != INTER_MB ||
(img->type == B_IMG && input->symbol_mode == CABAC) ||
(img->type == B_IMG && input->symbol_mode == UVLC && currMB->cbp != 0))
{
// 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
snprintf(currSE->tracestring, TRACESTRING_SIZE, "Intra mode = %3d",IPRED_ORDER[currSE->value1][currSE->value2]);
#endif
dataPart = &(currSlice->partArr[partMap[SE_INTRAPREDMODE]]);
}
else
{
#if TRACE
snprintf(currSE->tracestring, TRACESTRING_SIZE, "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_MB_MODE] + bitCount[BITS_COEFF_Y_MB] + bitCount[BITS_INTER_MB]
+ bitCount[BITS_CBP_MB] + bitCount[BITS_DELTA_QUANT_MB] + bitCount[BITS_COEFF_UV_MB];
stat->bit_slice += bitCount[BITS_TOTAL_MB];
}
/*!
************************************************************************
* \brief
* Passes for a given MB of a P picture the reference frame
* parameter and the motion vectors to the NAL
************************************************************************
*/
int 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];
int no_bits = 0;
// 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;
no_bits += currSE->len;
#if TRACE
snprintf(currSE->tracestring, TRACESTRING_SIZE, "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;
no_bits += currSE->len;
#if TRACE
snprintf(currSE->tracestring, TRACESTRING_SIZE, " MVD(%d) = %3d",k, curr_mvd);
#endif
// proceed to next SE
currSE++;
currMB->currSEnr++;
}
}
}
return no_bits;
}
/*!
************************************************************************
* \brief
* Passes coded block pattern and coefficients (run/level)
* to the NAL
************************************************************************
*/
void
writeCBPandCoeffs2NAL ()
{
Macroblock *currMB = &img->mb_data[img->current_mb_nr];
if (img->imod != INTRA_MB_NEW)
{
// Bits for CBP
writeMB_bits_for_CBP ();
// Bits for Delta quant
if (currMB->cbp != 0)
writeMB_bits_for_Dquant ();
// Bits for luma coefficients
writeMB_bits_for_luma (1);
}
else // 16x16 based intra modes
{
writeMB_bits_for_Dquant ();
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
snprintf(currSE->tracestring, TRACESTRING_SIZE, "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_Dquant ()
{
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->delta_qp;
#if TRACE
snprintf(currSE->tracestring, TRACESTRING_SIZE, "Delta QP (%2d,%2d) = %3d",img->mb_x, img->mb_y, currMB->delta_qp);
#endif
if (input->symbol_mode == UVLC)
currSE->mapping = dquant_linfo;
else if (input->symbol_mode == CABAC)
currSE->writing = writeDquant_CABAC;// writeMVD2Buffer_CABAC;
currSE->type = SE_DELTA_QUANT;
// 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_DELTA_QUANT_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
snprintf(currSE->tracestring, TRACESTRING_SIZE, "Luma dbl(%2d,%2d) level=%3d Run=%2d",kk,k,level,run);
#endif
// proceed to next SE
currSE++;
currMB->currSEnr++;
}
}
}
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)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -