📄 epzs.c
字号:
/*!
*************************************************************************************
* \file 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>
*
*************************************************************************************
*/
#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 "epzs.h"
#define EPZSREF 1
extern int *mvbits;
extern unsigned 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 int search_point_hp_x[10] = {0,-2, 0, 2, 0, -2, 2, 2, -2, -2};
static const int search_point_hp_y[10] = {0, 0, 2, 0, -2, 2, 2, -2, -2, 2};
static const int search_point_qp_x[10] = {0,-1, 0, 1, 0, -1, 1, 1, -1, -1};
static const int search_point_qp_y[10] = {0, 0, 1, 0, -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 img_width;
static short img_height;
static short weight1, weight2, offsetBi;
//! Define EPZS Refinement patterns
static int pattern_data[4][12][4] =
{
{ // Small Diamond pattern
{ 0, 1, 3, 3 }, { 1, 0, 0, 3 }, { 0, -1, 1, 3 }, { -1, 0, 2, 3 }
},
{ // Square pattern
{ 0, 1, 7, 3 }, { 1, 1, 7, 5 }, { 1, 0, 1, 3 }, { 1, -1, 1, 5 },
{ 0, -1, 3, 3 }, { -1, -1, 3, 5 }, { -1, 0, 5, 3 }, { -1, 1, 5, 5 }
},
{ // Enhanced Diamond pattern
{ -1, 1, 10, 5 }, { 0, 2, 10, 8 }, { 0, 1, 10, 7 }, { 1, 1, 1, 5 },
{ 2, 0, 1, 8 }, { 1, 0, 1, 7 }, { 1, -1, 4, 5 }, { 0, -2, 4, 8 },
{ 0, -1, 4, 7 }, { -1, -1, 7, 5 }, { -2, 0, 7, 8 }, { -1, 0, 7, 7 }
},
{ // Large Diamond pattern
{ 0, 2, 6, 5 }, { 1, 1, 0, 3 }, { 2, 0, 0, 5 }, { 1, -1, 2, 3 },
{ 0, -2, 2, 5 }, { -1, -1, 4, 3 }, { -2, 0, 4, 5 }, { -1, 1, 6, 3 }
}
};
// Other definitions
const char c_EPZSPattern[4][20] = { "Diamond", "Square", "Extended Diamond", "Large Diamond"};
const char c_EPZSDualPattern[5][20] = { "Disabled","Diamond", "Square", "Extended Diamond", "Large Diamond"};
const char c_EPZSFixed[3][20] = { "Disabled","All P", "All P + B"};
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 byte **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;
EPZSColocParams *EPZSCo_located;
static int (*computeBiPredSad)(pel_t **, int, int, int, int, int, int, int, int, int);
static pel_t *(*get_ref_line1)(int, pel_t *, int, int, int, int);
static pel_t *(*get_ref_line2)(int, pel_t *, int, int, int, int);
static pel_t *(*get_ref_line) (int, pel_t *, int, int, int, int);
static pel_t *(*get_line) (pel_t**, int, int, int, int);
static pel_t *ref_pic;
static pel_t *ref_pic1;
static pel_t *ref_pic2;
/*!
************************************************************************
* \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
************************************************************************
*/
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
*
************************************************************************
*/
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
************************************************************************
*/
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
*
************************************************************************
*/
void freeEPZSpattern(EPZSStructure* p)
{
if (p)
{
free ( (SPoint*) p->point);
free(p);
p=NULL;
}
}
void assignEPZSpattern(EPZSStructure *pattern,int type)
{
int i;
for (i = 0; i < pattern->searchPoints; i++)
{
pattern->point[i].x = pattern_data[type][i][0];
pattern->point[i].y = pattern_data[type][i][1];
pattern->point[i].start_nmbr = pattern_data[type][i][2];
pattern->point[i].next_points = pattern_data[type][i][3];
}
}
/*!
************************************************************************
* \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
************************************************************************
*/
void EPZSWindowPredictorInit (short search_range, EPZSStructure * predictor, short mode)
{
int pos;
int searchpos, fieldsearchpos;
int prednum = 0;
int i;
if (mode == 0)
{
for (pos = RoundLog2 (search_range) - 2; pos > -1; pos--)
{
searchpos = (search_range >> pos);
for (i=1; i>=-1; i-=2)
{
predictor->point[prednum ].x = i * searchpos;
predictor->point[prednum++].y = 0;
predictor->point[prednum ].x = i * searchpos;
predictor->point[prednum++].y = i * searchpos;
predictor->point[prednum ].x = 0;
predictor->point[prednum++].y = i * searchpos;
predictor->point[prednum ].x = -i * searchpos;
predictor->point[prednum++].y = i * searchpos;
}
}
}
else // if (mode == 0)
{
for (pos = RoundLog2 (search_range) - 2; pos > -1; pos--)
{
searchpos = (search_range >> pos);
fieldsearchpos = (3 * searchpos + 1) >> 1;
for (i=1; i>=-1; i-=2)
{
predictor->point[prednum ].x = i * searchpos;
predictor->point[prednum++].y = 0;
predictor->point[prednum ].x = i * searchpos;
predictor->point[prednum++].y = i * searchpos;
predictor->point[prednum ].x = 0;
predictor->point[prednum++].y = i * searchpos;
predictor->point[prednum ].x = -i * searchpos;
predictor->point[prednum++].y = i * searchpos;
}
for (i=1; i>=-1; i-=2)
{
predictor->point[prednum ].x = i * fieldsearchpos;
predictor->point[prednum++].y = -i * searchpos;
predictor->point[prednum ].x = i * fieldsearchpos;
predictor->point[prednum++].y = 0;
predictor->point[prednum ].x = i * fieldsearchpos;
predictor->point[prednum++].y = i * searchpos;
predictor->point[prednum ].x = i * searchpos;
predictor->point[prednum++].y = i * fieldsearchpos;
predictor->point[prednum ].x = 0;
predictor->point[prednum++].y = i * fieldsearchpos;
predictor->point[prednum ].x = -i * searchpos;
predictor->point[prednum++].y = i * fieldsearchpos;
}
}
}
predictor->searchPoints = prednum;
}
/*!
************************************************************************
* \brief
* EPZS Global Initialization
************************************************************************
*/
int
EPZSInit (void)
{
int pel_error_me = 1 << (img->bitdepth_luma - 8);
int i, memory_size = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -