]> git.sesse.net Git - x264/blob - common/osdep.c
d3bcd417110232971e1c6d2696a49d5405b079ce
[x264] / common / osdep.c
1 /*****************************************************************************
2  * osdep.c: platform-specific code
3  *****************************************************************************
4  * Copyright (C) 2003-2015 x264 project
5  *
6  * Authors: Steven Walters <kemuri9@gmail.com>
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 #include "common.h"
29
30 #ifdef _WIN32
31 #include <windows.h>
32 #include <io.h>
33 #endif
34
35 #if SYS_WINDOWS
36 #include <sys/types.h>
37 #include <sys/timeb.h>
38 #else
39 #include <sys/time.h>
40 #endif
41 #include <time.h>
42
43 #if PTW32_STATIC_LIB
44 /* this is a global in pthread-win32 to indicate if it has been initialized or not */
45 extern int ptw32_processInitialized;
46 #endif
47
48 int64_t x264_mdate( void )
49 {
50 #if SYS_WINDOWS
51     struct timeb tb;
52     ftime( &tb );
53     return ((int64_t)tb.time * 1000 + (int64_t)tb.millitm) * 1000;
54 #else
55     struct timeval tv_date;
56     gettimeofday( &tv_date, NULL );
57     return (int64_t)tv_date.tv_sec * 1000000 + (int64_t)tv_date.tv_usec;
58 #endif
59 }
60
61 #if HAVE_WIN32THREAD || PTW32_STATIC_LIB
62 /* state of the threading library being initialized */
63 static volatile LONG x264_threading_is_init = 0;
64
65 static void x264_threading_destroy( void )
66 {
67 #if PTW32_STATIC_LIB
68     pthread_win32_thread_detach_np();
69     pthread_win32_process_detach_np();
70 #else
71     x264_win32_threading_destroy();
72 #endif
73 }
74
75 int x264_threading_init( void )
76 {
77     /* if already init, then do nothing */
78     if( InterlockedCompareExchange( &x264_threading_is_init, 1, 0 ) )
79         return 0;
80 #if PTW32_STATIC_LIB
81     /* if static pthread-win32 is already initialized, then do nothing */
82     if( ptw32_processInitialized )
83         return 0;
84     if( !pthread_win32_process_attach_np() )
85         return -1;
86 #else
87     if( x264_win32_threading_init() )
88         return -1;
89 #endif
90     /* register cleanup to run at process termination */
91     atexit( x264_threading_destroy );
92
93     return 0;
94 }
95 #endif
96
97 #ifdef _WIN32
98 /* Functions for dealing with Unicode on Windows. */
99 FILE *x264_fopen( const char *filename, const char *mode )
100 {
101     wchar_t filename_utf16[MAX_PATH];
102     wchar_t mode_utf16[16];
103     if( utf8_to_utf16( filename, filename_utf16 ) && utf8_to_utf16( mode, mode_utf16 ) )
104         return _wfopen( filename_utf16, mode_utf16 );
105     return NULL;
106 }
107
108 int x264_rename( const char *oldname, const char *newname )
109 {
110     wchar_t oldname_utf16[MAX_PATH];
111     wchar_t newname_utf16[MAX_PATH];
112     if( utf8_to_utf16( oldname, oldname_utf16 ) && utf8_to_utf16( newname, newname_utf16 ) )
113     {
114         /* POSIX says that rename() removes the destination, but Win32 doesn't. */
115         _wunlink( newname_utf16 );
116         return _wrename( oldname_utf16, newname_utf16 );
117     }
118     return -1;
119 }
120
121 int x264_stat( const char *path, x264_struct_stat *buf )
122 {
123     wchar_t path_utf16[MAX_PATH];
124     if( utf8_to_utf16( path, path_utf16 ) )
125         return _wstati64( path_utf16, buf );
126     return -1;
127 }
128
129 int x264_vfprintf( FILE *stream, const char *format, va_list arg )
130 {
131     HANDLE console = NULL;
132     DWORD mode;
133
134     if( stream == stdout )
135         console = GetStdHandle( STD_OUTPUT_HANDLE );
136     else if( stream == stderr )
137         console = GetStdHandle( STD_ERROR_HANDLE );
138
139     /* Only attempt to convert to UTF-16 when writing to a non-redirected console screen buffer. */
140     if( GetConsoleMode( console, &mode ) )
141     {
142         char buf[4096];
143         wchar_t buf_utf16[4096];
144         va_list arg2;
145
146         va_copy( arg2, arg );
147         int length = vsnprintf( buf, sizeof(buf), format, arg2 );
148         va_end( arg2 );
149
150         if( length > 0 && length < sizeof(buf) )
151         {
152             /* WriteConsoleW is the most reliable way to output Unicode to a console. */
153             int length_utf16 = MultiByteToWideChar( CP_UTF8, 0, buf, length, buf_utf16, sizeof(buf_utf16)/sizeof(wchar_t) );
154             DWORD written;
155             WriteConsoleW( console, buf_utf16, length_utf16, &written, NULL );
156             return length;
157         }
158     }
159     return vfprintf( stream, format, arg );
160 }
161
162 int x264_is_pipe( const char *path )
163 {
164     wchar_t path_utf16[MAX_PATH];
165     if( utf8_to_utf16( path, path_utf16 ) )
166         return WaitNamedPipeW( path_utf16, 0 );
167     return 0;
168 }
169 #endif