📄 rdopt.c
字号:
ipmode_DPCM=ipmode;
}
}
else if ((img->yuv_format == YUV444) && IS_INDEPENDENT(input))
{
if((lossless_qpprime)&&(ipmode<2))
{
Residual_DPCM_4x4(ipmode, 0, block_y, block_x);
ipmode_DPCM=ipmode;
}
}
//===== store the coding state =====
//store_coding_state (currMB, cs_cm);
// get and check rate-distortion cost
#ifdef BEST_NZ_COEFF
currMB->cbp_bits[0] = cbp_bits;
#endif
if ((rdcost = RDCost_for_4x4IntraBlocks (currMB, &c_nz, b8, b4, ipmode, lambda, mostProbableMode, c_nzCbCr)) < min_rdcost)
{
//--- set coefficients ---
memcpy(cofAC4x4[0],ACLevel, 18 * sizeof(int));
memcpy(cofAC4x4[1],ACRun, 18 * sizeof(int));
//--- set reconstruction ---
for (y=0; y<4; y++)
{
memcpy(rec4x4[y],&enc_picture->imgY[pic_pix_y+y][pic_pix_x], BLOCK_SIZE * sizeof(imgpel));
}
// SP/SI reconstruction
if(img->type==SP_SLICE &&(!si_frame_indicator && !sp2_frame_indicator))
{
for (y=0; y<4; y++)
{
memcpy(lrec4x4[y],&lrec[pic_pix_y+y][pic_pix_x], BLOCK_SIZE * sizeof(int));// stores the mode coefficients
}
}
if( img->yuv_format==YUV444 && !IS_INDEPENDENT(input) )
{
//--- set coefficients ---
for (uv=0; uv < 2; uv++)
{
memcpy(cofAC4x4CbCr[uv][0],img->cofAC[b8+4+uv*4][b4][0], 18 * sizeof(int));
memcpy(cofAC4x4CbCr[uv][1],img->cofAC[b8+4+uv*4][b4][1], 18 * sizeof(int));
cr_cbp[uv + 1] = c_nzCbCr[uv + 1];
//--- set reconstruction ---
for (y=0; y<4; y++)
{
memcpy(rec4x4CbCr[uv][y],&enc_picture->imgUV[uv][pic_pix_y+y][pic_pix_x], BLOCK_SIZE * sizeof(imgpel));
}
}
}
//--- flag if dct-coefficients must be coded ---
nonzero = c_nz;
//--- set best mode update minimum cost ---
*min_cost = rdcost;
min_rdcost = rdcost;
best_ipmode = ipmode;
#ifdef BEST_NZ_COEFF
best_nz_coeff = img->nz_coeff [img->current_mb_nr][block_x4][block_y4];
best_coded_block_flag = (int)((currMB->cbp_bits[0] >> bit_pos)&(int64)(1));
#endif
//store_coding_state (currMB, cs_ib4);
if (img->AdaptiveRounding)
{
for (j = block_y; j < block_y + 4; j++)
memcpy(&fadjust4x4[j][block_x],&img->fadjust4x4[1][j][block_x], BLOCK_SIZE * sizeof(int));
if(img->yuv_format == YUV444 && !IS_INDEPENDENT(input))
{
for (j=0; j<4; j++)
{
memcpy(&fadjust4x4Cr[0][block_y+j][block_x],&img->fadjust4x4Cr[0][1][block_y+j][block_x], BLOCK_SIZE * sizeof(int));
memcpy(&fadjust4x4Cr[1][block_y+j][block_x],&img->fadjust4x4Cr[1][1][block_y+j][block_x], BLOCK_SIZE * sizeof(int));
}
}
}
}
#ifndef RESET_STATE
reset_coding_state (currMB, cs_cm);
#endif
}
}
}
#ifdef BEST_NZ_COEFF
img->nz_coeff [img->current_mb_nr][block_x4][block_y4] = best_nz_coeff;
cbp_bits &= (~(int64)(1<<bit_pos));
cbp_bits |= (int64)(best_coded_block_flag<<bit_pos);
#endif
//===== set intra mode prediction =====
img->ipredmode[pic_block_y][pic_block_x] = (char) best_ipmode;
currMB->intra_pred_modes[4*b8+b4] =
(char) (mostProbableMode == best_ipmode ? -1 : (best_ipmode < mostProbableMode ? best_ipmode : best_ipmode-1));
if (!input->rdopt)
{
// get prediction and prediction error
for (j=0; j < BLOCK_SIZE; j++)
{
m7 = &img->m7[0][block_y+j][block_x];
org_img = &pCurImg[pic_opix_y+j][pic_opix_x];
prd_img = img->mpr_4x4[0][best_ipmode][j];
memcpy(&curr_mpr[block_y+j][block_x], prd_img, BLOCK_SIZE * sizeof(imgpel));
for (i=0; i<BLOCK_SIZE; i++)
{
m7[i] = org_img[i] - prd_img[i];
}
}
if(lossless_qpprime) //For residual DPCM
{
ipmode_DPCM=best_ipmode;
if((best_ipmode<2))
{
Residual_DPCM_4x4(best_ipmode, 0, block_y, block_x);
}
}
select_dct(currMB);
nonzero = pDCT_4x4 (currMB, PLANE_Y, block_x, block_y, &dummy, 1);
if ((img->yuv_format == YUV444) && !IS_INDEPENDENT(input))
{
ColorPlane k;
for (k = PLANE_U; k <= PLANE_V; k++)
{
select_plane(k);
for (j=0; j<4; j++)
{
for (i=0; i<4; i++)
{
img->mpr[k][block_y+j][block_x+i] = img->mpr_4x4[k][best_ipmode][j][i];
img->m7[k][block_y+j][block_x+i] = pImgOrg[k][pic_opix_y+j][pic_opix_x+i] - img->mpr_4x4[k][best_ipmode][j][i];
}
}
if(lossless_qpprime) //For residual DPCM
{
if((best_ipmode<2))
{
Residual_DPCM_4x4(best_ipmode, k, block_y, block_x);
}
}
cr_cbp[k] = pDCT_4x4(currMB, k, block_x,block_y,&dummy,1);
}
select_plane(PLANE_Y);
}
}
else
{
if( (img->yuv_format==YUV444) && !IS_INDEPENDENT(input) )
{
select_plane(PLANE_U);
for (j=0; j<4; j++)
{
for (i=0; i<4; i++)
{
img->mpr[1][block_y+j][block_x+i] = img->mpr_4x4[1][best_ipmode][j][i];
img->m7[1][block_y+j][block_x+i] = imgUV_org[0][img->pix_y+block_y+j][img->pix_x+block_x+i] - img->mpr_4x4[1][best_ipmode][j][i];
}
}
cr_cbp[1] = pDCT_4x4(currMB, PLANE_U, block_x,block_y,&dummy,1);
select_plane(PLANE_V);
for (j=0; j<4; j++)
{
for (i=0; i<4; i++)
{
img->mpr[2][block_y+j][block_x+i] = img->mpr_4x4[2][best_ipmode][j][i];
img->m7[2][block_y+j][block_x+i] = imgUV_org[1][img->pix_y+block_y+j][img->pix_x+block_x+i] - img->mpr_4x4[2][best_ipmode][j][i];
}
}
cr_cbp[2] = pDCT_4x4(currMB, PLANE_V,block_x,block_y,&dummy,1);
select_plane(PLANE_Y);
}
//===== restore coefficients =====
memcpy (ACLevel,cofAC4x4[0], 18 * sizeof(int));
memcpy (ACRun,cofAC4x4[1], 18 * sizeof(int));
//===== restore reconstruction and prediction (needed if single coeffs are removed) =====
for (y=0; y<BLOCK_SIZE; y++)
{
memcpy (&enc_picture->imgY[pic_pix_y + y][pic_pix_x],rec4x4[y], BLOCK_SIZE * sizeof(imgpel));
memcpy (&curr_mpr[block_y + y][block_x],img->mpr_4x4[0][best_ipmode][y], BLOCK_SIZE * sizeof(imgpel));
}
// SP/SI reconstuction
if(img->type==SP_SLICE &&(!si_frame_indicator && !sp2_frame_indicator))
{
for (y=0; y<BLOCK_SIZE; y++)
{
memcpy (&lrec[pic_pix_y+y][pic_pix_x],lrec4x4[y], BLOCK_SIZE * sizeof(int));//restore coefficients when encoding primary SP frame
}
}
if( img->yuv_format == YUV444 && !IS_INDEPENDENT(input) )
{
for (uv=0; uv < 2; uv++ )
{
//===== restore coefficients =====
memcpy(img->cofAC[b8+4+uv*4][b4][0], cofAC4x4CbCr[uv][0], 18 * sizeof(int));
memcpy(img->cofAC[b8+4+uv*4][b4][1], cofAC4x4CbCr[uv][1], 18 * sizeof(int));
//===== restore reconstruction and prediction (needed if single coeffs are removed) =====
for (y=0; y<BLOCK_SIZE; y++)
{
memcpy(&enc_picture->imgUV[uv][pic_pix_y+y][pic_pix_x],rec4x4CbCr[uv][y], BLOCK_SIZE * sizeof(imgpel));
memcpy(&img->mpr[uv + 1][block_y+y][block_x], img->mpr_4x4[uv + 1][best_ipmode][y], BLOCK_SIZE * sizeof(imgpel));
}
}
}
if (img->AdaptiveRounding)
{
for (j=block_y; j<block_y + BLOCK_SIZE; j++)
memcpy (&img->fadjust4x4[1][j][block_x],&fadjust4x4[j][block_x], BLOCK_SIZE * sizeof(int));
if (img->yuv_format == YUV444 && !IS_INDEPENDENT(input))
{
for (j=0; j<BLOCK_SIZE; j++)
{
memcpy (&img->fadjust4x4Cr[0][1][block_y+j][block_x],&fadjust4x4Cr[0][block_y+j][block_x], BLOCK_SIZE * sizeof(int));
memcpy (&img->fadjust4x4Cr[1][1][block_y+j][block_x],&fadjust4x4Cr[1][block_y+j][block_x], BLOCK_SIZE * sizeof(int));
}
}
}
}
return nonzero;
}
/*!
*************************************************************************************
* \brief
* Mode Decision for an 8x8 Intra block
*************************************************************************************
*/
int Mode_Decision_for_8x8IntraBlocks(Macroblock *currMB, int b8,double lambda,double *cost, int non_zero[2])
{
int nonzero = 0, b4;
double cost4x4;
int CbCr_cbp[3]={0, 0, 0};
non_zero[0] = 0;
non_zero[1] = 0;
*cost = (int)floor(6.0 * lambda + 0.4999);
for (b4=0; b4<4; b4++)
{
if (Mode_Decision_for_4x4IntraBlocks (currMB, b8, b4, lambda, &cost4x4, CbCr_cbp))
{
nonzero = 1;
}
*cost += cost4x4;
non_zero[0] = (CbCr_cbp[1] != 0);
non_zero[1] = (CbCr_cbp[2] != 0);
}
#ifdef RESET_STATE
//reset_coding_state (currMB, cs_cm);
#endif
return nonzero;
}
/*!
*************************************************************************************
* \brief
* 4x4 Intra mode decision for an macroblock
*************************************************************************************
*/
int Mode_Decision_for_Intra4x4Macroblock (Macroblock *currMB, double lambda, double* cost)
{
int cbp=0, b8;
double cost8x8;
int non_zero[2] = {0, 0};
cmp_cbp[1] = cmp_cbp[2] = 0;
for (*cost=0, b8=0; b8<4; b8++)
{
if (Mode_Decision_for_8x8IntraBlocks (currMB, b8, lambda, &cost8x8, non_zero))
{
cbp |= (1<<b8);
}
*cost += cost8x8;
if (non_zero[0])
{
cmp_cbp[1] |= (1<<b8);
cbp |= cmp_cbp[1];
cmp_cbp[1] = cbp;
cmp_cbp[2] = cbp;
}
if (non_zero[1])
{
cmp_cbp[2] |= (1<<b8);
cbp |= cmp_cbp[2];
cmp_cbp[1] = cbp;
cmp_cbp[2] = cbp;
}
}
return cbp;
}
/*!
*************************************************************************************
* \brief
* R-D Cost for an 8x8 Partition
*************************************************************************************
*/
double RDCost_for_8x8blocks (Macroblock *currMB, // --> Current macroblock to code
int* cnt_nonz, // --> number of nonzero coefficients
int64* cbp_blk, // --> cbp blk
double lambda, // <-- lagrange multiplier
int block, // <-- 8x8 block number
int mode, // <-- partitioning mode
short pdir, // <-- prediction direction
short l0_ref, // <-- L0 reference picture
short l1_ref) // <-- L1 reference picture
{
int i, j, k;
int rate=0;
int64 distortion=0;
int dummy = 0, mrate;
int fw_mode, bw_mode;
int cbp = 0;
int pax = 8*(block & 0x01);
int pay = 8*(block >> 1);
int i0 = pax >> 2;
int j0 = pay >> 2;
int bframe = (img->type==B_SLICE);
int direct = (bframe && mode==0);
int b8value = B8Mode2Value (mode, pdir);
SyntaxElement se;
Slice *currSlice = img->currentSlice;
DataPartition *dataPart;
const int *partMap = assignSE2partition[input->partition_mode];
imgpel *img_enc, *img_org;
EncodingEnvironmentPtr eep_dp;
//=====
//===== GET COEFFICIENTS, RECONSTRUCTIONS, CBP
//=====
currMB->bi_pred_me=0;
if (direct)
{
if (direct_pdir[img->block_y+j0][img->block_x+i0]<0) // mode not allowed
return (1e20);
else
*cnt_nonz = LumaResidualCoding8x8 (currMB, &cbp, cbp_blk, block, direct_pdir[img->block_y+j0][img->block_x+i0], 0, 0,
(short)imax(0,direct_ref_idx[LIST_0][img->block_y+j0][img->block_x+i0]),
direct_ref_idx[LIST_1][img->block_y+j0][img->block_x+i0]);
}
else
{
if (pdir == 2 && active_pps->weighted_bipred_idc == 1)
{
int weight_sum = (active_pps->weighted_bipred_idc == 1)? wbp_weight[0][l0_ref][l1_ref][0] + wbp_weight[1][l0_ref][l1_ref][0] : 0;
if (weight_sum < -128 || weight_sum > 127)
{
return (1e20);
}
}
fw_mode = (pdir==0||pdir==2 ? mode : 0);
bw_mode = (pdir==1||pdir==2 ? mode : 0);
*cnt_nonz = LumaResidualCoding8x8 (currMB, &cbp, cbp_blk, block, pdir, fw_mode, bw_mode, l0_ref, l1_ref);
}
if( img->yuv_format==YUV444 && !IS_INDEPENDENT(input) )
{
*cnt_nonz += ( coeff_cost_cr[1] + coeff_cost_cr[2] );
}
//===== get residue =====
if (input->rdopt==3 && img->type!=B_SLICE)
{
// We need the reconstructed prediction residue for the simulated decoders.
compute_residue_b8block (block, -1);
}
//=====
//===== GET DISTORTION
//=====
if (input->rdopt==3 && img->type!=B_SLICE)
{
for (k=0; k<input->NoOfDecoders ;k++)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -