📄 block.c
字号:
/*!
************************************************************************
* \brief
* Residual DPCM for Intra lossless coding
************************************************************************
*/
//For residual DPCM
int Residual_DPCM_4x4_for_Intra16x16(int ipmode)
{
int i,j;
int temp[4][4];
if(ipmode==VERT_PRED)
{
for (j=0; j<4; j++)
for (i=1; i<4; i++)
temp[i][j] = lossless_res[i][j] - lossless_res[i-1][j];
for (j=0; j<4; j++)
for (i=1; i<4; i++)
lossless_res[i][j] = temp[i][j];
}
else //HOR_PRED
{
for (j=1; j<4; j++)
for (i=0; i<4; i++)
temp[i][j] = lossless_res[i][j] - lossless_res[i][j-1];
for (j=1; j<4; j++)
for (i=0; i<4; i++)
lossless_res[i][j] = temp[i][j];
}
return 0;
}
/*!
************************************************************************
* \brief
* Inverse residual DPCM for Intra lossless coding
************************************************************************
*/
//For residual DPCM
int Inv_Residual_DPCM_4x4_for_Intra16x16(int ipmode)
{
int i;
int temp[4][4];
if(ipmode==VERT_PRED)
{
for (i=0; i<4; i++)
{
temp[1][i]=lossless_res[0][i]+lossless_res[1][i];
temp[2][i]=lossless_res[0][i]+lossless_res[1][i]+lossless_res[2][i];
temp[3][i]=lossless_res[0][i]+lossless_res[1][i]+lossless_res[2][i]+lossless_res[3][i];
}
for (i=0; i<4; i++)
{
lossless_res[1][i]=temp[1][i];
lossless_res[2][i]=temp[2][i];
lossless_res[3][i]=temp[3][i];
}
}
else //HOR_PRED
{
for(i=0; i<4; i++)
{
temp[i][1]=lossless_res[i][0]+lossless_res[i][1];
temp[i][2]=lossless_res[i][0]+lossless_res[i][1]+lossless_res[i][2];
temp[i][3]=lossless_res[i][0]+lossless_res[i][1]+lossless_res[i][2]+lossless_res[i][3];
}
for (i=0; i<4; i++)
{
lossless_res[i][1]=temp[i][1];
lossless_res[i][2]=temp[i][2];
lossless_res[i][3]=temp[i][3];
}
}
return 0;
}
/*!
************************************************************************
* \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 \n
* cr_cbp: chroma coded block pattern
*
* \par Output:
* cr_cbp: Updated chroma coded block pattern.
************************************************************************
*/
int dct_chroma(Macroblock *currMB, int uv, int cr_cbp)
{
int i,j,n2,n1,coeff_ctr,level ,scan_pos,run;
static int m1[BLOCK_SIZE],m5[BLOCK_SIZE],m6[BLOCK_SIZE];
int coeff_cost;
int cr_cbp_tmp;
int DCcoded=0 ;
static imgpel *orig_img, *pred_img;
const byte *c_cost = COEFF_COST4x4[input->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);
static int scaled_coeff;
//FRExt
static const int64 cbpblk_pattern[4]={0, 0xf0000, 0xff0000, 0xffff0000};
int yuv = img->yuv_format;
int b8;
static int *m7;
static int m3[4][4];
static int m4[4][4];
int qp_per_dc = 0;
int qp_rem_dc = 0;
int q_bits_422 = 0;
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 cur_qp_dc = currMB->qpc[uv] + 3 + img->bitdepth_chroma_qp_scale;
Boolean lossless_qpprime = (Boolean) ((currMB->qp + img->bitdepth_luma_qp_scale)==0 && img->lossless_qpprime_flag==1);
int qp_per = qp_per_matrix[cur_qp];
int qp_rem = qp_rem_matrix[cur_qp];
int q_bits = Q_BITS + qp_per;
int max_imgpel_value_uv = img->max_imgpel_value_comp[1];
int (*curr_res)[16] = img->m7[uv + 1];
imgpel (*curr_mpr)[16] = img->mpr[uv + 1];
levelscale = LevelScale4x4Comp [uv + 1][intra][qp_rem];
leveloffset = LevelOffset4x4Comp [uv + 1][intra][cur_qp];
invlevelscale = InvLevelScale4x4Comp[uv + 1][intra][qp_rem];
fadjust4x4 = img->AdaptiveRounding ? img->fadjust4x4Cr[intra][uv] : NULL;
if (img->yuv_format == YUV422)
{
//for YUV422 only
qp_per_dc = qp_per_matrix[cur_qp_dc];
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];
q_bits_422 = Q_BITS + qp_per_dc;
}
//============= dct transform ===============
if (!lossless_qpprime)
{
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(curr_res, curr_res, n1, n2);
}
}
}
if (yuv == YUV420)
{
//================== CHROMA DC YUV420 ===================
// 2X2 transform of DC coeffs.
run=-1;
scan_pos=0;
if(!lossless_qpprime)
{
m1[0]=(curr_res[0][0] + curr_res[0][4] + curr_res[4][0] + curr_res[4][4]);
m1[1]=(curr_res[0][0] - curr_res[0][4] + curr_res[4][0] - curr_res[4][4]);
m1[2]=(curr_res[0][0] + curr_res[0][4] - curr_res[4][0] - curr_res[4][4]);
m1[3]=(curr_res[0][0] - curr_res[0][4] - curr_res[4][0] + curr_res[4][4]);
// Quant of chroma 2X2 coeffs.
for (coeff_ctr=0; coeff_ctr < 4; coeff_ctr++)
{
run++;
level =(iabs(m1[coeff_ctr]) * levelscale[0][0] + (leveloffset[0][0]<<1)) >> (q_bits+1);
if (level != 0)
{
if (input->symbol_mode == CAVLC && img->qp < 4)
level = imin(level, CAVLC_LEVEL_LIMIT);
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)
DCcoded = 1;
level = isignab(level, m1[coeff_ctr]);
DCLevel[scan_pos ] = level;
DCRun [scan_pos++] = run;
run=-1;
m1[coeff_ctr] = level;
}
else
m1[coeff_ctr] = 0;
}
DCLevel[scan_pos] = 0;
// Inverse transform of 2x2 DC levels
m5[0]=(m1[0] + m1[1] + m1[2] + m1[3]);
m5[1]=(m1[0] - m1[1] + m1[2] - m1[3]);
m5[2]=(m1[0] + m1[1] - m1[2] - m1[3]);
m5[3]=(m1[0] - m1[1] - m1[2] + m1[3]);
curr_res[0][0] = ((m5[0] * invlevelscale[0][0]) << qp_per) >> 5;
curr_res[0][4] = ((m5[1] * invlevelscale[0][0]) << qp_per) >> 5;
curr_res[4][0] = ((m5[2] * invlevelscale[0][0]) << qp_per) >> 5;
curr_res[4][4] = ((m5[3] * invlevelscale[0][0]) << qp_per) >> 5;
}
else // Lossless qpprime
{
m1[0]=curr_res[0][0];
m1[1]=curr_res[0][4];
m1[2]=curr_res[4][0];
m1[3]=curr_res[4][4];
for (coeff_ctr=0; coeff_ctr < 4; coeff_ctr++)
{
run++;
level =iabs(m1[coeff_ctr]);
if (level != 0)
{
if (input->symbol_mode == CAVLC && img->qp < 4)
level = imin(level, CAVLC_LEVEL_LIMIT);
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)
DCcoded = 1;
level = isignab(level, m1[coeff_ctr]);
DCLevel[scan_pos ] = level;
DCRun [scan_pos++] = run;
run=-1;
}
}
DCLevel[scan_pos] = 0;
}
}
else if(yuv == YUV422)
{
//================== CHROMA DC YUV422 ===================
//transform DC coeff
//horizontal
//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)
m3[i>>2][j>>2]= curr_res[j][i];
}
//horizontal
if(!lossless_qpprime)
{
m4[0][0] = m3[0][0] + m3[1][0];
m4[0][1] = m3[0][1] + m3[1][1];
m4[0][2] = m3[0][2] + m3[1][2];
m4[0][3] = m3[0][3] + m3[1][3];
m4[1][0] = m3[0][0] - m3[1][0];
m4[1][1] = m3[0][1] - m3[1][1];
m4[1][2] = m3[0][2] - m3[1][2];
m4[1][3] = m3[0][3] - m3[1][3];
// vertical
for (i=0;i<2;i++)
{
m5[0] = m4[i][0] + m4[i][3];
m5[1] = m4[i][1] + m4[i][2];
m5[2] = m4[i][1] - m4[i][2];
m5[3] = m4[i][0] - m4[i][3];
m4[i][0] = (m5[0] + m5[1]);
m4[i][2] = (m5[0] - m5[1]);
m4[i][1] = (m5[3] + m5[2]);
m4[i][3] = (m5[3] - m5[2]);
}
}
run=-1;
scan_pos=0;
//quant of chroma DC-coeffs
for (coeff_ctr=0;coeff_ctr<8;coeff_ctr++)
{
i=SCAN_YUV422[coeff_ctr][0];
j=SCAN_YUV422[coeff_ctr][1];
run++;
if(lossless_qpprime)
{
level = iabs(m3[i][j]);
m4[i][j]=m3[i][j];
}
else
level =(iabs(m4[i][j]) * levelscale[0][0] + (leveloffsetDC[0][0]*2)) >> (q_bits_422+1);
if (level != 0)
{
//YUV422
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
DCcoded = 1 ;
DCLevel[scan_pos ] = isignab(level,m4[i][j]);
DCRun [scan_pos++] = run;
run=-1;
}
if(!lossless_qpprime)
m3[i][j]=isignab(level,m4[i][j]);
}
DCLevel[scan_pos]=0;
//inverse DC transform
//horizontal
if(!lossless_qpprime)
{
m4[0][0] = m3[0][0] + m3[1][0];
m4[0][1] = m3[0][1] + m3[1][1];
m4[0][2] = m3[0][2] + m3[1][2];
m4[0][3] = m3[0][3] + m3[1][3];
m4[1][0] = m3[0][0] - m3[1][0];
m4[1][1] = m3[0][1] - m3[1][1];
m4[1][2] = m3[0][2] - m3[1][2];
m4[1][3] = m3[0][3] - m3[1][3];
// vertical
for (i=0;i<2;i++)
{
m6[0]=m4[i][0]+m4[i][2];
m6[1]=m4[i][0]-m4[i][2];
m6[2]=m4[i][1]-m4[i][3];
m6[3]=m4[i][1]+m4[i][3];
if(qp_per_dc < 4)
{
curr_res[0 ][i*4] = ((((m6[0]+m6[3])*invlevelscaleDC[0][0] + (1<<(3-qp_per_dc)))>>(4-qp_per_dc))+2)>>2;
curr_res[4 ][i*4] = ((((m6[1]+m6[2])*invlevelscaleDC[0][0] + (1<<(3-qp_per_dc)))>>(4-qp_per_dc))+2)>>2;
curr_res[8 ][i*4] = ((((m6[1]-m6[2])*invlevelscaleDC[0][0] + (1<<(3-qp_per_dc)))>>(4-qp_per_dc))+2)>>2;
curr_res[12][i*4] = ((((m6[0]-m6[3])*invlevelscaleDC[0][0] + (1<<(3-qp_per_dc)))>>(4-qp_per_dc))+2)>>2;
}
else
{
curr_res[0 ][i*4] = ((((m6[0]+m6[3])*invlevelscaleDC[0][0])<<(qp_per_dc-4))+2)>>2;
curr_res[4 ][i*4] = ((((m6[1]+m6[2])*invlevelscaleDC[0][0])<<(qp_per_dc-4))+2)>>2;
curr_res[8 ][i*4] = ((((m6[1]-m6[2])*invlevelscaleDC[0][0])<<(qp_per_dc-4))+2)>>2;
curr_res[12][i*4] = ((((m6[0]-m6[3])*invlevelscaleDC[0][0])<<(qp_per_dc-4))+2)>>2;
}
}//for (i=0;i<2;i++)
}
}
// Quant of chroma AC-coeffs.
coeff_cost=0;
cr_cbp_tmp=0;
if(!lossless_qpprime)
{
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];
run=-1;
scan_pos=0;
for (coeff_ctr=1; coeff_ctr < 16; coeff_ctr++) // start change rd_quant
{
i=pos_scan[coeff_ctr][0];
j=pos_scan[coeff_ctr][1];
m7 = &curr_res[n2+j][n1];
++run;
scaled_coeff = iabs(m7[i])*levelscale[j][i];
level=(scaled_coeff + leveloffset[j][i]) >> q_bits;
if (level != 0)
{
if (img->AdaptiveRounding)
fadjust4x4[n2+j][n1+i] = rshift_rnd_sf((AdaptRndCrWeight * (scaled_coeff - (level << q_bits))), (q_bits + 1));
currMB->cbp_blk |= uv_cbpblk;
// if level > 1 set high cost to avoid thresholding
coeff_cost += (level > 1) ? MAX_VALUE : c_cost[run];
cr_cbp_tmp=2;
level=isignab(level, m7[i]);
ACLevel[scan_pos ] = level;
ACRun [scan_pos++] = run;
run=-1;
m7[i] = rshift_rnd_sf((level * invlevelscale[j][i]) << qp_per, 4);
// inverse scale can be alternative performed as follows to ensure 16bit
// arithmetic is satisfied.
// curr_res[n2+j][n1+i] = (qp_per<4)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -