📄 macroblock.cpp
字号:
*
* Luma Blocks
************************************************************************
*/
int predict_nnz(struct img_par *img, int i,int j)
{
PixelPos pix;
int pred_nnz = 0;
int cnt = 0;
int mb_nr = img->current_mb_nr;
// left block
getLuma4x4Neighbour(mb_nr, i, j, -1, 0, &pix);
if (pix.available)
{
pred_nnz = img->nz_coeff [pix.mb_addr ][pix.x][pix.y];
cnt++;
}
// top block
getLuma4x4Neighbour(mb_nr, i, j, 0, -1, &pix);
if (pix.available)
{
pred_nnz += img->nz_coeff [pix.mb_addr ][pix.x][pix.y];
cnt++;
}
if (cnt==2)
{
pred_nnz++;
pred_nnz/=cnt;
}
return pred_nnz;
}
/*!
************************************************************************
* \brief
* Get the Prediction from the Neighboring Blocks for Number of Nonzero Coefficients
*
* Chroma Blocks
************************************************************************
*/
int predict_nnz_chroma(struct img_par *img, int i,int j)
{
PixelPos pix;
int pred_nnz = 0;
int cnt =0;
int mb_nr = img->current_mb_nr;
// left block
getChroma4x4Neighbour(mb_nr, i&0x0001, j-4, -1, 0, &pix);
if (pix.available)
{
pred_nnz = img->nz_coeff [pix.mb_addr ][2 * (i/2) + pix.x][4 + pix.y];
cnt++;
}
// top block
getChroma4x4Neighbour(mb_nr, i&0x0001, j-4, 0, -1, &pix);
if (pix.available)
{
pred_nnz += img->nz_coeff [pix.mb_addr ][2 * (i/2) + pix.x][4 + pix.y];
cnt++;
}
if (cnt==2)
{
pred_nnz++;
//pred_nnz/=cnt;
pred_nnz>>=1;
}
return pred_nnz;
}
/*!
************************************************************************
* \brief
* Reads coeff of an 4x4 block (CAVLC)
*
* \author
* Karl Lillevold <karll@real.com>
* contributions by James Au <james@ubvideo.com>
************************************************************************
*/
void readCoeff4x4_CAVLC (struct img_par *img,
int block_type,
int i, int j, int levarr[16], int runarr[16],
int *number_coefficients)
{
int mb_nr = img->current_mb_nr;
Macroblock *currMB = &img->mb_data[mb_nr];
SyntaxElement currSE;
Slice *currSlice = img->currentSlice;
DataPartition *dP;
int *partMap = assignSE2partition[currSlice->dp_mode];
int k, code, vlcnum;
int numcoeff, numtrailingones, numcoeff_vlc;
int level_two_or_higher;
int numones, totzeros, level, cdc=0, cac=0;
int zerosleft, ntr, dptype = 0;
int max_coeff_num = 0, nnz;
char type[15];
int incVlc[] = {0,3,6,12,24,48,32768}; // maximum vlc = 6
numcoeff = 0;
switch (block_type)
{
case LUMA:
max_coeff_num = 16;
sprintf(type, "%s", "Luma");
if (IS_INTRA (currMB))
{
dptype = SE_LUM_AC_INTRA;
}
else
{
dptype = SE_LUM_AC_INTER;
}
break;
case LUMA_INTRA16x16DC:
max_coeff_num = 16;
sprintf(type, "%s", "Lum16DC");
dptype = SE_LUM_DC_INTRA;
break;
case LUMA_INTRA16x16AC:
max_coeff_num = 15;
sprintf(type, "%s", "Lum16AC");
dptype = SE_LUM_AC_INTRA;
break;
case CHROMA_DC:
max_coeff_num = 4;
cdc = 1;
sprintf(type, "%s", "ChrDC");
if (IS_INTRA (currMB))
{
dptype = SE_CHR_DC_INTRA;
}
else
{
dptype = SE_CHR_DC_INTER;
}
break;
case CHROMA_AC:
max_coeff_num = 15;
cac = 1;
sprintf(type, "%s", "ChrAC");
if (IS_INTRA (currMB))
{
dptype = SE_CHR_AC_INTRA;
}
else
{
dptype = SE_CHR_AC_INTER;
}
break;
default:
error ("readCoeff4x4_CAVLC: invalid block type", 600);
break;
}
currSE.type = dptype;
dP = &(currSlice->partArr[partMap[dptype]]);
img->nz_coeff[img->current_mb_nr][i][j] = 0;
if (!cdc)
{
// luma or chroma AC
if (!cac)
{
nnz = predict_nnz(img, i, j);
}
else
{
nnz = predict_nnz_chroma(img, i, j);
}
numcoeff_vlc = (nnz < 2)? 0:((nnz < 4)? 1:((nnz < 8)? 2:3));
currSE.value1 = numcoeff_vlc;
readSyntaxElement_NumCoeffTrailingOnes(&currSE, dP, type);
numcoeff = currSE.value1;
numtrailingones = currSE.value2;
img->nz_coeff[img->current_mb_nr][i][j] = numcoeff;
}
else
{
// chroma DC
readSyntaxElement_NumCoeffTrailingOnesChromaDC(&currSE, dP);
numcoeff = currSE.value1;
numtrailingones = currSE.value2;
}
memset(levarr,0,max_coeff_num*4);
memset(runarr,0,max_coeff_num*4);
numones = numtrailingones;
*number_coefficients = numcoeff;
if (numcoeff)
{
if (numtrailingones)
{
currSE.len = numtrailingones;
readSyntaxElement_FLC (&currSE, dP->bitstream);
code = currSE.inf;
ntr = numtrailingones;
for (k = numcoeff-1; k > numcoeff-1-numtrailingones; k--)
{
ntr --;
if ((code>>ntr)&1)
levarr[k] = -1;
else
levarr[k] = 1;
}
}
// decode levels
level_two_or_higher = 1;
if (numcoeff > 3 && numtrailingones == 3)
level_two_or_higher = 0;
if (numcoeff > 10 && numtrailingones < 3)
vlcnum = 1;
else
vlcnum = 0;
for (k = numcoeff - 1 - numtrailingones; k >= 0; k--)
{
if (vlcnum == 0)
readSyntaxElement_Level_VLC0(&currSE, dP);
else
readSyntaxElement_Level_VLCN(&currSE, vlcnum, dP);
if (level_two_or_higher)
{
if (currSE.inf > 0)
currSE.inf ++;
else
currSE.inf --;
level_two_or_higher = 0;
}
level = levarr[k] = currSE.inf;
if (abs(level) == 1)
numones ++;
// update VLC table
if (abs(level)>incVlc[vlcnum])
vlcnum++;
if (k == numcoeff - 1 - numtrailingones && abs(level)>3)
vlcnum = 2;
}
if (numcoeff < max_coeff_num)
{
// decode total run
vlcnum = numcoeff-1;
currSE.value1 = vlcnum;
if (cdc)
readSyntaxElement_TotalZerosChromaDC(&currSE, dP);
else
readSyntaxElement_TotalZeros(&currSE, dP);
totzeros = currSE.value1;
}
else
{
totzeros = 0;
}
// decode run before each coefficient
zerosleft = totzeros;
i = numcoeff-1;
if (zerosleft > 0 && i > 0)
{
do
{
// select VLC for runbefore
vlcnum = zerosleft - 1;
if (vlcnum > RUNBEFORE_NUM-1)
vlcnum = RUNBEFORE_NUM-1;
currSE.value1 = vlcnum;
readSyntaxElement_Run(&currSE, dP);
runarr[i] = currSE.value1;
zerosleft -= runarr[i];
i --;
} while (zerosleft != 0 && i != 0);
}
runarr[i] = zerosleft;
} // if numcoeff
}
/*!
************************************************************************
* \brief
* Get coded block pattern and coefficients (run/level)
* from the NAL
************************************************************************
*/
void readCBPandCoeffsFromNAL(struct img_par *img)
{
int i,j,k;
int level;
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 coef_ctr, i0, j0, b8;
int ll;
int block_x,block_y;
int start_scan;
int uv;
int qp_uv;
// int run, len;
int levarr[16], runarr[16], numcoeff;
int qp_per = (img->qp-MIN_QP)/6;
int qp_rem = (img->qp-MIN_QP)%6;
int qp_per_uv = QP_SCALE_CR[img->qp-MIN_QP]/6;
int qp_rem_uv = QP_SCALE_CR[img->qp-MIN_QP]%6;
// QPI
qp_uv = img->qp + active_pps->chroma_qp_index_offset;
qp_uv = Clip3(0, 51, qp_uv);
qp_per_uv = QP_SCALE_CR[qp_uv-MIN_QP]/6;
qp_rem_uv = QP_SCALE_CR[qp_uv-MIN_QP]%6;
// read CBP if not new intra mode
if (!IS_NEWINTRA (currMB))
{
if (IS_OLDINTRA (currMB) || currMB->mb_type == SI4MB ) currSE.type = SE_CBP_INTRA;
else currSE.type = SE_CBP_INTER;
dP = &(currSlice->partArr[partMap[currSE.type]]);
if (IS_OLDINTRA (currMB) || currMB->mb_type == SI4MB) currSE.mapping = linfo_cbp_intra;
else currSE.mapping = linfo_cbp_inter;
//coded_block_pattern
dP->readSyntaxElement(&currSE,dP);
currMB->cbp = cbp = currSE.value1;
// Delta quant only if nonzero coeffs
if (cbp !=0)
{
if (IS_INTER (currMB)) currSE.type = SE_DELTA_QUANT_INTER;
else currSE.type = SE_DELTA_QUANT_INTRA;
dP = &(currSlice->partArr[partMap[currSE.type]]);
currSE.mapping = linfo_se;
//mb_qp_delta
dP->readSyntaxElement(&currSE,dP);
currMB->delta_quant = currSE.value1;
img->qp= (img->qp-MIN_QP+currMB->delta_quant+(MAX_QP-MIN_QP+1))%(MAX_QP-MIN_QP+1)+MIN_QP;
}
}
else
{
cbp = currMB->cbp;
}
memset(img->cof,0,1536); //1536 = 4*6*4*4*sizeof(int)/sizeof(byte)
if (IS_NEWINTRA (currMB)) // read DC coeffs for new intra modes
{
currSE.type = SE_DELTA_QUANT_INTRA;
dP = &(currSlice->partArr[partMap[currSE.type]]);
currSE.mapping = linfo_se;
dP->readSyntaxElement(&currSE,dP);
currMB->delta_quant = currSE.value1;
img->qp= (img->qp-MIN_QP+currMB->delta_quant+(MAX_QP-MIN_QP+1))%(MAX_QP-MIN_QP+1)+MIN_QP;
for (i=0;i<4;i++)
for (j=0;j<4;j++)
img->ipredmode[img->block_x+i][img->block_y+j]=DC_PRED;
readCoeff4x4_CAVLC(img, LUMA_INTRA16x16DC, 0, 0,
levarr, runarr, &numcoeff);
coef_ctr=-1;
level = 1; // just to get inside the loop
for(k = 0; k < numcoeff; k++)
{
if (levarr[k] != 0) // leave if len=1
{
coef_ctr=coef_ctr+runarr[k]+1;
i0=SNGL_SCAN[coef_ctr][0];
j0=SNGL_SCAN[coef_ctr][1];
img->cof[i0][j0][0][0]=levarr[k];// add new intra DC coeff
}
}
itrans_2(img);// transform new intra DC
}
qp_per = (img->qp-MIN_QP)/6;
qp_rem = (img->qp-MIN_QP)%6;
qp_uv = img->qp + active_pps->chroma_qp_index_offset;
qp_uv = Clip3(0, 51, qp_uv);
qp_per_uv = QP_SCALE_CR[qp_uv-MIN_QP]/6;
qp_rem_uv = QP_SCALE_CR[qp_uv-MIN_QP]%6;
currMB->qp = img->qp;
// luma coefficients
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -