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

📄 rdopt.c

📁 压缩JM12.3d的完整的全部C语言的代码文档,用于嵌入式系统的压缩编解码
💻 C
📖 第 1 页 / 共 5 页
字号:
        }
        else
        {
          for (y = y_pos ; y < y_pos + BLOCK_SIZE ; y++)
          {
            for (x = x_pos ; x < x_pos + BLOCK_SIZE ; x++)
            {
              pres_y = dy == 1 ? y : y + 1;
              pres_y = iClip3(0,maxold_y,pres_y);

              for(xx=-2;xx<4;xx++)
              {
                pres_x = iClip3(0,maxold_x,xx + x);
                if (pixel_map[pres_y][pres_x] < ref_frame)
                  return 0;
              }

              pres_x = dx == 1 ? x : x + 1;
              pres_x = iClip3(0,maxold_x,pres_x);

              for(yy=-2;yy<4;yy++)
              {
                pres_y = iClip3(0,maxold_y, yy + y);
                if (pixel_map[pres_y][pres_x] < ref_frame)
                  return 0;
              }
            }
          }
        }
      }
    }
  }
  return 1;
}



/*!
 *************************************************************************************
 * \brief
 *    R-D Cost for an 4x4 Intra block
 *************************************************************************************
 */
double RDCost_for_4x4IntraBlocks (int*    nonzero,
                                  int     b8,
                                  int     b4,
                                  int     ipmode,
                                  double  lambda,
                                  double  min_rdcost,
                                  int mostProbableMode)
{
  double  rdcost;
  int     dummy, x, y, rate;
  int64   distortion  = 0;
  int     block_x     = 8*(b8 & 0x01)+4*(b4 & 0x01);
  int     block_y     = 8*(b8 >> 1)+4*(b4 >> 1);
  int     pic_pix_x   = img->pix_x+block_x;
  int     pic_pix_y   = img->pix_y+block_y;
  int     pic_opix_y  = img->opix_y+block_y;
  imgpel  **imgY      = enc_picture->imgY;

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

  //===== perform DCT, Q, IQ, IDCT, Reconstruction =====
  dummy = 0;

  if(img->type!=SP_SLICE)
    *nonzero = dct_luma (block_x, block_y, &dummy, 1);
  else if(!si_frame_indicator && !sp2_frame_indicator)
  {
    *nonzero = dct_luma_sp(block_x, block_y, &dummy);
  }
  else
  {
    *nonzero = dct_luma_sp2(block_x, block_y, &dummy);
  }

  //===== get distortion (SSD) of 4x4 block =====
  for (y=0; y<4; y++)
  {
    for (x=pic_pix_x; x<pic_pix_x+4; x++)
    {
      distortion += iabs2( imgY_org[pic_opix_y+y][x] - imgY[pic_pix_y+y][x] );
    }
  }

  //===== RATE for INTRA PREDICTION MODE  (SYMBOL MODE MUST BE SET TO UVLC) =====
  se.value1 = (mostProbableMode == ipmode) ? -1 : ipmode < mostProbableMode ? ipmode : ipmode-1;

  //--- set position and type ---
  se.context = 4*b8 + b4;
  se.type    = SE_INTRAPREDMODE;

  //--- choose data partition ---
  dataPart = &(currSlice->partArr[partMap[SE_INTRAPREDMODE]]);
  //--- encode and update rate ---
  writeIntraPredMode (&se, dataPart);
  rate = se.len;

  //===== RATE for LUMINANCE COEFFICIENTS =====
  if (input->symbol_mode == UVLC)
  {
    rate  += writeCoeff4x4_CAVLC (LUMA, b8, b4, 0);
  }
  else
  {
    rate  += writeLumaCoeff4x4_CABAC (b8, b4, 1);
  }
  //reset_coding_state (cs_cm);
  rdcost = (double)distortion + lambda*(double)rate;

  return rdcost;
}


/*!
 *************************************************************************************
 * \brief
 *    Mode Decision for an 4x4 Intra block
 *************************************************************************************
 */
int Mode_Decision_for_4x4IntraBlocks (int  b8,  int  b4,  double  lambda,  int*  min_cost)
{
  int     ipmode, best_ipmode = 0, i, j, k, y, cost, dummy;
  int     c_nz, nonzero = 0;
  imgpel  rec4x4[4][4];
  double  rdcost;
  int     block_x     = 8 * (b8 & 0x01) + 4 * (b4 & 0x01);
  int     block_y     = 8 * (b8 >> 1)   + 4 * (b4 >> 1);
  int     pic_pix_x   = img->pix_x  + block_x;
  int     pic_pix_y   = img->pix_y  + block_y;
  int     pic_opix_x  = img->opix_x + block_x;
  int     pic_opix_y  = img->opix_y + block_y;
  int     pic_block_x = pic_pix_x >> 2;
  int     pic_block_y = pic_pix_y >> 2;
  double  min_rdcost  = 1e30;

  int left_available, up_available, all_available;

  char   upMode;
  char   leftMode;
  int     mostProbableMode;

  PixelPos left_block;
  PixelPos top_block;

  int  lrec4x4[4][4];
  int  fixedcost = (int) floor(4 * lambda );

#ifdef BEST_NZ_COEFF
  int best_nz_coeff = 0;
  int best_coded_block_flag = 0;
  int bit_pos = 1 + ((((b8>>1)<<1)+(b4>>1))<<2) + (((b8&1)<<1)+(b4&1));
  static int64 cbp_bits;

  if (b8==0 && b4==0)
   cbp_bits = 0;
#endif

  getLuma4x4Neighbour(img->current_mb_nr, block_x - 1, block_y,   &left_block);
  getLuma4x4Neighbour(img->current_mb_nr, block_x,     block_y-1, &top_block);

  // constrained intra pred
  if (input->UseConstrainedIntraPred)
  {
    left_block.available = left_block.available ? img->intra_block[left_block.mb_addr] : 0;
    top_block.available  = top_block.available  ? img->intra_block[top_block.mb_addr]  : 0;
  }

  upMode            =  top_block.available ? img->ipredmode[top_block.pos_y ][top_block.pos_x ] : -1;
  leftMode          = left_block.available ? img->ipredmode[left_block.pos_y][left_block.pos_x] : -1;

  mostProbableMode  = (upMode < 0 || leftMode < 0) ? DC_PRED : upMode < leftMode ? upMode : leftMode;

  *min_cost = INT_MAX;

  //===== INTRA PREDICTION FOR 4x4 BLOCK =====
  intrapred_luma (pic_pix_x, pic_pix_y, &left_available, &up_available, &all_available);

  //===== LOOP OVER ALL 4x4 INTRA PREDICTION MODES =====
  for (ipmode=0; ipmode<NO_INTRA_PMODE; ipmode++)
  {
    int available_mode =  (ipmode==DC_PRED) ||
      ((ipmode==VERT_PRED||ipmode==VERT_LEFT_PRED||ipmode==DIAG_DOWN_LEFT_PRED) && up_available ) ||
      ((ipmode==HOR_PRED||ipmode==HOR_UP_PRED) && left_available ) ||(all_available);

    if (input->IntraDisableInterOnly==0 || img->type != I_SLICE)
    {
      if (input->Intra4x4ParDisable && (ipmode==VERT_PRED||ipmode==HOR_PRED))
        continue;

      if (input->Intra4x4DiagDisable && (ipmode==DIAG_DOWN_LEFT_PRED||ipmode==DIAG_DOWN_RIGHT_PRED))
        continue;

      if (input->Intra4x4DirDisable && ipmode>=VERT_RIGHT_PRED)
        continue;
    }

    if( available_mode)
    {
      if (!input->rdopt)
      {
        for (k=j=0; j<4; j++)
        {
          int jj = pic_opix_y+j;
          for (i=0; i<4; i++, k++)
          {
            diff[k] = imgY_org[jj][pic_opix_x+i] - img->mprr[ipmode][j][i];
          }
        }
        cost  = (ipmode == mostProbableMode) ? 0 : fixedcost;
        cost += distortion4x4 (diff);
        if (cost < *min_cost)
        {
          best_ipmode = ipmode;
          *min_cost   = cost;
        }
      }
      else
      {
        // get prediction and prediction error
        for (j=0; j<4; j++)
        {
          memcpy(&img->mpr[block_y+j][block_x], img->mprr[ipmode][j], BLOCK_SIZE * sizeof(imgpel));
          for (i=0; i<4; i++)
          {
            img->m7[j][i] = (int) (imgY_org[pic_opix_y+j][pic_opix_x+i] - img->mprr[ipmode][j][i]);
          }
        }

        //===== store the coding state =====
        //store_coding_state (cs_cm);
        // get and check rate-distortion cost
#ifdef BEST_NZ_COEFF
        img->mb_data[img->current_mb_nr].cbp_bits = cbp_bits;
#endif
        if ((rdcost = RDCost_for_4x4IntraBlocks (&c_nz, b8, b4, ipmode, lambda, min_rdcost, mostProbableMode)) < min_rdcost)
        {
          //--- set coefficients ---
          memcpy(cofAC4x4[0],img->cofAC[b8][b4][0], 18 * sizeof(int));
          memcpy(cofAC4x4[1],img->cofAC[b8][b4][1], 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));
            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 mode coefficients
          }
          //--- 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];
          best_coded_block_flag = (int)((img->mb_data[img->current_mb_nr].cbp_bits>>bit_pos)&(int64)(1));
#endif
          //store_coding_state (cs_ib4);
          if (img->AdaptiveRounding)
          {
            for (j=0; j<4; j++)
              memcpy(&fadjust4x4[block_y+j][block_x],&img->fadjust4x4[1][block_y+j][block_x], BLOCK_SIZE * sizeof(int));
          }
        }

#ifndef RESET_STATE
        reset_coding_state (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;
  img->mb_data[img->current_mb_nr].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<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
  {
    //===== restore coefficients =====
    for (j=0; j<2; j++)
    {
      memcpy (img->cofAC[b8][b4][j],cofAC4x4[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));
    }

  }
  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   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);

  Macroblock    *currMB    = &img->mb_data[img->current_mb_nr];

⌨️ 快捷键说明

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