📄 block.c
字号:
int nonzero = FALSE;
int pos_x = block_x >> BLOCK_SHIFT;
int pos_y = block_y >> BLOCK_SHIFT;
int b8 = 2*(pos_y >> 1) + (pos_x >> 1) + (pl<<2);
int b4 = 2*(pos_y & 0x01) + (pos_x & 0x01);
int* ACLevel = img->cofAC[b8][b4][0];
int* ACRun = img->cofAC[b8][b4][1];
imgpel **img_enc = enc_picture->p_curr_img;
imgpel (*mb_pred)[MB_BLOCK_SIZE] = img->mb_pred[pl];
int (*mb_ores)[MB_BLOCK_SIZE] = img->mb_ores[pl];
int (*mb_rres)[MB_BLOCK_SIZE] = img->mb_rres[pl];
int max_imgpel_value = img->max_imgpel_value;
int qp = currMB->qp_scaled[pl];
const byte (*pos_scan)[2] = currMB->is_field_mode ? FIELD_SCAN : SNGL_SCAN;
int qp_rem = qp_rem_matrix[qp];
// select scaling parameters
levelscale = LevelScale4x4Comp[pl][intra][qp_rem];
invlevelscale = InvLevelScale4x4Comp[pl][intra][qp_rem];
leveloffset = ptLevelOffset4x4[intra][qp];
fadjust4x4 = img->AdaptiveRounding ? (pl ? &img->fadjust4x4Cr[pl-1][intra][block_y] : &img->fadjust4x4[intra][block_y]) : NULL;
img->subblock_x = ((b8&0x1)==0) ? (((b4&0x1)==0)? 0: 1) : (((b4&0x1)==0)? 2: 3); // horiz. position for coeff_count context
img->subblock_y = (b8<2) ? ((b4<2) ? 0: 1) : ((b4<2) ? 2: 3); // vert. position for coeff_count context
// Forward 4x4 transform
forward4x4(mb_ores, M1, block_y, block_x);
// Quantization process
nonzero = quant_4x4(&M1[block_y], block_y, block_x, qp, ACLevel, ACRun, fadjust4x4,
levelscale, invlevelscale, leveloffset, coeff_cost, pos_scan, COEFF_COST4x4[params->disthres], is_cavlc);
// Decoded block moved to frame memory
if (nonzero)
{
// Inverse 4x4 transform
inverse4x4(M1, mb_rres, block_y, block_x);
// generate final block
SampleReconstruct (img_enc, mb_pred, mb_rres, block_y, block_x, img->pix_y, img->pix_x + block_x, BLOCK_SIZE, BLOCK_SIZE, max_imgpel_value, DQ_BITS);
}
else // if (nonzero) => No transformed residual. Just use prediction.
{
for (j=block_y; j < block_y + BLOCK_SIZE; j++)
{
memcpy(&(img_enc[img->pix_y + j][img->pix_x + block_x]),&(mb_pred[j][block_x]), BLOCK_SIZE * sizeof(imgpel));
}
}
return nonzero;
}
/*!
************************************************************************
* \brief
* Process for lossless coding of coefficients.
* The routine performs transform, quantization,inverse transform,
* adds the diff to the prediction and writes the result to the
* decoded luma frame.
*
* \par Input:
* currMB: Current macroblock.
* pl: Color plane for 4:4:4 coding.
* block_x,block_y: Block position inside a macro block (0,4,8,12).
* intra: Intra block indicator.
*
* \par Output_
* nonzero: 0 if no levels are nonzero. \n
* 1 if there are nonzero levels.\n
* coeff_cost: Coeff coding cost for thresholding consideration.\n
************************************************************************
*/
int dct_4x4_ls(Macroblock *currMB, ColorPlane pl, int block_x,int block_y,int *coeff_cost, int intra, int is_cavlc)
{
int i,j, coeff_ctr;
int run = -1;
int nonzero = FALSE;
int pos_x = block_x >> BLOCK_SHIFT;
int pos_y = block_y >> BLOCK_SHIFT;
int b8 = 2*(pos_y >> 1) + (pos_x >> 1) + (pl<<2);
int b4 = 2*(pos_y & 0x01) + (pos_x & 0x01);
int* ACL = &img->cofAC[b8][b4][0][0];
int* ACR = &img->cofAC[b8][b4][1][0];
int pix_y, pix_x;
imgpel **img_enc = enc_picture->p_curr_img;
imgpel (*mb_pred)[MB_BLOCK_SIZE] = img->mb_pred[pl];
int (*mb_ores)[MB_BLOCK_SIZE] = img->mb_ores[pl];
int (*mb_rres)[MB_BLOCK_SIZE] = img->mb_rres[pl];
int *m7;
const byte *p_scan = currMB->is_field_mode ? &FIELD_SCAN[0][0] : &SNGL_SCAN[0][0];
// select scaling parameters
fadjust4x4 = img->AdaptiveRounding ? &img->fadjust4x4[intra][block_y] : NULL;
if( (ipmode_DPCM < 2) && (intra))
{
Residual_DPCM_4x4(ipmode_DPCM, mb_ores, mb_rres, block_y, block_x);
}
for (coeff_ctr=0;coeff_ctr < 16;coeff_ctr++)
{
i = *p_scan++;
j = *p_scan++;
run++;
m7 = &mb_rres[j+block_y][i+block_x];
if (img->AdaptiveRounding)
fadjust4x4[j][block_x+i] = 0;
if (*m7 != 0)
{
if (is_cavlc)
*m7 = iClip3(-CAVLC_LEVEL_LIMIT, CAVLC_LEVEL_LIMIT, *m7);
nonzero=TRUE;
*coeff_cost += MAX_VALUE;
*ACL++ = *m7;
*ACR++ = run;
run=-1; // reset zero level counter
}
}
*ACL = 0;
if( (ipmode_DPCM < 2) && (intra))
{
Inv_Residual_DPCM_4x4(mb_rres, block_y, block_x);
}
for (j=0; j < BLOCK_SIZE; j++)
{
pix_y = img->pix_y + block_y + j;
pix_x = img->pix_x+block_x;
for (i=0; i < BLOCK_SIZE; i++)
{
img_enc[pix_y][pix_x+i] = mb_rres[j+block_y][i+block_x] + mb_pred[j+block_y][i+block_x];
}
}
return nonzero;
}
/*!
************************************************************************
* \brief
* Residual DPCM for Intra lossless coding
*
* \par Input:
* block_x,block_y: Block position inside a macro block (0,4,8,12).
************************************************************************
*/
static int Residual_DPCM_4x4(int ipmode, int mb_ores[16][16], int mb_rres[16][16], int block_y, int block_x)
{
int i;
int temp[4][4];
if(ipmode==VERT_PRED)
{
temp[0][0] = mb_ores[block_y][block_x ];
temp[0][1] = mb_ores[block_y][block_x + 1];
temp[0][2] = mb_ores[block_y][block_x + 2];
temp[0][3] = mb_ores[block_y][block_x + 3];
for (i=1; i<4; i++)
{
temp[i][0] = mb_ores[block_y + i][block_x ] - mb_ores[block_y + i - 1][block_x ];
temp[i][1] = mb_ores[block_y + i][block_x + 1] - mb_ores[block_y + i - 1][block_x + 1];
temp[i][2] = mb_ores[block_y + i][block_x + 2] - mb_ores[block_y + i - 1][block_x + 2];
temp[i][3] = mb_ores[block_y + i][block_x + 3] - mb_ores[block_y + i - 1][block_x + 3];
}
for (i = 0; i < 4; i++)
{
mb_ores[block_y+i][block_x ] = temp[i][0];
mb_ores[block_y+i][block_x + 1] = temp[i][1];
mb_ores[block_y+i][block_x + 2] = temp[i][2];
mb_ores[block_y+i][block_x + 3] = temp[i][3];
}
}
else //HOR_PRED
{
temp[0][0] = mb_ores[block_y ][block_x];
temp[1][0] = mb_ores[block_y + 1][block_x];
temp[2][0] = mb_ores[block_y + 2][block_x];
temp[3][0] = mb_ores[block_y + 3][block_x];
for (i=0; i<4; i++)
{
temp[i][1] = mb_ores[block_y + i][block_x + 1] - mb_ores[block_y + i][block_x ];
temp[i][2] = mb_ores[block_y + i][block_x + 2] - mb_ores[block_y + i][block_x + 1];
temp[i][3] = mb_ores[block_y + i][block_x + 3] - mb_ores[block_y + i][block_x + 2];
}
for (i=0; i<4; i++)
{
mb_ores[block_y + i][block_x + 0] = temp[i][0];
mb_ores[block_y + i][block_x + 1] = temp[i][1];
mb_ores[block_y + i][block_x + 2] = temp[i][2];
mb_ores[block_y + i][block_x + 3] = temp[i][3];
}
}
return 0;
}
/*!
************************************************************************
* \brief
* Inverse residual DPCM for Intra lossless coding
*
* \par Input:
* block_x,block_y: Block position inside a macro block (0,4,8,12).
************************************************************************
*/
//For residual DPCM
static int Inv_Residual_DPCM_4x4(int m7[16][16], int block_y, int block_x)
{
int i;
int temp[4][4];
if(ipmode_DPCM==VERT_PRED)
{
for(i=0; i<4; i++)
{
temp[0][i] = m7[block_y + 0][block_x + i];
temp[1][i] = temp[0][i] + m7[block_y + 1][block_x + i];
temp[2][i] = temp[1][i] + m7[block_y + 2][block_x + i];
temp[3][i] = temp[2][i] + m7[block_y + 3][block_x + i];
}
for(i=0; i<4; i++)
{
m7[block_y + i][block_x ] = temp[i][0];
m7[block_y + i][block_x + 1] = temp[i][1];
m7[block_y + i][block_x + 2] = temp[i][2];
m7[block_y + i][block_x + 3] = temp[i][3];
}
}
else //HOR_PRED
{
for(i=0; i<4; i++)
{
temp[i][0] = m7[block_y+i][block_x+0];
temp[i][1] = temp[i][0] + m7[block_y + i][block_x + 1];
temp[i][2] = temp[i][1] + m7[block_y + i][block_x + 2];
temp[i][3] = temp[i][2] + m7[block_y + i][block_x + 3];
}
for(i=0; i<4; i++)
{
m7[block_y+i][block_x ] = temp[i][0];
m7[block_y+i][block_x+1] = temp[i][1];
m7[block_y+i][block_x+2] = temp[i][2];
m7[block_y+i][block_x+3] = temp[i][3];
}
}
return 0;
}
/*!
************************************************************************
* \brief
* Residual DPCM for Intra lossless coding
************************************************************************
*/
//For residual DPCM
static int Residual_DPCM_4x4_for_Intra16x16(int m7[4][4], int ipmode)
{
int i,j;
int temp[4][4];
if(ipmode==VERT_PRED)
{
for (i=1; i<4; i++)
for (j=0; j<4; j++)
temp[i][j] = m7[i][j] - m7[i-1][j];
for (i=1; i<4; i++)
for (j=0; j<4; j++)
m7[i][j] = temp[i][j];
}
else //HOR_PRED
{
for (i=0; i<4; i++)
for (j=1; j<4; j++)
temp[i][j] = m7[i][j] - m7[i][j-1];
for (i=0; i<4; i++)
for (j=1; j<4; j++)
m7[i][j] = temp[i][j];
}
return 0;
}
/*!
************************************************************************
* \brief
* Inverse residual DPCM for Intra lossless coding
************************************************************************
*/
//For residual DPCM
static int Inv_Residual_DPCM_4x4_for_Intra16x16(int m7[4][4], int ipmode)
{
int i;
int temp[4][4];
if(ipmode==VERT_PRED)
{
for (i=0; i<4; i++)
{
temp[0][i] = m7[0][i];
temp[1][i] = m7[1][i] + temp[0][i];
temp[2][i] = m7[2][i] + temp[1][i];
temp[3][i] = m7[3][i] + temp[2][i];
}
// These could now just use a memcpy
for (i=0; i<4; i++)
{
m7[1][i] = temp[1][i];
m7[2][i] = temp[2][i];
m7[3][i] = temp[3][i];
}
}
else //HOR_PRED
{
for(i=0; i<4; i++)
{
temp[i][0] = m7[i][0];
temp[i][1] = m7[i][1] + temp[i][0];
temp[i][2] = m7[i][2] + temp[i][1];
temp[i][3] = m7[i][3] + temp[i][2];
}
for (i=0; i<4; i++)
{
m7[i][1] = temp[i][1];
m7[i][2] = temp[i][2];
m7[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 is_cavlc)
{
int i, j, n2, n1, coeff_ctr;
static int m1[BLOCK_SIZE];
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)[MB_BLOCK_SIZE] = img->mb_rres[uv + 1];
int (*mb_ores)[MB_BLOCK_SIZE] = img->mb_ores[uv + 1];
imgpel (*mb_pred)[MB_BLOCK_SIZE] = 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];
fadjust4x4 = img->AdaptiveRounding ? img->fadjust4x4Cr[intra][uv] : NULL;
img->is_v_block = uv;
//============= 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)
{
//================== CHROMA DC YUV420 ===================
// forward 2x2 hadamard
hadamard2x2(mb_rres, m1);
// Quantization process of chroma 2X2 hadamard transformed DC coeffs.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -