osdep.h 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417
  1. /*****************************************************************************
  2. * osdep.h: platform-specific code
  3. *****************************************************************************
  4. * Copyright (C) 2007-2018 x264 project
  5. *
  6. * Authors: Loren Merritt <lorenm@u.washington.edu>
  7. * Laurent Aimar <fenrir@via.ecp.fr>
  8. * Henrik Gramner <henrik@gramner.com>
  9. *
  10. * This program is free software; you can redistribute it and/or modify
  11. * it under the terms of the GNU General Public License as published by
  12. * the Free Software Foundation; either version 2 of the License, or
  13. * (at your option) any later version.
  14. *
  15. * This program is distributed in the hope that it will be useful,
  16. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18. * GNU General Public License for more details.
  19. *
  20. * You should have received a copy of the GNU General Public License
  21. * along with this program; if not, write to the Free Software
  22. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111, USA.
  23. *
  24. * This program is also available under a commercial proprietary license.
  25. * For more information, contact us at licensing@x264.com.
  26. *****************************************************************************/
  27. #ifndef X264_OSDEP_H
  28. #define X264_OSDEP_H
  29. #define _LARGEFILE_SOURCE 1
  30. #define _FILE_OFFSET_BITS 64
  31. #include <stdio.h>
  32. #include <sys/stat.h>
  33. #include <inttypes.h>
  34. #include <stdarg.h>
  35. #include "config.h"
  36. #ifdef __INTEL_COMPILER
  37. #include <mathimf.h>
  38. #else
  39. #include <math.h>
  40. #endif
  41. #if !HAVE_LOG2F
  42. #define log2f(x) (logf(x)/0.693147180559945f)
  43. #define log2(x) (log(x)/0.693147180559945)
  44. #endif
  45. #ifdef _MSC_VER
  46. #define inline __inline
  47. #define strcasecmp _stricmp
  48. #define strncasecmp _strnicmp
  49. #define strtok_r strtok_s
  50. #define S_ISREG(x) (((x) & S_IFMT) == S_IFREG)
  51. #if _MSC_VER < 1900
  52. int x264_snprintf( char *s, size_t n, const char *fmt, ... );
  53. int x264_vsnprintf( char *s, size_t n, const char *fmt, va_list arg );
  54. #define snprintf x264_snprintf
  55. #define vsnprintf x264_vsnprintf
  56. #endif
  57. #else
  58. #include <strings.h>
  59. #endif
  60. #if !defined(va_copy) && defined(__INTEL_COMPILER)
  61. #define va_copy(dst, src) ((dst) = (src))
  62. #endif
  63. #if !defined(isfinite) && (SYS_OPENBSD || SYS_SunOS)
  64. #define isfinite finite
  65. #endif
  66. #if !HAVE_STRTOK_R && !defined(strtok_r)
  67. #define strtok_r(str,delim,save) strtok(str,delim)
  68. #endif
  69. #ifdef _WIN32
  70. #define utf8_to_utf16( utf8, utf16 )\
  71. MultiByteToWideChar( CP_UTF8, MB_ERR_INVALID_CHARS, utf8, -1, utf16, sizeof(utf16)/sizeof(wchar_t) )
  72. FILE *x264_fopen( const char *filename, const char *mode );
  73. int x264_rename( const char *oldname, const char *newname );
  74. #define x264_struct_stat struct _stati64
  75. #define x264_fstat _fstati64
  76. int x264_stat( const char *path, x264_struct_stat *buf );
  77. #else
  78. #define x264_fopen fopen
  79. #define x264_rename rename
  80. #define x264_struct_stat struct stat
  81. #define x264_fstat fstat
  82. #define x264_stat stat
  83. #endif
  84. /* mdate: return the current date in microsecond */
  85. int64_t x264_mdate( void );
  86. #if defined(_WIN32) && !HAVE_WINRT
  87. int x264_vfprintf( FILE *stream, const char *format, va_list arg );
  88. int x264_is_pipe( const char *path );
  89. #else
  90. #define x264_vfprintf vfprintf
  91. #define x264_is_pipe(x) 0
  92. #endif
  93. #define x264_glue3_expand(x,y,z) x##_##y##_##z
  94. #define x264_glue3(x,y,z) x264_glue3_expand(x,y,z)
  95. #ifdef _MSC_VER
  96. #define DECLARE_ALIGNED( var, n ) __declspec(align(n)) var
  97. #else
  98. #define DECLARE_ALIGNED( var, n ) var __attribute__((aligned(n)))
  99. #endif
  100. #define ALIGNED_4( var ) DECLARE_ALIGNED( var, 4 )
  101. #define ALIGNED_8( var ) DECLARE_ALIGNED( var, 8 )
  102. #define ALIGNED_16( var ) DECLARE_ALIGNED( var, 16 )
  103. // ARM compiliers don't reliably align stack variables
  104. // - EABI requires only 8 byte stack alignment to be maintained
  105. // - gcc can't align stack variables to more even if the stack were to be correctly aligned outside the function
  106. // - armcc can't either, but is nice enough to actually tell you so
  107. // - Apple gcc only maintains 4 byte alignment
  108. // - llvm can align the stack, but only in svn and (unrelated) it exposes bugs in all released GNU binutils...
  109. #define ALIGNED_ARRAY_EMU( mask, type, name, sub1, ... )\
  110. uint8_t name##_u [sizeof(type sub1 __VA_ARGS__) + mask]; \
  111. type (*name) __VA_ARGS__ = (void*)((intptr_t)(name##_u+mask) & ~mask)
  112. #if ARCH_ARM && SYS_MACOSX
  113. #define ALIGNED_ARRAY_8( ... ) EXPAND( ALIGNED_ARRAY_EMU( 7, __VA_ARGS__ ) )
  114. #else
  115. #define ALIGNED_ARRAY_8( type, name, sub1, ... ) ALIGNED_8( type name sub1 __VA_ARGS__ )
  116. #endif
  117. #if ARCH_ARM
  118. #define ALIGNED_ARRAY_16( ... ) EXPAND( ALIGNED_ARRAY_EMU( 15, __VA_ARGS__ ) )
  119. #else
  120. #define ALIGNED_ARRAY_16( type, name, sub1, ... ) ALIGNED_16( type name sub1 __VA_ARGS__ )
  121. #endif
  122. #define EXPAND(x) x
  123. #if ARCH_X86 || ARCH_X86_64
  124. #define NATIVE_ALIGN 64
  125. #define ALIGNED_32( var ) DECLARE_ALIGNED( var, 32 )
  126. #define ALIGNED_64( var ) DECLARE_ALIGNED( var, 64 )
  127. #if STACK_ALIGNMENT >= 32
  128. #define ALIGNED_ARRAY_32( type, name, sub1, ... ) ALIGNED_32( type name sub1 __VA_ARGS__ )
  129. #else
  130. #define ALIGNED_ARRAY_32( ... ) EXPAND( ALIGNED_ARRAY_EMU( 31, __VA_ARGS__ ) )
  131. #endif
  132. #if STACK_ALIGNMENT >= 64
  133. #define ALIGNED_ARRAY_64( type, name, sub1, ... ) ALIGNED_64( type name sub1 __VA_ARGS__ )
  134. #else
  135. #define ALIGNED_ARRAY_64( ... ) EXPAND( ALIGNED_ARRAY_EMU( 63, __VA_ARGS__ ) )
  136. #endif
  137. #else
  138. #define NATIVE_ALIGN 16
  139. #define ALIGNED_32 ALIGNED_16
  140. #define ALIGNED_64 ALIGNED_16
  141. #define ALIGNED_ARRAY_32 ALIGNED_ARRAY_16
  142. #define ALIGNED_ARRAY_64 ALIGNED_ARRAY_16
  143. #endif
  144. #if defined(__GNUC__) && (__GNUC__ > 3 || __GNUC__ == 3 && __GNUC_MINOR__ > 0)
  145. #define UNUSED __attribute__((unused))
  146. #define ALWAYS_INLINE __attribute__((always_inline)) inline
  147. #define NOINLINE __attribute__((noinline))
  148. #define MAY_ALIAS __attribute__((may_alias))
  149. #define x264_constant_p(x) __builtin_constant_p(x)
  150. #define x264_nonconstant_p(x) (!__builtin_constant_p(x))
  151. #else
  152. #ifdef _MSC_VER
  153. #define ALWAYS_INLINE __forceinline
  154. #define NOINLINE __declspec(noinline)
  155. #else
  156. #define ALWAYS_INLINE inline
  157. #define NOINLINE
  158. #endif
  159. #define UNUSED
  160. #define MAY_ALIAS
  161. #define x264_constant_p(x) 0
  162. #define x264_nonconstant_p(x) 0
  163. #endif
  164. /* threads */
  165. #if HAVE_BEOSTHREAD
  166. #include <kernel/OS.h>
  167. #define x264_pthread_t thread_id
  168. static inline int x264_pthread_create( x264_pthread_t *t, void *a, void *(*f)(void *), void *d )
  169. {
  170. *t = spawn_thread( f, "", 10, d );
  171. if( *t < B_NO_ERROR )
  172. return -1;
  173. resume_thread( *t );
  174. return 0;
  175. }
  176. #define x264_pthread_join(t,s) { long tmp; \
  177. wait_for_thread(t,(s)?(long*)(s):&tmp); }
  178. #elif HAVE_POSIXTHREAD
  179. #include <pthread.h>
  180. #define x264_pthread_t pthread_t
  181. #define x264_pthread_create pthread_create
  182. #define x264_pthread_join pthread_join
  183. #define x264_pthread_mutex_t pthread_mutex_t
  184. #define x264_pthread_mutex_init pthread_mutex_init
  185. #define x264_pthread_mutex_destroy pthread_mutex_destroy
  186. #define x264_pthread_mutex_lock pthread_mutex_lock
  187. #define x264_pthread_mutex_unlock pthread_mutex_unlock
  188. #define x264_pthread_cond_t pthread_cond_t
  189. #define x264_pthread_cond_init pthread_cond_init
  190. #define x264_pthread_cond_destroy pthread_cond_destroy
  191. #define x264_pthread_cond_broadcast pthread_cond_broadcast
  192. #define x264_pthread_cond_wait pthread_cond_wait
  193. #define x264_pthread_attr_t pthread_attr_t
  194. #define x264_pthread_attr_init pthread_attr_init
  195. #define x264_pthread_attr_destroy pthread_attr_destroy
  196. #define x264_pthread_num_processors_np pthread_num_processors_np
  197. #define X264_PTHREAD_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
  198. #elif HAVE_WIN32THREAD
  199. #include "win32thread.h"
  200. #else
  201. #define x264_pthread_t int
  202. #define x264_pthread_create(t,u,f,d) 0
  203. #define x264_pthread_join(t,s)
  204. #endif //HAVE_*THREAD
  205. #if !HAVE_POSIXTHREAD && !HAVE_WIN32THREAD
  206. #define x264_pthread_mutex_t int
  207. #define x264_pthread_mutex_init(m,f) 0
  208. #define x264_pthread_mutex_destroy(m)
  209. #define x264_pthread_mutex_lock(m)
  210. #define x264_pthread_mutex_unlock(m)
  211. #define x264_pthread_cond_t int
  212. #define x264_pthread_cond_init(c,f) 0
  213. #define x264_pthread_cond_destroy(c)
  214. #define x264_pthread_cond_broadcast(c)
  215. #define x264_pthread_cond_wait(c,m)
  216. #define x264_pthread_attr_t int
  217. #define x264_pthread_attr_init(a) 0
  218. #define x264_pthread_attr_destroy(a)
  219. #define X264_PTHREAD_MUTEX_INITIALIZER 0
  220. #endif
  221. #if HAVE_WIN32THREAD || PTW32_STATIC_LIB
  222. int x264_threading_init( void );
  223. #else
  224. #define x264_threading_init() 0
  225. #endif
  226. static ALWAYS_INLINE int x264_pthread_fetch_and_add( int *val, int add, x264_pthread_mutex_t *mutex )
  227. {
  228. #if HAVE_THREAD
  229. #if defined(__GNUC__) && (__GNUC__ > 4 || __GNUC__ == 4 && __GNUC_MINOR__ > 0) && (ARCH_X86 || ARCH_X86_64)
  230. return __sync_fetch_and_add( val, add );
  231. #else
  232. x264_pthread_mutex_lock( mutex );
  233. int res = *val;
  234. *val += add;
  235. x264_pthread_mutex_unlock( mutex );
  236. return res;
  237. #endif
  238. #else
  239. int res = *val;
  240. *val += add;
  241. return res;
  242. #endif
  243. }
  244. #define WORD_SIZE sizeof(void*)
  245. #define asm __asm__
  246. #if WORDS_BIGENDIAN
  247. #define endian_fix(x) (x)
  248. #define endian_fix64(x) (x)
  249. #define endian_fix32(x) (x)
  250. #define endian_fix16(x) (x)
  251. #else
  252. #if HAVE_X86_INLINE_ASM && HAVE_MMX
  253. static ALWAYS_INLINE uint32_t endian_fix32( uint32_t x )
  254. {
  255. asm("bswap %0":"+r"(x));
  256. return x;
  257. }
  258. #elif defined(__GNUC__) && HAVE_ARMV6
  259. static ALWAYS_INLINE uint32_t endian_fix32( uint32_t x )
  260. {
  261. asm("rev %0, %0":"+r"(x));
  262. return x;
  263. }
  264. #else
  265. static ALWAYS_INLINE uint32_t endian_fix32( uint32_t x )
  266. {
  267. return (x<<24) + ((x<<8)&0xff0000) + ((x>>8)&0xff00) + (x>>24);
  268. }
  269. #endif
  270. #if HAVE_X86_INLINE_ASM && ARCH_X86_64
  271. static ALWAYS_INLINE uint64_t endian_fix64( uint64_t x )
  272. {
  273. asm("bswap %0":"+r"(x));
  274. return x;
  275. }
  276. #else
  277. static ALWAYS_INLINE uint64_t endian_fix64( uint64_t x )
  278. {
  279. return endian_fix32(x>>32) + ((uint64_t)endian_fix32(x)<<32);
  280. }
  281. #endif
  282. static ALWAYS_INLINE intptr_t endian_fix( intptr_t x )
  283. {
  284. return WORD_SIZE == 8 ? endian_fix64(x) : endian_fix32(x);
  285. }
  286. static ALWAYS_INLINE uint16_t endian_fix16( uint16_t x )
  287. {
  288. return (x<<8)|(x>>8);
  289. }
  290. #endif
  291. /* For values with 4 bits or less. */
  292. static ALWAYS_INLINE int x264_ctz_4bit( uint32_t x )
  293. {
  294. static uint8_t lut[16] = {4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0};
  295. return lut[x];
  296. }
  297. #if defined(__GNUC__) && (__GNUC__ > 3 || __GNUC__ == 3 && __GNUC_MINOR__ > 3)
  298. #define x264_clz(x) __builtin_clz(x)
  299. #define x264_ctz(x) __builtin_ctz(x)
  300. #else
  301. static ALWAYS_INLINE int x264_clz( uint32_t x )
  302. {
  303. static uint8_t lut[16] = {4,3,2,2,1,1,1,1,0,0,0,0,0,0,0,0};
  304. int y, z = (((x >> 16) - 1) >> 27) & 16;
  305. x >>= z^16;
  306. z += y = ((x - 0x100) >> 28) & 8;
  307. x >>= y^8;
  308. z += y = ((x - 0x10) >> 29) & 4;
  309. x >>= y^4;
  310. return z + lut[x];
  311. }
  312. static ALWAYS_INLINE int x264_ctz( uint32_t x )
  313. {
  314. static uint8_t lut[16] = {4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0};
  315. int y, z = (((x & 0xffff) - 1) >> 27) & 16;
  316. x >>= z;
  317. z += y = (((x & 0xff) - 1) >> 28) & 8;
  318. x >>= y;
  319. z += y = (((x & 0xf) - 1) >> 29) & 4;
  320. x >>= y;
  321. return z + lut[x&0xf];
  322. }
  323. #endif
  324. #if HAVE_X86_INLINE_ASM && HAVE_MMX
  325. /* Don't use __builtin_prefetch; even as recent as 4.3.4, GCC seems incapable of
  326. * using complex address modes properly unless we use inline asm. */
  327. static ALWAYS_INLINE void x264_prefetch( void *p )
  328. {
  329. asm volatile( "prefetcht0 %0"::"m"(*(uint8_t*)p) );
  330. }
  331. /* We require that prefetch not fault on invalid reads, so we only enable it on
  332. * known architectures. */
  333. #elif defined(__GNUC__) && (__GNUC__ > 3 || __GNUC__ == 3 && __GNUC_MINOR__ > 1) &&\
  334. (ARCH_X86 || ARCH_X86_64 || ARCH_ARM || ARCH_PPC)
  335. #define x264_prefetch(x) __builtin_prefetch(x)
  336. #else
  337. #define x264_prefetch(x)
  338. #endif
  339. #if HAVE_POSIXTHREAD
  340. #if SYS_WINDOWS
  341. #define x264_lower_thread_priority(p)\
  342. {\
  343. x264_pthread_t handle = pthread_self();\
  344. struct sched_param sp;\
  345. int policy = SCHED_OTHER;\
  346. pthread_getschedparam( handle, &policy, &sp );\
  347. sp.sched_priority -= p;\
  348. pthread_setschedparam( handle, policy, &sp );\
  349. }
  350. #elif SYS_HAIKU
  351. #include <OS.h>
  352. #define x264_lower_thread_priority(p)\
  353. { UNUSED status_t nice_ret = set_thread_priority( find_thread( NULL ), B_LOW_PRIORITY ); }
  354. #else
  355. #include <unistd.h>
  356. #define x264_lower_thread_priority(p) { UNUSED int nice_ret = nice(p); }
  357. #endif /* SYS_WINDOWS */
  358. #elif HAVE_WIN32THREAD
  359. #define x264_lower_thread_priority(p) SetThreadPriority( GetCurrentThread(), X264_MAX( -2, -p ) )
  360. #else
  361. #define x264_lower_thread_priority(p)
  362. #endif
  363. static inline int x264_is_regular_file( FILE *filehandle )
  364. {
  365. x264_struct_stat file_stat;
  366. if( x264_fstat( fileno( filehandle ), &file_stat ) )
  367. return 1;
  368. return S_ISREG( file_stat.st_mode );
  369. }
  370. static inline int x264_is_regular_file_path( const char *filename )
  371. {
  372. x264_struct_stat file_stat;
  373. if( x264_stat( filename, &file_stat ) )
  374. return !x264_is_pipe( filename );
  375. return S_ISREG( file_stat.st_mode );
  376. }
  377. #endif /* X264_OSDEP_H */