OSDN Git Service

disable asserts in libdvdnav except when configured with --debug=max
[handbrake-jp/handbrake-jp-git.git] / libhb / ports.c
index 20c2cae..85e009a 100644 (file)
@@ -1,22 +1,50 @@
 /* $Id: ports.c,v 1.15 2005/10/15 18:05:03 titer Exp $
 
    This file is part of the HandBrake source code.
-   Homepage: <http://handbrake.m0k.org/>.
+   Homepage: <http://handbrake.fr/>.
    It may be used under the terms of the GNU General Public License. */
 
-#include <time.h> 
-#include <sys/time.h>
+#ifdef USE_PTHREAD
+#ifdef SYS_LINUX
+#define _GNU_SOURCE
+#include <sched.h>
+#endif
+#include <pthread.h>
+#endif
 
-#if defined( SYS_BEOS )
-#include <OS.h>
-#include <signal.h>
-#elif defined( SYS_DARWIN ) || defined( SYS_LINUX ) || defined( SYS_FREEBSD )
+#ifdef SYS_BEOS
+#include <kernel/OS.h>
+#endif
+
+#if defined(SYS_DARWIN) || defined(SYS_FREEBSD)
+#include <sys/types.h>
+#include <sys/sysctl.h>
+#endif
+
+#ifdef SYS_OPENBSD
+#include <sys/param.h>
+#include <sys/sysctl.h>
+#include <machine/cpu.h>
+#endif
+
+#ifdef SYS_CYGWIN
+#include <windows.h>
+#endif
+
+#ifdef SYS_MINGW
 #include <pthread.h>
-#elif defined( SYS_CYGWIN )
 #include <windows.h>
 #endif
 
-#ifdef SYS_CYGWIN
+#ifdef SYS_SunOS
+#include <sys/processor.h>
+#endif
+
+#include <time.h>
+#include <sys/time.h>
+
+
+#ifdef SYS_MINGW
 #include <winsock2.h>
 #include <ws2tcpip.h>
 #else
 #include <netinet/in.h>
 #endif
 
+#if defined( SYS_LINUX )
+#include <linux/cdrom.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#elif defined( SYS_OPENBSD )
+#include <sys/dvdio.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#endif
+
+#include <stddef.h>
+
 #include "hb.h"
 
 /************************************************************************
@@ -35,6 +75,7 @@
  * On Win32, we implement a gettimeofday emulation here because
  * libdvdread and libmp4v2 use it without checking.
  ************************************************************************/
+/*
 #ifdef SYS_CYGWIN
 struct timezone
 {
@@ -49,6 +90,41 @@ int gettimeofday( struct timeval * tv, struct timezone * tz )
     return 0;
 }
 #endif
+*/
+
+int hb_dvd_region(char *device, int *region_mask)
+{
+#if defined( DVD_LU_SEND_RPC_STATE ) && defined( DVD_AUTH )
+    struct stat  st;
+    dvd_authinfo ai;
+    int          fd, ret;
+
+    fd = open( device, O_RDONLY );
+    if ( fd < 0 )
+        return -1;
+    if ( fstat( fd, &st ) < 0 )
+       {
+        close( fd );
+        return -1;
+       }
+    if ( !( S_ISBLK( st.st_mode ) || S_ISCHR( st.st_mode ) ) )
+       {
+        close( fd );
+        return -1;
+       }
+
+    ai.type = DVD_LU_SEND_RPC_STATE;
+    ret = ioctl(fd, DVD_AUTH, &ai);
+    close( fd );
+    if ( ret < 0 )
+        return ret;
+
+    *region_mask = ai.lrpcs.region_mask;
+    return 0;
+#else
+    return -1;
+#endif
+}
 
 uint64_t hb_get_date()
 {
@@ -70,9 +146,9 @@ void hb_snooze( int delay )
     }
 #if defined( SYS_BEOS )
     snooze( 1000 * delay );
-#elif defined( SYS_DARWIN ) || defined( SYS_LINUX ) || defined( SYS_FREEBSD )
+#elif defined( SYS_DARWIN ) || defined( SYS_LINUX ) || defined( SYS_FREEBSD) || defined( SYS_SunOS )
     usleep( 1000 * delay );
-#elif defined( SYS_CYGWIN )
+#elif defined( SYS_CYGWIN ) || defined( SYS_MINGW )
     Sleep( delay );
 #endif
 }
@@ -94,54 +170,52 @@ int hb_get_cpu_count()
     }
     cpu_count = 1;
 
-#if defined( SYS_BEOS )
-    {
-        system_info info;
-        get_system_info( &info );
-        cpu_count = info.cpu_count;
-    }
-
-#elif defined( SYS_DARWIN ) || defined( SYS_FREEBSD )
-    FILE * info;
-    char   buffer[16];
+#if defined(SYS_CYGWIN) || defined(SYS_MINGW)
+    SYSTEM_INFO cpuinfo;
+    GetSystemInfo( &cpuinfo );
+    cpu_count = cpuinfo.dwNumberOfProcessors;
 
-    if( ( info = popen( "/usr/sbin/sysctl hw.ncpu", "r" ) ) )
+#elif defined(SYS_LINUX)
+    unsigned int bit;
+    cpu_set_t p_aff;
+    memset( &p_aff, 0, sizeof(p_aff) );
+    sched_getaffinity( 0, sizeof(p_aff), &p_aff );
+    for( cpu_count = 0, bit = 0; bit < sizeof(p_aff); bit++ )
+         cpu_count += (((uint8_t *)&p_aff)[bit / 8] >> (bit % 8)) & 1;
+
+#elif defined(SYS_BEOS)
+    system_info info;
+    get_system_info( &info );
+    cpu_count = info.cpu_count;
+
+#elif defined(SYS_DARWIN) || defined(SYS_FREEBSD) || defined(SYS_OPENBSD)
+    size_t length = sizeof( cpu_count );
+#ifdef SYS_OPENBSD
+    int mib[2] = { CTL_HW, HW_NCPU };
+    if( sysctl(mib, 2, &cpu_count, &length, NULL, 0) )
+#else
+    if( sysctlbyname("hw.ncpu", &cpu_count, &length, NULL, 0) )
+#endif
     {
-        memset( buffer, 0, 16 );
-        if( fgets( buffer, 15, info ) )
-        {
-            if( sscanf( buffer, "hw.ncpu: %d", &cpu_count ) != 1 )
-            {
-                cpu_count = 1;
-            }
-        }
-        fclose( info );
+        cpu_count = 1;
     }
 
-#elif defined( SYS_LINUX )
+#elif defined( SYS_SunOS )
     {
-        FILE * info;
-        char   buffer[8];
+        processorid_t cpumax;
+        int i,j=0;
+
+        cpumax = sysconf(_SC_CPUID_MAX);
 
-        if( ( info = popen( "grep -c '^processor' /proc/cpuinfo",
-                            "r" ) ) )
+        for(i = 0; i <= cpumax; i++ )
         {
-            memset( buffer, 0, 8 );
-            if( fgets( buffer, 7, info ) )
+            if(p_online(i, P_STATUS) != -1)
             {
-                if( sscanf( buffer, "%d", &cpu_count ) != 1 )
-                {
-                    cpu_count = 1;
-                }
+                j++;
             }
-            fclose( info );
         }
+        cpu_count=j;
     }
-
-#elif defined( SYS_CYGWIN )
-    SYSTEM_INFO cpuinfo;
-    GetSystemInfo( &cpuinfo );
-    cpu_count = cpuinfo.dwNumberOfProcessors;
 #endif
 
     cpu_count = MAX( 1, cpu_count );
@@ -158,7 +232,7 @@ void hb_get_tempory_directory( hb_handle_t * h, char path[512] )
     char base[512];
 
     /* Create the base */
-#ifdef SYS_CYGWIN
+#if defined( SYS_CYGWIN ) || defined( SYS_MINGW )
     char *p;
     int i_size = GetTempPath( 512, base );
     if( i_size <= 0 || i_size >= 512 )
@@ -190,7 +264,7 @@ void hb_get_tempory_filename( hb_handle_t * h, char name[1024],
 
     hb_get_tempory_directory( h, name );
     strcat( name, "/" );
-    
+
     va_start( args, fmt );
     vsnprintf( &name[strlen(name)], 1024 - strlen(name), fmt, args );
     va_end( args );
@@ -204,7 +278,7 @@ void hb_get_tempory_filename( hb_handle_t * h, char name[1024],
  ***********************************************************************/
 void hb_mkdir( char * name )
 {
-#ifdef SYS_CYGWIN
+#ifdef SYS_MINGW
     mkdir( name );
 #else
     mkdir( name, 0755 );
@@ -226,13 +300,34 @@ struct hb_thread_s
 
 #if defined( SYS_BEOS )
     thread_id    thread;
-#elif defined( SYS_DARWIN ) || defined( SYS_LINUX ) || defined( SYS_FREEBSD )
+#elif USE_PTHREAD
     pthread_t    thread;
-#elif defined( SYS_CYGWIN )
-    HANDLE       thread;
+//#elif defined( SYS_CYGWIN )
+//    HANDLE       thread;
 #endif
 };
 
+/* Get a unique identifier to thread and represent as 64-bit unsigned.
+ * If unsupported, the value 0 is be returned.
+ * Caller should use result only for display/log purposes.
+ */
+static uint64_t hb_thread_to_integer( const hb_thread_t* t )
+{
+#if defined( USE_PTHREAD )
+    #if defined( SYS_CYGWIN )
+        return (uint64_t)t->thread;
+    #elif defined( _WIN32 ) || defined( __MINGW32__ )
+        return (uint64_t)(ptrdiff_t)t->thread.p;
+    #elif defined( SYS_DARWIN )
+        return (unsigned long)t->thread;
+    #else
+        return (uint64_t)t->thread;
+    #endif
+#else
+    return 0;
+#endif
+}
+
 /************************************************************************
  * hb_thread_func()
  ************************************************************************
@@ -263,7 +358,7 @@ static void hb_thread_func( void * _t )
     t->function( t->arg );
 
     /* Inform that the thread can be joined now */
-    hb_log( "thread %d exited (\"%s\")", t->thread, t->name );
+    hb_deep_log( 2, "thread %"PRIx64" exited (\"%s\")", hb_thread_to_integer( t ), t->name );
     hb_lock( t->lock );
     t->exited = 1;
     hb_unlock( t->lock );
@@ -295,20 +390,20 @@ hb_thread_t * hb_thread_init( char * name, void (* function)(void *),
                               name, priority, t );
     resume_thread( t->thread );
 
-#elif defined( SYS_DARWIN ) || defined( SYS_LINUX ) || defined( SYS_FREEBSD )
+#elif USE_PTHREAD
     pthread_create( &t->thread, NULL,
                     (void * (*)( void * )) hb_thread_func, t );
 
-#elif defined( SYS_CYGWIN )
-    t->thread = CreateThread( NULL, 0,
-        (LPTHREAD_START_ROUTINE) hb_thread_func, t, 0, NULL );
-
-    /* Maybe use THREAD_PRIORITY_LOWEST instead */
-    if( priority == HB_LOW_PRIORITY )
-        SetThreadPriority( GetCurrentThread(), THREAD_PRIORITY_BELOW_NORMAL );
+//#elif defined( SYS_CYGWIN )
+//    t->thread = CreateThread( NULL, 0,
+//        (LPTHREAD_START_ROUTINE) hb_thread_func, t, 0, NULL );
+//
+//    /* Maybe use THREAD_PRIORITY_LOWEST instead */
+//    if( priority == HB_LOW_PRIORITY )
+//        SetThreadPriority( GetCurrentThread(), THREAD_PRIORITY_BELOW_NORMAL );
 #endif
 
-    hb_log( "thread %d started (\"%s\")", t->thread, t->name );
+    hb_deep_log( 2, "thread %"PRIx64" started (\"%s\")", hb_thread_to_integer( t ), t->name );
     return t;
 }
 
@@ -325,21 +420,20 @@ void hb_thread_close( hb_thread_t ** _t )
 #if defined( SYS_BEOS )
     long exit_value;
     wait_for_thread( t->thread, &exit_value );
-    
-#elif defined( SYS_DARWIN ) || defined( SYS_LINUX ) || defined( SYS_FREEBSD )
+
+#elif USE_PTHREAD
     pthread_join( t->thread, NULL );
 
-#elif defined( SYS_CYGWIN )
-    WaitForSingleObject( t->thread, INFINITE );
+//#elif defined( SYS_CYGWIN )
+//    WaitForSingleObject( t->thread, INFINITE );
 #endif
-    
-    hb_log( "thread %d joined (\"%s\")",
-            t->thread, t->name );
+
+    hb_deep_log( 2, "thread %"PRIx64" joined (\"%s\")", hb_thread_to_integer( t ), t->name );
 
     hb_lock_close( &t->lock );
     free( t->name );
     free( t );
-    *_t = NULL; 
+    *_t = NULL;
 }
 
 /************************************************************************
@@ -365,10 +459,10 @@ struct hb_lock_s
 {
 #if defined( SYS_BEOS )
     sem_id          sem;
-#elif defined( SYS_DARWIN ) || defined( SYS_LINUX ) || defined( SYS_FREEBSD )
+#elif USE_PTHREAD
     pthread_mutex_t mutex;
-#elif defined( SYS_CYGWIN )
-    HANDLE          mutex;
+//#elif defined( SYS_CYGWIN )
+//    HANDLE          mutex;
 #endif
 };
 
@@ -386,10 +480,18 @@ hb_lock_t * hb_lock_init()
 
 #if defined( SYS_BEOS )
     l->sem = create_sem( 1, "sem" );
-#elif defined( SYS_DARWIN ) || defined( SYS_LINUX ) || defined( SYS_FREEBSD )
-    pthread_mutex_init( &l->mutex, NULL );
-#elif defined( SYS_CYGWIN )
-    l->mutex = CreateMutex( 0, FALSE, 0 );
+#elif USE_PTHREAD
+    pthread_mutexattr_t mta;
+
+    pthread_mutexattr_init(&mta);
+
+#if defined( SYS_CYGWIN )
+    pthread_mutexattr_settype(&mta, PTHREAD_MUTEX_NORMAL);
+#endif
+
+    pthread_mutex_init( &l->mutex, &mta );
+//#elif defined( SYS_CYGWIN )
+//    l->mutex = CreateMutex( 0, FALSE, 0 );
 #endif
 
     return l;
@@ -401,10 +503,10 @@ void hb_lock_close( hb_lock_t ** _l )
 
 #if defined( SYS_BEOS )
     delete_sem( l->sem );
-#elif defined( SYS_DARWIN ) || defined( SYS_LINUX ) || defined( SYS_FREEBSD )
+#elif USE_PTHREAD
     pthread_mutex_destroy( &l->mutex );
-#elif defined( SYS_CYGWIN )
-    CloseHandle( l->mutex );
+//#elif defined( SYS_CYGWIN )
+//    CloseHandle( l->mutex );
 #endif
     free( l );
 
@@ -415,10 +517,10 @@ void hb_lock( hb_lock_t * l )
 {
 #if defined( SYS_BEOS )
     acquire_sem( l->sem );
-#elif defined( SYS_DARWIN ) || defined( SYS_LINUX ) || defined( SYS_FREEBSD )
+#elif USE_PTHREAD
     pthread_mutex_lock( &l->mutex );
-#elif defined( SYS_CYGWIN )
-    WaitForSingleObject( l->mutex, INFINITE );
+//#elif defined( SYS_CYGWIN )
+//    WaitForSingleObject( l->mutex, INFINITE );
 #endif
 }
 
@@ -426,10 +528,10 @@ void hb_unlock( hb_lock_t * l )
 {
 #if defined( SYS_BEOS )
     release_sem( l->sem );
-#elif defined( SYS_DARWIN ) || defined( SYS_LINUX ) || defined( SYS_FREEBSD )
+#elif USE_PTHREAD
     pthread_mutex_unlock( &l->mutex );
-#elif defined( SYS_CYGWIN )
-    ReleaseMutex( l->mutex );
+//#elif defined( SYS_CYGWIN )
+//    ReleaseMutex( l->mutex );
 #endif
 }
 
@@ -440,10 +542,10 @@ struct hb_cond_s
 {
 #if defined( SYS_BEOS )
     int                 thread;
-#elif defined( SYS_DARWIN ) || defined( SYS_LINUX ) || defined( SYS_FREEBSD )
+#elif USE_PTHREAD
     pthread_cond_t      cond;
-#elif defined( SYS_CYGWIN )
-    HANDLE              event;
+//#elif defined( SYS_CYGWIN )
+//    HANDLE              event;
 #endif
 };
 
@@ -462,10 +564,10 @@ hb_cond_t * hb_cond_init()
 
 #if defined( SYS_BEOS )
     c->thread = -1;
-#elif defined( SYS_DARWIN ) || defined( SYS_LINUX ) || defined( SYS_FREEBSD )
+#elif USE_PTHREAD
     pthread_cond_init( &c->cond, NULL );
-#elif defined( SYS_CYGWIN )
-    c->event = CreateEvent( NULL, FALSE, FALSE, NULL );
+//#elif defined( SYS_CYGWIN )
+//    c->event = CreateEvent( NULL, FALSE, FALSE, NULL );
 #endif
 
     return c;
@@ -476,10 +578,10 @@ void hb_cond_close( hb_cond_t ** _c )
     hb_cond_t * c = *_c;
 
 #if defined( SYS_BEOS )
-#elif defined( SYS_DARWIN ) || defined( SYS_LINUX ) || defined( SYS_FREEBSD )
+#elif USE_PTHREAD
     pthread_cond_destroy( &c->cond );
-#elif defined( SYS_CYGWIN )
-    CloseHandle( c->event );
+//#elif defined( SYS_CYGWIN )
+//    CloseHandle( c->event );
 #endif
     free( c );
 
@@ -494,11 +596,40 @@ void hb_cond_wait( hb_cond_t * c, hb_lock_t * lock )
     suspend_thread( c->thread );
     acquire_sem( lock->sem );
     c->thread = -1;
-#elif defined( SYS_DARWIN ) || defined( SYS_LINUX ) || defined( SYS_FREEBSD )
+#elif USE_PTHREAD
     pthread_cond_wait( &c->cond, &lock->mutex );
-#elif defined( SYS_CYGWIN )
-    SignalObjectAndWait( lock->mutex, c->event, INFINITE, FALSE );
-    WaitForSingleObject( lock->mutex, INFINITE );
+//#elif defined( SYS_CYGWIN )
+//    SignalObjectAndWait( lock->mutex, c->event, INFINITE, FALSE );
+//    WaitForSingleObject( lock->mutex, INFINITE );
+#endif
+}
+
+void hb_clock_gettime( struct timespec *tp )
+{
+    struct timeval tv;
+    time_t sec;
+
+    sec = time( NULL );
+    gettimeofday( &tv, NULL );
+    tp->tv_sec = tv.tv_sec;
+    tp->tv_nsec = tv.tv_usec * 1000;
+}
+
+void hb_cond_timedwait( hb_cond_t * c, hb_lock_t * lock, int msec )
+{
+#if defined( SYS_BEOS )
+    c->thread = find_thread( NULL );
+    release_sem( lock->sem );
+    suspend_thread( c->thread );
+    acquire_sem( lock->sem );
+    c->thread = -1;
+#elif USE_PTHREAD
+    struct timespec ts;
+    hb_clock_gettime(&ts);
+    ts.tv_nsec += (msec % 1000) * 1000000;
+    ts.tv_sec += msec / 1000 + (ts.tv_nsec / 1000000000);
+    ts.tv_nsec %= 1000000000;
+    pthread_cond_timedwait( &c->cond, &lock->mutex, &ts );
 #endif
 }
 
@@ -519,10 +650,17 @@ void hb_cond_signal( hb_cond_t * c )
            thread is actually suspended before we resume it */
         snooze( 5000 );
     }
-#elif defined( SYS_DARWIN ) || defined( SYS_LINUX ) || defined( SYS_FREEBSD )
+#elif USE_PTHREAD
     pthread_cond_signal( &c->cond );
-#elif defined( SYS_CYGWIN )
-    PulseEvent( c->event );
+//#elif defined( SYS_CYGWIN )
+//    PulseEvent( c->event );
+#endif
+}
+
+void hb_cond_broadcast( hb_cond_t * c )
+{
+#if USE_PTHREAD
+    pthread_cond_broadcast( &c->cond );
 #endif
 }
 
@@ -542,6 +680,23 @@ hb_net_t * hb_net_open( char * address, int port )
     struct sockaddr_in   sock;
     struct hostent     * host;
 
+#ifdef SYS_MINGW
+    WSADATA wsaData;
+    int iResult, winsock_init = 0;
+
+    // Initialize Winsock
+    if (!winsock_init)
+    {
+        iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
+        if (iResult != 0)
+        {
+            hb_log("WSAStartup failed: %d", iResult);
+            return NULL;
+        }
+        winsock_init = 1;
+    }
+#endif
+
     /* TODO: find out why this doesn't work on Win32 */
     if( !( host = gethostbyname( address ) ) )
     {
@@ -569,7 +724,7 @@ hb_net_t * hb_net_open( char * address, int port )
         free( n );
         return NULL;
     }
-    
+
     return n;
 }