14年小牛季后赛:JM86主体流程及encode_one_macroblock帧内部分讲解_太阳雨萌的空间_...

来源:百度文库 编辑:偶看新闻 时间:2024/05/07 23:03:54
【转】 JM86主体流程及encode_one_macroblock帧内部分讲解2011-03-04 09:18转载自 hainei_最终编辑 hainei_

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恢复。