📄 macroblock.c
字号:
*/
void readCBPandCoeffsFromNAL(struct img_par *img,struct inp_par *inp)
{
int i,j,k;
int level, run;
int mb_nr = img->current_mb_nr;
int ii,jj;
int i1,j1, m2,jg2;
Macroblock *currMB = &img->mb_data[mb_nr];
int cbp;
SyntaxElement currSE;
Slice *currSlice = img->currentSlice;
DataPartition *dP;
int *partMap = assignSE2partition[currSlice->dp_mode];
int iii,jjj;
int coef_ctr, len, i0,j0;
int ll;
int scan_loop_ctr;
int block_x,block_y;
int scan_mode, start_scan;
// read CBP if not new intra mode
if (img->imod != INTRA_MB_NEW)
{
if (img->imod == INTRA_MB_OLD)
currSE.type = SE_CBP_INTRA;
else
currSE.type = SE_CBP_INTER;
if(img->type == B_IMG_1 || img->type == B_IMG_MULT)
dP = &(currSlice->partArr[partMap[SE_BFRAME]]);
else
dP = &(currSlice->partArr[partMap[currSE.type]]);
if (inp->symbol_mode == UVLC || dP->bitstream->ei_flag)
{
if (img->imod == INTRA_MB_OLD)
currSE.mapping = linfo_cbp_intra;
else
currSE.mapping = linfo_cbp_inter;
}
else
currSE.reading = readCBPFromBuffer_CABAC;
#if TRACE
snprintf(currSE.tracestring, TRACESTRING_SIZE, " CBP ");
#endif
dP->readSyntaxElement(&currSE,img,inp,dP);
currMB->cbp = cbp = currSE.value1;
// Delta quant only if nonzero coeffs
if (cbp !=0)
{
if (currMB->intraOrInter == INTER_MB)
currSE.type = SE_DELTA_QUANT_INTER;
else
currSE.type = SE_DELTA_QUANT_INTRA;
if(img->type == B_IMG_1 || img->type == B_IMG_MULT)
dP = &(currSlice->partArr[partMap[SE_BFRAME]]);
else
dP = &(currSlice->partArr[partMap[currSE.type]]);
if (inp->symbol_mode == UVLC || dP->bitstream->ei_flag)
currSE.mapping = linfo_dquant;
else
currSE.reading= readDquantFromBuffer_CABAC;
#if TRACE
snprintf(currSE.tracestring, TRACESTRING_SIZE, " Delta quant ");
#endif
dP->readSyntaxElement(&currSE,img,inp,dP);
currMB->delta_quant = currSE.value1;
img->qp= (img->qp+currMB->delta_quant+32)%32;
}
}
else
cbp = currMB->cbp;
for (i=0;i<BLOCK_SIZE;i++)
for (j=0;j<BLOCK_SIZE;j++)
for(iii=0;iii<BLOCK_SIZE;iii++)
for(jjj=0;jjj<BLOCK_SIZE;jjj++)
img->cof[i][j][iii][jjj]=0;// reset luma coeffs
if(img->imod==INTRA_MB_NEW) // read DC coeffs for new intra modes
{
if (currMB->intraOrInter == INTER_MB)
currSE.type = SE_DELTA_QUANT_INTER;
else
currSE.type = SE_DELTA_QUANT_INTRA;
if(img->type == B_IMG_1 || img->type == B_IMG_MULT)
dP = &(currSlice->partArr[partMap[SE_BFRAME]]);
else
dP = &(currSlice->partArr[partMap[currSE.type]]);
if (inp->symbol_mode == UVLC || dP->bitstream->ei_flag)
currSE.mapping = linfo_dquant;
else
currSE.reading= readDquantFromBuffer_CABAC;
#if TRACE
snprintf(currSE.tracestring, TRACESTRING_SIZE, " Delta quant ");
#endif
dP->readSyntaxElement(&currSE,img,inp,dP);
currMB->delta_quant = currSE.value1;
img->qp= (img->qp+currMB->delta_quant+32)%32;
for (i=0;i<BLOCK_SIZE;i++)
for (j=0;j<BLOCK_SIZE;j++)
img->ipredmode[img->block_x+i+1][img->block_y+j+1]=0;
// //////
currSE.type = SE_LUM_DC_INTRA;
if(img->type == B_IMG_1 || img->type == B_IMG_MULT)
dP = &(currSlice->partArr[partMap[SE_BFRAME]]);
else
dP = &(currSlice->partArr[partMap[currSE.type]]);
if (inp->symbol_mode == UVLC || dP->bitstream->ei_flag)
currSE.mapping = linfo_levrun_inter;
else
{
currSE.reading = readRunLevelFromBuffer_CABAC;
currSE.context = 3; // for choosing context model
}
// ////////////
coef_ctr=-1;
level = 1; // just to get inside the loop
for(k=0;(k<17) && (level!=0);k++)
{
#if TRACE
snprintf(currSE.tracestring, TRACESTRING_SIZE, "DC luma 16x16 ");
#endif
dP->readSyntaxElement(&currSE,img,inp,dP);
level = currSE.value1;
run = currSE.value2;
len = currSE.len;
if (level != 0) // leave if len=1
{
coef_ctr=coef_ctr+run+1;
i0=SNGL_SCAN[coef_ctr][0];
j0=SNGL_SCAN[coef_ctr][1];
img->cof[i0][j0][0][0]=level;// add new intra DC coeff
}
}
itrans_2(img);// transform new intra DC
}
if (img->imod == INTRA_MB_OLD && img->qp < 24)
scan_mode=DOUBLE_SCAN;
else
scan_mode=SINGLE_SCAN;
// luma coefficients
for (block_y=0; block_y < 4; block_y += 2) // all modes
{
for (block_x=0; block_x < 4; block_x += 2)
{
for (j=block_y; j < block_y+2; j++)
{
jj=j/2;
for (i=block_x; i < block_x+2; i++)
{
ii=i/2;
if (img->imod == INTRA_MB_NEW)
start_scan = 1; // skip DC coeff
else
start_scan = 0; // take all coeffs
if((cbp & (int)pow(2,(ii+2*jj))) != 0) // are there any coeff in current block at all
{
if (scan_mode==SINGLE_SCAN)
{
coef_ctr=start_scan-1;
level = 1;
for(k=start_scan;(k<17) && (level!=0);k++)
{
/*
* make distinction between INTRA and INTER coded
* luminance coefficients
*/
if (k == 0)
{
if (img->imod == INTRA_MB_OLD || img->imod == INTRA_MB_NEW)
{
currSE.context = 2; // for choosing context model
currSE.type = SE_LUM_DC_INTRA;
}
else
{
currSE.context = 1; // for choosing context model
currSE.type = SE_LUM_DC_INTER;
}
}
else
{
if (img->imod == INTRA_MB_OLD /*|| img->imod == INTRA_MB_NEW*/)
{
currSE.context = 2; // for choosing context model
currSE.type = SE_LUM_AC_INTRA;
}
else if ( img->imod == INTRA_MB_NEW )
{
currSE.context = 4; // for choosing context model
currSE.type = SE_LUM_AC_INTRA;
}
else
{
currSE.context = 1; // for choosing context model
currSE.type = SE_LUM_AC_INTER;
}
}
#if TRACE
snprintf(currSE.tracestring, TRACESTRING_SIZE, " Luma sng ");
#endif
if(img->type == B_IMG_1 || img->type == B_IMG_MULT)
dP = &(currSlice->partArr[partMap[SE_BFRAME]]);
else
dP = &(currSlice->partArr[partMap[currSE.type]]);
if (inp->symbol_mode == UVLC || dP->bitstream->ei_flag)
currSE.mapping = linfo_levrun_inter;
else
currSE.reading = readRunLevelFromBuffer_CABAC;
dP->readSyntaxElement(&currSE,img,inp,dP);
level = currSE.value1;
run = currSE.value2;
len = currSE.len;
if (level != 0) // leave if len=1
{
coef_ctr += run+1;
currMB->cbp_blk |= 1 << ((j<<2) + i) ;
i0=SNGL_SCAN[coef_ctr][0];
j0=SNGL_SCAN[coef_ctr][1];
img->cof[i][j][i0][j0]=level*JQ1[img->qp];
}
}
}
else // double scan (old intra with QP<24
{
for(scan_loop_ctr=0;scan_loop_ctr<2;scan_loop_ctr++)
{
coef_ctr=start_scan-1;
level=1; // just to get inside the loop
for(k=0; k<9 && level!=0;k++)
{
if (k == 0)
currSE.type = SE_LUM_DC_INTRA; // element is of type DC
else
currSE.type = SE_LUM_AC_INTRA; // element is of type AC
#if TRACE
snprintf(currSE.tracestring, TRACESTRING_SIZE, "Luma dbl(%2d,%2d) ",scan_loop_ctr,k);
#endif
if(img->type == B_IMG_1 || img->type == B_IMG_MULT)
dP = &(currSlice->partArr[partMap[SE_BFRAME]]);
else
dP = &(currSlice->partArr[partMap[currSE.type]]);
if (inp->symbol_mode == UVLC || dP->bitstream->ei_flag)
currSE.mapping = linfo_levrun_intra;
else
{
currSE.context = 0; // for choosing context model
currSE.reading = readRunLevelFromBuffer_CABAC;
}
dP->readSyntaxElement(&currSE,img,inp,dP);
level = currSE.value1;
run = currSE.value2;
len = currSE.len;
if (level != 0) // leave if len=1
{
coef_ctr=coef_ctr+run+1;
currMB->cbp_blk |= 1 << ((j<<2) + i) ;
i0=DBL_SCAN[coef_ctr][0][scan_loop_ctr];
j0=DBL_SCAN[coef_ctr][1][scan_loop_ctr];
img->cof[i][j][i0][j0]=level*JQ1[img->qp];
}
}
}
}
}
}
}
}
}
for (j=4;j<6;j++) // reset all chroma coeffs before read
for (i=0;i<4;i++)
for (iii=0;iii<4;iii++)
for (jjj=0;jjj<4;jjj++)
img->cof[i][j][iii][jjj]=0;
m2=img->mb_x*2;
jg2=img->mb_y*2;
// chroma 2x2 DC coeff
if(cbp>15)
{
for (ll=0;ll<3;ll+=2)
{
for (i=0;i<4;i++)
img->cofu[i]=0;
coef_ctr=-1;
level=1;
for(k=0;(k<5)&&(level!=0);k++)
{
if ( img->imod == INTRA_MB_OLD || img->imod == INTRA_MB_NEW)
{
currSE.context = 6; // for choosing context model
currSE.type = SE_CHR_DC_INTRA;
}
else
{
currSE.context = 5; // for choosing context model
currSE.type = SE_CHR_DC_INTER;
}
#if TRACE
snprintf(currSE.tracestring, TRACESTRING_SIZE, " 2x2 DC Chroma ");
#endif
if(img->type == B_IMG_1 || img->type == B_IMG_MULT)
dP = &(currSlice->partArr[partMap[SE_BFRAME]]);
else
dP = &(currSlice->partArr[partMap[currSE.type]]);
if (inp->symbol_mode == UVLC || dP->bitstream->ei_flag)
currSE.mapping = linfo_levrun_c2x2;
else
currSE.reading = readRunLevelFromBuffer_CABAC;
dP->readSyntaxElement(&currSE,img,inp,dP);
level = currSE.value1;
run = currSE.value2;
len = currSE.len;
if (level != 0)
{
currMB->cbp_blk |= 0xf0000 << (ll<<1) ;
coef_ctr=coef_ctr+run+1;
// Bug: img->cofu has only 4 entries, hence coef_ctr MUST be <4 (which is
// caught by the assert(). If it is bigger than 4, it starts patching the
// img->predmode pointer, which leads to bugs later on.
//
// This assert() should be left in the code, because it captures a very likely
// bug early when testing in error prone environments (or when testing NAL
// functionality).
assert (coef_ctr < 4);
img->cofu[coef_ctr]=level*JQ1[QP_SCALE_CR[img->qp]];
}
}
if ((img->type==SP_IMG_1 || img->type==SP_IMG_MULT) && (currMB->mb_imode == INTRA_MB_INTER))
{
img->cof[0+ll][4][0][0]=img->cofu[0]/JQ1[QP_SCALE_CR[img->qp]];
img->cof[1+ll][4][0][0]=img->cofu[1]/JQ1[QP_SCALE_CR[img->qp]];
img->cof[0+ll][5][0][0]=img->cofu[2]/JQ1[QP_SCALE_CR[img->qp]];
img->cof[1+ll][5][0][0]=img->cofu[3]/JQ1[QP_SCALE_CR[img->qp]];
}
else
{
img->cof[0+ll][4][0][0]=(img->cofu[0]+img->cofu[1]+img->cofu[2]+img->cofu[3])/2;
img->cof[1+ll][4][0][0]=(img->cofu[0]-img->cofu[1]+img->cofu[2]-img->cofu[3])/2;
img->cof[0+ll][5][0][0]=(img->cofu[0]+img->cofu[1]-img->cofu[2]-img->cofu[3])/2;
img->cof[1+ll][5][0][0]=(img->cofu[0]-img->cofu[1]-img->cofu[2]+img->cofu[3])/2;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -