macros.h

来自「AMLOGIC DPF source code」· C头文件 代码 · 共 781 行 · 第 1/2 页

H
781
字号
    
        // Difference of two random numbers gives a triangle distribution and a range of (-2.5, 2.5)
        // it also gives a serial correlation of -0.5 at lag 1.  But all the other lags have normally small correlations.
        iTemp1 = iTemp - ptRandState->iPrior;

        // Save first term of this difference for next time.
        ptRandState->iPrior = iTemp;

        //return -2.5 to 2.5 with Binary Point = 3 with a triangle distribution
        return iTemp1;
    }

    static INLINE void RandStateClear(tRandState* ptRandState) {
        ptRandState->iPrior = 0;
        ptRandState->uiRand = 0;
    }

	// protect encoder from having these defined by mistake
#	ifdef REFERENCE_RAND_24
#		undef REFERENCE_RAND_24
#	endif
#	ifdef REFERENCE_RAND_16
#		undef REFERENCE_RAND_16
#	endif

#elif defined(REFERENCE_RAND_24)

    //****************************************************************************
    // Quick and dirty 24-bit rand generator.
    // Simulates 24-bits on a 32-bit reference machine.
    // Note this is the 24-bit referenced generator which can be used for compliance 
    // comparisions with 24-bit implementations by defining REFERENCE_RAN_24
    //****************************************************************************
    typedef struct tagRandState {
        I32 iPrior;         // prior value   (only top 24-bits used)
        U32 uiRand;         // current value (only top 24-bits used)
    } tRandState;

    static INLINE I32 quickRand(tRandState* ptRandState)
    {
        // OK to 512 lags, then ChiSquare is suspect at 1024 and rejects at 2048 (length 1024000)
        const U32 uLCa = 69857;         // 0x000110E1
        const U32 uLCc = 3546581;       // 0x00361DD5

        I32 iTemp, iTemp1;
        //a*x + c has to be done with unsigned 32 bit - but we similate a 24x24
        ptRandState->uiRand =  (uLCa * ((ptRandState->uiRand)>>8) + uLCc)<<8;

        // uiRand values starting from a 0 seed are: 0x361dd500, 0x78a60a00, 0xaaac9f00, 0xa0c59400, 0x7104e900, 0xc2fe9e00, 0x1fc6b300

        // do not change the above - see comment in 32-bit generator

        // cast and shift to make the range (-1, 1) with Binary Point 3.
        iTemp = (((I32)(ptRandState->uiRand)) >> 2) & 0xFFFFFF00; 

        // *1.25 to make the range (-1.25, 1.25) 
        iTemp += ((iTemp>>2) & 0xFFFFFF00);
    
        // Difference of two random numbers gives a triangle distribution and a range of (-2.5, 2.5)
        // it also gives a serial correlation of -0.5 at lag 1.  But all the other lags have normally small correlations.
        iTemp1 = iTemp - ptRandState->iPrior;

        // Save first term of this difference for next time.
        ptRandState->iPrior = iTemp;

        //return -2.5 to 2.5 with Binary Point = 3 with a triangle distribution
        return iTemp1;
    }

    static INLINE void RandStateClear(tRandState* ptRandState) {
        ptRandState->iPrior = 0;
        ptRandState->uiRand = 0;
    }


#elif defined(REFERENCE_RAND_16)
    //****************************************************************************
    // Quick and dirty 16-bit rand generator.
    // Simulates 16-bits on a 32-bit reference machine.
    // Note this is the 16-bit referenced generator for compliance comparisions 
    // with 16-bit implementations by defining REFERENCE_RAN_16.
    // The function actually returns 21 random bits at the top of the 32 
    // so is not a pure 16-bit generator, but does limit itself to a 16x16=>32 multiply
    //****************************************************************************

    // Background
    // A pure 16-bit Linear Congruent generator has limited sequence length.  
    // Use 13 A's and 3 C's choosen from good values in the middle of the range.
    // Tested OK up to lag 1024 (length 32768) and pretty good at 2048 and 2049.
    // Sequence length quite long.

    // these two arrays are defined once in dectables.c
#   define LCA_SET 13
#   define LCC_SET 3
    extern const unsigned int g_uWMALCA[LCA_SET];   // {1637,1033,1825,1621, 1657,1861,1229,1549, 2017,941,1409,1777, 1153};
    extern const unsigned int g_uWMALCC[LCC_SET];   // {13849,13841,13859};

    typedef struct tagRandState {
        I32 iPrior;         // prior value
        U16 uiRand;         // current value
        char bIdxLCA;       // index for uLCA
        char bIdxLCC;       // index for uLCC
    } tRandState;

    static INLINE I32 quickRand(tRandState* ptRandState)
    {
        // This 16-bit implementation returns a 32-bit result with the top 21 bits random.
        // But it base implementation is 16x16=>32, e.g. it requires only a single precision 16-bit multiply.

        I32 iTemp, iTemp1;
        U32 uTemp;

        //a*x + c is with unsigned 32 bit - but we similate a 16x16+16 =32
        uTemp =  (g_uWMALCA[ptRandState->bIdxLCA++] * (ptRandState->uiRand)) + g_uWMALCC[ptRandState->bIdxLCC++];

        // save bottom 16 bits
        ptRandState->uiRand  = (unsigned short)uTemp;

        // uiRand values starting from a 0 seed are: 0x3623, 0x259c, 0x5add, 0x5698, 0xb511, 0x78ae, 0x6af9, 0x09f2, 0xc49b, 0x4f3e, 0x4377, 0x1108

        // wrap indexes
        if (ptRandState->bIdxLCA>=LCA_SET) 
            ptRandState->bIdxLCA = 0;
        if (ptRandState->bIdxLCC>=LCC_SET)
            ptRandState->bIdxLCC = 0;

        // get best 19 bits into top
        uTemp <<= 13;           

        // do not change the above - see comment in 32-bit generator

        // cast and shift to make the range (-1, 1) with Binary Point 3.
        iTemp = (((I32)(uTemp)) >> 2); 

        // *1.25 to make the range (-1.25, 1.25) 
        iTemp += (iTemp>>2);
    
        // Difference of two random numbers gives a triangle distribution and a range of (-2.5, 2.5)
        // it also gives a serial correlation of -0.5 at lag 1.  But all the other lags have normally small correlations.
        iTemp1 = iTemp - ptRandState->iPrior;

        // Save first term of this difference for next time.
        ptRandState->iPrior = iTemp;

        //return -2.5 to 2.5 with Binary Point = 3 with a triangle distribution
        return iTemp1;
    }

    static INLINE void RandStateClear(tRandState* ptRandState) {
        ptRandState->iPrior = 0;
        ptRandState->uiRand = 0;
        ptRandState->bIdxLCA = 1;
        ptRandState->bIdxLCC = 2;
    }

#endif

//****************************************************************************
// log base 2 of a number which is a power of 2 
//****************************************************************************
static INLINE I32 LOG2(U32 i)
{   // returns n where n = log2(2^n) = log2(2^(n+1)-1)
    U32 iLog2 = 0;
    assert (i != 0);
    while ((i >> iLog2) > 1)
        iLog2++;

    return iLog2;
}

#define log2 LOG2

//****************************************************************************
// Normalize a dynamically scaled unsigned int 
//****************************************************************************
static INLINE void NormUInt( UInt* puiValue, Int* pcFracBits, const UInt uiTarget ){
    const UInt uiTarget2 = uiTarget>>1;
    register UInt uiV = *puiValue;
    register Int cFB = *pcFracBits;
    assert( uiV > 0 );    
    if (uiV == 0) return; // useful if asserts are disabled

    while ( uiV < uiTarget2 )
    {
        uiV <<= 2;        
        cFB += 2;
    }
    if ( uiV < uiTarget )
    {
        uiV <<= 1;        
        cFB += 1;
    }
    *puiValue = uiV;
    *pcFracBits = cFB;
}

//****************************************************************************
// Align a dynamically scaled int to a particular binary point position
//****************************************************************************
static INLINE Int Align2FracBits( const Int iValue, const Int cFracBits, const Int cAlignFracBits )
{
    const Int iShift = cFracBits-cAlignFracBits;

    if (iShift < 0) {
        return (iValue << -iShift);
    } else if (iShift < 32) { 
        return (iValue >> iShift);
    } else {
        return 0;
    }
}


// V4 Compatibility Mode: This mode allows us to compare V5 encoder with V4 encoder
#ifdef V4V5_COMPARE_MODE
#define V4V5COMPARE_SNAPTOZERO(x)   if (fabs(x) <= 1.0e-15) {(x) = 0;}
#define ROUNDF_V4V5COMPARE(x)  ROUNDD(x)
typedef double V4V5COMPARE;
#else   // V4V5_COMPARE_MODE
#define V4V5COMPARE_SNAPTOZERO(x)
#define ROUNDF_V4V5COMPARE(x)  ROUNDF(x)
typedef float  V4V5COMPARE;
#endif  // V4V5_COMPARE_MODE

typedef I32     FLOATORI32;
typedef U32     FLOATORU32;
typedef U16     FLOATORU16;
#define FLOATORU32_CONST(flop,fb)           ((U32)((flop)*(1 << (fb))))
#define FLOATORINT_TOFLOAT(x,fb)            ((Float)(x)/(Float)(1 << (fb)))
#define FLOATORINT_SELECTTOFLOAT(f,i,fb)    ((Float)(i)/(Float)(1 << (fb)))
#define FLOATORINT_ASSERT(x)                assert(x)
#define FLOATORINT_AB(a,b)                  (a)

// The following is used to allow non-integerized code to convert a FLOP
// result to a bit-discarded integer result
#define FLOATORU32_DISCARDBITSFROMFLT(x,fb) ((U32)((x)/(float)(1 << (fb))))
#define FLOATORU32_DISCARDBITSFROMU32(x,fb) ((U32)(x) >> (fb))
#define FLOATORU32_DISCARDBITSFROMI64(x,fb) ((I64)(x) >> (fb))
#define FLOATORU32_ADDFRACTBITS(i,fb)       ((i) << (fb))
#define FLOATORI32_DISCARDBITSFROMI32(x,fb) ((I32)(x) >> (fb))



// **************************************************************************
// Bring in platform-specific macros
// **************************************************************************
// Include them here because some of them use the global macros above
#include "wmaOS.h"

// Output target
#ifdef COMMONMACROS_OUTPUT_TARGET
#pragma COMPILER_MESSAGE("-----MACROS.H: Compiling for ANSI-C Target")
#endif // COMMONMACROS_OUTPUT_TARGET

// Bring in platform-independent macros
#define MULT_HI_DWORD_DOWN(a,b) (I32)((((I64)(a))*((I64)(b)))>>30)
#define MULT_HI_DWORD(a,b) (I32)((((I64)(a))*((I64)(b)))>>32)

// Unsigned version of multiply
#define MULT_HI_UDWORD(a,b) (U32)((((U64)(a))*((U64)(b)))>>32)


// **************************************************************************
// Overridable Macros (optimized for some platforms, but not all)
// **************************************************************************
// The following can be overridden within a particular platform macro file
static INLINE I32 ROUNDF(float f) {
    if (f < 0.0f)
        return (I32) (f - 0.5f);
    else
        return (I32) (f + 0.5f);
}

//---------------------------------------------------------------------------
static INLINE I32 ROUNDD(double f) {
    if (f < 0)
        return (I32) (f - 0.5);
    else
        return (I32) (f + 0.5);
}

//---------------------------------------------------------------------------
#ifndef PLATFORM_SPECIFIC_FNPTR
#define PLATFORM_SPECIFIC_FNPTR     //nothing for non-x86
#endif // PLATFORM_SPECIFIC_FNPTR


//**********************************************************************
// Support for FastFloat
//**********************************************************************

    // FastFloat
    // FastFloat is a quick way of handling values that exceed I32 range without incurring
    // the expense of floating point emulation on integer only platforms.
    // real value = iFraction * pow( 2, -iFracBits )
    // In debugger, iFraction*1.0F/(1<<iFracBits) works if 0<=iFracBits<31

    // Normalize a FastFloat
INLINE static void Norm4FastFloat( FastFloat* pfflt )
    {   // use the faster Norm4FastFloatU when you know the value is positive
        register UInt uiF = abs(pfflt->iFraction);
        register Int iFB = 0;
        if ( uiF == 0 )
        {
            pfflt->iFracBits = 0;
            return;
        }
        while ( uiF < 0x1FFFFFFF )
        {
            uiF <<= 2;
            iFB +=  2;
        }
        if ( uiF < 0x3FFFFFFF )
        {
            iFB +=  1;
        }
        pfflt->iFraction <<= iFB;
        pfflt->iFracBits += iFB;
    }


INLINE static void Norm4FastFloatU( FastFloat* pfflt )
    {   // same as above when we know value is positive (which we often do)
        register UInt uiF = pfflt->iFraction;
        register Int iFB = 0;
        assert( uiF > 0 );
        while ( uiF < 0x1FFFFFFF )
        {
            uiF  <<= 2;
            iFB +=  2;
        }
        if ( uiF < 0x3FFFFFFF )
        {
            uiF  <<= 1;
            iFB +=  1;
        }
        pfflt->iFraction = uiF;
        pfflt->iFracBits += iFB;
    }


INLINE static FastFloat FastFloatFromFloat(Float flt) {
        FastFloat fflt;
        Float fltScale = (Float)(1<<(31-24));
        fflt.iFracBits = 24;
        while( flt < -fltScale || fltScale < flt )
        {
            flt /= 2;
            fflt.iFracBits -= 1;
            fltScale *= 2;
        }
        fflt.iFraction = (I32)(flt*(1<<fflt.iFracBits));
        Norm4FastFloat( &fflt );
        return fflt;
    }   


INLINE static Float FloatFromFastFloat( FastFloat fflt )
    {
        assert( 0<= fflt.iFracBits && fflt.iFracBits <= 50 );
        if ( fflt.iFracBits > 30 )
            return fflt.iFraction/(1048576.0F*(1<<(fflt.iFracBits-20)));
        else
            return fflt.iFraction/((Float)(1<<fflt.iFracBits));

    }
#   define FASTFLOAT_FROM_FLOAT(flt) FastFloatFromFloat(flt)
#   define FLOAT_FROM_FASTFLOAT(fflt) FloatFromFastFloat(fflt)
#   define DOUBLE_FROM_FASTFLOAT(fflt) ((double)fflt.iFraction/(1<<fflt.iFracBits))



    typedef FastFloat QuantStepType;
#define DOUBLE_FROM_QUANTSTEPTYPE(qst) DOUBLE_FROM_FASTFLOAT(qst)
#define  FLOAT_FROM_QUANTSTEPTYPE(qst) FLOAT_FROM_FASTFLOAT(qst)
#define FASTFLOAT_FROM_QUANTSTEPTYPE(qst) (qst)



// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
// Define Macros to switch auReconMono and auSaveHistoryMono between Integer and Float


#define ROUND_SATURATE_STORE(piDst,cf,mn,mx,iTmp)      \
    *piDst = (I16) checkRange (cf, mn, mx);            \
    iTmp = cf;

#endif  // __COMMON_MACROS_H

⌨️ 快捷键说明

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