📄 macroblock.c
字号:
offset = -7;
}
for (*cr_cbp=0, uv=0; uv<2; uv++)
{
//===== prediction of chrominance blocks ===d==
block8 = 0;
for (block_y=0; block_y<8; block_y+=4)
for (block_x=0; block_x<8; block_x+=4, block8++)
{
SetModesAndRefframe (block8, &fw_mode, &bw_mode, &refframe, &bw_ref);
ChromaPrediction4x4 (uv, block_x, block_y, fw_mode, bw_mode, refframe, bw_ref);
}
// ==== set chroma residue to zero for skip Mode in SP frames
if (img->NoResidueDirect)
for (j=0; j<8; j++)
for (i=0; i<8; i++)
{
enc_picture->imgUV[uv][img->pix_c_y+j][img->pix_c_x+i] = img->mpr[i][j];
}
else
if (skipped && img->type==SP_SLICE)
for (j=0; j<8; j++)
for (i=0; i<8; i++)
{
img->m7[i][j] = 0;
}
else
if (skipped)
{
for (j=0; j<8; j++)
for (i=0; i<8; i++)
{
enc_picture->imgUV[uv][img->pix_c_y+j][img->pix_c_x+i] = img->mpr[i][j];
}
}
else
for (j=0; j<8; j++)
for (i=0; i<8; i++)
{
img->m7[i][j] = imgUV_org[uv][img->pix_c_y+(j*incr)+offset][img->pix_c_x+i] - img->mpr[i][j];
}
//===== DCT, Quantization, inverse Quantization, IDCT, and Reconstruction =====
//===== Call function for skip mode in SP frames to properly process frame ====
if (skipped && img->type==SP_SLICE)
{
*cr_cbp=dct_chroma_sp(uv,*cr_cbp);
}
else
if (!img->NoResidueDirect && !skipped)
{
if (img->type!=SP_SLICE || IS_INTRA (&img->mb_data[img->current_mb_nr]))
*cr_cbp=dct_chroma (uv,*cr_cbp);
else
*cr_cbp=dct_chroma_sp(uv,*cr_cbp);
}
}
//===== update currMB->cbp =====
img->mb_data[img->current_mb_nr].cbp += ((*cr_cbp)<<4);
}
/*!
************************************************************************
* \brief
* Predict an intra chroma 8x8 block
************************************************************************
*/
void IntraChromaPrediction8x8 (int *mb_up, int *mb_left, int*mb_up_left)
{
Macroblock *currMB = &img->mb_data[img->current_mb_nr];
int s, s0, s1, s2, s3, i, j, k;
pel_t** image;
int block_x, block_y, b4;
int img_cx = img->pix_c_x;
int img_cy = img->pix_c_y;
int img_cx_1 = img->pix_c_x-1;
int img_cx_4 = img->pix_c_x+4;
int img_cy_1 = img->pix_c_y-1;
int img_cy_4 = img->pix_c_y+4;
int mb_nr = img->current_mb_nr;
int mb_width = img->width/16;
int mb_available_up = (img_cy/BLOCK_SIZE == 0) ? 0 : (img->mb_data[mb_nr].slice_nr==img->mb_data[mb_nr-mb_width].slice_nr);
int mb_available_left = (img_cx/BLOCK_SIZE == 0) ? 0 : (img->mb_data[mb_nr].slice_nr==img->mb_data[mb_nr-1] .slice_nr);
int mb_available_up_left = (img_cx/BLOCK_SIZE == 0 || img_cy/BLOCK_SIZE == 0) ? 0 : (img->mb_data[mb_nr].slice_nr==img->mb_data[mb_nr-mb_width-1].slice_nr);
int ih,iv;
int ib,ic,iaa;
int uv;
int hline[8], vline[8];
int mode;
int best_mode = DC_PRED_8; //just an initilaization here, should always be overwritten
int cost;
int min_cost;
int diff[16];
if(input->InterlaceCodingOption >= MB_CODING && mb_adaptive && img->field_mode)
{
img_cy = img->field_pix_c_y;
img_cy_1 = img->field_pix_c_y-1;
img_cy_4 = img->field_pix_c_y+4;
mb_available_up = (img_cy/BLOCK_SIZE == 0) ? 0 : (img->mb_data[mb_nr].slice_nr==img->mb_data[mb_nr-mb_width].slice_nr);
mb_available_up_left = (img_cx/BLOCK_SIZE == 0 || img_cy/BLOCK_SIZE == 0) ? 0 : (img->mb_data[mb_nr].slice_nr==img->mb_data[mb_nr-mb_width-1].slice_nr);
}
if(input->UseConstrainedIntraPred)
{
/*
if (mb_available_up && (img->intra_block[mb_nr-mb_width][2]==0 || img->intra_block[mb_nr-mb_width][3]==0))
mb_available_up = 0;
if (mb_available_left && (img->intra_block[mb_nr- 1][1]==0 || img->intra_block[mb_nr -1][3]==0))
mb_available_left = 0;
if (mb_available_up_left && (img->intra_block[mb_nr-mb_width-1][3]==0))
mb_available_up_left = 0;
*/
}
if (mb_up)
*mb_up = mb_available_up;
if (mb_left)
*mb_left = mb_available_left;
if( mb_up_left )
*mb_up_left = mb_available_up_left;
// compute all chroma intra prediction modes for both U and V
for (uv=0; uv<2; uv++)
{
/* if(input->InterlaceCodingOption >= MB_CODING && mb_adaptive && img->field_mode)
{
if(img->top_field)
image = imgUV_top[uv];
else
image = imgUV_bot[uv];
}
else
*/
image = enc_picture->imgUV[uv];
// DC prediction
for (block_y=0; block_y<8; block_y+=4)
for (block_x=0; block_x<8; block_x+=4)
{
s=128;
s0=s1=s2=s3=0;
//===== get prediction value =====
switch ((block_y>>1) + (block_x>>2))
{
case 0: //===== TOP LEFT =====
if (mb_available_up) for (i=0;i<4;i++) s0 += image[img_cy_1 ][img_cx +i];
if (mb_available_left) for (i=0;i<4;i++) s2 += image[img_cy +i][img_cx_1 ];
if (mb_available_up && mb_available_left) s = (s0+s2+4) >> 3;
else if (mb_available_up) s = (s0 +2) >> 2;
else if (mb_available_left) s = (s2 +2) >> 2;
break;
case 1: //===== TOP RIGHT =====
if (mb_available_up) for (i=0;i<4;i++) s1 += image[img_cy_1 ][img_cx_4+i];
else if (mb_available_left) for (i=0;i<4;i++) s2 += image[img_cy +i][img_cx_1 ];
if (mb_available_up) s = (s1 +2) >> 2;
else if (mb_available_left) s = (s2 +2) >> 2;
break;
case 2: //===== BOTTOM LEFT =====
if (mb_available_left) for (i=0;i<4;i++) s3 += image[img_cy_4+i][img_cx_1 ];
else if (mb_available_up) for (i=0;i<4;i++) s0 += image[img_cy_1 ][img_cx +i];
if (mb_available_left) s = (s3 +2) >> 2;
else if (mb_available_up) s = (s0 +2) >> 2;
break;
case 3: //===== BOTTOM RIGHT =====
if (mb_available_up) for (i=0;i<4;i++) s1 += image[img_cy_1 ][img_cx_4+i];
if (mb_available_left) for (i=0;i<4;i++) s3 += image[img_cy_4+i][img_cx_1 ];
if (mb_available_up && mb_available_left) s = (s1+s3+4) >> 3;
else if (mb_available_up) s = (s1 +2) >> 2;
else if (mb_available_left) 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[img_cy_1][img_cx+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)
{
for (i=0; i<8; i++)
vline[i] = image[img_cy+i][img_cx_1];
for (i=0; i<8; i++)
for (j=0; j<8; j++)
img->mprr_c[uv][HOR_PRED_8][i][j] = vline[j];
}
// plane prediction
if (mb_available_up_left)
{
ih = 4*(hline[7] - image[img_cy_1][img_cx_1]);
iv = 4*(vline[7] - image[img_cy_1][img_cx_1]);
for (i=1;i<4;i++)
{
ih += i*(hline[3+i] - hline[3-i]);
iv += i*(vline[3+i] - vline[3-i]);
}
ib=(17*ih+16)>>5;
ic=(17*iv+16)>>5;
iaa=16*(hline[7]+vline[7]);
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 (mode=DC_PRED_8; mode<=PLANE_8; mode++)
{
if ((mode==VERT_PRED_8 && !mb_available_up) ||
(mode==HOR_PRED_8 && !mb_available_left) ||
(mode==PLANE_8 && (!mb_available_left || !mb_available_up || !mb_available_up_left)))
continue;
cost = 0;
for (uv=0; uv<2; uv++)
{
if(input->InterlaceCodingOption >= MB_CODING && mb_adaptive && img->field_mode)
{
if(img->top_field)
image = imgUV_org_top[uv];
else
image = imgUV_org_bot[uv];
}
else
image = imgUV_org[uv];
for (b4=0,block_y=0; block_y<8; block_y+=4)
for (block_x=0; block_x<8; block_x+=4,b4++)
{
for (k=0,j=block_y; j<block_y+4; j++)
for (i=block_x; i<block_x+4; i++,k++)
{
diff[k] = image[img_cy+j][img_cx+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
* Set reference frame information in global arrays
* depending on mode decision. Used for motion vector prediction.
************************************************************************
*/
void SetRefFrameInfo(int refframe, int bwrefframe)
{
int i,j;
if (img->type!=B_SLICE)
{
for (j=0; j<4; j++)
for (i=0; i<4; i++)
{
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;
int block_y = img->block_y;
int **frefarr = refFrArr;
if(input->InterlaceCodingOption >= MB_CODING && mb_adaptive && img->field_mode)
{
block_y = img->field_block_y;
frefarr = (img->top_field ? refFrArr_top:refFrArr_bot);
}
for (j=0; j<4; j++)
for (i=0; i<4; i++)
{
if (frefarr[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_SLICE && img->type!=BS_IMG)
{
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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -