?? mv-search.c
字號:
/*!
*************************************************************************************
* \file mv-search.c
*
* \brief
* Motion Vector Search, unified for B and P Pictures
*
* \author
* Main contributors (see contributors.h for copyright, address and affiliation details)
* - Stephan Wenger <stewe@cs.tu-berlin.de>
* - Inge Lille-Langoy <inge.lille-langoy@telenor.com>
* - Rickard Sjoberg <rickard.sjoberg@era.ericsson.se>
* - Stephan Wenger <stewe@cs.tu-berlin.de>
* - Jani Lainema <jani.lainema@nokia.com>
* - Detlev Marpe <marpe@hhi.de>
* - Thomas Wedi <wedi@tnt.uni-hannover.de>
* - Heiko Schwarz <hschwarz@hhi.de>
* - Alexis Michael Tourapis <alexismt@ieee.org>
*
*************************************************************************************
*/
#include "contributors.h"
#include <stdlib.h>
#include <math.h>
#include <limits.h>
#include <string.h>
#include "global.h"
#include "image.h"
#include "mv-search.h"
#include "refbuf.h"
#include "memalloc.h"
#include "mb_access.h"
#include "fast_me.h"
#include <time.h>
#include <sys/timeb.h>
// These procedure pointers are used by motion_search() and one_eigthpel()
static pel_t *(*PelYline_11) (pel_t *, int, int, int, int);
static pel_t *(*get_line) (pel_t**, int, int, int, int);
static pel_t *(*get_line_p1) (pel_t**, int, int, int, int);
static pel_t *(*get_line_p2) (pel_t**, int, int, int, int);
// Statistics, temporary
int max_mvd;
short* spiral_search_x;
short* spiral_search_y;
short* spiral_hpel_search_x;
short* spiral_hpel_search_y;
int* mvbits;
int* refbits;
unsigned int* byte_abs;
int**** motion_cost;
void SetMotionVectorPredictor (short pmv[2],
char **refPic,
short ***tmp_mv,
short ref_frame,
int list,
int block_x,
int block_y,
int blockshape_x,
int blockshape_y);
extern ColocatedParams *Co_located;
#ifdef _FAST_FULL_ME_
/*****
***** static variables for fast integer motion estimation
*****
*/
static int **search_setup_done; //!< flag if all block SAD's have been calculated yet
static int **search_center_x; //!< absolute search center for fast full motion search
static int **search_center_y; //!< absolute search center for fast full motion search
static int **pos_00; //!< position of (0,0) vector
static distpel *****BlockSAD; //!< SAD for all blocksize, ref. frames and motion vectors
static int **max_search_range;
/*!
***********************************************************************
* \brief
* function creating arrays for fast integer motion estimation
***********************************************************************
*/
void
InitializeFastFullIntegerSearch ()
{
int i, j, k, list;
int search_range = input->search_range;
int max_pos = (2*search_range+1) * (2*search_range+1);
if ((BlockSAD = (distpel*****)malloc (2 * sizeof(distpel****))) == NULL)
no_mem_exit ("InitializeFastFullIntegerSearch: BlockSAD");
for (list=0; list<2;list++)
{
if ((BlockSAD[list] = (distpel****)malloc ((img->max_num_references) * sizeof(distpel***))) == NULL)
no_mem_exit ("InitializeFastFullIntegerSearch: BlockSAD");
for (i = 0; i < img->max_num_references; i++)
{
if ((BlockSAD[list][i] = (distpel***)malloc (8 * sizeof(distpel**))) == NULL)
no_mem_exit ("InitializeFastFullIntegerSearch: BlockSAD");
for (j = 1; j < 8; j++)
{
if ((BlockSAD[list][i][j] = (distpel**)malloc (16 * sizeof(distpel*))) == NULL)
no_mem_exit ("InitializeFastFullIntegerSearch: BlockSAD");
for (k = 0; k < 16; k++)
{
if ((BlockSAD[list][i][j][k] = (distpel*)malloc (max_pos * sizeof(distpel))) == NULL)
no_mem_exit ("InitializeFastFullIntegerSearch: BlockSAD");
}
}
}
}
if ((search_setup_done = (int**)malloc (2*sizeof(int)))==NULL)
no_mem_exit ("InitializeFastFullIntegerSearch: search_setup_done");
if ((search_center_x = (int**)malloc (2*sizeof(int)))==NULL)
no_mem_exit ("InitializeFastFullIntegerSearch: search_center_x");
if ((search_center_y = (int**)malloc (2*sizeof(int)))==NULL)
no_mem_exit ("InitializeFastFullIntegerSearch: search_center_y");
if ((pos_00 = (int**)malloc (2*sizeof(int)))==NULL)
no_mem_exit ("InitializeFastFullIntegerSearch: pos_00");
if ((max_search_range = (int**)malloc (2*sizeof(int)))==NULL)
no_mem_exit ("InitializeFastFullIntegerSearch: max_search_range");
for (list=0; list<2; list++)
{
if ((search_setup_done[list] = (int*)malloc ((img->max_num_references)*sizeof(int)))==NULL)
no_mem_exit ("InitializeFastFullIntegerSearch: search_setup_done");
if ((search_center_x[list] = (int*)malloc ((img->max_num_references)*sizeof(int)))==NULL)
no_mem_exit ("InitializeFastFullIntegerSearch: search_center_x");
if ((search_center_y[list] = (int*)malloc ((img->max_num_references)*sizeof(int)))==NULL)
no_mem_exit ("InitializeFastFullIntegerSearch: search_center_y");
if ((pos_00[list] = (int*)malloc ((img->max_num_references)*sizeof(int)))==NULL)
no_mem_exit ("InitializeFastFullIntegerSearch: pos_00");
if ((max_search_range[list] = (int*)malloc ((img->max_num_references)*sizeof(int)))==NULL)
no_mem_exit ("InitializeFastFullIntegerSearch: max_search_range");
}
// assign max search ranges for reference frames
if (input->full_search == 2)
{
for (list=0;list<2;list++)
for (i=0; i<img->max_num_references; i++)
max_search_range[list][i] = search_range;
}
else
{
for (list=0;list<2;list++)
{
max_search_range[list][0] = search_range;
for (i=1; i< img->max_num_references; i++) max_search_range[list][i] = search_range / 2;
}
}
}
/*!
***********************************************************************
* \brief
* function for deleting the arrays for fast integer motion estimation
***********************************************************************
*/
void
ClearFastFullIntegerSearch ()
{
int i, j, k, list;
for (list=0; list<2; list++)
{
for (i = 0; i < img->max_num_references; i++)
{
for (j = 1; j < 8; j++)
{
for (k = 0; k < 16; k++)
{
free (BlockSAD[list][i][j][k]);
}
free (BlockSAD[list][i][j]);
}
free (BlockSAD[list][i]);
}
free (BlockSAD[list]);
}
free (BlockSAD);
for (list=0; list<2; list++)
{
free (search_setup_done[list]);
free (search_center_x[list]);
free (search_center_y[list]);
free (pos_00[list]);
free (max_search_range[list]);
}
free (search_setup_done);
free (search_center_x);
free (search_center_y);
free (pos_00);
free (max_search_range);
}
/*!
***********************************************************************
* \brief
* function resetting flags for fast integer motion estimation
* (have to be called in start_macroblock())
***********************************************************************
*/
void
ResetFastFullIntegerSearch ()
{
int i,list;
for (list=0; list<2; list++)
for (i = 0; i < img->max_num_references; i++)
search_setup_done [list][i] = 0;
}
/*!
***********************************************************************
* \brief
* calculation of SAD for larger blocks on the basis of 4x4 blocks
***********************************************************************
*/
void
SetupLargerBlocks (int list, int refindex, int max_pos)
{
#define ADD_UP_BLOCKS() _o=*_bo; _i=*_bi; _j=*_bj; for(pos=0;pos<max_pos;pos++) _o[pos] = _i[pos] + _j[pos];
#define INCREMENT(inc) _bo+=inc; _bi+=inc; _bj+=inc;
distpel pos, **_bo, **_bi, **_bj;
register distpel *_o, *_i, *_j;
//--- blocktype 6 ---
_bo = BlockSAD[list][refindex][6];
_bi = BlockSAD[list][refindex][7];
_bj = _bi + 4;
ADD_UP_BLOCKS(); INCREMENT(1);
ADD_UP_BLOCKS(); INCREMENT(1);
ADD_UP_BLOCKS(); INCREMENT(1);
ADD_UP_BLOCKS(); INCREMENT(5);
ADD_UP_BLOCKS(); INCREMENT(1);
ADD_UP_BLOCKS(); INCREMENT(1);
ADD_UP_BLOCKS(); INCREMENT(1);
ADD_UP_BLOCKS();
//--- blocktype 5 ---
_bo = BlockSAD[list][refindex][5];
_bi = BlockSAD[list][refindex][7];
_bj = _bi + 1;
ADD_UP_BLOCKS(); INCREMENT(2);
ADD_UP_BLOCKS(); INCREMENT(2);
ADD_UP_BLOCKS(); INCREMENT(2);
ADD_UP_BLOCKS(); INCREMENT(2);
ADD_UP_BLOCKS(); INCREMENT(2);
ADD_UP_BLOCKS(); INCREMENT(2);
ADD_UP_BLOCKS(); INCREMENT(2);
ADD_UP_BLOCKS();
//--- blocktype 4 ---
_bo = BlockSAD[list][refindex][4];
_bi = BlockSAD[list][refindex][6];
_bj = _bi + 1;
ADD_UP_BLOCKS(); INCREMENT(2);
ADD_UP_BLOCKS(); INCREMENT(6);
ADD_UP_BLOCKS(); INCREMENT(2);
ADD_UP_BLOCKS();
//--- blocktype 3 ---
_bo = BlockSAD[list][refindex][3];
_bi = BlockSAD[list][refindex][4];
_bj = _bi + 8;
ADD_UP_BLOCKS(); INCREMENT(2);
ADD_UP_BLOCKS();
//--- blocktype 2 ---
_bo = BlockSAD[list][refindex][2];
_bi = BlockSAD[list][refindex][4];
_bj = _bi + 2;
ADD_UP_BLOCKS(); INCREMENT(8);
ADD_UP_BLOCKS();
//--- blocktype 1 ---
_bo = BlockSAD[list][refindex][1];
_bi = BlockSAD[list][refindex][3];
_bj = _bi + 2;
ADD_UP_BLOCKS();
}
/*!
***********************************************************************
* \brief
* Setup the fast search for an macroblock
***********************************************************************
*/
void SetupFastFullPelSearch (short ref, int list) // <-- reference frame parameter, list0 or 1
{
short pmv[2];
pel_t orig_blocks[256], *orgptr=orig_blocks, *refptr;
int offset_x, offset_y, x, y, range_partly_outside, ref_x, ref_y, pos, abs_x, abs_y, bindex, blky;
int LineSadBlk0, LineSadBlk1, LineSadBlk2, LineSadBlk3;
int max_width, max_height;
int img_width, img_height;
StorablePicture *ref_picture;
pel_t *ref_pic;
distpel** block_sad = BlockSAD[list][ref][7];
int search_range = max_search_range[list][ref];
int max_pos = (2*search_range+1) * (2*search_range+1);
int list_offset = img->mb_data[img->current_mb_nr].list_offset;
int apply_weights = ( (active_pps->weighted_pred_flag && (img->type == P_SLICE || img->type == SP_SLICE)) ||
(active_pps->weighted_bipred_idc && (img->type == B_SLICE)));
ref_picture = listX[list+list_offset][ref];
//===== Use weighted Reference for ME ====
if (apply_weights && input->UseWeightedReferenceME)
ref_pic = ref_picture->imgY_11_w;
else
ref_pic = ref_picture->imgY_11;
max_width = ref_picture->size_x - 17;
max_height = ref_picture->size_y - 17;
img_width = ref_picture->size_x;
img_height = ref_picture->size_y;
//===== get search center: predictor of 16x16 block =====
SetMotionVectorPredictor (pmv, enc_picture->ref_idx[list], enc_picture->mv[list], ref, list, 0, 0, 16, 16);
search_center_x[list][ref] = pmv[0] / 4;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -