📄 block.c
字号:
* 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];
// 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++)
img->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]=img->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;
img->m7[j][i]=m6[i]+m6[i1];
img->m7[j][i1]=m6[i]-m6[i1];
}
}
// vertical
for (i=0;i<BLOCK_SIZE;i++)
{
for (j=0;j<BLOCK_SIZE;j++)
m5[j]=img->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;
img->m7[j][i] =iClip1(img->max_imgpel_value,rshift_rnd_sf((m6[j]+m6[j1]),DQ_BITS));
img->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) img->m7[j][i];
}
void itrans_sp_cr(struct img_par *img, int uv)
{
int ll = uv << 1;
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[n1+ll][4+n2][0][0]+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[n1+ll][4+n2][0][0]*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[n1+ll][4+n2][j][i] = (img->cof[n1+ll][4+n2][j][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[n1+ll][4+n2][j][i];
// Inverse quantization
img->cof[n1+ll][4+n2][j][i] = ilev * dequant_coef[qp_rem_sp][i][j] << qp_per_sp ;
}
else
{
//dequantization and addition of the predicted block
ilev=((img->cof[n1+ll][4+n2][j][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[n1+ll][4+n2][j][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[0+ll][4][0][0] = (mp1[0] + mp1[1] + mp1[2] + mp1[3]) >> 1;
img->cof[0+ll][5][0][0] = (mp1[0] + mp1[1] - mp1[2] - mp1[3]) >> 1;
img->cof[1+ll][4][0][0] = (mp1[0] - mp1[1] + mp1[2] - mp1[3]) >> 1;
img->cof[1+ll][5][0][0] = (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(struct img_par *img, int smb)
{
int j_pos, i_pos;
int block8x8;
int i, j, k;
// =============== 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
itrans (img, (i << BLOCK_SHIFT), (j << BLOCK_SHIFT), i, j, 0, LumaComp); // use DCT transform and make 4x4 block m7 from prediction block mpr
for(j = 0; j < BLOCK_SIZE; j++)
{
for(i = 0; i < BLOCK_SIZE; i++)
{
dec_picture->imgY[j_pos + j][i_pos + i] = img->m7[j][i]; // construct picture from 4x4 blocks
}
}
}
}
}
void iMBtrans8x8(struct img_par *img)
{
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(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++)
{
dec_picture->imgY[img->pix_y + j][img->pix_x + i] = img->m7[j][i]; // construct picture from 4x4 blocks
}
}
}
}
void iTransform(struct img_par *img, Macroblock *currMB, int need_4x4_transform, int smb, int yuv)
{
static imgpel (*mpr) [16];
int i, j, uv;
if ((currMB->cbp & 15) != 0 || smb)
{
if(need_4x4_transform)// 4x4 inverse transform
{
iMBtrans4x4(img, smb);
}
else // 8x8 inverse transform
{
iMBtrans8x8(img);
}
}
else
{
mpr = img->mpr[LumaComp];
for(j = 0; j < MB_BLOCK_SIZE; j++)
{
memcpy(&(dec_picture->imgY[img->pix_y + j][img->pix_x]), &(mpr[j][0]), MB_BLOCK_SIZE * sizeof(imgpel));
}
}
if ((dec_picture->chroma_format_idc != YUV400) && !IS_INDEPENDENT(img))
{
imgpel **curUV;
int b4, b8;
int ioff, joff, i4, j4, ii, jj;
int uv_shift;
for(uv=0;uv<2;uv++)
{
curUV = dec_picture->imgUV[uv];
if (!smb && (currMB->cbp>>4))
{
uv_shift = uv * (img->num_uv_blocks);
for (b8 = 0; b8 < (img->num_uv_blocks); b8++)
{
for(b4 = 0; b4 < 4; b4++)
{
joff = subblk_offset_y[yuv][b8][b4];
j4 = img->pix_c_y + joff;
ioff = subblk_offset_x[yuv][b8][b4];
i4 = img->pix_c_x + ioff;
itrans(img,ioff,joff, cofuv_blk_x[yuv][b8+uv_shift][b4], cofuv_blk_y[yuv][b8+uv_shift][b4], 1, uv + 1);
for(jj=0;jj<4;jj++)
for(ii=0;ii<4;ii++)
{
curUV[j4+jj][i4+ii]=img->m7[jj][ii];
}
}
}
}
else if (smb)
{
itrans_sp_cr(img, uv);
for (j=4;j<6;j++)
{
joff=(j-4)*4;
j4=img->pix_c_y+joff;
for(i=0;i<2;i++)
{
ioff=i*4;
i4=img->pix_c_x+ioff;
itrans(img, ioff, joff, 2*uv+i, j, 1, uv + 1);
for(jj=0;jj<4;jj++)
for(ii=0;ii<4;ii++)
{
curUV[j4+jj][i4+ii]=img->m7[jj][ii];
}
}
}
}
else
{
mpr = img->mpr[uv + 1];
for(jj = 0; jj < img->mb_size[1][1]; jj++)
memcpy(&(curUV[img->pix_c_y + 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 + -