📄 block.c
字号:
}
}
}
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. Includes the
* RD constrained quantization also.
*
* \par Input:
* 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(Macroblock *currMB, ColorPlane pl, int block_x,int block_y, int *coeff_cost, int intra)
{
int i,j, coeff_ctr;
static int m4[16][16];
static int *m7;
static imgpel *orig_img, *pred_img;
static int scaled_coeff;
const byte *c_cost = COEFF_COST4x4[input->disthres];
int level, scan_pos = 0, 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);
int b4 = 2*(pos_y & 0x01) + (pos_x & 0x01);
imgpel **img_enc = enc_picture->p_curr_img;
imgpel (*curr_mpr)[16] = img->mpr[pl];
int (*curr_res)[16] = img->m7[pl];
int pl_off = pl<<2;
int* ACLevel = img->cofAC[b8+pl_off][b4][0];
int* ACRun = img->cofAC[b8+pl_off][b4][1];
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_per = qp_per_matrix[qp];
int qp_rem = qp_rem_matrix[qp];
int q_bits = Q_BITS + qp_per;
// 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;
// Forward DCT transform
forward4x4(curr_res, m4, block_y, block_x);
// Quantization
for (coeff_ctr = 0; coeff_ctr < 16; coeff_ctr++)
{
i = pos_scan[coeff_ctr][0];
j = pos_scan[coeff_ctr][1];
run++;
m7 = &m4[block_y + j][block_x];
scaled_coeff = iabs (m7[i]) * levelscale[j][i];
level = (scaled_coeff + leveloffset[j][i]) >> q_bits;
if (level != 0)
{
if (img->AdaptiveRounding)
fadjust4x4[j][block_x+i] = rshift_rnd_sf((AdaptRndWeight * (scaled_coeff - (level << q_bits))), q_bits + 1);
nonzero=TRUE;
*coeff_cost += (level > 1) ? MAX_VALUE : c_cost[run];
level = isignab(level, m7[i]);
ACLevel[scan_pos ] = level;
ACRun [scan_pos++] = run;
m7[i] = rshift_rnd_sf(((level * invlevelscale[j][i]) << qp_per), 4);
// reset zero level counter
run = -1;
}
else
{
if (img->AdaptiveRounding)
fadjust4x4[j][block_x+i] = 0;
m7[i] = 0;
}
}
ACLevel[scan_pos] = 0;
if (scan_pos)
{
// inverse 4x4 DCT transform
inverse4x4(m4, curr_res, block_y, block_x);
// generate final block
for (j=block_y; j < block_y + BLOCK_SIZE; j++)
{
orig_img = &img_enc[img->pix_y + j][img->pix_x + block_x];
pred_img = &curr_mpr[j][block_x];
m7 = &curr_res[j][block_x];
for (i=0; i < BLOCK_SIZE; i++)
{
orig_img[i] = iClip1( max_imgpel_value, rshift_rnd_sf(m7[i], DQ_BITS) + pred_img[i]);
}
}
}
else // no transformed residual;
{
for (j=block_y; j < block_y + BLOCK_SIZE; j++)
{
memcpy(&(img_enc[img->pix_y + j][img->pix_x + block_x]),&(curr_mpr[j][block_x]), BLOCK_SIZE * sizeof(imgpel));
}
}
return nonzero;
}
/*!
************************************************************************
* \brief
* The routine performs transform,quantization,inverse transform, adds the diff.
* to the prediction and writes the result to the decoded luma frame. Includes the
* RD constrained quantization also.
*
* \par Input:
* 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_qpprime(Macroblock *currMB, ColorPlane pl, int block_x,int block_y,int *coeff_cost, int intra)
{
int i,j, coeff_ctr;
int level, scan_pos = 0, run = -1;
int nonzero = FALSE;
imgpel **img_enc = enc_picture->p_curr_img;
imgpel (*curr_mpr)[16] = img->mpr[pl];
int (*curr_res)[16] = img->m7[pl];
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 pl_off = pl<<2;
int* ACLevel = img->cofAC[b8+pl_off][b4][0];
int* ACRun = img->cofAC[b8+pl_off][b4][1];
int pix_y, pix_x;
const byte (*pos_scan)[2] = currMB->is_field_mode ? FIELD_SCAN : SNGL_SCAN;
// select scaling parameters
fadjust4x4 = img->AdaptiveRounding ? &img->fadjust4x4[intra][block_y] : NULL;
for (coeff_ctr=0;coeff_ctr < 16;coeff_ctr++)
{
i=pos_scan[coeff_ctr][0];
j=pos_scan[coeff_ctr][1];
run++;
level = iabs(curr_res[j+block_y][i+block_x]);
if (img->AdaptiveRounding)
fadjust4x4[j][block_x+i] = 0;
if (level != 0)
{
nonzero=TRUE;
*coeff_cost += MAX_VALUE;
level=isignab(level, curr_res[j+block_y][i+block_x]);
ACLevel[scan_pos ] = level;
ACRun [scan_pos++] = run;
run=-1; // reset zero level counter
}
}
ACLevel[scan_pos] = 0;
if(ipmode_DPCM<2) //For residual DPCM
{
Inv_Residual_DPCM_4x4(pl, 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]=curr_res[j+block_y][i+block_x] + curr_mpr[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).
************************************************************************
*/
int Residual_DPCM_4x4(int ipmode, ColorPlane pl, int block_y, int block_x)
{
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] = img->m7[pl][block_y+i][block_x+j] - img->m7[pl][block_y+i-1][block_x+j];
for (j=0; j<4; j++)
for (i=1; i<4; i++)
img->m7[pl][block_y+i][block_x+j] = temp[i][j];
}
else //HOR_PRED
{
for (j=1; j<4; j++)
for (i=0; i<4; i++)
temp[i][j] = img->m7[pl][block_y+i][block_x+j] - img->m7[pl][block_y+i][block_x+j-1];
for (j=1; j<4; j++)
for (i=0; i<4; i++)
img->m7[pl][block_y+i][block_x+j] = temp[i][j];
}
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
int Inv_Residual_DPCM_4x4(ColorPlane pl, int block_y, int block_x)
{
int i;
int temp[4][4];
if(ipmode_DPCM==VERT_PRED)
{
for(i=0; i<4; i++)
{
temp[1][i]=img->m7[pl][block_y+0][block_x+i]+img->m7[pl][block_y+1][block_x+i];
temp[2][i]=img->m7[pl][block_y+0][block_x+i]+img->m7[pl][block_y+1][block_x+i]+img->m7[pl][block_y+2][block_x+i];
temp[3][i]=img->m7[pl][block_y+0][block_x+i]+img->m7[pl][block_y+1][block_x+i]+img->m7[pl][block_y+2][block_x+i]+img->m7[pl][block_y+3][block_x+i];
}
for(i=0; i<4; i++)
{
img->m7[pl][block_y+1][block_x+i]=temp[1][i];
img->m7[pl][block_y+2][block_x+i]=temp[2][i];
img->m7[pl][block_y+3][block_x+i]=temp[3][i];
}
}
else //HOR_PRED
{
for(i=0; i<4; i++)
{
temp[i][1]=img->m7[pl][block_y+i][block_x+0]+img->m7[pl][block_y+i][block_x+1];
temp[i][2]=img->m7[pl][block_y+i][block_x+0]+img->m7[pl][block_y+i][block_x+1]+img->m7[pl][block_y+i][block_x+2];
temp[i][3]=img->m7[pl][block_y+i][block_x+0]+img->m7[pl][block_y+i][block_x+1]+img->m7[pl][block_y+i][block_x+2]+img->m7[pl][block_y+i][block_x+3];
}
for(i=0; i<4; i++)
{
img->m7[pl][block_y+i][block_x+1]=temp[i][1];
img->m7[pl][block_y+i][block_x+2]=temp[i][2];
img->m7[pl][block_y+i][block_x+3]=temp[i][3];
}
}
return 0;
}
/*!
************************************************************************
* \brief
* Residual DPCM for Intra lossless coding
*
* \par Input:
* block_x,block_y: Block position inside a macro block (0,8).
************************************************************************
*/
//For residual DPCM
int Residual_DPCM_8x8(int ipmode, ColorPlane pl, int block_y, int block_x)
{
int i,j;
int temp[8][8];
if(ipmode==VERT_PRED)
{
for (j=0; j<8; j++)
for (i=1; i<8; i++)
temp[i][j] = img->m7[pl][block_y+i][block_x+j] - img->m7[pl][block_y+i-1][block_x+j];
for (j=0; j<8; j++)
for (i=1; i<8; i++)
img->m7[pl][block_y+i][block_x+j] = temp[i][j];
}
else //HOR_PRED
{
for (j=1; j<8; j++)
for (i=0; i<8; i++)
temp[i][j] = img->m7[pl][block_y+i][block_x+j] - img->m7[pl][block_y+i][block_x+j-1];
for (j=1; j<8; j++)
for (i=0; i<8; i++)
img->m7[pl][block_y+i][block_x+j] = temp[i][j];
}
return 0;
}
/*!
************************************************************************
* \brief
* Inverse residual DPCM for Intra lossless coding
*
* \par Input:
* block_x,block_y: Block position inside a macro block (0,8).
************************************************************************
*/
//For residual DPCM
int Inv_Residual_DPCM_8x8(ColorPlane pl, int block_y, int block_x)
{
int i;
int temp[8][8];
if(ipmode_DPCM==VERT_PRED)
{
for(i=0; i<8; i++)
{
temp[1][i]=img->m7[pl][block_y+0][block_x+i]+img->m7[pl][block_y+1][block_x+i];
temp[2][i]=img->m7[pl][block_y+0][block_x+i]+img->m7[pl][block_y+1][block_x+i]+img->m7[pl][block_y+2][block_x+i];
temp[3][i]=img->m7[pl][block_y+0][block_x+i]+img->m7[pl][block_y+1][block_x+i]+img->m7[pl][block_y+2][block_x+i]+img->m7[pl][block_y+3][block_x+i];
temp[4][i]=img->m7[pl][block_y+0][block_x+i]+img->m7[pl][block_y+1][block_x+i]+img->m7[pl][block_y+2][block_x+i]+img->m7[pl][block_y+3][block_x+i]+img->m7[pl][block_y+4][block_x+i];
temp[5][i]=img->m7[pl][block_y+0][block_x+i]+img->m7[pl][block_y+1][block_x+i]+img->m7[pl][block_y+2][block_x+i]+img->m7[pl][block_y+3][block_x+i]+img->m7[pl][block_y+4][block_x+i]+img->m7[pl][block_y+5][block_x+i];
temp[6][i]=img->m7[pl][block_y+0][block_x+i]+img->m7[pl][block_y+1][block_x+i]+img->m7[pl][block_y+2][block_x+i]+img->m7[pl][block_y+3][block_x+i]+img->m7[pl][block_y+4][block_x+i]+img->m7[pl][block_y+5][block_x+i]+img->m7[pl][block_y+6][block_x+i];
temp[7][i]=img->m7[pl][block_y+0][block_x+i]+img->m7[pl][block_y+1][block_x+i]+img->m7[pl][block_y+2][block_x+i]+img->m7[pl][block_y+3][block_x+i]+img->m7[pl][block_y+4][block_x+i]+img->m7[pl][block_y+5][block_x+i]+img->m7[pl][block_y+6][block_x+i]+img->m7[pl][block_y+7][block_x+i];
}
for(i=0; i<8; i++)
{
img->m7[pl][block_y+1][block_x+i]=temp[1][i];
img->m7[pl][block_y+2][block_x+i]=temp[2][i];
img->m7[pl][block_y+3][block_x+i]=temp[3][i];
img->m7[pl][block_y+4][block_x+i]=temp[4][i];
img->m7[pl][block_y+5][block_x+i]=temp[5][i];
img->m7[pl][block_y+6][block_x+i]=temp[6][i];
img->m7[pl][block_y+7][block_x+i]=temp[7][i];
}
}
else //HOR_PRED
{
for(i=0; i<8; i++)
{
temp[i][1]=img->m7[pl][block_y+i][block_x+0]+img->m7[pl][block_y+i][block_x+1];
temp[i][2]=img->m7[pl][block_y+i][block_x+0]+img->m7[pl][block_y+i][block_x+1]+img->m7[pl][block_y+i][block_x+2];
temp[i][3]=img->m7[pl][block_y+i][block_x+0]+img->m7[pl][block_y+i][block_x+1]+img->m7[pl][block_y+i][block_x+2]+img->m7[pl][block_y+i][block_x+3];
temp[i][4]=img->m7[pl][block_y+i][block_x+0]+img->m7[pl][block_y+i][block_x+1]+img->m7[pl][block_y+i][block_x+2]+img->m7[pl][block_y+i][block_x+3]+img->m7[pl][block_y+i][block_x+4];
temp[i][5]=img->m7[pl][block_y+i][block_x+0]+img->m7[pl][block_y+i][block_x+1]+img->m7[pl][block_y+i][block_x+2]+img->m7[pl][block_y+i][block_x+3]+img->m7[pl][block_y+i][block_x+4]+img->m7[pl][block_y+i][block_x+5];
temp[i][6]=img->m7[pl][block_y+i][block_x+0]+img->m7[pl][block_y+i][block_x+1]+img->m7[pl][block_y+i][block_x+2]+img->m7[pl][block_y+i][block_x+3]+img->m7[pl][block_y+i][block_x+4]+img->m7[pl][block_y+i][block_x+5]+img->m7[pl][block_y+i][block_x+6];
temp[i][7]=img->m7[pl][block_y+i][block_x+0]+img->m7[pl][block_y+i][block_x+1]+img->m7[pl][block_y+i][block_x+2]+img->m7[pl][block_y+i][block_x+3]+img->m7[pl][block_y+i][block_x+4]+img->m7[pl][block_y+i][block_x+5]+img->m7[pl][block_y+i][block_x+6]+img->m7[pl][block_y+i][block_x+7];
}
for(i=0; i<8; i++)
{
img->m7[pl][block_y+i][block_x+1]=temp[i][1];
img->m7[pl][block_y+i][block_x+2]=temp[i][2];
img->m7[pl][block_y+i][block_x+3]=temp[i][3];
img->m7[pl][block_y+i][block_x+4]=temp[i][4];
img->m7[pl][block_y+i][block_x+5]=temp[i][5];
img->m7[pl][block_y+i][block_x+6]=temp[i][6];
img->m7[pl][block_y+i][block_x+7]=temp[i][7];
}
}
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -