📄 macroblock.c
字号:
se.value2 = 0;
#if TRACE
if (se.value1 < 0 )
snprintf(se.tracestring, TRACESTRING_SIZE, "Intra 8x8 mode = predicted (context: %d)",se.context);
else
snprintf(se.tracestring, TRACESTRING_SIZE, "Intra 8x8 mode = %3d (context: %d)",se.value1,se.context);
#endif
// set symbol type and function pointers
se.type = SE_INTRAPREDMODE;
// encode and update rate
writeIntraPredMode (&se, dataPart);
bitCount[BITS_COEFF_Y_MB]+=se.len;
rate += se.len;
}
return rate;
}
int writeIntraModes(Macroblock *currMB)
{
switch (currMB->mb_type)
{
case I4MB:
return writeIntra4x4Modes(currMB);
break;
case I8MB:
return writeIntra8x8Modes(currMB);
break;
default:
return 0;
break;
}
}
/*!
************************************************************************
* \brief
* Converts 8x8 block type to coding value
************************************************************************
*/
int B8Mode2Value (short b8mode, short 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};
return (img->type!=B_SLICE) ? (b8mode - 4) : b8start[b8mode] + b8inc[b8mode] * b8pdir;
}
static int writeIPCMLuma (ImageParameters *img, imgpel **imgY, Bitstream *currStream, SyntaxElement *se, int *bitCount)
{
int i, j;
int bit_size = MB_BLOCK_SIZE * MB_BLOCK_SIZE * img->bitdepth_luma;
bitCount[BITS_COEFF_Y_MB] += bit_size;
se->len = img->bitdepth_luma;
se->type = SE_MBTYPE;
for (j = img->pix_y; j < img->pix_y + MB_BLOCK_SIZE; j++)
{
for (i = img->pix_x; i < img->pix_x + MB_BLOCK_SIZE; i++)
{
se->bitpattern = imgY[j][i];
se->value1 = se->bitpattern;
#if TRACE
snprintf(se->tracestring, TRACESTRING_SIZE, "pcm_sample_luma (%d %d) = %d", j, i, se->bitpattern);
#endif
writeSE_Fix(se, currStream);
}
}
return bit_size;
}
static int writeIPCMChroma (ImageParameters *img, imgpel **imgUV, Bitstream *currStream, SyntaxElement *se, int *bitCount)
{
int i, j;
int bit_size = img->mb_cr_size_y * img->mb_cr_size_x * img->bitdepth_luma;
bitCount[BITS_COEFF_UV_MB] += bit_size;
se->len = img->bitdepth_chroma;
se->type = SE_MBTYPE;
for (j = img->pix_c_y; j < img->pix_c_y + img->mb_cr_size_y; j++)
{
for (i = img->pix_c_x; i < img->pix_c_x + img->mb_cr_size_x; i++)
{
se->bitpattern = imgUV[j][i];
se->value1 = se->bitpattern;
#if TRACE
//snprintf(se.tracestring, TRACESTRING_SIZE, "pcm_sample_chroma (%s) (%d %d) = %d", uv?"v":"u", j,i,se->bitpattern);
snprintf(se->tracestring, TRACESTRING_SIZE, "pcm_sample_chroma (%d %d) = %d", j, i, se->bitpattern);
#endif
writeSE_Fix(se, currStream);
}
}
return bit_size;
}
static int writeIPCMByteAlign(Bitstream *currStream, SyntaxElement *se, int *bitCount)
{
if (currStream->bits_to_go < 8)
{
// This will only happen in the CAVLC case, CABAC is already padded
se->type = SE_MBTYPE;
se->len = currStream->bits_to_go;
bitCount[BITS_COEFF_Y_MB]+= se->len;
se->bitpattern = 0;
#if TRACE
snprintf(se->tracestring, TRACESTRING_SIZE, "pcm_alignment_zero_bits = %d", se->len);
#endif
writeSE_Fix(se, currStream);
return se->len;
}
else
return 0;
}
/*!
************************************************************************
* \brief
* Codes macroblock header
* \param currMB
* current macroblock
* \param rdopt
* true for calls during RD-optimization
* \param coeff_rate
* bitrate of Luma and Chroma coeff
************************************************************************
*/
int writeMBLayer (Macroblock *currMB, int rdopt, int *coeff_rate)
{
int i,j;
int mb_nr = img->current_mb_nr;
int prev_mb_nr = FmoGetPreviousMBNr(img->current_mb_nr);
Macroblock* prevMB = mb_nr ? (&img->mb_data[prev_mb_nr]) : NULL;
SyntaxElement se;
int* bitCount = currMB->bitcounter;
Slice* currSlice = img->currentSlice;
DataPartition* dataPart;
const int* partMap = assignSE2partition[params->partition_mode];
int no_bits = 0;
int skip = currMB->mb_type ? 0:((img->type == B_SLICE) ? !currMB->cbp:1);
int mb_type;
int prevMbSkipped = 0;
int mb_field_tmp;
Macroblock *topMB = NULL;
int WriteFrameFieldMBInHeader = 0;
if (img->MbaffFrameFlag)
{
if (0==(mb_nr & 0x01))
{
WriteFrameFieldMBInHeader = 1; // top field
prevMbSkipped = 0;
}
else
{
if (prevMB->mb_type ? 0:((img->type == B_SLICE) ? !prevMB->cbp:1))
{
WriteFrameFieldMBInHeader = 1; // bottom, if top was skipped
}
topMB= &img->mb_data[prev_mb_nr];
prevMbSkipped = topMB->skip_flag;
}
}
currMB->IntraChromaPredModeFlag = IS_INTRA(currMB);
// choose the appropriate data partition
dataPart = &(currSlice->partArr[partMap[SE_MBTYPE]]);
if(img->type == I_SLICE)
{
//========= write mb_aff (I_SLICE) =========
if(WriteFrameFieldMBInHeader)
{
se.value1 = currMB->mb_field;
se.value2 = 0;
se.type = SE_MBTYPE;
TRACE_SE (se.tracestring, "mb_field_decoding_flag");
writeFieldModeInfo(&se, dataPart);
bitCount[BITS_MB_MODE] += se.len;
no_bits += se.len;
}
//========= write mb_type (I_SLICE) =========
se.value1 = MBType2Value (currMB);
se.value2 = 0;
se.type = SE_MBTYPE;
#if TRACE
snprintf(se.tracestring, TRACESTRING_SIZE, "mb_type (I_SLICE) (%2d,%2d) = %3d",img->mb_x, img->mb_y, currMB->mb_type);
#endif
writeMB_typeInfo (&se, dataPart);
bitCount[BITS_MB_MODE] += se.len;
no_bits += se.len;
}
// not I_SLICE, CABAC
else if (currSlice->symbol_mode == CABAC)
{
if (img->MbaffFrameFlag && ((img->current_mb_nr & 0x01) == 0||prevMbSkipped))
{
mb_field_tmp = currMB->mb_field;
currMB->mb_field = field_flag_inference(currMB);
CheckAvailabilityOfNeighborsCABAC(currMB);
currMB->mb_field = mb_field_tmp;
}
//========= write mb_skip_flag (CABAC) =========
mb_type = MBType2Value (currMB);
se.value1 = mb_type;
se.value2 = currMB->cbp;
se.type = SE_MBTYPE;
TRACE_SE (se.tracestring, "mb_skip_flag");
writeMB_skip_flagInfo_CABAC(currMB, &se, dataPart);
bitCount[BITS_MB_MODE] += se.len;
no_bits += se.len;
CheckAvailabilityOfNeighborsCABAC(currMB);
//========= write mb_aff (CABAC) =========
if(img->MbaffFrameFlag && !skip) // check for copy mode
{
if(WriteFrameFieldMBInHeader)
{
se.value1 = currMB->mb_field;
se.value2 = 0;
se.type = SE_MBTYPE;
TRACE_SE(se.tracestring, "mb_field_decoding_flag");
writeFieldModeInfo(&se, dataPart);
bitCount[BITS_MB_MODE] += se.len;
no_bits += se.len;
}
}
//========= write mb_type (CABAC) =========
if (currMB->mb_type != 0 || ((img->type == B_SLICE) && (currMB->cbp != 0 || cmp_cbp[1] !=0 || cmp_cbp[2]!=0 )))
{
se.value1 = mb_type;
se.value2 = 0;
se.type = SE_MBTYPE;
#if TRACE
if (img->type == B_SLICE)
snprintf(se.tracestring, TRACESTRING_SIZE, "mb_type (B_SLICE) (%2d,%2d) = %3d",img->mb_x, img->mb_y, currMB->mb_type);
else
snprintf(se.tracestring, TRACESTRING_SIZE, "mb_type (P_SLICE) (%2d,%2d) = %3d",img->mb_x, img->mb_y, currMB->mb_type);
#endif
writeMB_typeInfo( &se, dataPart);
bitCount[BITS_MB_MODE] += se.len;
no_bits += se.len;
}
}
// VLC not intra
else if (currMB->mb_type != 0 || ((img->type == B_SLICE) && (currMB->cbp != 0 || cmp_cbp[1] != 0 || cmp_cbp[2]!=0 )))
{
//===== Run Length Coding: Non-Skipped macroblock =====
se.value1 = img->cod_counter;
se.value2 = 0;
se.type = SE_MBTYPE;
TRACE_SE (se.tracestring, "mb_skip_run");
writeSE_UVLC(&se, dataPart);
bitCount[BITS_MB_MODE] += se.len;
no_bits += se.len;
// Reset cod counter
img->cod_counter = 0;
// write mb_aff
if(img->MbaffFrameFlag && !skip) // check for copy mode
{
if(WriteFrameFieldMBInHeader)
{
se.value1 = currMB->mb_field;
se.type = SE_MBTYPE;
TRACE_SE(se.tracestring, "mb_field_decoding_flag");
writeSE_Flag (&se, dataPart);
bitCount[BITS_MB_MODE] += se.len;
no_bits += se.len;
}
}
// Put out mb mode
se.value1 = MBType2Value (currMB);
if (img->type != B_SLICE)
{
se.value1--;
}
se.type = SE_MBTYPE;
se.value2 = 0;
#if TRACE
if (img->type == B_SLICE)
snprintf(se.tracestring, TRACESTRING_SIZE, "mb_type (B_SLICE) (%2d,%2d) = %3d",img->mb_x, img->mb_y, currMB->mb_type);
else
snprintf(se.tracestring, TRACESTRING_SIZE, "mb_type (P_SLICE) (%2d,%2d) = %3d",img->mb_x, img->mb_y, currMB->mb_type);
#endif
writeMB_typeInfo(&se, dataPart);
bitCount[BITS_MB_MODE] += se.len;
no_bits += se.len;
}
else
{
//Run Length Coding: Skipped macroblock
img->cod_counter++;
currMB->skip_flag = 1;
// CAVLC
for (j=0; j < (4 + img->num_blk8x8_uv); j++)
for (i=0; i < 4; i++)
img->nz_coeff [img->current_mb_nr][i][j]=0;
if(FmoGetNextMBNr(img->current_mb_nr) == -1 && img->cod_counter>0)
{
// Put out run
se.value1 = img->cod_counter;
se.value2 = 0;
se.type = SE_MBTYPE;
TRACE_SE(se.tracestring, "mb_skip_run");
writeSE_UVLC(&se, dataPart);
bitCount[BITS_MB_MODE] += se.len;
no_bits += se.len;
// Reset cod counter
img->cod_counter = 0;
}
}
//init NoMbPartLessThan8x8Flag
currMB->NoMbPartLessThan8x8Flag = (IS_DIRECT(currMB) && !(active_sps->direct_8x8_inference_flag))? 0: 1;
if (currMB->mb_type == IPCM)
{
dataPart = &(currSlice->partArr[partMap[SE_LUM_DC_INTRA]]);
if (currSlice->symbol_mode == CABAC)
{
int len;
EncodingEnvironmentPtr eep = &dataPart->ee_cabac;
len = arienco_bits_written(eep);
arienco_done_encoding(eep); // This pads to byte
len = arienco_bits_written(eep) - len;
no_bits += len;
// Now restart the encoder
arienco_start_encoding(eep, dataPart->bitstream->streamBuffer, &(dataPart->bitstream->byte_pos));
}
writeIPCMByteAlign(dataPart->bitstream, &se, bitCount);
no_bits += writeIPCMLuma (img, enc_picture->imgY, dataPart->bitstream, &se, bitCount);
if ((active_sps->chroma_format_idc != YUV400) && !IS_INDEPENDENT(params))
{
int uv;
for (uv = 0; uv < 2; uv ++)
{
no_bits += writeIPCMChroma (img, enc_picture->imgUV[uv], dataPart->bitstream, &se, bitCount);
}
}
return no_bits;
}
dataPart = &(currSlice->partArr[partMap[SE_MBTYPE]]);
//===== BITS FOR 8x8 SUB-PARTITION MODES =====
if (IS_P8x8 (currMB))
{
for (i=0; i<4; i++)
{
se.value1 = B8Mode2Value (currMB->b8mode[i], currMB->b8pdir[i]);
se.value2 = 0;
se.type = SE_MBTYPE;
#if TRACE
snprintf(se.tracestring, TRACESTRING_SIZE, "8x8 mode/pdir(%2d) = %3d/%d", i, currMB->b8mode[i], currMB->b8pdir[i]);
#endif
writeB8_typeInfo (&se, dataPart);
bitCount[BITS_MB_MODE]+= se.len;
no_bits += se.len;
//set NoMbPartLessThan8x8Flag for P8x8 mode
currMB->NoMbPartLessThan8x8Flag &= (currMB->b8mode[i]==0 && act
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -