📄 rdopt.c
字号:
residue_B = temp - (rec_resR[j][i]>>1);
residue_R = residue_B+rec_resR[j][i];
enc_picture->imgUV[0][pic_pix_y+j][pic_pix_x+i] = min(img->max_imgpel_value_uv,max(0,residue_B+(int)img->mprr_c[0][c_ipmode][block_y+j][block_x+i]));
enc_picture->imgY[pic_pix_y+j][pic_pix_x+i] = min(img->max_imgpel_value,max(0,residue_G+(int)img->mprr[ipmode][j][i]));
enc_picture->imgUV[1][pic_pix_y+j][pic_pix_x+i] = min(img->max_imgpel_value_uv,max(0,residue_R+(int)img->mprr_c[1][c_ipmode][block_y+j][block_x+i]));
}
}
//===== get distortion (SSD) of 4x4 block =====
distortion = 0;
for (y=0; y<4; y++)
{
for (x=pic_pix_x; x<pic_pix_x+4; x++)
{
distortion += img->quad[imgY_org [pic_pix_y+y][x] - enc_picture->imgY [pic_pix_y+y][x]];
distortion += img->quad[imgUV_org[0][pic_pix_y+y][x] - enc_picture->imgUV[0][pic_pix_y+y][x]];
distortion += img->quad[imgUV_org[1][pic_pix_y+y][x] - enc_picture->imgUV[1][pic_pix_y+y][x]];
}
}
rdcost = (double)distortion + lambda*(double)rate;
if (rdcost < min_rdcost)
{
//--- set coefficients ---
for (j=0; j<2; j++)
{
for (i=0; i<18;i++)
cofAC4x4[j][i]=img->cofAC[b8][b4][j][i];
for (i=0; i<18;i++)
cofAC4x4_chroma[0][j][i]=img->cofAC[b8+4][b4][j][i];
for (i=0; i<18;i++)
cofAC4x4_chroma[1][j][i]=img->cofAC[b8+8][b4][j][i];
}
for (i=0; i<2; i++)
{ //uv
dc_level [i][2*(b8 & 0x01)+(b4 & 0x01)][2*(b8 >> 1)+(b4 >> 1)] = dc_level_temp [i][2*(b8 & 0x01)+(b4 & 0x01)][2*(b8 >> 1)+(b4 >> 1)];
cbp_chroma_block[i][2*(b8 & 0x01)+(b4 & 0x01)][2*(b8 >> 1)+(b4 >> 1)] = cbp_chroma_block_temp[i][2*(b8 & 0x01)+(b4 & 0x01)][2*(b8 >> 1)+(b4 >> 1)];
//--- set reconstruction ---
for (y=0; y<BLOCK_SIZE; y++)
{
memcpy(rec4x4_c[i][y],&enc_picture->imgUV[i][pic_pix_y+y][pic_pix_x], BLOCK_SIZE * sizeof(imgpel));
if(img->type==SP_SLICE &&(!si_frame_indicator && !sp2_frame_indicator))
memcpy(lrec4x4[y],&lrec[pic_pix_y+y][pic_pix_x], BLOCK_SIZE * sizeof(int));//stores the coefficients for the mode
}
}
//--- set reconstruction ---
for (y=0; y<BLOCK_SIZE; y++)
{
memcpy(rec4x4[y],&enc_picture->imgY[pic_pix_y+y][pic_pix_x], BLOCK_SIZE * sizeof(imgpel));
if(img->type==SP_SLICE &&(!si_frame_indicator && !sp2_frame_indicator))
memcpy(lrec4x4[y],&lrec[pic_pix_y+y][pic_pix_x], BLOCK_SIZE * sizeof(int));
}
//--- flag if dct-coefficients must be coded ---
nonzero = c_nz;
//--- set best mode update minimum cost ---
min_rdcost = rdcost;
best_ipmode = ipmode;
#ifdef BEST_NZ_COEFF
best_nz_coeff = img->nz_coeff [img->current_mb_nr][block_x4][block_y4];
// yuwen 2005.11.17 => should be an error here, requiring process for img->mb_data[img->current_mb_nr].cbp_bits
#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] = best_ipmode;
img->mb_data[img->current_mb_nr].intra_pred_modes[4*b8+b4] = mostProbableMode == best_ipmode ? -1 : best_ipmode < mostProbableMode ? best_ipmode : best_ipmode-1;
if (!input->rdopt)
{
// Residue Color Transform
if(!img->residue_transform_flag)
{
// get prediction and prediction error
for (j=0; j<4; j++)
{
int jj = pic_opix_y+j;
for (i=0; i<4; i++)
{
img->mpr[block_y+j][block_x+i] = img->mprr[best_ipmode][j][i];
img->m7[j][i] = imgY_org[jj][pic_opix_x+i] - img->mprr[best_ipmode][j][i];
}
}
nonzero = dct_luma (block_x, block_y, &dummy, 1);
}
else
{
int y_pos = 2*(b8 & 0x01)+(b4 & 0x01);
int x_pos = 2*(b8 >> 1)+(b4 >> 1);
for (j=0; j<4; j++)
{
for (i=0; i<4; i++)
{
residue_B = imgUV_org[0][pic_opix_y+j][pic_opix_x+i] - img->mprr_c[0][c_ipmode][block_y+j][block_x+i];
residue_G = imgY_org[pic_opix_y+j][pic_opix_x+i] - img->mprr[best_ipmode][j][i];
residue_R = imgUV_org[1][pic_opix_y+j][pic_opix_x+i] - img->mprr_c[1][c_ipmode][block_y+j][block_x+i];
/* Forward Residue Transform */
resTrans_R[j][i] = residue_R-residue_B;
temp = residue_B+(resTrans_R[j][i]>>1);
resTrans_B[j][i] = residue_G-temp;
resTrans_G[j][i] = temp+(resTrans_B[j][i]>>1);
}
}
for (j=0; j<4; j++)
{
for (i=0; i<4; i++)
{
img->m7[j][i] = resTrans_G[j][i];
}
}
nonzero = dct_luma (block_x, block_y, &dummy, 1);
for (j=0; j<4; j++)
{
for (i=0; i<4; i++)
{
rec_resG[j][i] = img->m7[j][i];
img->m7[j][i] = resTrans_B[j][i];
}
}
cbp_chroma_block[0][y_pos][x_pos] = dct_chroma4x4 (0, b8+4, b4);
dc_level [0][y_pos][x_pos] = dc_level_temp[0][y_pos][x_pos];
for (j=0; j<4; j++)
{
for (i=0; i<4; i++)
{
rec_resB[j][i] = img->m7[j][i];
img->m7[j][i] = resTrans_R[j][i];
}
}
cbp_chroma_block[1][y_pos][x_pos] = dct_chroma4x4 (1, b8+8, b4);
dc_level [1][y_pos][x_pos] = dc_level_temp[1][y_pos][x_pos];
for (j=0; j<4; j++)
{
for (i=0; i<4; i++)
{
rec_resR[j][i] = img->m7[j][i];
}
}
for (j=0; j<4; j++)
{
for (i=0; i<4; i++)
{
/* Inverse Residue Transform */
temp = rec_resG[j][i]-(rec_resB[j][i]>>1);
residue_G = rec_resB[j][i]+temp;
residue_B = temp - (rec_resR[j][i]>>1);
residue_R = residue_B+rec_resR[j][i];
enc_picture->imgUV[0][pic_pix_y+j][pic_pix_x+i] = min(img->max_imgpel_value_uv,max(0,residue_B+(int)img->mprr_c[0][c_ipmode][block_y+j][block_x+i]));
enc_picture->imgY[pic_pix_y+j][pic_pix_x+i] = min(img->max_imgpel_value,max(0,residue_G+(int)img->mprr[best_ipmode][j][i]));
enc_picture->imgUV[1][pic_pix_y+j][pic_pix_x+i] = min(img->max_imgpel_value_uv,max(0,residue_R+(int)img->mprr_c[1][c_ipmode][block_y+j][block_x+i]));
}
}
}
}
else
{
//===== restore coefficients =====
for (j=0; j<2; j++)
{
memcpy (img->cofAC[b8][b4][j],cofAC4x4[j], 18 * sizeof(int));
}
// Residue Color Transform
if(img->residue_transform_flag)
{
for (j=0; j<2; j++)
{
memcpy (img->cofAC[b8+4][b4][j],cofAC4x4_chroma[0][j], 18 * sizeof(int));
memcpy (img->cofAC[b8+8][b4][j],cofAC4x4_chroma[1][j], 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 (&img->mpr[block_y+y][block_x],img->mprr[best_ipmode][y], BLOCK_SIZE * sizeof(imgpel));
if(img->type==SP_SLICE &&(!si_frame_indicator && !sp2_frame_indicator))
memcpy (&lrec[pic_pix_y+y][pic_pix_x],lrec4x4[y], BLOCK_SIZE * sizeof(int));//restore coefficients when encoding primary SP frame
}
if (img->AdaptiveRounding)
{
for (j=0; j<BLOCK_SIZE; j++)
memcpy (&img->fadjust4x4[1][block_y+j][block_x],&fadjust4x4[block_y+j][block_x], BLOCK_SIZE * sizeof(int));
}
// Residue Color Transform
if(img->residue_transform_flag)
{
for (i=0; i<2; i++)
{ //uv
//--- set reconstruction ---
for (y=0; y<4; y++)
{
memcpy(&enc_picture->imgUV[i][pic_pix_y+y][pic_pix_x],rec4x4_c[i][y], BLOCK_SIZE * sizeof(imgpel));
if(img->type==SP_SLICE &&(!si_frame_indicator && !sp2_frame_indicator))
memcpy (&lrec_uv[i][pic_pix_y+y][pic_pix_x],lrec4x4_c[i][y], BLOCK_SIZE * sizeof(int));//restore coefficients for primary SP frame encoding
}
}
}
}
return nonzero;
}
/*!
*************************************************************************************
* \brief
* Mode Decision for an 8x8 Intra block
*************************************************************************************
*/
int Mode_Decision_for_8x8IntraBlocks(int b8,double lambda,int *cost)
{
int nonzero=0, b4;
int cost4x4;
*cost = (int)floor(6.0 * lambda + 0.4999);
for (b4=0; b4<4; b4++)
{
if (Mode_Decision_for_4x4IntraBlocks (b8, b4, lambda, &cost4x4))
{
nonzero = 1;
}
*cost += cost4x4;
}
#ifdef RESET_STATE
reset_coding_state (cs_cm);
#endif
return nonzero;
}
/*!
*************************************************************************************
* \brief
* 4x4 Intra mode decision for an macroblock
*************************************************************************************
*/
int Mode_Decision_for_Intra4x4Macroblock (double lambda, int* cost)
{
int cbp=0, b8, cost8x8;
for (*cost=0, b8=0; b8<4; b8++)
{
if (Mode_Decision_for_8x8IntraBlocks (b8, lambda, &cost8x8))
{
cbp |= (1<<b8);
}
*cost += cost8x8;
}
return cbp;
}
/*!
*************************************************************************************
* \brief
* R-D Cost for an 8x8 Partition
*************************************************************************************
*/
double RDCost_for_8x8blocks (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 ref, // <-- reference frame
short bwd_ref) // <-- abp type
{
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);
Macroblock *currMB = &img->mb_data[img->current_mb_nr];
SyntaxElement *currSE = &img->MB_SyntaxElements[currMB->currSEnr];
Slice *currSlice = img->currentSlice;
DataPartition *dataPart;
const int *partMap = assignSE2partition[input->partition_mode];
EncodingEnvironmentPtr eep_dp;
// Residue Color Transform
int residue_R, residue_G, residue_B, temp, b4;
int b4_x, b4_y;
//=====
//===== 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 (&cbp, cbp_blk, block, direct_pdir[img->block_y+j0][img->block_x+i0], 0, 0,
(short)max(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
{
fw_mode = (pdir==0||pdir==2 ? mode : 0);
bw_mode = (pdir==1||pdir==2 ? mode : 0);
*cnt_nonz = LumaResidualCoding8x8 (&cbp, cbp_blk, block, pdir, fw_mode, bw_mode, ref, bwd_ref);
}
// Residue Color Transform
if(img->residue_transform_flag)
{
for(b4 = 0; b4 < 4; b4++)
{
b4_x = pax+(b4 & 0x01)*4;
b4_y = pay+(b4 >> 1 )*4;
for (j=0; j<4; j++)
{
for (i=0; i<4; i++)
img->m7[j][i] = resTrans_B[j+b4_y][i+b4_x];
}
rate += RDCost_for_4x4Blocks_Chroma (block+4, b4, 0);
for (j=0; j<4; j++)
{
for (i=0; i<4; i++)
{
rec_resB[j+b4_y][i+b4_x] = img->m7[j][i];
img->m7[j][i] = resTrans_R[j+b4_y][i+b4_x];
}
}
rate += RDCost_for_4x4Blocks_Chroma (block+8, b4, 1);
for (j=0; j<4; j++)
{
for (i=0; i<4; i++)
{
rec_resR[j+b4_y][i+b4_x] = img->m7[j][i];
}
}
}
reset_coding_state (cs_cm);
/* Inverse Residue Transform */
for (j=pay; j<pay+8; j++)
for (i=pax; i<pax+8; i++)
{
/* YCoCg-R */
temp = rec_resG[j][i]-(rec_resB[j][i]>>1);
residue_G = rec_resB[j][i]+temp;
residue_B = temp - (rec_resR[j][i]>>1);
residue_R = residue_B+rec_resR[j][i];
enc_picture->imgUV[0][img->pix_y+j][img->pix_x+i] = min(img->max_imgpel_value_uv,max(0,residue_B+mprRGB[1][j][i]));
enc_picture->imgY[img->pix_y+j][img->pix_x+i] = min(img->max_imgpel_value,max(0,residue_G+mprRGB[0][j][i]));
enc_picture->imgUV[1][img->pix_y+j][img->pix_x+i] = min(img->max_imgpel_value_uv,max(0,residue_R+mprRGB[2][j][i]));
}
}
//===== 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 + -