📄 mv-search.c
字号:
#define ABIPRED 1
/*
***********************************************************************
* COPYRIGHT AND WARRANTY INFORMATION
*
* Copyright 2001, International Telecommunications Union, Geneva
*
* DISCLAIMER OF WARRANTY
*
* These software programs are available to the user without any
* license fee or royalty on an "as is" basis. The ITU disclaims
* any and all warranties, whether express, implied, or
* statutory, including any implied warranties of merchantability
* or of fitness for a particular purpose. In no event shall the
* contributor or the ITU be liable for any incidental, punitive, or
* consequential damages of any kind whatsoever arising from the
* use of these programs.
*
* This disclaimer of warranty extends to the user of these programs
* and user's customers, employees, agents, transferees, successors,
* and assigns.
*
* The ITU does not represent or warrant that the programs furnished
* hereunder are free of infringement of any third-party patents.
* Commercial implementations of ITU-T Recommendations, including
* shareware, may be subject to royalty fees to patent holders.
* Information regarding the ITU-T patent policy is available from
* the ITU Web site at http://www.itu.int.
*
* THIS IS NOT A GRANT OF PATENT RIGHTS - SEE THE ITU-T PATENT POLICY.
************************************************************************
*/
/*!
*************************************************************************************
* \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-Lang鴜 <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>
*
*************************************************************************************
*/
#include "contributors.h"
#include <math.h>
#include <stdlib.h>
#include <assert.h>
#include <limits.h>
#include "global.h"
#include "mv-search.h"
#include "refbuf.h"
#include "memalloc.h"
// These procedure pointers are used by motion_search() and one_eigthpel()
static pel_t (*PelY_14) (pel_t**, int, int);
static pel_t *(*PelYline_11) (pel_t *, int, int);
// Statistics, temporary
int max_mvd;
int* spiral_search_x;
int* spiral_search_y;
int* mvbits;
int* refbits;
int* byte_abs;
int*** motion_cost;
void SetMotionVectorPredictor (int pmv[2],
int **refFrArr,
int ***tmp_mv,
int ref_frame,
int mb_x,
int mb_y,
int blockshape_x,
int blockshape_y);
#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 int ****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;
int search_range = input->search_range;
int max_pos = (2*search_range+1) * (2*search_range+1);
if(input->InterlaceCodingOption != FRAME_CODING)
img->buf_cycle *= 2;
if ((BlockSAD = (int****)malloc ((img->buf_cycle+1) * sizeof(int***))) == NULL)
no_mem_exit ("InitializeFastFullIntegerSearch: BlockSAD");
for (i = 0; i <= img->buf_cycle; i++)
{
if ((BlockSAD[i] = (int***)malloc (8 * sizeof(int**))) == NULL)
no_mem_exit ("InitializeFastFullIntegerSearch: BlockSAD");
for (j = 1; j < 8; j++)
{
if ((BlockSAD[i][j] = (int**)malloc (16 * sizeof(int*))) == NULL)
no_mem_exit ("InitializeFastFullIntegerSearch: BlockSAD");
for (k = 0; k < 16; k++)
{
if ((BlockSAD[i][j][k] = (int*)malloc (max_pos * sizeof(int))) == NULL)
no_mem_exit ("InitializeFastFullIntegerSearch: BlockSAD");
}
}
}
if ((search_setup_done = (int*)malloc ((img->buf_cycle+1)*sizeof(int)))==NULL)
no_mem_exit ("InitializeFastFullIntegerSearch: search_setup_done");
if ((search_center_x = (int*)malloc ((img->buf_cycle+1)*sizeof(int)))==NULL)
no_mem_exit ("InitializeFastFullIntegerSearch: search_center_x");
if ((search_center_y = (int*)malloc ((img->buf_cycle+1)*sizeof(int)))==NULL)
no_mem_exit ("InitializeFastFullIntegerSearch: search_center_y");
if ((pos_00 = (int*)malloc ((img->buf_cycle+1)*sizeof(int)))==NULL)
no_mem_exit ("InitializeFastFullIntegerSearch: pos_00");
if ((max_search_range = (int*)malloc ((img->buf_cycle+1)*sizeof(int)))==NULL)
no_mem_exit ("InitializeFastFullIntegerSearch: max_search_range");
// assign max search ranges for reference frames
if (input->full_search == 2)
{
for (i=0; i<=img->buf_cycle; i++) max_search_range[i] = search_range;
}
else
{
max_search_range[0] = max_search_range[img->buf_cycle] = search_range;
for (i=1; i< img->buf_cycle; i++) max_search_range[i] = search_range / 2;
}
if(input->InterlaceCodingOption != FRAME_CODING)
img->buf_cycle /= 2;
}
/*!
***********************************************************************
* \brief
* function for deleting the arrays for fast integer motion estimation
***********************************************************************
*/
void
ClearFastFullIntegerSearch ()
{
int i, j, k;
if(input->InterlaceCodingOption != FRAME_CODING)
img->buf_cycle *= 2;
for (i = 0; i <= img->buf_cycle; i++)
{
for (j = 1; j < 8; j++)
{
for (k = 0; k < 16; k++)
{
free (BlockSAD[i][j][k]);
}
free (BlockSAD[i][j]);
}
free (BlockSAD[i]);
}
free (BlockSAD);
free (search_setup_done);
free (search_center_x);
free (search_center_y);
free (pos_00);
free (max_search_range);
if(input->InterlaceCodingOption != FRAME_CODING)
img->buf_cycle /= 2;
}
/*!
***********************************************************************
* \brief
* function resetting flags for fast integer motion estimation
* (have to be called in start_macroblock())
***********************************************************************
*/
void
ResetFastFullIntegerSearch ()
{
int i;
for (i = 0; i <= img->buf_cycle; i++)
search_setup_done [i] = 0;
}
/*!
***********************************************************************
* \brief
* calculation of SAD for larger blocks on the basis of 4x4 blocks
***********************************************************************
*/
void
SetupLargerBlocks (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;
int pos, **_bo, **_bi, **_bj;
register int *_o, *_i, *_j;
//--- blocktype 6 ---
_bo = BlockSAD[refindex][6];
_bi = BlockSAD[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[refindex][5];
_bi = BlockSAD[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[refindex][4];
_bi = BlockSAD[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[refindex][3];
_bi = BlockSAD[refindex][4];
_bj = _bi + 8;
ADD_UP_BLOCKS(); INCREMENT(2);
ADD_UP_BLOCKS();
//--- blocktype 2 ---
_bo = BlockSAD[refindex][2];
_bi = BlockSAD[refindex][4];
_bj = _bi + 2;
ADD_UP_BLOCKS(); INCREMENT(8);
ADD_UP_BLOCKS();
//--- blocktype 1 ---
_bo = BlockSAD[refindex][1];
_bi = BlockSAD[refindex][3];
_bj = _bi + 2;
ADD_UP_BLOCKS();
}
/*!
***********************************************************************
* \brief
* Setup the fast search for an macroblock
***********************************************************************
*/
void
SetupFastFullPelSearch (int ref) // <-- reference frame parameter (0... or -1 (backward))
{
int 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 refframe = (ref>=0 ? ref : 0);
int refindex = (ref>=0 ? ref : img->buf_cycle);
pel_t* ref_pic; // = img->type==B_IMG? Refbuf11 [ref+((mref==mref_fld)) +1] : Refbuf11[ref];
int** ref_array = ((img->type!=B_IMG && img->type!=BS_IMG)? refFrArr : ref>=0 ? fw_refFrArr : bw_refFrArr);
int*** mv_array = ((img->type!=B_IMG && img->type!=BS_IMG)? tmp_mv : ref>=0 ? tmp_fwMV : tmp_bwMV);
int** block_sad = BlockSAD[refindex][7];
int max_width = img->width - 17;
int max_height = img->height - 17;
int search_range = max_search_range[refindex];
int max_pos = (2*search_range+1) * (2*search_range+1);
byte** imgY_orig = imgY_org;
int pix_y = img->pix_y;
int apply_weights = ( (input->WeightedPrediction && img->type == INTER_IMG) ||
(input->WeightedBiprediction && (img->type == B_IMG || img->type == BS_IMG)));
if (apply_weights)
ref_pic = img->type==B_IMG? Refbuf11_w [ref+((mref==mref_fld)) +1] : Refbuf11_w[ref];
else
ref_pic = img->type==B_IMG? Refbuf11 [ref+((mref==mref_fld)) +1] : Refbuf11[ref];
if(input->InterlaceCodingOption >= MB_CODING && mb_adaptive && img->field_mode)
{
if (apply_weights)
ref_pic = img->type==B_IMG? Refbuf11_w [ref+(img->field_mode) +1] : Refbuf11_w[ref];
else
ref_pic = img->type==B_IMG? Refbuf11 [ref+(img->field_mode) +1] : Refbuf11[ref];
block_sad = BlockSAD[refindex][7];
pix_y = img->field_pix_y;
if(img->top_field)
{
ref_array = ((img->type!=B_IMG && img->type!=BS_IMG) ? refFrArr_top : ref>=0 ? fw_refFrArr_top : bw_refFrArr_top);
mv_array = ((img->type!=B_IMG && img->type!=BS_IMG) ? tmp_mv_top : ref>=0 ? tmp_fwMV_top : tmp_bwMV_top);
imgY_orig = imgY_org_top;
}
else
{
ref_array = ((img->type!=B_IMG && img->type!=BS_IMG) ? refFrArr_bot : ref>=0 ? fw_refFrArr_bot : bw_refFrArr_bot);
mv_array = ((img->type!=B_IMG && img->type!=BS_IMG) ? tmp_mv_bot : ref>=0 ? tmp_fwMV_bot : tmp_bwMV_bot);
imgY_orig = imgY_org_bot;
}
}
//===== get search center: predictor of 16x16 block =====
SetMotionVectorPredictor (pmv, ref_array, mv_array, refframe, 0, 0, 16, 16);
search_center_x[refindex] = pmv[0] / 4;
search_center_y[refindex] = pmv[1] / 4;
if (!input->rdopt)
{
//--- correct center so that (0,0) vector is inside ---
search_center_x[refindex] = max(-search_range, min(search_range, search_center_x[refindex]));
search_center_y[refindex] = max(-search_range, min(search_range, search_center_y[refindex]));
}
search_center_x[refindex] += img->pix_x;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -