📄 transform8x8.c
字号:
memcpy(LoopArray,PredPel, 25 * sizeof(imgpel));
if(block_up)
{
if(block_up_left)
{
LoopArray[1] = ((PredPel[0] + (PredPel[1]<<1) + PredPel[2] + 2)>>2);
}
else
LoopArray[1] = ((PredPel[1] + (PredPel[1]<<1) + PredPel[2] + 2)>>2);
for(i = 2; i <16; i++)
{
LoopArray[i] = ((PredPel[i-1] + (PredPel[i]<<1) + PredPel[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] = ((PredPel[i-1] + (PredPel[i]<<1) + PredPel[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 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;
Slice *currSlice = img->currentSlice;
SyntaxElement se;
const int *partMap = assignSE2partition[params->partition_mode];
DataPartition *dataPart;
//===== perform DCT, Q, IQ, IDCT, Reconstruction =====
dummy = 0;
*nonzero = pDCT_8x8 (currMB, PLANE_Y, b8, &dummy, 1);
//===== get distortion (SSD) of 8x8 block =====
distortion += compute_SSE(&pCurImg[pic_opix_y], &enc_picture->imgY[pic_pix_y], pic_pix_x, pic_pix_x, 8, 8);
if(img->P444_joined)
{
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->mb_pred[k][block_y+j][block_x+i] = img->mpr_8x8[k][ipmode][j][i];
img->mb_ores[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 ]= pDCT_8x8(currMB, k, b8, &dummy,1);
distortion += compute_SSE(&pImgOrg[k][pic_opix_y], &enc_picture->p_curr_img[pic_pix_y], pic_pix_x, pic_pix_x, 8, 8);
}
ipmode_DPCM = NO_INTRA_PMODE;
select_plane(PLANE_Y);
}
else if( img->yuv_format==YUV444 && IS_INDEPENDENT(params) ) //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 (currSlice->symbol_mode == CAVLC)
{
if (img->P444_joined)
{
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->P444_joined)
{
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.
************************************************************************
*/
int dct_8x8(Macroblock *currMB, ColorPlane pl, int b8, int *coeff_cost, int intra)
{
int j;
int nonzero = FALSE;
int block_x = 8*(b8 & 0x01);
int block_y = 8*(b8 >> 1);
int pl_off = b8+ (pl<<2);
int* ACLevel = img->cofAC[pl_off][0][0];
int* ACRun = img->cofAC[pl_off][0][1];
imgpel **img_enc = enc_picture->p_curr_img;
imgpel (*mb_pred)[MB_BLOCK_SIZE] = img->mb_pred[pl];
int (*mb_ores)[MB_BLOCK_SIZE] = img->mb_ores[pl];
int (*mb_rres)[MB_BLOCK_SIZE] = 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_SCAN8x8 : SNGL_SCAN8x8;
int qp_rem = qp_rem_matrix[qp];
levelscale = LevelScale8x8Comp [pl][intra][qp_rem];
invlevelscale = InvLevelScale8x8Comp[pl][intra][qp_rem];
leveloffset = LevelOffset8x8Comp [pl][intra][qp];
fadjust8x8 = img->AdaptiveRounding ? (pl ? &img->fadjust8x8Cr[pl-1][intra][block_y] : &img->fadjust8x8[intra][block_y]) :NULL;
// Forward 8x8 transform
forward8x8(mb_ores, mb_rres, block_y, block_x);
// Quantization process
nonzero = quant_8x8(&mb_rres[block_y], block_y, block_x, qp, ACLevel, ACRun, fadjust8x8,
levelscale, invlevelscale, leveloffset, coeff_cost, pos_scan, COEFF_COST8x8[params->disthres]);
if (nonzero)
{
// Inverse 8x8 transform
inverse8x8(mb_rres, 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_8x8, BLOCK_SIZE_8x8, max_imgpel_value, DQ_BITS_8);
}
else // if (nonzero) => No transformed residual. Just use prediction.
{
for( j=block_y; j< block_y + BLOCK_SIZE_8x8; j++)
{
memcpy(&(img_enc[img->pix_y + j][img->pix_x + block_x]),&(mb_pred[j][block_x]), BLOCK_SIZE_8x8 * sizeof(imgpel));
}
}
// Decoded block moved to frame memory
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. Used for CAVLC.
*
* \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.
************************************************************************
*/
int dct_8x8_cavlc(Macroblock *currMB, ColorPlane pl, int b8, int *coeff_cost, int intra)
{
int j;
int nonzero = FALSE;
int block_x = 8*(b8 & 0x01);
int block_y = 8*(b8 >> 1);
int pl_off = b8+ (pl<<2);
imgpel **img_enc = enc_picture->p_curr_img;
imgpel (*mb_pred)[MB_BLOCK_SIZE] = img->mb_pred[pl];
int (*mb_ores)[MB_BLOCK_SIZE] = img->mb_ores[pl];
int (*mb_rres)[MB_BLOCK_SIZE] = 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_SCAN8x8 : SNGL_SCAN8x8;
int qp_rem = qp_rem_matrix[qp];
levelscale = LevelScale8x8Comp [pl][intra][qp_rem];
invlevelscale = InvLevelScale8x8Comp[pl][intra][qp_rem];
leveloffset = LevelOffset8x8Comp [pl][intra][qp];
fadjust8x8 = img->AdaptiveRounding ? (pl ? &img->fadjust8x8Cr[pl-1][intra][block_y] : &img->fadjust8x8[intra][block_y]) :NULL;
// Forward 8x8 transform
forward8x8(mb_ores, mb_rres, block_y, block_x);
// Quantization process
nonzero = quant_8x8cavlc(&mb_rres[block_y], block_y, block_x, qp, img->cofAC[pl_off], fadjust8x8,
levelscale, invlevelscale, leveloffset, coeff_cost, pos_scan, COEFF_COST8x8[params->disthres]);
if (nonzero)
{
// Inverse 8x8 transform
inverse8x8(mb_rres, 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_8x8, BLOCK_SIZE_8x8, max_imgpel_value, DQ_BITS_8);
}
else // if (nonzero) => No transformed residual. Just use prediction.
{
for( j=block_y; j< block_y + BLOCK_SIZE_8x8; j++)
{
memcpy(&(img_enc[img->pix_y + j][img->pix_x + block_x]),&(mb_pred[j][block_x]), BLOCK_SIZE_8x8 * sizeof(imgpel));
}
}
// Decoded block moved to frame memory
return nonzero;
}
int dct_8x8_ls(Macroblock *currMB, ColorPlane pl, int b8, int *coeff_cost, int intra)
{
int i,j,coeff_ctr;
int scan_pos = 0,run = -1;
int nonzero = FALSE;
int block_x = 8*(b8 & 0x01);
int block_y = 8*(b8 >> 1);
int pl_off = b8 + (pl<<2);
int* ACLevel = img->cofAC[pl_off][0][0];
int* ACRun = img->cofAC[pl_off][0][1];
imgpel **img_enc = enc_picture->p_curr_img;
imgpel (*mb_pred)[MB_BLOCK_SIZE] = img->mb_pred[pl];
int (*mb_ores)[MB_BLOCK_SIZE] = img->mb_ores[pl];
int (*mb_rres)[MB_BLOCK_SIZE] = img->mb_rres[pl];
int scan_poss[4] = { 0 }, runs[4] = { -1, -1, -1, -1 };
int MCcoeff = 0;
int *m7;
int is_cavlc = (img->currentSlice->symbol_mode == CAVLC);
const byte (*pos_scan)[2] = currMB->is_field_mode ? FIELD_SCAN8x8 : SNGL_SCAN8x8;
int **fadjust8x8 = img->AdaptiveRounding ? (pl ? &img->fadjust8x8Cr[pl-1][intra][block_y] : &img->fadjust8x8[intra][block_y]) :NULL;
runs[0]=runs[1]=runs[2]=runs[3]=-1;
scan_poss[0] = scan_poss[1] = scan_poss[2] = scan_poss[3] = 0;
if( (ipmode_DPCM < 2)&&(intra))
{
Residual_DPCM_8x8(ipmode_DPCM, mb_ores, mb_rres, block_y, block_x);
}
for (coeff_ctr=0; coeff_ctr < 64; coeff_ctr++)
{
i=pos_scan[coeff_ctr][0];
j=pos_scan[coeff_ctr][1];
run++;
if (currMB->luma_transform_size_8x8_flag && is_cavlc)
{
MCcoeff = (coeff_ctr & 3);
runs[MCcoeff]++;
}
m7 = &mb_rres[block_y + j][block_x + i];
if (img->AdaptiveRounding)
{
fadjust8x8[j][block_x+i] = 0;
}
if (*m7 != 0)
{
nonzero = TRUE;
if (currMB->luma_transform_size_8x8_flag && is_cavlc)
{
*m7 = iClip3(-CAVLC_LEVEL_LIMIT, CAVLC_LEVEL_LIMIT, *m7);
*coeff_cost += MAX_VALUE;
img->cofAC[pl_off][MCcoeff][0][scan_poss[MCcoeff] ] = *m7;
img->cofAC[pl_off][MCcoeff][1][scan_poss[MCcoeff]++] = runs[MCcoeff];
++scan_pos;
runs[MCcoeff]=-1;
}
else
{
*coeff_cost += MAX_VALUE;
ACLevel[scan_pos ] = *m7;
ACRun [scan_pos++] = run;
run=-1; // reset zero level counter
}
}
}
if (!currMB->luma_transform_size_8x8_flag || !is_cavlc)
ACLevel[scan_pos] = 0;
else
{
for(i=0; i<4; i++)
img->cofAC[pl_off][i][0][scan_poss[i]] = 0;
}
if( (ipmode_DPCM < 2) && (intra))
{
Inv_Residual_DPCM_8x8(mb_rres, 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++)
{
mb_rres[j][i] += mb_pred[j][i];
img_enc[img->pix_y + j][img->pix_x + i]= (imgpel) mb_rres[j][i];
}
}
// Decoded block moved to frame memory
return nonzero;
}
/*static inline void compute_diff(int *diff, imgpel *cimg, imgpel *cmpr, int width)
{
int i;
for (i = 0; i < width; i++)
{
*(diff++) = *(cimg++) - *(cmpr++);
}
}*/
/*!
*************************************************************************************
* \brief
* distortion for an 8x8 Intra block
*************************************************************************************
*/
void compute_comp_cost8x8(imgpel **cur_img, imgpel mpr8x8[16][16], int pic_opix_x, double *cost)
{
int i, j;
int *diff = &diff64[0];
imgpel *cimg, *cmpr;
for (j=0; j<8; j++)
{
// compute_diff(diff, &cur_img[j][pic_opix_x], &mpr8x8[j][0], BLOCK_SIZE_8x8);
cimg = &cur_img[j][pic_opix_x];
cmpr = &mpr8x8[j][0];
for (i=0; i<8; i++)
{
*diff++ = *cimg++ - *cmpr++;
}
}
*cost += distortion8x8 (diff64);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -