📄 block.c
字号:
break;
}
}
if (shift==16) shift=15;
QPI = (int)((1<<shift)*QP99+0.5);
// this has to be done for each subblock seperately
intra = IS_INTRA(currMB);
inumblk = 1;
inumcoeff = 65; // all positions + EOB
// ========= dequantization values ===========
q_bits = qp_chroma/QUANT_PERIOD;
//make decoder table for 2DVLC_CHROMA code
if(AVS_2DVLC_CHROMA_dec[0][0][1]<0) // Don't need to set this every time. rewrite later.
{
memset(AVS_2DVLC_CHROMA_dec,-1,sizeof(AVS_2DVLC_CHROMA_dec));
for(i=0;i<5;i++)
{
table2D=AVS_2DVLC_CHROMA[i];
for(run=0;run<26;run++)
for(level=0;level<27;level++)
{
ipos=table2D[run][level];
assert(ipos<64);
if(ipos>=0)
{
if(i==0)
{
AVS_2DVLC_CHROMA_dec[i][ipos][0]=level+1;
AVS_2DVLC_CHROMA_dec[i][ipos][1]=run;
AVS_2DVLC_CHROMA_dec[i][ipos+1][0]=-(level+1);
AVS_2DVLC_CHROMA_dec[i][ipos+1][1]=run;
}
else
{
AVS_2DVLC_CHROMA_dec[i][ipos][0]=level;
AVS_2DVLC_CHROMA_dec[i][ipos][1]=run;
if(level)
{
AVS_2DVLC_CHROMA_dec[i][ipos+1][0]=-(level);
AVS_2DVLC_CHROMA_dec[i][ipos+1][1]=run;
}
}
}
}
}
assert(AVS_2DVLC_CHROMA_dec[0][0][1]>=0); //otherwise, tables are bad.
}
//clear cbp_blk bits of thie 8x8 block (and not all 4!)
vlc_numcoef=-1;
Golomb_se_type=SE_LUM_AC_INTER;
if( intra )
{
vlc_numcoef=0; //this means 'use numcoeffs symbol'.
Golomb_se_type=SE_LUM_AC_INTRA;
}
AVS_VLC_table_chroma = AVS_2DVLC_CHROMA_dec;
// === set offset in current macroblock ===
boff_x = ( (block8x8%2)<<3 );
boff_y = ( (block8x8/2)<<3 );
img->subblock_x = boff_x>>2;
img->subblock_y = boff_y>>2;
ipos = -1;
any_coeff=1;
is_last_levelrun=0;
tablenum = 0;
for(i=0; i<inumcoeff; i++)
{
//read 2D symbol
currSE.type = Golomb_se_type;
currSE.golomb_grad = VLC_Golomb_Order[2][tablenum][0]; //qwang 11.29
currSE.golomb_maxlevels = VLC_Golomb_Order[2][tablenum][1]; //qwang 11.29
readSyntaxElement_GOLOMB(&currSE,img,inp);
symbol2D = currSE.value1;
//if(symbol2D == EOB_Pos_chroma[tablenum])
if(symbol2D == EOB_Pos_chroma[1][tablenum]) //qwang 11.29
{
vlc_numcoef = i;
break;
}
if(symbol2D < CODE2D_ESCAPE_SYMBOL)
{
level = AVS_VLC_table_chroma[tablenum][symbol2D][0]; //qwang 11.29
run = AVS_VLC_table_chroma[tablenum][symbol2D][1]; //qwang 11.29
}
else
{
// changed by dj
run = (symbol2D-CODE2D_ESCAPE_SYMBOL)>>1;
//decode level
currSE.type=Golomb_se_type;
currSE.golomb_grad = 0;
currSE.golomb_maxlevels=11;
readSyntaxElement_GOLOMB(&currSE,img,inp);
level = currSE.value1 + ((run>MaxRun[2][tablenum])?1:RefAbsLevel[tablenum+14][run]);
// if( (symbol2D-CODE2D_ESCAPE_SYMBOL) & 1 )
if(symbol2D & 1) // jlzheng 7.20
level=-level;
}
// 保存level,run到缓冲区
buffer_level[i] = level;
buffer_run[i] = run;
if(abs(level) > incVlc_chroma[tablenum]) //qwang 11.29
{
if(abs(level) <= 2)
tablenum = abs(level);
else if(abs(level) <= 4)
tablenum = 3;
else
tablenum = 4;
}
}//loop for icoef
//将解码的level,run写到img->m7[][];
for(i=(vlc_numcoef-1); i>=0; i--)
{
ipos += (buffer_run[i]+1);
ii = SCAN[img->picture_structure][ipos][0];
jj = SCAN[img->picture_structure][ipos][1];
shift = IQ_SHIFT[qp_chroma];
QPI = IQ_TAB[qp_chroma];
val = buffer_level[i];
temp = (val*QPI+(1<<(shift-2)) )>>(shift-1);
img->m8[block8x8-4][ii][jj] = temp;
}
// CAVLC store number of coefficients
sbx = img->subblock_x;
sby = img->subblock_y;
sbx = (img->subblock_x == 2) ? 1:0;
if(any_coeff)
{
currMB->cbp_blk |= 0xf0000 << ((block8x8-4) << 2);
}
}
/*
*************************************************************************
* Function:Copy region of img->m7 corresponding to block8x8 to curr_blk[][].
* Input:
* Output:
* Return:
* Attention:img->m7 is [x][y] and curr_blk is [y][x].
*************************************************************************
*/
void get_curr_blk( int block8x8,struct img_par *img, int curr_blk[B8_SIZE][B8_SIZE])
{
int xx, yy;
int mb_y = (block8x8 / 2) << 3;
int mb_x = (block8x8 % 2) << 3;
Macroblock *currMB = &mb_data[img->current_mb_nr];/*lgp*/
for (yy=0; yy<B8_SIZE; yy++)
for (xx=0; xx<B8_SIZE; xx++)
{
if (block8x8<=3)
curr_blk[yy][xx] = img->m7[mb_x+xx][mb_y+yy];
else
curr_blk[yy][xx] = img->m8[block8x8-4][xx][yy];
}
}
/*
*************************************************************************
* Function:Make Intra prediction for all 9 modes for larger blocks than 4*4,
that is for 4*8, 8*4 and 8*8 blocks.
bs_x and bs_y may be only 4 and 8.
img_x and img_y are pixels offsets in the picture.
* Input:
* Output:
* Return:
* Attention:
*************************************************************************
*/
int intrapred(struct img_par *img,int img_x,int img_y)
{
unsigned char edgepixels[40];
int x,y,last_pix,new_pix;
unsigned int x_off,y_off;
int i,predmode;
int b4_x,b4_y;
int b4,b8,mb;
int block_available_up,block_available_up_right;
int block_available_left,block_available_left_down;
int bs_x,bs_y;
int b8_x,b8_y;
Macroblock *currMB = &mb_data[img->current_mb_nr];/*lgp*/
int MBRowSize = img->width / MB_BLOCK_SIZE;/*lgp*/
int off_up=1,incr_y=1,off_y=0; /*lgp*/
/*oliver*/
const int mb_nr = img->current_mb_nr; /*oliver*/
int mb_left_available = (img_x >= MB_BLOCK_SIZE)?currMB->slice_nr == mb_data[mb_nr-1].slice_nr:0; /*oliver*/
int mb_up_available = (img_y >= MB_BLOCK_SIZE)?currMB->slice_nr == mb_data[mb_nr-MBRowSize].slice_nr:0; /*oliver*/
int mb_up_right_available;
int mb_left_down_available;
if((img->mb_y==0)||(img->mb_x==img->width/MB_BLOCK_SIZE-1))
mb_up_right_available =1;
else if((img_y-img->pix_y)>0)
mb_up_right_available =(img_x-img->pix_x)>0? (currMB->slice_nr == mb_data[mb_nr+1].slice_nr):1; /*oliver*/
else
mb_up_right_available =((img_x-img->pix_x)>0? (currMB->slice_nr == mb_data[mb_nr-MBRowSize+1].slice_nr):(currMB->slice_nr== mb_data[mb_nr-MBRowSize].slice_nr)); /*oliver*/
if((img->mb_x==0)||(img->mb_y==img->height/MB_BLOCK_SIZE-1))
mb_left_down_available = 1;
else if(img_x-img->pix_x>0)
mb_left_down_available =(img_y-img->pix_y)>0? (currMB->slice_nr == mb_data[mb_nr+MBRowSize].slice_nr):1; /*oliver*/
else
mb_left_down_available =((img_y-img->pix_y)>0? (currMB->slice_nr == mb_data[mb_nr+MBRowSize-1].slice_nr):(currMB->slice_nr == mb_data[mb_nr-1].slice_nr)); /*oliver*/
//0512
b8_x=img_x>>3;
b8_y=img_y>>3;
bs_x = bs_y = 8;
x_off=img_x&0x0FU;
y_off=img_y&0x0FU;
predmode = img->ipredmode[img_x/(2*BLOCK_SIZE)+1][img_y/(2*BLOCK_SIZE)+1];
assert(predmode>=0);
{
b4_x=img_x>>2;
b4_y=img_y>>2;
mb=(b4_x>>2)+(b4_y>>2)*(img->width>>2); b8=((b4_x&2)>>1)|(b4_y&2); b4=(b4_x&1)|((b4_y&1)<<1);
//check block up
block_available_up=( b8_y-1>=0 && (mb_up_available||(img_y/8)%2));
//check block up right
block_available_up_right=( b8_x+1<(img->width>>3) && b8_y-1>=0 && mb_up_right_available);
//check block left
block_available_left=( b8_x - 1 >=0 && ( mb_left_available)||((img_x/8)%2));
//check block left down
block_available_left_down=( b8_x - 1>=0 && b8_y + 1 < (img->height>>3) && mb_left_down_available);
if( ((img_x/8)%2) && ((img_y/8)%2))
block_available_up_right=0;
if( ((img_x/8)%2) || ((img_y/8)%2))
block_available_left_down=0;
//get prediciton pixels
if(block_available_up)
{
for(x=0;x<bs_x;x++)
EP[x+1]=imgY[img_y-1][img_x+x];
if(block_available_up_right)
{
for(x=0;x<bs_x;x++)
EP[1+x+bs_x]=imgY[img_y-1][img_x+bs_x+x];
for(;x<bs_y;x++)
EP[1+x+bs_x]=imgY[img_y-1][img_x+bs_x+bs_x-1];
}else
for(x=0;x<bs_y;x++)
EP[1+x+bs_x]=EP[bs_x];
for(;x<bs_y+2;x++)
EP[1+x+bs_x]=EP[bs_x+x];
EP[0]=imgY[img_y-1][img_x];
}
if(block_available_left)
{
for(y=0;y<bs_y;y++)
EP[-1-y]=imgY[img_y+y][img_x-1];
if(block_available_left_down)
{
for(y=0;y<bs_y;y++)
EP[-1-y-bs_y]=imgY[img_y+bs_y+y][img_x-1];
for(;y<bs_x;y++)
EP[-1-y-bs_y]=imgY[img_y+bs_y+bs_y-1][img_x-1];
}
else
for(y=0;y<bs_x;y++)
EP[-1-y-bs_y]=EP[-bs_y];
for(;y<bs_x+2;y++)
EP[-1-y-bs_y]=EP[-y-bs_y];
EP[0]=imgY[img_y][img_x-1];
}
if(block_available_up&&block_available_left)
EP[0]=imgY[img_y-1][img_x-1];
//lowpass (Those emlements that are not needed will not disturb)
last_pix=EP[-(bs_x+bs_y)];
for(i=-(bs_x+bs_y);i<=(bs_x+bs_y);i++)
{
new_pix=( last_pix + (EP[i]<<1) + EP[i+1] + 2 )>>2;
last_pix=EP[i];
EP[i]=(unsigned char)new_pix;
}
}
switch(predmode)
{
case DC_PRED:// 0 DC
if(!block_available_up && !block_available_left)
for(y=0UL;y<bs_y;y++)
for(x=0UL;x<bs_x;x++)
img->mpr[x+x_off][y+y_off]=128UL;
if(block_available_up && !block_available_left)
for(y=0UL;y<bs_y;y++)
for(x=0UL;x<bs_x;x++)
img->mpr[x+x_off][y+y_off]=EP[1+x];
if(!block_available_up && block_available_left)
for(y=0UL;y<bs_y;y++)
for(x=0UL;x<bs_x;x++)
img->mpr[x+x_off][y+y_off]=EP[-1-y];
if(block_available_up && block_available_left)
for(y=0UL;y<bs_y;y++)
for(x=0UL;x<bs_x;x++)
img->mpr[x+x_off][y+y_off]=(EP[1+x]+EP[-1-y])>>1;
break;
case VERT_PRED:// 1 vertical
if(!block_available_up)
printf("!!invalid intrapred mode %d!! %d \n",predmode, img->current_mb_nr);
for(y=0UL;y<bs_y;y++)
for(x=0UL;x<bs_x;x++)
img->mpr[x+x_off][y+y_off]=imgY[img_y-1][img_x+x];
break;
case HOR_PRED:// 2 horizontal
if(!block_available_left)
printf("!!invalid intrapred mode %d!! %d \n",predmode, img->current_mb_nr);
for(y=0UL;y<bs_y;y++)
for(x=0UL;x<bs_x;x++)
img->mpr[x+x_off][y+y_off]=imgY[img_y+y][img_x-1];
break;
case DOWN_RIGHT_PRED:// 3 down-right
if(!block_available_left||!block_available_up)
printf("!!invalid intrapred mode %d!! %d \n",predmode, img->current_mb_nr);
for(y=0UL;y<bs_y;y++)
for(x=0UL;x<bs_x;x++)
img->mpr[x+x_off][y+y_off]=EP[(int)x-(int)y];
break;
case DOWN_LEFT_PRED:// 4 up-right bidirectional
if(!block_available_left||!block_available_up)
printf("!!invalid intrapred mode %d!! %d \n",predmode, img->current_mb_nr);
for(y=0UL;y<bs_y;y++)
for(x=0UL;x<bs_x;x++)
img->mpr[x+x_off][y+y_off]=(EP[2+x+y]+EP[-2-(int)(x+y)])>>1;
break;
}//end switch predmode
return DECODING_OK;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -