📄 macroblock.c
字号:
//===== update currMB->cbp =====
img->mb_data[img->current_mb_nr].cbp +=(*cr_cbp);//((*cr_cbp)<<4); /*lgp*dct*/
}
/*
*************************************************************************
* Function:Predict an intra chroma 8x8 block
* Input:
* Output:
* Return:
* Attention:
*************************************************************************
*/
void IntraChromaPrediction8x8 (int *mb_up, int *mb_left, int*mb_up_left)
{
Macroblock *currMB = &img->mb_data[img->current_mb_nr];
unsigned char edgepixu[40];
#define EPU (edgepixu+20)
unsigned char edgepixv[40];
#define EPV (edgepixv+20)
int last_pix,new_pix;
int bs_x=8;
int bs_y=8;
int x, y;
int 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 b8_x = img->pix_c_x/4;
int b8_y = 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 || (img_cy/BLOCK_SIZE >0 && img->ipredmode[1+b8_x][1+b8_y-1]<0)) ? 0 : 1;
int mb_available_left = (img_cx/BLOCK_SIZE == 0 || (img_cx/BLOCK_SIZE >0 && img->ipredmode[1+b8_x - 1][1+b8_y]<0)) ? 0 : 1;
int mb_available_up_left = (img_cx/BLOCK_SIZE == 0 || img_cy/BLOCK_SIZE == 0 || (img_cy/BLOCK_SIZE >0 && img->ipredmode[1+b8_x][1+b8_y-1]<0) ||
(img_cx/BLOCK_SIZE >0 && img->ipredmode[1+b8_x - 1][1+b8_y]<0)) ? 0 : 1;
int mb_available_up_right= (img_cy > 0)&&(b8_x<(img->width_cr/BLOCK_SIZE-2))&&(img->ipredmode[1+b8_x+1][1+b8_y-1]>=0);
int mb_available_left_down=(img_cx > 0)&&(b8_y<(img->height_cr/BLOCK_SIZE-2))&&(img->ipredmode[1+b8_x - 1][1+b8_y+1]>=0);
//by oliver according to 1658*/
/***********************************/
int mb_available_up_right=((img_cy==0)||(b8_x>=(img->width_cr/BLOCK_SIZE-2))) ? 0 : (img->mb_data[img->current_mb_nr].slice_nr == img->mb_data[img->current_mb_nr-mb_width+1].slice_nr);
int mb_available_left_down=((img_cx==0)||(b8_y>=(img->height_cr/BLOCK_SIZE-2))) ? 0 : (img->mb_data[img->current_mb_nr].slice_nr == img->mb_data[img->current_mb_nr+mb_width-1].slice_nr);
int mb_available_up = (img_cy == 0) ? 0 : (img->mb_data[img->current_mb_nr].slice_nr == img->mb_data[img->current_mb_nr-mb_width].slice_nr);
int mb_available_left = (img_cx == 0) ? 0 : (img->mb_data[img->current_mb_nr].slice_nr == img->mb_data[img->current_mb_nr-1].slice_nr);
int mb_available_up_left = (img_cx/BLOCK_SIZE == 0 || img_cy/BLOCK_SIZE == 0 ) ? 0 : (img->mb_data[img->current_mb_nr].slice_nr == img->mb_data[img->current_mb_nr-mb_width-1].slice_nr);
//changed by oliver 0512
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];
int incr_y=1,off_y=0;/*lgp*/
int stage_block8x8_pos=0;/*lgp*/
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
uv=0;
if(mb_available_up)
{
for(x=0;x<bs_x;x++)
EPU[x+1]=imgUV[uv][img_cy-1][img_cx+x];
/*
for(x=0;x<bs_y;x++)
EPU[1+x+bs_x]=EPU[bs_x];*/
if(mb_available_up_right){
for(x=0;x<bs_y;x++)
EPU[1+x+bs_x]=imgUV[uv][img_cy-1][img_cx+bs_x+x];
}
else{
for(x=0;x<bs_y;x++)
EPU[1+x+bs_x]=EPU[bs_x]; //bs_x=8; EPU[9~16]=r[8]
}
//by oliver according to 1658
EPU[0]=imgUV[uv][img_cy-1][img_cx];
}
if(mb_available_left)
{
for(y=0;y<bs_y;y++)
EPU[-1-y]=imgUV[uv][img_cy+y][img_cx-1];
for(y=0;y<bs_x;y++)
EPU[-1-y-bs_y]=EPU[-bs_y];
EPU[0]=imgUV[uv][img_cy][img_cx-1];
}
if(mb_available_up&&mb_available_left)
EPU[0]=imgUV[uv][img_cy-1][img_cx-1];
//lowpass (Those emlements that are not needed will not disturb)
last_pix=EPU[-8];
for(i=-8;i<=8;i++)
{
new_pix=( last_pix + (EPU[i]<<1) + EPU[i+1] + 2 )>>2;
last_pix=EPU[i];
EPU[i]=(unsigned char)new_pix;
}
uv=1;
if(mb_available_up)
{
for(x=0;x<bs_x;x++)
EPV[x+1]=imgUV[uv][img_cy-1][img_cx+x];
/*
for(x=0;x<bs_y;x++)
EPV[1+x+bs_x]=EPV[bs_x];*/
if(mb_available_up_right){
for(x=0;x<bs_y;x++)
EPV[1+x+bs_x]=imgUV[uv][img_cy-1][img_cx+bs_x+x];
}
else{
for(x=0;x<bs_y;x++)
EPV[1+x+bs_x]=EPV[bs_x]; //bs_x=8; EPV[9~16]=r[8]
}
//by oliver according to 1658
EPV[0]=imgUV[uv][img_cy-1][img_cx];
}
if(mb_available_left)
{
for(y=0;y<bs_y;y++)
EPV[-1-y]=imgUV[uv][img_cy+y][img_cx-1];
for(y=0;y<bs_x;y++)
EPV[-1-y-bs_y]=EPV[-bs_y];
EPV[0]=imgUV[uv][img_cy][img_cx-1];
}
if(mb_available_up&&mb_available_left)
EPV[0]=imgUV[uv][img_cy-1][img_cx-1];
//lowpass (Those emlements that are not needed will not disturb)
last_pix=EPV[-8];
for(i=-8;i<=8;i++)
{
new_pix=( last_pix + (EPV[i]<<1) + EPV[i+1] + 2 )>>2;
last_pix=EPV[i];
EPV[i]=(unsigned char)new_pix;
}
// compute all chroma intra prediction modes for both U and V
for (uv=0; uv<2; uv++)
{
image = imgUV[uv];
// DC prediction
for (block_y=/*0*/4*(stage_block8x8_pos/2); block_y<8; block_y+=4)
for (block_x=0; block_x<8; block_x+=4)
{
if (uv==0)
{
if (!mb_available_up && !mb_available_left)
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] = 128;
}
if (mb_available_up && !mb_available_left)
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] = EPU[1+i];
}
if (!mb_available_up && mb_available_left)
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] = EPU[-1-j];
}
if (mb_available_up && mb_available_left)
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] = (EPU[1+i]+EPU[-1-j])>>1;
}
}
if (uv==1)
{
if (!mb_available_up && !mb_available_left)
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] = 128;
}
if (mb_available_up && !mb_available_left)
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] = EPV[1+i];
}
if (!mb_available_up && mb_available_left)
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] = EPV[-1-j];
}
if (mb_available_up && mb_available_left)
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] = (EPV[1+i]+EPV[-1-j])>>1;
}
}
// vertical prediction
if (mb_available_up)
{
for (i=block_x; i<block_x+4; i++)
hline[i] = image[img_cy_1][img_cx+i];
for (j=block_y; j<block_y+4; j++)
for (i=block_x; i<block_x+4; i++)
img->mprr_c[uv][VERT_PRED_8][i][j] = hline[i];
}
// horizontal prediction
if (mb_available_left)
{
for (j=0; j<4; j++)
vline[block_y+j] = image[img_cy+block_y+incr_y*j+off_y/*lgp*/][img_cx_1];
for (j=block_y; j<block_y+4; j++)
for (i=block_x; i<block_x+4; i++)
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++)
{
image = imgUV_org[uv];
for (b4=0,block_y=/*0*/4*(stage_block8x8_pos/2); 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*/incr_y*j + off_y/*lgp*/][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;
}
}
/*lgp*/
/*
16x8_direct 0
16x8_fwd 1
16x8_bwd 2
16x8_sym 3
8x8 4
intra 5
*/
/*
*************************************************************************
* Function: Converts macroblock type to coding value
* Input:
* Output:
* Return:
* Attention:
*************************************************************************
*/
int SubMBType2Value (Macroblock* currMB,int layer)
{
int mbtype;
if (img->type!=B_IMG)
{
if (currMB->mb_type==4)
currMB->mb_type = P8x8;
if (currMB->mb_type==I4MB)
return (img->type==INTRA_IMG ? 0 : 5);
else if (currMB->mb_type==P8x8)
{
return 4;
}
else
return currMB->mb_type;
}
else
{
if(currMB->mb_type==4)
currMB->mb_type = P8x8;
mbtype = currMB->mb_type;
if (mbtype==0)
return 0;
else if (mbtype==I4MB)
return 5;
else if (mbtype==P8x8)
return 4;
else if (mbtype==2)
return 1 + currMB->b8pdir[2*layer];
else
return 0;
}
}
/*lgp*/
/*
*************************************************************************
* Function:Converts macroblock type to coding value
* Input:
* Output:
* Return:
* Attention:
*************************************************************************
*/
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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -