📄 macroblock.c
字号:
case 0: //===== TOP LEFT =====
if (mb_available_up) for (i=0;i<4;i++) s0 += image[up.pos_y][up.pos_x + i];
if (mb_available_left[0]) for (i=1;i<5;i++) s2 += image[left[i].pos_y][left[i].pos_x];
if (mb_available_up && mb_available_left[0]) s = (s0+s2+4) >> 3;
else if (mb_available_up) s = (s0 +2) >> 2;
else if (mb_available_left[0]) s = (s2 +2) >> 2;
break;
case 1: //===== TOP RIGHT =====
if (mb_available_up) for (i=4;i<8;i++) s1 += image[up.pos_y][up.pos_x + i];
else if (mb_available_left[0]) for (i=1;i<5;i++) s2 += image[left[i].pos_y][left[i].pos_x];
if (mb_available_up) s = (s1 +2) >> 2;
else if (mb_available_left[0]) s = (s2 +2) >> 2;
break;
case 2: //===== BOTTOM LEFT =====
if (mb_available_left[1]) for (i=5;i<9;i++) s3 += image[left[i].pos_y][left[i].pos_x];
else if (mb_available_up) for (i=0;i<4;i++) s0 += image[up.pos_y][up.pos_x + i];
if (mb_available_left[1]) s = (s3 +2) >> 2;
else if (mb_available_up) s = (s0 +2) >> 2;
break;
case 3: //===== BOTTOM RIGHT =====
if (mb_available_up) for (i=4;i<8;i++) s1 += image[up.pos_y][up.pos_x + i];
if (mb_available_left[1]) for (i=5;i<9;i++) s3 += image[left[i].pos_y][left[i].pos_x];
if (mb_available_up && mb_available_left[1]) s = (s1+s3+4) >> 3;
else if (mb_available_up) s = (s1 +2) >> 2;
else if (mb_available_left[1]) s = (s3 +2) >> 2;
break;
}
//===== prediction =====
for (j=block_y; j<block_y+4; j++)
for (i=block_x; i<block_x+4; i++)
{
img->mprr_c[uv][DC_PRED_8][i][j] = s;
}
}
// vertical prediction
if (mb_available_up)
{
for (i=0; i<8; i++)
hline[i] = image[up.pos_y][up.pos_x + i];
for (i=0; i<8; i++)
for (j=0; j<8; j++)
img->mprr_c[uv][VERT_PRED_8][i][j] = hline[i];
}
// horizontal prediction
if (mb_available_left[0] && mb_available_left[1])
{
for (i=1; i<9; i++)
vline[i] = image[left[i].pos_y][left[i].pos_x];
for (i=0; i<8; i++)
for (j=0; j<8; j++)
img->mprr_c[uv][HOR_PRED_8][i][j] = vline[j+1];
}
// plane prediction
if (mb_available_left[0] && mb_available_left[1] && mb_available_up && mb_available_up_left)
{
ih = 4*(hline[7] - image[left[0].pos_y][left[0].pos_x]);
iv = 4*(vline[7+1] - image[left[0].pos_y][left[0].pos_x]);
for (i=1;i<4;i++)
{
ih += i*(hline[3+i] - hline[3-i]);
iv += i*(vline[3+i+1] - vline[3-i+1]);
}
ib=(17*ih+16)>>5;
ic=(17*iv+16)>>5;
iaa=16*(hline[7]+vline[7+1]);
for (j=0; j<8; j++)
for (i=0; i<8; i++)
img->mprr_c[uv][PLANE_8][i][j]=max(0,min(255,(iaa+(i-3)*ib +(j-3)*ic + 16)/32));// store plane prediction
}
}
if (!input->rdopt) // the rd-opt part does not work correctly (see encode_one_macroblock)
{ // since ipredmodes could be overwritten => encoder-decoder-mismatches
// pick lowest cost prediction mode
min_cost = 1<<20;
for (i=0;i<8;i++)
{
getNeighbour(mb_nr, 0 , i , 0, &left[i]);
}
for (mode=DC_PRED_8; mode<=PLANE_8; mode++)
{
if ((mode==VERT_PRED_8 && !mb_available_up) ||
(mode==HOR_PRED_8 && (!mb_available_left[0] || !mb_available_left[1])) ||
(mode==PLANE_8 && (!mb_available_left[0] || !mb_available_left[1] || !mb_available_up || !mb_available_up_left)))
continue;
cost = 0;
for (uv=0; uv<2; uv++)
{
image = imgUV_org[uv];
for (block_y=0; block_y<8; block_y+=4)
for (block_x=0; block_x<8; block_x+=4)
{
for (k=0,j=block_y; j<block_y+4; j++)
for (i=block_x; i<block_x+4; i++,k++)
{
diff[k] = image[left[j].pos_y][left[j].pos_x+i] - img->mprr_c[uv][mode][i][j];
}
cost += SATD(diff, input->hadamard);
}
}
if (cost < min_cost)
{
best_mode = mode;
min_cost = cost;
}
}
currMB->c_ipred_mode = best_mode;
}
}
/*!
************************************************************************
* \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 (enc_picture->ref_idx[LIST_0][img->block_x+i][img->block_y+j]!=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_SLICE)
{
if (currMB->mb_type==I4MB) return (img->type==I_SLICE ? 0 : 6);
else if (currMB->mb_type==I16MB) return (img->type==I_SLICE ? 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 only_this_block)
{
int i,j,bs_x,bs_y,ii,jj;
int block8x8;
int rate;
int ipred_array[16],cont_array[16],ipred_number;
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];
ipred_number=0;
for(block8x8=0;block8x8<4;block8x8++)
{
if( currMB->b8mode[block8x8]==IBLOCK && (only_this_block<0||only_this_block==block8x8) )
{
bs_x=bs_y=4;
ii=(bs_x>>2); // bug fix for solaris. mwi
jj=(bs_y>>2); // bug fix for solaris. mwi
for(j=0;j<2;j+=jj)
{
for(i=0;i<2;i+=ii)
{
ipred_array[ipred_number]=currMB->intra_pred_modes[(block8x8<<2)|(j<<1)|i];
cont_array[ipred_number]=(block8x8<<2)+(j<<1)+i;
ipred_number++;
}
}
}
}
rate=0;
for(i=0;i<ipred_number;i++)
{
currMB->IntraChromaPredModeFlag = 1;
currSE->context = cont_array[i];
currSE->value1 = ipred_array[i];
currSE->value2 = 0;
#if TRACE
snprintf(currSE->tracestring, TRACESTRING_SIZE, "Intra mode = %3d %d",currSE->value1,currSE->context);
#endif
/*--- set symbol type and function pointers ---*/
if (input->symbol_mode != UVLC) currSE->writing = writeIntraPredMode_CABAC;
currSE->type = SE_INTRAPREDMODE;
/*--- choose data partition ---*/
dataPart = &(currSlice->partArr[partMap[SE_INTRAPREDMODE]]);
/*--- encode and update rate ---*/
if (input->symbol_mode == UVLC) writeSyntaxElement_Intra4x4PredictionMode(currSE, dataPart);
else 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_SLICE)
{
return (b8mode-4);
}
else
{
return b8start[b8mode] + b8inc[b8mode] * b8pdir;
}
}
/*!
************************************************************************
* \brief
* Codes macroblock header
************************************************************************
*/
int writeMBHeader (int rdopt) // GB CHROMA !!!!!!!!
{
int i,j;
int mb_nr = img->current_mb_nr;
Macroblock* currMB = &img->mb_data[mb_nr];
Macroblock* prevMB = mb_nr ? (&img->mb_data[mb_nr-1]) : NULL;
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;
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%2))
{
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[img->current_mb_nr-1];
if(!(img->type == B_SLICE))
prevMbSkipped = (topMB->mb_type == 0);
else
prevMbSkipped = (topMB->mb_type == 0 && topMB->cbp == 0);
}
}
currMB->IntraChromaPredModeFlag = IS_INTRA(currMB);
// choose the appropriate data partition
dataPart = &(currSlice->partArr[partMap[SE_MBTYPE]]);
//===== BITS FOR MACROBLOCK MODE =====
if(img->type == I_SLICE)//GB
{
// write mb_aff
if(img->MbaffFrameFlag && !skip) // check for copy mode, Krit
{
if(WriteFrameFieldMBInHeader)
{
currSE->value1 = currMB->mb_field;
currSE->value2 = 0;
currSE->type = SE_MBTYPE;
if (input->symbol_mode==UVLC) currSE->mapping = ue_linfo;
else currSE->writing = writeFieldModeInfo_CABAC;
#if TRACE
snprintf(currSE->tracestring, TRACESTRING_SIZE, "Field mode = %3d",currMB->mb_field);
#endif
if( input->symbol_mode==UVLC)
{
currSE->bitpattern = (currMB->mb_field ? 1 : 0);
currSE->len = 1;
writeSyntaxElement2Buf_Fixed(currSE, dataPart->bitstream);
}
else
{
dataPart->writeSyntaxElement(currSE, dataPart);
}
bitCount[BITS_MB_MODE] += currSE->len;
no_bits += currSE->len;
currSE++;
currMB->currSEnr++;
}
}
// write mb_type
currSE->value1 = MBType2Value (currMB);
currSE->value2 = 0;
currSE->type = SE_MBTYPE;
if (input->symbol_mode == UVLC) currSE->mapping = ue_linfo;
else currSE->writing = writeMB_typeInfo_CABAC;
dataPart->writeSyntaxElement( currSE, dataPart);
#if TRACE
snprintf(currS
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -