📄 transform8x8.c
字号:
cur_pred[0][5] = (imgpel) ((P_U + P_S + 2*P_T + 2) >> 2);
cur_pred[1][1] =
cur_pred[0][3] = (imgpel) ((P_T + P_R + 2*P_S + 2) >> 2);
cur_pred[0][1] = (imgpel) ((P_S + P_Q + 2*P_R + 2) >> 2);
}
}
/*!
*************************************************************************************
* \brief
* Prefiltering for Intra8x8 prediction
*************************************************************************************
*/
void LowPassForIntra8x8Pred(imgpel *PredPel, int block_up_left, int block_up, int block_left)
{
int i;
static imgpel LoopArray[25];
memcpy(LoopArray,PredPel, 25 * sizeof(imgpel));
if(block_up)
{
if(block_up_left)
{
LoopArray[1] = (((&P_Z)[0] + ((&P_Z)[1]<<1) + (&P_Z)[2] + 2)>>2);
}
else
LoopArray[1] = (((&P_Z)[1] + ((&P_Z)[1]<<1) + (&P_Z)[2] + 2)>>2);
for(i = 2; i <16; i++)
{
LoopArray[i] = (((&P_Z)[i-1] + ((&P_Z)[i]<<1) + (&P_Z)[i+1] + 2)>>2);
}
LoopArray[16] = ((P_P + (P_P<<1) + P_O + 2)>>2);
}
if(block_up_left)
{
if(block_up && block_left)
{
LoopArray[0] = ((P_Q + (P_Z<<1) + P_A +2)>>2);
}
else
{
if(block_up)
LoopArray[0] = ((P_Z + (P_Z<<1) + P_A +2)>>2);
else
if(block_left)
LoopArray[0] = ((P_Z + (P_Z<<1) + P_Q +2)>>2);
}
}
if(block_left)
{
if(block_up_left)
LoopArray[17] = ((P_Z + (P_Q<<1) + P_R + 2)>>2);
else
LoopArray[17] = ((P_Q + (P_Q<<1) + P_R + 2)>>2);
for(i = 18; i <24; i++)
{
LoopArray[i] = (((&P_Z)[i-1] + ((&P_Z)[i]<<1) + (&P_Z)[i+1] + 2)>>2);
}
LoopArray[24] = ((P_W + (P_X<<1) + P_X + 2) >> 2);
}
memcpy(PredPel, LoopArray, 25 * sizeof(imgpel));
}
/*!
*************************************************************************************
* \brief
* R-D Cost for an 8x8 Intra block
*************************************************************************************
*/
double RDCost_for_8x8IntraBlocks(Macroblock *currMB, int *nonzero, int b8, int ipmode, double lambda, double min_rdcost, int mostProbableMode, int c_nzCbCr[3])
{
double rdcost = 0.0;
int dummy;
int x, y, rate;
int64 distortion = 0;
int block_x = (b8 & 0x01) << 3;
int block_y = (b8 >> 1) << 3;
int pic_pix_x = img->pix_x + block_x;
int pic_pix_y = img->pix_y + block_y;
int pic_opix_y = img->opix_y + block_y;
imgpel *img_org, *img_enc;
Slice *currSlice = img->currentSlice;
SyntaxElement se;
const int *partMap = assignSE2partition[input->partition_mode];
DataPartition *dataPart;
//===== perform DCT, Q, IQ, IDCT, Reconstruction =====
dummy = 0;
*nonzero = dct_8x8 (currMB, PLANE_Y, b8, &dummy, 1);
//===== get distortion (SSD) of 8x8 block =====
for (y=0; y<8; y++)
{
img_org = pCurImg[pic_opix_y+y];
img_enc = enc_picture->imgY[pic_pix_y+y];
for (x = pic_pix_x; x < pic_pix_x + 8; x++)
distortion += iabs2( img_org[x] - img_enc[x]);
}
if( img->yuv_format==YUV444 && !IS_INDEPENDENT(input) ) // INDEPENDENT_MODE 2006.07.26
{
ColorPlane k;
for (k = PLANE_U; k <= PLANE_V; k++)
{
select_plane(k);
/* for (j=0; j<8; j++) //KHHan, I think these line are not necessary
{
for (i=0; i<8; i++)
{
img->mpr[k][block_y+j][block_x+i] = img->mpr_8x8[k][ipmode][j][i];
img->m7[k][j][i] = pImgOrg[k][img->pix_y+block_y+j][img->pix_x+block_x+i] - img->mpr_8x8[k][ipmode][j][i];
}
}*/
c_nzCbCr[k]=dct_8x8(currMB, k, b8, &dummy,1);
for( y = 0; y < 8; y++ )
for (x=pic_pix_x; x<pic_pix_x+8; x++)
distortion +=iabs2(pImgOrg[k][pic_opix_y+y][x] - enc_picture->p_curr_img[pic_pix_y+y][x]);
}
ipmode_DPCM=NO_INTRA_PMODE; //For residual DPCM
select_plane(PLANE_Y);
}
else if( img->yuv_format==YUV444 && IS_INDEPENDENT(input) ) //For residual DPCM
{
ipmode_DPCM=NO_INTRA_PMODE;
}
//===== RATE for INTRA PREDICTION MODE (SYMBOL MODE MUST BE SET TO CAVLC) =====
se.value1 = (mostProbableMode == ipmode) ? -1 : ipmode < mostProbableMode ? ipmode : ipmode-1;
//--- set position and type ---
se.context = b8;
se.type = SE_INTRAPREDMODE;
//--- choose data partition ---
if (img->type!=B_SLICE)
dataPart = &(currSlice->partArr[partMap[SE_INTRAPREDMODE]]);
else
dataPart = &(currSlice->partArr[partMap[SE_BFRAME]]);
//--- encode and update rate ---
writeIntraPredMode (&se, dataPart);
rate = se.len;
//===== RATE for LUMINANCE COEFFICIENTS =====
if (input->symbol_mode == CAVLC)
{
if ( img->yuv_format==YUV444 && !IS_INDEPENDENT(input) )
{
int b4;
for(b4=0; b4<4; b4++)
{
rate += writeCoeff4x4_CAVLC (currMB, LUMA, b8, b4, 0);
rate += writeCoeff4x4_CAVLC (currMB, CB, b8, b4, 0);
rate += writeCoeff4x4_CAVLC (currMB, CR, b8, b4, 0);
}
}
else
{
rate += writeCoeff4x4_CAVLC (currMB, LUMA, b8, 0, 0);
rate += writeCoeff4x4_CAVLC (currMB, LUMA, b8, 1, 0);
rate += writeCoeff4x4_CAVLC (currMB, LUMA, b8, 2, 0);
rate += writeCoeff4x4_CAVLC (currMB, LUMA, b8, 3, 0);
}
}
else
{
rate += writeCoeff8x8_CABAC (currMB, PLANE_Y, b8, 1);
if( img->yuv_format==YUV444 && !IS_INDEPENDENT(input) )
{
rate += writeCoeff8x8_CABAC (currMB, PLANE_U, b8, 1);
rate += writeCoeff8x8_CABAC (currMB, PLANE_V, b8, 1);
}
}
rdcost = (double)distortion + lambda*(double)rate;
return rdcost;
}
/*!
************************************************************************
* \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:
* b8: Block position inside a macro block (0,1,2,3).
*
* \par Output:
* nonzero: 0 if no levels are nonzero. 1 if there are nonzero levels.
* coeff_cost: Counter for nonzero coefficients, used to discard expensive levels.
************************************************************************
*/
#define MC(coeff) ((coeff)&3)
int dct_8x8(Macroblock *currMB, ColorPlane pl, int b8,int *coeff_cost, int intra)
{
int i,j,ilev,coeff_ctr;
int level,scan_pos = 0,run = -1;
int nonzero = FALSE;
int block_x = 8*(b8 & 0x01);
int block_y = 8*(b8 >> 1);
int pl_off = pl<<2;
int* ACLevel = img->cofAC[b8+pl_off][0][0];
int* ACRun = img->cofAC[b8+pl_off][0][1];
const byte *c_cost = COEFF_COST8x8[input->disthres];
imgpel **img_enc = enc_picture->p_curr_img;
imgpel (*curr_mpr)[16] = img->mpr[pl];
int (*curr_res)[16] = img->m7[pl];
int max_imgpel_value = img->max_imgpel_value;
int scan_poss[4] = { 0 }, runs[4] = { -1, -1, -1, -1 };
int MCcoeff = 0;
static imgpel *img_Y, *predY;
int *m7;
int qp = currMB->qp_scaled[pl];
Boolean lossless_qpprime = (Boolean) ((qp == 0) && img->lossless_qpprime_flag==1);
const byte (*pos_scan)[2] = currMB->is_field_mode ? FIELD_SCAN8x8 : SNGL_SCAN8x8;
int qp_per = qp_per_matrix[qp];
int qp_rem = qp_rem_matrix[qp];
int q_bits = Q_BITS_8 + qp_per;
int **fadjust8x8 = img->AdaptiveRounding ? (pl ? &img->fadjust8x8Cr[pl-1][intra][block_y] : &img->fadjust8x8[intra][block_y]) :NULL;
int **levelscale = LevelScale8x8Comp [pl][intra][qp_rem];
int **invlevelscale = InvLevelScale8x8Comp[pl][intra][qp_rem];
int **leveloffset = LevelOffset8x8Comp [pl][intra][qp];
if (!lossless_qpprime)
{
// forward 8x8 transform
forward8x8(curr_res, curr_res, block_y, block_x);
// Quant
for (coeff_ctr = 0; coeff_ctr < 64; coeff_ctr++)
{
i=pos_scan[coeff_ctr][0];
j=pos_scan[coeff_ctr][1];
run++;
ilev=0;
if (currMB->luma_transform_size_8x8_flag && input->symbol_mode == CAVLC)
{
MCcoeff = MC(coeff_ctr);
runs[MCcoeff]++;
}
m7 = &curr_res[block_y + j][block_x];
level = (iabs (m7[i]) * levelscale[j][i] + leveloffset[j][i]) >> q_bits;
if (level != 0)
{
if (img->AdaptiveRounding)
{
fadjust8x8[j][block_x + i] = rshift_rnd_sf((AdaptRndWeight * (iabs (m7[i]) * levelscale[j][i] - (level << q_bits))), (q_bits + 1));
}
nonzero=TRUE;
if (currMB->luma_transform_size_8x8_flag && input->symbol_mode == CAVLC)
{
*coeff_cost += (level > 1) ? MAX_VALUE : c_cost[runs[MCcoeff]];
img->cofAC[b8+pl_off][MCcoeff][0][scan_poss[MCcoeff] ] = isignab(level,m7[i]);
img->cofAC[b8+pl_off][MCcoeff][1][scan_poss[MCcoeff]++] = runs[MCcoeff];
runs[MCcoeff]=-1;
}
else
{
*coeff_cost += (level > 1) ? MAX_VALUE : c_cost[run];
ACLevel[scan_pos ] = isignab(level,m7[i]);
ACRun [scan_pos++] = run;
run=-1; // reset zero level counter
}
level = isignab(level, m7[i]);
m7[i] = rshift_rnd_sf(level*invlevelscale[j][i]<<qp_per, 6); // dequantization
}
else
{
if (img->AdaptiveRounding)
fadjust8x8[j][block_x + i] = 0;
m7[i] = 0;
}
}
if (!currMB->luma_transform_size_8x8_flag || input->symbol_mode != CAVLC)
ACLevel[scan_pos] = 0;
else
{
for(i=0; i<4; i++)
img->cofAC[b8+pl_off][i][0][scan_poss[i]] = 0;
}
if (nonzero)
{
// Inverse Transform
inverse8x8(curr_res, curr_res, block_y, block_x);
for( j=block_y; j<block_y + BLOCK_SIZE_8x8; j++)
{
img_Y = &img_enc[img->pix_y + j][img->pix_x + block_x];
predY = &curr_mpr[j][block_x];
m7 = &curr_res[j][block_x];
for( i=0; i<BLOCK_SIZE_8x8; i++)
{
img_Y[i] = iClip1( max_imgpel_value, rshift_rnd_sf((m7[i]),DQ_BITS_8) + predY[i]);
}
}
}
else // no transform coefficients
{
for( j=block_y; j< block_y + BLOCK_SIZE_8x8; j++)
{
memcpy(&(img_enc[img->pix_y + j][img->pix_x + block_x]),&(curr_mpr[j][block_x]), BLOCK_SIZE_8x8 * sizeof(imgpel));
}
}
}
else
{
// Quant
runs[0]=runs[1]=runs[2]=runs[3]=-1;
scan_poss[0]=scan_poss[1]=scan_poss[2]=scan_poss[3]=0;
for (coeff_ctr=0; coeff_ctr < 64; coeff_ctr++)
{
i=pos_scan[coeff_ctr][0];
j=pos_scan[coeff_ctr][1];
run++;
ilev=0;
if (currMB->luma_transform_size_8x8_flag && input->symbol_mode == CAVLC)
{
MCcoeff = MC(coeff_ctr);
runs[MCcoeff]++;
}
m7 = &curr_res[block_y + j][block_x];
level = iabs (m7[i]);
if (img->AdaptiveRounding)
{
fadjust8x8[j][block_x+i] = 0;
}
if (level != 0)
{
nonzero = TRUE;
if (currMB->luma_transform_size_8x8_flag && input->symbol_mode == CAVLC)
{
*coeff_cost += MAX_VALUE;
img->cofAC[b8+pl_off][MCcoeff][0][scan_poss[MCcoeff] ] = isignab(level,m7[i]);
img->cofAC[b8+pl_off][MCcoeff][1][scan_poss[MCcoeff]++] = runs[MCcoeff];
++scan_pos;
runs[MCcoeff]=-1;
}
else
{
*coeff_cost += MAX_VALUE;
ACLevel[scan_pos ] = isignab(level,m7[i]);
ACRun [scan_pos++] = run;
run=-1; // reset zero level counter
}
level = isignab(level, m7[i]);
ilev = level;
}
}
if (!currMB->luma_transform_size_8x8_flag || input->symbol_mode != CAVLC)
ACLevel[scan_pos] = 0;
else
{
for(i=0; i<4; i++)
img->cofAC[b8+pl_off][i][0][scan_poss[i]] = 0;
}
if(ipmode_DPCM<2) //For residual DPCM
{
Inv_Residual_DPCM_8x8(pl, block_y, block_x);
}
for( j=block_y; j<block_y + BLOCK_SIZE_8x8; j++)
{
for( i=block_x; i< block_x + BLOCK_SIZE_8x8; i++)
{
curr_res[j][i] = curr_res[j][i] + curr_mpr[j][i];
img_enc[img->pix_y + j][img->pix_x + i]= (imgpel) curr_res[j][i];
}
}
}
// Decoded block moved to frame memory
return nonzero;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -