OSDN Git Service

WinGui:
[handbrake-jp/handbrake-jp-git.git] / libhb / scan.c
index 1ae5de0..445314b 100644 (file)
@@ -19,18 +19,21 @@ typedef struct
     int            title_index;
     hb_list_t    * list_title;
 
+    hb_bd_t      * bd;
     hb_dvd_t     * dvd;
     hb_stream_t  * stream;
     hb_batch_t   * batch;
-       
+
     int            preview_count;
     int            store_previews;
 
+    uint64_t       min_title_duration;
+
 } hb_scan_t;
 
 static void ScanFunc( void * );
 static int  DecodePreviews( hb_scan_t *, hb_title_t * title );
-static int LookForAudio( hb_title_t * title, hb_buffer_t * b );
+static void LookForAudio( hb_title_t * title, hb_buffer_t * b );
 static int  AllAudioOK( hb_title_t * title );
 
 static const char *aspect_to_string( double aspect )
@@ -48,7 +51,7 @@ static const char *aspect_to_string( double aspect )
 hb_thread_t * hb_scan_init( hb_handle_t * handle, volatile int * die,
                             const char * path, int title_index, 
                             hb_list_t * list_title, int preview_count, 
-                            int store_previews )
+                            int store_previews, uint64_t min_duration )
 {
     hb_scan_t * data = calloc( sizeof( hb_scan_t ), 1 );
 
@@ -60,6 +63,7 @@ hb_thread_t * hb_scan_init( hb_handle_t * handle, volatile int * die,
     
     data->preview_count  = preview_count;
     data->store_previews = store_previews;
+    data->min_title_duration = min_duration;
     
     return hb_thread_init( "scan", ScanFunc, data, HB_NORMAL_PRIORITY );
 }
@@ -69,13 +73,35 @@ static void ScanFunc( void * _data )
     hb_scan_t  * data = (hb_scan_t *) _data;
     hb_title_t * title;
     int          i;
+    int          feature = 0;
 
-       data->dvd = NULL;
-       data->stream = NULL;
+    data->bd = NULL;
+    data->dvd = NULL;
+    data->stream = NULL;
 
     /* Try to open the path as a DVD. If it fails, try as a file */
-    hb_log( "scan: trying to open with libdvdread" );
-    if( ( data->dvd = hb_dvd_init( data->path ) ) )
+    if( ( data->bd = hb_bd_init( data->path ) ) )
+    {
+        hb_log( "scan: BD has %d title(s)",
+                hb_bd_title_count( data->bd ) );
+        if( data->title_index )
+        {
+            /* Scan this title only */
+            hb_list_add( data->list_title, hb_bd_title_scan( data->bd,
+                         data->title_index, 0 ) );
+        }
+        else
+        {
+            /* Scan all titles */
+            for( i = 0; i < hb_bd_title_count( data->bd ); i++ )
+            {
+                hb_list_add( data->list_title, hb_bd_title_scan( data->bd, 
+                             i + 1, data->min_title_duration ) );
+            }
+            feature = hb_bd_main_feature( data->bd, data->list_title );
+        }
+    }
+    else if( ( data->dvd = hb_dvd_init( data->path ) ) )
     {
         hb_log( "scan: DVD has %d title(s)",
                 hb_dvd_title_count( data->dvd ) );
@@ -83,34 +109,44 @@ static void ScanFunc( void * _data )
         {
             /* Scan this title only */
             hb_list_add( data->list_title, hb_dvd_title_scan( data->dvd,
-                            data->title_index ) );
+                            data->title_index, 0 ) );
         }
         else
         {
             /* Scan all titles */
             for( i = 0; i < hb_dvd_title_count( data->dvd ); i++ )
             {
-                hb_list_add( data->list_title,
-                             hb_dvd_title_scan( data->dvd, i + 1 ) );
+                hb_list_add( data->list_title, hb_dvd_title_scan( data->dvd, 
+                            i + 1, data->min_title_duration ) );
             }
+            feature = hb_dvd_main_feature( data->dvd, data->list_title );
         }
     }
     else if ( ( data->batch = hb_batch_init( data->path ) ) )
     {
-        int j = 1;
-
-        /* Scan all titles */
-        for( i = 0; i < hb_batch_title_count( data->batch ); i++ )
+        if( data->title_index )
         {
-            hb_title_t * title;
-
-            title = hb_batch_title_scan( data->batch, i );
-            if ( title != NULL )
+            /* Scan this title only */
+            title = hb_batch_title_scan( data->batch, data->title_index );
+            if ( title )
             {
-                title->index = j++;
                 hb_list_add( data->list_title, title );
             }
         }
+        else
+        {
+            /* Scan all titles */
+            for( i = 0; i < hb_batch_title_count( data->batch ); i++ )
+            {
+                hb_title_t * title;
+
+                title = hb_batch_title_scan( data->batch, i + 1 );
+                if ( title != NULL )
+                {
+                    hb_list_add( data->list_title, title );
+                }
+            }
+        }
     }
     else if ( (data->stream = hb_stream_open( data->path, 0 ) ) != NULL )
     {
@@ -130,7 +166,7 @@ static void ScanFunc( void * _data )
 
         if ( *data->die )
         {
-                       goto finish;
+            goto finish;
         }
         title = hb_list_item( data->list_title, i );
 
@@ -138,7 +174,9 @@ static void ScanFunc( void * _data )
         /* Update the UI */
         state.state   = HB_STATE_SCANNING;
         p.title_cur   = title->index;
-        p.title_count = data->dvd ? hb_dvd_title_count( data->dvd ) : hb_list_count(data->list_title);
+        p.title_count = data->dvd ? hb_dvd_title_count( data->dvd ) : 
+                        data->bd ? hb_bd_title_count( data->bd ) :
+                                   hb_list_count(data->list_title);
         hb_set_state( data->h, &state );
 #undef p
 
@@ -171,6 +209,22 @@ static void ScanFunc( void * _data )
             j++;
         }
 
+        if ( data->dvd || data->bd )
+        {
+            // The subtitle width and height needs to be set to the 
+            // title widht and height for DVDs.  title width and
+            // height don't get set until we decode previews, so
+            // we can't set subtitle width/height till we get here.
+            for( j = 0; j < hb_list_count( title->list_subtitle ); j++ )
+            {
+                hb_subtitle_t *subtitle = hb_list_item( title->list_subtitle, j );
+                if ( subtitle->source == VOBSUB )
+                {
+                    subtitle->width = title->width;
+                    subtitle->height = title->height;
+                }
+            }
+        }
         i++;
     }
 
@@ -184,6 +238,7 @@ static void ScanFunc( void * _data )
         title->job = job;
 
         job->title = title;
+        job->feature = feature;
 
         /* Set defaults settings */
         job->chapter_start = 1;
@@ -234,14 +289,18 @@ static void ScanFunc( void * _data )
 
 finish:
 
+    if( data->bd )
+    {
+        hb_bd_close( &data->bd );
+    }
     if( data->dvd )
     {
         hb_dvd_close( &data->dvd );
     }
-       if (data->stream)
-       {
-               hb_stream_close(&data->stream);
-       }
+    if (data->stream)
+    {
+        hb_stream_close(&data->stream);
+    }
     if( data->batch )
     {
         hb_batch_close( &data->batch );
@@ -413,7 +472,12 @@ static int DecodePreviews( hb_scan_t * data, hb_title_t * title )
 
     hb_log( "scan: decoding previews for title %d", title->index );
 
-    if (data->dvd)
+    if (data->bd)
+    {
+        hb_bd_start( data->bd, title );
+        hb_log( "scan: title angle(s) %d", title->angle_count );
+    }
+    else if (data->dvd)
     {
         hb_dvd_start( data->dvd, title, 1 );
         title->angle_count = hb_dvd_angle_count( data->dvd );
@@ -434,9 +498,16 @@ static int DecodePreviews( hb_scan_t * data, hb_title_t * title )
         {
             return 0;
         }
+        if (data->bd)
+        {
+            if( !hb_bd_seek( data->bd, (float) ( i + 1 ) / ( data->preview_count + 1.0 ) ) )
+          {
+              continue;
+          }
+        }
         if (data->dvd)
         {
-          if( !hb_dvd_seek( data->dvd, (float) ( i + 1 ) / ( data->preview_count + 1.0 ) ) )
+            if( !hb_dvd_seek( data->dvd, (float) ( i + 1 ) / ( data->preview_count + 1.0 ) ) )
           {
               continue;
           }
@@ -474,10 +545,26 @@ static int DecodePreviews( hb_scan_t * data, hb_title_t * title )
             {
                 vidskip = (double)title->rate / (double)title->rate_base + 0.5;
             }
+            // If it's a BD, we can relax this a bit. Since seeks will
+            // at least get us to a recovery point.
+            if (data->bd)
+                vidskip = 4;
         }
 
         for( j = 0; j < 10240 ; j++ )
         {
+            if (data->bd)
+            {
+              if( !hb_bd_read( data->bd, buf_ps ) )
+              {
+                  if ( vid_buf )
+                  {
+                    break;
+                  }
+                  hb_log( "Warning: Could not read data for preview %d, skipped", i + 1 );
+                  goto skip_preview;
+              }
+            }
             if (data->dvd)
             {
               if( !hb_dvd_read( data->dvd, buf_ps ) )
@@ -514,15 +601,19 @@ static int DecodePreviews( hb_scan_t * data, hb_title_t * title )
                     {
                         // we're dropping frames to get the video decoder in sync
                         // when the video stream doesn't contain IDR frames
-                        hb_buffer_close( &vid_buf );
-                        vid_buf = NULL;
+                        while (vid_buf && --vidskip >= 0)
+                        {
+                            hb_buffer_t * next = vid_buf->next;
+                            vid_buf->next = NULL;
+                            hb_buffer_close( &vid_buf );
+                            vid_buf = next;
+                        }
                     }
                 }
-                else 
+                else if( ! AllAudioOK( title ) ) 
                 {
-                    if( ! AllAudioOK( title ) )
-                        if ( !LookForAudio( title, buf_es ) )
-                            buf_es = NULL;
+                    LookForAudio( title, buf_es );
+                    buf_es = NULL;
                 }
                 if ( buf_es )
                     hb_buffer_close( &buf_es );
@@ -547,6 +638,10 @@ static int DecodePreviews( hb_scan_t * data, hb_title_t * title )
              * Could not fill vid_info, don't continue and try to use vid_info
              * in this case.
              */
+            if (vid_buf)
+            {
+                hb_buffer_close( &vid_buf );
+            }
             vid_decoder->close( vid_decoder );
             free( vid_decoder );
             continue;
@@ -714,8 +809,10 @@ skip_preview:
                 hb_fifo_flush( audio->priv.scan_cache );
             }
         }
-        if ( vid_buf )
+        if (vid_buf)
+        {
             hb_buffer_close( &vid_buf );
+        }
     }
 
     if ( data->batch && data->stream )
@@ -805,6 +902,8 @@ skip_preview:
         hb_buffer_close( &buf_es );
     }
     hb_list_close( &list_es );
+    if (data->bd)
+      hb_bd_stop( data->bd );
     if (data->dvd)
       hb_dvd_stop( data->dvd );
 
@@ -825,7 +924,7 @@ skip_preview:
  * aren't (e.g., some European DVD Teletext streams use the same IDs as US ATSC
  * AC-3 audio).
  */
-static int LookForAudio( hb_title_t * title, hb_buffer_t * b )
+static void LookForAudio( hb_title_t * title, hb_buffer_t * b )
 {
     int i;
 
@@ -846,7 +945,8 @@ static int LookForAudio( hb_title_t * title, hb_buffer_t * b )
     if( !audio || audio->config.in.bitrate != 0 )
     {
         /* not found or already done */
-        return 1;
+        hb_buffer_close( &b );
+        return;
     }
 
     if ( audio->priv.scan_cache == NULL )
@@ -884,7 +984,7 @@ static int LookForAudio( hb_title_t * title, hb_buffer_t * b )
     if ( !info.bitrate )
     {
         /* didn't find any info */
-        return 0;
+        return;
     }
     hb_fifo_flush( audio->priv.scan_cache );
     hb_fifo_close( &audio->priv.scan_cache );
@@ -917,7 +1017,7 @@ static int LookForAudio( hb_title_t * title, hb_buffer_t * b )
             audio->config.lang.description );
  
     free( w );
-    return 1;
+    return;
 
     // We get here if there's no hope of finding info on an audio bitstream,
     // either because we don't have a decoder (or a decoder with a bitstream
@@ -932,7 +1032,7 @@ static int LookForAudio( hb_title_t * title, hb_buffer_t * b )
     hb_fifo_flush( audio->priv.scan_cache );
     hb_fifo_close( &audio->priv.scan_cache );
     hb_list_rem( title->list_audio, audio );
-    return -1;
+    return;
 }
 
 /*