OSDN Git Service

WinGui:
[handbrake-jp/handbrake-jp-git.git] / libhb / hb.c
index 0541b9f..0c951f4 100644 (file)
@@ -1,8 +1,14 @@
 #include "hb.h"
 #include "hbffmpeg.h"
 
+#if defined( SYS_MINGW ) && defined( PTW32_STATIC_LIB )
+#include <pthread.h>
+#endif
+
 struct hb_handle_s
 {
+    int            id;
+    
     /* The "Check for update" thread */
     int            build;
     char           version[32];
@@ -49,6 +55,7 @@ struct hb_handle_s
 
 hb_lock_t *hb_avcodec_lock;
 hb_work_object_t * hb_objects = NULL;
+int hb_instance_counter = 0;
 int hb_process_initialized = 0;
 
 static void thread_func( void * );
@@ -77,6 +84,99 @@ int hb_avcodec_close(AVCodecContext *avctx)
     return ret;
 }
 
+int hb_ff_layout_xlat(int64_t ff_channel_layout, int channels)
+{
+    int hb_layout;
+
+    switch (ff_channel_layout)
+    {
+        case CH_LAYOUT_MONO:
+            hb_layout = HB_INPUT_CH_LAYOUT_MONO;
+            break;
+        case CH_LAYOUT_STEREO:
+            hb_layout = HB_INPUT_CH_LAYOUT_STEREO;
+            break;
+        case CH_LAYOUT_SURROUND:
+            hb_layout = HB_INPUT_CH_LAYOUT_3F;
+            break;
+        case CH_LAYOUT_4POINT0:
+            hb_layout = HB_INPUT_CH_LAYOUT_3F1R;
+            break;
+        case CH_LAYOUT_2_2:
+            hb_layout = HB_INPUT_CH_LAYOUT_2F2R;
+            break;
+        case CH_LAYOUT_QUAD:
+            hb_layout = HB_INPUT_CH_LAYOUT_2F2R;
+            break;
+        case CH_LAYOUT_5POINT0:
+            hb_layout = HB_INPUT_CH_LAYOUT_3F2R;
+            break;
+        case CH_LAYOUT_5POINT1:
+            hb_layout = HB_INPUT_CH_LAYOUT_3F2R|HB_INPUT_CH_LAYOUT_HAS_LFE;
+            break;
+        case CH_LAYOUT_5POINT0_BACK:
+            hb_layout = HB_INPUT_CH_LAYOUT_3F2R;
+            break;
+        case CH_LAYOUT_5POINT1_BACK:
+            hb_layout = HB_INPUT_CH_LAYOUT_3F2R|HB_INPUT_CH_LAYOUT_HAS_LFE;
+            break;
+        case CH_LAYOUT_7POINT0:
+            hb_layout = HB_INPUT_CH_LAYOUT_3F4R;
+            break;
+        case CH_LAYOUT_7POINT1:
+            hb_layout = HB_INPUT_CH_LAYOUT_3F4R|HB_INPUT_CH_LAYOUT_HAS_LFE;
+            break;
+        case CH_LAYOUT_STEREO_DOWNMIX:
+            hb_layout = HB_INPUT_CH_LAYOUT_STEREO;
+            break;
+        default:
+            hb_layout = HB_INPUT_CH_LAYOUT_STEREO;
+            break;
+    }
+    // Now make sure the chosen layout agrees with the number of channels
+    // ffmpeg tells us there are.  It seems ffmpeg is sometimes confused
+    // about this. So we will make a best guess based on the number
+    // of channels.
+    int chans = HB_INPUT_CH_LAYOUT_GET_DISCRETE_COUNT( hb_layout );
+    if ( chans == channels )
+    {
+        return hb_layout;
+    }
+    hb_log( "Channels reported by ffmpeg (%d) != computed layout channels (%d).", channels, chans );
+    switch (channels)
+    {
+        case 1:
+            hb_layout = HB_INPUT_CH_LAYOUT_MONO;
+            break;
+        case 2:
+            hb_layout = HB_INPUT_CH_LAYOUT_STEREO;
+            break;
+        case 3:
+            hb_layout = HB_INPUT_CH_LAYOUT_3F;
+            break;
+        case 4:
+            hb_layout = HB_INPUT_CH_LAYOUT_3F1R;
+            break;
+        case 5:
+            hb_layout = HB_INPUT_CH_LAYOUT_3F2R;
+            break;
+        case 6:
+            hb_layout = HB_INPUT_CH_LAYOUT_3F2R|HB_INPUT_CH_LAYOUT_HAS_LFE;
+            break;
+        case 7:
+            hb_layout = HB_INPUT_CH_LAYOUT_3F4R;
+            break;
+        case 8:
+            hb_layout = HB_INPUT_CH_LAYOUT_3F4R|HB_INPUT_CH_LAYOUT_HAS_LFE;
+            break;
+        default:
+            hb_log("Unsupported number of audio channels (%d).\n", channels);
+            hb_layout = 0;
+            break;
+    }
+    return hb_layout;
+}
+
 /**
  * Registers work objects, by adding the work object to a liked list.
  * @param w Handle to hb_work_object_t to register.
@@ -95,16 +195,14 @@ void hb_register( hb_work_object_t * w )
  */
 hb_handle_t * hb_init( int verbose, int update_check )
 {
-       if (!hb_process_initialized)
-       {
-#ifdef USE_PTHREAD
-#if defined( _WIN32 ) || defined( __MINGW32__ )
-               pthread_win32_process_attach_np();
-#endif
+    if (!hb_process_initialized)
+    {
+#if defined( SYS_MINGW ) && defined( PTW32_STATIC_LIB )
+        pthread_win32_process_attach_np();
 #endif
-               hb_process_initialized =1;
-       }
-       
+        hb_process_initialized =1;
+    }
+    
     hb_handle_t * h = calloc( sizeof( hb_handle_t ), 1 );
     uint64_t      date;
 
@@ -112,7 +210,9 @@ hb_handle_t * hb_init( int verbose, int update_check )
     global_verbosity_level = verbose;
     if( verbose )
         putenv( "HB_DEBUG=1" );
-
+    
+    h->id = hb_instance_counter++;
+    
     /* Check for an update on the website if asked to */
     h->build = -1;
 
@@ -176,6 +276,8 @@ hb_handle_t * hb_init( int verbose, int update_check )
     hb_register( &hb_encvobsub );
     hb_register( &hb_deccc608 );
     hb_register( &hb_decsrtsub );
+    hb_register( &hb_decutf8sub );
+    hb_register( &hb_dectx3gsub );
        hb_register( &hb_render );
        hb_register( &hb_encavcodec );
        hb_register( &hb_encx264 );
@@ -194,7 +296,7 @@ hb_handle_t * hb_init( int verbose, int update_check )
 #ifdef __APPLE__
        hb_register( &hb_encca_aac );
 #endif
-
+    
     return h;
 }
 
