OSDN Git Service

add dvd main feature title detection
authorjstebbins <jstebbins@b64f7644-9d1e-0410-96f1-a4d463321fa5>
Tue, 20 Apr 2010 02:19:16 +0000 (02:19 +0000)
committerjstebbins <jstebbins@b64f7644-9d1e-0410-96f1-a4d463321fa5>
Tue, 20 Apr 2010 02:19:16 +0000 (02:19 +0000)
scans the dvd menus and presses buttons to see where they might lead.
when a button press leads to a title, i check to see if it is the
longest seen thus far and save it's index.

this only applies when dvdnav is enabled.  when dvdread is in use,
the longest title of all the titles is flagged as the "main feature"

git-svn-id: svn://localhost/HandBrake/trunk@3245 b64f7644-9d1e-0410-96f1-a4d463321fa5

contrib/libdvdnav/A08-dvdnav-dup.patch [new file with mode: 0644]
gtk/src/hb-backend.c
libhb/common.h
libhb/dvd.c
libhb/dvd.h
libhb/dvdnav.c
libhb/internal.h
libhb/scan.c
macosx/Controller.m
test/test.c

diff --git a/contrib/libdvdnav/A08-dvdnav-dup.patch b/contrib/libdvdnav/A08-dvdnav-dup.patch
new file mode 100644 (file)
index 0000000..ce6072a
--- /dev/null
@@ -0,0 +1,137 @@
+Index: src/dvdnav.c
+===================================================================
+--- libdvdnav.orig/src/dvdnav.c        (revision 1168)
++++ libdvdnav/src/dvdnav.c     (working copy)
+@@ -71,6 +71,67 @@
+   return DVDNAV_STATUS_OK;
+ }
++dvdnav_status_t dvdnav_dup(dvdnav_t **dest, dvdnav_t *src) {
++  dvdnav_t *this;
++
++  (*dest) = NULL;
++  this = (dvdnav_t*)malloc(sizeof(dvdnav_t));
++  if(!this)
++    return DVDNAV_STATUS_ERR;
++
++  memcpy(this, src, sizeof(dvdnav_t));
++  this->file = NULL;
++
++  pthread_mutex_init(&this->vm_lock, NULL);
++
++  this->vm = vm_new_copy(src->vm);
++  if(!this->vm) {
++    printerr("Error initialising the DVD VM.");
++    pthread_mutex_destroy(&this->vm_lock);
++    free(this);
++    return DVDNAV_STATUS_ERR;
++  }
++
++  /* Start the read-ahead cache. */
++  this->cache = dvdnav_read_cache_new(this);
++
++  (*dest) = this;
++  return DVDNAV_STATUS_OK;
++}
++
++dvdnav_status_t dvdnav_free_dup(dvdnav_t *this) {
++
++#ifdef LOG_DEBUG
++  fprintf(MSG_OUT, "libdvdnav: free_dup:called\n");
++#endif
++
++  if (this->file) {
++    pthread_mutex_lock(&this->vm_lock);
++    DVDCloseFile(this->file);
++#ifdef LOG_DEBUG
++    fprintf(MSG_OUT, "libdvdnav: close:file closing\n");
++#endif
++    this->file = NULL;
++    pthread_mutex_unlock(&this->vm_lock);
++  }
++
++  /* Free the VM */
++  if(this->vm)
++    vm_free_copy(this->vm);
++
++  pthread_mutex_destroy(&this->vm_lock);
++
++  /* We leave the final freeing of the entire structure to the cache,
++   * because we don't know, if there are still buffers out in the wild,
++   * that must return first. */
++  if(this->cache)
++    dvdnav_read_cache_free(this->cache);
++  else
++    free(this);
++
++  return DVDNAV_STATUS_OK;
++}
++
+ dvdnav_status_t dvdnav_open(dvdnav_t** dest, const char *path) {
+   dvdnav_t *this;
+   struct timeval time;
+Index: src/dvdnav/dvdnav.h
+===================================================================
+--- libdvdnav.orig/src/dvdnav/dvdnav.h (revision 1168)
++++ libdvdnav/src/dvdnav/dvdnav.h      (working copy)
+@@ -89,6 +89,9 @@
+  */
+ dvdnav_status_t dvdnav_open(dvdnav_t **dest, const char *path);
++dvdnav_status_t dvdnav_dup(dvdnav_t **dest, dvdnav_t *src);
++dvdnav_status_t dvdnav_free_dup(dvdnav_t *this);
++
+ /*
+  * Closes a dvdnav_t previously opened with dvdnav_open(), freeing any
+  * memory associated with it.
+Index: src/vm/vm.c
+===================================================================
+--- libdvdnav.orig/src/vm/vm.c (revision 1168)
++++ libdvdnav/src/vm/vm.c      (working copy)
+@@ -96,6 +98,7 @@
+ static pgcit_t* get_MENU_PGCIT(vm_t *vm, ifo_handle_t *h, uint16_t lang);
+ static pgcit_t* get_PGCIT(vm_t *vm);
++static void vm_close(vm_t *vm);
+ /* Helper functions */
+@@ -262,7 +265,7 @@
+ }
+ void vm_free_vm(vm_t *vm) {
+-  vm_stop(vm);
++  vm_close(vm);
+   free(vm);
+ }
+@@ -289,12 +292,20 @@
+ int vm_start(vm_t *vm) {
+   /* Set pgc to FP (First Play) pgc */
++  if (vm->stopped) {
++    vm_reset(vm, NULL);
++    vm->stopped = 0;
++  }
+   set_FP_PGC(vm);
+   process_command(vm, play_PGC(vm));
+   return !vm->stopped;
+ }
+ void vm_stop(vm_t *vm) {
++  vm->stopped = 1;
++}
++
++static void vm_close(vm_t *vm) {
+   if(vm->vmgi) {
+     ifoClose(vm->vmgi);
+     vm->vmgi=NULL;
+@@ -346,7 +357,7 @@
+   if (vm->dvd && dvdroot) {
+     /* a new dvd device has been requested */
+-    vm_stop(vm);
++    vm_close(vm);
+   }
+   if (!vm->dvd) {
+     vm->dvd = DVDOpen(dvdroot);
index abe02b8..55f9747 100644 (file)
@@ -2019,19 +2019,22 @@ ghb_longest_title()
        gint count = 0;
        guint64 longest = 0;
        gint titleindex = 0;
+       gint feature;
        
        g_debug("ghb_longest_title ()\n");
        if (h_scan == NULL) return 0;
        list = hb_get_titles( h_scan );
        count = hb_list_count( list );
        if (count > 100) count = 100;
+       if (count < 1) return 0;
+       title = (hb_title_t*)hb_list_item(list, 0);
+       feature = title->job->feature;
        for (ii = 0; ii < count; ii++)
        {
                title = (hb_title_t*)hb_list_item(list, ii);
-               if (title->duration > longest)
+               if (title->index == feature)
                {
-                       titleindex = ii;
-                       longest = title->duration;
+                       return ii;
                }
        }
        return titleindex;
index 69c6dde..33c3da2 100644 (file)
@@ -155,6 +155,7 @@ struct hb_job_s
 
     /* Pointer to the title to be ripped */
     hb_title_t    * title;
+    int             feature; // Detected DVD feature title
 
     /* Chapter selection */
     int             chapter_start;
index fbac84d..e51fd95 100644 (file)
@@ -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];
@@ -1293,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 )
index bcba78e..79cf4e8 100644 (file)
@@ -79,6 +79,7 @@ struct hb_dvd_func_s
     int           (* chapter)     ( hb_dvd_t * );
     int           (* angle_count) ( hb_dvd_t * );
     void          (* set_angle)   ( hb_dvd_t *, int );
+    int           (* main_feature)( hb_dvd_t *, hb_list_t * );
 };
 typedef struct hb_dvd_func_s hb_dvd_func_t;
 
index 09d0ad2..a1a8da4 100644 (file)
@@ -26,7 +26,8 @@ static int           hb_dvdnav_read( hb_dvd_t * d, hb_buffer_t * b );
 static int           hb_dvdnav_chapter( hb_dvd_t * d );
 static void          hb_dvdnav_close( hb_dvd_t ** _d );
 static int           hb_dvdnav_angle_count( hb_dvd_t * d );
-static void          hb_dvdnav_set_angle( hb_dvd_t * e, int angle );
+static void          hb_dvdnav_set_angle( hb_dvd_t * d, int angle );
+static int           hb_dvdnav_main_feature( hb_dvd_t * d, hb_list_t * list_title );
 
 hb_dvd_func_t hb_dvdnav_func =
 {
@@ -41,7 +42,8 @@ hb_dvd_func_t hb_dvdnav_func =
     hb_dvdnav_read,
     hb_dvdnav_chapter,
     hb_dvdnav_angle_count,
-    hb_dvdnav_set_angle
+    hb_dvdnav_set_angle,
+    hb_dvdnav_main_feature
 };
 
 // there can be at most 999 PGCs per title. round that up to the nearest
@@ -818,6 +820,423 @@ cleanup:
 }
 
 /***********************************************************************
+ * hb_dvdnav_title_scan
+ **********************************************************************/
+static int find_title( hb_list_t * list_title, int title )
+{
+    int ii;
+
+    for ( ii = 0; ii < hb_list_count( list_title ); ii++ )
+    {
+        hb_title_t * hbtitle = hb_list_item( list_title, ii );
+        if ( hbtitle->index == title )
+            return ii;
+    }
+    return -1;
+}
+
+static int try_button( dvdnav_t * dvdnav, int menu_id, int button, hb_list_t * list_title )
+{
+    int result, event, len;
+    uint8_t buf[HB_DVD_READ_BUFFER_SIZE];
+    int ii;
+    int32_t cur_title, title, pgcn, pgn;
+    uint64_t longest_duration = 0;
+    int longest = -1;
+
+    pci_t *pci = dvdnav_get_current_nav_pci( dvdnav );
+    result = dvdnav_button_select_and_activate( dvdnav, pci, button + 1 );
+    if (result != DVDNAV_STATUS_OK)
+    {
+        hb_log("dvdnav_button_select_and_activate: %s", dvdnav_err_to_string(dvdnav));
+    }
+
+    result = dvdnav_current_title_program( dvdnav, &title, &pgcn, &pgn );
+    if (result != DVDNAV_STATUS_OK)
+        hb_log("dvdnav cur pgcn err: %s", dvdnav_err_to_string(dvdnav));
+
+    if ( title > 0 )
+    {
+        hb_title_t * hbtitle;
+        int index;
+        index = find_title( list_title, title );
+        hbtitle = hb_list_item( list_title, index );
+        if ( hbtitle != NULL )
+        {
+            if ( hbtitle->duration > longest_duration )
+            {
+                longest_duration = hbtitle->duration;
+                longest = title;
+            }
+        }
+        // If the duration is longer than 10min, assume
+        // this isn't garbage leading to something bigger.
+        if ( longest_duration / 90000 > 10 * 60 )
+        {
+            return longest;
+        }
+    }
+    cur_title = title;
+
+    for (ii = 0; ii < 8000; ii++)
+    {
+        result = dvdnav_get_next_block( dvdnav, buf, &event, &len );
+        if ( result == DVDNAV_STATUS_ERR )
+        {
+            hb_error("dvdnav: Read Error, %s", dvdnav_err_to_string(dvdnav));
+            return 0;
+        }
+        switch ( event )
+        {
+        case DVDNAV_BLOCK_OK:
+            break;
+
+        case DVDNAV_CELL_CHANGE:
+        {
+            result = dvdnav_current_title_program( dvdnav, &title, &pgcn, &pgn );
+            if (result != DVDNAV_STATUS_OK)
+                hb_log("dvdnav cur pgcn err: %s", dvdnav_err_to_string(dvdnav));
+            if ( title != cur_title && title > 0 )
+            {
+                hb_title_t * hbtitle;
+                int index;
+                index = find_title( list_title, title );
+                hbtitle = hb_list_item( list_title, index );
+                if ( hbtitle != NULL )
+                {
+                    if ( hbtitle->duration > longest_duration )
+                    {
+                        longest_duration = hbtitle->duration;
+                        longest = title;
+                    }
+                }
+                // If the duration is longer than 10min, assume
+                // this isn't garbage leading to something bigger.
+                if ( longest_duration / 90000 > 10 * 60 )
+                {
+                    return longest;
+                }
+                cur_title = title;
+            }
+            if (title > 0)
+            {
+                result = dvdnav_next_pg_search( dvdnav );
+                if ( result != DVDNAV_STATUS_OK )
+                {
+                    return longest;
+                }
+                int next_title, next_pgcn, next_pgn;
+                dvdnav_current_title_program( dvdnav, &next_title, &next_pgcn, &next_pgn );
+                if (title == next_title && pgcn == next_pgcn && pgn == next_pgn)
+                {
+                    return longest;
+                }
+            }
+        } break;
+
+        case DVDNAV_STILL_FRAME:
+            dvdnav_still_skip( dvdnav );
+            break;
+
+        case DVDNAV_WAIT:
+            dvdnav_wait_skip( dvdnav );
+            break;
+
+        case DVDNAV_STOP:
+            hb_log("dvdnav: stop encountered during seek");
+            return 0;
+
+        case DVDNAV_HOP_CHANNEL:
+            break;
+
+        case DVDNAV_NAV_PACKET:
+        {
+        } break;
+
+        case DVDNAV_VTS_CHANGE:
+        {
+            result = dvdnav_current_title_program( dvdnav, &title, &pgcn, &pgn );
+            if (result != DVDNAV_STATUS_OK)
+                hb_log("dvdnav cur pgcn err: %s", dvdnav_err_to_string(dvdnav));
+            if ( title != cur_title && title > 0 )
+            {
+                hb_title_t * hbtitle;
+                int index;
+                index = find_title( list_title, title );
+                hbtitle = hb_list_item( list_title, index );
+                if ( hbtitle != NULL )
+                {
+                    if ( hbtitle->duration > longest_duration )
+                    {
+                        longest_duration = hbtitle->duration;
+                        longest = title;
+                    }
+                }
+                cur_title = title;
+                if ( longest_duration / 90000 > 10 * 60 )
+                {
+                    return longest;
+                }
+            }
+            if ( title > 0 )
+            {
+                dvdnav_next_pg_search( dvdnav );
+            }
+        } break;
+
+        case DVDNAV_HIGHLIGHT:
+            break;
+
+        case DVDNAV_AUDIO_STREAM_CHANGE:
+            break;
+
+        case DVDNAV_SPU_STREAM_CHANGE:
+            break;
+
+        case DVDNAV_SPU_CLUT_CHANGE:
+            break;
+
+        case DVDNAV_NOP:
+            break;
+
+        default:
+            break;
+        }
+    }
+    return longest;
+}
+
+static int try_menu( hb_dvdnav_t * d, hb_list_t * list_title, DVDMenuID_t menu )
+{
+    int result, event, len;
+    uint8_t buf[HB_DVD_READ_BUFFER_SIZE];
+    int ii;
+    int32_t cur_title, title, pgcn, pgn;
+    uint64_t longest_duration = 0;
+    int longest = -1;
+
+    dvdnav_reset( d->dvdnav );
+    result = dvdnav_title_play( d->dvdnav, 1 );
+    if ( result == DVDNAV_STATUS_ERR )
+    {
+        hb_error("dvdnav: Can not set title, %s", dvdnav_err_to_string(d->dvdnav));
+        goto done;
+    }
+    result = dvdnav_menu_call( d->dvdnav, menu );
+    if ( result != DVDNAV_STATUS_OK )
+    {
+        hb_error("dvdnav: Can not set dvd menu, %s", dvdnav_err_to_string(d->dvdnav));
+        goto done;
+    }
+
+    result = dvdnav_current_title_program( d->dvdnav, &cur_title, &pgcn, &pgn );
+    if (result != DVDNAV_STATUS_OK)
+        hb_log("dvdnav cur pgcn err: %s", dvdnav_err_to_string(d->dvdnav));
+
+    // Hit the root menu again to see if we can force
+    // our way to the main menu.
+    dvdnav_next_pg_search( d->dvdnav );
+    result = dvdnav_menu_call( d->dvdnav, menu );
+
+    dvdnav_next_pg_search( d->dvdnav );
+    result = dvdnav_menu_call( d->dvdnav, menu );
+
+    if ( cur_title > 0 )
+    {
+        dvdnav_next_pg_search( d->dvdnav );
+    }
+
+    for (ii = 0; ii < 5000; ii++)
+    {
+        result = dvdnav_get_next_block( d->dvdnav, buf, &event, &len );
+        if ( result == DVDNAV_STATUS_ERR )
+        {
+            hb_error("dvdnav: Read Error, %s", dvdnav_err_to_string(d->dvdnav));
+            goto done;
+        }
+        switch ( event )
+        {
+        case DVDNAV_BLOCK_OK:
+            break;
+
+        case DVDNAV_CELL_CHANGE:
+        {
+            result = dvdnav_current_title_program( d->dvdnav, &title, &pgcn, &pgn );
+            if (result != DVDNAV_STATUS_OK)
+                hb_log("dvdnav cur pgcn err: %s", dvdnav_err_to_string(d->dvdnav));
+            cur_title = title;
+            if ( title > 0 )
+            {
+                dvdnav_next_pg_search( d->dvdnav );
+            }
+        } break;
+
+        case DVDNAV_STILL_FRAME:
+            dvdnav_still_skip( d->dvdnav );
+            break;
+
+        case DVDNAV_WAIT:
+            dvdnav_wait_skip( d->dvdnav );
+            break;
+
+        case DVDNAV_STOP:
+            hb_log("dvdnav: stop encountered during seek");
+            d->stopped = 1;
+            goto done;
+
+        case DVDNAV_HOP_CHANNEL:
+            break;
+
+        case DVDNAV_NAV_PACKET:
+        {
+            pci_t *pci = dvdnav_get_current_nav_pci( d->dvdnav );
+            int kk;
+            int buttons;
+            if ( pci == NULL ) break;
+
+            buttons = pci->hli.hl_gi.btn_ns;
+            if ( cur_title == 0 && buttons > 0 )
+            {
+                int menu_title, menu_id;
+                result = dvdnav_current_title_info( d->dvdnav, &menu_title, &menu_id );
+                if (result != DVDNAV_STATUS_OK)
+                    hb_log("dvdnav cur pgcn err: %s", dvdnav_err_to_string(d->dvdnav));
+                for (kk = 0; kk < buttons; kk++)
+                {
+                    dvdnav_t *dvdnav_copy;
+
+                    result = dvdnav_dup( &dvdnav_copy, d->dvdnav );
+                    if (result != DVDNAV_STATUS_OK)
+                    {
+                        hb_log("dvdnav dup failed: %s", dvdnav_err_to_string(d->dvdnav));
+                        goto done;
+                    }
+                    title = try_button( dvdnav_copy, menu_id, kk, list_title );
+                    dvdnav_free_dup( dvdnav_copy );
+
+                    if ( title >= 0 )
+                    {
+                        hb_title_t * hbtitle;
+                        int index;
+                        index = find_title( list_title, title );
+                        hbtitle = hb_list_item( list_title, index );
+                        if ( hbtitle != NULL )
+                        {
+                            if ( hbtitle->duration > longest_duration )
+                            {
+                                longest_duration = hbtitle->duration;
+                                longest = title;
+                            }
+                        }
+                    }
+                }
+                goto done;
+            }
+        } break;
+
+        case DVDNAV_VTS_CHANGE:
+        {
+            result = dvdnav_current_title_program( d->dvdnav, &title, &pgcn, &pgn );
+            if (result != DVDNAV_STATUS_OK)
+                hb_log("dvdnav cur pgcn err: %s", dvdnav_err_to_string(d->dvdnav));
+            cur_title = title;
+            if ( title > 0 )
+            {
+                dvdnav_next_pg_search( d->dvdnav );
+            }
+        } break;
+
+        case DVDNAV_HIGHLIGHT:
+            break;
+
+        case DVDNAV_AUDIO_STREAM_CHANGE:
+            break;
+
+        case DVDNAV_SPU_STREAM_CHANGE:
+            break;
+
+        case DVDNAV_SPU_CLUT_CHANGE:
+            break;
+
+        case DVDNAV_NOP:
+            break;
+
+        default:
+            break;
+        }
+    }
+
+done:
+    return longest;
+}
+
+static int hb_dvdnav_main_feature( hb_dvd_t * e, hb_list_t * list_title )
+{
+    hb_dvdnav_t * d = &(e->dvdnav);
+    int longest_root;
+    int longest_title;
+    int longest_fallback;
+    int ii;
+    uint64_t longest_duration_root = 0;
+    uint64_t longest_duration_title = 0;
+    uint64_t longest_duration_fallback = 0;
+
+    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_fallback )
+        {
+            longest_duration_fallback = title->duration;
+            longest_fallback = title->index;
+        }
+    }
+
+    longest_root = try_menu( d, list_title, DVD_MENU_Root );
+    if ( longest_root >= 0 )
+    {
+        hb_title_t * hbtitle;
+        int index;
+        index = find_title( list_title, longest_root );
+        hbtitle = hb_list_item( list_title, index );
+        if ( hbtitle )
+            longest_duration_root = hbtitle->duration;
+    }
+    if ( longest_root < 0 || 
+         (float)longest_duration_fallback * 0.7 > longest_duration_root)
+    {
+        longest_title = try_menu( d, list_title, DVD_MENU_Title );
+        if ( longest_title >= 0 )
+        {
+            hb_title_t * hbtitle;
+            int index;
+            index = find_title( list_title, longest_title );
+            hbtitle = hb_list_item( list_title, index );
+            if ( hbtitle )
+                longest_duration_title = hbtitle->duration;
+        }
+    }
+
+    uint64_t longest_duration;
+    int longest;
+
+    if ( longest_duration_root > longest_duration_title )
+    {
+        longest_duration = longest_duration_root;
+        longest = longest_root;
+    }
+    else
+    {
+        longest_duration = longest_duration_title;
+        longest = longest_title;
+    }
+    if ((float)longest_duration_fallback * 0.7 > longest_duration)
+    {
+        longest = longest_fallback;
+    }
+    return longest;
+}
+
+/***********************************************************************
  * hb_dvdnav_start
  ***********************************************************************
  * Title and chapter start at 1
@@ -1097,7 +1516,7 @@ static int hb_dvdnav_read( hb_dvd_t * e, hb_buffer_t * b )
             * necessary and update the decoding/displaying accordingly. 
             */
             {
-                int tt = 0, pgcn = 0, pgn = 0, c;
+                int tt = 0, pgcn = 0, pgn = 0;
 
                 dvdnav_current_title_program(d->dvdnav, &tt, &pgcn, &pgn);
                 if (tt != d->title)
index 8223ebf..dd922dc 100644 (file)
@@ -205,6 +205,7 @@ int          hb_dvd_is_break( hb_dvd_t * d );
 void         hb_dvd_close( hb_dvd_t ** );
 int          hb_dvd_angle_count( hb_dvd_t * d );
 void         hb_dvd_set_angle( hb_dvd_t * d, int angle );
+int          hb_dvd_main_feature( hb_dvd_t * d, hb_list_t * list_title );
 
 hb_stream_t * hb_stream_open( char * path, hb_title_t *title );
 void            hb_stream_close( hb_stream_t ** );
index f93e6a2..a45829b 100644 (file)
@@ -69,6 +69,7 @@ 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;
@@ -93,6 +94,7 @@ static void ScanFunc( void * _data )
                 hb_list_add( data->list_title,
                              hb_dvd_title_scan( data->dvd, i + 1 ) );
             }
+            feature = hb_dvd_main_feature( data->dvd, data->list_title );
         }
     }
     else if ( ( data->batch = hb_batch_init( data->path ) ) )
@@ -184,6 +186,7 @@ static void ScanFunc( void * _data )
         title->job = job;
 
         job->title = title;
+        job->feature = feature;
 
         /* Set defaults settings */
         job->chapter_start = 1;
index 71cc5a6..6a88149 100644 (file)
@@ -1803,9 +1803,7 @@ static NSString *        ChooseSourceIdentifier             = @"Choose Source It
 {
     hb_list_t  * list;
        hb_title_t * title;
-       int indxpri=0;    // Used to search the longuest title (default in combobox)
-       int longuestpri=0; // Used to search the longuest title (default in combobox)
-    
+       int feature_title=0; // Used to store the main feature title
 
         list = hb_get_titles( fHandle );
         
@@ -1879,11 +1877,10 @@ static NSString *        ChooseSourceIdentifier             = @"Choose Source It
                                                      @"%@/Desktop/%@.mp4", NSHomeDirectory(),[browsedSourceDisplayName stringByDeletingPathExtension]]];
                 }
                 
-                
-                if (longuestpri < title->hours*60*60 + title->minutes *60 + title->seconds)
+                /* See if this is the main feature according to libhb */
+                if (title->index == title->job->feature)
                 {
-                    longuestpri=title->hours*60*60 + title->minutes *60 + title->seconds;
-                    indxpri=i;
+                    feature_title = i;
                 }
                 
                 [fSrcTitlePopUp addItemWithTitle: [NSString
@@ -1899,8 +1896,8 @@ static NSString *        ChooseSourceIdentifier             = @"Choose Source It
             }
             else
             {
-                /* if not then select the longest title (dvd) */
-                [fSrcTitlePopUp selectItemAtIndex: indxpri];
+                /* if not then select the main feature title */
+                [fSrcTitlePopUp selectItemAtIndex: feature_title];
             }
             [self titlePopUpChanged:nil];
             
index 4cd8c5c..87acb8c 100644 (file)
@@ -378,6 +378,10 @@ static void PrintTitleInfo( hb_title_t * title )
     int i;
 
     fprintf( stderr, "+ title %d:\n", title->index );
+    if ( title->index == title->job->feature )
+    {
+        fprintf( stderr, "  + Main Feature\n" );
+    }
     if ( title->type == HB_STREAM_TYPE )
     {
         fprintf( stderr, "  + stream: %s\n", title->path );