📄 mv-search.c
字号:
/*
*****************************************************************************
* COPYRIGHT AND WARRANTY INFORMATION
*
* Copyright 2003, Advanced Audio Video Coding Standard, Part II
*
* DISCLAIMER OF WARRANTY
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
* License for the specific language governing rights and limitations under
* the License.
*
* THIS IS NOT A GRANT OF PATENT RIGHTS - SEE THE AVS PATENT POLICY.
* The AVS Working Group doesn't represent or warrant that the programs
* furnished here under are free of infringement of any third-party patents.
* Commercial implementations of AVS, including shareware, may be
* subject to royalty fees to patent holders. Information regarding
* the AVS patent policy for standardization procedure is available at
* AVS Web site http://www.avs.org.cn. Patent Licensing is outside
* of AVS Working Group.
*
* The Original Code is Reference Software for China National Standard
* GB/T 20090.2-2006 (short for AVS-P2 or AVS Video) at version RM52J.
*
* The Initial Developer of the Original Code is Video subgroup of AVS
* Workinggroup (Audio and Video coding Standard Working Group of China).
* Contributors: Guoping Li, Siwei Ma, Jian Lou, Qiang Wang ,
* Jianwen Chen,Haiwu Zhao, Xiaozhen Zheng, Junhao Zheng, Zhiming Wang
*
******************************************************************************
*/
/*
*************************************************************************************
* File name:
* Function:
*
*************************************************************************************
*/
#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"
#include "block.h"
#ifdef FastME
#include "fast_me.h"
#endif
// 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;
int*** motion_cost_bid;
#define MEDIAN(a,b,c) (a + b + c - min(a, min(b, c)) - max(a, max(b, c))); //jlzheng 6.30
/*
******************************************************************************
* Function: calculated field or frame distance between current field(frame)
* and the reference field(frame).
* Input:
* Output:
* Return:
* Attention:
* Author: Yulj 2004.07.14
******************************************************************************
*/
int calculate_distance(int blkref, int fw_bw ) //fw_bw>=: forward prediction.
{
int distance=1;
//if( img->picture_structure == 1 ) // frame
if ( img->top_bot == -1 ) // frame
{
if ( img->type == INTER_IMG ) // P img
{
if(blkref==0)
distance = picture_distance*2 - img->imgtr_last_P_frm*2 ; // Tsinghua 200701
else if(blkref==1)
distance = picture_distance*2 - img->imgtr_last_prev_P_frm*2; // Tsinghua 200701
else
{
assert(0); //only two reference pictures for P frame
}
}
else //B_IMG
{
if (fw_bw >=0 ) //forward
distance = picture_distance*2 - img->imgtr_last_P_frm*2; // Tsinghua 200701
else
distance = img->imgtr_next_P_frm*2 - picture_distance*2; // Tsinghua 200701
}
}
//else if( !progressive_sequence )
//else if( ! img->picture_structure )
else // field
{
if(img->type==INTER_IMG)
{
if(img->top_bot==0) //top field
{
switch ( blkref )
{
case 0:
distance = picture_distance*2 - img->imgtr_last_P_frm*2 - 1 ; // Tsinghua 200701
break;
case 1:
distance = picture_distance*2 - img->imgtr_last_P_frm*2 ; // Tsinghua 200701
break;
case 2:
distance = picture_distance*2 - img->imgtr_last_prev_P_frm*2 - 1; // Tsinghua 200701
break;
case 3:
distance = picture_distance*2 - img->imgtr_last_prev_P_frm*2 ; // Tsinghua 200701
break;
}
}
else if(img->top_bot==1) // bottom field.
{
switch ( blkref )
{
case 0:
distance = 1 ;
break;
case 1:
distance = picture_distance*2 - img->imgtr_last_P_frm*2 ; // Tsinghua 200701
break;
case 2:
distance = picture_distance*2 - img->imgtr_last_P_frm*2 + 1; // Tsinghua 200701
break;
case 3:
distance = picture_distance*2 - img->imgtr_last_prev_P_frm*2 ; // Tsinghua 200701
break;
}
}
else
{
printf("Error. frame picture should not run into this branch.");
exit(-1);
}
}
else if(img->type==B_IMG)
{
if(!(blkref==0 || blkref == 1))
return 1;
assert(blkref==0 || blkref == 1);
if (fw_bw >= 0 ) //forward
{
if(img->top_bot==0) //top field
{
switch ( blkref )
{
case 0:
distance = picture_distance*2 - img->imgtr_last_P_frm*2 - 1 ; // Tsinghua 200701
break;
case 1:
distance = picture_distance*2 - img->imgtr_last_P_frm*2; // Tsinghua 200701
break;
}
}
else if(img->top_bot==1) // bottom field.
{
switch ( blkref )
{
case 0:
distance = picture_distance*2 - img->imgtr_last_P_frm*2 ; // Tsinghua 200701
break;
case 1:
distance = picture_distance*2 - img->imgtr_last_P_frm*2 + 1; // Tsinghua 200701
break;
}
}
else
{
printf("Error. frame picture should not run into this branch.");
exit(-1);
}
}
else // backward
{
if(img->top_bot==0) //top field
{
switch ( blkref )
{
case 0:
distance = img->imgtr_next_P_frm*2 - picture_distance*2; // Tsinghua 200701
break;
case 1:
distance = img->imgtr_next_P_frm*2 - picture_distance*2 + 1; // Tsinghua 200701
break;
}
}
else if(img->top_bot==1) // bottom field.
{
switch ( blkref )
{
case 0:
distance = img->imgtr_next_P_frm*2 - picture_distance*2 - 1; // Tsinghua 200701
break;
case 1:
distance = img->imgtr_next_P_frm*2 - picture_distance*2 ; // Tsinghua 200701
break;
}
}
else
{
printf("Error. frame picture should not run into this branch.");
exit(-1);
}
}
}
}
distance = (distance+512)%512; // Added by Xiaozhen ZHENG, 20070413, HiSilicon
return distance;
}
/*Lou 1016 End*/
/*Lou 1016 Start*/
//The unit of time distance is calculated by field time
int scale_motion_vector(int motion_vector, int currblkref, int neighbourblkref, int currsmbtype, int neighboursmbtype, int block_y_pos, int curr_block_y, int ref, int direct_mv)
{
int neighbour_coding_stage = -2;
int current_coding_stage = -2;
int sign = (motion_vector>0?1:-1);
int mult_distance;
int devide_distance;
motion_vector = abs(motion_vector);
if(motion_vector == 0)
return 0;
//!!!--- Yulj 2004.07.15
// The better way is to deinfe ref_frame same as index in motion search function.
// ref_frame is different from index when it is B field back ward prediction.
// change ref_frame to index for backwward prediction of B field.
// ref_frame : 1 | 0 | -2 | -1
// index: 1 | 0 | 0 | 1
// direction: f | f | b | b
if ( img->type == B_IMG && !img->picture_structure && ref < 0 )
{
currblkref = 1 - currblkref;
neighbourblkref = 1 - neighbourblkref;
}
//---end
mult_distance = calculate_distance(currblkref, ref);
devide_distance = calculate_distance(neighbourblkref, ref);
motion_vector = sign*((motion_vector*mult_distance*(512/devide_distance)+256)>>9);
// motion_vector = ((motion_vector * mult_distance * (512 / devide_distance) + 256) >> 9 );
return motion_vector;
}
/*Lou 1016 End*/
/*
*************************************************************************
* Function:setting the motion vector predictor
* Input:
* Output:
* Return:
* Attention:
*************************************************************************
*/
void SetMotionVectorPredictor (int pmv[2],
int **refFrArr,
int ***tmp_mv,
int ref_frame,
int mb_pix_x,
int mb_pix_y,
int blockshape_x,
int blockshape_y,//Lou 1016
int ref,
int direct_mv)//Lou 1016
{
int pic_block_x = (img->block_x>>1) + (mb_pix_x>>3);
int pic_block_y = (img->block_y>>1) + (mb_pix_y>>3);
int mb_nr = img->current_mb_nr;
int mb_width = img->width/16;
int mb_available_up = (img->mb_y == 0 ) ? 0 : (img->mb_data[mb_nr].slice_nr == img->mb_data[mb_nr-mb_width ].slice_nr); //jlzheng 6.23
int mb_available_left = (img->mb_x == 0 ) ? 0 : (img->mb_data[mb_nr].slice_nr == img->mb_data[mb_nr-1 ].slice_nr); // jlzheng 6.23
int mb_available_upleft = (img->mb_x == 0 ||
img->mb_y == 0 ) ? 0 : (img->mb_data[mb_nr].slice_nr == img->mb_data[mb_nr-mb_width-1].slice_nr);
int mb_available_upright = (img->mb_x >= mb_width-1 ||
img->mb_y == 0 ) ? 0 : (img->mb_data[mb_nr].slice_nr == img->mb_data[mb_nr-mb_width+1].slice_nr);
int block_available_up, block_available_left, block_available_upright, block_available_upleft;
int mv_a, mv_b, mv_c, mv_d, pred_vec=0;
int mvPredType, rFrameL, rFrameU, rFrameUR;
int hv;
int mva[3] , mvb[3],mvc[3];
/*lgp*/
int y_up = 1,y_upright=1,y_upleft=1,off_y=0;
/*Lou 1016 Start*/
int rFrameUL;
Macroblock* currMB = &img->mb_data[img->current_mb_nr];
int smbtypecurr, smbtypeL, smbtypeU, smbtypeUL, smbtypeUR;
if(input->slice_set_enable) //added by mz, 2008.04
{
mb_available_up = (img->mb_y == 0 ) ? 0 : (img->mb_data[mb_nr].slice_set_index == img->mb_data[mb_nr-mb_width ].slice_set_index);
mb_available_left = (img->mb_x == 0 ) ? 0 : (img->mb_data[mb_nr].slice_set_index == img->mb_data[mb_nr-1 ].slice_set_index);
mb_available_upleft = (img->mb_x == 0 ||
img->mb_y == 0 ) ? 0 : (img->mb_data[mb_nr].slice_set_index == img->mb_data[mb_nr-mb_width-1].slice_set_index);
mb_available_upright = (img->mb_x >= mb_width-1 ||
img->mb_y == 0 ) ? 0 : (img->mb_data[mb_nr].slice_set_index == img->mb_data[mb_nr-mb_width+1].slice_set_index);
}
smbtypecurr = -2;
smbtypeL = -2;
smbtypeU = -2;
smbtypeUL = -2;
smbtypeUR = -2;
/*Lou 1016 End*/
/* D B C */
/* A X */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -