openh264/codec/encoder/core/inc/macros.h
Martin Storsjö d3ee1de5ac Remove trailing whitespace in comments
The astyle cleanup keeps trailing whitespace within comments,
but the whitespace here is not significant nor intentional
and thus should be removed.
2014-01-05 14:53:21 +02:00

402 lines
11 KiB
C++

/*!
* \copy
* Copyright (c) 2009-2013, Cisco Systems
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*
* \file macros.h
*
* \brief MACRO based tool utilization
*
* \date 3/13/2009 Created
*
*************************************************************************************
*/
#ifndef WELS_MACRO_UTILIZATIONS_H__
#define WELS_MACRO_UTILIZATIONS_H__
//#include <math.h>
#include "typedefs.h"
namespace WelsSVCEnc {
#if defined(_MSC_VER)
#if _MSC_VER <= 1200
#define ALLOC_ALLIGN_MEM(name,size,type,alignment) \
type name##_storage[size+(alignment)-1]; \
type * name = (type *) (((int32_t) name##_storage+(alignment - 1)) & ~((int32_t)(alignment)-1))
#define ALLOC_ALLIGN_MEM_2(name,sizex,sizey,type,alignment) \
type name##_storage[(sizex)*(sizey)+(alignment)-1]; \
type * name = (type *) (((int32_t) name##_storage+(alignment - 1)) & ~((int32_t)(alignment)-1))
#else //_MSC_VER <= 1200
#define ALLOC_ALLIGN_MEM(name,size,type,alignment) \
__declspec(align(alignment)) type name[size]
#define ALLOC_ALLIGN_MEM_2(name,sizex,sizey,type,alignment) \
__declspec(align(alignment)) type name[(sizex)*(sizey)]
#endif//_MSC_VER <= 1200
#elif defined(__GNUC__)
#define ALLOC_ALLIGN_MEM(name,size,type,alignment) \
type name[size] __attribute__((aligned(alignment)))
#define ALLOC_ALLIGN_MEM_2(name,sizex,sizey,type,alignment) \
type name[(sizex)*(sizey)] __attribute__((aligned(alignment)))
#endif//_MSC_VER
#if defined(_MSC_VER)
#if(_MSC_VER < 1700)
#define inline __inline
#endif
#define __FASTCALL __fastcall
#define ALIGNED_DECLARE( type, var, n ) __declspec(align(n)) type var
#define __align8(t,v) __declspec(align(8)) t v
#define __align16(t,v) __declspec(align(16)) t v
#elif defined(__GNUC__)
#if !defined(MAC_POWERPC)
#define __FASTCALL __attribute__ ((fastcall))
#else
#define __FASTCALL // mean NULL for mac ppc
#endif//MAC_POWERPC
#define ALIGNED_DECLARE( type, var, n ) type var __attribute__((aligned(n)))
#define __align8(t,v) t v __attribute__ ((aligned (8)))
#define __align16(t,v) t v __attribute__ ((aligned (16)))
#endif//_MSC_VER
#if defined(_MACH_PLATFORM) || defined(__GNUC__)
#define ALIGNED_DECLARE_MATRIX_2D(name,sizex,sizey,type,alignment) \
type name[(sizex)*(sizey)] __attribute__((aligned(alignment)))
#else //_MSC_VER <= 1200
#define ALIGNED_DECLARE_MATRIX_2D(name,sizex,sizey,type,alignment) \
__declspec(align(alignment)) type name[(sizex)*(sizey)]
#endif//#if _MACH_PLATFORM
#if defined(_MACH_PLATFORM) || defined(__GNUC__)
#define ALIGNED_DECLARE_MATRIX_1D(name,size,type,alignment) \
type name[size] __attribute__((aligned(alignment)))
#else //_MSC_VER <= 1200
#define ALIGNED_DECLARE_MATRIX_1D(name,size,type,alignment) \
__declspec(align(alignment)) type name[(size)]
#endif//#if _MACH_PLATFORM
//#if !defined(SIZEOFRGB24)
//#define SIZEOFRGB24(cx, cy) (3 * (cx) * (cy))
//#endif//SIZEOFRGB24
//#if !defined(SIZEOFRGB32)
//#define SIZEOFRGB32(cx, cy) (4 * (cx) * (cy))
//#endif//SIZEOFRGB32
#ifndef WELS_ALIGN
#define WELS_ALIGN(x, n) (((x)+(n)-1)&~((n)-1))
#endif//WELS_ALIGN
#ifndef WELS_MAX
//#define WELS_MAX(x, y) ((x) > (y) ? (x) : (y))
//#define WELS_MAX(x, y) ((x) - (((x)-(y))&(((x)-(y))>>31)))
#define WELS_MAX(x, y) ((x) ^ (((x)^(y))& -((x)<(y)))) // WELS_MAX(x, y)
#endif//WELS_MAX
#ifndef WELS_MIN
//#define WELS_MIN(x, y) ((x) < (y) ? (x) : (y))
//#define WELS_MIN(x, y) ((y) + (((x)-(y))&(((x)-(y))>>31)))
#define WELS_MIN(x, y) ((y) ^ (((x)^(y))& -((x)<(y)))) // WELS_MIN(x, y)
#endif//WELS_MIN
#ifndef WELS_ROUND
#define WELS_ROUND(x) ((int32_t)((x)+0.5f+EPSN))
#endif//WELS_ROUND
static inline int32_t WELS_CEIL (float v) {
const int32_t n = (int32_t)v; // floor value
return ((v > EPSN + n) ? (1 + n) : n); // (int32_t)ceil(v);
}
static inline int32_t WELS_FLOOR (float v) {
return (int32_t)v;
}
#define WELS_NON_ZERO_COUNT_AVERAGE(iC,iA,iB) { \
iC = iA + iB + 1; \
iC >>= (int32_t)( iA != -1 && iB != -1); \
iC += (iA == -1 && iB == -1); \
}
/*
* log base 2 of v and ceil/floor extension
*/
static inline int32_t WELS_CEILLOG2 (uint32_t v) {
int32_t r = 0;
--v;
while (v > 0) {
++r;
v >>= 1;
}
return r;
}
static inline int32_t WELS_FLOORLOG2 (uint32_t v) {
int32_t r = 0;
while (v > 1) {
++r;
v >>= 1;
}
return r;
}
static inline int32_t WELS_LOG2 (uint32_t v) {
int32_t r = 0;
while (v >>= 1) {
++r;
}
return r;
}
static inline BOOL_T WELS_POWER2_IF (uint32_t v) {
return (v && ! (v & (v - 1)));
}
static inline int32_t WELS_MEDIAN (int32_t x, int32_t y, int32_t z) {
int32_t t = (x - y) & ((x - y) >> 31);
x -= t;
y += t;
y -= (y - z) & ((y - z) >> 31);
y += (x - y) & ((x - y) >> 31);
return y;
}
#ifndef BUTTERFLY1x2
#define BUTTERFLY1x2(b) (((b)<<8) | (b))
#endif//BUTTERFLY1x2
#ifndef BUTTERFLY2x4
#define BUTTERFLY2x4(wd) (((uint32_t)(wd)<<16) |(wd))
#endif//BUTTERFLY2x4
#ifndef BUTTERFLY4x8
#define BUTTERFLY4x8(dw) (((uint64_t)(dw)<<32) | (dw))
#endif//BUTTERFLY4x8
//when RS accumulation, should clip rs among range of [-255, 255]
#ifndef CLIP_RS
#define CLIP_RS( value ) ( WELS_MAX( WELS_MIN( value, 255 ), -255 ) )
#endif //CLIP_RS
//#ifndef NEG_NUM
//#define NEG_NUM( num ) (1+(~(num)))
//#endif// NEG_NUM
#ifndef WELS_CLIP1
#define WELS_CLIP1(x) (((x) & ~255) ? (-(x) >> 31) : (x))
#endif//WELS_CLIP1
#ifndef WELS_SIGN
#define WELS_SIGN(a) ((int32_t)(a) >> 31) // General: (a)>>(sizeof(int)*CHAR_BIT-1), CHAR_BIT= the number of bits per byte (normally 8)
#endif //WELS_SIGN
static inline int32_t WELS_ABS (int32_t a) {
const int32_t sign = WELS_SIGN (a);
return ((a + sign) ^ sign);
}
// wels_tostring
//#ifndef wels_tostring
//#define wels_tostring(s) #s
//#endif //wels_tostring
// WELS_CLIP3
#ifndef WELS_CLIP3
#define WELS_CLIP3(x, y, z) ((x) < (y) ? (y) : ((x) > (z) ? (z) : (x)))
#endif //WELS_CLIP3
#define CLIP3_QP_0_51(q) WELS_CLIP3(q, 0, 51) // ((q) < (0) ? (0) : ((q) > (51) ? (51) : (q)))
// Bitwise routines
// n: ulong
// b: bit order
static inline bool_t BITWISE_ENABLED (const uint32_t n, const uint8_t b) {
const uint8_t bit = (b & 0x1f); // maximal bit position 31 for uint32_t 4 bytes
#if defined(WORDS_BIGENDIAN)
/*
* 31 .. 24, 23 .. 16, 15 .. 8, 7 .. 0
* 7 .. 0, 15 .. 8, 23 .. 16, 31 .. 24
*/
const uint8_t map = 24 + ((bit & 7) << 1) - bit; // BIG_ENDIAN map
return (bool_t) ((n & (1 << map)) >> map); // BIG_ENDIAN
#else
return ((n & (1 << bit)) >> bit) ? true : false; // LITTLE_ENDIAN
#endif//WORDS_BIGENDIAN
}
#define CALC_BI_STRIDE(width,bitcount) ((((width * bitcount) + 31) & ~31) >> 3)
//////////////////////////////////////////////////////////
#ifdef WORDS_BIGENDIAN
static inline uint32_t ENDIAN_FIX (uint32_t x) {
return x;
}
#else
#if defined(WIN32) && !defined(WIN64) && defined(_MSC_VER)
static inline uint32_t ENDIAN_FIX (uint32_t x) {
__asm {
mov eax, x
bswap eax
mov x, eax
}
return x;
}
#else // GCC
static inline uint32_t ENDIAN_FIX (uint32_t x) {
#ifdef X86_ARCH
__asm__ __volatile__ ("bswap %0":"+r" (x));
#else
x = ((x & 0xff000000) >> 24) | ((x & 0xff0000) >> 8) |
((x & 0xff00) << 8) | ((x & 0xff) << 24);
#endif
return x;
}
#endif
#endif
// wels_swap16
// wels_swap32
// sad, satd, avg might being in other header
/*
* Description: to check variable validation and return the specified result
* result: value to be return
* case_if: negative condition to be verified
*/
#ifndef WELS_VERIFY_RETURN_IF
#define WELS_VERIFY_RETURN_IF(result, case_if) \
if ( case_if ){ \
return result; \
}
#endif//#if WELS_VERIFY_RETURN_IF
/*
* Description: to check variable validation and return the specified result
* with correspoinding process advance.
* result: value to be return
* case_if: negative condition to be verified
* proc: process need perform
*/
#ifndef WELS_VERIFY_RETURN_PROC_IF
#define WELS_VERIFY_RETURN_PROC_IF(result, case_if, proc) \
if ( case_if ){ \
proc; \
return result; \
}
#endif//#if WELS_VERIFY_RETURN_PROC_IF
/*
* Description: to check variable validation and return
* case_if: negtive condition to be verified
* return: NONE
*/
#ifndef WELS_VERIFY_IF
#define WELS_VERIFY_IF(case_if) \
if ( case_if ){ \
return; \
}
#endif//#if WELS_VERIFY_IF
/*
* Description: to check variable validation and return with correspoinding process advance.
* case_if: negtive condition to be verified
* proc: process need preform
* return: NONE
*/
#ifndef WELS_VERIFY_PROC_IF
#define WELS_VERIFY_PROC_IF(case_if, proc) \
if ( case_if ){ \
proc; \
return; \
}
#endif//#if WELS_VERIFY_IF
/*
* Description: to safe free a ptr with free function pointer
* p: pointer to be destroyed
* free_fn: free function pointer used
*/
#ifndef WELS_SAFE_FREE_P
#define WELS_SAFE_FREE_P(p, free_fn) \
do{ \
if ( NULL != (p) ){ \
free_fn( (p) ); \
(p) = NULL; \
} \
}while( 0 );
#endif//#if WELS_SAFE_FREE_P
/*
* Description: to safe free an array ptr with free function pointer
* arr: pointer to an array, something like "**p";
* num: number of elements in array
* free_fn: free function pointer
*/
#ifndef WELS_SAFE_FREE_ARR
#define WELS_SAFE_FREE_ARR(arr, num, free_fn) \
do{ \
if ( NULL != (arr) ){ \
int32_t iidx = 0; \
while( iidx < num ){ \
if ( NULL != (arr)[iidx] ){ \
free_fn( (arr)[iidx] ); \
(arr)[iidx] = NULL; \
} \
++ iidx; \
} \
free_fn((arr)); \
(arr) = NULL; \
} \
}while( 0 );
#endif//#if WELS_SAFE_FREE_ARR
}
#endif//WELS_MACRO_UTILIZATIONS_H__