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

📄 rdopt.c

📁 H264视频编解码程序
💻 C
📖 第 1 页 / 共 5 页
字号:
              residue_B = temp - (rec_resR[j][i]>>1);
              residue_R = residue_B+rec_resR[j][i];
              enc_picture->imgUV[0][pic_pix_y+j][pic_pix_x+i] = min(img->max_imgpel_value_uv,max(0,residue_B+(int)img->mprr_c[0][c_ipmode][block_y+j][block_x+i]));
              enc_picture->imgY[pic_pix_y+j][pic_pix_x+i]     = min(img->max_imgpel_value,max(0,residue_G+(int)img->mprr[ipmode][j][i]));
              enc_picture->imgUV[1][pic_pix_y+j][pic_pix_x+i] = min(img->max_imgpel_value_uv,max(0,residue_R+(int)img->mprr_c[1][c_ipmode][block_y+j][block_x+i]));
            }
          } 
          //===== get distortion (SSD) of 4x4 block =====
          distortion = 0;
          for (y=0; y<4; y++)
          {
            for (x=pic_pix_x; x<pic_pix_x+4; x++)
            {
              distortion += img->quad[imgY_org    [pic_pix_y+y][x] - enc_picture->imgY    [pic_pix_y+y][x]];
              distortion += img->quad[imgUV_org[0][pic_pix_y+y][x] - enc_picture->imgUV[0][pic_pix_y+y][x]];
              distortion += img->quad[imgUV_org[1][pic_pix_y+y][x] - enc_picture->imgUV[1][pic_pix_y+y][x]];
            }
          }
          rdcost = (double)distortion + lambda*(double)rate;
          
          if (rdcost < min_rdcost)
          {
            //--- set coefficients ---
            for (j=0; j<2; j++)
            {
              for (i=0; i<18;i++)  
                cofAC4x4[j][i]=img->cofAC[b8][b4][j][i];
              for (i=0; i<18;i++)  
                cofAC4x4_chroma[0][j][i]=img->cofAC[b8+4][b4][j][i];
              for (i=0; i<18;i++)
                cofAC4x4_chroma[1][j][i]=img->cofAC[b8+8][b4][j][i];
            }
            
            for (i=0; i<2; i++)
            { //uv
              dc_level        [i][2*(b8 & 0x01)+(b4 & 0x01)][2*(b8 >> 1)+(b4 >> 1)] = dc_level_temp        [i][2*(b8 & 0x01)+(b4 & 0x01)][2*(b8 >> 1)+(b4 >> 1)];
              cbp_chroma_block[i][2*(b8 & 0x01)+(b4 & 0x01)][2*(b8 >> 1)+(b4 >> 1)] = cbp_chroma_block_temp[i][2*(b8 & 0x01)+(b4 & 0x01)][2*(b8 >> 1)+(b4 >> 1)];
              //--- set reconstruction ---
              for (y=0; y<BLOCK_SIZE; y++)
              {
                memcpy(rec4x4_c[i][y],&enc_picture->imgUV[i][pic_pix_y+y][pic_pix_x], BLOCK_SIZE * sizeof(imgpel)); 
                if(img->type==SP_SLICE &&(!si_frame_indicator && !sp2_frame_indicator))
                  memcpy(lrec4x4[y],&lrec[pic_pix_y+y][pic_pix_x], BLOCK_SIZE * sizeof(int));//stores the coefficients for the mode
              }
            }
            
            //--- set reconstruction ---
            for (y=0; y<BLOCK_SIZE; y++)
            {
              memcpy(rec4x4[y],&enc_picture->imgY[pic_pix_y+y][pic_pix_x], BLOCK_SIZE * sizeof(imgpel));
              if(img->type==SP_SLICE &&(!si_frame_indicator && !sp2_frame_indicator))
                memcpy(lrec4x4[y],&lrec[pic_pix_y+y][pic_pix_x], BLOCK_SIZE * sizeof(int));
            }
            
            //--- flag if dct-coefficients must be coded ---
            nonzero = c_nz;
            
            //--- set best mode update minimum cost ---
            min_rdcost  = rdcost;
            best_ipmode = ipmode;
#ifdef BEST_NZ_COEFF
            best_nz_coeff = img->nz_coeff [img->current_mb_nr][block_x4][block_y4];
            // yuwen 2005.11.17 => should be an error here, requiring process for img->mb_data[img->current_mb_nr].cbp_bits
#endif
          }
        }
      }
    }
  }
  
#ifdef BEST_NZ_COEFF
  img->nz_coeff [img->current_mb_nr][block_x4][block_y4] = best_nz_coeff;
  cbp_bits &= (~(int64)(1<<bit_pos));
  cbp_bits |= (int64)(best_coded_block_flag<<bit_pos);
#endif
  //===== set intra mode prediction =====
  img->ipredmode[pic_block_y][pic_block_x] = best_ipmode;
  img->mb_data[img->current_mb_nr].intra_pred_modes[4*b8+b4] = mostProbableMode == best_ipmode ? -1 : best_ipmode < mostProbableMode ? best_ipmode : best_ipmode-1;
  
  if (!input->rdopt)
  {
    // Residue Color Transform
    if(!img->residue_transform_flag)
    {
      // get prediction and prediction error
      for (j=0; j<4; j++)
      {
        int jj = pic_opix_y+j;
        for (i=0; i<4; i++)
        {
          img->mpr[block_y+j][block_x+i]  = img->mprr[best_ipmode][j][i];
          img->m7[j][i]                   = imgY_org[jj][pic_opix_x+i] - img->mprr[best_ipmode][j][i];
        }
      }
      nonzero = dct_luma (block_x, block_y, &dummy, 1);
    } 
    else 
    {
      int y_pos = 2*(b8 & 0x01)+(b4 & 0x01);
      int x_pos = 2*(b8 >> 1)+(b4 >> 1);
      for (j=0; j<4; j++)
      {
        for (i=0; i<4; i++)
        {
          residue_B = imgUV_org[0][pic_opix_y+j][pic_opix_x+i] - img->mprr_c[0][c_ipmode][block_y+j][block_x+i];
          residue_G = imgY_org[pic_opix_y+j][pic_opix_x+i] - img->mprr[best_ipmode][j][i];
          residue_R = imgUV_org[1][pic_opix_y+j][pic_opix_x+i] - img->mprr_c[1][c_ipmode][block_y+j][block_x+i];
          
          /* Forward Residue Transform */
          resTrans_R[j][i] = residue_R-residue_B;
          temp = residue_B+(resTrans_R[j][i]>>1);
          resTrans_B[j][i] = residue_G-temp;
          resTrans_G[j][i] = temp+(resTrans_B[j][i]>>1);
        }
      }
      
      for (j=0; j<4; j++)
      {
        for (i=0; i<4; i++)
        {
          img->m7[j][i]  = resTrans_G[j][i];
        }
      }
      nonzero = dct_luma (block_x, block_y, &dummy, 1);
      for (j=0; j<4; j++)
      {
        for (i=0; i<4; i++)
        {
          rec_resG[j][i] = img->m7[j][i];
          img->m7[j][i]  = resTrans_B[j][i];
        }
      }
      cbp_chroma_block[0][y_pos][x_pos] = dct_chroma4x4 (0, b8+4, b4);
      dc_level        [0][y_pos][x_pos] = dc_level_temp[0][y_pos][x_pos];
      for (j=0; j<4; j++)
      {
        for (i=0; i<4; i++)
        {
          rec_resB[j][i] = img->m7[j][i];
          img->m7[j][i]  = resTrans_R[j][i];
        }
      }
      cbp_chroma_block[1][y_pos][x_pos] = dct_chroma4x4 (1, b8+8, b4);
      dc_level        [1][y_pos][x_pos] = dc_level_temp[1][y_pos][x_pos];
      for (j=0; j<4; j++)
      {
        for (i=0; i<4; i++)
        {
          rec_resR[j][i] = img->m7[j][i];
        }
      }
      for (j=0; j<4; j++)
      {
        for (i=0; i<4; i++)
        {
          /* Inverse Residue Transform */
          temp      = rec_resG[j][i]-(rec_resB[j][i]>>1);
          residue_G = rec_resB[j][i]+temp;
          residue_B = temp - (rec_resR[j][i]>>1);
          residue_R = residue_B+rec_resR[j][i];
          enc_picture->imgUV[0][pic_pix_y+j][pic_pix_x+i] = min(img->max_imgpel_value_uv,max(0,residue_B+(int)img->mprr_c[0][c_ipmode][block_y+j][block_x+i]));
          enc_picture->imgY[pic_pix_y+j][pic_pix_x+i]     = min(img->max_imgpel_value,max(0,residue_G+(int)img->mprr[best_ipmode][j][i]));
          enc_picture->imgUV[1][pic_pix_y+j][pic_pix_x+i] = min(img->max_imgpel_value_uv,max(0,residue_R+(int)img->mprr_c[1][c_ipmode][block_y+j][block_x+i]));
        }
      }
    }
  }
  else
  {
    //===== restore coefficients =====
    for (j=0; j<2; j++)
    {
      memcpy (img->cofAC[b8][b4][j],cofAC4x4[j], 18 * sizeof(int));
    } 
    // Residue Color Transform
    if(img->residue_transform_flag)
    {
      for (j=0; j<2; j++)
      {
        memcpy (img->cofAC[b8+4][b4][j],cofAC4x4_chroma[0][j], 18 * sizeof(int));            
        memcpy (img->cofAC[b8+8][b4][j],cofAC4x4_chroma[1][j], 18 * sizeof(int));            
      }
    }
    
    //===== restore reconstruction and prediction (needed if single coeffs are removed) =====
    for (y=0; y<BLOCK_SIZE; y++)
    {
      memcpy (&enc_picture->imgY[pic_pix_y+y][pic_pix_x],rec4x4[y],    BLOCK_SIZE * sizeof(imgpel));
      memcpy (&img->mpr[block_y+y][block_x],img->mprr[best_ipmode][y], BLOCK_SIZE * sizeof(imgpel));
      if(img->type==SP_SLICE &&(!si_frame_indicator && !sp2_frame_indicator))
        memcpy (&lrec[pic_pix_y+y][pic_pix_x],lrec4x4[y], BLOCK_SIZE * sizeof(int));//restore coefficients when encoding primary SP frame
    }
    
    if (img->AdaptiveRounding)
    {
      for (j=0; j<BLOCK_SIZE; j++)
        memcpy (&img->fadjust4x4[1][block_y+j][block_x],&fadjust4x4[block_y+j][block_x], BLOCK_SIZE * sizeof(int));      
    }
    
    // Residue Color Transform
    if(img->residue_transform_flag)
    {
      for (i=0; i<2; i++)
      { //uv
        //--- set reconstruction ---
        for (y=0; y<4; y++)
        {
          memcpy(&enc_picture->imgUV[i][pic_pix_y+y][pic_pix_x],rec4x4_c[i][y], BLOCK_SIZE * sizeof(imgpel));
          if(img->type==SP_SLICE &&(!si_frame_indicator && !sp2_frame_indicator))
            memcpy (&lrec_uv[i][pic_pix_y+y][pic_pix_x],lrec4x4_c[i][y], BLOCK_SIZE * sizeof(int));//restore coefficients for primary SP frame encoding
        }
      }
    }    
  }  
  return nonzero;
}


/*!
 *************************************************************************************
 * \brief
 *    Mode Decision for an 8x8 Intra block
 *************************************************************************************
 */
int Mode_Decision_for_8x8IntraBlocks(int b8,double lambda,int *cost)
{
  int  nonzero=0, b4;
  int  cost4x4;
  
  *cost = (int)floor(6.0 * lambda + 0.4999);
  
  for (b4=0; b4<4; b4++)
  {
    if (Mode_Decision_for_4x4IntraBlocks (b8, b4, lambda, &cost4x4))
    {
      nonzero        = 1;
    }
    *cost += cost4x4;
  }
#ifdef RESET_STATE
  reset_coding_state (cs_cm);
#endif
  
  return nonzero;
}

/*!
 *************************************************************************************
 * \brief
 *    4x4 Intra mode decision for an macroblock
 *************************************************************************************
 */
int Mode_Decision_for_Intra4x4Macroblock (double lambda,  int* cost)
{
  int  cbp=0, b8, cost8x8;
  
  for (*cost=0, b8=0; b8<4; b8++)
  {
    if (Mode_Decision_for_8x8IntraBlocks (b8, lambda, &cost8x8))
    {
      cbp |= (1<<b8);
    }
    *cost += cost8x8;
  }
  
  return cbp;
}


/*!
 *************************************************************************************
 * \brief
 *    R-D Cost for an 8x8 Partition
 *************************************************************************************
 */
double RDCost_for_8x8blocks (int*    cnt_nonz,   // --> number of nonzero coefficients
                             int64*  cbp_blk,    // --> cbp blk
                             double  lambda,     // <-- lagrange multiplier
                             int     block,      // <-- 8x8 block number
                             int     mode,       // <-- partitioning mode
                             short   pdir,       // <-- prediction direction
                             short   ref,        // <-- reference frame
                             short   bwd_ref)    // <-- abp type
{
  int  i, j, k;
  int  rate=0;
  int64 distortion=0;
  int  dummy = 0, mrate;
  int  fw_mode, bw_mode;
  int  cbp     = 0;
  int  pax     = 8*(block & 0x01);
  int  pay     = 8*(block >> 1);
  int  i0      = pax >> 2;
  int  j0      = pay >> 2;
  int  bframe  = (img->type==B_SLICE);
  int  direct  = (bframe && mode==0);
  int  b8value = B8Mode2Value (mode, pdir);
  
  Macroblock    *currMB    = &img->mb_data[img->current_mb_nr];
  SyntaxElement *currSE    = &img->MB_SyntaxElements[currMB->currSEnr];
  Slice         *currSlice = img->currentSlice;
  DataPartition *dataPart;
  const int     *partMap   = assignSE2partition[input->partition_mode];
  
  EncodingEnvironmentPtr eep_dp;
  
  // Residue Color Transform
  int residue_R, residue_G, residue_B, temp, b4;
  int b4_x, b4_y;
  
  //=====
  //=====  GET COEFFICIENTS, RECONSTRUCTIONS, CBP
  //=====
  currMB->bi_pred_me=0;
  
  if (direct)
  {
    if (direct_pdir[img->block_y+j0][img->block_x+i0]<0) // mode not allowed
      return (1e20);
    else
      *cnt_nonz = LumaResidualCoding8x8 (&cbp, cbp_blk, block, direct_pdir[img->block_y+j0][img->block_x+i0], 0, 0, 
                  (short)max(0,direct_ref_idx[LIST_0][img->block_y+j0][img->block_x+i0]), direct_ref_idx[LIST_1][img->block_y+j0][img->block_x+i0]);
  }
  else
  {
    fw_mode   = (pdir==0||pdir==2 ? mode : 0);
    bw_mode   = (pdir==1||pdir==2 ? mode : 0);
    *cnt_nonz = LumaResidualCoding8x8 (&cbp, cbp_blk, block, pdir, fw_mode, bw_mode, ref, bwd_ref);
  }
  
  // Residue Color Transform
  if(img->residue_transform_flag)
  {
    for(b4 = 0; b4 < 4; b4++)
    {
      b4_x = pax+(b4 & 0x01)*4;
      b4_y = pay+(b4 >> 1  )*4;
      for (j=0; j<4; j++)
      {
        for (i=0; i<4; i++)
          img->m7[j][i] = resTrans_B[j+b4_y][i+b4_x];
      }
      rate += RDCost_for_4x4Blocks_Chroma (block+4, b4, 0);
      
      for (j=0; j<4; j++)
      {
        for (i=0; i<4; i++)
        {
          rec_resB[j+b4_y][i+b4_x] = img->m7[j][i];
          img->m7[j][i]  = resTrans_R[j+b4_y][i+b4_x];
        }
      }
      rate += RDCost_for_4x4Blocks_Chroma (block+8, b4, 1);
      
      for (j=0; j<4; j++)
      {
        for (i=0; i<4; i++)
        {
          rec_resR[j+b4_y][i+b4_x] = img->m7[j][i];
        }
      }
    }
    reset_coding_state (cs_cm);  
    /* Inverse Residue Transform */
    for (j=pay; j<pay+8; j++)
      for (i=pax; i<pax+8; i++)
      {
        /* YCoCg-R */
        temp      = rec_resG[j][i]-(rec_resB[j][i]>>1);
        residue_G = rec_resB[j][i]+temp;
        residue_B = temp - (rec_resR[j][i]>>1);
        residue_R = residue_B+rec_resR[j][i];
        
        enc_picture->imgUV[0][img->pix_y+j][img->pix_x+i] = min(img->max_imgpel_value_uv,max(0,residue_B+mprRGB[1][j][i]));
        enc_picture->imgY[img->pix_y+j][img->pix_x+i]     = min(img->max_imgpel_value,max(0,residue_G+mprRGB[0][j][i]));
        enc_picture->imgUV[1][img->pix_y+j][img->pix_x+i] = min(img->max_imgpel_value_uv,max(0,residue_R+mprRGB[2][j][i]));
      }
  }
  
  //===== get residue =====
  if (input->rdopt==3 && img->type!=B_SLICE)
  {
    // We need the reconstructed prediction residue for the simulated decoders.
    compute_residue_b8block (block, -1);
  }
  
  //=====
  //=====   GET DISTORTION
  //=====
  if (input->rdopt==3 && img->type!=B_SLICE)
  {
    for (k=0; k<input->NoOfDecoders ;k++)

⌨️ 快捷键说明

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