📄 block.c
字号:
m7[j][i]=m6[i]+m6[i1];
m7[j][i1]=m6[i]-m6[i1];
}
}
// vertical
for (i=0;i<BLOCK_SIZE;i++)
{
for (j=0;j<BLOCK_SIZE;j++)
m5[j]=m7[j][i];
m6[0]=(m5[0]+m5[2]);
m6[1]=(m5[0]-m5[2]);
m6[2]=(m5[1]>>1)-m5[3];
m6[3]=m5[1]+(m5[3]>>1);
for (j=0;j<2;j++)
{
j1=3-j;
m7[j][i] =iClip1(img->max_imgpel_value,rshift_rnd_sf((m6[j]+m6[j1]),DQ_BITS));
m7[j1][i]=iClip1(img->max_imgpel_value,rshift_rnd_sf((m6[j]-m6[j1]),DQ_BITS));
}
}
}
/*!
***********************************************************************
* \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 expencive levels.
************************************************************************
*/
void copyblock_sp(struct img_par *img,int block_x,int block_y)
{
int i,j,i1,j1,m5[4],m6[4];
int predicted_block[BLOCK_SIZE][BLOCK_SIZE];
int qp_per = (img->qpsp-MIN_QP)/6;
int qp_rem = (img->qpsp-MIN_QP)%6;
int q_bits = Q_BITS+qp_per;
int qp_const2=(1<<q_bits)/2; //sp_pred
imgpel (*mpr)[16] = img->mpr[LumaComp];
int (*m7) [16] = img->m7[LumaComp];
// Horizontal transform
for (j=0; j< BLOCK_SIZE; j++)
for (i=0; i< BLOCK_SIZE; i++)
predicted_block[i][j]=mpr[j+block_y][i+block_x];
for (j=0; j < BLOCK_SIZE; j++)
{
for (i=0; i < 2; i++)
{
i1=3-i;
m5[i]=predicted_block[i][j]+predicted_block[i1][j];
m5[i1]=predicted_block[i][j]-predicted_block[i1][j];
}
predicted_block[0][j]=(m5[0]+m5[1]);
predicted_block[2][j]=(m5[0]-m5[1]);
predicted_block[1][j]=m5[3]*2+m5[2];
predicted_block[3][j]=m5[3]-m5[2]*2;
}
// Vertival transform
for (i=0; i < BLOCK_SIZE; i++)
{
for (j=0; j < 2; j++)
{
j1=3-j;
m5[j]=predicted_block[i][j]+predicted_block[i][j1];
m5[j1]=predicted_block[i][j]-predicted_block[i][j1];
}
predicted_block[i][0]=(m5[0]+m5[1]);
predicted_block[i][2]=(m5[0]-m5[1]);
predicted_block[i][1]=m5[3]*2+m5[2];
predicted_block[i][3]=m5[3]-m5[2]*2;
}
// Quant
for (j=0;j < BLOCK_SIZE; j++)
for (i=0; i < BLOCK_SIZE; i++)
m7[j][i]=isignab((iabs(predicted_block[i][j])* quant_coef[qp_rem][i][j]+qp_const2)>> q_bits,predicted_block[i][j])*dequant_coef[qp_rem][i][j]<<qp_per;
// IDCT.
// horizontal
for (j=0;j<BLOCK_SIZE;j++)
{
for (i=0;i<BLOCK_SIZE;i++)
{
m5[i]=m7[j][i];
}
m6[0]=(m5[0]+m5[2]);
m6[1]=(m5[0]-m5[2]);
m6[2]=(m5[1]>>1)-m5[3];
m6[3]=m5[1]+(m5[3]>>1);
for (i=0;i<2;i++)
{
i1=3-i;
m7[j][i]=m6[i]+m6[i1];
m7[j][i1]=m6[i]-m6[i1];
}
}
// vertical
for (i=0;i<BLOCK_SIZE;i++)
{
for (j=0;j<BLOCK_SIZE;j++)
m5[j]=m7[j][i];
m6[0]=(m5[0]+m5[2]);
m6[1]=(m5[0]-m5[2]);
m6[2]=(m5[1]>>1)-m5[3];
m6[3]=m5[1]+(m5[3]>>1);
for (j=0;j<2;j++)
{
j1=3-j;
m7[j][i] =iClip1(img->max_imgpel_value,rshift_rnd_sf((m6[j]+m6[j1]),DQ_BITS));
m7[j1][i]=iClip1(img->max_imgpel_value,rshift_rnd_sf((m6[j]-m6[j1]),DQ_BITS));
}
}
// Decoded block moved to frame memory
for (j=0; j < BLOCK_SIZE; j++)
for (i=0; i < BLOCK_SIZE; i++)
dec_picture->imgY[img->pix_y+block_y+j][img->pix_x+block_x+i]=(imgpel) m7[j][i];
}
void itrans_sp_cr(struct img_par *img, int uv)
{
int i,j,i1,j2,ilev,n2,n1,j1,mb_y;
int m5[BLOCK_SIZE];
int predicted_chroma_block[MB_BLOCK_SIZE/2][MB_BLOCK_SIZE/2],mp1[BLOCK_SIZE];
int qp_per,qp_rem,q_bits;
int qp_per_sp,qp_rem_sp,q_bits_sp,qp_const2;
imgpel (*mpr)[16] = img->mpr[uv + 1];
qp_per = ((img->qp<0?img->qp:QP_SCALE_CR[img->qp])-MIN_QP)/6;
qp_rem = ((img->qp<0?img->qp:QP_SCALE_CR[img->qp])-MIN_QP)%6;
q_bits = Q_BITS+qp_per;
qp_per_sp = ((img->qpsp<0?img->qpsp:QP_SCALE_CR[img->qpsp])-MIN_QP)/6;
qp_rem_sp = ((img->qpsp<0?img->qpsp:QP_SCALE_CR[img->qpsp])-MIN_QP)%6;
q_bits_sp = Q_BITS+qp_per_sp;
qp_const2=(1<<q_bits_sp)/2; //sp_pred
if (img->type == SI_SLICE)
{
qp_per = ((img->qpsp < 0 ? img->qpsp : QP_SCALE_CR[img->qpsp]) - MIN_QP) / 6;
qp_rem = ((img->qpsp < 0 ? img->qpsp : QP_SCALE_CR[img->qpsp]) - MIN_QP) % 6;
q_bits = Q_BITS + qp_per;
}
for (j=0; j < MB_BLOCK_SIZE/2; j++)
for (i=0; i < MB_BLOCK_SIZE/2; i++)
{
predicted_chroma_block[i][j]=mpr[j][i];
mpr[j][i]=0;
}
for (n2=0; n2 <= BLOCK_SIZE; n2 += BLOCK_SIZE)
{
for (n1=0; n1 <= BLOCK_SIZE; n1 += BLOCK_SIZE)
{
// Horizontal transform.
for (j=0; j < BLOCK_SIZE; j++)
{
mb_y=n2+j;
for (i=0; i < 2; i++)
{
i1=3-i;
m5[i]=predicted_chroma_block[i+n1][mb_y]+predicted_chroma_block[i1+n1][mb_y];
m5[i1]=predicted_chroma_block[i+n1][mb_y]-predicted_chroma_block[i1+n1][mb_y];
}
predicted_chroma_block[n1][mb_y] =(m5[0]+m5[1]);
predicted_chroma_block[n1+2][mb_y]=(m5[0]-m5[1]);
predicted_chroma_block[n1+1][mb_y]=m5[3]*2+m5[2];
predicted_chroma_block[n1+3][mb_y]=m5[3]-m5[2]*2;
}
// Vertical transform.
for (i=0; i < BLOCK_SIZE; i++)
{
j1=n1+i;
for (j=0; j < 2; j++)
{
j2=3-j;
m5[j]=predicted_chroma_block[j1][n2+j]+predicted_chroma_block[j1][n2+j2];
m5[j2]=predicted_chroma_block[j1][n2+j]-predicted_chroma_block[j1][n2+j2];
}
predicted_chroma_block[j1][n2+0]=(m5[0]+m5[1]);
predicted_chroma_block[j1][n2+2]=(m5[0]-m5[1]);
predicted_chroma_block[j1][n2+1]=m5[3]*2+m5[2];
predicted_chroma_block[j1][n2+3]=m5[3]-m5[2]*2;
}
}
}
// 2X2 transform of DC coeffs.
mp1[0]=(predicted_chroma_block[0][0]+predicted_chroma_block[4][0]+predicted_chroma_block[0][4]+predicted_chroma_block[4][4]);
mp1[1]=(predicted_chroma_block[0][0]-predicted_chroma_block[4][0]+predicted_chroma_block[0][4]-predicted_chroma_block[4][4]);
mp1[2]=(predicted_chroma_block[0][0]+predicted_chroma_block[4][0]-predicted_chroma_block[0][4]-predicted_chroma_block[4][4]);
mp1[3]=(predicted_chroma_block[0][0]-predicted_chroma_block[4][0]-predicted_chroma_block[0][4]+predicted_chroma_block[4][4]);
for (n1=0; n1 < 2; n1 ++)
for (n2=0; n2 < 2; n2 ++)
{
if (img->sp_switch || img->type==SI_SLICE) //M.W. patched for SI
{
//quantization fo predicted block
ilev=(iabs (mp1[n1+n2*2]) * quant_coef[qp_rem_sp][0][0] + 2 * qp_const2) >> (q_bits_sp + 1);
//addition
ilev=img->cof[uv + 1][n2<<2][n1<<2]+isignab(ilev,mp1[n1+n2*2]);
//dequantization
mp1[n1+n2*2] =ilev*dequant_coef[qp_rem_sp][0][0]<<qp_per_sp;
}
else
{
ilev=((img->cof[uv + 1][n2<<2][n1<<2]*dequant_coef[qp_rem][0][0]*A[0][0]<< qp_per) >>5)+mp1[n1+n2*2];
mp1[n1+n2*2]=isignab((iabs(ilev)* quant_coef[qp_rem_sp][0][0]+ 2 * qp_const2)>> (q_bits_sp+1),ilev)*dequant_coef[qp_rem_sp][0][0]<<qp_per_sp;
}
}
for (n2=0; n2 < 2; n2 ++)
for (n1=0; n1 < 2; n1 ++)
for (i=0;i< BLOCK_SIZE; i++)
for (j=0;j< BLOCK_SIZE; j++)
{
// recovering coefficient since they are already dequantized earlier
img->cof[uv + 1][(n2<<2) + j][(n1<<2) + i] = (img->cof[uv + 1][(n2<<2) + j][(n1<<2) + i] >> qp_per) / dequant_coef[qp_rem][i][j];
if (img->sp_switch || img->type==SI_SLICE) //M.W. patched for SI
{
//quantization of the predicted block
ilev = (iabs(predicted_chroma_block[n1*BLOCK_SIZE+i][n2*BLOCK_SIZE+j]) * quant_coef[qp_rem_sp][i][j] + qp_const2) >> q_bits_sp;
//addition of the residual
ilev = isignab(ilev,predicted_chroma_block[n1*BLOCK_SIZE+i][n2*BLOCK_SIZE+j]) + img->cof[uv + 1][(n2<<2) + j][(n1<<2) + i];
// Inverse quantization
img->cof[uv + 1][(n2<<2) + j][(n1<<2) + i] = ilev * dequant_coef[qp_rem_sp][i][j] << qp_per_sp;
}
else
{
//dequantization and addition of the predicted block
ilev=((img->cof[uv + 1][(n2<<2) + j][(n1<<2) + i]*dequant_coef[qp_rem][i][j]*A[i][j]<< qp_per) >>6)+predicted_chroma_block[n1*BLOCK_SIZE+i][n2*BLOCK_SIZE+j] ;
//quantization and dequantization
img->cof[uv + 1][(n2<<2) + j][(n1<<2) + i] = isignab((iabs(ilev) * quant_coef[qp_rem_sp][i][j] + qp_const2)>> q_bits_sp,ilev)*dequant_coef[qp_rem_sp][i][j]<<qp_per_sp;
}
}
img->cof[uv+1][0][0] = (mp1[0] + mp1[1] + mp1[2] + mp1[3]) >> 1;
img->cof[uv+1][0][4] = (mp1[0] + mp1[1] - mp1[2] - mp1[3]) >> 1;
img->cof[uv+1][4][0] = (mp1[0] - mp1[1] + mp1[2] - mp1[3]) >> 1;
img->cof[uv+1][4][4] = (mp1[0] - mp1[1] - mp1[2] + mp1[3]) >> 1;
}
static const byte decode_block_scan[16] = {0, 1, 4, 5, 2, 3, 6, 7, 8, 9, 12, 13, 10, 11, 14, 15};
void iMBtrans4x4(ColorPlane pl, struct img_par *img, int smb)
{
int j_pos, i_pos;
int jj, ii;
int block8x8;
int i, j, k;
int (*m7) [16] = img->m7[pl];
imgpel **curr_img = pl ? dec_picture->imgUV[pl - 1]: dec_picture->imgY;
//For residual DPCM
Boolean lossless_qpprime = (Boolean) (((img->qp + img->bitdepth_luma_qp_scale) == 0) && (img->lossless_qpprime_flag == 1));
// =============== 4x4 itrans ================
// -------------------------------------------
for (block8x8=0; block8x8 < MB_BLOCK_SIZE; block8x8 += 4)
{
for (k = block8x8; k < block8x8 + 4; k ++)
{
i = (decode_block_scan[k] & 3);
j = ((decode_block_scan[k] >> 2) & 3);
i_pos = (img->block_x + i) << BLOCK_SHIFT;
j_pos = (img->block_y + j) << BLOCK_SHIFT;
if(smb)
itrans_sp(img, (i << BLOCK_SHIFT), (j << BLOCK_SHIFT), i, j);
else
{
// itrans4x4(img, (i << BLOCK_SHIFT), (j << BLOCK_SHIFT), pl); // use DCT transform and make 4x4 block m7 from prediction block mpr
if(!lossless_qpprime)
itrans4x4(img, (i << BLOCK_SHIFT), (j << BLOCK_SHIFT), pl); // use DCT transform and make 4x4 block m7 from prediction block mpr
else
Inv_Residual_trans_4x4(img, (i << BLOCK_SHIFT), (j << BLOCK_SHIFT), i, j+4*(pl), 1, pl);
}
jj = j << BLOCK_SHIFT;
ii = i << BLOCK_SHIFT;
for(j = 0; j < BLOCK_SIZE; j++)
{
for(i = 0; i < BLOCK_SIZE; i++)
{
curr_img[j_pos + j][i_pos + i] = m7[j + jj][i + ii]; // construct picture from 4x4 blocks
}
}
}
}
}
void iMBtrans8x8(ColorPlane pl, struct img_par *img)
{
imgpel **curr_img = pl ? dec_picture->imgUV[pl - 1]: dec_picture->imgY;
int (*m7)[16] = img->m7[pl];
int block8x8;
int i,j;
int ioff, joff;
for (block8x8=0; block8x8<4; block8x8++)
{
// =============== 8x8 itrans ================
// -------------------------------------------
ioff = 8 * (block8x8 & 0x01);
joff = 8 * (block8x8 >> 1);
itrans8x8(pl, img, ioff, joff); // use DCT transform and make 8x8 block m7 from prediction block mpr
for(j = joff; j < joff + 8; j++)
{
for(i = ioff; i < ioff + 8; i++)
{
curr_img[img->pix_y + j][img->pix_x + i] = m7[j][i];
}
}
}
}
void iTransform(Macroblock *currMB, ColorPlane pl, struct img_par *img, int need_4x4_transform, int smb, int yuv)
{
static imgpel (*mpr) [16];
static imgpel **curr_img;
int j, uv = pl-1;
if ((currMB->cbp & 15) != 0 || smb)
{
if(need_4x4_transform) // 4x4 inverse transform
{
iMBtrans4x4(pl, img, smb);
}
else // 8x8 inverse transform
{
iMBtrans8x8(pl, img);
}
}
else
{
mpr = img->mpr[pl];
curr_img = pl ? dec_picture->imgUV[uv] : dec_picture->imgY;
for(j = 0; j < MB_BLOCK_SIZE; j++)
{
memcpy(&(curr_img[img->pix_y + j][img->pix_x]), &(mpr[j][0]), MB_BLOCK_SIZE * sizeof(imgpel));
}
}
if ((dec_picture->chroma_format_idc != YUV400) && (dec_picture->chroma_format_idc != YUV444))
{
static imgpel **curUV, *cur_line;
static int b4, b8;
static int ioff, joff, ii, jj;
static int (*m7UV)[16], *m7;
for(uv=0;uv<2;uv++)
{
curUV = &dec_picture->imgUV[uv][img->pix_c_y];
m7UV = img->m7[uv+1];
if (!smb && (currMB->cbp>>4))
{
for (b8 = 0; b8 < (img->num_uv_blocks); b8++)
{
for(b4 = 0; b4 < 4; b4++)
{
joff = subblk_offset_y[yuv][b8][b4];
ioff = subblk_offset_x[yuv][b8][b4];
itrans4x4(img, ioff, joff, uv + 1);
for(jj=joff;jj<joff + 4;jj++)
{
cur_line = &curUV[jj][img->pix_c_x + ioff];
m7 = &m7UV[jj][ioff];
for(ii=0;ii<4;ii++)
{
*(cur_line++) = *(m7++);
}
}
}
}
}
else if (smb)
{
itrans_sp_cr(img, uv);
for (joff=0;joff<8;joff+=4)
{
for(ioff=0;ioff<8;ioff+=4)
{
itrans4x4(img, ioff, joff, uv + 1);
for(jj=joff;jj<joff + 4;jj++)
for(ii=ioff;ii<ioff + 4;ii++)
{
curUV[jj][img->pix_c_x+ii]=m7UV[jj][ii];
}
}
}
}
else
{
mpr = img->mpr[uv + 1];
for(jj = 0; jj < img->mb_size[1][1]; jj++)
memcpy(&(curUV[jj][img->pix_c_x]), &(mpr[jj][0]), img->mb_size[1][0] * sizeof(imgpel));
}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -