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恢复。
|
联系客服