⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rdopt.c

📁 本源码是H.26L标准的Visual C++源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
  if (!copy)
  {
  /*==================================================*
   *=====   GET RATE OF CHROMA AND UPDATE COST   =====*
   *==================================================*/
    rd->rate_chroma  = writeMB_bits_for_DC_chroma (0);
    rd->rate_chroma += writeMB_bits_for_AC_chroma (0);
    //=== update and check rate-distortion cost ===
    rd->rdcost += rdopt->lambda_mode * (double)rd->rate_chroma;
    if (rd->rdcost >= rdopt->min_rdcost)
    {
      restore_coding_state ();
      return 0;
    }
  }


  //=== restore encoding environment ===
  restore_coding_state ();


  /*=================================================*
   *=====                                       =====*
   *=====   STORE PARAMETERS OF NEW BEST MODE   =====*
   *=====                                       =====*
   *=================================================*/
  rdopt->min_rdcost     = rd->rdcost;
  rdopt->best_mode      = mode;
  rdopt->ref_or_i16mode = ref_or_i16mode;
  rdopt->blocktype      = blocktype;
  rdopt->blocktype_back = blocktype_back;

  //=== LUMINANCE OF RECONSTRUCTED MACROBLOCK ===
  if (copy)
    for   (j=0; j<MB_BLOCK_SIZE; j++)
      for (i=0; i<MB_BLOCK_SIZE; i++)
        rdopt->rec_mb_Y[j][i] = FastPelY_14(mref[refidx], (img->pix_y+j)<<2, (img->pix_x+i)<<2);
  else
    for   (j=0; j<MB_BLOCK_SIZE; j++)
      for (i=0; i<MB_BLOCK_SIZE; i++)
        rdopt->rec_mb_Y[j][i] = imgY[img->pix_y+j][img->pix_x+i];

  //=== CHROMINANCE OF RECONSTRUCTED MACROBLOCK ===
  if (copy)
    for   (j=0; j<(BLOCK_SIZE<<1); j++)
      for (i=0; i<(BLOCK_SIZE<<1); i++)
      {
        rdopt->rec_mb_U[j][i] = mcef[refidx][0][img->pix_c_y+j][img->pix_c_x+i];
        rdopt->rec_mb_V[j][i] = mcef[refidx][1][img->pix_c_y+j][img->pix_c_x+i];
      }
  else
    for   (j=0; j<(BLOCK_SIZE<<1); j++)
      for (i=0; i<(BLOCK_SIZE<<1); i++)
      {
        rdopt->rec_mb_U[j][i] = imgUV[0][img->pix_c_y+j][img->pix_c_x+i];
        rdopt->rec_mb_V[j][i] = imgUV[1][img->pix_c_y+j][img->pix_c_x+i];
      }

  //=== CBP, KAC, DCT-COEFFICIENTS ===
  if (!copy)
  {
    rdopt->cbp         = currMB->cbp;
    rdopt->cbp_blk     = currMB->cbp_blk;
    rdopt->kac         = img->kac;
    memcpy (rdopt->cof,  img->cof,  1728*sizeof(int));
    memcpy (rdopt->cofu, img->cofu,   20*sizeof(int));
  }
  else
      rdopt->cbp_blk     = 0 ;


  //=== INTRA PREDICTION MODES ===
  if (intra4)
  {
    memcpy (rdopt->ipredmode, currMB->intra_pred_modes, 16*sizeof(int));
  }

  //=== MOTION VECTORS ===
  if (inter)
    for   (j=0; j<BLOCK_SIZE; j++)
      for (i=0; i<BLOCK_SIZE; i++)
      {
        rdopt->   mv[j][i][0] = tmp_mv  [0][img->block_y+j][img->block_x+4+i];
        rdopt->   mv[j][i][1] = tmp_mv  [1][img->block_y+j][img->block_x+4+i];
      }
  else if (inter_for)
    for   (j=0; j<BLOCK_SIZE; j++)
      for (i=0; i<BLOCK_SIZE; i++)
      {
        rdopt->   mv[j][i][0] = tmp_fwMV[0][img->block_y+j][img->block_x+4+i];
        rdopt->   mv[j][i][1] = tmp_fwMV[1][img->block_y+j][img->block_x+4+i];
      }
  else if (inter_back)
    for   (j=0; j<BLOCK_SIZE; j++)
      for (i=0; i<BLOCK_SIZE; i++)
      {
        rdopt->bw_mv[j][i][0] = tmp_bwMV[0][img->block_y+j][img->block_x+4+i];
        rdopt->bw_mv[j][i][1] = tmp_bwMV[1][img->block_y+j][img->block_x+4+i];
      }
  else if (inter_bidir)
    for   (j=0; j<BLOCK_SIZE; j++)
      for (i=0; i<BLOCK_SIZE; i++)
      {
        rdopt->   mv[j][i][0] = tmp_fwMV[0][img->block_y+j][img->block_x+4+i];
        rdopt->   mv[j][i][1] = tmp_fwMV[1][img->block_y+j][img->block_x+4+i];
        rdopt->bw_mv[j][i][0] = tmp_bwMV[0][img->block_y+j][img->block_x+4+i];
        rdopt->bw_mv[j][i][1] = tmp_bwMV[1][img->block_y+j][img->block_x+4+i];
      }

  if (input->rdopt==2)
  {
    int k;
    for (k=0; k<input->NoOfDecoders; k++)
    {
      for (j=img->pix_y; j<img->pix_y+MB_BLOCK_SIZE; j++)
        for (i=img->pix_x; i<img->pix_x+MB_BLOCK_SIZE; i++)
        {
          /* Keep the decoded values of each MB for updating the ref frames*/
          decY_best[k][j][i] = decY[k][j][i];
        }
    }
  }

  return 1; // new best mode
}



