📄 macroblock.c
字号:
{
refFrArr[img->block_y+j][img->block_x+i] = refframe;
}
}
else
{
for (j=0; j<4; j++)
for (i=0; i<4; i++)
{
fw_refFrArr[img->block_y+j][img->block_x+i] = refframe;
bw_refFrArr[img->block_y+j][img->block_x+i] = bwrefframe;
}
}
}
/*!
************************************************************************
* \brief
* Check if all reference frames for a macroblock are zero
************************************************************************
*/
int
ZeroRef (Macroblock* currMB)
{
int i,j;
for (j=0; j<4; j++)
for (i=0; i<4; i++)
{
if (currMB->b8mode[2*(j/2)+(i/2)]!=IBLOCK && refFrArr[img->block_y+j][img->block_x+i]!=0)
{
return 0;
}
}
return 1;
}
/*!
************************************************************************
* \brief
* Converts macroblock type to coding value
************************************************************************
*/
int
MBType2Value (Macroblock* currMB)
{
static const int dir1offset[3] = { 1, 2, 3};
static const int dir2offset[3][3] = {{ 0, 4, 8}, // 1. block forward
{ 6, 2, 10}, // 1. block backward
{12, 14, 16}}; // 1. block bi-directional
int mbtype, pdir0, pdir1;
if (img->type!=B_IMG)
{
if (currMB->mb_type==I4MB) return (img->type==INTRA_IMG ? 0 : 6);
else if (currMB->mb_type==I16MB) return (img->type==INTRA_IMG ? 0 : 6) + img->i16offset;
else if (currMB->mb_type==P8x8)
{
if (input->symbol_mode==UVLC && ZeroRef (currMB)) return 5;
else return 4;
}
else return currMB->mb_type;
}
else
{
mbtype = currMB->mb_type;
pdir0 = currMB->b8pdir[0];
pdir1 = currMB->b8pdir[3];
if (mbtype==0) return 0;
else if (mbtype==I4MB) return 23;
else if (mbtype==I16MB) return 23 + img->i16offset;
else if (mbtype==P8x8) return 22;
else if (mbtype==1) return dir1offset[pdir0];
else if (mbtype==2) return 4 + dir2offset[pdir0][pdir1];
else return 5 + dir2offset[pdir0][pdir1];
}
}
/*!
************************************************************************
* \brief
* Writes intra prediction modes for an 8x8 block
************************************************************************
*/
int
writeIntra4x4Modes (int block8x8)
{
int i, i0=4*block8x8, i1=i0+4;
int rate = 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;
const int *partMap = assignSE2partition[input->partition_mode];
for (i=i0; i<i1; )
{
currSE->context = i;
currSE->value1 = currMB->intra_pred_modes[i++];
currSE->value2 = currMB->intra_pred_modes[i++];
#if TRACE
snprintf(currSE->tracestring, TRACESTRING_SIZE, "Intra mode = %3d",IPRED_ORDER[currSE->value1][currSE->value2]);
#endif
/*--- set symbol type and function pointers ---*/
if (input->symbol_mode == UVLC) currSE->mapping = intrapred_linfo;
else currSE->writing = writeIntraPredMode2Buffer_CABAC;
currSE->type = SE_INTRAPREDMODE;
/*--- choose data partition ---*/
if (img->type==B_IMG) dataPart = &(currSlice->partArr[partMap[SE_BFRAME]]);
else dataPart = &(currSlice->partArr[partMap[SE_INTRAPREDMODE]]);
/*--- encode and update rate ---*/
dataPart->writeSyntaxElement (currSE, dataPart);
bitCount[BITS_COEFF_Y_MB]+=currSE->len;
rate += currSE->len;
currSE++;
currMB->currSEnr++;
}
return rate;
}
/*!
************************************************************************
* \brief
* Converts 8x8 block tyoe to coding value
************************************************************************
*/
int
B8Mode2Value (int b8mode, int b8pdir)
{
static const int b8start[8] = {0,0,0,0, 1, 4, 5, 10};
static const int b8inc [8] = {0,0,0,0, 1, 2, 2, 1};
if (img->type!=B_IMG)
{
return (b8mode==IBLOCK?4:b8mode-4);
}
else
{
if (b8mode==IBLOCK) return 13;
else return b8start[b8mode] + b8inc[b8mode] * b8pdir;
}
}
/*!
************************************************************************
* \brief
* Codes macroblock header
************************************************************************
*/
int
writeMBHeader ()
{
int i;
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;
const int* partMap = assignSE2partition[input->partition_mode];
int no_bits = 0;
// choose the appropriate data partition
if (img->type == B_IMG) dataPart = &(currSlice->partArr[partMap[SE_BFRAME]]);
else dataPart = &(currSlice->partArr[partMap[SE_MBTYPE]]);
//===== BITS FOR MACROBLOCK MODE =====
if(img->type == INTRA_IMG || img->types == SP_IMG || input->symbol_mode == CABAC)
{
//===== No Run Length Coding of SKIP modes =====
currSE->value1 = MBType2Value (currMB);
currSE->type = SE_MBTYPE;
if (input->symbol_mode == UVLC) currSE->mapping = n_linfo2;
else currSE->writing = writeMB_typeInfo2Buffer_CABAC;
dataPart->writeSyntaxElement( currSE, dataPart);
#if TRACE
if (img->type == B_IMG) snprintf(currSE->tracestring, TRACESTRING_SIZE, "B_MB mode(%2d,%2d) = %3d",img->mb_x, img->mb_y, currMB->mb_type);
else snprintf(currSE->tracestring, TRACESTRING_SIZE, "MB mode(%2d,%2d) = %3d",img->mb_x, img->mb_y,currMB->mb_type);
#endif
bitCount[BITS_MB_MODE] += currSE->len;
no_bits += currSE->len;
currSE++;
currMB->currSEnr++;
}
else if (currMB->mb_type != 0 || (img->type == B_IMG && currMB->cbp != 0))
{
//===== Run Length Coding: Non-Skipped macorblock =====
currSE->value1 = img->cod_counter;
currSE->mapping = n_linfo2;
currSE->type = SE_MBTYPE;
dataPart->writeSyntaxElement( currSE, dataPart);
#if TRACE
snprintf(currSE->tracestring, TRACESTRING_SIZE, "MB runlength = %3d",img->cod_counter);
#endif
bitCount[BITS_MB_MODE] += currSE->len;
no_bits += currSE->len;
currSE++;
currMB->currSEnr++;
// Reset cod counter
img->cod_counter = 0;
// Put out mb mode
currSE->value1 = MBType2Value (currMB);
if(img->type != B_IMG)
{
currSE->value1--;
}
currSE->mapping = n_linfo2;
currSE->type = SE_MBTYPE;
dataPart->writeSyntaxElement( currSE, dataPart);
#if TRACE
if (img->type == B_IMG) snprintf(currSE->tracestring, TRACESTRING_SIZE, "B_MB mode(%2d,%2d) = %3d",img->mb_x, img->mb_y, currMB->mb_type);
else snprintf(currSE->tracestring, TRACESTRING_SIZE, "MB mode(%2d,%2d) = %3d",img->mb_x, img->mb_y,currMB->mb_type);
#endif
bitCount[BITS_MB_MODE] += currSE->len;
no_bits += currSE->len;
currSE++;
currMB->currSEnr++;
}
else
{
//Run Length Coding: Skipped macroblock
img->cod_counter++;
if(img->current_mb_nr == img->total_number_mb)
{
// Put out run
currSE->value1 = img->cod_counter;
currSE->mapping = n_linfo2;
currSE->type = SE_MBTYPE;
dataPart->writeSyntaxElement( currSE, dataPart);
#if TRACE
snprintf(currSE->tracestring, TRACESTRING_SIZE, "MB runlength = %3d",img->cod_counter);
#endif
bitCount[BITS_MB_MODE] += currSE->len;
no_bits += currSE->len;
currSE++;
currMB->currSEnr++;
// Reset cod counter
img->cod_counter = 0;
}
}
//===== BITS FOR 8x8 SUB-PARTITION MODI =====
if (IS_P8x8 (currMB))
{
if (img->type==B_IMG) dataPart = &(currSlice->partArr[partMap[SE_BFRAME]]);
else dataPart = &(currSlice->partArr[partMap[SE_MBTYPE]]);
for (i=0; i<4; i++)
{
if (input->symbol_mode==UVLC) currSE->mapping = n_linfo2;
else currSE->writing = writeB8_typeInfo2Buffer_CABAC;
currSE->value1 = B8Mode2Value (currMB->b8mode[i], currMB->b8pdir[i]);
currSE->type = SE_MBTYPE;
dataPart->writeSyntaxElement (currSE, dataPart);
bitCount[BITS_MB_MODE]+= currSE->len;
no_bits += currSE->len;
currSE++;
currMB->currSEnr++;
}
}
//===== BITS FOR INTRA PREDICTION MODI ====
for (i=0; i<4; i++)
{
if (currMB->b8mode[i]==IBLOCK)
{
no_bits += writeIntra4x4Modes (i);
}
}
return no_bits;
}
/*!
************************************************************************
* \brief
* Passes the chosen syntax elements to the NAL
************************************************************************
*/
void write_one_macroblock ()
{
Macroblock* currMB = &img->mb_data[img->current_mb_nr];
int* bitCount = currMB->bitcounter;
//--- write header ---
writeMBHeader ();
// Do nothing more if copy and inter mode
if ((IS_INTERMV (currMB) || IS_INTRA (currMB) ) ||
(img->type==B_IMG && input->symbol_mode== CABAC ) ||
(img->type==B_IMG && input->symbol_mode== UVLC && currMB->cbp != 0) )
{
writeMotionInfo2NAL ();
writeCBPandLumaCoeff ();
writeChromaCoeff ();
}
//--- constrain intra prediction ---
if(input->UseConstrainedIntraPred && img->type==INTER_IMG && img->types != SP_IMG)
{
if (!IS_NEWINTRA (currMB) && currMB->b8mode[0]!=IBLOCK) img->intra_block[img->current_mb_nr][0] = 0;
if (!IS_NEWINTRA (currMB) && currMB->b8mode[1]!=IBLOCK) img->intra_block[img->current_mb_nr][1] = 0;
if (!IS_NEWINTRA (currMB) && currMB->b8mode[2]!=IBLOCK) img->intra_block[img->current_mb_nr][2] = 0;
if (!IS_NEWINTRA (currMB) && currMB->b8mode[3]!=IBLOCK) img->intra_block[img->current_mb_nr][3] = 0;
}
//--- set total bit-counter ---
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
* Sets context for reference frame parameter
************************************************************************
*/
int
BType2CtxRef (int btype)
{
if (btype<4) return 0;
else return 1;
}
/*!
************************************************************************
* \brief
* Codes the reference frame
************************************************************************
*/
int
writeReferenceFrame (int mode,
int i,
int j,
int ref)
{
Macroblock* currMB = &img->mb_data[img->current_mb_nr];
SyntaxElement* currSE = &img->MB_SyntaxElements[currMB->currSEnr];
Slice* currSlice = img->currentSlice;
int* bitCount = currMB->bitcounter;
const int* partMap = assignSE2partition[input->partition_mode];
int rate = 0;
DataPartition* dataPart;
currSE->value1 = ref;
currSE->type = (img->type==B_IMG ? SE_BFRAME : SE_REFFRAME);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -