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

📄 me_epzs.c

📁 This program can encode the YUV vdieo format to H.264 and decode it.
💻 C
📖 第 1 页 / 共 5 页
字号:

/*!
*************************************************************************************
* \file me_epzs.c
*
* \brief
*    Motion Estimation using EPZS
*
* \author
*    Main contributors (see contributors.h for copyright, address and affiliation details)
*      - Alexis Michael Tourapis <alexismt@ieee.org>
*      - Athanasios Leontaris    <aleon@dolby.com>
*
*************************************************************************************
*/

#include "contributors.h"

#include <stdlib.h>
#include <limits.h>
#include <string.h>

#include "global.h"
#include "image.h"
#include "memalloc.h"
#include "mb_access.h"
#include "refbuf.h"

#include "me_distortion.h"
#include "me_epzs.h"

#define EPZSREF 1

extern int *mvbits;
extern int *byte_abs;

// Define Global Parameters
static const short blk_parent[8] = {1, 1, 1, 1, 2, 4, 4, 5}; //!< {skip, 16x16, 16x8, 8x16, 8x8, 8x4, 4x8, 4x4}
//static const short blk_child[8]  = {1, 2, 4, 4, 5, 7, 7, 7}; //!< {skip, 16x16, 16x8, 8x16, 8x8, 8x4, 4x8, 4x4}
static const int   minthres_base[8] = {0,  64,  32,  32,  16,  8,  8,  4};
static const int   medthres_base[8] = {0, 256, 128, 128,  64, 32, 32, 16};
static const int   maxthres_base[8] = {0, 768, 384, 384, 192, 96, 96, 48};
static const short search_point_hp[10][2] = {{0,0},{-2,0}, {0,2}, {2,0},  {0,-2}, {-2,2},  {2,2},  {2,-2}, {-2,-2}, {-2,2}};
static const short search_point_qp[10][2] = {{0,0},{-1,0}, {0,1}, {1,0},  {0,-1}, {-1,1},  {1,1},  {1,-1}, {-1,-1}, {-1,1}};
//static const int   next_subpel_pos_start[5][5] = {};
//static const int   next_subpel_pos_end  [5][5] = {};

static short EPZSBlkCount;
static int   searcharray;
static int   mv_rescale;

//! Define EPZS Refinement patterns
static int pattern_data[5][12][4] =
{
  { // Small Diamond pattern
    {  0,  4,  3, 3 }, {  4,  0,  0, 3 }, {  0, -4,  1, 3 }, { -4,  0, 2, 3 }
  },
  { // Square pattern
    {  0,  4,  7, 3 }, {  4,  4,  7, 5 }, {  4,  0,  1, 3 }, {  4, -4, 1, 5 },
    {  0, -4,  3, 3 }, { -4, -4,  3, 5 }, { -4,  0,  5, 3 }, { -4,  4, 5, 5 }
  },
  { // Enhanced Diamond pattern
    { -4,  4, 10, 5 }, {  0,  8, 10, 8 }, {  0,  4, 10, 7 }, {  4,  4, 1, 5 },
    {  8,  0, 1,  8 }, {  4,  0,  1, 7 }, {  4, -4,  4, 5 }, {  0, -8, 4, 8 },
    {  0, -4, 4,  7 }, { -4, -4, 7,  5 }, { -8,  0,  7, 8 }, { -4,  0, 7, 7 }

  },
  { // Large Diamond pattern
    {  0,  8, 6,  5 }, {  4,  4, 0,  3 }, {  8,  0, 0,  5 }, {  4, -4, 2, 3 },
    {  0, -8, 2,  5 }, { -4, -4, 4,  3 }, { -8,  0, 4,  5 }, { -4,  4, 6, 3 }
  },
  { // Extended Subpixel pattern
    {  0,  8, 6, 12 }, {  4,  4, 0, 12 }, {  8,  0, 0, 12 }, {  4, -4, 2, 12 },
    {  0, -8, 2, 12 }, { -4, -4, 4, 12 }, { -8,  0, 4, 12 }, { -4,  4, 6, 12 },
    {  0,  2, 6, 12 }, {  2,  0, 0, 12 }, {  0, -2, 2, 12 }, { -2,  0, 4, 12 }
  }
};

// Other definitions
static const  char c_EPZSPattern[6][20]    = { "Diamond", "Square", "Extended Diamond", "Large Diamond", "SBP Large Diamond", "PMVFAST"};
static const  char c_EPZSDualPattern[7][20] = { "Disabled","Diamond", "Square", "Extended Diamond", "Large Diamond", "SBP Large Diamond", "PMVFAST"};
static const  char c_EPZSFixed[3][20] = { "Disabled","All P", "All P + B"};
static const  char c_EPZSOther[2][20] = { "Disabled","Enabled"};

static int medthres[8];
static int maxthres[8];
static int minthres[8];
static int subthres[8];
static int mv_scale[6][MAX_REFERENCE_PICTURES][MAX_REFERENCE_PICTURES];

static short **EPZSMap;  //!< Memory Map definition
int ***EPZSDistortion;  //!< Array for storing SAD Values
#if EPZSREF
short ******EPZSMotion;  //!< Array for storing Motion Vectors
#else
short *****EPZSMotion;  //!< Array for storing Motion Vectors
#endif

//
EPZSStructure *searchPattern,*searchPatternD, *predictor;
EPZSStructure *window_predictor, *window_predictor_extended;
EPZSStructure *sdiamond,*square,*ediamond,*ldiamond, *sbdiamond, *pmvfast;
EPZSColocParams *EPZSCo_located;

/*!
************************************************************************
* \brief
*    Allocate co-located memory
*
* \param size_x
*    horizontal luma size
* \param size_y
*    vertical luma size
* \param mb_adaptive_frame_field_flag
*    flag that indicates macroblock adaptive frame/field coding
*
* \return
*    the allocated EPZSColocParams structure
************************************************************************
*/
static EPZSColocParams* allocEPZScolocated(int size_x, int size_y, int mb_adaptive_frame_field_flag)
{
  EPZSColocParams *s;

  s = calloc(1, sizeof(EPZSColocParams));
  if (NULL == s)
    no_mem_exit("alloc_EPZScolocated: s");

  s->size_x = size_x;
  s->size_y = size_y;
  get_mem4Dshort (&(s->mv), 2, size_y / BLOCK_SIZE, size_x / BLOCK_SIZE, 2);

  if (mb_adaptive_frame_field_flag)
  {
    get_mem4Dshort (&(s->top_mv),   2, size_y / BLOCK_SIZE/2, size_x / BLOCK_SIZE, 2);
    get_mem4Dshort (&(s->bottom_mv),2, size_y / BLOCK_SIZE/2, size_x / BLOCK_SIZE, 2);
  }

  s->mb_adaptive_frame_field_flag  = mb_adaptive_frame_field_flag;

  return s;
}

/*!
************************************************************************
* \brief
*    Free co-located memory.
*
* \param p
*    structure to be freed
*
************************************************************************
*/
static void freeEPZScolocated(EPZSColocParams* p)
{
  if (p)
  {
    free_mem4Dshort (p->mv, 2, p->size_y / BLOCK_SIZE);

    if (p->mb_adaptive_frame_field_flag)
    {
      free_mem4Dshort (p->top_mv, 2, p->size_y / BLOCK_SIZE / 2);
      free_mem4Dshort (p->bottom_mv, 2, p->size_y / BLOCK_SIZE / 2);
    }

    free(p);

    p=NULL;
  }
}

/*!
************************************************************************
* \brief
*    Allocate EPZS pattern memory
*
* \param searchpoints
*    number of searchpoints to allocate
*
* \return
*    the allocated EPZSStructure structure
************************************************************************
*/
static EPZSStructure* allocEPZSpattern(int searchpoints)
{
  EPZSStructure *s;

  s = calloc(1, sizeof(EPZSStructure));
  if (NULL == s)
    no_mem_exit("alloc_EPZSpattern: s");

  s->searchPoints = searchpoints;
  s->point = (SPoint*) calloc(searchpoints, sizeof(SPoint));

  return s;
}

/*!
************************************************************************
* \brief
*    Free EPZS pattern memory.
*
* \param p
*    structure to be freed
*
************************************************************************
*/
static void freeEPZSpattern(EPZSStructure* p)
{
  if (p)
  {
    free ( (SPoint*) p->point);
    free(p);
    p=NULL;
  }
}

static void assignEPZSpattern(EPZSStructure *pattern,int type, int stopSearch, int nextLast, EPZSStructure *nextpattern)
{
  int i;

  for (i = 0; i < pattern->searchPoints; i++)
  {
    pattern->point[i].mv[0]       = pattern_data[type][i][0] >> mv_rescale;
    pattern->point[i].mv[1]       = pattern_data[type][i][1] >> mv_rescale;
    pattern->point[i].start_nmbr  = pattern_data[type][i][2];
    pattern->point[i].next_points = pattern_data[type][i][3];
  }
  pattern->stopSearch = stopSearch;
  pattern->nextLast = nextLast;
  pattern->nextpattern = nextpattern;
}

/*!
************************************************************************
* \brief
*    calculate RoundLog2(uiVal)
************************************************************************
*/
static int RoundLog2 (int iValue)
{
  int iRet = 0;
  int iValue_square = iValue * iValue;

  while ((1 << (iRet + 1)) <= iValue_square)
    iRet++;

  iRet = (iRet + 1) >> 1;

  return iRet;
}


/*!
************************************************************************
* \brief
*    EPZS Search Window Predictor Initialization
************************************************************************
*/
static void EPZSWindowPredictorInit (short search_range, EPZSStructure * predictor, short mode)
{
  int pos;
  int searchpos, fieldsearchpos;
  int prednum = 0;
  int i;
  int search_range_qpel = input->EPZSSubPelGrid ? 2 : 0;
  if (mode == 0)
  {
    for (pos = RoundLog2 (search_range) - 2; pos > -1; pos--)
    {
      searchpos = ((search_range << search_range_qpel)>> pos);

      for (i=1; i>=-1; i-=2)
      {
        predictor->point[prednum  ].mv[0] =  i * searchpos;
        predictor->point[prednum++].mv[1] =  0;
        predictor->point[prednum  ].mv[0] =  i * searchpos;
        predictor->point[prednum++].mv[1] =  i * searchpos;
        predictor->point[prednum  ].mv[0] =  0;
        predictor->point[prednum++].mv[1] =  i * searchpos;
        predictor->point[prednum  ].mv[0] = -i * searchpos;
        predictor->point[prednum++].mv[1] =  i * searchpos;
      }
    }
  }
  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  ].mv[0] =  i * searchpos;
        predictor->point[prednum++].mv[1] =  0;
        predictor->point[prednum  ].mv[0] =  i * searchpos;
        predictor->point[prednum++].mv[1] =  i * searchpos;
        predictor->point[prednum  ].mv[0] =  0;
        predictor->point[prednum++].mv[1] =  i * searchpos;
        predictor->point[prednum  ].mv[0] = -i * searchpos;
        predictor->point[prednum++].mv[1] =  i * searchpos;
      }

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

/*!
************************************************************************
* \brief
*    EPZS Global Initialization
************************************************************************
*/
int
EPZSInit (void)
{
  int pel_error_me = 1 << (img->bitdepth_luma - 8);

⌨️ 快捷键说明

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