📄 mode_decision.c
字号:
if (img->yuv_format != YUV400)
// precompute all chroma intra prediction modes
IntraChromaPrediction(NULL, NULL, NULL);
if (enc_mb.valid[0] && bslice) // check DIRECT MODE
{
if(have_direct)
{
switch(input->Transform8x8Mode)
{
case 1: // Mixture of 8x8 & 4x4 transform
cost = ((cost8x8_direct < cost_direct) || !(enc_mb.valid[5] && enc_mb.valid[6] && enc_mb.valid[7]))
? cost8x8_direct : cost_direct;
break;
case 2: // 8x8 Transform only
cost = cost8x8_direct;
break;
default: // 4x4 Transform only
cost = cost_direct;
break;
}
}
else
{ //!have_direct
cost = Get_Direct_CostMB (enc_mb.lambda_mf);
}
if (cost!=INT_MAX)
{
cost -= (int)floor(16*enc_mb.lambda_me+0.4999);
}
if (cost <= min_cost)
{
if(active_sps->direct_8x8_inference_flag && input->Transform8x8Mode)
{
if(input->Transform8x8Mode==2)
currMB->luma_transform_size_8x8_flag=1;
else
{
if(cost8x8_direct < cost_direct)
currMB->luma_transform_size_8x8_flag=1;
else
currMB->luma_transform_size_8x8_flag=0;
}
}
else
currMB->luma_transform_size_8x8_flag=0;
//Rate control
if (input->RCEnable)
rc_store_diff(img->opix_x,img->opix_y,img->mpr);
min_cost = cost;
best_mode = 0;
}
else
{
currMB->luma_transform_size_8x8_flag = tmp_8x8_flag; // restore if not best
currMB->NoMbPartLessThan8x8Flag = tmp_no_mbpart; // restore if not best
}
}
if (enc_mb.valid[I8MB]) // check INTRA8x8
{
currMB->luma_transform_size_8x8_flag = 1; // at this point cost will ALWAYS be less than min_cost
currMB->mb_type = I8MB;
temp_cpb = Mode_Decision_for_new_Intra8x8Macroblock (enc_mb.lambda_md, &cost);
if (cost <= min_cost)
{
// Residue Color Transform
if(img->residue_transform_flag)
{
for(i=0; i<2; i++)
{
for(j=0; j<4; j++)
for(k=0; k<4; k++)
if(cbp_chroma_block[i][j][k]) cr_cbp = 2;
}
cr_cbp = dct_chroma_DC(0, cr_cbp);
cr_cbp = dct_chroma_DC(1, cr_cbp);
temp_cpb += (cr_cbp<<4);
for(j=0; j<MB_BLOCK_SIZE; j++)
{
pix_y = img->pix_y + j;
for(i=0; i<MB_BLOCK_SIZE; i++)
{
pix_x = img->pix_x + i;
temp_imgU[j][i] = enc_picture->imgUV[0][pix_y][pix_x];
temp_imgV[j][i] = enc_picture->imgUV[1][pix_y][pix_x];
}
}
}
currMB->cbp = temp_cpb;
//coeffs
if (input->Transform8x8Mode != 2)
{
i4p=cofAC; cofAC=img->cofAC; img->cofAC=i4p;
}
for(j=0; j<MB_BLOCK_SIZE; j++)
{
pix_y = img->pix_y + j;
for(i=0; i<MB_BLOCK_SIZE; i++)
{
pix_x = img->pix_x + i;
temp_imgY[j][i] = enc_picture->imgY[pix_y][pix_x];
}
}
//Rate control
if (input->RCEnable)
rc_store_diff(img->opix_x,img->opix_y,img->mpr);
min_cost = cost;
best_mode = I8MB;
tmp_8x8_flag = currMB->luma_transform_size_8x8_flag;
}
else
currMB->luma_transform_size_8x8_flag = tmp_8x8_flag; // restore if not best
}
if (enc_mb.valid[I4MB]) // check INTRA4x4
{
currMB->luma_transform_size_8x8_flag = 0;
currMB->mb_type = I4MB;
temp_cpb = Mode_Decision_for_Intra4x4Macroblock (enc_mb.lambda_md, &cost);
if (cost <= min_cost)
{
// Residue Color Transform
if(img->residue_transform_flag)
{
for(i=0; i<2; i++)
{
for(j=0; j<4; j++)
for(k=0; k<4; k++)
if(cbp_chroma_block[i][j][k])
cr_cbp = 2;
}
cr_cbp = dct_chroma_DC(0, cr_cbp);
cr_cbp = dct_chroma_DC(1, cr_cbp);
temp_cpb += (cr_cbp<<4);
}
currMB->cbp = temp_cpb;
//Rate control
if (input->RCEnable)
rc_store_diff(img->opix_x,img->opix_y,img->mpr);
min_cost = cost;
best_mode = I4MB;
tmp_8x8_flag = currMB->luma_transform_size_8x8_flag;
}
else
{
currMB->luma_transform_size_8x8_flag = tmp_8x8_flag; // restore if not best
//coeffs
i4p=cofAC; cofAC=img->cofAC; img->cofAC=i4p;
}
}
if (enc_mb.valid[I16MB]) // check INTRA16x16
{
currMB->luma_transform_size_8x8_flag = 0;
intrapred_luma_16x16 ();
cost = find_sad_16x16 (&i16mode);
if (cost < min_cost)
{
//Rate control
// should this access opix or pix?
if (input->RCEnable)
rc_store_diff(img->opix_x,img->opix_y,img->mprr_2[i16mode]);
// Residue Color Transform
if(img->residue_transform_flag)
{
for (j = 0; j < MB_BLOCK_SIZE; j++)
{
pix_y = img->pix_y + j;
for (i = 0; i < MB_BLOCK_SIZE; i++)
{
pix_x = img->pix_x + i;
residue_G = imgY_org [pix_y][pix_x] - img->mprr_2 [i16mode] [j][i];
residue_B = imgUV_org[0][pix_y][pix_x] - img->mprr_c[0][currMB->c_ipred_mode][j][i];
residue_R = imgUV_org[1][pix_y][pix_x] - img->mprr_c[1][currMB->c_ipred_mode][j][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);
img->m7[j][i] = resTrans_G[j][i];
}
}
}
best_mode = I16MB;
currMB->cbp = dct_luma_16x16 (i16mode);
// Residue Color Transform
if(img->residue_transform_flag)
{
for (j = 0; j < MB_BLOCK_SIZE; j++)
{
for (i=0; i < MB_BLOCK_SIZE; i++)
{
rec_resG[j][i] = img->m7[j][i];
img->m7[j][i] = resTrans_B[j][i];
}
}
cr_cbp = dct_chroma(0, 0);
for (j=0; j < MB_BLOCK_SIZE; j++)
{
for (i=0; i < MB_BLOCK_SIZE; i++)
{
rec_resB[j][i] = img->m7[j][i];
img->m7[j][i] = resTrans_R[j][i];
}
}
cr_cbp = dct_chroma(1, cr_cbp);
for (j=0; j < MB_BLOCK_SIZE; j++)
{
for (i=0; i < MB_BLOCK_SIZE; i++)
rec_resR[j][i] = img->m7[j][i];
}
currMB->cbp += (cr_cbp<<4);
/* Inverse Residue Transform */
for (j=0; j < MB_BLOCK_SIZE; j++)
{
pix_y = img->pix_y + j;
for (i=0; i < MB_BLOCK_SIZE; i++)
{
pix_x = img->pix_x + i;
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->imgY [pix_y][pix_x] =
min(img->max_imgpel_value ,max(0, residue_G + (int) img->mprr_2[i16mode][j][i]));
enc_picture->imgUV[0][pix_y][pix_x] =
min(img->max_imgpel_value_uv,max(0, residue_B + (int) img->mprr_c[0][currMB->c_ipred_mode][j][i]));
enc_picture->imgUV[1][pix_y][pix_x] =
min(img->max_imgpel_value_uv,max(0, residue_R + (int) img->mprr_c[1][currMB->c_ipred_mode][j][i]));
}
}
}
}
else
{
currMB->luma_transform_size_8x8_flag = tmp_8x8_flag; // restore
currMB->NoMbPartLessThan8x8Flag = tmp_no_mbpart; // restore
}
}
}
if (rerun==0)
intra1 = IS_INTRA(currMB);
} // for (rerun=0; rerun<runs; rerun++)
//===== S E T F I N A L M A C R O B L O C K P A R A M E T E R S ======
//---------------------------------------------------------------------------
if (input->rdopt)
{
if ((cbp!=0 || best_mode==I16MB ))
currMB->prev_cbp = 1;
else if (cbp==0 && !input->RCEnable)
{
currMB->delta_qp = 0;
currMB->qp = currMB->prev_qp;
img->qp = currMB->qp;
currMB->prev_cbp = 0;
}
set_stored_macroblock_parameters ();
}
else
{
//===== set parameters for chosen mode =====
SetModesAndRefframeForBlocks (best_mode);
if (best_mode==P8x8)
{
if (currMB->luma_transform_size_8x8_flag && (cbp8_8x8ts == 0) && input->Transform8x8Mode != 2)
currMB->luma_transform_size_8x8_flag = 0;
SetCoeffAndReconstruction8x8 (currMB);
memset(currMB->intra_pred_modes, DC_PRED, MB_BLOCK_PARTITIONS * sizeof(char));
for (k=0, j = img->block_y; j < img->block_y + BLOCK_MULTIPLE; j++)
memset(&ipredmodes[j][img->block_x], DC_PRED, BLOCK_MULTIPLE * sizeof(char));
}
else
{
//===== set parameters for chosen mode =====
if (best_mode == I8MB)
{
memcpy(currMB->intra_pred_modes,currMB->intra_pred_modes8x8, MB_BLOCK_PARTITIONS * sizeof(char));
for(j = img->block_y; j < img->block_y + BLOCK_MULTIPLE; j++)
memcpy(&img->ipredmode[j][img->block_x],&img->ipredmode8x8[j][img->block_x], BLOCK_MULTIPLE * sizeof(char));
//--- restore reconstruction for 8x8 transform ---
for(j=0; j<MB_BLOCK_SIZE; j++)
{
memcpy(&enc_picture->imgY[img->pix_y + j][img->pix_x],temp_imgY[j], MB_BLOCK_SIZE * sizeof(imgpel));
}
// Residue Color Transform
if(img->residue_transform_flag)
{
for(j=0; j<MB_BLOCK_SIZE; j++)
{
pix_y = img->pix_c_y + j;
for(i=0; i<MB_BLOCK_SIZE; i++)
{
pix_x = img->pix_c_x + i;
enc_picture->imgUV[0][pix_y][pix_x] = temp_imgU[j][i] ;
enc_picture->imgUV[1][pix_y][pix_x] = temp_imgV[j][i] ;
}
}
}
}
if ((best_mode!=I4MB)&&(best_mode != I8MB))
{
memset(currMB->intra_pred_modes,DC_PRED, MB_BLOCK_PARTITIONS * sizeof(char));
for(j = img->block_y; j < img->block_y + BLOCK_MULTIPLE; j++)
memset(&ipredmodes[j][img->block_x],DC_PRED, BLOCK_MULTIPLE * sizeof(char));
if (best_mode!=I16MB)
{
if((best_mode>=1) && (best_mode<=3))
currMB->luma_transform_size_8x8_flag = best_transform_flag;
LumaResidualCoding ();
if((currMB->cbp==0)&&(best_mode==0))
currMB->luma_transform_size_8x8_flag = 0;
//Rate control
if (input->RCEnable)
rc_store_diff(img->opix_x,img->opix_y,img->mpr);
}
}
}
//check luma cbp for transform size flag
if (((currMB->cbp&15) == 0) && !(IS_OLDINTRA(currMB) || currMB->mb_type == I8MB))
currMB->luma_transform_size_8x8_flag = 0;
if (img->yuv_format != YUV400)
// precompute all chroma intra prediction modes
IntraChromaPre
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -