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

📄 mot_est.cpp

📁 H.263的编码程序,加了CPU指令优化,VC版.
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/*!
********************************************************
*\file
*    mot_est.cpp
*\brief
*    implementation for functions which is used for motion estimation.
*\date
*    12/6/2002
*
********************************************************/
#include <stdio.h>
#include <stdlib.h>
#include "mot_est.h"

#define MAX_SAD       99999    //!< MAX_SAD  
#define PREF_NULL_VEC 100      //!< according to tmn
#define PREF_16_VEC   200      //!< according to tmn

//#define PRINTMV

//!MVFAST STRUCTURE
typedef struct  {
	int x;
	int y;
	int iStartNmbr;	
	   } DPOINT;
//!MVFAST STRUCTURE       
typedef struct   {
	   int   no_check_pts;
	   DPOINT dpoint[8];
       } DIAMOND;
//!MVFAST DATA USED
static DIAMOND diamond[3]={
	{4,{{0,1,3},{1,0,0},{0,-1,1},{-1,0,2}}},
	{8,{{0,2,6},{1,1,0},{2,0,0},{1,-1,2},{0,-2,2},{-1,-1,4},{-2,0,4},{-1,1,6}}},
	{3,{{0,0,0},{0,0,0,},{0,0,0}}}
};
//!MVFAST STRUCTURE
enum {SDiamond, LDiamond, MotAdaptPat} dType;  
/*!
*******************************************************************************
*
*   Name:          interpolate_lum
*   Description:   make interpolated lum image for 1/2 pel mv search
*   Input:          
*   Output:        
*   Side effect:   fill the buffer for interpolated image(encoder->prev_ipol) 
*   Optimization:  NO
*   Last modified: 2002/11/21
*
*******************************************************************************/
void interpolate_lum_c(H263VencStatus *encoder)
{
	int width  = encoder->mv_outside_frame ? encoder->pels+32 : encoder->pels;
	int height = encoder->mv_outside_frame ? encoder->lines+32: encoder->lines;
	unsigned char *oo = encoder->mv_outside_frame ? (encoder->frame_buf[encoder->ref_index]).pLum-width*16-16 : (encoder->frame_buf[encoder->ref_index]).pLum;
	unsigned char *ii = encoder->mv_outside_frame ? encoder->prev_ipol-width*64-32 : encoder->prev_ipol;
	int i, j;
	
    if (encoder->PTYPE == B_IMG)
	{
		/* for backward mv search */
		// it is always permitted that MVs be across the picture boundary
		oo = encoder->frame_buf[encoder->zero_index].pLum - width*16 - 16;
		ii = encoder->next_ipol - width*64 - 32;
	}

	/* main image */
	for (j = 0; j < height-1; j++) 
	{
		for (i = 0; i  < width-1; i++) 
		{
			*(ii + (i<<1)) = *(oo + i);
			*(ii + (i<<1)+1) = (*(oo + i) + *(oo + i + 1) + 1)>>1;
			*(ii + (i<<1)+(width<<1)) = (*(oo + i) + *(oo + i + width) + 1)>>1;
			*(ii + (i<<1)+1+(width<<1)) = (*(oo+i) + *(oo+i+1) + 
				                           *(oo+i+width) + *(oo+i+1+width) + 2)>>2;
		}
		/* last pels on each line */
		*(ii+ (width<<1) - 2) = *(oo + width - 1);
		*(ii+ (width<<1) - 1) = *(oo + width - 1);
		*(ii+ (width<<1)+ (width<<1)-2) = (*(oo+width-1)+*(oo+width+width-1)+1)>>1;
		*(ii+ (width<<1)+ (width<<1)-1) = (*(oo+width-1)+*(oo+width+width-1)+1)>>1;
		ii += (width<<2);
		oo += width;
	}
	
	/* last lines */
	for (i = 0; i < width-1; i++) 
	{
		*(ii+ (i<<1)) = *(oo + i);    
		*(ii+ (i<<1)+1) = (*(oo + i) + *(oo + i + 1) + 1)>>1;
		*(ii+ (width<<1)+ (i<<1)) = *(oo + i);    
		*(ii+ (width<<1)+ (i<<1)+1) = (*(oo + i) + *(oo + i + 1) + 1)>>1;
		
	}
	
	/* bottom right corner pels */
	*(ii + (width<<1) - 2) = *(oo + width -1);
	*(ii + (width<<1) - 1) = *(oo + width -1);
	*(ii + (width<<2) - 2) = *(oo + width -1);
	*(ii + (width<<2) - 1) = *(oo + width -1);

}



/*!
*******************************************************************************
*
*   Name:          grabVec
*   Description:   refine best motion vectors and choose best mode for all mbs
*                  of one picture
*   Input:         the pointer of encoder strcture and MC structure
*   Output:        MV(in MC structure)
*   Last modified: 2002/11/21
*
*******************************************************************************/
void grabVec(H263VencStatus *encoder, MCParam *MC, int BACKWARD)
{
	int i, j;
	int pix_x, pix_y;
	int pix_x_8, pix_y_8;
	int block;
	int x_center, y_center;
	int sad_gate = 512;
	void (*mv_search) (H263VencStatus*, MCParam*, int, int, int, int);  //!< search functions
// added by lcl on 2003/2/26, parameter for calculation of SAD
	int lx1 = encoder->pels;
	int lx2 = encoder->mv_outside_frame ? encoder->pels+32 : encoder->pels;
	unsigned char *p1 = (encoder->frameToEncode).pLum ;

	if (encoder->PTYPE == B_IMG)
	{
		p1 = (encoder->BPicture[encoder->B_count]).pLum;
	}	
	//! choose search method
	if (0 == MC->method)
	{
		mv_search = mv_search_fs;
	}
	else if(1 == MC->method)
	{
		mv_search = mv_search_dmd;
	}
	else
	{
		printf("Invalid MV search method");
		exit(-1);
	}

    /*! main loop */
	for (pix_y = 0, i = 0; pix_y < encoder->lines; pix_y+=16, i++)
	{
		for (pix_x = 0, j = 0; pix_x < encoder->pels; pix_x+=16, j++)
		{
			if (!BACKWARD)
			{  
				/* Forward MV search(for both P frames and B frames). */
				
				MC->mv = MC->mv_frame[0][i+1][j+1];     //!< assign a pointer for current mv
				//! check zero point ahead of searching
				(MC->mv)->x = 0;
				(MC->mv)->y = 0;
				(MC->mv)->min_sad = encoder->method.me_sad_a(lx1, lx2, pix_x, pix_y, pix_x, pix_y, p1,
					                              encoder->frame_buf[encoder->ref_index].pLum,
                                                  MAX_SAD, 16) - PREF_NULL_VEC;
			//	(MC->mv)->min_sad = me_sad_a(encoder, pix_x, pix_y, pix_x, pix_y, MAX_SAD, 16, 0) - PREF_NULL_VEC;
				if ((MC->mv)->min_sad > sad_gate)
				{
					mv_search(encoder, MC, pix_x, pix_y, 16, BACKWARD);  //!< search integer mv (predictor of mv not used)
				}
				findhalfpel(encoder, MC, pix_x, pix_y, 16, BACKWARD);
				
				//! 8x8 block Search(only for P frames).
				if (encoder->use4mv && (encoder->PTYPE!=B_IMG))
				{
					for (block = 0; block < 4; block++)
					{
						pix_x_8 = pix_x+((block&1)<<3);
						pix_y_8 = pix_y+((block&2)<<2);
						MC->mv = MC->mv_frame[block+1][i+1][j+1];   //!< assign a pointer
						// decide searching center 
						x_center = MC->mv_frame[0][i+1][j+1]->x;
						y_center = MC->mv_frame[0][i+1][j+1]->y;
						if (x_center > 15 - MC->search_range_8x8) { x_center =  15 - MC->search_range_8x8; }
						if (y_center > 15 - MC->search_range_8x8) { y_center =  15 - MC->search_range_8x8; }
						if (x_center < -15 + MC->search_range_8x8) { x_center =  -15 + MC->search_range_8x8; }
						if (y_center < -15 + MC->search_range_8x8) { y_center =  -15 + MC->search_range_8x8; }
						// do pre-search check
						(MC->mv)->x = x_center;
						(MC->mv)->y = y_center;
						(MC->mv)->min_sad = encoder->method.me_sad_a(lx1, lx2, pix_x_8, pix_y_8, pix_x_8+x_center, pix_y_8+y_center, p1,
							                              encoder->frame_buf[encoder->ref_index].pLum, MAX_SAD, 8);
			//			(MC->mv)->min_sad = me_sad_a(encoder, pix_x_8, pix_y_8, pix_x_8+x_center, pix_y_8+y_center, MAX_SAD, 8, 0);
						if((MC->mv)->min_sad > sad_gate/4)
						{
							mv_search(encoder, MC, pix_x_8, pix_y_8, 8, BACKWARD);
						}
						findhalfpel(encoder, MC, pix_x_8, pix_y_8, 8, BACKWARD);
					}
				}
			}
			else
			{
				/*! Backward MV Search(only for B frames). */

				if (encoder->PTYPE == B_IMG)
				{
					MC->mv = MC->mv_frame[5][i+1][j+1];         //!< assign a pointer
					// check zero point ahead of searching
					(MC->mv)->x = 0;
					(MC->mv)->y = 0;
                    (MC->mv)->min_sad = encoder->method.me_sad_a(lx1, lx2, pix_x, pix_y, pix_x, pix_y, p1,
						                              encoder->frame_buf[encoder->zero_index].pLum,
													  MAX_SAD, 16) - PREF_NULL_VEC;
				//	(MC->mv)->min_sad = me_sad_a(encoder, pix_x, pix_y, pix_x, pix_y, MAX_SAD, 16, 1) - PREF_NULL_VEC;
					if ((MC->mv)->min_sad > sad_gate)
					{
						mv_search(encoder, MC, pix_x, pix_y, 16, BACKWARD);  //!< search integer mv (predictor of mv not used)
					}
					findhalfpel(encoder, MC, pix_x, pix_y, 16, BACKWARD);
				}
			}
			/* Choose mode(only for P frames, prediction mode of B frames 
			   will be decided outside).        */
			if (encoder->PTYPE != B_IMG)    
			{
				choose_mode(encoder, MC, pix_x, pix_y);
			}
#ifdef PRINTMV
			printmv(encoder, MC, i, j, BACKWARD);
#endif
		}
#ifdef PRINTMV
		printf("\n");
#endif
	}
}

/*!
*******************************************************************************
*
*   Name:          FindPMV
*   Description:   find predictor for mv of current block
*   Input:         Array of motion vectors, positon of current block
*   Output:        x value and y value of predictor
*   Last modified: 2002/11/23 by lcl
*
*******************************************************************************/

void FindPMV(MotionVector *MV[6][MBR+1][MBC+2], int x, int y, 
             int *pmv0, int *pmv1, int block, int newgob, int half_pel)
{
	int p1,p2,p3;
	int xin1,xin2,xin3;
	int yin1,yin2,yin3;
	int vec1,vec2,vec3;
	int l8,o8,or8;
	
	
	l8 = o8 = or8 = 0;
	if ((MV[0][y][x-1]->Mode == MODE_INTER4V) || (MV[0][y][x-1]->Mode == MODE_INTER4V_Q))
	{
		l8 = 1;
	}
	
	if ((MV[0][y-1][x]->Mode == MODE_INTER4V) || (MV[0][y-1][x]->Mode == MODE_INTER4V_Q))
	{
		o8 = 1;
	}
	
	if ((MV[0][y-1][x+1]->Mode == MODE_INTER4V || MV[0][y-1][x+1]->Mode == MODE_INTER4V_Q))
	{
		or8 = 1;
	}
	
	
	switch (block) 
	{
	case 0: 
		vec1 = (l8 ? 2 : 0) ; yin1 = y  ; xin1 = x-1;
		vec2 = (o8 ? 3 : 0) ; yin2 = y-1; xin2 = x;
		vec3 = (or8? 3 : 0) ; yin3 = y-1; xin3 = x+1;
		break;
	case 1:
		vec1 = (l8 ? 2 : 0) ; yin1 = y  ; xin1 = x-1;
		vec2 = (o8 ? 3 : 0) ; yin2 = y-1; xin2 = x;
		vec3 = (or8? 3 : 0) ; yin3 = y-1; xin3 = x+1;
		break;
	case 2:
		vec1 = 1            ; yin1 = y  ; xin1 = x;
		vec2 = (o8 ? 4 : 0) ; yin2 = y-1; xin2 = x;
		vec3 = (or8? 3 : 0) ; yin3 = y-1; xin3 = x+1;
		break;
	case 3:
		vec1 = (l8 ? 4 : 0) ; yin1 = y  ; xin1 = x-1;
		vec2 = 1            ; yin2 = y  ; xin2 = x;
		vec3 = 2            ; yin3 = y  ; xin3 = x;
		break;
	case 4:
		vec1 = 3            ; yin1 = y  ; xin1 = x;
		vec2 = 1            ; yin2 = y  ; xin2 = x;
		vec3 = 2            ; yin3 = y  ; xin3 = x;
		break;
	default:
		fprintf(stderr,"Illegal block number in FindPMV (countbit.c)\n");
		exit(-1);
		break;
	}
	if (half_pel)
	{
		p1 = 2*MV[vec1][yin1][xin1]->x + MV[vec1][yin1][xin1]->x_half;
		p2 = 2*MV[vec2][yin2][xin2]->x + MV[vec2][yin2][xin2]->x_half;
		p3 = 2*MV[vec3][yin3][xin3]->x + MV[vec3][yin3][xin3]->x_half;
	}
	else 
	{
		p1 = 2*MV[vec1][yin1][xin1]->x;
		p2 = 2*MV[vec2][yin2][xin2]->x;
		p3 = 2*MV[vec3][yin3][xin3]->x;
	}
	if (newgob && (block == 0 || block == 1 || block == 2))
	{
		p2 = 2 * NO_VEC;   //!< MV above can not be accessed 
	}
	if (p2 == 2*NO_VEC)
	{
		p2 = p3 = p1;      //!< When MV above can not be accessed, use left MV instead 
	}
	
	*pmv0 = p1+p2+p3 - mmax(p1,mmax(p2,p3)) - mmin(p1,mmin(p2,p3));
    
	if (half_pel) 
	{
		p1 = 2*MV[vec1][yin1][xin1]->y + MV[vec1][yin1][xin1]->y_half;
		p2 = 2*MV[vec2][yin2][xin2]->y + MV[vec2][yin2][xin2]->y_half;
		p3 = 2*MV[vec3][yin3][xin3]->y + MV[vec3][yin3][xin3]->y_half;
	}
	else 
	{
		p1 = 2*MV[vec1][yin1][xin1]->y;
		p2 = 2*MV[vec2][yin2][xin2]->y;
		p3 = 2*MV[vec3][yin3][xin3]->y;
	}    
	if (newgob && (block == 0 || block == 1 || block == 2))
	{
		p2 = 2 * NO_VEC;   //!< MV above can not be accessed 
	}
	if (p2 == 2*NO_VEC)
	{
		p2 = p3 = p1;      //!< When MV above can not be accessed, use left MV instead 
	}
	
	*pmv1 = p1+p2+p3 - mmax(p1,mmax(p2,p3)) - mmin(p1,mmin(p2,p3));
	
}
/*!
*******************************************************************************
*
*   Name:          FindPMV_B
*   Description:   find predictor for mv of current block for B picture
*   Input:         Array of motion vectors, positon of current block
*   Output:        x value and y value of predictor
*   Last modified: 2003/1/13 by lcl
*
*******************************************************************************/
void FindPMV_B(MotionVector *MV[6][MBR+1][MBC+2], int x, int y, 
             int *pmv0, int *pmv1, int newgob, int half_pel, int BACKWARD)
{
	int vec = BACKWARD ? 5 : 0;
	int yin1 = y; 
	int xin1 = x-1;
	int yin2 = y-1; 
	int xin2 = x;
	int yin3 = y-1; 
	int xin3 = x+1;
	int p1, p2, p3;

	
	if (half_pel)
	{
		p1 = 2*MV[vec][yin1][xin1]->x + MV[vec][yin1][xin1]->x_half;
		p2 = 2*MV[vec][yin2][xin2]->x + MV[vec][yin2][xin2]->x_half;
		p3 = 2*MV[vec][yin3][xin3]->x + MV[vec][yin3][xin3]->x_half;
	}
	else 
	{

⌨️ 快捷键说明

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