帧内预测模式提取

if (input->rdopt)
{
int mb_available_up;
int mb_available_left;
int mb_available_up_left;

min_rdcost = max_rdcost;

// precompute all new chroma intra prediction modes
//++ 对色度进行帧内预测
IntraChromaPrediction8x8(&mb_available_up, &mb_available_left, &mb_available_up_left);

//++ 分别在四种色度模式下进行 RDO 计算,如果是 inter 模式,因为色度预测模式与 SSD 计算
//++ 无关,因此只需要计算一次(利用 currMB->c_ipred_mode == DC_PRED_8 条件限制来实现)
for (currMB->c_ipred_mode=DC_PRED_8; currMB->c_ipred_mode<=PLANE_8; currMB->c_ipred_mode++)
{

// bypass if c_ipred_mode is not allowed
if ((currMB->c_ipred_mode==VERT_PRED_8 && !mb_available_up) ||
(currMB->c_ipred_mode==HOR_PRED_8 && !mb_available_left) ||
(currMB->c_ipred_mode==PLANE_8 && (!mb_available_left || !mb_available_up || !mb_available_up_left)))
continue;


//===== GET BEST MACROBLOCK MODE =====
for (ctr16x16=0, index=0; index<7; index++)
{
mode = mb_mode_table[index];

//--- for INTER16x16 check all prediction directions ---
if (mode==1 && img->type==B_SLICE)
{
best8x8pdir[1][0] = best8x8pdir[1][1] = best8x8pdir[1][2] = best8x8pdir[1][3] = ctr16x16;
if (ctr16x16 < 2) index--;
ctr16x16++;
}

img->NoResidueDirect = 0;

if (valid[mode])
{
// bypass if c_ipred_mode not used
//++ 设置当前宏块类型以及其中每个8*8块的分割方式和预测方向,每个4*4块的参考帧索引
//++ 该函数在下面的 RDCost_for_macroblocks 函数内再次调用,进行了重复操作
SetModesAndRefframeForBlocks (mode);
if (currMB->c_ipred_mode == DC_PRED_8 || //++ 利用这个条件限制来实现 inter 模式时只计算一次 RDO
(IS_INTRA(currMB) ))
{
if (RDCost_for_macroblocks (lambda_mode, mode, &min_rdcost)) //++ 帧内模式时亮度存在重复计算情况:因为色度预测模式与亮度预测模式无关,所以在该色度模
{ //++ 式循环中每次计算得到的 intra16*16 和 intra4*4 宏块类型的最佳亮度模式都是完全相同的
//Rate control
if(mode == P8x8)
{
for (i=0; i<16; i++)
for(j=0; j<16; j++)
diffy[j][i] = imgY_org[img->opix_y+j][img->opix_x+i] - mpr8x8[j][i];
}else
{
for (i=0; i<16; i++)
for(j=0; j<16; j++)
diffy[j][i] = imgY_org[img->opix_y+j][img->opix_x+i] - pred[j][i];
}

store_macroblock_parameters (mode);
}
}
}
if (valid[0] && bframe && mode == 0 && currMB->cbp && (currMB->cbp&15) != 15) //g050
{
img->NoResidueDirect = 1;
if (RDCost_for_macroblocks (lambda_mode, mode, &min_rdcost))
{
//Rate control
for (i=0; i<16; i++)
for(j=0; j<16; j++)
diffy[j][i] = imgY_org[img->opix_y+j][img->opix_x+i] - pred[j][i];
store_macroblock_parameters (mode);
}
}
}
}
}
else
{
if (valid[0] && bframe) // check DIRECT MODE
{
cost = (have_direct?cost_direct:Get_Direct_CostMB (lambda_mode));
cost -= (int)floor(16*lambda_motion+0.4999);
if (cost <= min_cost)
{
//Rate control
for (i=0; i<16; i++)
for(j=0; j<16; j++)
diffy[j][i] = imgY_org[img->pix_y+j][img->pix_x+i]-img->mpr[i][j];

min_cost = cost;
best_mode = 0;
}
}
if (valid[I4MB]) // check INTRA4x4
{
currMB->cbp = Mode_Decision_for_Intra4x4Macroblock (lambda_mode, &cost); //++ 计算当前宏块采用intra4*4编码时的代价和CBP
if (cost <= min_cost)
{
//Rate control
for (i=0; i<16; i++)
for(j=0; j<16; j++)
diffy[j][i] = imgY_org[img->pix_y+j][img->pix_x+i]-img->mpr[i][j]; //++ 保存采用intra4*4编码时最佳模式的残差块

min_cost = cost;
best_mode = I4MB;
}
}
if (valid[I16MB]) // check INTRA16x16
{
intrapred_luma_16x16 (); //++ 分别计算当前宏块在4种intra16*16帧内预测模式下的预测块
cost = find_sad_16x16 (&i16mode); //++ 计算intra16*16类型的代价(以SATD作为判断标准,因为该段代码是不采用RDO的处理过程)
if (cost < min_cost) //++ 如果采用intra16*16类型编码的代价小于采用intra4*4类型编码的代价,则对当前宏块采用intra16*16类型编码
{
//Rate control
for (i=0; i<16; i++)
for(j=0; j<16; j++)
diffy[j][i] = imgY_org[img->pix_y+j][img->pix_x+i]-img->mprr_2[i16mode][j][i];

best_mode = I16MB;
currMB->cbp = dct_luma_16x16 (i16mode); //++ 对当前宏块采用intra16*16类型进行编码,并计算CBP
}
}
}

if (rerun==0)
{
intra1 = (currMB->mb_type==I16MB || currMB->mb_type==I4MB ? 1 : 0);
}
} // for (rerun=0; rerun<runs; rerun++)

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); //++ 设置当前宏块的参数,包括:宏块类型(mb_type)、4个8*8块的分割模式和预测方向(b8mode,b8pdir)、16个4*4块的参考帧索引(ref_idx,ref_pic_id)
if (best_mode==P8x8)
{
SetCoeffAndReconstruction8x8 (currMB);
}
else
{
if (best_mode!=I4MB)
{
for (k=0, j=img->block_y; j<img->block_y+4; j++)
for ( i=img->block_x; i<img->block_x+4; i++, k++)
{
ipredmodes [i][j] = DC_PRED;
currMB->intra_pred_modes[k] = DC_PRED;
}
if (best_mode!=I16MB)
{
LumaResidualCoding ();
//Rate control
for (i=0; i<16; i++)
for(j=0; j<16; j++)
diffy[j][i] = imgY_org[img->pix_y+j][img->pix_x+i]-img->mpr[i][j];
}
}
}
// precompute all chroma intra prediction modes
IntraChromaPrediction8x8(NULL, NULL, NULL); //++ 对色度块进行处理,包括:分别计算4种色度帧内预测模式下的预测块、代价(该分支未采用RDO,因此以SATD作为判断标准)、最佳预测模式
img->i16offset = 0;
dummy = 0;
ChromaResidualCoding (&dummy);
if (best_mode==I16MB)
{
img->i16offset = I16Offset (currMB->cbp, i16mode);
}
SetMotionVectorsMB (currMB, bframe);

//===== check for SKIP mode =====
if ((img->type==P_SLICE || img->type==SP_SLICE) && best_mode==1 && currMB->cbp==0 &&
enc_picture->ref_idx[LIST_0][img->block_x][img->block_y]==0 &&
enc_picture->mv[LIST_0][img->block_x][img->block_y][0]==allmvs[0][0][0][0][0][0] &&
enc_picture->mv[LIST_0][img->block_x][img->block_y][1]==allmvs[0][0][0][0][0][1] )
{
currMB->mb_type=currMB->b8mode[0]=currMB->b8mode[1]=currMB->b8mode[2]=currMB->b8mode[3]=0;
}

if(img->MbaffFrameFlag)
set_mbaff_parameters();
}

// Rate control
if(input->RCEnable)
{
if(img->type==P_SLICE)
{
img->MADofMB[img->current_mb_nr] = calc_MAD();

if(input->basicunit<img->Frame_Total_Number_MB)
{
img->TotalMADBasicUnit +=img->MADofMB[img->current_mb_nr];

/* delta_qp is present only for non-skipped macroblocks*/
if ((cbp!=0 || best_mode==I16MB))
currMB->prev_cbp = 1;
else
{
img->qp -= currMB->delta_qp;
currMB->delta_qp = 0;
currMB->qp = img->qp;
currMB->prev_cbp = 0;
}
/* When MBAFF is used, delta_qp is only present for the first non-skipped macroblock of each
macroblock pair*/
if (input->MbInterlace)
{
if(!currMB->mb_field)
{
DELTA_QP = currMB->delta_qp;
QP = currMB->qp;
}
else
{
DELTA_QP2 = currMB->delta_qp;
QP2 = currMB->qp;
}
}
}
}
}


if(input->rdopt)
rdopt->min_rdcost = min_rdcost;
else
rdopt->min_rdcost = min_cost;

if(img->MbaffFrameFlag)
{
if (img->current_mb_nr%2) //bottom
{
if ((currMB->mb_type ? 0:((img->type == B_SLICE) ? !currMB->cbp:1)) // bottom is skip
&&(prevMB->mb_type ? 0:((img->type == B_SLICE) ? !prevMB->cbp:1))) // top is skip
{
if (!(field_flag_inference() == curr_mb_field))
{
rdopt->min_rdcost = 1e30; // don't allow coding of an MB pair as skip if wrong inference
}
}
}
}

//===== Decide if this MB will restrict the reference frames =====
if (input->RestrictRef==1)
{
if (input->rdopt==1)
{
refresh_map[2*img->mb_y ][2*img->mb_x ] = (intra ? 1 : 0);
refresh_map[2*img->mb_y ][2*img->mb_x+1] = (intra ? 1 : 0);
refresh_map[2*img->mb_y+1][2*img->mb_x ] = (intra ? 1 : 0);
refresh_map[2*img->mb_y+1][2*img->mb_x+1] = (intra ? 1 : 0);
}
else if (input->rdopt==2)
{
refresh_map[2*img->mb_y ][2*img->mb_x ] = (intra1==0 && (currMB->mb_type==I16MB || currMB->mb_type==I4MB) ? 1 : 0);
refresh_map[2*img->mb_y ][2*img->mb_x+1] = (intra1==0 && (currMB->mb_type==I16MB || currMB->mb_type==I4MB) ? 1 : 0);
refresh_map[2*img->mb_y+1][2*img->mb_x ] = (intra1==0 && (currMB->mb_type==I16MB || currMB->mb_type==I4MB) ? 1 : 0);
refresh_map[2*img->mb_y+1][2*img->mb_x+1] = (intra1==0 && (currMB->mb_type==I16MB || currMB->mb_type==I4MB) ? 1 : 0);
}
}
else if (input->RestrictRef==2)
{
refresh_map[2*img->mb_y ][2*img->mb_x ] = (currMB->mb_type==I16MB || currMB->mb_type==I4MB ? 1 : 0);
refresh_map[2*img->mb_y ][2*img->mb_x+1] = (currMB->mb_type==I16MB || currMB->mb_type==I4MB ? 1 : 0);
refresh_map[2*img->mb_y+1][2*img->mb_x ] = (currMB->mb_type==I16MB || currMB->mb_type==I4MB ? 1 : 0);
refresh_map[2*img->mb_y+1][2*img->mb_x+1] = (currMB->mb_type==I16MB || currMB->mb_type==I4MB ? 1 : 0);
}

if(input->FMEnable)
skip_intrabk_SAD(best_mode, listXsize[LIST_0+list_offset]);
}

你可能感兴趣的:(模式)