diff vm/vm.c @ 409:9b8bfc56a7fe src

Add dvdnav_program_play & dvdnav_current_title_program Using title parts w/ dvdnav_part_play and dvdnav_current_title_info is not reliable for use as chapter marks in files made from transcoding. The start of a part does not necessarily fall strictly inside the main title. Parts can have an intro sequence before getting into the title. So we use program boundaries instead of part markers to test when we have reached a chapter point during encoding of the title. The same would apply to displaying the current chapter during playback. The program boundaries should be checked instead of looking for a part. Patch from John Stebbins. Thanks!
author erik
date Fri, 30 Jul 2010 23:34:16 +0000
parents 7923e813ec61
children 799f85209145
line wrap: on
line diff
--- a/vm/vm.c	Fri Jul 30 23:34:13 2010 +0000
+++ b/vm/vm.c	Fri Jul 30 23:34:16 2010 +0000
@@ -85,6 +85,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);
@@ -520,6 +522,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;
 
@@ -1647,6 +1667,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 = 0;
+
+  (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) {