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

📄 mode_decision.c

📁 H.264ITU-T 标准源码JM98 ITU推荐的免费解码器
💻 C
📖 第 1 页 / 共 5 页
字号:
    *bi_pred_me = 0;
    //--- get prediction direction ----
    if  (bmcost[LIST_0] <= bmcost[LIST_1] 
      && bmcost[LIST_0] <= bmcost[BI_PRED] 
      && bmcost[LIST_0] <= bmcost[BI_PRED_L0] 
      && bmcost[LIST_0] <= bmcost[BI_PRED_L1])
    {
      *best_pdir = 0;
      *cost += bmcost[LIST_0];
      //best_ref[LIST_1] = 0;
    }
    else if (bmcost[LIST_1] <= bmcost[LIST_0] 
      &&     bmcost[LIST_1] <= bmcost[BI_PRED] 
      &&     bmcost[LIST_1] <= bmcost[BI_PRED_L0] 
      &&     bmcost[LIST_1] <= bmcost[BI_PRED_L1])
    {
      *best_pdir = 1;
      *cost += bmcost[LIST_1];
      //best_ref[LIST_0] = 0;
    }
    else if (bmcost[BI_PRED] <= bmcost[LIST_0] 
      &&     bmcost[BI_PRED] <= bmcost[LIST_1] 
      &&     bmcost[BI_PRED] <= bmcost[BI_PRED_L0] 
      &&     bmcost[BI_PRED] <= bmcost[BI_PRED_L1])
    {
      *best_pdir = 2;
      *cost += bmcost[BI_PRED];
      //best_ref[LIST_1] = 0;  
    }
    else if (bmcost[BI_PRED_L0] <= bmcost[LIST_0] 
      &&     bmcost[BI_PRED_L0] <= bmcost[LIST_1] 
      &&     bmcost[BI_PRED_L0] <= bmcost[BI_PRED]
      &&     bmcost[BI_PRED_L0] <= bmcost[BI_PRED_L1])
    {
      *best_pdir = 2;
      *cost += bmcost[BI_PRED_L0];                  
      *bi_pred_me = 1;
      img->bi_pred_me[mode]=1;
      best_ref[LIST_1] = 0;
      best_ref[LIST_0] = 0;
    }
    else
    {
      *best_pdir = 2;
      *cost += bmcost[BI_PRED_L1];                                  
      *bi_pred_me = 2;
      best_ref[LIST_1] = 0;
      best_ref[LIST_0] = 0;
      img->bi_pred_me[mode]=2;
    }               
  }
}

/*!
*************************************************************************************
* \brief
*    RD decision process
*************************************************************************************
*/
void compute_mode_RD_cost(int mode, 
                          Macroblock *currMB, 
                          RD_PARAMS enc_mb, 
                          double *min_rdcost, 
                          double *min_rate, 
                          int i16mode, 
                          short bslice, 
                          short *inter_skip)
{
  //--- transform size ---           
  currMB->luma_transform_size_8x8_flag = input->Transform8x8Mode==2
    ?  (mode >= 1 && mode <= 3)
    || (mode == 0 && bslice && active_sps->direct_8x8_inference_flag)
    || ((mode == P8x8) && (enc_mb.valid[4]))
    :  0;
  
  SetModesAndRefframeForBlocks (mode);
  
  // Encode with coefficients
  img->NoResidueDirect = 0;  
  if (currMB->c_ipred_mode == DC_PRED_8 || (IS_INTRA(currMB) ))
  {
    while(1)
    {
      if (RDCost_for_macroblocks (enc_mb.lambda_md, mode, min_rdcost, min_rate, i16mode))
      {
        //Rate control
        if (input->RCEnable)
        {
          if(mode == P8x8)
            rc_store_diff(img->opix_x,img->opix_y,
            currMB->luma_transform_size_8x8_flag == 1 ? tr8x8.mpr8x8 : tr4x4.mpr8x8);
          else
            rc_store_diff(img->opix_x, img->opix_y, pred);
        }      
        store_macroblock_parameters (mode);
        
        if(input->rdopt==2 && mode == 0 && input->EarlySkipEnable)
        {
          // check transform quantized coeff.
          if(currMB->cbp == 0)
            *inter_skip = 1;
        }
        
      }
      
      // Go through transform modes. 
      // Note that if currMB->cbp is 0 one could choose to skip 8x8 mode
      // although this could be due to deadzoning decisions.
      //if (input->Transform8x8Mode==1 && currMB->cbp!=0) 
      if (input->Transform8x8Mode==1)
      {
        //=========== try mb_types 1,2,3 with 8x8 transform ===========
        if ((mode >= 1 && mode <= 3) && currMB->luma_transform_size_8x8_flag == 0)
        {
          //try with 8x8 transform size
          currMB->luma_transform_size_8x8_flag = 1;
          continue;
        }
        //=========== try DIRECT-MODE with 8x8 transform ===========
        else if (mode == 0 && bslice && active_sps->direct_8x8_inference_flag && currMB->luma_transform_size_8x8_flag == 0)
        {
          //try with 8x8 transform size
          currMB->luma_transform_size_8x8_flag = 1;
          continue;
        }
        //=========== try mb_type P8x8 for mode 4 with 4x4/8x8 transform ===========
        else if ((mode == P8x8) && (enc_mb.valid[4]) && (currMB->luma_transform_size_8x8_flag == 0))
        {
          currMB->luma_transform_size_8x8_flag = 1; //check 8x8 partition for transform size 8x8
          continue;
        }
        else
        {
          currMB->luma_transform_size_8x8_flag = 0;
          break;
        }
      }
      else
        break;
    }
  }
  
  // Encode with no coefficients. Currently only for direct. This could be extended to all other modes as in example.
  //if (mode < P8x8 && (*inter_skip == 0) && enc_mb.valid[mode] && currMB->cbp && (currMB->cbp&15) != 15 && !input->nobskip)
  if ( bslice && mode == 0 && (*inter_skip == 0) && enc_mb.valid[mode] 
    && currMB->cbp && (currMB->cbp&15) != 15 && !input->nobskip) 
  {
    img->NoResidueDirect = 1;
    if (RDCost_for_macroblocks (enc_mb.lambda_md, mode, min_rdcost, min_rate, i16mode)) 
    {
      //Rate control
      if (input->RCEnable)
        rc_store_diff(img->opix_x,img->opix_y,pred);
      
      store_macroblock_parameters (mode);
    }
  }
};


/*!
*************************************************************************************
* \brief
*    Mode Decision for an 8x8 sub-macroblock
*************************************************************************************
*/
void submacroblock_mode_decision(RD_PARAMS enc_mb, 
                                 RD_8x8DATA *dataTr, 
                                 Macroblock *currMB,
                                 int ***cofACtr, 
                                 int *have_direct, 
                                 short bslice, 
                                 int block, 
                                 int *cost_direct,                                  
                                 int *cost,
                                 int *cost8x8_direct,
                                 int transform8x8)  
{
  int j0, i0, j1, i1;
  int i,j, k;
  int min_cost8x8, index;
  double min_rdcost, rdcost = 0.0;
  short best_pdir = 0;
  char best_ref[2] = {0, -1};
  int mode;
  int64 curr_cbp_blk;
  int direct4x4_tmp, direct8x8_tmp;
  int bmcost[5] = {INT_MAX};
  int cnt_nonz = 0;
  short pdir;
  int dummy;
  short bi_pred_me;
  int best_cnt_nonz = 0;
  int maxindex =  (transform8x8) ? 2 : 5;
  int pix_x, pix_y;
  int block_x, block_y;
  
  int fadjust[16][16], fadjustCr[2][16][16];    
  int (*fadjustTransform)[16][16] = transform8x8? img->fadjust8x8 : img->fadjust4x4;
  int (*fadjustTransformCr)[2][16][16] = transform8x8? img->fadjust8x8Cr : img->fadjust4x4Cr;
  int lumaAdjustIndex = transform8x8? 2 : 3;
  int chromaAdjustIndex = transform8x8? 0 : 2;
  
  //--- set coordinates ---
  j0 = ((block/2)<<3);    j1 = (j0>>2);
  i0 = ((block%2)<<3);    i1 = (i0>>2);
  
#ifdef BEST_NZ_COEFF
  for(j = 0; j <= 1; j++)
  {
    for(i = 0; i <= 1; i++)
      best_nz_coeff[i][j] = img->nz_coeff[img->current_mb_nr][i1 + i][j1 + j] = 0;
  }
#endif
  
  if (transform8x8)
    currMB->luma_transform_size_8x8_flag = 1; //switch to transform size 8x8
  
  //--- store coding state before coding ---
  store_coding_state (cs_cm);

  //=====  LOOP OVER POSSIBLE CODING MODES FOR 8x8 SUB-PARTITION  =====
  for (min_cost8x8=INT_MAX, min_rdcost=1e30, index=(bslice?0:1); index<maxindex; index++)
  {
    mode = b8_mode_table[index]; 
    *cost = 0;
    if (enc_mb.valid[mode] && (transform8x8 == 0 || mode != 0 || (mode == 0 && active_sps->direct_8x8_inference_flag)))
    {
      curr_cbp_blk = 0;
      
      if (mode==0)
      {
        //--- Direct Mode ---                                      
        if (!input->rdopt )
        {
          direct4x4_tmp=0; direct8x8_tmp=0;
          direct4x4_tmp = Get_Direct_Cost8x8 ( block, &direct8x8_tmp);
          
          if ((direct4x4_tmp==INT_MAX)||(*cost_direct==INT_MAX))
          {
            *cost_direct = INT_MAX;
            if (transform8x8) 
              *cost8x8_direct = INT_MAX;
          }
          else
          {
            *cost_direct += direct4x4_tmp;
            if (transform8x8) 
              *cost8x8_direct += direct8x8_tmp;
          }                     
          *have_direct ++;
          
          if (transform8x8)
          {
            switch(input->Transform8x8Mode)
            {
            case 1: // Mixture of 8x8 & 4x4 transform
              if((direct8x8_tmp < direct4x4_tmp) || !(enc_mb.valid[5] && enc_mb.valid[6] && enc_mb.valid[7]))
                *cost = direct8x8_tmp;
              else
                *cost = direct4x4_tmp;
              break;
            case 2: // 8x8 Transform only
              *cost = direct8x8_tmp;
              break;
            default: // 4x4 Transform only
              *cost = direct4x4_tmp;
              break;
            }            
            if (input->Transform8x8Mode==2) 
              *cost = INT_MAX;                                       
          }
          else
          {
            *cost = direct4x4_tmp;
          }
        }

        block_x = img->block_x+(block&1)*2;
        block_y = img->block_y+(block&2);
        best_ref[LIST_0] = direct_ref_idx[LIST_0][block_y][block_x];
        best_ref[LIST_1] = direct_ref_idx[LIST_1][block_y][block_x];
        best_pdir   = direct_pdir[block_y][block_x];
      } // if (mode==0)
      else
      {        
        //======= motion estimation for all reference frames ========
        //-----------------------------------------------------------
        PartitionMotionSearch (mode, block, enc_mb.lambda_mf);
        
        //--- get cost and reference frame for LIST 0 prediction ---
        bmcost[LIST_0] = INT_MAX;
        list_prediction_cost(LIST_0, block, mode, enc_mb, bmcost, best_ref);
        
        //store LIST 0 reference index for every block
        block_x = img->block_x+(block&1)*2;
        block_y = img->block_y+(block&2);
        for (j = block_y; j< block_y + 2; j++)
        {
          for (i = block_x; i < block_x + 2; i++)
          {
            enc_picture->ref_idx   [LIST_0][j][i] = best_ref[LIST_0];
            enc_picture->ref_pic_id[LIST_0][j][i] = 
              enc_picture->ref_pic_num[enc_mb.list_offset[LIST_0]][(short)best_ref[LIST_0]];
          }
        } 
        
        if (bslice)
        {
          //--- get cost and reference frame for LIST 1 prediction ---
          bmcost[LIST_1] = INT_MAX;
          list_prediction_cost(LIST_1, block, mode, enc_mb, bmcost, best_ref);
          
          // Compute bipredictive cost between best list 0 and best list 1 references
          list_prediction_cost(BI_PRED, block, mode, enc_mb, bmcost, best_ref);
          
          //--- get prediction direction ----          
          determine_prediction_list(mode, bmcost, best_ref, &best_pdir, cost, &bi_pred_me);
          
          //store backward reference index for every block
          for (j = block_y; j< block_y + 2; j++)
          {
            for (i = block_x; i < block_x + 2; i++)
            {
              enc_picture->ref_idx[LIST_0][j][i] = best_ref[LIST_0];
              enc_picture->ref_idx[LIST_1][j][i] = best_ref[LIST_1];
            }
          }
        } // if (bslice)
        else
        {
          best_pdir = 0;
          *cost     = bmcost[LIST_0];
        }
      } // if (mode!=0)
      
      if (input->rdopt)
      {
        //--- get and check rate-distortion cost ---
        rdcost = RDCost_for_8x8blocks (&cnt_nonz, &curr_cbp_blk, enc_mb.lambda_md,
          block, mode, best_pdir, best_ref[LIST_0], best_ref[LIST_1]);
      }
      else
      {
        if (*cost!=INT_MAX)
          *cost += (REF_COST (enc_mb.lambda_mf, B8Mode2Value (mode, best_pdir),
          enc_mb.list_offset[(best_pdir<1?LIST_0:LIST_1)]) - 1);
      }
      
      //--- set variables if best mode has changed ---
      if ( ( input->rdopt && rdcost < min_rdcost) 
        || (!input->rdopt && *cost < min_cost8x8))
      {
        min_cost8x8                 = *cost;
        min_rdcost                  = rdcost;
        dataTr->part8x8mode [block] = mode;
        dataTr->part8x8pdir [block] = best_pdir;

⌨️ 快捷键说明

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