📄 rdopt.c
字号:
{
// cod counter and macroblock mode are written ==> do not consider code counter
tmp_cc = img->cod_counter;
rate = writeMBLayer (currMB, 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 (currMB, 1, &coeff_rate);
}
//===== R E S T O R E C O D I N G S T A T E =====
//-------------------------------------------------------
reset_coding_state (currMB, cs_cm);
rdcost = (double)distortion + lambda * dmax(0.5,(double)rate);
if (rdcost >= *min_rdcost ||
((currMB->qp_scaled[0]) == 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(params->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) == 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 macroblock parameters
*************************************************************************************
*/
void store_macroblock_parameters (Macroblock *currMB, int mode)
{
int j, ****i4p, ***i3p;
int bframe = (img->type==B_SLICE);
//--- store best mode ---
best_mode = mode;
best_c_imode = currMB->c_ipred_mode;
best_i16offset = img->i16offset;
memcpy(b8mode, currMB->b8mode, BLOCK_MULTIPLE * sizeof(short));
memcpy(b8bipred_me, currMB->bipred_me, BLOCK_MULTIPLE * sizeof(short));
memcpy(b8pdir, currMB->b8pdir, BLOCK_MULTIPLE * sizeof(short));
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 (currMB, mode);
if (img->yuv_format != YUV400)
{
int k;
for (k = 0; k < 2; k++)
{
for (j = 0; j<img->mb_cr_size_y; j++)
{
memcpy(rec_mb_cr[k][j], &enc_picture->imgUV[k][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 (k = 0; k < 2; k++)
{
for (j = 0; j<img->mb_cr_size_y; j++)
{
memcpy(lrec_rec_uv[k][j],&lrec_uv[k][img->pix_c_y+j][img->pix_c_x], img->mb_cr_size_x * sizeof(int));
}
}
}
}
//--- store results of decoders ---
if (params->rdopt == 3 && img->type!=B_SLICE)
{
errdo_store_best_block(img, decs->dec_mbY, enc_picture->p_dec_img[0], 0, 0, MB_BLOCK_SIZE);
}
//--- 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;
curr_cbp[0] = cmp_cbp[1];
curr_cbp[1] = cmp_cbp[2];
cur_cbp_blk[0] = currMB->cbp_blk;
}
else
{
cur_cbp_blk[0] = cbp = 0;
cmp_cbp[1] = cmp_cbp[2] = 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->motion.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->motion.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)
{
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, total_bipred_me;
//===== reconstruction values =====
// Luma
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->MbaffFrameFlag || (params->UseRDOQuant && params->RDOQ_QP_Num > 1))
{
for (j = 0; j < MB_BLOCK_SIZE; j++)
memcpy(rdopt->rec_mbY[j],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->AdaptiveRounding)
{
update_offset_params(currMB, mode,luma_transform_size_8x8_flag);
}
if (img->yuv_format != YUV400)
{
int k;
for (k = 0; k < 2; k++)
{
for (j = 0; j<img->mb_cr_size_y; j++)
{
memcpy(&imgUV[k][img->pix_c_y+j][img->pix_c_x], rec_mb_cr[k][j], img->mb_cr_size_x * sizeof(imgpel));
}
}
if (img->MbaffFrameFlag || (params->UseRDOQuant && params->RDOQ_QP_Num > 1))
{
for (k = 0; k < 2; k++)
{
for (j = 0; j<img->mb_cr_size_y; j++)
{
memcpy(rdopt->rec_mb_cr[k][j],rec_mb_cr[k][j], img->mb_cr_size_x * sizeof(imgpel));
}
}
}
if((img->type==SP_SLICE) &&(!si_frame_indicator && !sp2_frame_indicator))
{
for (k = 0; k < 2; k++)
{
for (j = 0; j<img->mb_cr_size_y; j++)
{
memcpy(&lrec_uv[k][img->pix_c_y+j][img->pix_c_x],lrec_rec_uv[k][j], img->mb_cr_size_x * sizeof(int));
}
}
}
}
//===== 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 = cur_cbp_blk[0];
cmp_cbp[1] = curr_cbp[0];
cmp_cbp[2] = curr_cbp[1];
currMB->cbp |= cmp_cbp[1];
currMB->cbp |= cmp_cbp[2];
cmp_cbp[1] = currMB->cbp;
cmp_cbp[2] = currMB->cbp;
//==== macroblock type ====
currMB->mb_type = mode;
memcpy(currMB->b8mode, b8mode, BLOCK_MULTIPLE * sizeof(short));
memcpy(currMB->b8pdir, b8pdir, BLOCK_MULTIPLE * sizeof(short));
memcpy(currMB->bipred_me, b8bipred_me, BLOCK_MULTIPLE * sizeof(short));
if (img->MbaffFrameFlag || (params->UseRDOQuant && params->RDOQ_QP_Num > 1))
{
rdopt->mode = mode;
rdopt->i16offset = img->i16offset;
rdopt->cbp = cbp;
rdopt->cbp_blk = cur_cbp_blk[0];
rdopt->mb_type = mode;
rdopt->prev_qp = currMB->prev_qp;
rdopt->prev_dqp = currMB->prev_dqp;
rdopt->delta_qp = currMB->delta_qp;
rdopt->qp = currMB->qp;
rdopt->prev_cbp = currMB->prev_cbp;
memcpy(rdopt->cofAC[0][0][0], img->cofAC[0][0][0], (4+img->num_blk8x8_uv) * 4 * 2 * 65 * sizeof(int));
memcpy(rdopt->cofDC[0][0], img->cofDC[0][0], 3 * 2 * 18 * sizeof(int));
memcpy(rdopt->b8mode,b8mode, BLOCK_MULTIPLE * sizeof(short));
memcpy(rdopt->b8pdir,b8pdir, BLOCK_MULTIPLE * sizeof(short));
}
//if P8x8 mode and transform size 4x4 choosen, restore motion vector data for this transform size
if (mode == P8x8 && !luma_transform_size_8x8_flag && params->Transform8x8Mode)
RestoreMV8x8(1);
//==== transform size flag ====
if (img->P444_joined)
{
if (((currMB->cbp == 0) && cmp_cbp[1] == 0 && cmp_cbp[2] == 0) && !(IS_OLDINTRA(currMB) || currMB->mb_type == I8MB))
currMB->luma_transform_size_8x8_flag = 0;
else
currMB->luma_transform_size_8x8_flag = luma_transform_size_8x8_flag;
}
else
{
if (((currMB->cbp & 15) == 0) && !(IS_OLDINTRA(currMB) || currMB->mb_type == I8MB))
currMB->luma_transform_size_8x8_flag = 0;
else
currMB->luma_transform_size_8x8_flag = luma_transform_size_8x8_flag;
}
rdopt->luma_transform_size_8x8_flag = currMB->luma_transform_size_8x8_flag;
if (params->rdopt == 3 && img->type!=B_SLICE)
{
errdo_get_best_block(img, enc_picture->p_dec_img[0], decs->dec_mbY, 0, MB_BLOCK_SIZE);
}
//==== reference frames =====
for (j = 0; j < 4; j++)
{
block_y = img->block_y + j;
for (i = 0; i < 4; i++)
{
block_x = img->block_x + i;
k = 2*(j >> 1)+(i >> 1);
// backward prediction or intra
if ((currMB->b8pdir[k] == 1) || IS_INTRA(currMB))
{
enc_picture->motion.ref_idx [LIST_0][block_y][block_x] = -1;
enc_picture->motion.ref_pic_id [LIST_0][block_y][block_x] = -1;
enc_picture->motion.mv [LIST_0][block_y][block_x][0] = 0;
enc_picture->motion.mv [LIST_0][block_y][block_x][1] = 0;
if (img->MbaffFrameFlag || (params->UseRDOQuant && params->RDOQ_QP_Num > 1))
rdopt->refar[LIST_0][j][i] = -1;
}
else
{
if (currMB->bipred_me[k] && (currMB->b8pdir[k] == 2) && is_bipred_enabled(currMB->mb_type))
{
cur_mv = img->bipred_mv[currMB->bipred_me[k] - 1][LIST_0][0][currMB->b8mode[k]][j][i];
enc_picture->motion.ref_idx [LIST_0][block_y][block_x] = 0;
enc_picture->motion.ref_pic_id [LIST_0][block_y][block_x] = enc_picture->ref_pic_num[LIST_0 + currMB->list_offset][0];
enc_picture->motion.mv [LIST_0][block_y][block_x][0] = cur_mv[0];
enc_picture->motion.mv [LIST_0][block_y][block_x][1] = cur_mv[1];
if (img->MbaffFrameFlag || (params->UseRDOQuant && params->RDOQ_QP_Num > 1))
rdopt->refar[LIST_0][j][i] = 0;
}
else
{
char cur_ref = l0_refframe[j][i];
enc_picture->motion.ref_idx [LIST_0][block_y][block_x] = cur_ref;
enc_picture->motion.ref_pic_id [LIST_0][block_y][block_x] = enc_picture->ref_pic_num[LIST_0 + currMB->list_offset][(short)cur_ref];
memcpy(enc_picture->motion.mv [LIST_0][block_y][block_x], img->all_mv[LIST_0][(short)cur_ref][currMB->b8mode[k]][j][i], 2 * sizeof(short));
if (img->MbaffFrameFlag || (params->UseRDOQuant && params->RDOQ_QP_Num > 1))
rdopt->refar[LIST_0][j][i] = cur_ref;
}
}
// forward prediction or intra
if ((currMB->b8pdir[k] == 0) || IS_INTRA(currMB))
{
enc_picture->motion.ref_idx [LIST_1][block_y][block_x] = -1;
enc_picture->motion.ref_pic_id [LIST_1][block_y][block_x] = -1;
enc_picture->motion.mv [LIST_1][block_y][block_x][0] = 0;
enc_picture->motion.mv [LIST_1][block_y][block_x][1] = 0;
if (img->MbaffFrameFlag || (params->UseRDOQuant && params->RDOQ_QP_Num > 1))
rdopt->refar[LIST_1][j][i] = -1;
}
}
}
if (bframe)
{
for (j=0; j<4; j++)
{
block_y = img->block_y + j;
for (i=0; i<4; i++)
{
block_x = img->block_x + i;
k = 2*(j >> 1)+(i >> 1);
// forward
if (IS_INTRA(currMB)||(currMB->b8pdir[k] == 0))
{
enc_picture-
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -