📄 umc_me.h
字号:
/* /////////////////////////////////////////////////////////////////////////////
//
// INTEL CORPORATION PROPRIETARY INFORMATION
// This software is supplied under the terms of a license agreement or
// nondisclosure agreement with Intel Corporation and may not be copied
// or disclosed except in accordance with the terms of that agreement.
// Copyright(c) 2007 Intel Corporation. All Rights Reserved.
//
//
// motion estimation
//
*/
#include "umc_defs.h"
#include "umc_structures.h"
#ifndef _UMC_ME_H_
#define _UMC_ME_H_
#include <ippdefs.h>
#include <ippvc.h>
#include <ippi.h>
//#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#define VC1ABS(value) ((value)*(2*((value)>>15)+1))
namespace UMC
{
typedef enum
{
IntegerPixel = 0x0,
HalfPixel = 0x1,
QuarterPixel = 0x2
} MePixelType;
typedef enum
{
IntegerPixIn = IntegerPixel,
HalfPixIn = HalfPixel,
QuarterPixIn = QuarterPixel,
QuadPixIn
} MeInPixType;
typedef enum
{
Mb16x16 = 0x00000001,
Mb16x8 = 0x00000002,
Mb8x16 = 0x00000004,
Mb8x8 = 0x00000008,
Mb4x8x8 = 0x00000010,
Mb4x4 = 0x00000020
} MeMbPart;
typedef enum
{
Bilinear,
Vc1QpBicubic
} MeInterpolation;
typedef enum
{
forward_search = 0,
bidir_search
}MeSearchDirection;
typedef struct _MeSearchRange
{
Ipp32s x;
Ipp32s y;
}MeSearchRange;
typedef struct _MePoint
{
Ipp32s x;
Ipp32s y;
}MePoint;
typedef struct _MePicRange
{
MePoint top_left;
MePoint bottom_right;
}MePicRange;
typedef enum
{
MbIntra,
MbFrw,
MbBkw,
MbBidir,
MbFrw_Skipped,
MbBkw_Skipped,
MbBidir_Skipped,
MbDirect
} MeMbType;
typedef enum
{
FrmIntra,
FrmFrw,
FrmBidir
} MeFrameType;
typedef enum
{
Small,
Medium,
Big
} MeDiamondType;
typedef enum
{
SAD,
SADT,
MAXAD
} MeCostEnum;
typedef enum
{
sad,
sadt,
maxad
} MeSkippedMetrics;
typedef enum
{
non_skipped,
skipped_forward,
skipped_backward,
skipped_bidir,
direct
} MeSkippedStatus;
typedef union
{
Ipp32s sum;
Ipp16u sum8x8[4];
} MeCost;
//*******************************************************************************************************
class MeMV
{
public:
MeMV(){};
MeMV(int a0){x = (Ipp16s)a0; y=(Ipp16s)a0;};
MeMV(int a0, int a1){x = (Ipp16s)a0; y=(Ipp16s)a1;};
Ipp16s x;
Ipp16s y;
inline MeMV operator + (const MeMV& a)
{return MeMV(a.x + x, a.y + y);};
inline bool operator == (const MeMV& a)
{return a.x==x && a.y==y;};
};
/*
struct _MeDirectMV
{
MeMV VDirectFW;
MeMV VDirectBW;
}MeDirectMV;
*/
class MeMbStat{
public:
Ipp16u whole; //whole MB size in bit, including MV, coefficients and any additional info. TODO: should we further separate additional info?
Ipp16u* MV; //size of each MVs in bit, number of allocated element is MeFrame::NumOfMVs
Ipp16u* coeff; //size of coeffficients in bit, for each block. Number of element is the same as for MeMB::MbCosts.
//Block is motion compensated entity, not the transformation block. So if there is only one MV for MB,
//then only one element is set here, even if 4x4 trunsformation was used. It is intended for simplifying
//feedback implementation.
Ipp16u qp; // QP used for encoding of this MB
};
class MeMB {
public:
MeMV* MVs; //best found MVs, order: <16x16 fwd> or <16x16 bkw> or <16x16 fwd, 16x16 bkw> or <8x8 block 0 fwd, block1 fwd, ..., block 0 bkw, ...>
// TODO: allocate half MbCosts for bidir prediction
Ipp32s* MbCosts; //costs of best MVs, number of allocated elements is equal to number ov MVs, but only half are used in case of bidir prediction
Ipp8u MbPart; //MB partitioning 16x16, 16x8, 8x16, 8x8, 4x4 -> MeMbPart
Ipp8u BlockPart; //block partitioning, 4x2 bits field, 00 - 8x8, 01 - 8x4, 10 - 4x8, 11 - 4x4
Ipp8u MbType; // MbIntra,MbFrw,MbBkw,MbBidir,MbFrw_Skipped,MbBkw_Skipped,MbBidir_Skipped,MbDirect -> MeMbType
Ipp8u BlockTrans; //block transforming, 4x2 bits field, 00 - 8x8, 01 - 8x4, 10 - 4x8, 11 - 4x4
Ipp8u* Difference; //NULL - no differences was calculated
bool is_A_active;//is MBA taken in accordance;
bool is_C_active;//is MBC taken in accordance;
};
class MeFrame {
public:
#ifdef ME_NEW_INTERFACE
Ipp8u* ptr[3]; //YUV pointers
Ipp32s step[3]; //YUV steps
Ipp32u qp; //proposed QP, will be used in mode decision
#endif
MeFrameType Type;
Ipp32s Index; // TODO: is it really necessary?
Ipp32s NumOfMVs; //num of MVs in MBs structure
MeMB* MBs; //allocated by MeBase
MeMbStat* stat; //allocated by MeBase
};
//*******************************************************************************************************
//it may be used to query estimator capabilities
//use in initialization of MeBase
typedef struct _MeInnerParams
{
MeInPixType SPixelType;
Ipp32u UseMvPrediction;
Ipp32u UseLowThresholdForMvPrediction;
Ipp32u UseDownSampledImageForSearch;
Ipp32u UseFastIntraInterDecision;
Ipp32s SearchSpeed; //0-127, 0 - maximum quality, 127 - maximum speed, -1 use specified parameters
}MeInnerParams;
typedef struct _MeInitParams
{
Ipp32s width; //frame width
Ipp32s height;
Ipp32s refPadding; //at least 32 bits on each side
MeSearchDirection SearchDirection;//forward, bidir
MeMbPart MbPart;//16x16,16x8,8x16,8x8,4x8x8,4x4
VideoStreamType m_stream_type;//VC1_VIDEO,MPEG2_VIDEO...
// MeSkippedMetrics SkippedMetrics;
MeCostEnum CostMetrics;//SAD or SADT
}MeInitParams;
class MeParams
{
public:
#ifdef ME_NEW_INTERFACE
MeFrame* pSrc;
Ipp32s FirstMB; //for multy threading slice processing
Ipp32s LastMB;
Ipp32s NumOfRefFrames;
MeFrame** pRefFY; //array of forward reference frames, allocated by encoder
MeFrame** pRefBY; //array of backward reference frames, allocated by encoder
bool UseHW; //use HW for estimation, if HW doesn't support this set of parameters, EstimateFrame will fall
//call GetHWCapabilities() first to check HW capabilities
#else
Ipp8u *pSrcY;
Ipp32s srcStep;
Ipp8u** pRefFY; //array of forward reference frames, allocated by encoder
Ipp8u** pRefBY; //array of backward reference frames, allocated by encoder
Ipp32s refStep;
#endif
MeMV* MVDirectFW;//pointer to the array of direct forward for each MB
MeMV* MVDirectBW;//pointer to the array of direct backward for each MB
MeSearchRange SearchRange;//SearchRange.x, SearchRange.y
MeSearchDirection SearchDirection;//forward, bidir
MeInterpolation Interpolation; //bilinear, bicubic, ...
MeMbPart MbPart;//16x16,16x8,8x16,8x8,4x8x8,4x4
MePixelType PixelType;
MePicRange PicRange; // TODO: why don't use IppiRect?
MeSkippedMetrics SkippedMetrics;//SAD, SADT, MAXAD
Ipp32s Quant;
bool toProcessSkipped;
bool toProcessDirect;
void SetSearchSpeed(Ipp32s Speed) {inPars.SearchSpeed = Speed;};
MeInnerParams* GetMeInnerParams() {return &inPars;};
bool SetSpeedQualityParams();
protected:
MeInnerParams inPars;
};
class MeBase
{
public:
MeBase();
~MeBase();
bool Init(MeInitParams *par); //allocates memory
#ifdef ME_NEW_INTERFACE
MeParams* GetHWCapabilities();
MeFrame* LockFrame();
void UnLockFrame(MeFrame *frm);
#endif
bool EstimateFrame(MeParams *par, MeFrame *res); //par and res should be allocated by caller, except MeFrame::MBs
void Close(); //frees memory, also called from destructor
MeMV* m_MVDirectFW;//pointer to the array of direct forward for each MB
MeMV* m_MVDirectBW;//pointer to the array of direct backward for each MB
protected:
bool CheckParams(bool FirsCall);
template<typename T> void DownSamplePicture4(const T* pSrc, IppiSize srcSize, Ipp32s srcStep, T* pDst);
void DownsampleReference();
MeMV GetAMV();
MeMV GetBMV();
MeMV GetCMV();
MeMV GetAMVHibrid();
MeMV GetCMVHibrid();
MeMV GetPredictorMPEG2();
MeMV GetMedian();
MeMV GetMedianHibrid();
Ipp32s GetT2();
typedef MeMV (MeBase::*GetPredictorFunc)();
GetPredictorFunc GetPredictor;
inline int median3( int a, int b, int c ){return IPP_MIN(a,b)^IPP_MIN(b,c)^IPP_MIN(c,a);};
inline void ResetBestCost();
Ipp32s WeightMV(MeMV mv);
void EstimateMB();
void MakeMbModeDecision();
bool EstimateSkipped();
bool EstimateSkippedBidir();
template<MeMbPart mt, MeInPixType pix> void EstimatePoint(MeMV mv);
template<MeMbPart mt, MeInPixType pix> void FullSearch(Ipp32s RangeX, Ipp32s RangeY);
template<MeMbPart mt, MeInPixType pix, MeDiamondType dm> void DiamondSearch();
template<MeMbPart mt, MeInPixType pix> bool RefineSearch();
template<MeMbPart mt, MeInPixType pix, MeCostEnum cst> inline void GetCost(const Ipp8u* pSrc,Ipp32s srcStep,const Ipp8u* pRef,Ipp32s refStep,MeCost *cost,Ipp32s mcType);
template<MeMbPart mt, MeInPixType pix> inline void CalcCost(const Ipp8u* pSrc,Ipp32s srcStep,const Ipp8u* pRef,Ipp32s refStep,MeCost * cost, Ipp32s mcType, MeCostEnum cst);
inline void Interpolate(const Ipp8u* pSrc,Ipp32s srcStep,Ipp8u* pDst,Ipp32s dstStep, MeMV mv);
//parameters
Ipp8u* m_pSrcFrameY;
Ipp8u* m_pRefFrameY;
Ipp8u* m_pSrcFrameYDwn4;
Ipp8u* m_pRefFrameYDwn4;
Ipp8u* m_pRefFrameFYDwn4;
Ipp8u* m_pRefFrameBYDwn4;
Ipp32s m_WidthMB;
Ipp32s m_HeightMB;
Ipp32s m_SrcStep;
Ipp32s m_RefStep;
Ipp32s m_SrcStepDwn4;
Ipp32s m_RefStepDwn4;
Ipp32s m_Padding;
Ipp32s m_SearchRangeX; //search range, in qurter pixel, -4*x ... 4*x-1, (-x...x-1/4 in pixel)
Ipp32s m_SearchRangeY;
MePicRange m_PicRange;
MeParams* m_MePar; //ptr to current frame parameters
MeInitParams* m_MeParInit; //ptr to current frame parameters
VideoStreamType m_stream_type;
Ipp32s m_predictor_index;
MeSkippedStatus mbSkippedStatus;
//current search
Ipp32s m_adr; //current MB address
MeMV m_CurMB; //current MB location
Ipp32s m_BlockIdx; //block index
MeMV m_CurPrediction; //median prediction for current MB
MeMV m_CurPredictionB; //median backward prediction for current MB
MeMV m_CurPredictionF; //median forward prediction for current MB
Ipp8u* m_16x16buf; //buffer for interpolated MB for subpixel search, aligned
Ipp8u* m_16x16bufB; //buffer for interpolated MB for subpixel search, aligned
Ipp8u* m_bufAvrg; //buffer for average forward-backward interpolated MB for subpixel search, aligned
Ipp32s m_SkippedThreshold;//pixel abs. diff. threshhold for the skipped macroblocks (unifirm metric)
MeCostEnum m_CostMetrics;//SAD or SADT
Ipp32s MaxBlock;
Ipp32s MaxRefFrame;
Ipp32s *m_BestCost; //array of best cost for current search, 0 - 16x16, 1 - 8x8 block 0 and so on
MeMV *m_BestMV; //array of best MVs for current search
Ipp32s **m_BestBCost; //array of best costs for backward ref frames
MeMV **m_BestBMV; //array of best MVs for bkw
//Ipp32s m_BestFCost[MaxRefFrame][MaxBlock];
//MeMV m_BestFMV[MaxRefFrame][MaxBlock];
//for statistic only!!!
bool predicted;
bool refined;
Ipp32s BidirCost;
Ipp32s IntraCost;
Ipp32s InterCost;
//res array
Ipp32s m_NumOfMVs; //num of MVs in MeMB
MeMB* m_ResMB; //results
#ifdef ME_NEW_INTERFACE
//frames are alocated by motion estimator in Init function. Arrays MBs and stat are also allocated by estimator.
Ipp32u m_NumOfFrames;
MeFrame* m_Frames;
bool* m_FrameLocked; //to keep track of locked by encoder frames
#endif
};
//typedef MeMV (MeBase::*GetPredictorFunc)();
}//namespace
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -