📄 rdoq_cavlc.c
字号:
if (numcoef > 1 && zerosleft)
{
vlcnum = imin(zerosleft - 1, RUNBEFORE_NUM_M1);
se.len = vlcnum;
no_bits += Run_lentab[se.len][se.value1];
zerosleft -= run;
numcoef --;
}
}
}
return no_bits;
}
/*!
****************************************************************************
* \brief
* estimate run and level for CAVLC
****************************************************************************
*/
void est_RunLevel_CAVLC(levelDataStruct *levelData, int *levelTrellis, int block_type,
int b8, int b4, int coeff_num, double lambda)
{
int k, lastnonzero = -1, coeff_ctr;
int level_to_enc[16] = {0}, sign_to_enc[16] = {0};
int cstat, bestcstat = 0;
int nz_coeff=0;
double lagr, lagrAcc = 0, minlagr = 0;
int subblock_x = ((b8&0x1)==0)?(((b4&0x1)==0)?0:1):(((b4&0x1)==0)?2:3);
// horiz. position for coeff_count context
int subblock_y = (b8<2)?((b4<2)?0:1):((b4<2)?2:3);
// vert. position for coeff_count context
int nnz;
levelDataStruct *dataLevel = &levelData[0];
if (block_type != CHROMA_AC)
nnz = predict_nnz(&img->mb_data[img->current_mb_nr], LUMA, subblock_x,subblock_y);
else
nnz = predict_nnz_chroma(&img->mb_data[img->current_mb_nr], img->subblock_x, img->subblock_y+4);
for (coeff_ctr=0;coeff_ctr < coeff_num;coeff_ctr++)
{
levelTrellis[coeff_ctr] = 0;
for(k=0; k < dataLevel->noLevels; k++)
{
dataLevel->errLevel[k] /= 32768;
}
lagrAcc += dataLevel->errLevel[dataLevel->noLevels - 1];
level_to_enc[coeff_ctr] = dataLevel->pre_level;
sign_to_enc[coeff_ctr] = dataLevel->sign;
if(dataLevel->noLevels > 1)
{
dataLevel->coeff_ctr = coeff_ctr;
lastnonzero = coeff_ctr;
}
else
dataLevel->coeff_ctr = -1;
dataLevel++;
}
if(lastnonzero != -1)
{
//sort the coefficients based on their absolute value
qsort(levelData, lastnonzero + 1, sizeof(levelDataStruct), cmp);
dataLevel = &levelData[lastnonzero];
for(coeff_ctr = lastnonzero; coeff_ctr >= 0; coeff_ctr--) // go over all coeff
{
if(dataLevel->noLevels == 1)
{
dataLevel--;
continue;
}
lagrAcc -= dataLevel->errLevel[dataLevel->noLevels-1];
for(cstat=0; cstat<dataLevel->noLevels; cstat++) // go over all states of cur coeff k
{
level_to_enc[dataLevel->coeff_ctr] = dataLevel->level[cstat];
lagr = lagrAcc + dataLevel->errLevel[cstat];
lagr += lambda * est_CAVLC_bits(levelData, level_to_enc, sign_to_enc, nnz, block_type);
if(cstat==0 || lagr<minlagr)
{
minlagr = lagr;
bestcstat = cstat;
}
}
lagrAcc += dataLevel->errLevel[bestcstat];
level_to_enc[dataLevel->coeff_ctr] = dataLevel->level[bestcstat];
dataLevel--;
}
for(coeff_ctr = 0; coeff_ctr <= lastnonzero; coeff_ctr++)
{
levelTrellis[coeff_ctr] = level_to_enc[coeff_ctr];
if (level_to_enc[coeff_ctr] != 0)
nz_coeff++;
}
}
img->nz_coeff [img->current_mb_nr ][subblock_x][subblock_y] = nz_coeff;
}
/*!
****************************************************************************
* \brief
* Initialize levelData
****************************************************************************
*/
void init_trellis_data_4x4_CAVLC(int (*tblock)[16], int block_x, int qp_per, int qp_rem, int **levelscale, int **leveloffset,
const byte *p_scan, Macroblock *currMB, levelDataStruct *dataLevel, int type)
{
int i, j, coeff_ctr;
static int *m7;
int end_coeff_ctr = ( ( type == LUMA_4x4 ) ? 16 : 15 );
int q_bits = Q_BITS + qp_per;
int q_offset = ( 1 << (q_bits - 1) );
int level, lowerInt, k;
double err, estErr;
for (coeff_ctr = 0; coeff_ctr < end_coeff_ctr; coeff_ctr++)
{
i = *p_scan++; // horizontal position
j = *p_scan++; // vertical position
m7 = &tblock[j][block_x + i];
if (*m7 == 0)
{
dataLevel->levelDouble = 0;
dataLevel->level[0] = 0;
dataLevel->noLevels = 1;
err = 0.0;
dataLevel->errLevel[0] = 0.0;
dataLevel->pre_level = 0;
dataLevel->sign = 0;
}
else
{
estErr = ((double) estErr4x4[qp_rem][j][i]) / norm_factor_4x4;
dataLevel->levelDouble = iabs(*m7 * levelscale[j][i]);
level = (dataLevel->levelDouble >> q_bits);
lowerInt = (((int)dataLevel->levelDouble - (level << q_bits)) < q_offset )? 1 : 0;
dataLevel->level[0] = 0;
if (level == 0 && lowerInt == 1)
{
dataLevel->noLevels = 1;
}
else if (level == 0 && lowerInt == 0)
{
dataLevel->level[1] = 1;
dataLevel->noLevels = 2;
}
else if (level > 0 && lowerInt == 1)
{
dataLevel->level[1] = level;
dataLevel->noLevels = 2;
}
else
{
dataLevel->level[1] = level;
dataLevel->level[2] = level + 1;
dataLevel->noLevels = 3;
}
for (k = 0; k < dataLevel->noLevels; k++)
{
err = (double)(dataLevel->level[k] << q_bits) - (double)dataLevel->levelDouble;
dataLevel->errLevel[k] = (err * err * estErr);
}
if(dataLevel->noLevels == 1)
dataLevel->pre_level = 0;
else
dataLevel->pre_level = (iabs (*m7) * levelscale[j][i] + leveloffset[j][i]) >> q_bits;
dataLevel->sign = isign(*m7);
}
dataLevel++;
}
}
/*!
****************************************************************************
* \brief
* Initialize levelData for Luma DC
****************************************************************************
*/
void init_trellis_data_DC_CAVLC(int (*tblock)[4], int qp_per, int qp_rem,
int levelscale, int leveloffset, const byte *p_scan, Macroblock *currMB,
levelDataStruct *dataLevel, int type)
{
int i, j, coeff_ctr, end_coeff_ctr = 16;
int q_bits = Q_BITS + qp_per + 1;
int q_offset = ( 1 << (q_bits - 1) );
int level, lowerInt, k;
int *m7;
double err, estErr = (double) estErr4x4[qp_rem][0][0] / norm_factor_4x4; // note that we could also use int64
for (coeff_ctr = 0; coeff_ctr < end_coeff_ctr; coeff_ctr++)
{
i = *p_scan++; // horizontal position
j = *p_scan++; // vertical position
m7 = &tblock[j][i];
if (*m7 == 0)
{
dataLevel->levelDouble = 0;
dataLevel->level[0] = 0;
dataLevel->noLevels = 1;
err = 0.0;
dataLevel->errLevel[0] = 0.0;
dataLevel->pre_level = 0;
dataLevel->sign = 0;
}
else
{
dataLevel->levelDouble = iabs(*m7 * levelscale);
level = (dataLevel->levelDouble >> q_bits);
lowerInt=( ((int)dataLevel->levelDouble - (level<<q_bits)) < q_offset )? 1 : 0;
dataLevel->level[0] = 0;
if (level == 0 && lowerInt == 1)
{
dataLevel->noLevels = 1;
}
else if (level == 0 && lowerInt == 0)
{
dataLevel->level[1] = 1;
dataLevel->noLevels = 2;
}
else if (level > 0 && lowerInt == 1)
{
dataLevel->level[1] = level;
dataLevel->noLevels = 2;
}
else
{
dataLevel->level[1] = level;
dataLevel->level[2] = level + 1;
dataLevel->noLevels = 3;
}
for (k = 0; k < dataLevel->noLevels; k++)
{
err = (double)(dataLevel->level[k] << q_bits) - (double)dataLevel->levelDouble;
dataLevel->errLevel[k] = (err * err * estErr);
}
if(dataLevel->noLevels == 1)
dataLevel->pre_level = 0;
else
dataLevel->pre_level = (iabs (*m7) * levelscale + leveloffset) >> q_bits;
dataLevel->sign = isign(*m7);
}
dataLevel++;
}
}
/*!
****************************************************************************
* \brief
* Initialize levelData
****************************************************************************
*/
void init_trellis_data_8x8_CAVLC(int (*tblock)[16], int block_x, int qp_per, int qp_rem, int **levelscale, int **leveloffset,
const byte *p_scan, Macroblock *currMB, levelDataStruct levelData[4][16])
{
int i, j, block, coeff_ctr;
static int *m7;
int q_bits = Q_BITS_8 + qp_per;
int q_offset = ( 1 << (q_bits - 1) );
double err, estErr;
int level, lowerInt, k;
levelDataStruct *dataLevel = &levelData[0][0];
for (coeff_ctr = 0; coeff_ctr < 16; coeff_ctr++)
{
for (block = 0; block < 4; block++)
{
i = *p_scan++; // horizontal position
j = *p_scan++; // vertical position
m7 = &tblock[j][block_x + i];
dataLevel = &levelData[block][coeff_ctr];
if (*m7 == 0)
{
dataLevel->levelDouble = 0;
dataLevel->level[0] = 0;
dataLevel->noLevels = 1;
err = 0.0;
dataLevel->errLevel[0] = 0.0;
dataLevel->pre_level = 0;
dataLevel->sign = 0;
}
else
{
estErr = (double) estErr8x8[qp_rem][j][i] / norm_factor_8x8;
dataLevel->levelDouble = iabs(*m7 * levelscale[j][i]);
level = (dataLevel->levelDouble >> q_bits);
lowerInt = (((int)dataLevel->levelDouble - (level << q_bits)) < q_offset ) ? 1 : 0;
dataLevel->level[0] = 0;
if (level == 0 && lowerInt == 1)
{
dataLevel->noLevels = 1;
}
else if (level == 0 && lowerInt == 0)
{
dataLevel->level[1] = 1;
dataLevel->noLevels = 2;
}
else if (level > 0 && lowerInt == 1)
{
if (level > 1)
{
dataLevel->level[1] = level - 1;
dataLevel->level[2] = level;
dataLevel->noLevels = 3;
}
else
{
dataLevel->level[1] = level;
dataLevel->noLevels = 2;
}
}
else
{
dataLevel->level[1] = level;
dataLevel->level[2] = level + 1;
dataLevel->noLevels = 3;
}
for (k = 0; k < dataLevel->noLevels; k++)
{
err = (double)(dataLevel->level[k] << q_bits) - (double)dataLevel->levelDouble;
dataLevel->errLevel[k] = err * err * estErr;
}
if(dataLevel->noLevels == 1)
dataLevel->pre_level = 0;
else
dataLevel->pre_level = (iabs (*m7) * levelscale[j][i] + leveloffset[j][i]) >> q_bits;
dataLevel->sign = isign(*m7);
}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -