block.c
来自「the newest JM software by h.264 JVT offi」· C语言 代码 · 共 2,206 行 · 第 1/5 页
C
2,206 行
// AC inverse trans/quant for MB
for (jj=0;jj<4;jj++)
{
for (ii=0;ii<4;ii++)
{
for (j=0;j<4;j++)
{
memcpy(M4[j],&M1[(jj<<2)+j][(ii<<2)], BLOCK_SIZE * sizeof(int));
}
//For residual DPCM
if(new_intra_mode < 2) //residual DPCM
{
Residual_DPCM_4x4_for_Intra16x16(M4, new_intra_mode);
}
run = -1;
scan_pos = 0;
b8 = 2*(jj >> 1) + (ii >> 1);
b4 = 2*(jj & 0x01) + (ii & 0x01);
ACLevel = img->cofAC [b8+pl_off][b4][0];
ACRun = img->cofAC [b8+pl_off][b4][1];
for (coeff_ctr=1;coeff_ctr<16;coeff_ctr++) // set in AC coeff
{
i=pos_scan[coeff_ctr][0];
j=pos_scan[coeff_ctr][1];
run++;
m7 = &M4[j][i];
if (*m7 != 0)
{
if (is_cavlc)
*m7 = iClip3(-CAVLC_LEVEL_LIMIT, CAVLC_LEVEL_LIMIT, *m7);
ac_coef = 15;
ACLevel[scan_pos ] = *m7;
ACRun [scan_pos++] = run;
run=-1;
}
// set adaptive rounding params to 0 since process is not meaningful here.
}
ACLevel[scan_pos] = 0;
///For residual DPCM. inv. residual DCPM
if(new_intra_mode<2)
{
Inv_Residual_DPCM_4x4_for_Intra16x16(M4, new_intra_mode);
}
for (j=0;j<4;j++)
memcpy(&M1[(jj<<2)+j][(ii<<2)],M4[j], BLOCK_SIZE * sizeof(int));
}
}
for (j = 0; j < 16; j++)
{
img_Y = &img_enc[img->pix_y + j][img->pix_x];
predY = curr_mpr_16x16[new_intra_mode][j];
for (i = 0; i < 16; i++)
img_Y[i]=(imgpel)(M1[j][i] + predY[i]);
}
if(img->type == SP_SLICE)
{
for (j = img->pix_y; j < img->pix_y + 16;j++)
for (i = img->pix_x; i < img->pix_x + 16;i++)
lrec[j][i]=-16; //signals an I16 block in the SP frame
}
return ac_coef;
}
/*!
************************************************************************
* \brief
* 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(Macroblock *currMB, ColorPlane pl, int block_x,int block_y, int *coeff_cost, int intra, int is_cavlc)
{
int j;
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 = img->mb_pred[pl];
int **mb_ores = img->mb_ores[pl];
int **mb_rres = 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 ? (&img->ARCofAdj4x4[pl][currMB->ar_mode][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 = img->mb_pred[pl];
int **mb_ores = img->mb_ores[pl];
int **mb_rres = 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->ARCofAdj4x4[pl][currMB->ar_mode][block_y]) : NULL;
if( (ipmode_DPCM < 2) && (intra))
{
Residual_DPCM_4x4(ipmode_DPCM, mb_ores, mb_rres, block_y, block_x);
}
else
{
for (j=block_y; j < block_y + BLOCK_SIZE; j++)
for (i=block_x; i < block_x + BLOCK_SIZE; i++)
mb_rres[j][i] = mb_ores[j][i];
}
for (coeff_ctr=0;coeff_ctr < 16;coeff_ctr++)
{
i = *p_scan++;
j = *p_scan++;
run++;
m7 = &mb_rres[block_y + j][block_x + i];
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, int **mb_rres, int block_y, int block_x)
{
int i;
int temp[4][4];
if(ipmode==VERT_PRED)
{
for (i=0; i<4; i++)
{
temp[0][i] = mb_ores[block_y + 0][block_x + i];
temp[1][i] = mb_ores[block_y + 1][block_x + i] - mb_ores[block_y ][block_x + i];
temp[2][i] = mb_ores[block_y + 2][block_x + i] - mb_ores[block_y + 1][block_x + i];
temp[3][i] = mb_ores[block_y + 3][block_x + i] - mb_ores[block_y + 2][block_x + i];
}
for (i = 0; i < 4; i++)
{
mb_rres[block_y + 0][block_x + i] = temp[0][i];
mb_rres[block_y + 1][block_x + i] = temp[1][i];
mb_rres[block_y + 2][block_x + i] = temp[2][i];
mb_rres[block_y + 3][block_x + i] = temp[3][i];
}
}
else //HOR_PRED
{
for (i=0; i<4; i++)
{
temp[i][0] = mb_ores[block_y + i][block_x];
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_rres[block_y + i][block_x + 0] = temp[i][0];
mb_rres[block_y + i][block_x + 1] = temp[i][1];
mb_rres[block_y + i][block_x + 2] = temp[i][2];
mb_rres[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, 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] = m7[block_y + 1][block_x + i] + temp[0][i];
temp[2][i] = m7[block_y + 2][block_x + i] + temp[1][i];
temp[3][i] = m7[block_y + 3][block_x + i] + temp[2][i];
}
for(i=0; i<4; i++)
{
m7[block_y + 0][block_x + i] = temp[0][i];
m7[block_y + 1][block_x + i] = temp[1][i];
m7[block_y + 2][block_x + i] = temp[2][i];
m7[block_y + 3][block_x + i] = temp[3][i];
}
}
else //HOR_PRED
{
for(i=0; i<4; i++)
{
temp[i][0] = m7[block_y + i][block_x + 0];
temp[i][1] = m7[block_y + i][block_x + 1] + temp[i][0];
temp[i][2] = m7[block_y + i][block_x + 2] + temp[i][1];
temp[i][3] = m7[block_y + i][block_x + 3] + temp[i][2];
}
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, 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, 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;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?