📄 rdopt.c
字号:
}
}
else
{
// LUMA
for (j = 0; j < MB_BLOCK_SIZE; j++)
{
j1 = j + img->opix_y;
j2 = j + img->pix_y;
for (i = img->opix_x; i < img->opix_x + MB_BLOCK_SIZE; i++)
distortion += iabs2( imgY_org[j1][i] - enc_picture->imgY[j2][i] );
}
if ((img->yuv_format != YUV400) && !IS_INDEPENDENT(input))
{
// CHROMA
for (j = 0; j<img->mb_cr_size_y; j++)
{
j1 = j + img->opix_c_y;
j2 = j + img->pix_c_y;
for (i = img->opix_c_x; i < img->opix_c_x + img->mb_cr_size_x; i++)
{
distortion += iabs2( imgUV_org[0][j1][i] - enc_picture->imgUV[0][j2][i] );
distortion += iabs2( imgUV_org[1][j1][i] - enc_picture->imgUV[1][j2][i] );
}
}
}
}
//===== S T O R E C O D I N G S T A T E =====
//---------------------------------------------------
store_coding_state (cs_cm);
//=====
//===== GET RATE
//=====
//----- macroblock header -----
if (use_of_cc)
{
if (currMB->mb_type!=0 || (bframe && currMB->cbp!=0))
{
// cod counter and macroblock mode are written ==> do not consider code counter
tmp_cc = img->cod_counter;
rate = writeMBLayer (1, &coeff_rate);
ue_linfo (tmp_cc, dummy, &cc_rate, &dummy);
rate -= cc_rate;
img->cod_counter = tmp_cc;
}
else
{
// cod counter is just increased ==> get additional rate
ue_linfo (img->cod_counter+1, dummy, &rate, &dummy);
ue_linfo (img->cod_counter, dummy, &cc_rate, &dummy);
rate -= cc_rate;
}
}
else
{
rate = writeMBLayer (1, &coeff_rate);
}
//===== R E S T O R E C O D I N G S T A T E =====
//-------------------------------------------------------
reset_coding_state (cs_cm);
rdcost = (double)distortion + lambda * dmax(0.5,(double)rate);
if (rdcost >= *min_rdcost ||
((img->qp_scaled) == 0 && img->lossless_qpprime_flag == 1 && distortion != 0))
{
#if FASTMODE
// Reordering RDCost comparison order of mode 0 and mode 1 in P_SLICE
// if RDcost of mode 0 and mode 1 is same, we choose best_mode is 0
// This might not always be good since mode 0 is more biased towards rate than quality.
if((img->type!=P_SLICE || mode != 0 || rdcost != *min_rdcost) || IS_FREXT_PROFILE(input->ProfileIDC))
#endif
return 0;
}
if ((img->MbaffFrameFlag) && (mode ? 0: ((img->type == B_SLICE) ? !currMB->cbp:1))) // AFF and current is skip
{
if (img->current_mb_nr & 0x01) //bottom
{
if (prevMB->mb_type ? 0:((img->type == B_SLICE) ? !prevMB->cbp:1)) //top is skip
{
if (!(field_flag_inference() == currMB->mb_field)) //skip only allowed when correct inference
return 0;
}
}
}
//===== U P D A T E M I N I M U M C O S T =====
//-----------------------------------------------------
*min_rdcost = rdcost;
*min_dcost = (double) distortion;
*min_rate = lambda * (double)coeff_rate;
#ifdef BEST_NZ_COEFF
for (j=0;j<4;j++)
memcpy(&gaaiMBAFF_NZCoeff[j][0], &img->nz_coeff[img->current_mb_nr][j][0], (4+img->num_blk8x8_uv) * sizeof(int));
#endif
return 1;
}
/*!
*************************************************************************************
* \brief
* Store adaptive rounding parameters
*************************************************************************************
*/
void store_adaptive_rounding_parameters (int mode, Macroblock *currMB)
{
int j;
int is_inter = (mode != I4MB)&&(mode != I16MB)&&(mode != I8MB);
if (currMB->luma_transform_size_8x8_flag)
{
if ((mode == P8x8))
memcpy(&(bestInterFAdjust8x8[0][0]),&(img->fadjust8x8[2][0][0]),MB_PIXELS * sizeof(int));
else if (is_inter)
memcpy(&(bestInterFAdjust8x8[0][0]),&(img->fadjust8x8[0][0][0]),MB_PIXELS * sizeof(int));
else
memcpy(&(bestIntraFAdjust8x8[0][0]),&(img->fadjust8x8[1][0][0]),MB_PIXELS * sizeof(int));
}
else
{
if ((mode == P8x8))
memcpy(&(bestInterFAdjust4x4[0][0]),&(img->fadjust4x4[3][0][0]),MB_PIXELS * sizeof(int));
else if (is_inter)
memcpy(&(bestInterFAdjust4x4[0][0]),&(img->fadjust4x4[0][0][0]),MB_PIXELS * sizeof(int));
else
memcpy(&(bestIntraFAdjust4x4[0][0]),&(img->fadjust4x4[1 + mode == I16MB][0][0]),MB_PIXELS * sizeof(int));
}
if ((input->yuv_format != 0)&&(input->AdaptRndChroma))
{
if (currMB->luma_transform_size_8x8_flag && mode == P8x8)
{
for (j = 0; j < img->mb_cr_size_y; j++)
{
memcpy(bestInterFAdjust4x4Cr[0][j],img->fadjust8x8Cr[0][0][j],img->mb_cr_size_x * sizeof(int));
memcpy(bestInterFAdjust4x4Cr[1][j],img->fadjust8x8Cr[0][1][j],img->mb_cr_size_x * sizeof(int));
}
}
else if (mode == P8x8)
{
for (j = 0; j < img->mb_cr_size_y; j++)
{
memcpy(bestInterFAdjust4x4Cr[0][j],img->fadjust4x4Cr[2][0][j],img->mb_cr_size_x * sizeof(int));
memcpy(bestInterFAdjust4x4Cr[1][j],img->fadjust4x4Cr[2][1][j],img->mb_cr_size_x * sizeof(int));
}
}
else if (is_inter)
{
for (j = 0; j < img->mb_cr_size_y; j++)
{
memcpy(bestInterFAdjust4x4Cr[0][j],img->fadjust4x4Cr[0][0][j],img->mb_cr_size_x * sizeof(int));
memcpy(bestInterFAdjust4x4Cr[1][j],img->fadjust4x4Cr[0][1][j],img->mb_cr_size_x * sizeof(int));
}
}
else
{
for (j = 0; j < img->mb_cr_size_y; j++)
{
memcpy(bestIntraFAdjust4x4Cr[0][j],img->fadjust4x4Cr[1][0][j],img->mb_cr_size_x * sizeof(int));
memcpy(bestIntraFAdjust4x4Cr[1][j],img->fadjust4x4Cr[1][1][j],img->mb_cr_size_x * sizeof(int));
}
}
}
}
/*!
*************************************************************************************
* \brief
* Store macroblock parameters
*************************************************************************************
*/
void store_macroblock_parameters (int mode)
{
int i, j, k, ****i4p, ***i3p;
Macroblock *currMB = &img->mb_data[img->current_mb_nr];
int bframe = (img->type==B_SLICE);
//--- store best mode ---
best_mode = mode;
best_c_imode = currMB->c_ipred_mode;
best_i16offset = img->i16offset;
// If condition is not really necessary.
bi_pred_me = (mode == 1) ? currMB->bi_pred_me : 0;
memcpy(b8mode, currMB->b8mode, BLOCK_MULTIPLE * sizeof(int));
memcpy(b8pdir, currMB->b8pdir, BLOCK_MULTIPLE * sizeof(int));
memcpy(b4_intra_pred_modes,currMB->intra_pred_modes, MB_BLOCK_PARTITIONS * sizeof(char));
memcpy(b8_intra_pred_modes8x8,currMB->intra_pred_modes8x8, MB_BLOCK_PARTITIONS * sizeof(char));
for (j = 0 ; j < BLOCK_MULTIPLE; j++)
{
memcpy(&b4_ipredmode[j * BLOCK_MULTIPLE],&img->ipredmode[img->block_y + j][img->block_x],BLOCK_MULTIPLE * sizeof(char));
memcpy(b8_ipredmode8x8[j],&img->ipredmode8x8[img->block_y + j][img->block_x],BLOCK_MULTIPLE * sizeof(char));
}
//--- reconstructed blocks ----
for (j = 0; j < MB_BLOCK_SIZE; j++)
{
memcpy(rec_mbY[j],&enc_picture->imgY[img->pix_y+j][img->pix_x], MB_BLOCK_SIZE * sizeof(imgpel));
}
if((img->type==SP_SLICE) && (si_frame_indicator==0 && sp2_frame_indicator==0))
{
for (j = 0; j < MB_BLOCK_SIZE; j++)
{
memcpy(lrec_rec[j],&lrec[img->pix_y+j][img->pix_x], MB_BLOCK_SIZE * sizeof(int));//store coefficients SP frame
}
}
if (img->AdaptiveRounding)
store_adaptive_rounding_parameters (mode, currMB);
if (img->yuv_format != YUV400)
{
for (j = 0; j<img->mb_cr_size_y; j++)
{
memcpy(rec_mbU[j],&enc_picture->imgUV[0][img->pix_c_y+j][img->pix_c_x], img->mb_cr_size_x * sizeof(imgpel));
memcpy(rec_mbV[j],&enc_picture->imgUV[1][img->pix_c_y+j][img->pix_c_x], img->mb_cr_size_x * sizeof(imgpel));
}
if((img->type==SP_SLICE) && (si_frame_indicator==0 && sp2_frame_indicator==0))
{
//store uv coefficients SP frame
for (j = 0; j<img->mb_cr_size_y; j++)
{
memcpy(lrec_rec_U[j],&lrec_uv[0][img->pix_c_y+j][img->pix_c_x], img->mb_cr_size_x * sizeof(int));
memcpy(lrec_rec_V[j],&lrec_uv[1][img->pix_c_y+j][img->pix_c_x], img->mb_cr_size_x * sizeof(int));
}
}
}
//--- store results of decoders ---
if (input->rdopt==3 && img->type!=B_SLICE)
{
for (k = 0; k<input->NoOfDecoders; k++)
{
for (j=img->pix_y; j<img->pix_y+16; j++)
for (i=img->pix_x; i<img->pix_x+16; i++)
{
// Keep the decoded values of each MB for updating the ref frames
decs->decY_best[k][j][i] = decs->decY[k][j][i];
}
}
}
//--- coeff, cbp, kac ---
if (mode || bframe)
{
i4p=cofAC; cofAC=img->cofAC; img->cofAC=i4p;
i3p=cofDC; cofDC=img->cofDC; img->cofDC=i3p;
cbp = currMB->cbp;
cbp_blk = currMB->cbp_blk;
}
else
{
cbp_blk = cbp = 0;
}
//--- store transform size ---
luma_transform_size_8x8_flag = currMB->luma_transform_size_8x8_flag;
for (j = 0; j<4; j++)
memcpy(l0_refframe[j],&enc_picture->ref_idx[LIST_0][img->block_y+j][img->block_x], BLOCK_MULTIPLE * sizeof(char));
if (bframe)
{
for (j = 0; j<4; j++)
memcpy(l1_refframe[j],&enc_picture->ref_idx[LIST_1][img->block_y+j][img->block_x], BLOCK_MULTIPLE * sizeof(char));
}
}
/*!
*************************************************************************************
* \brief
* Set stored macroblock parameters
*************************************************************************************
*/
void set_stored_macroblock_parameters ()
{
Macroblock *currMB = &img->mb_data[img->current_mb_nr];
imgpel **imgY = enc_picture->imgY;
imgpel ***imgUV = enc_picture->imgUV;
int mode = best_mode;
int bframe = (img->type==B_SLICE);
int i, j, k, ****i4p, ***i3p;
int block_x, block_y;
char **ipredmodes = img->ipredmode;
short *cur_mv;
//===== reconstruction values =====
for (j = 0; j < MB_BLOCK_SIZE; j++)
{
memcpy(&imgY[img->pix_y+j][img->pix_x],rec_mbY[j], MB_BLOCK_SIZE * sizeof(imgpel));
}
if((img->type==SP_SLICE) &&(si_frame_indicator==0 && sp2_frame_indicator==0 ))
{
for (j = 0; j < MB_BLOCK_SIZE; j++)
memcpy(&lrec[img->pix_y+j][img->pix_x],lrec_rec[j], MB_BLOCK_SIZE * sizeof(int)); //restore coeff SP frame
}
if(img->MbaffFrameFlag)
{
for (j = 0; j < MB_BLOCK_SIZE; j++)
memcpy(rdopt->rec_mbY[j],rec_mbY[j], MB_BLOCK_SIZE * sizeof(imgpel));
}
if (img->AdaptiveRounding)
{
update_offset_params(mode,luma_transform_size_8x8_flag);
}
if (img->yuv_format != YUV400)
{
for (j = 0; j<img->mb_cr_size_y; j++)
{
memcpy(&imgUV[0][img->pix_c_y+j][img->pix_c_x],rec_mbU[j], img->mb_cr_size_x * sizeof(imgpel));
memcpy(&imgUV[1][img->pix_c_y+j][img->pix_c_x],rec_mbV[j], img->mb_cr_size_x * sizeof(imgpel));
if((img->type==SP_SLICE) &&(!si_frame_indicator && !sp2_frame_indicator))
{
memcpy(&lrec_uv[0][img->pix_c_y+j][img->pix_c_x],lrec_rec_U[j], img->mb_cr_size_x * sizeof(int));
memcpy(&lrec_uv[1][img->pix_c_y+j][img->pix_c_x],lrec_rec_V[j], img->mb_cr_size_x * sizeof(int));
}
if(img->MbaffFrameFlag)
{
memcpy(rdopt->rec_mbU[j],rec_mbU[j], img->mb_cr_size_x * sizeof(imgpel));
memcpy(rdopt->rec_mbV[j],rec_mbV[j], img->mb_cr_size_x * sizeof(imgpel));
}
}
if((img->type==SP_SLICE) &&(!si_frame_indicator && !sp2_frame_indicator))
{
for (j = 0; j<img->mb_cr_size_y; j++)
{
memcpy(&lrec_uv[0][img->pix_c_y+j][img->pix_c_x],lrec_rec_U[j], img->mb_cr_size_x * sizeof(int));
memcpy(&lrec_uv[1][img->pix_c_y+j][img->pix_c_x],lrec_rec_V[j], img->mb_cr_size_x * sizeof(int));
}
}
if(img->MbaffFrameFlag)
{
for (j = 0; j<img->mb_cr_size_y; j++)
{
memcpy(rdopt->rec_mbU[j],rec_mbU[j], img->mb_cr_size_x * sizeof(imgpel));
memcpy(rdopt->rec_mbV[j],rec_mbV[j], img->mb_cr_size_x * sizeof(imgpel));
}
}
}
//===== coefficients and cbp =====
i4p=cofAC; cofAC=img->cofAC; img->cofAC=i4p;
i3p=cofDC; cofDC=img->cofDC; img->cofDC=i3p;
currMB->cbp = cbp;
currMB->cbp_blk = cbp_blk;
//==== macroblock type ====
currMB->mb_type = mode;
if(img->MbaffFrameFlag)
{
rdopt->mode = mode;
rdopt->i16offset = img->i16offset;
rdopt->cbp = cbp;
rdopt->cbp_blk = cbp_blk;
rdopt->mb_type = mode;
rdopt->prev_qp = currMB->prev_qp;
rdopt->prev_delta_qp = currMB->prev_delta_qp;
rdopt->delta_qp = currMB->delta_qp;
rdopt->qp = currMB->qp;
rdopt->prev_cbp = currMB->prev_cbp;
for(i = 0;i<4+img->num_blk8x8_uv;i++)
{
for(j = 0;j<4;j++)
for(k = 0;k<2;k++)
memcpy(rdopt->cofAC[i][j][k], img->cofAC[i][j][k], 65 * sizeof(int));
}
for(i = 0;i<3;i++)
for(k = 0;k<2;k++)
memcpy(rdopt->cofDC[i][k], img->cofDC[i][k], 18 * sizeof(int));
}
memcpy(currMB->b8mode,b8mode, BLOCK_MULTIPLE * sizeof(int));
memcpy(currMB->b8pdir,b8pdir, BLOCK_MULTIPLE * sizeof(int));
if(img->MbaffFrameFlag)
{
memcpy(rdopt->b8mode,b8mode, BLOCK_MULTIPLE * sizeof(int));
memcpy(rdopt->b8pdir,b8pdir, BLOCK_MULTIPLE * sizeof(int));
}
currMB->bi_pred_me = currMB->mb_type == 1 ? bi_pred_me : 0;
//if P8x8 mode and transform size 4x4 choosen, restore motion vector data for this transform size
if (mode == P8x8 && !luma_transform_size_8x8_flag && input->Transform8x8Mode)
RestoreMV8x8(1);
//====
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -