14年小牛季后赛:JM86主体流程及encode_one_macroblock帧内部分讲解_太阳雨萌的空间_...
来源:百度文库 编辑:偶看新闻 时间:2024/05/07 23:03:54
JM86编码器的一个主体框架:
Main()——>encode_one_frame——>frame_picture——>code_a_picture——>encode_one_slice——>encode_one_macroblock
Encode_one_macroblock()帧内部分讲解:
if (input->rdopt) //hainei_12_19_率失真
{
int mb_available_up;
int mb_available_left;
int mb_available_up_left;
min_rdcost = max_rdcost;
// precompute all new chroma intra prediction modes
//++对色度进行帧内预测,(并求出最优模式hainei)
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++)
{ //hainei_09_12_19_intra模式共9种预测模式
// 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); //hainei_09_12_20_存储相关编码信息
}//hainei_10_01_23 if (RDCost_for_macroblocks (lambda_mode, mode, &min_rdcost))
}// hainei_10_01_23 if (currMB->c_ipred_mode == DC_PRED_8
}//hainei_10_01_23 if (valid[mode])
……
set_stored_macroblock_parameters(); //在这里取出store_macroblock_paramepers()中存储中数据
在RDCost_for_macroblocks求取最优模式,如果其返回的rdcost小于之前的min-rdcost,则进行最优模式的更新。执行store_macroblock_parameters将当前的模式信息存储起来,因为执行下一模式进入RDCost_for_macroblocks后会将当前模式的一些数据覆盖掉,比如img->cofAC等等。因此要将其保存起来。之后会在store_macroblock_parameters恢复。