OSDN Git Service

libhb: don't truncate last chapter of a stream
[handbrake-jp/handbrake-jp-git.git] / libhb / scan.c
index 26927ff..74cc52a 100644 (file)
@@ -106,36 +106,9 @@ static void ScanFunc( void * _data )
         int j;
         hb_state_t state;
         hb_audio_t * audio;
-        hb_title_t * title_tmp = NULL;
 
         title = hb_list_item( data->list_title, i );
 
-        /* I've seen a DVD with strictly identical titles. Check this
-           here and ignore it if redundant */
-        for( j = 0; j < i; j++ )
-        {
-            title_tmp = hb_list_item( data->list_title, j );
-            if( title->vts         == title_tmp->vts &&
-                title->block_start == title_tmp->block_start &&
-                title->block_end   == title_tmp->block_end &&
-                title->block_count == title_tmp->block_count )
-            {
-                break;
-            }
-            else
-            {
-                title_tmp = NULL;
-            }
-        }
-        if( title_tmp )
-        {
-            hb_log( "scan: title %d is duplicate with title %d",
-                    title->index, title_tmp->index );
-            hb_list_rem( data->list_title, title );
-            free( title );      /* This _will_ leak! */
-            continue;
-        }
-
 #define p state.param.scanning
         /* Update the UI */
         state.state   = HB_STATE_SCANNING;
@@ -168,15 +141,6 @@ static void ScanFunc( void * _data )
             j++;
         }
 
-        /* If we don't have any audio streams left, remove the title */
-        if( !hb_list_count( title->list_audio ) )
-        {
-            hb_log("scan: ignoring title %i, no audio tracks found", title->index );
-            hb_list_rem( data->list_title, title );
-            free( title );
-            continue;
-        }
-
         i++;
     }
 
@@ -201,15 +165,15 @@ static void ScanFunc( void * _data )
         /* Preserve a source's pixel aspect, if it's available. */
         if( title->pixel_aspect_width && title->pixel_aspect_height )
         {
-            job->pixel_aspect_width  = title->pixel_aspect_width;
-            job->pixel_aspect_height = title->pixel_aspect_height;
+            job->anamorphic.par_width  = title->pixel_aspect_width;
+            job->anamorphic.par_height = title->pixel_aspect_height;
         }
 
         if( title->aspect != 0 && title->aspect != 1. &&
-            !job->pixel_aspect_width && !job->pixel_aspect_height)
+            !job->anamorphic.par_width && !job->anamorphic.par_height)
         {
-            hb_reduce( &job->pixel_aspect_width, &job->pixel_aspect_height,
-                       (int)(title->aspect * title->height), title->width );
+            hb_reduce( &job->anamorphic.par_width, &job->anamorphic.par_height,
+                       (int)(title->aspect * title->height + 0.5), title->width );
         }
 
         job->width = title->width - job->crop[2] - job->crop[3];
@@ -233,8 +197,7 @@ static void ScanFunc( void * _data )
         job->vrate_base = title->rate_base;
 
         job->list_audio = hb_list_init();
-
-        job->subtitle = -1;
+        job->list_subtitle = hb_list_init();
 
         job->mux = HB_MUX_MP4;
     }
@@ -415,7 +378,11 @@ static int DecodePreviews( hb_scan_t * data, hb_title_t * title )
     hb_log( "scan: decoding previews for title %d", title->index );
 
     if (data->dvd)
-      hb_dvd_start( data->dvd, title->index, 1 );
+    {
+      hb_dvd_start( data->dvd, title, 1 );
+      title->angle_count = hb_dvd_angle_count( data->dvd );
+      hb_log( "scan: title angle(s) %d", title->angle_count );
+    }
 
     for( i = 0; i < data->preview_count; i++ )
     {
@@ -446,8 +413,24 @@ static int DecodePreviews( hb_scan_t * data, hb_title_t * title )
         int vcodec = title->video_codec? title->video_codec : WORK_DECMPEG2;
         hb_work_object_t *vid_decoder = hb_get_work( vcodec );
         vid_decoder->codec_param = title->video_codec_param;
+        vid_decoder->title = title;
         vid_decoder->init( vid_decoder, NULL );
         hb_buffer_t * vid_buf = NULL;
+        int vidskip = 0;
+
+        if ( title->flags & HBTF_NO_IDR )
+        {
+            // title doesn't have IDR frames so we decode but drop one second's
+            // worth of frames to allow the decoder to converge.
+            if ( ! title->rate_base )
+            {
+                vidskip = 30;
+            }
+            else
+            {
+                vidskip = (double)title->rate / (double)title->rate_base + 0.5;
+            }
+        }
 
         for( j = 0; j < 10240 ; j++ )
         {
@@ -455,6 +438,10 @@ static int DecodePreviews( hb_scan_t * data, hb_title_t * title )
             {
               if( !hb_dvd_read( data->dvd, buf_ps ) )
               {
+                  if ( vid_buf )
+                  {
+                    break;
+                  }
                   hb_log( "Warning: Could not read data for preview %d, skipped", i + 1 );
                   goto skip_preview;
               }
@@ -463,6 +450,10 @@ static int DecodePreviews( hb_scan_t * data, hb_title_t * title )
             {
               if ( !hb_stream_read(data->stream,buf_ps) )
               {
+                  if ( vid_buf )
+                  {
+                    break;
+                  }
                   hb_log( "Warning: Could not read data for preview %d, skipped", i + 1 );
                   goto skip_preview;
               }
@@ -475,6 +466,13 @@ static int DecodePreviews( hb_scan_t * data, hb_title_t * title )
                 if( buf_es->id == title->video_id && vid_buf == NULL )
                 {
                     vid_decoder->work( vid_decoder, &buf_es, &vid_buf );
+                    if ( vid_buf && vidskip && --vidskip > 0 )
+                    {
+                        // 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;
+                    }
                 }
                 else if( ! AllAudioOK( title ) )
                 {
@@ -572,10 +570,10 @@ static int DecodePreviews( hb_scan_t * data, hb_title_t * title )
         
         if( data->store_previews )
         {
-            hb_get_tempory_filename( data->h, filename, "%x%d",
+            hb_get_tempory_filename( data->h, filename, "%" PRIxPTR "%d",
                                      (intptr_t)title, i );
 
-            file_preview = fopen( filename, "w" );
+            file_preview = fopen( filename, "wb" );
             if( file_preview )
             {
                 fwrite( vid_buf->data, title->width * title->height * 3 / 2,
@@ -691,14 +689,14 @@ skip_preview:
             // aspect ratio from the DVD metadata. So, if the aspect computed
             // from the PAR is different from the container's aspect we use
             // the container's aspect & recompute the PAR from it.
-            if( title->container_aspect && title->aspect != title->container_aspect )
+            if( title->container_aspect && (int)(title->aspect * 9) != (int)(title->container_aspect * 9) )
             {
                 hb_log("scan: content PAR gives wrong aspect %.2f; "
                        "using container aspect %.2f", title->aspect,
                        title->container_aspect );
                 title->aspect = title->container_aspect;
                 hb_reduce( &title->pixel_aspect_width, &title->pixel_aspect_height,
-                           (int)(title->aspect * title->height), title->width );
+                           (int)(title->aspect * title->height + 0.5), title->width );
             }
         }