diff navigation.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 9c5aef10d165
children 264c5b900bfb
line wrap: on
line diff
--- a/navigation.c	Fri Jul 30 23:34:13 2010 +0000
+++ b/navigation.c	Fri Jul 30 23:34:16 2010 +0000
@@ -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;