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

📄 me_epzs.c

📁 压缩JM12.3d的完整的全部C语言的代码文档,用于嵌入式系统的压缩编解码
💻 C
📖 第 1 页 / 共 5 页
字号:
  int i, memory_size = 0;
  int searchlevels = RoundLog2 (input->search_range) - 1;

  searcharray = input->BiPredMotionEstimation? (2 * imax (input->search_range, input->BiPredMESearchRange) + 1) << (2 * input->EPZSSubPelGrid) : (2 * input->search_range + 1)<< (2 * input->EPZSSubPelGrid);

  mv_rescale = input->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] = input->EPZSMedThresScale * medthres_base[i] * pel_error_me;
    maxthres[i] = input->EPZSMaxThresScale * maxthres_base[i] * pel_error_me;
    minthres[i] = input->EPZSMinThresScale * minthres_base[i] * pel_error_me;
    subthres[i] = input->EPZSSubPelThresScale * medthres_base[i] * pel_error_me;
  }

  //! 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) input->search_range, window_predictor, 0);
  EPZSWindowPredictorInit ((short) input->search_range, window_predictor_extended, 1);
  //! Also assing search predictor memory
  // maxwindow + spatial + blocktype + temporal + memspatial
  predictor = allocEPZSpattern(searchlevels * 20 + 5 + 5 + 9 * (input->EPZSTemporal) + 3 * (input->EPZSSpatialMem));

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

  memory_size += get_mem3Dint (&EPZSDistortion, 6, 7, img->width/BLOCK_SIZE);
  memory_size += get_mem2Dshort (&EPZSMap, searcharray, searcharray );
  if (input->EPZSSpatialMem)
  {
#if EPZSREF
    memory_size += get_mem6Dshort (&EPZSMotion, 6, img->max_num_references, 7, 4, img->width/BLOCK_SIZE, 2);
#else
    memory_size += get_mem5Dshort (&EPZSMotion, 6, 7, 4, img->width/BLOCK_SIZE, 2);
#endif
  }

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

  switch (input->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 (input->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 (void)
{
  if (input->EPZSTemporal)
    freeEPZScolocated (EPZSCo_located);

  free_mem2Dshort(EPZSMap);
  free_mem3Dint  (EPZSDistortion, 6);
  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 (input->EPZSSpatialMem)
  {
#if EPZSREF
    free_mem6Dshort (EPZSMotion, 6, img->max_num_references, 7, 4);
#else
    free_mem5Dshort (EPZSMotion, 6, 7, 4);
#endif
  }

}

//! For ME purposes restricting the co-located partition is not necessary.
/*!
************************************************************************
* \brief
*    EPZS Slice Level Initialization
************************************************************************
*/
void
EPZSSliceInit (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/2 == 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/2 == 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 (input->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
        {
          epzs_scale[1][j][i] = epzs_scale[0][j][i];
          epzs_scale[1][j + 1][i] = epzs_scale[0][j + 1][i];
        }
      }
    }
    if (img->MbaffFrameFlag)
    {
      fs_top = listX[list + 2][0];
      fs_bottom = listX[list + 4][0];
      if (listXsize[0]> 1)
      {
        fs_top1 = listX[list + 2][1];
        fs_bottom = listX[list + 4][1];
      }
    }
    else
    {
      if (img->structure != FRAME)
      {
        if ((img->structure != fs->structure) && (fs->coded_frame))
        {
          if (img->structure == TOP_FIELD)
          {
            fs_top = fs_bottom = fs = listX[list][0]->top_field;
            fs_top1 = fs_bottom1 = fs1 = listX[list][0]->bottom_field;
          }
          else
          {
            fs_top = fs_bottom = fs = listX[list][0]->bottom_field;
            fs_top1 = fs_bottom1 = fs1 = listX[list][0]->top_field;
          }
        }
      }
    }

    //if (!active_sps->frame_mbs_only_flag || active_sps->direct_8x8_inference_flag)
    if (!active_sps->frame_mbs_only_flag)
    {
      for (j = 0; j < fs->size_y >> 2; j++)
      {
        jj = j / 2;
        jdiv = j / 2 + 4 * (j / 8);
        for (i = 0; i < fs->size_x >> 2; i++)
        {
          if (img->MbaffFrameFlag && fs->field_frame[j][i])
          {
            //! Assign frame buffers for field MBs
            //! Check whether we should use top or bottom field mvs.
            //! Depending on the assigned poc values.
            if (iabs (enc_picture->poc - fs_bottom->poc) > iabs (enc_picture->poc - fs_top->poc))
            {
              tempmv_scale[LIST_0] = 256;
              tempmv_scale[LIST_1] = 0;

              if (fs->ref_id [LIST_0][jdiv][i] < 0 && listXsize[LIST_0] > 1)
              {
                fsx = fs_top1;
                loffset = 1;
              }
              else
              {
                fsx = fs_top;
                loffset = 0;
              }

              if (fs->ref_id [LIST_0][jdiv][i] != -1)
              {
                for (iref = 0; iref < imin(img->num_ref_idx_l0_active,listXsize[LIST_0]); iref++)
                {
                  if (enc_picture->ref_pic_num[LIST_0][iref]==fs->ref_id [LIST_0][jdiv][i])

⌨️ 快捷键说明

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