#define PFRAME    0
#define B_FORWARD 1
#define B_BACKWARD  2

/*!
 ************************************************************************
 * \brief
 *    Rate-Distortion optimized mode decision
 ************************************************************************
 */
void
RD_Mode_Decision ()
{
  int             i, j, k, k0 = 0, dummy;
  int             mode, intra16mode, refframe, blocktype, blocktype_back;
  int             valid_mode [NO_MAX_MBMODES], valid_intra16mode[4];
  int             bframe, intra_macroblock, any_inter_mode = 0;
  int             tot_inter_sad, min_inter_sad;
  int             backward_me_done[9];
  double          forward_rdcost[9], backward_rdcost[9];
  double          min_rdcost;
  int             max_ref_frame, best_refframe[9];
  RateDistortion  rd;
  int             k1 = 1;
  int             mb_nr           = img->current_mb_nr;
  Macroblock     *currMB          = &img->mb_data[mb_nr];


  /*==============================================*
   *===  INIT PARAMETERS OF RD-OPT. STRUCTURE  ===*
   *==============================================*/

  //--- set lagrange parameters ---
  double qp = (double)img->qp;

  rdopt->lambda_mode = 5.0 * exp (0.1 * qp) * (qp + 5.0) / (34.0 - qp);
  
  if (img->type == B_IMG || img->types == SP_IMG)
    rdopt->lambda_mode *= 4;

  rdopt->lambda_motion = sqrt (rdopt->lambda_mode);
  rdopt->lambda_intra  = rdopt->lambda_mode;

  if (input->rdopt == 2)
  {
    rdopt->lambda_mode=(1.0-input->LossRateA/100.0)*rdopt->lambda_mode;
    rdopt->lambda_motion = sqrt (1.0-input->LossRateA/100.0) * rdopt->lambda_motion;
  }
  
  //--- cost values ---
  rdopt->best_mode   = -1;
  rdopt->min_rdcost  =  1e30;
  for (i = 0; i < 9; i++)
  {
    forward_rdcost  [i] = backward_rdcost [i] = -1.0;
    backward_me_done[i] =  0;
    for (j = 0; j < img->buf_cycle; j++)
    {
      forward_me_done[i][j] = 0;
    }
  }


  /*========================*
   *===  SET SOME FLAGS  ===*
   *========================*/
  bframe           = (img->type==B_IMG);
  intra_macroblock = (img->mb_y==img->mb_y_upd && img->mb_y_upd!=img->mb_y_intra) || img->type==INTRA_IMG;
  max_ref_frame    = min (img->number, img->buf_cycle);

  /*========================================*
   *===  MARK POSSIBLE MACROBLOCK MODES  ===*
   *========================================*/
  //--- reset arrays ---
  memset (valid_mode,        0, sizeof(int)*NO_MAX_MBMODES);
  memset (valid_intra16mode, 0, sizeof(int)*4);
  //--- set intra modes ---
  valid_mode [MBMODE_INTRA4x4  ] = 1;
  valid_mode [MBMODE_INTRA16x16] = 1;
  //--- set inter modes ---
  if (!intra_macroblock || bframe)
  {
    for (i=MBMODE_INTER16x16; i <= MBMODE_INTER4x4; i++)
      if (input->blc_size [i][0] > 0)
        any_inter_mode = valid_mode [i] = 1;
      if (bframe)
      {
        memcpy (valid_mode+MBMODE_BACKWARD16x16,
                valid_mode+MBMODE_INTER16x16,   NO_INTER_MBMODES*sizeof(int));
        valid_mode[MBMODE_BIDIRECTIONAL] = valid_mode[MBMODE_DIRECT] = any_inter_mode;
      }
      else
      {
        valid_mode[MBMODE_COPY] = valid_mode[MBMODE_INTER16x16];
      }
  }

  if (img->type==INTER_IMG && img->types== SP_IMG)
    valid_mode[MBMODE_COPY] =0;

  //===== LOOP OVER ALL MACROBLOCK MODES =====
  for (mode = 0; mode < NO_MAX_MBMODES; mode++)
    if (valid_mode[mode])
    {
    /*==================================================================*
     *===  MOTION ESTIMATION, INTRA PREDICTION and COST CALCULATION  ===*
     *==================================================================*/
       if (mode == MBMODE_INTRA4x4)
       {
       /*======================*
        *=== INTRA 4x4 MODE ===*
        *======================*/
         currMB->intraOrInter = INTRA_MB_4x4;
         img->imod            = INTRA_MB_OLD;
         Intra4x4_Mode_Decision ();   // intra 4x4 prediction, dct, etc.
         RDCost_Macroblock (&rd, mode, 0, 0, 0);
       }
       else if (mode == MBMODE_INTRA16x16)
       {
       /*========================*
        *=== INTRA 16x16 MODE ===*
        *========================*/
         currMB->intraOrInter = INTRA_MB_16x16;
         img->imod            = INTRA_MB_NEW;
         intrapred_luma_2 ();   // make intra pred for all 4 new modes
         find_sad2 (&k);        // get best new intra mode
         RDCost_Macroblock (&rd, mode, k, 0, 0);
       }
       else if (mode == MBMODE_COPY)
       {
       /*=======================*
        *=== COPY MACROBLOCK ===*
        *=======================*/
         currMB->intraOrInter = INTER_MB;
         img->imod            = INTRA_MB_INTER;
         RDCost_Macroblock (&rd, mode, 0, 0, 0);
       }
       else if (!bframe && (mode >= MBMODE_INTER16x16 && mode <= MBMODE_INTER4x4))
       {
       /*===================================*
        *=== INTER MACROBLOCK in P-FRAME ===*
        *===================================*/
         currMB->intraOrInter = INTER_MB;
         img->imod            = INTRA_MB_INTER;

         min_inter_sad = MAX_VALUE;
         for (k=0; k<max_ref_frame; k++)
#ifdef _ADDITIONAL_REFERENCE_FRAME_
           if (k <  input->no_multpred ||
               k == input->add_ref_frame)
#endif
           {
             tot_inter_sad  = (int)floor(rdopt->lambda_motion * (1+2*floor(log(k+1)/log(2)+1e-10)));
             tot_inter_sad += SingleUnifiedMotionSearch (k, mode,
                            refFrArr, tmp_mv, img->mv, PFRAME, img->all_mv,
                            rdopt->lambda_motion);
             if (tot_inter_sad <  min_inter_sad)
             {
               k0 = k;
               min_inter_sad = tot_inter_sad;
             }
           }
         for (  i=0; i < 4; i++)
           for (j=0; j < 4; j++)
           {
             tmp_mv[0][img->block_y+j][img->block_x+i+4]=img->all_mv[i][j][k0][mode][0];
             tmp_mv[1][img->block_y+j][img->block_x+i+4]=img->all_mv[i][j][k0][mode][1];
           }
         RDCost_Macroblock (&rd, mode, k0, mode, 0);
       }
       else if (bframe && (mode >= MBMODE_INTER16x16 && mode <= MBMODE_INTER4x4))
       {
        /*===============================================*
         *=== FORWARD PREDICTED MACROBLOCK in B-FRAME ===*
         *===============================================*/
         if (forward_rdcost[mode] < 0.0)
         {
           currMB->intraOrInter = INTER_MB;
           img->imod            = B_Forward;

           min_inter_sad = MAX_VALUE;
           for (k=0; k<max_ref_frame; k++)
#ifdef _ADDITIONAL_REFERENCE_FRAME_
             if (k <  input->no_multpred ||
                 k == input->add_ref_frame)
#endif
             {
               if (!forward_me_done[mode][k])
               {
                 tot_for_sad[mode][k]  = (int)floor(rdopt->lambda_motion * (1+2*floor(log(k+1)/log(2)+1e-10)));
                 tot_for_sad[mode][k] += SingleUnifiedMotionSearch (k, mode,
                                         fw_refFrArr, tmp_fwMV, img->p_fwMV,
                                         B_FORWARD, img->all_mv,
                                         rdopt->lambda_motion);
                                         forward_me_done[mode][k] = 1;
               }
               if (tot_for_sad[mode][k] < min_inter_sad)
               {
                 k0 = k;
                 min_inter_sad = tot_for_sad[mode][k];
               }
             }
           for (  i=0; i < 4; i++)
             for (j=0; j < 4; j++)
             {
               tmp_fwMV[0][img->block_y+j][img->block_x+i+4]=img->all_mv[i][j][k0][mode][0];
               tmp_fwMV[1][img->block_y+j][img->block_x+i+4]=img->all_mv[i][j][k0][mode][1];
             }
           RDCost_Macroblock (&rd, mode, k0, mode, 0);
           forward_rdcost[mode] = rd.rdcost;
           best_refframe [mode] = k0;
         }
       }
       else if (mode >= MBMODE_BACKWARD16x16 && mode <= MBMODE_BACKWARD4x4)
       {
        /*================================================*
         *=== BACKWARD PREDICTED MACROBLOCK in B-FRAME ===*
         *================================================*/
         if (backward_rdcost [mode-NO_INTER_MBMODES] < 0.0)
         {
           currMB->intraOrInter = INTER_MB;
           img->imod            = B_Backward;
           if (!backward_me_done[mode-NO_INTER_MBMODES])
           {
             SingleUnifiedMotionSearch (0, mode-NO_INTER_MBMODES,
               bw_refFrArr, tmp_bwMV, img->p_bwMV, B_BACKWARD, img->all_bmv,
               rdopt->lambda_motion);
             backward_me_done[mode-NO_INTER_MBMODES]=1;
           }
           else
             for (j = 0; j < 4; j++)
               for (i = 0; i < 4; i++)
               {
                 tmp_bwMV[0][img->block_y+j][img->block_x+i+4]=
                   img->all_bmv[i][j][0][mode-NO_INTER_MBMODES][0];
                 tmp_bwMV[1][img->block_y+j][img->block_x+i+4]=
                   img->all_bmv[i][j][0][mode-NO_INTER_MBMODES][1];
               }
           RDCost_Macroblock (&rd, mode, 0, 0, mode-NO_INTER_MBMODES);
           backward_rdcost[mode-NO_INTER_MBMODES] = rd.rdcost;
         }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -