⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 macroblock.c

📁 AVS视频编解码器 能实现视频图像的高效率压缩 能在VC上高速运行
💻 C
📖 第 1 页 / 共 5 页
字号:
    /*
***********************************************************************
* 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 + -