diff options
Diffstat (limited to 'contrib/libdvdnav')
-rw-r--r-- | contrib/libdvdnav/A01-program-info.patch | 214 |
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); |