📄 macroblock.c
字号:
/*
***********************************************************************
* COPYRIGHT AND WARRANTY INFORMATION
*
* Copyright 2003, Advanced Audio Video Coding Standard, Part II
*
* DISCLAIMER OF WARRANTY
*
* These software programs are available to the users without any
* license fee or royalty on an "as is" basis. The AVS 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 contributors or
* the AVS be liable for any incidental, punitive, or consequential
* damages of any kind whatsoever arising from the use of this program.
*
* This disclaimer of warranty extends to the user of this program
* and user's customers, employees, agents, transferees, successors,
* and assigns.
*
* The AVS does not represent or warrant that the program furnished
* hereunder 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 is available from the AVS Web site at
* http://www.avs.org.cn
*
* THIS IS NOT A GRANT OF PATENT RIGHTS - SEE THE AVS PATENT POLICY.
************************************************************************
*/
/*
*************************************************************************************
* File name: macroblock.c
* Function: Decode a Macroblock
*
*************************************************************************************
*/
#include "contributors.h"
#include <math.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>
#include "global.h"
#include "mbuffer.h"
#include "elements.h"
#include "macroblock.h"
#include "vlc.h"
#include "defines.h"
#include "block.h"
void readReferenceIndex(struct img_par *img, struct inp_par *inp);
void readMotionVector(struct img_par *img, struct inp_par *inp);
#define MODE_IS_P8x8 (mbmode==4)
#define MODE_IS_I4x4 (mbmode==5) //xfwang modify 2004.7.29
#define I16OFFSET (mbmode-7)
#define fwd_ref_idx_to_refframe(idx) ((idx)+fwd_refframe_offset)
#define bwd_ref_idx_to_refframe(idx) ((idx)+bwd_refframe_offset)
/*
******************************************************************************
* Function: calculated field or frame distance between current field(frame)
* and the reference field(frame).
* Input:
* Output:
* Return:
* Attention:
* Author: Yulejun // 2004.07.14
******************************************************************************
*/
int calculate_distance_old(int blkref, int fw_bw ) //fw_bw>=0: forward ; fw_bw<0: backward
{
int distance;
if( img->picture_structure == 1 )
{
if ( img->type==P_IMG ) // P img
{
if(blkref==0)
distance = img->tr*2 - img->imgtr_last_P*2;
else if(blkref==1)
distance = img->tr*2 - img->imgtr_last_prev_P*2;
else
{
assert(0); //only two reference pictures for P frame
}
}
else //B_IMG
{
if (fw_bw >=0 ) //forward
distance = img->tr*2 - img->imgtr_last_P*2;
else
distance = img->imgtr_next_P*2 - img->tr*2;
}
}
else if( ! img->picture_structure )
{
if(img->type==P_IMG)
{
if(img->top_bot==0) //top field
{
switch ( blkref )
{
case 0:
distance = img->tr*2 - img->imgtr_last_P*2 - 1 ;
break;
case 1:
distance = img->tr*2 - img->imgtr_last_P*2 ;
break;
case 2:
distance = img->tr*2 - img->imgtr_last_prev_P*2 - 1;
break;
case 3:
distance = img->tr*2 - img->imgtr_last_prev_P*2 ;
break;
}
}
else if(img->top_bot==1) // bottom field.
{
switch ( blkref )
{
case 0:
distance = 1 ;
break;
case 1:
distance = img->tr*2 - img->imgtr_last_P*2 ;
break;
case 2:
distance = img->tr*2 - img->imgtr_last_P*2 + 1;
break;
case 3:
distance = img->tr*2 - img->imgtr_last_prev_P*2 ;
break;
}
}
else
{
printf("Error. frame picture should not run into this branch.");
exit(-1);
}
}
else if(img->type==B_IMG)
{
assert(blkref==0 || blkref == 1);
if (fw_bw >= 0 ) //forward
{
if(img->top_bot==0) //top field
{
switch ( blkref )
{
case 0:
distance = img->tr*2 - img->imgtr_last_P*2 - 1 ;
break;
case 1:
distance = img->tr*2 - img->imgtr_last_P*2;
break;
}
}
else if(img->top_bot==1) // bottom field.
{
switch ( blkref )
{
case 0:
distance = img->tr*2 - img->imgtr_last_P*2 ;
break;
case 1:
distance = img->tr*2 - img->imgtr_last_P*2 + 1;
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*2 - img->tr*2;
break;
case 1:
distance = img->imgtr_next_P*2 - img->tr*2 + 1;
break;
}
}
else if(img->top_bot==1) // bottom field.
{
switch ( blkref )
{
case 0:
distance = img->imgtr_next_P*2 - img->tr*2 - 1;
break;
case 1:
distance = img->imgtr_next_P*2 - img->tr*2 ;
break;
}
}
else
{
printf("Error. frame picture should not run into this branch.");
exit(-1);
}
}
}
}
return distance;
}
/*
******************************************************************************
* Function: calculated field or frame distance between current field(frame)
* and the reference field(frame).
* Input: blkref
fw_bw
* Output: distance for motion vector scale
* Return:
* Attention:
* Author: Yulejun // 2004.07.14
******************************************************************************
*/
// The funtion int calculate_distance(int blkref, int fw_bw ) is modified by Xiaozhen Zheng, HiSilicon, 20070327.
// At the modified version, 'img->tr' is replaced by 'picture_distance', which is used to calculate DistanceIndex and BlockDistance.
int calculate_distance(int blkref, int fw_bw ) //fw_bw>=0: forward ; fw_bw<0: backward
{
int distance;
if( img->picture_structure == 1 ) //frame coding
{
if ( img->type==P_IMG ) // P img
{
if(blkref==0)
distance = picture_distance*2 - img->imgtr_last_P*2;
else if(blkref==1)
distance = picture_distance*2 - img->imgtr_last_prev_P*2;
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*2;
else
distance = img->imgtr_next_P*2 - picture_distance*2;
}
}
else if( ! img->picture_structure ) //field coding
{
if(img->type==P_IMG)
{
if(img->top_bot==0) //top field
{
switch ( blkref )
{
case 0:
distance = picture_distance*2 - img->imgtr_last_P*2 - 1 ;
break;
case 1:
distance = picture_distance*2 - img->imgtr_last_P*2 ;
break;
case 2:
distance = picture_distance*2 - img->imgtr_last_prev_P*2 - 1;
break;
case 3:
distance = picture_distance*2 - img->imgtr_last_prev_P*2 ;
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*2 ;
break;
case 2:
distance = picture_distance*2 - img->imgtr_last_P*2 + 1;
break;
case 3:
distance = picture_distance*2 - img->imgtr_last_prev_P*2 ;
break;
}
}
else
{
printf("Error. frame picture should not run into this branch.");
exit(-1);
}
}
else if(img->type==B_IMG)
{
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*2 - 1 ;
break;
case 1:
distance = picture_distance*2 - img->imgtr_last_P*2;
break;
}
}
else if(img->top_bot==1) // bottom field.
{
switch ( blkref )
{
case 0:
distance = picture_distance*2 - img->imgtr_last_P*2 ;
break;
case 1:
distance = picture_distance*2 - img->imgtr_last_P*2 + 1;
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*2 - picture_distance*2;
break;
case 1:
distance = img->imgtr_next_P*2 - picture_distance*2 + 1;
break;
}
}
else if(img->top_bot==1) // bottom field.
{
switch ( blkref )
{
case 0:
distance = img->imgtr_next_P*2 - picture_distance*2 - 1;
break;
case 1:
distance = img->imgtr_next_P*2 - picture_distance*2 ;
break;
}
}
else
{
printf("Error. frame picture should not run into this branch.");
exit(-1);
}
}
}
}
return distance;
}
/*Lou 1016 Start*/
//The unit of time distance is calculated by field time
/*
*************************************************************************
* Function:
* Input:
* Output:
* Return:
* Attention:
*************************************************************************
*/
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 sign = (motion_vector>0?1:-1);
int mult_distance;
int devide_distance;
motion_vector = abs(motion_vector);
if(motion_vector == 0)
return 0;
mult_distance = calculate_distance( currblkref, ref );
devide_distance = calculate_distance(neighbourblkref, ref);
motion_vector = sign*((motion_vector*mult_distance*(512/devide_distance)+256)>>9);
return motion_vector;
}
/*Lou 1016 End*/
/*
*************************************************************************
* Function:Set motion vector predictor
* Input:
* Output:
* Return:
* Attention:
*************************************************************************
*/
static void SetMotionVectorPredictor (struct img_par *img,
int *pmv_x,
int *pmv_y,
int ref_frame,
int **refFrArr,
int ***tmp_mv,
int block_x,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -