1 diff -Naur libdvdnav.orig/src/dvdnav/dvdnav.h libdvdnav/src/dvdnav/dvdnav.h
2 --- libdvdnav.orig/src/dvdnav/dvdnav.h 2009-03-13 18:28:22.000000000 -0700
3 +++ libdvdnav/src/dvdnav/dvdnav.h 2009-04-30 10:56:29.000000000 -0700
5 dvdnav_status_t dvdnav_part_play(dvdnav_t *self, int32_t title, int32_t part);
8 + * Plays the specified title, starting from the specified program
10 +dvdnav_status_t dvdnav_program_play(dvdnav_t *this, int32_t title, int32_t pgcn, int32_t pgn);
13 * Stores in *times an array (that the application *must* free) of
14 * dvdtimes corresponding to the chapter times for the chosen title.
15 * *duration will have the duration of the title
20 + * Return the title number, pgcn and pgn currently being played.
21 + * A title of 0 indicates, we are in a menu.
23 +dvdnav_status_t dvdnav_current_title_program(dvdnav_t *self, int32_t *title,
24 + int32_t *pgcn, int32_t *pgn);
27 * Return the current position (in blocks) within the current
28 * title and the length (in blocks) of said title.
30 diff -Naur libdvdnav.orig/src/navigation.c libdvdnav/src/navigation.c
31 --- libdvdnav.orig/src/navigation.c 2009-01-08 14:57:11.000000000 -0800
32 +++ libdvdnav/src/navigation.c 2009-04-30 10:55:47.000000000 -0700
34 return DVDNAV_STATUS_ERR;
37 +dvdnav_status_t dvdnav_current_title_program(dvdnav_t *this, int32_t *title, int32_t *pgcn, int32_t *pgn) {
41 + pthread_mutex_lock(&this->vm_lock);
42 + if (!this->vm->vtsi || !this->vm->vmgi) {
43 + printerr("Bad VM state.");
44 + pthread_mutex_unlock(&this->vm_lock);
45 + return DVDNAV_STATUS_ERR;
47 + if (!this->started) {
48 + printerr("Virtual DVD machine not started.");
49 + pthread_mutex_unlock(&this->vm_lock);
50 + return DVDNAV_STATUS_ERR;
52 + if (!this->vm->state.pgc) {
53 + printerr("No current PGC.");
54 + pthread_mutex_unlock(&this->vm_lock);
55 + return DVDNAV_STATUS_ERR;
57 + if ( (this->vm->state.domain == VTSM_DOMAIN)
58 + || (this->vm->state.domain == VMGM_DOMAIN) ) {
59 + /* Get current Menu ID: into *part. */
60 + if(! vm_get_current_menu(this->vm, &part)) {
61 + pthread_mutex_unlock(&this->vm_lock);
62 + return DVDNAV_STATUS_ERR;
66 + *pgcn = this->vm->state.pgcN;
67 + *pgn = this->vm->state.pgN;
68 + pthread_mutex_unlock(&this->vm_lock);
69 + return DVDNAV_STATUS_OK;
72 + if (this->vm->state.domain == VTS_DOMAIN) {
73 + retval = vm_get_current_title_part(this->vm, title, &part);
74 + *pgcn = this->vm->state.pgcN;
75 + *pgn = this->vm->state.pgN;
76 + pthread_mutex_unlock(&this->vm_lock);
77 + return retval ? DVDNAV_STATUS_OK : DVDNAV_STATUS_ERR;
79 + printerr("Not in a title or menu.");
80 + pthread_mutex_unlock(&this->vm_lock);
81 + return DVDNAV_STATUS_ERR;
84 dvdnav_status_t dvdnav_title_play(dvdnav_t *this, int32_t title) {
85 return dvdnav_part_play(this, title, 1);
88 +dvdnav_status_t dvdnav_program_play(dvdnav_t *this, int32_t title, int32_t pgcn, int32_t pgn) {
91 + pthread_mutex_lock(&this->vm_lock);
92 + if (!this->vm->vmgi) {
93 + printerr("Bad VM state.");
94 + pthread_mutex_unlock(&this->vm_lock);
95 + return DVDNAV_STATUS_ERR;
97 + if (!this->started) {
98 + /* don't report an error but be nice */
102 + if (!this->vm->state.pgc) {
103 + printerr("No current PGC.");
104 + pthread_mutex_unlock(&this->vm_lock);
105 + return DVDNAV_STATUS_ERR;
107 + if((title < 1) || (title > this->vm->vmgi->tt_srpt->nr_of_srpts)) {
108 + printerr("Title out of range.");
109 + pthread_mutex_unlock(&this->vm_lock);
110 + return DVDNAV_STATUS_ERR;
113 + retval = vm_jump_title_program(this->vm, title, pgcn, pgn);
115 + this->vm->hop_channel++;
116 + pthread_mutex_unlock(&this->vm_lock);
118 + return retval ? DVDNAV_STATUS_OK : DVDNAV_STATUS_ERR;
121 dvdnav_status_t dvdnav_part_play(dvdnav_t *this, int32_t title, int32_t part) {
124 diff -Naur libdvdnav.orig/src/vm/vm.c libdvdnav/src/vm/vm.c
125 --- libdvdnav.orig/src/vm/vm.c 2009-03-13 18:28:22.000000000 -0700
126 +++ libdvdnav/src/vm/vm.c 2009-04-30 11:07:35.000000000 -0700
128 static int set_PTT(vm_t *vm, int tt, int ptt);
129 static int set_VTS_TT(vm_t *vm, int vtsN, int vts_ttn);
130 static int set_VTS_PTT(vm_t *vm, int vtsN, int vts_ttn, int part);
131 +static int set_PROG(vm_t *vm, int tt, int pgcn, int pgn);
132 +static int set_VTS_PROG(vm_t *vm, int vtsN, int vts_ttn, int pgcn, int pgn);
133 static int set_FP_PGC(vm_t *vm);
134 static int set_MENU(vm_t *vm, int menu);
135 static int set_PGCN(vm_t *vm, int pgcN);
140 +int vm_jump_title_program(vm_t *vm, int title, int pgcn, int pgn) {
143 + if(!set_PROG(vm, title, pgcn, pgn))
145 + /* Some DVDs do not want us to jump directly into a title and have
146 + * PGC pre commands taking us back to some menu. Since we do not like that,
147 + * we do not execute PGC pre commands that would do a jump. */
148 + /* process_command(vm, play_PGC_PG(vm, (vm->state).pgN)); */
149 + link = play_PGC_PG(vm, (vm->state).pgN);
150 + if (link.command != PlayThis)
151 + /* jump occured -> ignore it and play the PG anyway */
152 + process_command(vm, play_PG(vm));
154 + process_command(vm, link);
158 int vm_jump_title_part(vm_t *vm, int title, int part) {
161 @@ -1644,6 +1664,42 @@
165 +static int set_PROG(vm_t *vm, int tt, int pgcn, int pgn) {
166 + assert(tt <= vm->vmgi->tt_srpt->nr_of_srpts);
167 + return set_VTS_PROG(vm, vm->vmgi->tt_srpt->title[tt - 1].title_set_nr,
168 + vm->vmgi->tt_srpt->title[tt - 1].vts_ttn, pgcn, pgn);
171 +static int set_VTS_PROG(vm_t *vm, int vtsN, int vts_ttn, int pgcn, int pgn) {
172 + int pgcN, pgN, res, title, part;
174 + (vm->state).domain = VTS_DOMAIN;
176 + if (vtsN != (vm->state).vtsN)
177 + if (!ifoOpenNewVTSI(vm, vm->dvd, vtsN)) /* Also sets (vm->state).vtsN */
180 + if ((vts_ttn < 1) || (vts_ttn > vm->vtsi->vts_ptt_srpt->nr_of_srpts)) {
187 + (vm->state).TT_PGCN_REG = pgcN;
188 + (vm->state).TTN_REG = get_TT(vm, vtsN, vts_ttn);
189 + assert( (vm->state.TTN_REG) != 0 );
190 + (vm->state).VTS_TTN_REG = vts_ttn;
191 + (vm->state).vtsN = vtsN; /* Not sure about this one. We can get to it easily from TTN_REG */
192 + /* Any other registers? */
194 + res = set_PGCN(vm, pgcN); /* This clobber's state.pgN (sets it to 1), but we don't want clobbering here. */
195 + (vm->state).pgN = pgN;
196 + vm_get_current_title_part(vm, &title, &part);
197 + (vm->state).PTTN_REG = part;
201 static int set_FP_PGC(vm_t *vm) {
202 (vm->state).domain = FP_DOMAIN;
203 if (!vm->vmgi->first_play_pgc) {
204 diff -Naur libdvdnav.orig/src/vm/vm.h libdvdnav/src/vm/vm.h
205 --- libdvdnav.orig/src/vm/vm.h 2009-03-13 18:28:22.000000000 -0700
206 +++ libdvdnav/src/vm/vm.h 2009-04-30 10:57:02.000000000 -0700
208 int vm_jump_pg(vm_t *vm, int pg);
209 int vm_jump_cell_block(vm_t *vm, int cell, int block);
210 int vm_jump_title_part(vm_t *vm, int title, int part);
211 +int vm_jump_title_program(vm_t *vm, int title, int pgcn, int pgn);
212 int vm_jump_top_pg(vm_t *vm);
213 int vm_jump_next_pg(vm_t *vm);
214 int vm_jump_prev_pg(vm_t *vm);