shithub: openh264

ref: 9254d722d397569a1e4d2bbce99bde6c5374830c
dir: /codec/encoder/core/inc/macros.h/

View raw version
/*!
 * \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__