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

📄 rdoq.c

📁 H.264编码实现
💻 C
📖 第 1 页 / 共 2 页
字号:

  masterQP = img->masterQP = img->qp;
  Motion_Selected = 0;
  rddata_trellis_best.min_rdcost = 1e30;

  if (params->symbol_mode == CABAC)
  {
    estRunLevel_CABAC(currMB, LUMA_4x4); 
    estRunLevel_CABAC(currMB, LUMA_16AC);
    estRunLevel_CABAC(currMB, LUMA_16DC);
    if (params->Transform8x8Mode)
      estRunLevel_CABAC(currMB, LUMA_8x8);
    if (params->yuv_format != YUV400)
    {
      estRunLevel_CABAC(currMB, CHROMA_AC);
      if (params->yuv_format == YUV420)
        estRunLevel_CABAC(currMB, CHROMA_DC);
      else
        estRunLevel_CABAC(currMB, CHROMA_DC_2x4);
    }
  }

  qp_left   = (currMB->mb_available_left) ? currMB->mb_available_left->qp : img->masterQP;
  qp_up     = (currMB->mb_available_up)   ? currMB->mb_available_up->qp   : img->masterQP;
  qp_anchor = (qp_left + qp_up + 1)>>1;

  for (deltaQPCnt=0; deltaQPCnt < params->RDOQ_QP_Num; deltaQPCnt++)
  {
    rdopt = &rddata_trellis_curr;
#if RDOQ_BASE
    if (img->type == B_SLICE)
      deltaQP = deltaQPTabB[deltaQPCnt];      
    else
      deltaQP = deltaQPTabP[deltaQPCnt];
#else

    // It seems that pushing the masterQP as first helps things when fast me is enabled. 
    // Could there be an issue with motion estimation?
    if (deltaQPCnt == 0)
      deltaQP = 0;
    else if (deltaQPCnt <= qp_offset)
      deltaQP = deltaQPCnt - 1 - qp_offset;
    else
      deltaQP = deltaQPCnt - qp_offset;
    //printf("qp %d %d %d\n", deltaQP,  deltaQPCnt, masterQP);
#endif

    img->qp = iClip3(-img->bitdepth_luma_qp_scale, 51, masterQP + deltaQP);
    deltaQP = masterQP - img->qp;    

#if 0
    if(deltaQP != 0 && !(img->qp - qp_anchor >= -2 && img->qp - qp_anchor <= 1) && currMB->mb_available_left && currMB->mb_available_up && img->type == P_SLICE)
      continue; 
    if(deltaQP != 0 && !(img->qp - qp_anchor >= -1 && img->qp - qp_anchor <= 2) && currMB->mb_available_left && currMB->mb_available_up && img->type == B_SLICE)
      continue;
#endif

    reset_macroblock(currMB, prev_mb);
    currMB->qp       = img->qp;
    currMB->delta_qp = currMB->qp - currMB->prev_qp;
    update_qp (img, currMB);

    encode_one_macroblock (currMB);

    if ( rddata_trellis_curr.min_rdcost < rddata_trellis_best.min_rdcost)
      copy_rddata_trellis(&rddata_trellis_best, rdopt);

    if (params->RDOQ_CP_MV)
      Motion_Selected = 1;

#if (!RDOQ_BASE)
    if (params->RDOQ_Fast)
    {
      if ((img->qp - rddata_trellis_best.qp > 1))
        break;
      if ((rddata_trellis_curr.cbp == 0) && (rddata_trellis_curr.mb_type != 0))
        break;
      if ((rddata_trellis_best.mb_type == 0) && (rddata_trellis_best.cbp == 0))
        break;
    }
#endif
  }

  reset_macroblock(currMB, prev_mb);
  rdopt = &rddata_trellis_best;

  copy_rdopt_data (currMB, FALSE);  // copy the MB data for Top MB from the temp buffers
  write_one_macroblock (currMB, 1, prev_recode_mb);
  img->qp = masterQP;
}

void trellis_sp(Macroblock *currMB, int CurrentMbAddr, Boolean prev_recode_mb)
{
  img->masterQP = img->qp;

  if (params->symbol_mode == CABAC)
  {
    estRunLevel_CABAC(currMB, LUMA_4x4); 
    estRunLevel_CABAC(currMB, LUMA_16AC);
    
    estRunLevel_CABAC(currMB, LUMA_16DC);
    if (params->Transform8x8Mode)
      estRunLevel_CABAC(currMB, LUMA_8x8);

    if (params->yuv_format != YUV400)
    {
      estRunLevel_CABAC(currMB, CHROMA_AC);

      if (params->yuv_format == YUV420)
        estRunLevel_CABAC(currMB, CHROMA_DC);
      else
        estRunLevel_CABAC(currMB, CHROMA_DC_2x4);
    }
  }

  encode_one_macroblock (currMB);
  write_one_macroblock (currMB, 1, prev_recode_mb);    
}

void trellis_coding(Macroblock *currMB, int CurrentMbAddr, Boolean prev_recode_mb)
{
  if (params->RDOQ_QP_Num > 1)
  {
    trellis_mp(currMB, CurrentMbAddr, prev_recode_mb);   
  }
  else
  {
    trellis_sp(currMB, CurrentMbAddr, prev_recode_mb);   
  }
}


void RDOQ_update_mode(RD_PARAMS *enc_mb, int bslice)
{
  int i;
  for(i=0; i<MAXMODE; i++)
    enc_mb->valid[i] = 0;

  enc_mb->valid[rdopt->mb_type] = 1;

  if(rdopt->mb_type  == P8x8)
  {            
    enc_mb->valid[4] = (params->InterSearch[bslice][4]);
    enc_mb->valid[5] = (params->InterSearch[bslice][5] && !(params->Transform8x8Mode==2));
    enc_mb->valid[6] = (params->InterSearch[bslice][6] && !(params->Transform8x8Mode==2));
    enc_mb->valid[7] = (params->InterSearch[bslice][7] && !(params->Transform8x8Mode==2));
  }
}

void copy_rddata_trellis (RD_DATA *dest, RD_DATA *src)
{
  int j; 

  dest->min_rdcost = src->min_rdcost;
  dest->min_dcost  = src->min_dcost;

  memcpy(&dest->rec_mbY[0][0],&src->rec_mbY[0][0], MB_PIXELS * sizeof(imgpel));

  if (img->yuv_format != YUV400) 
  {
    // we could allocate these dynamically to improve performance.
    memcpy(&dest->rec_mb_cr[0][0][0],&src->rec_mb_cr[0][0][0], 2 * MB_PIXELS * sizeof(imgpel));
  }

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

  dest->mb_type = src->mb_type;
  memcpy(dest->b8mode, src->b8mode, BLOCK_MULTIPLE * sizeof(short));
  memcpy(dest->b8pdir, src->b8pdir, BLOCK_MULTIPLE * sizeof(short));
  dest->cbp  = src->cbp;
  dest->mode = src->mode;
  dest->i16offset = src->i16offset;
  dest->c_ipred_mode = src->c_ipred_mode;
  dest->luma_transform_size_8x8_flag = src->luma_transform_size_8x8_flag;
  dest->NoMbPartLessThan8x8Flag = src->NoMbPartLessThan8x8Flag;
  dest->qp = src->qp;

  dest->prev_qp  = src->prev_qp;
  dest->prev_dqp = src->prev_dqp;
  dest->delta_qp = src->delta_qp;
  dest->prev_cbp = src->prev_cbp;
  dest->cbp_blk  = src->cbp_blk;
 

  if (img->type != I_SLICE)
  {
    // note that this is not copying the bipred mvs!!!
    memcpy(&dest->all_mv [0][0][0][0][0][0], &src->all_mv [0][0][0][0][0][0], 2 * img->max_num_references * 9 * 4 * 4 * 2 * sizeof(short));
    memcpy(&dest->pred_mv[0][0][0][0][0][0], &src->pred_mv[0][0][0][0][0][0], 2 * img->max_num_references * 9 * 4 * 4 * 2 * sizeof(short));
  }

  memcpy(dest->intra_pred_modes,src->intra_pred_modes, MB_BLOCK_PARTITIONS * sizeof(char));
  memcpy(dest->intra_pred_modes8x8,src->intra_pred_modes8x8, MB_BLOCK_PARTITIONS * sizeof(char));
  for(j = img->block_y; j < img->block_y + BLOCK_MULTIPLE; j++)
    memcpy(&dest->ipredmode[j][img->block_x],&src->ipredmode[j][img->block_x], BLOCK_MULTIPLE * sizeof(char));
  memcpy(&dest->refar[LIST_0][0][0], &src->refar[LIST_0][0][0], 2 * BLOCK_MULTIPLE * BLOCK_MULTIPLE * sizeof(char));
}                            

void updateMV_mp(int *m_cost, short ref, int list, int h, int v, int blocktype, int *lambda_factor, int block8x8)
{
  int       i, j;
  int       bsx       = params->blc_size[blocktype][0];
  int       bsy       = params->blc_size[blocktype][1];
  short     tmp_pred_mv[2];
  short*    pred_mv = img->pred_mv[list][ref][blocktype][v][h];
  short     all_mv[2];
  Macroblock *currMB = &img->mb_data[img->current_mb_nr];
  if ( (params->Transform8x8Mode == 1) && (blocktype == 4) && currMB->luma_transform_size_8x8_flag)
  {
    all_mv[0] = tmp_mv8[list][ref][v][h][0];
    all_mv[1] = tmp_mv8[list][ref][v][h][1];
    tmp_pred_mv[0] = tmp_pmv8[list][ref][v][h][0];
    tmp_pred_mv[1] = tmp_pmv8[list][ref][v][h][1];
    *m_cost   = motion_cost8[list][ref][block8x8];
  }
  else
  {
    all_mv[0] = rddata_trellis_best.all_mv[list][ref][blocktype][v][h][0];
    all_mv[1] = rddata_trellis_best.all_mv[list][ref][blocktype][v][h][1];
    tmp_pred_mv[0] = rddata_trellis_best.pred_mv[list][ref][blocktype][v][h][0];
    tmp_pred_mv[1] = rddata_trellis_best.pred_mv[list][ref][blocktype][v][h][1];
  }

  for (j = 0; j < (bsy>>2); j++)
  {
    for (i = 0; i < (bsx>>2); i++) 
      memcpy(img->all_mv[list][ref][blocktype][v+j][h+i], all_mv, 2 * sizeof(short));
  }

  SetMotionVectorPredictor (currMB, pred_mv, enc_picture->motion.ref_idx[list], enc_picture->motion.mv[list], ref, list, h<<2, v<<2, bsx, bsy);

  if ( (tmp_pred_mv[0] != pred_mv[0]) || (tmp_pred_mv[1] != pred_mv[1]) )
  {
    *m_cost -= MV_COST_SMP (lambda_factor[H_PEL], all_mv[0], all_mv[1], tmp_pred_mv[0], tmp_pred_mv[1]);
    *m_cost += MV_COST_SMP (lambda_factor[H_PEL], all_mv[0], all_mv[1], pred_mv[0], pred_mv[1]);
  }
}



⌨️ 快捷键说明

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