@@ -216,6 +318,8 @@ hb_handle_t * hb_init_dl( int verbose, int update_check )
         putenv( "HB_DEBUG=1" );
     }
 
+    h->id = hb_instance_counter++;
+
     /* Check for an update on the website if asked to */
     h->build = -1;
 
@@ -275,6 +379,8 @@ hb_handle_t * hb_init_dl( int verbose, int update_check )
     hb_register( &hb_encvobsub );
     hb_register( &hb_deccc608 );
     hb_register( &hb_decsrtsub );
+    hb_register( &hb_decutf8sub );
+    hb_register( &hb_dectx3gsub );
        hb_register( &hb_render );
        hb_register( &hb_encavcodec );
        hb_register( &hb_encx264 );
@@ -356,7 +462,7 @@ void hb_remove_previews( hb_handle_t * h )
     struct dirent * entry;
 
     memset( dirname, 0, 1024 );
-    hb_get_tempory_directory( h, dirname );
+    hb_get_temporary_directory( dirname );
     dir = opendir( dirname );
     if (dir == NULL) return;
 
@@ -370,7 +476,7 @@ void hb_remove_previews( hb_handle_t * h )
         for( i = 0; i < count; i++ )
         {
             title = hb_list_item( h->list_title, i );
-            len = snprintf( filename, 1024, "%" PRIxPTR, (intptr_t) title );
+            len = snprintf( filename, 1024, "%d_%d", h->id, title->index );
             if (strncmp(entry->d_name, filename, len) == 0)
             {
                 snprintf( filename, 1024, "%s/%s", dirname, entry->d_name );
@@ -461,8 +567,8 @@ void hb_get_preview( hb_handle_t * h, hb_title_t * title, int picture,
 
     memset( filename, 0, 1024 );
 
-    hb_get_tempory_filename( h, filename, "%" PRIxPTR "%d",
-                             (intptr_t) title, picture );
+    hb_get_tempory_filename( h, filename, "%d_%d_%d",
+                             h->id, title->index, picture );
 
     file = fopen( filename, "rb" );
     if( !file )
@@ -628,13 +734,13 @@ int hb_detect_comb( hb_buffer_t * buf, int width, int height, int color_equal, i
     if( average_cc > threshold )
     {
 #if 0
-            hb_log("Average %i combed (Threshold %i) %i/%i/%i | PTS: %lld (%fs) %s", average_cc, threshold, cc[0], cc[1], cc[2], buf->start, (float)buf->start / 90000, (buf->flags & 16) ? "Film" : "Video" );
+            hb_log("Average %i combed (Threshold %i) %i/%i/%i | PTS: %"PRId64" (%fs) %s", average_cc, threshold, cc[0], cc[1], cc[2], buf->start, (float)buf->start / 90000, (buf->flags & 16) ? "Film" : "Video" );
 #endif
         return 1;
     }
 
 #if 0
-    hb_log("SKIPPED Average %i combed (Threshold %i) %i/%i/%i | PTS: %lld (%fs) %s", average_cc, threshold, cc[0], cc[1], cc[2], buf->start, (float)buf->start / 90000, (buf->flags & 16) ? "Film" : "Video" );
+    hb_log("SKIPPED Average %i combed (Threshold %i) %i/%i/%i | PTS: %"PRId64" (%fs) %s", average_cc, threshold, cc[0], cc[1], cc[2], buf->start, (float)buf->start / 90000, (buf->flags & 16) ? "Film" : "Video" );
 #endif
 
     /* Reaching this point means no combing detected. */
@@ -1314,6 +1420,7 @@ void hb_close( hb_handle_t ** _h )
     hb_title_t * title;
 
     h->die = 1;
+    
     hb_thread_close( &h->main_thread );
 
     while( ( title = hb_list_item( h->list_title, 0 ) ) )
@@ -1331,9 +1438,41 @@ void hb_close( hb_handle_t ** _h )
     hb_list_close( &h->jobs );
     hb_lock_close( &h->state_lock );
     hb_lock_close( &h->pause_lock );
+
     free( h );
     *_h = NULL;
+}
 
+/**
+ * Cleans up libhb at a process level. Call before the app closes. Removes preview directory.
+ */
+void hb_global_close()
+{
+    char dirname[1024];
+    DIR * dir;
+    struct dirent * entry;
+    
+    /* Find and remove temp folder */
+    memset( dirname, 0, 1024 );
+    hb_get_temporary_directory( dirname );
+
+    dir = opendir( dirname );
+    if (dir)
+    {
+        while( ( entry = readdir( dir ) ) )
+        {
+            char filename[1024];
+            if( entry->d_name[0] == '.' )
+            {
+                continue;
+            }
+            memset( filename, 0, 1024 );
+            snprintf( filename, 1023, "%s/%s", dirname, entry->d_name );
+            unlink( filename );
+        }
+        closedir( dir );
+        rmdir( dirname );
+    }
 }
 
 /**
@@ -1346,14 +1485,12 @@ static void thread_func( void * _h )
 {
     hb_handle_t * h = (hb_handle_t *) _h;
     char dirname[1024];
-    DIR * dir;
-    struct dirent * entry;
 
     h->pid = getpid();
 
     /* Create folder for temporary files */
     memset( dirname, 0, 1024 );
-    hb_get_tempory_directory( h, dirname );
+    hb_get_temporary_directory( dirname );
 
     hb_mkdir( dirname );
 
@@ -1420,30 +1557,17 @@ static void thread_func( void * _h )
         hb_snooze( 50 );
     }
 
+    if( h->scan_thread )
+    {
+        hb_scan_stop( h );
+        hb_thread_close( &h->scan_thread );
+    }
     if( h->work_thread )
     {
         hb_stop( h );
         hb_thread_close( &h->work_thread );
     }
-
-    /* Remove temp folder */
-    dir = opendir( dirname );
-    if (dir)
-    {
-        while( ( entry = readdir( dir ) ) )
-        {
-            char filename[1024];
-            if( entry->d_name[0] == '.' )
-            {
-                continue;
-            }
-            memset( filename, 0, 1024 );
-            snprintf( filename, 1023, "%s/%s", dirname, entry->d_name );
-            unlink( filename );
-        }
-        closedir( dir );
-        rmdir( dirname );
-    }
+    hb_remove_previews( h );
 }
 
 /**
@@ -1456,6 +1580,15 @@ int hb_get_pid( hb_handle_t * h )
 }
 
 /**
+ * Returns the id for the given instance.
+ * @param h Handle to hb_handle_t
+ */
+int hb_get_instance_id( hb_handle_t * h )
+{
+    return h->id;
+}
+
+/**
  * Sets the current state.
  * @param h Handle to hb_handle_t
  * @param s Handle to new hb_state_t