block.c
来自「the newest JM software by h.264 JVT offi」· C语言 代码 · 共 2,206 行 · 第 1/5 页
C
2,206 行
* block_x,block_y: Block position inside a macro block (0,4,8,12).
*
* \par Output:
* nonzero: 0 if no levels are nonzero. 1 if there are nonzero levels. \n
* coeff_cost: Counter for nonzero coefficients, used to discard expensive levels.
*
*
************************************************************************
*/
int dct_4x4_sp(Macroblock *currMB, ColorPlane pl, int block_x,int block_y,int *coeff_cost, int intra, int is_cavlc)
{
int i,j,coeff_ctr;
int qp_const,ilev, level,scan_pos = 0,run = -1;
int nonzero = FALSE;
imgpel **img_enc = enc_picture->p_curr_img;
imgpel **mb_pred = img->mb_pred[pl];
int **mb_rres = img->mb_rres[pl];
int **mb_ores = img->mb_ores[pl];
int c_err,qp_const2;
int qp = currMB->qp_scaled[pl];
int qp_sp = (currMB->qpsp);
const byte *c_cost = COEFF_COST4x4[params->disthres];
const byte (*pos_scan)[2] = currMB->is_field_mode ? FIELD_SCAN : SNGL_SCAN;
int pos_x = block_x >> BLOCK_SHIFT;
int pos_y = block_y >> BLOCK_SHIFT;
int b8 = 2*(pos_y >> 1) + (pos_x >> 1);
int b4 = 2*(pos_y & 0x01) + (pos_x & 0x01);
int* ACLevel = img->cofAC[b8][b4][0];
int* ACRun = img->cofAC[b8][b4][1];
// For encoding optimization
int c_err1, c_err2, level1, level2;
double D_dis1, D_dis2;
int len, info;
double lambda_mode = 0.85 * pow (2, (qp - SHIFT_QP)/3.0) * 4;
int qp_per = qp_per_matrix[qp];
int qp_rem = qp_rem_matrix[qp];
int q_bits = Q_BITS + qp_per;
int qp_per_sp = qp_per_matrix[qp_sp];
int qp_rem_sp = qp_rem_matrix[qp_sp];
int q_bits_sp = Q_BITS + qp_per_sp;
levelscale = LevelScale4x4Comp[pl][intra][qp_rem];
invlevelscale = InvLevelScale4x4Comp[pl][intra][qp_rem];
leveloffset = ptLevelOffset4x4[intra][qp];
levelscale_sp = LevelScale4x4Comp[pl][intra][qp_rem_sp];
invlevelscale_sp = InvLevelScale4x4Comp[pl][intra][qp_rem_sp];
leveloffset_sp = ptLevelOffset4x4[intra][qp_sp];
qp_const = (1<<q_bits)/6; // inter
qp_const2 = (1<<q_bits_sp)/2; //sp_pred
// Horizontal transform
for (j=block_y; j< block_x + BLOCK_SIZE; j++)
{
for (i=block_x; i< block_x + BLOCK_SIZE; i++)
{
mb_rres[j][i] = mb_ores[j][i];
mb_rres[j][i]+=mb_pred[j][i];
M1[j][i] = mb_pred[j][i];
}
}
// 4x4 transform
forward4x4(mb_rres, mb_rres, block_y, block_x);
forward4x4(M1, M1, block_y, block_x);
for (coeff_ctr = 0;coeff_ctr < 16;coeff_ctr++)
{
i = pos_scan[coeff_ctr][0];
j = pos_scan[coeff_ctr][1];
run++;
ilev=0;
// decide prediction
// case 1
level1 = (iabs (M1[j][i]) * levelscale_sp[j][i] + qp_const2) >> q_bits_sp;
level1 = (level1 << q_bits_sp) / levelscale_sp[j][i];
c_err1 = mb_rres[j][i] - isignab(level1, M1[j][i]);
level1 = (iabs (c_err1) * levelscale[j][i] + qp_const) >> q_bits;
// case 2
c_err2 = mb_rres[j][i] - M1[j][i];
level2 = (iabs (c_err2) * levelscale[j][i] + qp_const) >> q_bits;
// select prediction
if ((level1 != level2) && (level1 != 0) && (level2 != 0))
{
D_dis1 = mb_rres[j][i] - ((isignab(level1,c_err1) * invlevelscale[j][i] * A[j][i]<< qp_per) >>6) - M1[j][i];
levrun_linfo_inter(level1, run, &len, &info);
D_dis1 = D_dis1 * D_dis1 + lambda_mode * len;
D_dis2 = mb_rres[j][i] - ((isignab(level2,c_err2)*invlevelscale[j][i] * A[j][i]<< qp_per) >>6) - M1[j][i];
levrun_linfo_inter(level2, run, &len, &info);
D_dis2 = D_dis2 * D_dis2 + lambda_mode * len;
if (D_dis1 == D_dis2)
level = (iabs(level1) < iabs(level2)) ? level1 : level2;
else if (D_dis1 < D_dis2)
level = level1;
else
level = level2;
c_err = (level == level1) ? c_err1 : c_err2;
}
else if (level1 == level2)
{
level = level1;
c_err = c_err1;
}
else
{
level = (level1 == 0) ? level1 : level2;
c_err = (level1 == 0) ? c_err1 : c_err2;
}
if (level != 0)
{
nonzero = TRUE;
*coeff_cost += (level > 1) ? MAX_VALUE : c_cost[run];
level = isignab(level,c_err);
ACLevel[scan_pos] = level;
ACRun [scan_pos] = run;
++scan_pos;
run=-1; // reset zero level counter
ilev=((level * invlevelscale[j][i] * A[j][i] << qp_per) >>6);
}
ilev += M1[j][i];
if(!si_frame_indicator && !sp2_frame_indicator)//stores the SP frame coefficients in lrec, will be useful to encode these and create SI or SP switching frame
{
lrec[img->pix_y+block_y+j][img->pix_x+block_x+i]=
isignab((iabs(ilev) * levelscale_sp[j][i] + qp_const2) >> q_bits_sp, ilev);
}
mb_rres[j][i] = isignab((iabs(ilev) * levelscale_sp[j][i] + qp_const2)>> q_bits_sp, ilev) * invlevelscale_sp[j][i] << qp_per_sp;
}
ACLevel[scan_pos] = 0;
// inverse transform
// inverse4x4(mb_rres, mb_rres, block_y, block_x);
inverse4x4(M1, mb_rres, 0, 0);
for (j=0; j < BLOCK_SIZE; j++)
for (i=0; i < BLOCK_SIZE; i++)
{
//printf("%d ",mb_rres[j][i]);
mb_rres[j][i] = iClip1 (img->max_imgpel_value, rshift_rnd_sf(mb_rres[j][i], DQ_BITS));
//printf("%d\n",mb_rres[j][i]);
}
// Decoded block moved to frame memory
for (j=0; j < BLOCK_SIZE; j++)
{
for (i=0; i < BLOCK_SIZE; i++)
{
img_enc[img->pix_y+block_y+j][img->pix_x+block_x+i]= (imgpel) mb_rres[j][i];
//printf("%d\n",mb_rres[j][i]);
}
}
return nonzero;
}
/*!
************************************************************************
* \brief
* Transform,quantization,inverse transform for chroma.
* The main reason why this is done in a separate routine is the
* additional 2x2 transform of DC-coeffs. This routine is called
* once for each of the chroma components.
*
* \par Input:
* uv : Make difference between the U and V chroma component
* cr_cbp: chroma coded block pattern
*
* \par Output:
* cr_cbp: Updated chroma coded block pattern.
************************************************************************
*/
int dct_chroma_sp(Macroblock *currMB, int uv,int cr_cbp, int is_cavlc)
{
int i, j, n2, n1, coeff_ctr;
static int *m1;
int coeff_cost = 0;
int cr_cbp_tmp = 0;
int DCzero = FALSE;
int nonzero[4][4] = {{FALSE}};
int nonezero = FALSE;
const byte *c_cost = COEFF_COST4x4[params->disthres];
int b4;
int* DCLevel = img->cofDC[uv+1][0];
int* DCRun = img->cofDC[uv+1][1];
int* ACLevel;
int* ACRun;
int intra = IS_INTRA (currMB);
int uv_scale = uv * (img->num_blk8x8_uv >> 1);
//FRExt
static const int64 cbpblk_pattern[4]={0, 0xf0000, 0xff0000, 0xffff0000};
int yuv = img->yuv_format;
int b8;
const byte (*pos_scan)[2] = currMB->is_field_mode ? FIELD_SCAN : SNGL_SCAN;
int cur_qp = currMB->qpc[uv] + img->bitdepth_chroma_qp_scale;
int qp_rem = qp_rem_matrix[cur_qp];
int max_imgpel_value_uv = img->max_imgpel_value_comp[uv + 1];
int **mb_rres = img->mb_rres[uv + 1];
int **mb_ores = img->mb_ores[uv + 1];
imgpel **mb_pred = img->mb_pred[uv + 1];
levelscale = LevelScale4x4Comp [uv + 1][intra][qp_rem];
leveloffset = LevelOffset4x4Comp [uv + 1][intra][cur_qp];
invlevelscale = InvLevelScale4x4Comp[uv + 1][intra][qp_rem];
if (currMB->mb_type == P8x8 && currMB->luma_transform_size_8x8_flag)
{
//P8x8, treansform 8x8 chroma adjustments must be stored in a different array to avoid conflict with tranform 4x4
fadjust4x4 = img->AdaptiveRounding ? img->ARCofAdj4x4[uv + 1][4] : NULL;
}
else
{
fadjust4x4 = img->AdaptiveRounding ? img->ARCofAdj4x4[uv + 1][currMB->ar_mode] : NULL;
}
//============= dct transform ===============
for (n2=0; n2 < img->mb_cr_size_y; n2 += BLOCK_SIZE)
{
for (n1=0; n1 < img->mb_cr_size_x; n1 += BLOCK_SIZE)
{
forward4x4(mb_ores, mb_rres, n2, n1);
}
}
if (yuv == YUV420)
{
m1 = M4[0];
//================== CHROMA DC YUV420 ===================
// forward 2x2 hadamard
hadamard2x2(mb_rres, m1);
// Quantization process of chroma 2X2 hadamard transformed DC coeffs.
DCzero = quant_dc_cr(&m1, cur_qp, DCLevel, DCRun, fadjust2x2, levelscale[0][0], invlevelscale[0][0], leveloffset[0][0], pos_scan, is_cavlc);
if (DCzero)
{
currMB->cbp_blk |= 0xf0000 << (uv << 2) ; // if one of the 2x2-DC levels is != 0 set the
cr_cbp=imax(1,cr_cbp); // coded-bit all 4 4x4 blocks (bit 16-19 or 20-23)
}
// Inverse transform of 2x2 DC levels
ihadamard2x2(m1, m1);
mb_rres[0][0] = m1[0];
mb_rres[0][4] = m1[1];
mb_rres[4][0] = m1[2];
mb_rres[4][4] = m1[3];
}
else if (yuv == YUV422)
{
//for YUV422 only
int cur_qp_dc = currMB->qpc[uv] + 3 + img->bitdepth_chroma_qp_scale;
int qp_rem_dc = qp_rem_matrix[cur_qp_dc];
invlevelscaleDC = InvLevelScale4x4Comp[uv + 1][intra][qp_rem_dc];
levelscaleDC = LevelScale4x4Comp [uv + 1][intra][qp_rem_dc];
leveloffsetDC = LevelOffset4x4Comp [uv + 1][intra][cur_qp_dc];
//================== CHROMA DC YUV422 ===================
//pick out DC coeff
for (j=0; j < img->mb_cr_size_y; j+=BLOCK_SIZE)
{
for (i=0; i < img->mb_cr_size_x; i+=BLOCK_SIZE)
M4[i>>2][j>>2]= mb_rres[j][i];
}
// forward hadamard transform. Note that coeffs have been transposed (4x2 instead of 2x4) which makes transform a bit faster
hadamard4x2(M4, M4);
// Quantization process of chroma transformed DC coeffs.
DCzero = quant_dc_cr(M4, cur_qp_dc, DCLevel, DCRun, fadjust4x2, levelscaleDC[0][0], invlevelscaleDC[0][0], leveloffsetDC[0][0], SCAN_YUV422, is_cavlc);
if (DCzero)
{
currMB->cbp_blk |= 0xff0000 << (uv << 3) ; // if one of the DC levels is != 0 set the
cr_cbp=imax(1,cr_cbp); // coded-bit all 4 4x4 blocks (bit 16-31 or 32-47) //YUV444
}
//inverse DC transform. Note that now M4 is transposed back
ihadamard4x2(M4, M4);
// This code assumes sizeof(int) > 16. Therefore, no need to have conditional
for (j = 0; j < 4; j++)
{
mb_rres[j << 2 ][0] = M4[j][0];
mb_rres[j << 2 ][4] = M4[j][1];
}
}
// Quant of chroma AC-coeffs.
for (b8=0; b8 < (img->num_blk8x8_uv >> 1); b8++)
{
for (b4=0; b4 < 4; b4++)
{
int64 uv_cbpblk = ((int64)1) << cbp_blk_chroma[b8 + uv_scale][b4];
n1 = hor_offset[yuv][b8][b4];
n2 = ver_offset[yuv][b8][b4];
ACLevel = img->cofAC[4 + b8 + uv_scale][b4][0];
ACRun = img->cofAC[4 + b8 + uv_scale][b4][1];
// Quantization process
nonzero[n2>>2][n1>>2] = quant_ac4x4cr(&mb_rres[n2], n2, n1, cur_qp, ACLevel, ACRun, &fadjust4x4[n2],
levelscale, invlevelscale, leveloffset, &coeff_cost, pos_scan, c_cost, CHROMA_AC, is_cavlc);
if (nonzero[n2>>2][n1>>2])
{
currMB->cbp_blk |= uv_cbpblk;
cr_cbp_tmp = 2;
nonezero = TRUE;
}
}
}
// Perform thresholding
// * reset chroma coeffs
if(nonezero && coeff_cost < _CHROMA_COEFF_COST_)
{
int64 uv_cbpblk = ((int64)cbpblk_pattern[yuv] << (uv << (1+yuv)));
cr_cbp_tmp = 0;
for (b8 = 0; b8 < (img->num_blk8x8_uv >> 1); b8++)
{
for (b4 = 0; b4 < 4; b4++)
{
n1 = hor_offset[yuv][b8][b4];
n2 = ver_offset[yuv][b8][b4];
if (nonzero[n2>>2][n1>>2] == TRUE)
{
nonzero[n2>>2][n1>>2] = FALSE;
ACLevel = img->cofAC[4 + b8 + uv_scale][b4][0];
ACRun = img->cofAC[4 + b8 + uv_scale][b4][1];
if (DCzero == 0)
currMB->cbp_blk &= ~(uv_cbpblk); // if no chroma DC's: then reset coded-bits of this chroma subblock
ACLevel[0] = 0;
for (coeff_ctr=1; coeff_ctr < 16; coeff_ctr++)// ac coeff
{
mb_rres[n2 + pos_scan[coeff_ctr][1]][n1 + pos_scan[coeff_ctr][0]] = 0;
ACLevel[coeff_ctr] = 0;
}
}
}
}
}
// IDCT.
// Horizontal.
if(cr_cbp_tmp == 2)
cr_cbp = 2;
nonezero = FALSE;
for (n2=0; n2 < img->mb_cr_size_y; n2 += BLOCK_SIZE)
{
for (n1=0; n1 < img->mb_cr_size_x; n1 += BLOCK_SIZE)
{
if (mb_rres[n2][n1] != 0 || nonzero[n2>>2][n1>>2] == TRUE)
{
inverse4x4(mb_rres, mb_rres, n2, n1);
nonezero = TRUE;
}
}
}
// Decoded block moved to memory
if (nonezero == TRUE)
{
SampleReconstruct (enc_picture->imgUV[uv], mb_pred, mb_rres, 0, 0, img->pix_c_y, img->pix_c_x, img->mb_cr_size_x, img->mb_cr_size_y, max_imgpel_value_uv, DQ_BITS);
}
else
{
for (j=0; j < img->mb_cr_size_y; j++)
{
memcpy(&enc_picture->imgUV[uv][img->pix_c_y + j][img->pix_c_x], mb_pred[j], img->mb_cr_size_x * sizeof(imgpel));
}
}
return cr_cbp;
}
int dct_chroma_sp_old(Macroblock *currMB, int uv,int cr_cbp, int is_cavlc)
{
int i,j,ilev,n2,n1,coeff_ctr,c_err,level ,scan_pos,run;
int m1[BLOCK_SIZE];
int coeff_cost;
int cr_cbp_tmp;
int mp1[BLOCK_SIZE];
const byte *c_cost = COEFF_COST4x4[params->disthres];
const byte (*pos_scan)[2] = currMB->is_field_mode ? FIELD_SCAN : SNGL_SCAN;
int intra = IS_INTRA (currMB);
int b4;
int* DCLevel = img->cofDC[uv+1][0];
int* DCRun = img->cofDC[uv+1][1];
int* ACLevel;
int* ACRun;
int c_err1, c_err2, level1, level2;
int len, info;
double D_dis1, D_dis2;
double lambda_mode = 0.85 * pow (2, (currMB->qp -SHIFT_QP)/3.0) * 4;
int max_imgpel_value_uv = img->max_imgpel_value_comp[1];
int qpChroma = currMB->qpc[uv] + img->bitdepth_chroma_qp_scale;
int qpChromaSP=iClip3(-img->bitdepth_chroma_qp_scale, 51, currMB->qpsp + active_pps->chroma_qp_index_offset);
int **mb_rres = img->mb_rres[uv + 1];
int **mb_ores = img->mb_ores[uv + 1];
imgpel **mb_pred = img->mb_pred[uv + 1];
int qp_per = qp_per_matrix[qpChroma];
int qp_rem = qp_rem_matrix[qpChroma];
int q_bits
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?