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

📄 me_epzs.c

📁 H.264编码实现
💻 C
📖 第 1 页 / 共 5 页
字号:
  else // if (mode == 0)
  {
    for (pos = RoundLog2 (search_range) - 2; pos > -1; pos--)
    {
      searchpos = ((search_range << search_range_qpel) >> pos);
      fieldsearchpos = ((3 * searchpos + 1) << search_range_qpel) >> 1;

      for (i=1; i>=-1; i-=2)
      {
        predictor->point[prednum  ].motion.mv_x =  i * searchpos;
        predictor->point[prednum++].motion.mv_y =  0;
        predictor->point[prednum  ].motion.mv_x =  i * searchpos;
        predictor->point[prednum++].motion.mv_y =  i * searchpos;
        predictor->point[prednum  ].motion.mv_x =  0;
        predictor->point[prednum++].motion.mv_y =  i * searchpos;
        predictor->point[prednum  ].motion.mv_x = -i * searchpos;
        predictor->point[prednum++].motion.mv_y =  i * searchpos;
      }

      for (i=1; i>=-1; i-=2)
      {
        predictor->point[prednum  ].motion.mv_x =  i * fieldsearchpos;
        predictor->point[prednum++].motion.mv_y = -i * searchpos;
        predictor->point[prednum  ].motion.mv_x =  i * fieldsearchpos;
        predictor->point[prednum++].motion.mv_y =  0;
        predictor->point[prednum  ].motion.mv_x =  i * fieldsearchpos;
        predictor->point[prednum++].motion.mv_y =  i * searchpos;
        predictor->point[prednum  ].motion.mv_x =  i * searchpos;
        predictor->point[prednum++].motion.mv_y =  i * fieldsearchpos;
        predictor->point[prednum  ].motion.mv_x =  0;
        predictor->point[prednum++].motion.mv_y =  i * fieldsearchpos;
        predictor->point[prednum  ].motion.mv_x = -i * searchpos;
        predictor->point[prednum++].motion.mv_y =  i * fieldsearchpos;
      }
    }
  }
  predictor->searchPoints = prednum;
}

/*!
************************************************************************
* \brief
*    EPZS Global Initialization
************************************************************************
*/
int EPZSInit (InputParameters *params, ImageParameters *img)
{
  int pel_error_me = 1 << (img->bitdepth_luma - 8);
  int pel_error_me_cr = 1 << (img->bitdepth_chroma - 8);
  int i, memory_size = 0;
  double chroma_weight = params->ChromaMEEnable ? pel_error_me_cr * params->ChromaMEWeight * (double) (img->width_cr * img->height_cr) / (double) (img->width * img->height) : 0;
  int searchlevels = RoundLog2 (params->search_range) - 1;
  
  searcharray = params->BiPredMotionEstimation? (2 * imax (params->search_range, params->BiPredMESearchRange) + 1) << (params->EPZSGrid) : (2 * params->search_range + 1)<< (params->EPZSGrid);

  mv_rescale = params->EPZSSubPelGrid ? 0 : 2;
  
  //! In this implementation we keep threshold limits fixed.
  //! However one could adapt these limits based on lagrangian
  //! optimization considerations (i.e. qp), while also allow
  //! adaptation of the limits themselves based on content or complexity.
  for (i=0;i<8;i++)
  {
    medthres[i] = params->EPZSMedThresScale * (medthres_base[i] * pel_error_me + (int) (medthres_base[i] * chroma_weight + 0.5));
    maxthres[i] = params->EPZSMaxThresScale * (maxthres_base[i] * pel_error_me + (int) (maxthres_base[i] * chroma_weight + 0.5));
    minthres[i] = params->EPZSMinThresScale * (minthres_base[i] * pel_error_me + (int) (minthres_base[i] * chroma_weight + 0.5));
    subthres[i] = params->EPZSSubPelThresScale * (medthres_base[i] * pel_error_me + (int) (medthres_base[i] * chroma_weight + 0.5));
  }

  //! Definition of pottential EPZS patterns.
  //! It is possible to also define other patterns, or even use
  //! resizing patterns (such as the PMVFAST scheme. These patterns
  //! are only shown here as reference, while the same also holds
  //! for this implementation (i.e. new conditions could be added
  //! on adapting predictors, or thresholds etc. Note that search
  //! could also be performed on subpel positions directly while
  //! pattern needs not be restricted on integer positions only.

  //! Allocate memory and assign search patterns
  sdiamond = allocEPZSpattern(4);
  assignEPZSpattern(sdiamond, SDIAMOND, TRUE, TRUE, sdiamond);
  square = allocEPZSpattern(8);
  assignEPZSpattern(square, SQUARE, TRUE, TRUE, square);
  ediamond = allocEPZSpattern(12);
  assignEPZSpattern(ediamond, EDIAMOND, TRUE, TRUE, ediamond);
  ldiamond = allocEPZSpattern(8);
  assignEPZSpattern(ldiamond, LDIAMOND, TRUE, TRUE, ldiamond);
  sbdiamond = allocEPZSpattern(12);
  assignEPZSpattern(sbdiamond, SBDIAMOND, FALSE, TRUE, sdiamond);
  pmvfast = allocEPZSpattern(8);
  assignEPZSpattern(pmvfast, LDIAMOND, FALSE, TRUE, sdiamond);

  //! Allocate and assign window based predictors.
  //! Other window types could also be used, while method could be
  //! made a bit more adaptive (i.e. patterns could be assigned
  //! based on neighborhood
  window_predictor = allocEPZSpattern(searchlevels * 8);
  window_predictor_extended = allocEPZSpattern(searchlevels * 20);
  EPZSWindowPredictorInit ((short) params->search_range, window_predictor, 0);
  EPZSWindowPredictorInit ((short) params->search_range, window_predictor_extended, 1);
  //! Also assing search predictor memory
  // maxwindow + spatial + blocktype + temporal + memspatial
  predictor = allocEPZSpattern(searchlevels * 20 + 5 + 5 + 9 * (params->EPZSTemporal) + 3 * (params->EPZSSpatialMem));

  //! Finally assign memory for all other elements
  //! (distortion, EPZSMap, and temporal predictors)

  //memory_size += get_offset_mem2Dshort(&EPZSMap, searcharray, searcharray, (searcharray>>1), (searcharray>>1));
  memory_size += get_mem3Dint (&EPZSDistortion, 6, 7, img->width/BLOCK_SIZE);
  if (params->BiPredMotionEstimation)
    memory_size += get_mem3Dint (&EPZSBiDistortion, 6, 7, img->width/BLOCK_SIZE);
  memory_size += get_mem2Dshort (&EPZSMap, searcharray, searcharray );

  if (params->EPZSSpatialMem)
  {
#if EPZSREF
    memory_size += get_mem5Dmv (&EPZS_Motion, 6, img->max_num_references, 7, 4, img->width/BLOCK_SIZE);
    memory_size += get_mem6Dshort (&EPZSMotion, 6, img->max_num_references, 7, 4, img->width/BLOCK_SIZE, 2);
#else
    memory_size += get_mem4Dmv (&EPZS_Motion, 6, 7, 4, img->width/BLOCK_SIZE);
    memory_size += get_mem5Dshort (&EPZSMotion, 6, 7, 4, img->width/BLOCK_SIZE, 2);
#endif
  }

  if (params->EPZSTemporal)
    EPZSCo_located = allocEPZScolocated (img->width, img->height, active_sps->mb_adaptive_frame_field_flag);

  switch (params->EPZSPattern)
  {
  case 5:
    searchPattern = pmvfast;
    break;
  case 4:
    searchPattern = sbdiamond;
    break;
  case 3:
    searchPattern = ldiamond;
    break;
  case 2:
    searchPattern = ediamond;
    break;
  case 1:
    searchPattern = square;
    break;
  case 0:
  default:
    searchPattern = sdiamond;
    break;
  }

  switch (params->EPZSDual)
  {
  case 6:
    searchPatternD = pmvfast;
    break;
  case 5:
    searchPatternD = sbdiamond;
    break;
  case 4:
    searchPatternD = ldiamond;
    break;
  case 3:
    searchPatternD = ediamond;
    break;
  case 2:
    searchPatternD = square;
    break;
  case 1:
  default:
    searchPatternD = sdiamond;
    break;
  }

  return memory_size;
}

/*!
************************************************************************
* \brief
*    Delete EPZS Alocated memory
************************************************************************
*/
void EPZSDelete (InputParameters *params)
{
  if (params->EPZSTemporal)
    freeEPZScolocated (EPZSCo_located);

  //free_offset_mem2Dshort(EPZSMap, searcharray, (searcharray>>1), (searcharray>>1));
  free_mem2Dshort(EPZSMap);
  free_mem3Dint  (EPZSDistortion);
  if (params->BiPredMotionEstimation)
    free_mem3Dint  (EPZSBiDistortion);
  freeEPZSpattern(window_predictor_extended);
  freeEPZSpattern(window_predictor);
  freeEPZSpattern(predictor);
  // Free search patterns
  freeEPZSpattern(pmvfast);
  freeEPZSpattern(sbdiamond);
  freeEPZSpattern(ldiamond);
  freeEPZSpattern(ediamond);
  freeEPZSpattern(sdiamond);
  freeEPZSpattern(square);
  if (params->EPZSSpatialMem)
  {
#if EPZSREF
    free_mem5Dmv (EPZS_Motion);
    free_mem6Dshort (EPZSMotion);
#else
    free_mem4Dmv (EPZS_Motion);
    free_mem5Dshort (EPZSMotion);
#endif
  }

}

//! For ME purposes restricting the co-located partition is not necessary.
/*!
************************************************************************
* \brief
*    EPZS Slice Level Initialization
************************************************************************
*/
void EPZSSliceInit (InputParameters *params, ImageParameters *img, EPZSColocParams * p, StorablePicture ** listX[6])
{
  StorablePicture *fs, *fs_top, *fs_bottom;
  StorablePicture *fs1, *fs_top1, *fs_bottom1, *fsx;
  int i, j, k, jj, jdiv, loffset;
  int prescale, iTRb, iTRp;
  int list = img->type == B_SLICE ? LIST_1 : LIST_0;
  int tempmv_scale[2];
  int epzs_scale[2][6][MAX_LIST_SIZE];
  int iref;
  int invmv_precision = 8;

  // Lets compute scaling factoes between all references in lists.
  // Needed to scale spatial predictors.
  for (j = LIST_0; j < 2 + (img->MbaffFrameFlag * 4); j ++)
  {
    for (k = 0; k < listXsize[j]; k++)
    {
      for (i = 0; i < listXsize[j]; i++)
      {
        if ((j >> 1) == 0)
        {
          iTRb = iClip3 (-128, 127, enc_picture->poc - listX[j][i]->poc);
          iTRp = iClip3 (-128, 127, enc_picture->poc - listX[j][k]->poc);
        }
        else if ((j >> 1) == 1)
        {
          iTRb = iClip3 (-128, 127, enc_picture->top_poc - listX[j][i]->poc);
          iTRp = iClip3 (-128, 127, enc_picture->top_poc - listX[j][k]->poc);
        }
        else
        {
          iTRb = iClip3 (-128, 127, enc_picture->bottom_poc - listX[j][i]->poc);
          iTRp = iClip3 (-128, 127, enc_picture->bottom_poc - listX[j][k]->poc);
        }

        if (iTRp != 0)
        {
          prescale = (16384 + iabs (iTRp / 2)) / iTRp;
          mv_scale[j][i][k] = iClip3 (-2048, 2047, rshift_rnd_sf((iTRb * prescale), 6));
        }
        else
          mv_scale[j][i][k] = 256;
      }
    }
  }

  if (params->EPZSTemporal)
  {
    fs_top = fs_bottom = fs = listX[list][0];
    if (listXsize[list]> 1)
      fs_top1 = fs_bottom1 = fs1 = listX[list][1];
    else
      fs_top1 = fs_bottom1 = fs1 = listX[list][0];

    for (j = 0; j < 6; j++)
    {
      for (i = 0; i < 6; i++)
      {
        epzs_scale[0][j][i] = 256;
        epzs_scale[1][j][i] = 256;
      }
    }

    for (j = 0; j < 2 + (img->MbaffFrameFlag * 4); j += 2)
    {
      for (i = 0; i < listXsize[j]; i++)
      {
        if (j == 0)
          iTRb = iClip3 (-128, 127, enc_picture->poc - listX[LIST_0 + j][i]->poc);
        else if (j == 2)
          iTRb = iClip3 (-128, 127, enc_picture->top_poc - listX[LIST_0 + j][i]->poc);
        else
          iTRb = iClip3 (-128, 127, enc_picture->bottom_poc - listX[LIST_0 + j][i]->poc);
        iTRp = iClip3 (-128, 127, listX[list + j][0]->poc - listX[LIST_0 + j][i]->poc);
        if (iTRp != 0)
        {
          prescale = (16384 + iabs (iTRp / 2)) / iTRp;
          prescale = iClip3 (-2048, 2047, rshift_rnd_sf((iTRb * prescale), 6));
          //prescale = (iTRb * prescale + 32) >> 6;
        }
        else      // This could not happen but lets use it in case that reference is removed.
          prescale = 256;
        epzs_scale[0][j][i] = rshift_rnd_sf((mv_scale[j][0][i] * prescale), 8);
        epzs_scale[0][j + 1][i] = prescale - 256;
        
        if (listXsize[list + j]>1)
        {
          iTRp = iClip3 (-128, 127, listX[list + j][1]->poc - listX[LIST_0 + j][i]->poc);
          if (iTRp != 0)
          {
            prescale = (16384 + iabs (iTRp / 2)) / iTRp;
            prescale = iClip3 (-2048, 2047, rshift_rnd_sf((iTRb * prescale), 6));
            //prescale = (iTRb * prescale + 32) >> 6;
          }
          else      // This could not happen but lets use it for case that reference is removed.
            prescale = 256;
          epzs_scale[1][j][i] = rshift_rnd_sf((mv_scale[j][1][i] * prescale), 8);
          epzs_scale[1][j + 1][i] = prescale - 256;
        }
        else

⌨️ 快捷键说明

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