OSDN Git Service

Fix potential crash in libbluray
[handbrake-jp/handbrake-jp-git.git] / libhb / dvd.c
index 2d5fb8c..5fd0a4a 100644 (file)
@@ -16,7 +16,7 @@ static hb_dvd_t    * hb_dvdread_init( char * path );
 static void          hb_dvdread_close( hb_dvd_t ** _d );
 static char        * hb_dvdread_name( char * path );
 static int           hb_dvdread_title_count( hb_dvd_t * d );
-static hb_title_t  * hb_dvdread_title_scan( hb_dvd_t * d, int t );
+static hb_title_t  * hb_dvdread_title_scan( hb_dvd_t * d, int t, uint64_t min_duration );
 static int           hb_dvdread_start( hb_dvd_t * d, hb_title_t *title, int chapter );
 static void          hb_dvdread_stop( hb_dvd_t * d );
 static int           hb_dvdread_seek( hb_dvd_t * d, float f );
@@ -24,6 +24,7 @@ static int           hb_dvdread_read( hb_dvd_t * d, hb_buffer_t * b );
 static int           hb_dvdread_chapter( hb_dvd_t * d );
 static int           hb_dvdread_angle_count( hb_dvd_t * d );
 static void          hb_dvdread_set_angle( hb_dvd_t * d, int angle );
+static int           hb_dvdread_main_feature( hb_dvd_t * d, hb_list_t * list_title );
 
 hb_dvd_func_t hb_dvdread_func =
 {
@@ -38,7 +39,8 @@ hb_dvd_func_t hb_dvdread_func =
     hb_dvdread_read,
     hb_dvdread_chapter,
     hb_dvdread_angle_count,
-    hb_dvdread_set_angle
+    hb_dvdread_set_angle,
+    hb_dvdread_main_feature
 };
 
 static hb_dvd_func_t *dvd_methods = &hb_dvdread_func;
@@ -55,6 +57,24 @@ hb_dvd_func_t * hb_dvdread_methods( void )
     return &hb_dvdread_func;
 }
 
+static int hb_dvdread_main_feature( hb_dvd_t * e, hb_list_t * list_title )
+{
+    int ii;
+    uint64_t longest_duration = 0;
+    int longest = -1;
+
+    for ( ii = 0; ii < hb_list_count( list_title ); ii++ )
+    {
+        hb_title_t * title = hb_list_item( list_title, ii );
+        if ( title->duration > longest_duration )
+        {
+            longest_duration = title->duration;
+            longest = title->index;
+        }
+    }
+    return longest;
+}
+
 static char * hb_dvdread_name( char * path )
 {
     static char name[1024];
@@ -87,10 +107,21 @@ hb_dvd_t * hb_dvdread_init( char * path )
 {
     hb_dvd_t * e;
     hb_dvdread_t * d;
+    int region_mask;
 
     e = calloc( sizeof( hb_dvd_t ), 1 );
     d = &(e->dvdread);
 
+       /* Log DVD drive region code */
+    if ( hb_dvd_region( path, &region_mask ) == 0 )
+    {
+        hb_log( "dvd: Region mask 0x%02x", region_mask );
+        if ( region_mask == 0xFF )
+        {
+            hb_log( "dvd: Warning, DVD device has no region set" );
+        }
+    }
+
     /* Open device */
     if( !( d->reader = DVDOpen( path ) ) )
     {
@@ -131,7 +162,7 @@ static int hb_dvdread_title_count( hb_dvd_t * e )
 /***********************************************************************
  * hb_dvdread_title_scan
  **********************************************************************/
-static hb_title_t * hb_dvdread_title_scan( hb_dvd_t * e, int t )
+static hb_title_t * hb_dvdread_title_scan( hb_dvd_t * e, int t, uint64_t min_duration )
 {
 
     hb_dvdread_t *d = &(e->dvdread);
@@ -147,6 +178,8 @@ static hb_title_t * hb_dvdread_title_scan( hb_dvd_t * e, int t )
     hb_log( "scan: scanning title %d", t );
 
     title = hb_title_init( d->path, t );
+    title->type = HB_DVD_TYPE;
+
     if( DVDUDFVolumeInfo( d->reader, title->name, sizeof( title->name ),
                           unused, sizeof( unused ) ) )
     {
@@ -232,7 +265,7 @@ static hb_title_t * hb_dvdread_title_scan( hb_dvd_t * e, int t )
     pgn    = vts->vts_ptt_srpt->title[title->ttn-1].ptt[0].pgn;
     d->pgc = vts->vts_pgcit->pgci_srp[pgc_id-1].pgc;
 
-    hb_log("pgc_id: %d, pgn: %d: pgc: 0x%x", pgc_id, pgn, d->pgc);
+    hb_log("pgc_id: %d, pgn: %d: pgc: %p", pgc_id, pgn, d->pgc);
 
     if( !d->pgc )
     {
@@ -266,8 +299,8 @@ static hb_title_t * hb_dvdread_title_scan( hb_dvd_t * e, int t )
         d->cell_cur = d->cell_next;
     }
 
-    hb_log( "scan: vts=%d, ttn=%d, cells=%d->%d, blocks=%d->%d, "
-            "%d blocks", title->vts, title->ttn, title->cell_start,
+    hb_log( "scan: vts=%d, ttn=%d, cells=%d->%d, blocks=%"PRIu64"->%"PRIu64", "
+            "%"PRIu64" blocks", title->vts, title->ttn, title->cell_start,
             title->cell_end, title->block_start, title->block_end,
             title->block_count );
 
@@ -276,14 +309,14 @@ static hb_title_t * hb_dvdread_title_scan( hb_dvd_t * e, int t )
     title->hours    = title->duration / 90000 / 3600;
     title->minutes  = ( ( title->duration / 90000 ) % 3600 ) / 60;
     title->seconds  = ( title->duration / 90000 ) % 60;
-    hb_log( "scan: duration is %02d:%02d:%02d (%lld ms)",
+    hb_log( "scan: duration is %02d:%02d:%02d (%"PRId64" ms)",
             title->hours, title->minutes, title->seconds,
             title->duration / 90 );
 
     /* ignore titles under 10 seconds because they're often stills or
      * clips with no audio & our preview code doesn't currently handle
      * either of these. */
-    if( title->duration < 900000LL )
+    if( title->duration < min_duration )
     {
         hb_log( "scan: ignoring title (too short)" );
         goto fail;
@@ -410,16 +443,6 @@ static hb_title_t * hb_dvdread_title_scan( hb_dvd_t * e, int t )
         hb_list_add( title->list_audio, audio );
     }
 
-    if( !hb_list_count( title->list_audio ) )
-    {
-        hb_log( "scan: ignoring title (no audio track)" );
-        goto fail;
-    }
-
-    memcpy( title->palette,
-            vts->vts_pgcit->pgci_srp[pgc_id-1].pgc->palette,
-            16 * sizeof( uint32_t ) );
-
     /* Check for subtitles */
     for( i = 0; i < vts->vtsi_mat->nr_of_vts_subp_streams; i++ )
     {
@@ -475,6 +498,10 @@ static hb_title_t * hb_dvdread_title_scan( hb_dvd_t * e, int t )
         subtitle->config.dest   = RENDERSUB;  // By default render (burn-in) the VOBSUB.
 
         subtitle->type = lang_extension;
+        
+        memcpy( subtitle->palette,
+            vts->vts_pgcit->pgci_srp[pgc_id-1].pgc->palette,
+            16 * sizeof( uint32_t ) );
 
         switch( lang_extension )
         {  
@@ -597,7 +624,7 @@ static hb_title_t * hb_dvdread_title_scan( hb_dvd_t * e, int t )
         chapter->minutes   = ( seconds % 3600 ) / 60;
         chapter->seconds   = seconds % 60;
 
-        hb_log( "scan: chap %d c=%d->%d, b=%d->%d (%d), %lld ms",
+        hb_log( "scan: chap %d c=%d->%d, b=%"PRIu64"->%"PRIu64" (%"PRIu64"), %"PRId64" ms",
                 chapter->index, chapter->cell_start, chapter->cell_end,
                 chapter->block_start, chapter->block_end,
                 chapter->block_count, chapter->duration / 90 );
@@ -1241,9 +1268,9 @@ int hb_dvd_title_count( hb_dvd_t * d )
     return dvd_methods->title_count(d);
 }
 
-hb_title_t * hb_dvd_title_scan( hb_dvd_t * d, int t )
+hb_title_t * hb_dvd_title_scan( hb_dvd_t * d, int t, uint64_t min_duration )
 {
-    return dvd_methods->title_scan(d, t);
+    return dvd_methods->title_scan(d, t, min_duration);
 }
 
 int hb_dvd_start( hb_dvd_t * d, hb_title_t *title, int chapter )
@@ -1286,6 +1313,11 @@ void hb_dvd_set_angle( hb_dvd_t * d, int angle )
     dvd_methods->set_angle(d, angle);
 }
 
+int hb_dvd_main_feature( hb_dvd_t * d, hb_list_t * list_title )
+{
+    return dvd_methods->main_feature(d, list_title);
+}
+
 // hb_dvd_set_dvdnav must only be called when no dvd source is open
 // it rips the rug out from under things so be careful
 void hb_dvd_set_dvdnav( int enable )