summaryrefslogtreecommitdiffstats
path: root/contrib/libdvdnav
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/libdvdnav')
-rw-r--r--contrib/libdvdnav/A01-program-info.patch214
1 files changed, 214 insertions, 0 deletions
diff --git a/contrib/libdvdnav/A01-program-info.patch b/contrib/libdvdnav/A01-program-info.patch
new file mode 100644
index 000000000..531741b84
--- /dev/null
+++ b/contrib/libdvdnav/A01-program-info.patch
@@ -0,0 +1,214 @@
+diff -Naur libdvdnav.orig/src/dvdnav/dvdnav.h libdvdnav/src/dvdnav/dvdnav.h
+--- libdvdnav.orig/src/dvdnav/dvdnav.h 2009-03-13 18:28:22.000000000 -0700
++++ libdvdnav/src/dvdnav/dvdnav.h 2009-04-30 10:56:29.000000000 -0700
+@@ -279,6 +279,11 @@
+ dvdnav_status_t dvdnav_part_play(dvdnav_t *self, int32_t title, int32_t part);
+
+ /*
++ * Plays the specified title, starting from the specified program
++ */
++dvdnav_status_t dvdnav_program_play(dvdnav_t *this, int32_t title, int32_t pgcn, int32_t pgn);
++
++/*
+ * Stores in *times an array (that the application *must* free) of
+ * dvdtimes corresponding to the chapter times for the chosen title.
+ * *duration will have the duration of the title
+@@ -320,6 +325,13 @@
+ int32_t *part);
+
+ /*
++ * Return the title number, pgcn and pgn currently being played.
++ * A title of 0 indicates, we are in a menu.
++ */
++dvdnav_status_t dvdnav_current_title_program(dvdnav_t *self, int32_t *title,
++ int32_t *pgcn, int32_t *pgn);
++
++/*
+ * Return the current position (in blocks) within the current
+ * title and the length (in blocks) of said title.
+ *
+diff -Naur libdvdnav.orig/src/navigation.c libdvdnav/src/navigation.c
+--- libdvdnav.orig/src/navigation.c 2009-01-08 14:57:11.000000000 -0800
++++ libdvdnav/src/navigation.c 2009-04-30 10:55:47.000000000 -0700
+@@ -122,10 +122,90 @@
+ return DVDNAV_STATUS_ERR;
+ }
+
++dvdnav_status_t dvdnav_current_title_program(dvdnav_t *this, int32_t *title, int32_t *pgcn, int32_t *pgn) {
++ int32_t retval;
++ int32_t part;
++
++ pthread_mutex_lock(&this->vm_lock);
++ if (!this->vm->vtsi || !this->vm->vmgi) {
++ printerr("Bad VM state.");
++ pthread_mutex_unlock(&this->vm_lock);
++ return DVDNAV_STATUS_ERR;
++ }
++ if (!this->started) {
++ printerr("Virtual DVD machine not started.");
++ pthread_mutex_unlock(&this->vm_lock);
++ return DVDNAV_STATUS_ERR;
++ }
++ if (!this->vm->state.pgc) {
++ printerr("No current PGC.");
++ pthread_mutex_unlock(&this->vm_lock);
++ return DVDNAV_STATUS_ERR;
++ }
++ if ( (this->vm->state.domain == VTSM_DOMAIN)
++ || (this->vm->state.domain == VMGM_DOMAIN) ) {
++ /* Get current Menu ID: into *part. */
++ if(! vm_get_current_menu(this->vm, &part)) {
++ pthread_mutex_unlock(&this->vm_lock);
++ return DVDNAV_STATUS_ERR;
++ }
++ if (part > -1) {
++ *title = 0;
++ *pgcn = this->vm->state.pgcN;
++ *pgn = this->vm->state.pgN;
++ pthread_mutex_unlock(&this->vm_lock);
++ return DVDNAV_STATUS_OK;
++ }
++ }
++ if (this->vm->state.domain == VTS_DOMAIN) {
++ retval = vm_get_current_title_part(this->vm, title, &part);
++ *pgcn = this->vm->state.pgcN;
++ *pgn = this->vm->state.pgN;
++ pthread_mutex_unlock(&this->vm_lock);
++ return retval ? DVDNAV_STATUS_OK : DVDNAV_STATUS_ERR;
++ }
++ printerr("Not in a title or menu.");
++ pthread_mutex_unlock(&this->vm_lock);
++ return DVDNAV_STATUS_ERR;
++}
++
+ dvdnav_status_t dvdnav_title_play(dvdnav_t *this, int32_t title) {
+ return dvdnav_part_play(this, title, 1);
+ }
+
++dvdnav_status_t dvdnav_program_play(dvdnav_t *this, int32_t title, int32_t pgcn, int32_t pgn) {
++ int32_t retval;
++
++ pthread_mutex_lock(&this->vm_lock);
++ if (!this->vm->vmgi) {
++ printerr("Bad VM state.");
++ pthread_mutex_unlock(&this->vm_lock);
++ return DVDNAV_STATUS_ERR;
++ }
++ if (!this->started) {
++ /* don't report an error but be nice */
++ vm_start(this->vm);
++ this->started = 1;
++ }
++ if (!this->vm->state.pgc) {
++ printerr("No current PGC.");
++ pthread_mutex_unlock(&this->vm_lock);
++ return DVDNAV_STATUS_ERR;
++ }
++ if((title < 1) || (title > this->vm->vmgi->tt_srpt->nr_of_srpts)) {
++ printerr("Title out of range.");
++ pthread_mutex_unlock(&this->vm_lock);
++ return DVDNAV_STATUS_ERR;
++ }
++
++ retval = vm_jump_title_program(this->vm, title, pgcn, pgn);
++ if (retval)
++ this->vm->hop_channel++;
++ pthread_mutex_unlock(&this->vm_lock);
++
++ return retval ? DVDNAV_STATUS_OK : DVDNAV_STATUS_ERR;
++}
++
+ dvdnav_status_t dvdnav_part_play(dvdnav_t *this, int32_t title, int32_t part) {
+ int32_t retval;
+
+diff -Naur libdvdnav.orig/src/vm/vm.c libdvdnav/src/vm/vm.c
+--- libdvdnav.orig/src/vm/vm.c 2009-03-13 18:28:22.000000000 -0700
++++ libdvdnav/src/vm/vm.c 2009-04-30 11:07:35.000000000 -0700
+@@ -83,6 +83,8 @@
+ static int set_PTT(vm_t *vm, int tt, int ptt);
+ static int set_VTS_TT(vm_t *vm, int vtsN, int vts_ttn);
+ static int set_VTS_PTT(vm_t *vm, int vtsN, int vts_ttn, int part);
++static int set_PROG(vm_t *vm, int tt, int pgcn, int pgn);
++static int set_VTS_PROG(vm_t *vm, int vtsN, int vts_ttn, int pgcn, int pgn);
+ static int set_FP_PGC(vm_t *vm);
+ static int set_MENU(vm_t *vm, int menu);
+ static int set_PGCN(vm_t *vm, int pgcN);
+@@ -516,6 +518,24 @@
+ return 1;
+ }
+
++int vm_jump_title_program(vm_t *vm, int title, int pgcn, int pgn) {
++ link_t link;
++
++ if(!set_PROG(vm, title, pgcn, pgn))
++ return 0;
++ /* Some DVDs do not want us to jump directly into a title and have
++ * PGC pre commands taking us back to some menu. Since we do not like that,
++ * we do not execute PGC pre commands that would do a jump. */
++ /* process_command(vm, play_PGC_PG(vm, (vm->state).pgN)); */
++ link = play_PGC_PG(vm, (vm->state).pgN);
++ if (link.command != PlayThis)
++ /* jump occured -> ignore it and play the PG anyway */
++ process_command(vm, play_PG(vm));
++ else
++ process_command(vm, link);
++ return 1;
++}
++
+ int vm_jump_title_part(vm_t *vm, int title, int part) {
+ link_t link;
+
+@@ -1644,6 +1664,42 @@
+ return res;
+ }
+
++static int set_PROG(vm_t *vm, int tt, int pgcn, int pgn) {
++ assert(tt <= vm->vmgi->tt_srpt->nr_of_srpts);
++ return set_VTS_PROG(vm, vm->vmgi->tt_srpt->title[tt - 1].title_set_nr,
++ vm->vmgi->tt_srpt->title[tt - 1].vts_ttn, pgcn, pgn);
++}
++
++static int set_VTS_PROG(vm_t *vm, int vtsN, int vts_ttn, int pgcn, int pgn) {
++ int pgcN, pgN, res, title, part;
++
++ (vm->state).domain = VTS_DOMAIN;
++
++ if (vtsN != (vm->state).vtsN)
++ if (!ifoOpenNewVTSI(vm, vm->dvd, vtsN)) /* Also sets (vm->state).vtsN */
++ return 0;
++
++ if ((vts_ttn < 1) || (vts_ttn > vm->vtsi->vts_ptt_srpt->nr_of_srpts)) {
++ return 0;
++ }
++
++ pgcN = pgcn;
++ pgN = pgn;
++
++ (vm->state).TT_PGCN_REG = pgcN;
++ (vm->state).TTN_REG = get_TT(vm, vtsN, vts_ttn);
++ assert( (vm->state.TTN_REG) != 0 );
++ (vm->state).VTS_TTN_REG = vts_ttn;
++ (vm->state).vtsN = vtsN; /* Not sure about this one. We can get to it easily from TTN_REG */
++ /* Any other registers? */
++
++ res = set_PGCN(vm, pgcN); /* This clobber's state.pgN (sets it to 1), but we don't want clobbering here. */
++ (vm->state).pgN = pgN;
++ vm_get_current_title_part(vm, &title, &part);
++ (vm->state).PTTN_REG = part;
++ return res;
++}
++
+ static int set_FP_PGC(vm_t *vm) {
+ (vm->state).domain = FP_DOMAIN;
+ if (!vm->vmgi->first_play_pgc) {
+diff -Naur libdvdnav.orig/src/vm/vm.h libdvdnav/src/vm/vm.h
+--- libdvdnav.orig/src/vm/vm.h 2009-03-13 18:28:22.000000000 -0700
++++ libdvdnav/src/vm/vm.h 2009-04-30 10:57:02.000000000 -0700
+@@ -139,6 +139,7 @@
+ int vm_jump_pg(vm_t *vm, int pg);
+ int vm_jump_cell_block(vm_t *vm, int cell, int block);
+ int vm_jump_title_part(vm_t *vm, int title, int part);
++int vm_jump_title_program(vm_t *vm, int title, int pgcn, int pgn);
+ int vm_jump_top_pg(vm_t *vm);
+ int vm_jump_next_pg(vm_t *vm);
+ int vm_jump_prev_pg(vm_t *vm);