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

📄 rdopt.c

📁 h.264 影像壓縮 必須在 .net 的環境 下操作
💻 C
📖 第 1 页 / 共 5 页
字号:
              ipmode_DPCM=ipmode;
            }
          }
          else if ((img->yuv_format == YUV444) && IS_INDEPENDENT(input))
          {
            if((lossless_qpprime)&&(ipmode<2))  
            {
              Residual_DPCM_4x4(ipmode, 0, block_y, block_x);
              ipmode_DPCM=ipmode;
            }
          }

        //===== store the coding state =====
        //store_coding_state (currMB, cs_cm);
        // get and check rate-distortion cost
#ifdef BEST_NZ_COEFF
        currMB->cbp_bits[0] = cbp_bits;
#endif
        if ((rdcost = RDCost_for_4x4IntraBlocks (currMB, &c_nz, b8, b4, ipmode, lambda, mostProbableMode, c_nzCbCr)) < min_rdcost)
        {
          //--- set coefficients ---
          memcpy(cofAC4x4[0],ACLevel, 18 * sizeof(int));
          memcpy(cofAC4x4[1],ACRun, 18 * sizeof(int));

          //--- set reconstruction ---
          for (y=0; y<4; y++)
          {
            memcpy(rec4x4[y],&enc_picture->imgY[pic_pix_y+y][pic_pix_x], BLOCK_SIZE * sizeof(imgpel));
          }

          // SP/SI reconstruction
          if(img->type==SP_SLICE &&(!si_frame_indicator && !sp2_frame_indicator))
          {
            for (y=0; y<4; y++)
            {
              memcpy(lrec4x4[y],&lrec[pic_pix_y+y][pic_pix_x], BLOCK_SIZE * sizeof(int));// stores the mode coefficients
            }
          }
            if( img->yuv_format==YUV444 && !IS_INDEPENDENT(input) ) 
            { 
              //--- set coefficients ---
              for (uv=0; uv < 2; uv++)
              {
                memcpy(cofAC4x4CbCr[uv][0],img->cofAC[b8+4+uv*4][b4][0], 18 * sizeof(int));
                memcpy(cofAC4x4CbCr[uv][1],img->cofAC[b8+4+uv*4][b4][1], 18 * sizeof(int));
                cr_cbp[uv + 1] = c_nzCbCr[uv + 1];

                //--- set reconstruction ---
                for (y=0; y<4; y++)
                {
                  memcpy(rec4x4CbCr[uv][y],&enc_picture->imgUV[uv][pic_pix_y+y][pic_pix_x], BLOCK_SIZE * sizeof(imgpel));
                } 
              }
            }
          //--- flag if dct-coefficients must be coded ---
          nonzero = c_nz;

          //--- set best mode update minimum cost ---
          *min_cost     = rdcost;
          min_rdcost    = rdcost;
          best_ipmode   = ipmode;
#ifdef BEST_NZ_COEFF
          best_nz_coeff = img->nz_coeff [img->current_mb_nr][block_x4][block_y4];
          best_coded_block_flag = (int)((currMB->cbp_bits[0] >> bit_pos)&(int64)(1));
#endif
          //store_coding_state (currMB, cs_ib4);
          if (img->AdaptiveRounding)
          {
            for (j = block_y; j < block_y + 4; j++)
              memcpy(&fadjust4x4[j][block_x],&img->fadjust4x4[1][j][block_x], BLOCK_SIZE * sizeof(int));
              if(img->yuv_format == YUV444 && !IS_INDEPENDENT(input))
              {
                for (j=0; j<4; j++)
                {
                  memcpy(&fadjust4x4Cr[0][block_y+j][block_x],&img->fadjust4x4Cr[0][1][block_y+j][block_x], BLOCK_SIZE * sizeof(int));
                  memcpy(&fadjust4x4Cr[1][block_y+j][block_x],&img->fadjust4x4Cr[1][1][block_y+j][block_x], BLOCK_SIZE * sizeof(int));
                }
              }
          }
        }

#ifndef RESET_STATE
        reset_coding_state (currMB, cs_cm);
#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] = (char) best_ipmode;
  currMB->intra_pred_modes[4*b8+b4] =
    (char) (mostProbableMode == best_ipmode ? -1 : (best_ipmode < mostProbableMode ? best_ipmode : best_ipmode-1));

  if (!input->rdopt)
  {
    // get prediction and prediction error
    for (j=0; j < BLOCK_SIZE; j++)
    {
      m7 = &img->m7[0][block_y+j][block_x];
      org_img = &pCurImg[pic_opix_y+j][pic_opix_x];
      prd_img = img->mpr_4x4[0][best_ipmode][j];      
      memcpy(&curr_mpr[block_y+j][block_x], prd_img, BLOCK_SIZE * sizeof(imgpel));
      for (i=0; i<BLOCK_SIZE; i++)
      {
        m7[i] = org_img[i] - prd_img[i];
      }
    }

    if(lossless_qpprime)   //For residual DPCM
    {
      ipmode_DPCM=best_ipmode;  
      if((best_ipmode<2))
      {
        Residual_DPCM_4x4(best_ipmode, 0, block_y, block_x);
      }
    }

    select_dct(currMB);
    nonzero = pDCT_4x4 (currMB, PLANE_Y, block_x, block_y, &dummy, 1);

    if ((img->yuv_format == YUV444) && !IS_INDEPENDENT(input))
    {
      ColorPlane k;
      for (k = PLANE_U; k <= PLANE_V; k++)
      {
        select_plane(k);
        for (j=0; j<4; j++)
        {
          for (i=0; i<4; i++)
          {
            img->mpr[k][block_y+j][block_x+i]  = img->mpr_4x4[k][best_ipmode][j][i];    
            img->m7[k][block_y+j][block_x+i]   = pImgOrg[k][pic_opix_y+j][pic_opix_x+i] - img->mpr_4x4[k][best_ipmode][j][i]; 
          }
        }

        if(lossless_qpprime)   //For residual DPCM
        { 
          if((best_ipmode<2))
          {
            Residual_DPCM_4x4(best_ipmode, k, block_y, block_x);
          }
        }

        cr_cbp[k] = pDCT_4x4(currMB, k, block_x,block_y,&dummy,1);
      }
      select_plane(PLANE_Y);
    }
  }
  else
  {
    if( (img->yuv_format==YUV444) && !IS_INDEPENDENT(input) )
    {
      select_plane(PLANE_U);
      for (j=0; j<4; j++)
      {
        for (i=0; i<4; i++)
        {
          img->mpr[1][block_y+j][block_x+i]  = img->mpr_4x4[1][best_ipmode][j][i];
          img->m7[1][block_y+j][block_x+i]   = imgUV_org[0][img->pix_y+block_y+j][img->pix_x+block_x+i] - img->mpr_4x4[1][best_ipmode][j][i];
        }
      }
      cr_cbp[1] = pDCT_4x4(currMB, PLANE_U, block_x,block_y,&dummy,1);
      select_plane(PLANE_V);
      for (j=0; j<4; j++)
      {
        for (i=0; i<4; i++)
        {
          img->mpr[2][block_y+j][block_x+i]  = img->mpr_4x4[2][best_ipmode][j][i];
          img->m7[2][block_y+j][block_x+i]   = imgUV_org[1][img->pix_y+block_y+j][img->pix_x+block_x+i] - img->mpr_4x4[2][best_ipmode][j][i];
        }
      }
      cr_cbp[2]  = pDCT_4x4(currMB, PLANE_V,block_x,block_y,&dummy,1);
      select_plane(PLANE_Y);
    }
    //===== restore coefficients =====
    memcpy (ACLevel,cofAC4x4[0], 18 * sizeof(int));
    memcpy (ACRun,cofAC4x4[1], 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 (&curr_mpr[block_y + y][block_x],img->mpr_4x4[0][best_ipmode][y], BLOCK_SIZE * sizeof(imgpel));
    }
    
    // SP/SI reconstuction
    if(img->type==SP_SLICE &&(!si_frame_indicator && !sp2_frame_indicator))
    {
      for (y=0; y<BLOCK_SIZE; y++)
      {
        memcpy (&lrec[pic_pix_y+y][pic_pix_x],lrec4x4[y], BLOCK_SIZE * sizeof(int));//restore coefficients when encoding primary SP frame
      }
    }
    if( img->yuv_format == YUV444 && !IS_INDEPENDENT(input) ) 
    {
      for (uv=0; uv < 2; uv++ )
      {
        //===== restore coefficients =====
        memcpy(img->cofAC[b8+4+uv*4][b4][0], cofAC4x4CbCr[uv][0], 18 * sizeof(int));
        memcpy(img->cofAC[b8+4+uv*4][b4][1], cofAC4x4CbCr[uv][1], 18 * sizeof(int));
        //===== restore reconstruction and prediction (needed if single coeffs are removed) =====
        for (y=0; y<BLOCK_SIZE; y++)
        {
          memcpy(&enc_picture->imgUV[uv][pic_pix_y+y][pic_pix_x],rec4x4CbCr[uv][y], BLOCK_SIZE * sizeof(imgpel));
          memcpy(&img->mpr[uv + 1][block_y+y][block_x], img->mpr_4x4[uv + 1][best_ipmode][y], BLOCK_SIZE * sizeof(imgpel));
        } 
      }
    }

    if (img->AdaptiveRounding)
    {
      for (j=block_y; j<block_y + BLOCK_SIZE; j++)
        memcpy (&img->fadjust4x4[1][j][block_x],&fadjust4x4[j][block_x], BLOCK_SIZE * sizeof(int));
      if (img->yuv_format == YUV444 && !IS_INDEPENDENT(input))
      {
        for (j=0; j<BLOCK_SIZE; j++)
        {
          memcpy (&img->fadjust4x4Cr[0][1][block_y+j][block_x],&fadjust4x4Cr[0][block_y+j][block_x], BLOCK_SIZE * sizeof(int));
          memcpy (&img->fadjust4x4Cr[1][1][block_y+j][block_x],&fadjust4x4Cr[1][block_y+j][block_x], BLOCK_SIZE * sizeof(int));
        }
      }
    }
   
  }  

  return nonzero;
}


/*!
 *************************************************************************************
 * \brief
 *    Mode Decision for an 8x8 Intra block
 *************************************************************************************
 */
int Mode_Decision_for_8x8IntraBlocks(Macroblock *currMB, int b8,double lambda,double *cost, int non_zero[2])
{
  int  nonzero = 0, b4;
  double  cost4x4;
  int CbCr_cbp[3]={0, 0, 0};
  non_zero[0] = 0;
  non_zero[1] = 0;

  *cost = (int)floor(6.0 * lambda + 0.4999);

  for (b4=0; b4<4; b4++)
  {
    if (Mode_Decision_for_4x4IntraBlocks (currMB, b8, b4, lambda, &cost4x4, CbCr_cbp))
    {
      nonzero = 1;
    }
    *cost += cost4x4;

    non_zero[0] = (CbCr_cbp[1] != 0);
    non_zero[1] = (CbCr_cbp[2] != 0);
  }
#ifdef RESET_STATE
  //reset_coding_state (currMB, cs_cm);
#endif

  return nonzero;
}

/*!
 *************************************************************************************
 * \brief
 *    4x4 Intra mode decision for an macroblock
 *************************************************************************************
 */
int Mode_Decision_for_Intra4x4Macroblock (Macroblock *currMB, double lambda,  double* cost)
{
  int  cbp=0, b8;
  double cost8x8;
  int non_zero[2] = {0, 0};
  
  cmp_cbp[1] = cmp_cbp[2] = 0;

  for (*cost=0, b8=0; b8<4; b8++)
  {
    if (Mode_Decision_for_8x8IntraBlocks (currMB, b8, lambda, &cost8x8, non_zero))
    {
      cbp |= (1<<b8);
    }
    *cost += cost8x8;
    if (non_zero[0])
    {
      cmp_cbp[1] |= (1<<b8);
      cbp |= cmp_cbp[1];
      cmp_cbp[1] = cbp;
      cmp_cbp[2] = cbp;
    }
    if (non_zero[1])
    {
      cmp_cbp[2] |= (1<<b8);
      cbp |= cmp_cbp[2];
      cmp_cbp[1] = cbp;
      cmp_cbp[2] = cbp;
    }
  }
  return cbp;
}


/*!
 *************************************************************************************
 * \brief
 *    R-D Cost for an 8x8 Partition
 *************************************************************************************
 */
double RDCost_for_8x8blocks (Macroblock *currMB, // --> Current macroblock to code
                             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   l0_ref,     // <-- L0 reference picture
                             short   l1_ref)     // <-- L1 reference picture
{
  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);

  SyntaxElement se;
  Slice         *currSlice = img->currentSlice;
  DataPartition *dataPart;
  const int     *partMap   = assignSE2partition[input->partition_mode];
  imgpel *img_enc, *img_org;

  EncodingEnvironmentPtr eep_dp;

  //=====
  //=====  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 (currMB, &cbp, cbp_blk, block, direct_pdir[img->block_y+j0][img->block_x+i0], 0, 0,
      (short)imax(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
  {
    if (pdir == 2 && active_pps->weighted_bipred_idc == 1)
    {
      int weight_sum = (active_pps->weighted_bipred_idc == 1)? wbp_weight[0][l0_ref][l1_ref][0] + wbp_weight[1][l0_ref][l1_ref][0] : 0;
      if (weight_sum < -128 ||  weight_sum > 127)
      {
        return (1e20);
      }
    }

    fw_mode   = (pdir==0||pdir==2 ? mode : 0);
    bw_mode   = (pdir==1||pdir==2 ? mode : 0);
    *cnt_nonz = LumaResidualCoding8x8 (currMB, &cbp, cbp_blk, block, pdir, fw_mode, bw_mode, l0_ref, l1_ref);
  }

  if( img->yuv_format==YUV444 && !IS_INDEPENDENT(input) ) 
  {
    *cnt_nonz += ( coeff_cost_cr[1] + coeff_cost_cr[2] );
  }
  //===== 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 + -