Line | Count | Source |
1 | | /***************************************************************************** |
2 | | * osdep.h: platform-specific code |
3 | | ***************************************************************************** |
4 | | * Copyright (C) 2007-2025 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 | | |
28 | | #ifndef X264_OSDEP_H |
29 | | #define X264_OSDEP_H |
30 | | |
31 | | #define _LARGEFILE_SOURCE 1 |
32 | | #define _FILE_OFFSET_BITS 64 |
33 | | #include <stdio.h> |
34 | | #include <sys/stat.h> |
35 | | #include <inttypes.h> |
36 | | #include <stdarg.h> |
37 | | #include <stdlib.h> |
38 | | |
39 | | #include "config.h" |
40 | | |
41 | | #ifdef __INTEL_COMPILER |
42 | | #include <mathimf.h> |
43 | | #else |
44 | | #include <math.h> |
45 | | #endif |
46 | | |
47 | | #ifdef _WIN32 |
48 | | #include <windows.h> |
49 | | #include <io.h> |
50 | | #endif |
51 | | |
52 | | #include "x264.h" |
53 | | |
54 | | #if !HAVE_LOG2F |
55 | | #define log2f(x) (logf(x)/0.693147180559945f) |
56 | | #define log2(x) (log(x)/0.693147180559945) |
57 | | #endif |
58 | | |
59 | | #ifdef _MSC_VER |
60 | | #define inline __inline |
61 | | #define strcasecmp _stricmp |
62 | | #define strncasecmp _strnicmp |
63 | | #define strtok_r strtok_s |
64 | | #define S_ISREG(x) (((x) & S_IFMT) == S_IFREG) |
65 | | #else |
66 | | #include <strings.h> |
67 | | #endif |
68 | | |
69 | | #if !defined(va_copy) && defined(__INTEL_COMPILER) |
70 | | #define va_copy(dst, src) ((dst) = (src)) |
71 | | #endif |
72 | | |
73 | | #if !defined(isfinite) && (SYS_OPENBSD || SYS_SunOS) |
74 | | #define isfinite finite |
75 | | #endif |
76 | | |
77 | | #if !HAVE_STRTOK_R && !defined(strtok_r) |
78 | | #define strtok_r(str,delim,save) strtok(str,delim) |
79 | | #endif |
80 | | |
81 | | #if defined(_MSC_VER) && _MSC_VER < 1900 |
82 | | /* MSVC pre-VS2015 has broken snprintf/vsnprintf implementations which are incompatible with C99. */ |
83 | | static inline int x264_vsnprintf( char *s, size_t n, const char *fmt, va_list arg ) |
84 | | { |
85 | | int length = -1; |
86 | | |
87 | | if( n ) |
88 | | { |
89 | | va_list arg2; |
90 | | va_copy( arg2, arg ); |
91 | | length = _vsnprintf( s, n, fmt, arg2 ); |
92 | | va_end( arg2 ); |
93 | | |
94 | | /* _(v)snprintf adds a null-terminator only if the length is less than the buffer size. */ |
95 | | if( length < 0 || length >= n ) |
96 | | s[n-1] = '\0'; |
97 | | } |
98 | | |
99 | | /* _(v)snprintf returns a negative number if the length is greater than the buffer size. */ |
100 | | if( length < 0 ) |
101 | | return _vscprintf( fmt, arg ); |
102 | | |
103 | | return length; |
104 | | } |
105 | | |
106 | | static inline int x264_snprintf( char *s, size_t n, const char *fmt, ... ) |
107 | | { |
108 | | va_list arg; |
109 | | va_start( arg, fmt ); |
110 | | int length = x264_vsnprintf( s, n, fmt, arg ); |
111 | | va_end( arg ); |
112 | | return length; |
113 | | } |
114 | | |
115 | | #define snprintf x264_snprintf |
116 | | #define vsnprintf x264_vsnprintf |
117 | | #endif |
118 | | |
119 | | #ifdef _WIN32 |
120 | | /* Functions for dealing with Unicode on Windows. */ |
121 | | static inline wchar_t *x264_utf8_to_utf16( const char *utf8 ) |
122 | | { |
123 | | int len = MultiByteToWideChar( CP_UTF8, MB_ERR_INVALID_CHARS, utf8, -1, NULL, 0 ); |
124 | | if( len ) |
125 | | { |
126 | | wchar_t *utf16 = malloc( len * sizeof( wchar_t ) ); |
127 | | if( utf16 ) |
128 | | { |
129 | | if( MultiByteToWideChar( CP_UTF8, MB_ERR_INVALID_CHARS, utf8, -1, utf16, len ) ) |
130 | | return utf16; |
131 | | free( utf16 ); |
132 | | } |
133 | | } |
134 | | return NULL; |
135 | | } |
136 | | |
137 | | static inline wchar_t *x264_utf8_to_utf16_try_buf( const char *utf8, wchar_t *buf_utf16, int buf_len ) { |
138 | | if( MultiByteToWideChar( CP_UTF8, MB_ERR_INVALID_CHARS, utf8, -1, buf_utf16, buf_len ) ) |
139 | | return buf_utf16; |
140 | | return x264_utf8_to_utf16( utf8 ); |
141 | | } |
142 | | |
143 | | #define x264_fopen( filename, mode ) x264_fopen_internal( filename, L##mode ) |
144 | | static inline FILE *x264_fopen_internal( const char *filename, const wchar_t *mode_utf16 ) |
145 | | { |
146 | | FILE *f = NULL; |
147 | | wchar_t filename_buf[MAX_PATH]; |
148 | | wchar_t *filename_utf16 = x264_utf8_to_utf16_try_buf( filename, filename_buf, MAX_PATH ); |
149 | | if( filename_utf16 ) |
150 | | { |
151 | | f = _wfopen( filename_utf16, mode_utf16 ); |
152 | | if( filename_utf16 != filename_buf ) |
153 | | free( filename_utf16 ); |
154 | | } |
155 | | return f; |
156 | | } |
157 | | |
158 | | static inline int x264_rename( const char *oldname, const char *newname ) |
159 | | { |
160 | | int ret = -1; |
161 | | wchar_t oldname_buf[MAX_PATH]; |
162 | | wchar_t *oldname_utf16 = x264_utf8_to_utf16_try_buf( oldname, oldname_buf, MAX_PATH ); |
163 | | if( oldname_utf16 ) |
164 | | { |
165 | | wchar_t newname_buf[MAX_PATH]; |
166 | | wchar_t *newname_utf16 = x264_utf8_to_utf16_try_buf( newname, newname_buf, MAX_PATH ); |
167 | | if( newname_utf16 ) |
168 | | { |
169 | | /* POSIX says that rename() removes the destination, but Win32 doesn't. */ |
170 | | _wunlink( newname_utf16 ); |
171 | | ret = _wrename( oldname_utf16, newname_utf16 ); |
172 | | if( newname_utf16 != newname_buf ) |
173 | | free( newname_utf16 ); |
174 | | } |
175 | | if( oldname_utf16 != oldname_buf ) |
176 | | free( oldname_utf16 ); |
177 | | } |
178 | | return ret; |
179 | | } |
180 | | |
181 | | #define x264_struct_stat struct _stati64 |
182 | | #define x264_fstat _fstati64 |
183 | | |
184 | | static inline int x264_stat( const char *path, x264_struct_stat *buf ) |
185 | | { |
186 | | int ret = -1; |
187 | | wchar_t path_buf[MAX_PATH]; |
188 | | wchar_t *path_utf16 = x264_utf8_to_utf16_try_buf( path, path_buf, MAX_PATH ); |
189 | | if( path_utf16 ) |
190 | | { |
191 | | ret = _wstati64( path_utf16, buf ); |
192 | | if( path_utf16 != path_buf ) |
193 | | free( path_utf16 ); |
194 | | } |
195 | | return ret; |
196 | | } |
197 | | #else |
198 | 0 | #define x264_fopen fopen |
199 | 0 | #define x264_rename rename |
200 | 0 | #define x264_struct_stat struct stat |
201 | 0 | #define x264_fstat fstat |
202 | | #define x264_stat stat |
203 | | #endif |
204 | | |
205 | | /* mdate: return the current date in microsecond */ |
206 | | X264_API int64_t x264_mdate( void ); |
207 | | |
208 | | #if defined(_WIN32) && !HAVE_WINRT |
209 | | static inline int x264_vfprintf( FILE *stream, const char *format, va_list arg ) |
210 | | { |
211 | | HANDLE console = NULL; |
212 | | DWORD mode; |
213 | | |
214 | | if( stream == stdout ) |
215 | | console = GetStdHandle( STD_OUTPUT_HANDLE ); |
216 | | else if( stream == stderr ) |
217 | | console = GetStdHandle( STD_ERROR_HANDLE ); |
218 | | |
219 | | /* Only attempt to convert to UTF-16 when writing to a non-redirected console screen buffer. */ |
220 | | if( GetConsoleMode( console, &mode ) ) |
221 | | { |
222 | | char buf[4096]; |
223 | | wchar_t buf_utf16[4096]; |
224 | | va_list arg2; |
225 | | |
226 | | va_copy( arg2, arg ); |
227 | | int length = vsnprintf( buf, sizeof(buf), format, arg2 ); |
228 | | va_end( arg2 ); |
229 | | |
230 | | if( length > 0 && (unsigned)length < sizeof(buf) ) |
231 | | { |
232 | | /* WriteConsoleW is the most reliable way to output Unicode to a console. */ |
233 | | int length_utf16 = MultiByteToWideChar( CP_UTF8, 0, buf, length, buf_utf16, sizeof(buf_utf16)/sizeof(wchar_t) ); |
234 | | DWORD written; |
235 | | WriteConsoleW( console, buf_utf16, length_utf16, &written, NULL ); |
236 | | return length; |
237 | | } |
238 | | } |
239 | | return vfprintf( stream, format, arg ); |
240 | | } |
241 | | |
242 | | static inline int x264_is_regular_file_path( const char *path ) |
243 | | { |
244 | | int ret = -1; |
245 | | wchar_t path_buf[MAX_PATH]; |
246 | | wchar_t *path_utf16 = x264_utf8_to_utf16_try_buf( path, path_buf, MAX_PATH ); |
247 | | if( path_utf16 ) |
248 | | { |
249 | | x264_struct_stat buf; |
250 | | ret = !(WaitNamedPipeW( path_utf16, 0 ) || GetLastError() == ERROR_SEM_TIMEOUT); |
251 | | if( ret && !_wstati64( path_utf16, &buf ) ) |
252 | | ret = S_ISREG( buf.st_mode ); |
253 | | if( path_utf16 != path_buf ) |
254 | | free( path_utf16 ); |
255 | | } |
256 | | return ret; |
257 | | } |
258 | | #else |
259 | 0 | #define x264_vfprintf vfprintf |
260 | | |
261 | | static inline int x264_is_regular_file_path( const char *filename ) |
262 | 0 | { |
263 | 0 | x264_struct_stat file_stat; |
264 | 0 | if( x264_stat( filename, &file_stat ) ) |
265 | 0 | return 1; |
266 | 0 | return S_ISREG( file_stat.st_mode ); |
267 | 0 | } Unexecuted instantiation: base.c:x264_is_regular_file_path Unexecuted instantiation: cpu.c:x264_is_regular_file_path Unexecuted instantiation: api.c:x264_is_regular_file_path Unexecuted instantiation: bitstream.c:x264_is_regular_file_path Unexecuted instantiation: encoder.c:x264_is_regular_file_path Unexecuted instantiation: lookahead.c:x264_is_regular_file_path Unexecuted instantiation: threadpool.c:x264_is_regular_file_path Unexecuted instantiation: tables.c:x264_is_regular_file_path Unexecuted instantiation: mc.c:x264_is_regular_file_path Unexecuted instantiation: predict.c:x264_is_regular_file_path Unexecuted instantiation: pixel.c:x264_is_regular_file_path Unexecuted instantiation: macroblock.c:x264_is_regular_file_path Unexecuted instantiation: frame.c:x264_is_regular_file_path Unexecuted instantiation: dct.c:x264_is_regular_file_path Unexecuted instantiation: cabac.c:x264_is_regular_file_path Unexecuted instantiation: common.c:x264_is_regular_file_path Unexecuted instantiation: set.c:x264_is_regular_file_path Unexecuted instantiation: quant.c:x264_is_regular_file_path Unexecuted instantiation: deblock.c:x264_is_regular_file_path Unexecuted instantiation: vlc.c:x264_is_regular_file_path Unexecuted instantiation: mvpred.c:x264_is_regular_file_path Unexecuted instantiation: analyse.c:x264_is_regular_file_path Unexecuted instantiation: me.c:x264_is_regular_file_path Unexecuted instantiation: ratecontrol.c:x264_is_regular_file_path Unexecuted instantiation: cavlc.c:x264_is_regular_file_path Unexecuted instantiation: rectangle.c:x264_is_regular_file_path |
268 | | #endif |
269 | | |
270 | | static inline int x264_is_regular_file( FILE *filehandle ) |
271 | 0 | { |
272 | 0 | x264_struct_stat file_stat; |
273 | 0 | if( x264_fstat( fileno( filehandle ), &file_stat ) ) |
274 | 0 | return 1; |
275 | 0 | return S_ISREG( file_stat.st_mode ); |
276 | 0 | } Unexecuted instantiation: base.c:x264_is_regular_file Unexecuted instantiation: cpu.c:x264_is_regular_file Unexecuted instantiation: api.c:x264_is_regular_file Unexecuted instantiation: bitstream.c:x264_is_regular_file Unexecuted instantiation: encoder.c:x264_is_regular_file Unexecuted instantiation: lookahead.c:x264_is_regular_file Unexecuted instantiation: threadpool.c:x264_is_regular_file Unexecuted instantiation: tables.c:x264_is_regular_file Unexecuted instantiation: mc.c:x264_is_regular_file Unexecuted instantiation: predict.c:x264_is_regular_file Unexecuted instantiation: pixel.c:x264_is_regular_file Unexecuted instantiation: macroblock.c:x264_is_regular_file Unexecuted instantiation: frame.c:x264_is_regular_file Unexecuted instantiation: dct.c:x264_is_regular_file Unexecuted instantiation: cabac.c:x264_is_regular_file Unexecuted instantiation: common.c:x264_is_regular_file Unexecuted instantiation: set.c:x264_is_regular_file Unexecuted instantiation: quant.c:x264_is_regular_file Unexecuted instantiation: deblock.c:x264_is_regular_file Unexecuted instantiation: vlc.c:x264_is_regular_file Unexecuted instantiation: mvpred.c:x264_is_regular_file Unexecuted instantiation: analyse.c:x264_is_regular_file Unexecuted instantiation: me.c:x264_is_regular_file Unexecuted instantiation: ratecontrol.c:x264_is_regular_file Unexecuted instantiation: cavlc.c:x264_is_regular_file Unexecuted instantiation: rectangle.c:x264_is_regular_file |
277 | | |
278 | 0 | #define x264_glue3_expand(x,y,z) x##_##y##_##z |
279 | 0 | #define x264_glue3(x,y,z) x264_glue3_expand(x,y,z) |
280 | | |
281 | | #ifdef _MSC_VER |
282 | | #define DECLARE_ALIGNED( var, n ) __declspec(align(n)) var |
283 | | #else |
284 | 0 | #define DECLARE_ALIGNED( var, n ) var __attribute__((aligned(n))) |
285 | | #endif |
286 | | |
287 | 0 | #define ALIGNED_4( var ) DECLARE_ALIGNED( var, 4 ) |
288 | 0 | #define ALIGNED_8( var ) DECLARE_ALIGNED( var, 8 ) |
289 | 0 | #define ALIGNED_16( var ) DECLARE_ALIGNED( var, 16 ) |
290 | | |
291 | | // ARM compilers don't reliably align stack variables |
292 | | // - EABI requires only 8 byte stack alignment to be maintained |
293 | | // - gcc can't align stack variables to more even if the stack were to be correctly aligned outside the function |
294 | | // - armcc can't either, but is nice enough to actually tell you so |
295 | | // - Apple gcc only maintains 4 byte alignment |
296 | | // - llvm can align the stack, but only in svn and (unrelated) it exposes bugs in all released GNU binutils... |
297 | | |
298 | | #define ALIGNED_ARRAY_EMU( mask, type, name, sub1, ... )\ |
299 | | uint8_t name##_u [sizeof(type sub1 __VA_ARGS__) + mask]; \ |
300 | | type (*name) __VA_ARGS__ = (void*)((intptr_t)(name##_u+mask) & ~mask) |
301 | | |
302 | | #if ARCH_ARM && SYS_MACOSX |
303 | | #define ALIGNED_ARRAY_8( ... ) EXPAND( ALIGNED_ARRAY_EMU( 7, __VA_ARGS__ ) ) |
304 | | #else |
305 | 0 | #define ALIGNED_ARRAY_8( type, name, sub1, ... ) ALIGNED_8( type name sub1 __VA_ARGS__ ) |
306 | | #endif |
307 | | |
308 | | #if ARCH_ARM |
309 | | #define ALIGNED_ARRAY_16( ... ) EXPAND( ALIGNED_ARRAY_EMU( 15, __VA_ARGS__ ) ) |
310 | | #else |
311 | 0 | #define ALIGNED_ARRAY_16( type, name, sub1, ... ) ALIGNED_16( type name sub1 __VA_ARGS__ ) |
312 | | #endif |
313 | | |
314 | | #define EXPAND(x) x |
315 | | |
316 | | #if ARCH_X86 || ARCH_X86_64 || ARCH_LOONGARCH |
317 | 0 | #define NATIVE_ALIGN 64 |
318 | 0 | #define ALIGNED_32( var ) DECLARE_ALIGNED( var, 32 ) |
319 | 0 | #define ALIGNED_64( var ) DECLARE_ALIGNED( var, 64 ) |
320 | | #if STACK_ALIGNMENT >= 32 |
321 | 0 | #define ALIGNED_ARRAY_32( type, name, sub1, ... ) ALIGNED_32( type name sub1 __VA_ARGS__ ) |
322 | | #else |
323 | | #define ALIGNED_ARRAY_32( ... ) EXPAND( ALIGNED_ARRAY_EMU( 31, __VA_ARGS__ ) ) |
324 | | #endif |
325 | | #if STACK_ALIGNMENT >= 64 |
326 | 0 | #define ALIGNED_ARRAY_64( type, name, sub1, ... ) ALIGNED_64( type name sub1 __VA_ARGS__ ) |
327 | | #else |
328 | | #define ALIGNED_ARRAY_64( ... ) EXPAND( ALIGNED_ARRAY_EMU( 63, __VA_ARGS__ ) ) |
329 | | #endif |
330 | | #else |
331 | | #define NATIVE_ALIGN 16 |
332 | | #define ALIGNED_32 ALIGNED_16 |
333 | | #define ALIGNED_64 ALIGNED_16 |
334 | | #define ALIGNED_ARRAY_32 ALIGNED_ARRAY_16 |
335 | | #define ALIGNED_ARRAY_64 ALIGNED_ARRAY_16 |
336 | | #endif |
337 | | |
338 | | #if STACK_ALIGNMENT > 16 || (ARCH_X86 && STACK_ALIGNMENT > 4) |
339 | | #define REALIGN_STACK __attribute__((force_align_arg_pointer)) |
340 | | #else |
341 | | #define REALIGN_STACK |
342 | | #endif |
343 | | |
344 | | #if defined(__GNUC__) && (__GNUC__ > 3 || __GNUC__ == 3 && __GNUC_MINOR__ > 0) |
345 | 0 | #define UNUSED __attribute__((unused)) |
346 | | #define ALWAYS_INLINE __attribute__((always_inline)) inline |
347 | | #define NOINLINE __attribute__((noinline)) |
348 | | #define MAY_ALIAS __attribute__((may_alias)) |
349 | 0 | #define x264_constant_p(x) __builtin_constant_p(x) |
350 | 0 | #define x264_nonconstant_p(x) (!__builtin_constant_p(x)) |
351 | | #else |
352 | | #ifdef _MSC_VER |
353 | | #define ALWAYS_INLINE __forceinline |
354 | | #define NOINLINE __declspec(noinline) |
355 | | #else |
356 | | #define ALWAYS_INLINE inline |
357 | | #define NOINLINE |
358 | | #endif |
359 | | #define UNUSED |
360 | | #define MAY_ALIAS |
361 | | #define x264_constant_p(x) 0 |
362 | | #define x264_nonconstant_p(x) 0 |
363 | | #endif |
364 | | |
365 | | /* threads */ |
366 | | #if HAVE_BEOSTHREAD |
367 | | #include <kernel/OS.h> |
368 | | #define x264_pthread_t thread_id |
369 | | static inline int x264_pthread_create( x264_pthread_t *t, void *a, void *(*f)(void *), void *d ) |
370 | | { |
371 | | *t = spawn_thread( f, "", 10, d ); |
372 | | if( *t < B_NO_ERROR ) |
373 | | return -1; |
374 | | resume_thread( *t ); |
375 | | return 0; |
376 | | } |
377 | | #define x264_pthread_join(t,s) { long tmp; \ |
378 | | wait_for_thread(t,(s)?(long*)(s):&tmp); } |
379 | | |
380 | | #elif HAVE_POSIXTHREAD |
381 | | #include <pthread.h> |
382 | | #define x264_pthread_t pthread_t |
383 | 0 | #define x264_pthread_create pthread_create |
384 | 0 | #define x264_pthread_join pthread_join |
385 | | #define x264_pthread_mutex_t pthread_mutex_t |
386 | 0 | #define x264_pthread_mutex_init pthread_mutex_init |
387 | 0 | #define x264_pthread_mutex_destroy pthread_mutex_destroy |
388 | 0 | #define x264_pthread_mutex_lock pthread_mutex_lock |
389 | 0 | #define x264_pthread_mutex_unlock pthread_mutex_unlock |
390 | | #define x264_pthread_cond_t pthread_cond_t |
391 | 0 | #define x264_pthread_cond_init pthread_cond_init |
392 | 0 | #define x264_pthread_cond_destroy pthread_cond_destroy |
393 | 0 | #define x264_pthread_cond_broadcast pthread_cond_broadcast |
394 | 0 | #define x264_pthread_cond_wait pthread_cond_wait |
395 | | #define x264_pthread_attr_t pthread_attr_t |
396 | | #define x264_pthread_attr_init pthread_attr_init |
397 | | #define x264_pthread_attr_destroy pthread_attr_destroy |
398 | | #define x264_pthread_num_processors_np pthread_num_processors_np |
399 | | #define X264_PTHREAD_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER |
400 | | |
401 | | #elif HAVE_WIN32THREAD |
402 | | #include "win32thread.h" |
403 | | |
404 | | #else |
405 | | #define x264_pthread_t int |
406 | | #define x264_pthread_create(t,u,f,d) 0 |
407 | | #define x264_pthread_join(t,s) |
408 | | #endif //HAVE_*THREAD |
409 | | |
410 | | #if !HAVE_POSIXTHREAD && !HAVE_WIN32THREAD |
411 | | #define x264_pthread_mutex_t int |
412 | | #define x264_pthread_mutex_init(m,f) 0 |
413 | | #define x264_pthread_mutex_destroy(m) |
414 | | #define x264_pthread_mutex_lock(m) |
415 | | #define x264_pthread_mutex_unlock(m) |
416 | | #define x264_pthread_cond_t int |
417 | | #define x264_pthread_cond_init(c,f) 0 |
418 | | #define x264_pthread_cond_destroy(c) |
419 | | #define x264_pthread_cond_broadcast(c) |
420 | | #define x264_pthread_cond_wait(c,m) |
421 | | #define x264_pthread_attr_t int |
422 | | #define x264_pthread_attr_init(a) 0 |
423 | | #define x264_pthread_attr_destroy(a) |
424 | | #define X264_PTHREAD_MUTEX_INITIALIZER 0 |
425 | | #endif |
426 | | |
427 | | #if HAVE_WIN32THREAD || PTW32_STATIC_LIB |
428 | | X264_API int x264_threading_init( void ); |
429 | | #else |
430 | 0 | #define x264_threading_init() 0 |
431 | | #endif |
432 | | |
433 | | static ALWAYS_INLINE int x264_pthread_fetch_and_add( int *val, int add, x264_pthread_mutex_t *mutex ) |
434 | 0 | { |
435 | 0 | #if HAVE_THREAD |
436 | 0 | #if defined(__GNUC__) && (__GNUC__ > 4 || __GNUC__ == 4 && __GNUC_MINOR__ > 0) && HAVE_SYNC_FETCH_AND_ADD |
437 | 0 | return __sync_fetch_and_add( val, add ); |
438 | | #else |
439 | | x264_pthread_mutex_lock( mutex ); |
440 | | int res = *val; |
441 | | *val += add; |
442 | | x264_pthread_mutex_unlock( mutex ); |
443 | | return res; |
444 | | #endif |
445 | | #else |
446 | | int res = *val; |
447 | | *val += add; |
448 | | return res; |
449 | | #endif |
450 | 0 | } Unexecuted instantiation: base.c:x264_pthread_fetch_and_add Unexecuted instantiation: cpu.c:x264_pthread_fetch_and_add Unexecuted instantiation: api.c:x264_pthread_fetch_and_add Unexecuted instantiation: bitstream.c:x264_pthread_fetch_and_add Unexecuted instantiation: encoder.c:x264_pthread_fetch_and_add Unexecuted instantiation: lookahead.c:x264_pthread_fetch_and_add Unexecuted instantiation: threadpool.c:x264_pthread_fetch_and_add Unexecuted instantiation: tables.c:x264_pthread_fetch_and_add Unexecuted instantiation: mc.c:x264_pthread_fetch_and_add Unexecuted instantiation: predict.c:x264_pthread_fetch_and_add Unexecuted instantiation: pixel.c:x264_pthread_fetch_and_add Unexecuted instantiation: macroblock.c:x264_pthread_fetch_and_add Unexecuted instantiation: frame.c:x264_pthread_fetch_and_add Unexecuted instantiation: dct.c:x264_pthread_fetch_and_add Unexecuted instantiation: cabac.c:x264_pthread_fetch_and_add Unexecuted instantiation: common.c:x264_pthread_fetch_and_add Unexecuted instantiation: set.c:x264_pthread_fetch_and_add Unexecuted instantiation: quant.c:x264_pthread_fetch_and_add Unexecuted instantiation: deblock.c:x264_pthread_fetch_and_add Unexecuted instantiation: vlc.c:x264_pthread_fetch_and_add Unexecuted instantiation: mvpred.c:x264_pthread_fetch_and_add Unexecuted instantiation: analyse.c:x264_pthread_fetch_and_add Unexecuted instantiation: me.c:x264_pthread_fetch_and_add Unexecuted instantiation: ratecontrol.c:x264_pthread_fetch_and_add Unexecuted instantiation: cavlc.c:x264_pthread_fetch_and_add Unexecuted instantiation: rectangle.c:x264_pthread_fetch_and_add |
451 | | |
452 | 0 | #define WORD_SIZE sizeof(void*) |
453 | | |
454 | | #define asm __asm__ |
455 | | |
456 | | #if WORDS_BIGENDIAN |
457 | | #define endian_fix(x) (x) |
458 | | #define endian_fix64(x) (x) |
459 | | #define endian_fix32(x) (x) |
460 | | #define endian_fix16(x) (x) |
461 | | #else |
462 | | #if HAVE_X86_INLINE_ASM && HAVE_MMX |
463 | | static ALWAYS_INLINE uint32_t endian_fix32( uint32_t x ) |
464 | | { |
465 | | asm("bswap %0":"+r"(x)); |
466 | | return x; |
467 | | } |
468 | | #elif defined(__GNUC__) && HAVE_ARMV6 |
469 | | static ALWAYS_INLINE uint32_t endian_fix32( uint32_t x ) |
470 | | { |
471 | | asm("rev %0, %0":"+r"(x)); |
472 | | return x; |
473 | | } |
474 | | #else |
475 | | static ALWAYS_INLINE uint32_t endian_fix32( uint32_t x ) |
476 | 0 | { |
477 | 0 | return (x<<24) + ((x<<8)&0xff0000) + ((x>>8)&0xff00) + (x>>24); |
478 | 0 | } Unexecuted instantiation: base.c:endian_fix32 Unexecuted instantiation: cpu.c:endian_fix32 Unexecuted instantiation: api.c:endian_fix32 Unexecuted instantiation: bitstream.c:endian_fix32 Unexecuted instantiation: encoder.c:endian_fix32 Unexecuted instantiation: lookahead.c:endian_fix32 Unexecuted instantiation: threadpool.c:endian_fix32 Unexecuted instantiation: tables.c:endian_fix32 Unexecuted instantiation: mc.c:endian_fix32 Unexecuted instantiation: predict.c:endian_fix32 Unexecuted instantiation: pixel.c:endian_fix32 Unexecuted instantiation: macroblock.c:endian_fix32 Unexecuted instantiation: frame.c:endian_fix32 Unexecuted instantiation: dct.c:endian_fix32 Unexecuted instantiation: cabac.c:endian_fix32 Unexecuted instantiation: common.c:endian_fix32 Unexecuted instantiation: set.c:endian_fix32 Unexecuted instantiation: quant.c:endian_fix32 Unexecuted instantiation: deblock.c:endian_fix32 Unexecuted instantiation: vlc.c:endian_fix32 Unexecuted instantiation: mvpred.c:endian_fix32 Unexecuted instantiation: analyse.c:endian_fix32 Unexecuted instantiation: me.c:endian_fix32 Unexecuted instantiation: ratecontrol.c:endian_fix32 Unexecuted instantiation: cavlc.c:endian_fix32 Unexecuted instantiation: rectangle.c:endian_fix32 |
479 | | #endif |
480 | | #if HAVE_X86_INLINE_ASM && ARCH_X86_64 |
481 | | static ALWAYS_INLINE uint64_t endian_fix64( uint64_t x ) |
482 | | { |
483 | | asm("bswap %0":"+r"(x)); |
484 | | return x; |
485 | | } |
486 | | #else |
487 | | static ALWAYS_INLINE uint64_t endian_fix64( uint64_t x ) |
488 | 0 | { |
489 | 0 | return endian_fix32(x>>32) + ((uint64_t)endian_fix32(x)<<32); |
490 | 0 | } Unexecuted instantiation: base.c:endian_fix64 Unexecuted instantiation: cpu.c:endian_fix64 Unexecuted instantiation: api.c:endian_fix64 Unexecuted instantiation: bitstream.c:endian_fix64 Unexecuted instantiation: encoder.c:endian_fix64 Unexecuted instantiation: lookahead.c:endian_fix64 Unexecuted instantiation: threadpool.c:endian_fix64 Unexecuted instantiation: tables.c:endian_fix64 Unexecuted instantiation: mc.c:endian_fix64 Unexecuted instantiation: predict.c:endian_fix64 Unexecuted instantiation: pixel.c:endian_fix64 Unexecuted instantiation: macroblock.c:endian_fix64 Unexecuted instantiation: frame.c:endian_fix64 Unexecuted instantiation: dct.c:endian_fix64 Unexecuted instantiation: cabac.c:endian_fix64 Unexecuted instantiation: common.c:endian_fix64 Unexecuted instantiation: set.c:endian_fix64 Unexecuted instantiation: quant.c:endian_fix64 Unexecuted instantiation: deblock.c:endian_fix64 Unexecuted instantiation: vlc.c:endian_fix64 Unexecuted instantiation: mvpred.c:endian_fix64 Unexecuted instantiation: analyse.c:endian_fix64 Unexecuted instantiation: me.c:endian_fix64 Unexecuted instantiation: ratecontrol.c:endian_fix64 Unexecuted instantiation: cavlc.c:endian_fix64 Unexecuted instantiation: rectangle.c:endian_fix64 |
491 | | #endif |
492 | | static ALWAYS_INLINE uintptr_t endian_fix( uintptr_t x ) |
493 | 0 | { |
494 | 0 | return WORD_SIZE == 8 ? endian_fix64(x) : endian_fix32(x); |
495 | 0 | } Unexecuted instantiation: base.c:endian_fix Unexecuted instantiation: cpu.c:endian_fix Unexecuted instantiation: api.c:endian_fix Unexecuted instantiation: bitstream.c:endian_fix Unexecuted instantiation: encoder.c:endian_fix Unexecuted instantiation: lookahead.c:endian_fix Unexecuted instantiation: threadpool.c:endian_fix Unexecuted instantiation: tables.c:endian_fix Unexecuted instantiation: mc.c:endian_fix Unexecuted instantiation: predict.c:endian_fix Unexecuted instantiation: pixel.c:endian_fix Unexecuted instantiation: macroblock.c:endian_fix Unexecuted instantiation: frame.c:endian_fix Unexecuted instantiation: dct.c:endian_fix Unexecuted instantiation: cabac.c:endian_fix Unexecuted instantiation: common.c:endian_fix Unexecuted instantiation: set.c:endian_fix Unexecuted instantiation: quant.c:endian_fix Unexecuted instantiation: deblock.c:endian_fix Unexecuted instantiation: vlc.c:endian_fix Unexecuted instantiation: mvpred.c:endian_fix Unexecuted instantiation: analyse.c:endian_fix Unexecuted instantiation: me.c:endian_fix Unexecuted instantiation: ratecontrol.c:endian_fix Unexecuted instantiation: cavlc.c:endian_fix Unexecuted instantiation: rectangle.c:endian_fix |
496 | | static ALWAYS_INLINE uint16_t endian_fix16( uint16_t x ) |
497 | 0 | { |
498 | 0 | return (uint16_t)((x<<8)|(x>>8)); |
499 | 0 | } Unexecuted instantiation: base.c:endian_fix16 Unexecuted instantiation: cpu.c:endian_fix16 Unexecuted instantiation: api.c:endian_fix16 Unexecuted instantiation: bitstream.c:endian_fix16 Unexecuted instantiation: encoder.c:endian_fix16 Unexecuted instantiation: lookahead.c:endian_fix16 Unexecuted instantiation: threadpool.c:endian_fix16 Unexecuted instantiation: tables.c:endian_fix16 Unexecuted instantiation: mc.c:endian_fix16 Unexecuted instantiation: predict.c:endian_fix16 Unexecuted instantiation: pixel.c:endian_fix16 Unexecuted instantiation: macroblock.c:endian_fix16 Unexecuted instantiation: frame.c:endian_fix16 Unexecuted instantiation: dct.c:endian_fix16 Unexecuted instantiation: cabac.c:endian_fix16 Unexecuted instantiation: common.c:endian_fix16 Unexecuted instantiation: set.c:endian_fix16 Unexecuted instantiation: quant.c:endian_fix16 Unexecuted instantiation: deblock.c:endian_fix16 Unexecuted instantiation: vlc.c:endian_fix16 Unexecuted instantiation: mvpred.c:endian_fix16 Unexecuted instantiation: analyse.c:endian_fix16 Unexecuted instantiation: me.c:endian_fix16 Unexecuted instantiation: ratecontrol.c:endian_fix16 Unexecuted instantiation: cavlc.c:endian_fix16 Unexecuted instantiation: rectangle.c:endian_fix16 |
500 | | #endif |
501 | | |
502 | | /* For values with 4 bits or less. */ |
503 | | static ALWAYS_INLINE int x264_ctz_4bit( uint32_t x ) |
504 | 0 | { |
505 | 0 | static uint8_t lut[16] = {4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0}; |
506 | 0 | return lut[x]; |
507 | 0 | } Unexecuted instantiation: base.c:x264_ctz_4bit Unexecuted instantiation: cpu.c:x264_ctz_4bit Unexecuted instantiation: api.c:x264_ctz_4bit Unexecuted instantiation: bitstream.c:x264_ctz_4bit Unexecuted instantiation: encoder.c:x264_ctz_4bit Unexecuted instantiation: lookahead.c:x264_ctz_4bit Unexecuted instantiation: threadpool.c:x264_ctz_4bit Unexecuted instantiation: tables.c:x264_ctz_4bit Unexecuted instantiation: mc.c:x264_ctz_4bit Unexecuted instantiation: predict.c:x264_ctz_4bit Unexecuted instantiation: pixel.c:x264_ctz_4bit Unexecuted instantiation: macroblock.c:x264_ctz_4bit Unexecuted instantiation: frame.c:x264_ctz_4bit Unexecuted instantiation: dct.c:x264_ctz_4bit Unexecuted instantiation: cabac.c:x264_ctz_4bit Unexecuted instantiation: common.c:x264_ctz_4bit Unexecuted instantiation: set.c:x264_ctz_4bit Unexecuted instantiation: quant.c:x264_ctz_4bit Unexecuted instantiation: deblock.c:x264_ctz_4bit Unexecuted instantiation: vlc.c:x264_ctz_4bit Unexecuted instantiation: mvpred.c:x264_ctz_4bit Unexecuted instantiation: analyse.c:x264_ctz_4bit Unexecuted instantiation: me.c:x264_ctz_4bit Unexecuted instantiation: ratecontrol.c:x264_ctz_4bit Unexecuted instantiation: cavlc.c:x264_ctz_4bit Unexecuted instantiation: rectangle.c:x264_ctz_4bit |
508 | | |
509 | | #if defined(__GNUC__) && (__GNUC__ > 3 || __GNUC__ == 3 && __GNUC_MINOR__ > 3) |
510 | 0 | #define x264_clz(x) __builtin_clz(x) |
511 | 0 | #define x264_ctz(x) __builtin_ctz(x) |
512 | | #else |
513 | | static ALWAYS_INLINE int x264_clz( uint32_t x ) |
514 | | { |
515 | | static uint8_t lut[16] = {4,3,2,2,1,1,1,1,0,0,0,0,0,0,0,0}; |
516 | | int y, z = (((x >> 16) - 1) >> 27) & 16; |
517 | | x >>= z^16; |
518 | | z += y = ((x - 0x100) >> 28) & 8; |
519 | | x >>= y^8; |
520 | | z += y = ((x - 0x10) >> 29) & 4; |
521 | | x >>= y^4; |
522 | | return z + lut[x]; |
523 | | } |
524 | | |
525 | | static ALWAYS_INLINE int x264_ctz( uint32_t x ) |
526 | | { |
527 | | static uint8_t lut[16] = {4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0}; |
528 | | int y, z = (((x & 0xffff) - 1) >> 27) & 16; |
529 | | x >>= z; |
530 | | z += y = (((x & 0xff) - 1) >> 28) & 8; |
531 | | x >>= y; |
532 | | z += y = (((x & 0xf) - 1) >> 29) & 4; |
533 | | x >>= y; |
534 | | return z + lut[x&0xf]; |
535 | | } |
536 | | #endif |
537 | | |
538 | | #if HAVE_X86_INLINE_ASM && HAVE_MMX |
539 | | /* Don't use __builtin_prefetch; even as recent as 4.3.4, GCC seems incapable of |
540 | | * using complex address modes properly unless we use inline asm. */ |
541 | | static ALWAYS_INLINE void x264_prefetch( void *p ) |
542 | | { |
543 | | asm volatile( "prefetcht0 %0"::"m"(*(uint8_t*)p) ); |
544 | | } |
545 | | /* We require that prefetch not fault on invalid reads, so we only enable it on |
546 | | * known architectures. */ |
547 | | #elif defined(__GNUC__) && (__GNUC__ > 3 || __GNUC__ == 3 && __GNUC_MINOR__ > 1) &&\ |
548 | | (ARCH_X86 || ARCH_X86_64 || ARCH_ARM || ARCH_PPC) |
549 | 0 | #define x264_prefetch(x) __builtin_prefetch(x) |
550 | | #else |
551 | | #define x264_prefetch(x) |
552 | | #endif |
553 | | |
554 | | #endif /* X264_OSDEP_H */ |