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

📄 motion_est.c

📁 基于Linux的ffmepg decoder
💻 C
字号:
#include "encoder.h"
#include "global.h"

#include "motion.h"
#include "mbfunctions.h"

// --------------------------------------------------------------------
int32_t (*MotionEstimation)(MACROBLOCK *const pMB,
				 MACROBLOCK *const pMB_mc,
		  		 uint32_t x, uint32_t y,
		 		 MBParam * const pParam,
		 		 Encoder *pEnc,
		 		 int32_t counter) = NULL;
int32_t (*MotionEstimation_blocklast)(MACROBLOCK *const pMB_mc,
                 MBParam * const pParam,
				 Encoder *pEnc) = NULL;

int32_t (*MotionEstimation_block0)(MACROBLOCK *const pMB,Encoder * pEnc) = NULL;

//  rounded values for lambda param for weight of motion bits as in modified H.26L
static int32_t lambda_vec16[32] =	
{ 0, (int) (1.00235 + 0.5), (int) (1.15582 + 0.5), (int) (1.31976 + 0.5),
		(int) (1.49591 + 0.5), (int) (1.68601 + 0.5),
	(int) (1.89187 + 0.5), (int) (2.11542 + 0.5), (int) (2.35878 + 0.5),
		(int) (2.62429 + 0.5), (int) (2.91455 + 0.5),
	(int) (3.23253 + 0.5), (int) (3.58158 + 0.5), (int) (3.96555 + 0.5),
		(int) (4.38887 + 0.5), (int) (4.85673 + 0.5),
	(int) (5.37519 + 0.5), (int) (5.95144 + 0.5), (int) (6.59408 + 0.5),
		(int) (7.31349 + 0.5), (int) (8.12242 + 0.5),
	(int) (9.03669 + 0.5), (int) (10.0763 + 0.5), (int) (11.2669 + 0.5),
		(int) (12.6426 + 0.5), (int) (14.2493 + 0.5),
	(int) (16.1512 + 0.5), (int) (18.442 + 0.5), (int) (21.2656 + 0.5),
		(int) (24.8580 + 0.5), (int) (29.6436 + 0.5),
	(int) (36.4949 + 0.5)
};

__inline uint32_t MBTransQuantIntra_p(const MBParam * pParam, FRAMEINFO * frame,FTMCP100_CODEC *pCodec)
{
	uint32_t iQuant = frame->quant;
	int32_t index;
	DECLARE_MP4_PTR

	index = ((pCodec->even_odd_I)<<4) | 3 | (pParam->h263 << 14) | (MODE_INTRA) << 6 | pCodec->acdc_status << 11 | 0 << 15;

	if (pParam->m_quant_type == MPEG4_QUANT) {
		index |= 1 << 3;									//		MPEG Q, AC don't care, INTER
	}
	SET_QCR_0(iQuant<<18)

    #ifdef CORE_VERSION_1
	  SET_MCIADDR(INTER_Y0 + (pCodec->even_odd_1 ^ 1) * stride_MB)		///  MC Interpolation and Result Block Start Address Register
	#elif defined(CORE_VERSION_2)
	  SET_MCIADDR(INTER_Y0 + ((pCodec->triple_buffer_selector+2)%3)*stride_MB) //  MC Interpolation and Result Block Start Address Register
	#endif
	
	return index;
}


#if defined(CORE_VERSION_1)
__inline void
get_pmvdata0_4MV(const MACROBLOCK * const mbs,
         const int mb_width,
         const int x,
         const int counter,
		 VECTOR * const pmv,
		 MBParam * const pParam,FTMCP100_CODEC *pCodec)
#elif defined(CORE_VERSION_2)
__inline void
get_pmvdata0_4MV(const MACROBLOCK * const mbs,
         const int mb_width,
         const int x,
         const int counter,
		 VECTOR * const pmv,
		 MBParam * const pParam)
#else  
  #error "please define the version of core"    
#endif
{
  #if defined(CORE_VERSION_1)
    int rx;
    int tpos, rpos;
    
    if (pParam->resyn==0)
	{
        rx = x + 1;	
        tpos = counter - mb_width;
        if (tpos >= 0) {
            pmv[1].x = mbs[tpos].mv16x_2;
            pmv[1].y = mbs[tpos].mv16y_2;
            pmv[2].x = mbs[tpos].mv16x_3;
            pmv[2].y = mbs[tpos].mv16y_3;
            pCodec->SRC_X[0] = (pmv[1].x & 0x7f) << 7;
            pCodec->SRC_Y[0] = (pmv[1].y & 0x7f) << 7;
            pCodec->SRC_X[1] = (pmv[2].x & 0x7f) << 7;
            pCodec->SRC_Y[1] = (pmv[2].y & 0x7f) << 7;
        } else {
            pmv[1].x = 0;
            pmv[1].y = 0;
            pmv[2].x = 0;
            pmv[2].y = 0;
            pmv[3].x = 0;
            pmv[3].y = 0;
            pCodec->SRC_X[0] = (1 << 27) | (1 << 7) | (1 << 28) | (1 << 14);
            pCodec->SRC_Y[0] = (1 << 27) | (1 << 7) | (1 << 28) | (1 << 14);
            pCodec->SRC_X[1] = (1 << 27) | (0 << 7) | (1 << 28) | (0 << 14);
            pCodec->SRC_Y[1] = (1 << 27) | (0 << 7) | (1 << 28) | (0 << 14);
            return;        
        }
    
        rpos = tpos + 1;
        if (rx != mb_width) {
            pmv[3].x = mbs[rpos].mv16x_2;
            pmv[3].y = mbs[rpos].mv16y_2;
            pCodec->SRC_X[0] |= (pmv[3].x & 0x7f) << 14;
            pCodec->SRC_Y[0] |= (pmv[3].y & 0x7f) << 14;
            pCodec->SRC_X[1] |= (pmv[3].x & 0x7f) << 14;
            pCodec->SRC_Y[1] |= (pmv[3].y & 0x7f) << 14;
        } else {
            pmv[3].x = 0;
            pmv[3].y = 0;
        }
    }
	else
	{
        pmv[1].x = 0;
        pmv[1].y = 0;
		pmv[2].x = 0;
		pmv[2].y = 0;
		pmv[3].x = 0;
		pmv[3].y = 0;
        pCodec->SRC_X[0] = (1 << 27) | (1 << 7) | (1 << 28) | (1 << 14);
        pCodec->SRC_Y[0] = (1 << 27) | (1 << 7) | (1 << 28) | (1 << 14);
        pCodec->SRC_X[1] = (1 << 27) | (0 << 7) | (1 << 28) | (0 << 14);
        pCodec->SRC_Y[1] = (1 << 27) | (0 << 7) | (1 << 28) | (0 << 14);
	}
	pCodec->SRC_X[1] |= (1<<26);
	pCodec->SRC_Y[1] |= (1<<26);
	
  #elif defined(CORE_VERSION_2) // core version 2 of get_pmvdata0_4MV() procedure
    
    int rx;
    int tpos, rpos;

    if (pParam->resyn==0)
      {
        rx = x + 1;	
        tpos = counter - mb_width;
        if (tpos >= 0) {
          pmv[1].x = mbs[tpos].mv16x_2;
          pmv[1].y = mbs[tpos].mv16y_2;
          pmv[2].x = mbs[tpos].mv16x_3;
          pmv[2].y = mbs[tpos].mv16y_3;
          
        } else {
          pmv[1].x = 0;
          pmv[1].y = 0;
          pmv[2].x = 0;
          pmv[2].y = 0;
          pmv[3].x = 0;
          pmv[3].y = 0;
            
          return;        
        }
        rpos = tpos + 1;
        if (rx != mb_width) {
          pmv[3].x = mbs[rpos].mv16x_2;
          pmv[3].y = mbs[rpos].mv16y_2;
            
        } else {
          pmv[3].x = 0;
          pmv[3].y = 0;
        }
      }
    else
      {
        pmv[1].x = 0;
        pmv[1].y = 0;
        pmv[2].x = 0;
        pmv[2].y = 0;
        pmv[3].x = 0;
        pmv[3].y = 0;
      }
      
  #else
  
    #error "please define the version of core"
    
  #endif
}

__inline void
get_pmvdata1_4MV(const int x, int iWcount, int *a, int *b, int *c, int *d, MBParam * const pParam,FTMCP100_CODEC *pCodec)
{
    if ((x+1) >= iWcount) 
    {
        *a = 0;
        *b = 0;
        *c = 0;
        *d = 0;
        
        if (pParam->resyn==1)
		{
			pCodec->ME_command_queue0[1] = 0;
		}
    }
    return;
}

#if defined(CORE_VERSION_1)
__inline void
get_pmvdata0_1MV(const MACROBLOCK * const mbs,
         const int mb_width,
         const int x,
         const int counter,
		 VECTOR * const pmv,
         MBParam * const pParam,FTMCP100_CODEC *pCodec)
#elif defined(CORE_VERSION_2)
__inline void
get_pmvdata0_1MV(const MACROBLOCK * const mbs,
         const int mb_width,
         const int x,
         const int counter,
		 VECTOR * const pmv,
         MBParam * const pParam)
#endif
{
  #if defined(CORE_VERSION_1)

    int rx;
    int tpos, rpos;
    
	if (pParam->resyn==0)
	{
        tpos = counter - mb_width;
        if (tpos >= 0) {
            pmv[2].x = mbs[tpos].mv16x_3;
            pmv[2].y = mbs[tpos].mv16y_3;
            pCodec->SRC_X[0] = (pmv[2].x & 0x7f) << 7;
            pCodec->SRC_Y[0] = (pmv[2].y & 0x7f) << 7;
        } else {
            pmv[2].x = 0;
            pmv[2].y = 0;
            pmv[3].x = 0;
            pmv[3].y = 0;
            pCodec->SRC_X[0] = (1 << 27) | (3 << 7) | (1 << 28) | (3 << 14);
            pCodec->SRC_Y[0] = (1 << 27) | (3 << 7) | (1 << 28) | (3 << 14);
            return;        
        }
        rpos = tpos + 1;
        rx = x + 1;	
        if (rx != mb_width) {
            pmv[3].x = mbs[rpos].mv16x_3;
            pmv[3].y = mbs[rpos].mv16y_3;
            pCodec->SRC_X[0] |= (pmv[3].x & 0x7f) << 14;
            pCodec->SRC_Y[0] |= (pmv[3].y & 0x7f) << 14;
        } else {
            pmv[3].x = 0;
            pmv[3].y = 0;
        }
    }
    else
    {
		pmv[2].x = 0;
		pmv[2].y = 0;
		pmv[3].x = 0;
		pmv[3].y = 0;
		pCodec->SRC_X[0] = (1 << 28) | (1 << 27) | (3 << 7) | (3 << 14);
		pCodec->SRC_Y[0] = (1 << 28) | (1 << 27) | (3 << 7) | (3 << 14);
	}

  #elif defined(CORE_VERSION_2)

    int rx;
    int tpos, rpos;
    
	if (pParam->resyn==0)
      {
        rx = x + 1;	
        tpos = counter - mb_width;
        if (tpos >= 0) {
          pmv[2].x = mbs[tpos].mv16x_3;
          pmv[2].y = mbs[tpos].mv16y_3;
        } else {
          pmv[2].x = 0;
          pmv[2].y = 0;
          pmv[3].x = 0;
          pmv[3].y = 0;
          return;
        }

        rpos = tpos + 1;
        if (rx != mb_width) {
          pmv[3].x = mbs[rpos].mv16x_3;
          pmv[3].y = mbs[rpos].mv16y_3;
        } else {
          pmv[3].x = 0;
          pmv[3].y = 0;
        }
      }
    else
      {
        pmv[2].x = 0;
        pmv[2].y = 0;
        pmv[3].x = 0;
        pmv[3].y = 0;
      }

  #else
  
    #error "please define the version of core"
  
  #endif
}

__inline void
get_pmvdata1_1MV(const int x, int iWcount, int *a, int *b, int *Z,FTMCP100_CODEC *pCodec)
{
  #if defined(CORE_VERSION_1)
    if ((x+1) >= iWcount) {
        *a = 0;
        *b = 0;
        *Z = 0;
        pCodec->ME_command_queue0[3] = 0;
    }
    return;

  #elif defined(CORE_VERSION_2)

    if ((x+1) >= iWcount) {
        *a = 0;
        *b = 0;
        *Z = 0;
    }
    return;
    
  #else
  
    #error "please define the version of core"
  
  #endif
}


// there are quite different structures here for core version 1 , core version 2 
// and DMA optimized version of core version 2.
// If we put them into one file, that would be too large, so we separate them into different files

#if defined(CORE_VERSION_1)
  #include "motion_est_core_1.c"
#elif defined(CORE_VERSION_2)
  #include "motion_est_core_2_optimized.c"
#else  
  #error "please define the version of core , either 'CORE_VERSION_1' or 'CORE_VERSION_2' "    
#endif

⌨️ 快捷键说明

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