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

📄 rdopt.c

📁 H.264编码实现
💻 C
📖 第 1 页 / 共 5 页
字号:
    {
      // cod counter and macroblock mode are written ==> do not consider code counter
      tmp_cc = img->cod_counter;
      rate   = writeMBLayer (currMB, 1, &coeff_rate);
      ue_linfo (tmp_cc, dummy, &cc_rate, &dummy);
      rate  -= cc_rate;
      img->cod_counter = tmp_cc;
    }
    else
    {
      // cod counter is just increased  ==> get additional rate
      ue_linfo (img->cod_counter + 1, dummy, &rate,    &dummy);
      ue_linfo (img->cod_counter    , dummy, &cc_rate, &dummy);
      rate -= cc_rate;
    }
  }
  else
  {
    rate = writeMBLayer (currMB, 1, &coeff_rate);
  }

  //=====   R E S T O R E   C O D I N G   S T A T E   =====
  //-------------------------------------------------------
  reset_coding_state (currMB, cs_cm);

  rdcost = (double)distortion + lambda * dmax(0.5,(double)rate);

  if (rdcost >= *min_rdcost ||
    ((currMB->qp_scaled[0]) == 0 && img->lossless_qpprime_flag == 1 && distortion != 0))
  {
#if FASTMODE
    // Reordering RDCost comparison order of mode 0 and mode 1 in P_SLICE
    // if RDcost of mode 0 and mode 1 is same, we choose best_mode is 0
    // This might not always be good since mode 0 is more biased towards rate than quality.
    if((img->type!=P_SLICE || mode != 0 || rdcost != *min_rdcost) || IS_FREXT_PROFILE(params->ProfileIDC))
#endif
      return 0;
  }


  if ((img->MbaffFrameFlag) && (mode ? 0: ((img->type == B_SLICE) ? !currMB->cbp:1)))  // AFF and current is skip
  {
    if (img->current_mb_nr & 0x01) //bottom
    {
      if (prevMB->mb_type ? 0:((img->type == B_SLICE) ? !prevMB->cbp:1)) //top is skip
      {
        if (!(field_flag_inference(currMB) == currMB->mb_field)) //skip only allowed when correct inference
          return 0;
      }
    }
  }

  //=====   U P D A T E   M I N I M U M   C O S T   =====
  //-----------------------------------------------------
  *min_rdcost = rdcost;
  *min_dcost = (double) distortion;
  *min_rate = lambda * (double)coeff_rate;

#ifdef BEST_NZ_COEFF
  for (j=0;j<4;j++)
    memcpy(&gaaiMBAFF_NZCoeff[j][0], &img->nz_coeff[img->current_mb_nr][j][0], (4 + img->num_blk8x8_uv) * sizeof(int));
#endif

  return 1;
}


/*!
 *************************************************************************************
 * \brief
 *    Store macroblock parameters
 *************************************************************************************
 */
void store_macroblock_parameters (Macroblock *currMB, int mode)
{
  int  j, ****i4p, ***i3p;
  int  bframe   = (img->type==B_SLICE);

  //--- store best mode ---
  best_mode = mode;
  best_c_imode = currMB->c_ipred_mode;
  best_i16offset = img->i16offset;

  
  memcpy(b8mode, currMB->b8mode, BLOCK_MULTIPLE * sizeof(short));
  memcpy(b8bipred_me, currMB->bipred_me, BLOCK_MULTIPLE * sizeof(short));
  memcpy(b8pdir, currMB->b8pdir, BLOCK_MULTIPLE * sizeof(short));
  memcpy(b4_intra_pred_modes,   currMB->intra_pred_modes, MB_BLOCK_PARTITIONS * sizeof(char));
  memcpy(b8_intra_pred_modes8x8,currMB->intra_pred_modes8x8, MB_BLOCK_PARTITIONS * sizeof(char));

  for (j = 0 ; j < BLOCK_MULTIPLE; j++)
  {
    memcpy(&b4_ipredmode[j * BLOCK_MULTIPLE],&img->ipredmode   [img->block_y + j][img->block_x],BLOCK_MULTIPLE * sizeof(char));
    memcpy(b8_ipredmode8x8[j],               &img->ipredmode8x8[img->block_y + j][img->block_x],BLOCK_MULTIPLE * sizeof(char));
  }
  //--- reconstructed blocks ----
  for (j = 0; j < MB_BLOCK_SIZE; j++)
  {
    memcpy(rec_mbY[j], &enc_picture->imgY[img->pix_y+j][img->pix_x], MB_BLOCK_SIZE * sizeof(imgpel));
  }
  if((img->type==SP_SLICE) && (si_frame_indicator==0 && sp2_frame_indicator==0))
  {
    for (j = 0; j < MB_BLOCK_SIZE; j++)
    {
      memcpy(lrec_rec[j], &lrec[img->pix_y+j][img->pix_x], MB_BLOCK_SIZE * sizeof(int));//store coefficients SP frame
    }
  }

  if (img->AdaptiveRounding)
    store_adaptive_rounding_parameters (currMB, mode);

  if (img->yuv_format != YUV400)
  {
    int k;
    for (k = 0; k < 2; k++)
    {
      for (j = 0; j<img->mb_cr_size_y; j++)
      {
        memcpy(rec_mb_cr[k][j], &enc_picture->imgUV[k][img->pix_c_y+j][img->pix_c_x], img->mb_cr_size_x * sizeof(imgpel));
      }
    }

    if((img->type==SP_SLICE) && (si_frame_indicator==0 && sp2_frame_indicator==0))
    {
      //store uv coefficients SP frame
      for (k = 0; k < 2; k++)
      {
        for (j = 0; j<img->mb_cr_size_y; j++)
        {
          memcpy(lrec_rec_uv[k][j],&lrec_uv[k][img->pix_c_y+j][img->pix_c_x], img->mb_cr_size_x * sizeof(int));
        }
      }
    }
  }

  //--- store results of decoders ---
  if (params->rdopt == 3 && img->type!=B_SLICE)
  {
    errdo_store_best_block(img, decs->dec_mbY, enc_picture->p_dec_img[0], 0, 0, MB_BLOCK_SIZE);
  }

  //--- coeff, cbp, kac ---
  if (mode || bframe)
  {
    i4p=cofAC; cofAC=img->cofAC; img->cofAC=i4p;
    i3p=cofDC; cofDC=img->cofDC; img->cofDC=i3p;
    cbp     = currMB->cbp;
    curr_cbp[0] = cmp_cbp[1];  
    curr_cbp[1] = cmp_cbp[2]; 

    cur_cbp_blk[0] = currMB->cbp_blk;
  }
  else
  {
    cur_cbp_blk[0] = cbp = 0;
    cmp_cbp[1] = cmp_cbp[2] = 0; 
  }

  //--- store transform size ---
  luma_transform_size_8x8_flag = currMB->luma_transform_size_8x8_flag;


  for (j = 0; j<4; j++)
    memcpy(l0_refframe[j],&enc_picture->motion.ref_idx[LIST_0][img->block_y+j][img->block_x], BLOCK_MULTIPLE * sizeof(char));

  if (bframe)
  {
    for (j = 0; j<4; j++)
      memcpy(l1_refframe[j],&enc_picture->motion.ref_idx[LIST_1][img->block_y+j][img->block_x], BLOCK_MULTIPLE * sizeof(char));
  }
}


/*!
 *************************************************************************************
 * \brief
 *    Set stored macroblock parameters
 *************************************************************************************
 */
void set_stored_macroblock_parameters (Macroblock *currMB)
{
  imgpel     **imgY  = enc_picture->imgY;
  imgpel    ***imgUV = enc_picture->imgUV;

  int         mode   = best_mode;
  int         bframe = (img->type==B_SLICE);
  int         i, j, k, ****i4p, ***i3p;
  int         block_x, block_y;
  char    **ipredmodes = img->ipredmode;
  short   *cur_mv, total_bipred_me;

  //===== reconstruction values =====

  // Luma
  for (j = 0; j < MB_BLOCK_SIZE; j++)
  {
    memcpy(&imgY[img->pix_y+j][img->pix_x],rec_mbY[j], MB_BLOCK_SIZE * sizeof(imgpel));
  }

  if (img->MbaffFrameFlag || (params->UseRDOQuant && params->RDOQ_QP_Num > 1))
  {
    for (j = 0; j < MB_BLOCK_SIZE; j++)
      memcpy(rdopt->rec_mbY[j],rec_mbY[j], MB_BLOCK_SIZE * sizeof(imgpel));
  }

  if((img->type==SP_SLICE) &&(si_frame_indicator==0 && sp2_frame_indicator==0 ))
  {
    for (j = 0; j < MB_BLOCK_SIZE; j++)
      memcpy(&lrec[img->pix_y+j][img->pix_x],lrec_rec[j], MB_BLOCK_SIZE * sizeof(int)); //restore coeff SP frame
  }

  if (img->AdaptiveRounding)
  {
    update_offset_params(currMB, mode,luma_transform_size_8x8_flag);
  }

  if (img->yuv_format != YUV400)
  {
    int k;
    for (k = 0; k < 2; k++)
    {
      for (j = 0; j<img->mb_cr_size_y; j++)
      {
        memcpy(&imgUV[k][img->pix_c_y+j][img->pix_c_x], rec_mb_cr[k][j], img->mb_cr_size_x * sizeof(imgpel));
      }
    }

    if (img->MbaffFrameFlag || (params->UseRDOQuant && params->RDOQ_QP_Num > 1))
    {
      for (k = 0; k < 2; k++)
      {
        for (j = 0; j<img->mb_cr_size_y; j++)
        {
          memcpy(rdopt->rec_mb_cr[k][j],rec_mb_cr[k][j], img->mb_cr_size_x * sizeof(imgpel));
        }
      }
    }

    if((img->type==SP_SLICE) &&(!si_frame_indicator && !sp2_frame_indicator))
    {
      for (k = 0; k < 2; k++)
      {
        for (j = 0; j<img->mb_cr_size_y; j++)
        {
          memcpy(&lrec_uv[k][img->pix_c_y+j][img->pix_c_x],lrec_rec_uv[k][j], img->mb_cr_size_x * sizeof(int));
        }
      }
    }
  }

  //===== coefficients and cbp =====
  i4p=cofAC; cofAC=img->cofAC; img->cofAC=i4p;
  i3p=cofDC; cofDC=img->cofDC; img->cofDC=i3p;
  currMB->cbp      = cbp;
  currMB->cbp_blk = cur_cbp_blk[0];
  cmp_cbp[1] = curr_cbp[0]; 
  cmp_cbp[2] = curr_cbp[1]; 
  currMB->cbp |= cmp_cbp[1];
  currMB->cbp |= cmp_cbp[2];
  cmp_cbp[1] = currMB->cbp; 
  cmp_cbp[2] = currMB->cbp;

  //==== macroblock type ====
  currMB->mb_type = mode;

  memcpy(currMB->b8mode, b8mode, BLOCK_MULTIPLE * sizeof(short));
  memcpy(currMB->b8pdir, b8pdir, BLOCK_MULTIPLE * sizeof(short));
  memcpy(currMB->bipred_me, b8bipred_me, BLOCK_MULTIPLE * sizeof(short));

  if (img->MbaffFrameFlag || (params->UseRDOQuant && params->RDOQ_QP_Num > 1))
  {
    rdopt->mode = mode;
    rdopt->i16offset = img->i16offset;
    rdopt->cbp = cbp;
    rdopt->cbp_blk = cur_cbp_blk[0];
    rdopt->mb_type  = mode;

    rdopt->prev_qp  = currMB->prev_qp;
    rdopt->prev_dqp = currMB->prev_dqp;
    rdopt->delta_qp = currMB->delta_qp;
    rdopt->qp       = currMB->qp;
    rdopt->prev_cbp = currMB->prev_cbp;

    memcpy(rdopt->cofAC[0][0][0], img->cofAC[0][0][0], (4+img->num_blk8x8_uv) * 4 * 2 * 65 * sizeof(int));
    memcpy(rdopt->cofDC[0][0], img->cofDC[0][0], 3 * 2 * 18 * sizeof(int));

    memcpy(rdopt->b8mode,b8mode, BLOCK_MULTIPLE * sizeof(short));
    memcpy(rdopt->b8pdir,b8pdir, BLOCK_MULTIPLE * sizeof(short));
  }

  //if P8x8 mode and transform size 4x4 choosen, restore motion vector data for this transform size
  if (mode == P8x8 && !luma_transform_size_8x8_flag && params->Transform8x8Mode)
    RestoreMV8x8(1);

  //==== transform size flag ====
  if (img->P444_joined)
  {
    if (((currMB->cbp == 0) && cmp_cbp[1] == 0 && cmp_cbp[2] == 0) && !(IS_OLDINTRA(currMB) || currMB->mb_type == I8MB))
      currMB->luma_transform_size_8x8_flag = 0;
    else
      currMB->luma_transform_size_8x8_flag = luma_transform_size_8x8_flag;
  }
  else
  {

    if (((currMB->cbp & 15) == 0) && !(IS_OLDINTRA(currMB) || currMB->mb_type == I8MB))
      currMB->luma_transform_size_8x8_flag = 0;
    else
      currMB->luma_transform_size_8x8_flag = luma_transform_size_8x8_flag;
  }

  rdopt->luma_transform_size_8x8_flag  = currMB->luma_transform_size_8x8_flag;

  if (params->rdopt == 3 && img->type!=B_SLICE)  
  {
    errdo_get_best_block(img, enc_picture->p_dec_img[0], decs->dec_mbY, 0, MB_BLOCK_SIZE);
  }

  //==== reference frames =====
  for (j = 0; j < 4; j++)
  {
    block_y = img->block_y + j;
    for (i = 0; i < 4; i++)
    {
      block_x = img->block_x + i;
      k = 2*(j >> 1)+(i >> 1);

      // backward prediction or intra
      if ((currMB->b8pdir[k] == 1) || IS_INTRA(currMB))
      {
        enc_picture->motion.ref_idx    [LIST_0][block_y][block_x]    = -1;
        enc_picture->motion.ref_pic_id [LIST_0][block_y][block_x]    = -1;
        enc_picture->motion.mv         [LIST_0][block_y][block_x][0] = 0;
        enc_picture->motion.mv         [LIST_0][block_y][block_x][1] = 0;

        if (img->MbaffFrameFlag || (params->UseRDOQuant && params->RDOQ_QP_Num > 1))
          rdopt->refar[LIST_0][j][i] = -1;
      }
      else
      {
        if (currMB->bipred_me[k] && (currMB->b8pdir[k] == 2) && is_bipred_enabled(currMB->mb_type))
        {
          cur_mv = img->bipred_mv[currMB->bipred_me[k] - 1][LIST_0][0][currMB->b8mode[k]][j][i]; 

          enc_picture->motion.ref_idx    [LIST_0][block_y][block_x] = 0;
          enc_picture->motion.ref_pic_id [LIST_0][block_y][block_x] = enc_picture->ref_pic_num[LIST_0 + currMB->list_offset][0];
          enc_picture->motion.mv         [LIST_0][block_y][block_x][0] = cur_mv[0];
          enc_picture->motion.mv         [LIST_0][block_y][block_x][1] = cur_mv[1];

          if (img->MbaffFrameFlag || (params->UseRDOQuant && params->RDOQ_QP_Num > 1))
            rdopt->refar[LIST_0][j][i] = 0;
        }
        else
        {
          char cur_ref = l0_refframe[j][i];
          enc_picture->motion.ref_idx    [LIST_0][block_y][block_x] = cur_ref;
          enc_picture->motion.ref_pic_id [LIST_0][block_y][block_x] = enc_picture->ref_pic_num[LIST_0 + currMB->list_offset][(short)cur_ref];
          memcpy(enc_picture->motion.mv  [LIST_0][block_y][block_x], img->all_mv[LIST_0][(short)cur_ref][currMB->b8mode[k]][j][i], 2 * sizeof(short));

          if (img->MbaffFrameFlag || (params->UseRDOQuant && params->RDOQ_QP_Num > 1))
            rdopt->refar[LIST_0][j][i] = cur_ref;
        }
      }

      // forward prediction or intra
      if ((currMB->b8pdir[k] == 0) || IS_INTRA(currMB))
      {
        enc_picture->motion.ref_idx    [LIST_1][block_y][block_x]    = -1;
        enc_picture->motion.ref_pic_id [LIST_1][block_y][block_x]    = -1;
        enc_picture->motion.mv         [LIST_1][block_y][block_x][0] = 0;
        enc_picture->motion.mv         [LIST_1][block_y][block_x][1] = 0;

        if (img->MbaffFrameFlag || (params->UseRDOQuant && params->RDOQ_QP_Num > 1))
          rdopt->refar[LIST_1][j][i] = -1;
      }
    }
  }

  if (bframe)
  {
    for (j=0; j<4; j++)
    {
      block_y = img->block_y + j;
      for (i=0; i<4; i++)
      {
        block_x = img->block_x + i;
        k = 2*(j >> 1)+(i >> 1);

        // forward
        if (IS_INTRA(currMB)||(currMB->b8pdir[k] == 0))
        {
          enc_picture-

⌨️ 快捷键说明

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