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

📄 field_pixels.c

📁 avs-s最新代码,包括编码器和解码器源码
💻 C
字号:


#include <assert.h>
#include "global.h"

int calculate_distance(int blkref, int fw_bw );

#ifdef half_pixel_compensation
#define offset 2

//for P&B forward MV scaling at space domain, i.e. MV prediction
int MV_compensation(int *delt,			//delt for original MV
					int *delt2,			//delt for scaled MV
					int currblkref,		//ref index for scaled MV, i.e. forward MV of current block
					int neighbourblkref)//ref index for original MV, i.e. forward MV of neighbor block 
{
	assert(img->picture_structure == 0);
	assert(currblkref != -1);

if(img->type == P_IMG) {
	
	if(img->top_bot == 0)
	{
		if(currblkref%2 ==0 )
			*delt2 = offset;
		else
			*delt2 = 0;
	}
	else if(img->top_bot == 1)
	{
		if( currblkref%2 ==0 )
			*delt2 = -offset;
		else
			*delt2 = 0;
	}
	else
	{
		assert(0);
	}

	if(neighbourblkref == -1) { //neightbour block is Intra block or unavailable. 
		*delt = 0;				//delt value doesn't affect result.
		return -1;
	}

	if(img->top_bot == 0)
	{
		if( neighbourblkref%2 ==0 )
			*delt = offset;
		else
			*delt = 0;
	}
	else if(img->top_bot == 1)
	{
		if( neighbourblkref%2 ==0 )
			*delt = -offset;
		else
			*delt = 0;
	}
	else
	{
		assert(0);
	}
}
else if(img->type == B_IMG)
{
	if(img->top_bot == 0)
	{
		if(currblkref%2 ==0 ) 
			*delt2 = offset;
		else
			*delt2 = 0;
	}
	else if(img->top_bot == 1)
	{
		if( currblkref%2 ==0 )
			*delt2 = 0;
		else
			*delt2 = -offset;
	}
	else
	{
		assert(0);
	}

	if(neighbourblkref == -1) { 
		*delt = 0;			
		return -1;
	}

	if(img->top_bot == 0)
	{
		if( neighbourblkref%2 ==0 )
			*delt = offset;
		else
			*delt = 0;
	}
	else if(img->top_bot == 1)
	{
		if( neighbourblkref%2 ==0 )
			*delt = 0;
		else
			*delt = -offset;
	}
	else
	{
		assert(0);
	}
}
	return 0;
}

//for B backward MV scaling at space domain, i.e. MV prediction
int MV_compensation_bw(int *delt, int *delt2, int currblkref, int neighbourblkref)
{
	assert(img->picture_structure == 0);
	assert(img->type == B_IMG);
	assert(currblkref != -1);
	//assert(neighbourblkref != -1);
if(img->type == B_IMG)
{
	if(img->top_bot == 0)
	{
		if(currblkref%2 ==0 ) 
			*delt2 = 0;
		else
			*delt2 = offset;
	}
	else if(img->top_bot == 1)
	{
		if( currblkref%2 ==0 )
			*delt2 = -offset;
		else
			*delt2 = 0;
	}
	else
	{
		assert(0);
	}

	if(neighbourblkref == -1 || neighbourblkref == 2 ) {  // 1-neighbourblcref = 2  
		*delt = 0;				//delt value doesn't affect result.
		return -1;
	}

	if(img->top_bot == 0)
	{
		if( neighbourblkref%2 ==0 )
			*delt = 0;
		else
			*delt = offset;
	}
	else if(img->top_bot == 1)
	{
		if( neighbourblkref%2 ==0 )
			*delt = -offset;
		else
			*delt = 0;
	}
	else
	{
		assert(0);
	}
}
	return 0;
}

//for symmetric mode
int MV_compensation_sym(int *delt,			//delt for original MV
						int *delt2,			//delt for scaled MV
						int currblkref,		//ref_index for scaled MV,	i.e. backward MV
						int neighbourblkref)//ref_index for original MV, i.e. forward MV
{
	assert(img->picture_structure == 0);
	assert(currblkref != -1);
	assert(neighbourblkref != -1);

if(img->type == B_IMG)
{
	if(img->top_bot == 0)
	{
		if(currblkref%2 ==0 ) 
			*delt2 = 0;
		else
			*delt2 = offset;
	}
	else if(img->top_bot == 1)
	{
		if( currblkref%2 ==0 )
			*delt2 = -offset;
		else
			*delt2 = 0;
	}
	else
	{
		assert(0);
	}


	if(img->top_bot == 0)
	{
		if( neighbourblkref%2 ==0 )
			*delt = offset;
		else
			*delt = 0;
	}
	else if(img->top_bot == 1)
	{
		if( neighbourblkref%2 ==0 )
			*delt = 0;
		else
			*delt = -offset;
	}
	else
	{
		assert(0);
	}
}
	return 0;
}

//for direct mode,
int MV_compensation_fw_fw(int *delt,		//delt for original MV
						int *delt2,			//delt for scaled MV
						int currblkref,		//ref_index for scaled MV,	i.e. forward MV of current block
						int neighbourblkref)//ref_index for original MV, i.e. forward MV of the co-located block
{
	assert(img->picture_structure == 0);
	assert(img->type == B_IMG);
	assert(currblkref != -1);
	assert(neighbourblkref != -1);
if(img->type == B_IMG)
{
	if(img->top_bot == 0)
	{
		if(currblkref%2 ==0 ) 
			*delt2 = offset;
		else
			*delt2 = 0;
	}
	else if(img->top_bot == 1)
	{
		if( currblkref%2 ==0 )
			*delt2 = 0;
		else
			*delt2 = -offset;
	}
	else
	{
		assert(0);
	}


	if(img->top_bot == 0)
	{
		if( neighbourblkref%2 ==0 )
			*delt = offset;
		else
			*delt = 0;
	}
	else if(img->top_bot == 1)
	{
		if( neighbourblkref%2 ==0 )
			*delt = -offset;
		else
			*delt = 0;
	}
	else
	{
		assert(0);
	}
}
	return 0;
}

//for direct mode,
int MV_compensation_fw_bw(int *delt,		//delt for original MV
						int *delt2,			//delt for scaled MV
						int currblkref,		//ref_index for scaled MV,	 i.e. backward MV of current block
						int neighbourblkref)//ref_index for original MV, i.e. forward MV of the co-located block
{
	assert(img->picture_structure == 0);
	assert(img->type == B_IMG);
	assert(currblkref != -1);
	assert(neighbourblkref != -1);
if(img->type == B_IMG)
{
	if(img->top_bot == 0)
	{
		if(currblkref%2 ==0 ) 
			*delt2 = 0;
		else
			*delt2 = offset;
	}
	else if(img->top_bot == 1)
	{
		if( currblkref%2 ==0 )
			*delt2 = -offset;
		else
			*delt2 = 0;
	}
	else
	{
		assert(0);
	}


	if(img->top_bot == 0)
	{
		if( neighbourblkref%2 ==0 )
			*delt = offset;
		else
			*delt = 0;
	}
	else if(img->top_bot == 1)
	{
		if( neighbourblkref%2 ==0 )
			*delt = -offset;
		else
			*delt = 0;
	}
	else
	{
		assert(0);
	}
}
	return 0;
}

//to replace MV scaling in MV prediction
//only valid for MV_y
int scale_motion_vector_pixel(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;

    	int delt=0, delt2=0; 
		assert(currblkref != -1);

		if(ref >= 0) { //forward prediction
			MV_compensation(&delt, &delt2, currblkref, neighbourblkref);
		}else
		{
			assert(img->type == B_IMG);
			//MV_compensation_bw(&delt, &delt2, 1-currblkref, 1-neighbourblkref);
			MV_compensation_bw(&delt, &delt2, currblkref, neighbourblkref); //note: the bw_ref is just different to that in encoder
		}

		if(neighbourblkref == -1 ) { //intra or unavailable block
			assert(motion_vector == 0);
			return 0;
		}

	motion_vector = motion_vector + delt;
	sign = (motion_vector>0?1:-1); 

  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)) - delt2;
  //motion_vector = sign*((motion_vector*mult_distance*(512/devide_distance)+256)>>9);
 
  return motion_vector;
}

#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -