summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--contrib/libdvdnav/A08-dvdnav-dup.patch137
-rw-r--r--gtk/src/hb-backend.c9
-rw-r--r--libhb/common.h1
-rw-r--r--libhb/dvd.c27
-rw-r--r--libhb/dvd.h1
-rw-r--r--libhb/dvdnav.c425
-rw-r--r--libhb/internal.h1
-rw-r--r--libhb/scan.c3
-rw-r--r--macosx/Controller.m15
-rw-r--r--test/test.c4
10 files changed, 607 insertions, 16 deletions
diff --git a/contrib/libdvdnav/A08-dvdnav-dup.patch b/contrib/libdvdnav/A08-dvdnav-dup.patch
new file mode 100644
index 000000000..ce6072a4c
--- /dev/null
+++ b/contrib/libdvdnav/A08-dvdnav-dup.patch
@@ -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);
diff --git a/gtk/src/hb-backend.c b/gtk/src/hb-backend.c
index abe02b8e7..55f9747c9 100644
--- a/gtk/src/hb-backend.c
+++ b/gtk/src/hb-backend.c
@@ -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;
diff --git a/libhb/common.h b/libhb/common.h
index 69c6ddea0..33c3da2f7 100644
--- a/libhb/common.h
+++ b/libhb/common.h
@@ -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;
diff --git a/libhb/dvd.c b/libhb/dvd.c
index fbac84de4..e51fd95bf 100644
--- a/libhb/dvd.c
+++ b/libhb/dvd.c
@@ -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 )
diff --git a/libhb/dvd.h b/libhb/dvd.h
index bcba78ea4..79cf4e888 100644
--- a/libhb/dvd.h
+++ b/libhb/dvd.h
@@ -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;
diff --git a/libhb/dvdnav.c b/libhb/dvdnav.c
index 09d0ad2e4..a1a8da472 100644
--- a/libhb/dvdnav.c
+++ b/libhb/dvdnav.c
@@ -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)
diff --git a/libhb/internal.h b/libhb/internal.h
index 8223ebfba..dd922dc46 100644
--- a/libhb/internal.h
+++ b/libhb/internal.h
@@ -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 ** );
diff --git a/libhb/scan.c b/libhb/scan.c
index f93e6a24b..a45829b15 100644
--- a/libhb/scan.c
+++ b/libhb/scan.c
@@ -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;
diff --git a/macosx/Controller.m b/macosx/Controller.m
index 71cc5a618..6a8814965 100644
--- a/macosx/Controller.m
+++ b/macosx/Controller.m
@@ -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];
diff --git a/test/test.c b/test/test.c
index 4cd8c5c42..87acb8caa 100644
--- a/test/test.c
+++ b/test/test.c
@@ -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 );