No subject


Mon Jul 5 15:10:54 CEST 2010


This patch prevents an abort when a nav command tries to send you to a
menu that doesn't exist. Mac the ripper's feature title extraction
removes menus from the resulting image, but does not remove navigation
instructions that attempt to jump to those menus. This patch checks that
a menu exists before acting on such  instructions. If the menu does not
exist, it puts the vm into the stopped state.

Thanks goes to John Stebbins for the original send of this patch and
noticing that I introduced a bug when attempting to streamline this
patch. Finally, he has guided this patch and many more for an
extended period of time. Thanks again John.

Modified:
   trunk/libdvdnav/src/vm/vm.c

Modified: trunk/libdvdnav/src/vm/vm.c
==============================================================================
--- trunk/libdvdnav/src/vm/vm.c	Sat Sep 11 17:15:43 2010	(r1218)
+++ trunk/libdvdnav/src/vm/vm.c	Mon Nov 22 00:59:43 2010	(r1219)
@@ -609,6 +609,9 @@ int vm_jump_menu(vm_t *vm, DVDMenuID_t m
     switch(menuid) {
     case DVD_MENU_Title:
     case DVD_MENU_Escape:
+      if(vm->vmgi == NULL || vm->vmgi->pgci_ut == NULL) {
+        return 0;
+      }
       (vm->state).domain = VMGM_DOMAIN;
       break;
     case DVD_MENU_Root:
@@ -616,12 +619,13 @@ int vm_jump_menu(vm_t *vm, DVDMenuID_t m
     case DVD_MENU_Audio:
     case DVD_MENU_Angle:
     case DVD_MENU_Part:
+      if(vm->vtsi == NULL || vm->vtsi->pgci_ut == NULL) {
+        return 0;
+      }
       (vm->state).domain = VTSM_DOMAIN;
       break;
     }
-    if(vm->vmgi == NULL || vm->vmgi->pgci_ut == NULL)
-      return 0;
-    else if(get_PGCIT(vm) && set_MENU(vm, menuid)) {
+    if(get_PGCIT(vm) && set_MENU(vm, menuid)) {
       process_command(vm, play_PGC(vm));
       return 1;  /* Jump */
     } else {
@@ -1437,8 +1441,9 @@ static int process_command(vm_t *vm, lin
       if(link_values.data2 != 0)
 	(vm->state).HL_BTNN_REG = link_values.data2 << 10;
       if(!set_VTS_PTT(vm, (vm->state).vtsN, (vm->state).VTS_TTN_REG, link_values.data1))
-	assert(0);
-      link_values = play_PG(vm);
+        link_values.command = Exit;
+      else
+        link_values = play_PG(vm);
       break;
     case LinkPGN:
       /* Link to Program Number:data1 */
@@ -1483,8 +1488,9 @@ static int process_command(vm_t *vm, lin
       /* Set SPRM1 and SPRM2 */
       assert((vm->state).domain == VTSM_DOMAIN || (vm->state).domain == VTS_DOMAIN); /* ?? */
       if(!set_VTS_TT(vm, (vm->state).vtsN, link_values.data1))
-	assert(0);
-      link_values = play_PGC(vm);
+        link_values.command = Exit;
+      else
+        link_values = play_PGC(vm);
       break;
     case JumpVTS_PTT:
       /* Jump to Part:data2 of Title:data1 in same VTS Title Domain */
@@ -1494,8 +1500,9 @@ static int process_command(vm_t *vm, lin
       /* Set SPRM1 and SPRM2 */
       assert((vm->state).domain == VTSM_DOMAIN || (vm->state).domain == VTS_DOMAIN); /* ?? */
       if(!set_VTS_PTT(vm, (vm->state).vtsN, link_values.data1, link_values.data2))
-	assert(0);
-      link_values = play_PGC_PG(vm, (vm->state).pgN);
+        link_values.command = Exit;
+      else
+        link_values = play_PGC_PG(vm, (vm->state).pgN);
       break;
 
     case JumpSS_FP:
@@ -1513,6 +1520,10 @@ static int process_command(vm_t *vm, lin
       /* Allowed from anywhere except the VTS Title domain */
       /* Stop SPRM9 Timer and any GPRM counters */
       assert((vm->state).domain != VTS_DOMAIN); /* ?? */
+      if(vm->vmgi == NULL || vm->vmgi->pgci_ut == NULL) {
+        link_values.command = Exit;
+        break;
+      }
       (vm->state).domain = VMGM_DOMAIN;
       if(!set_MENU(vm, link_values.data1))
 	assert(0);
@@ -1529,14 +1540,22 @@ static int process_command(vm_t *vm, lin
 	if (link_values.data1 != (vm->state).vtsN) {
 	  /* the normal case */
 	  assert((vm->state).domain == VMGM_DOMAIN || (vm->state).domain == FP_DOMAIN); /* ?? */
-	  (vm->state).domain = VTSM_DOMAIN;
 	  if (!ifoOpenNewVTSI(vm, vm->dvd, link_values.data1))  /* Also sets (vm->state).vtsN */
 	    assert(0);
+          if(vm->vtsi == NULL || vm->vtsi->pgci_ut == NULL) {
+            link_values.command = Exit;
+            break;
+          }
+	  (vm->state).domain = VTSM_DOMAIN;
 	} else {
 	  /* This happens on some discs like "Captain Scarlet & the Mysterons" or
 	   * the German RC2 of "Anatomie" in VTSM. */
 	  assert((vm->state).domain == VTSM_DOMAIN ||
 	    (vm->state).domain == VMGM_DOMAIN || (vm->state).domain == FP_DOMAIN); /* ?? */
+          if(vm->vtsi == NULL || vm->vtsi->pgci_ut == NULL) {
+            link_values.command = Exit;
+            break;
+          }
 	  (vm->state).domain = VTSM_DOMAIN;
 	}
       } else {
@@ -1558,6 +1577,10 @@ static int process_command(vm_t *vm, lin
       /* set_PGCN:data1 */
       /* Stop SPRM9 Timer and any GPRM counters */
       assert((vm->state).domain != VTS_DOMAIN); /* ?? */
+      if(vm->vmgi == NULL || vm->vmgi->pgci_ut == NULL) {
+        link_values.command = Exit;
+        break;
+      }
       (vm->state).domain = VMGM_DOMAIN;
       if(!set_PGCN(vm, link_values.data1))
 	assert(0);
@@ -1577,6 +1600,10 @@ static int process_command(vm_t *vm, lin
       /* set_RSMinfo:data2 */
       assert((vm->state).domain == VTS_DOMAIN); /* ?? */
       /* Must be called before domain is changed */
+      if(vm->vmgi == NULL || vm->vmgi->pgci_ut == NULL) {
+        link_values.command = Exit;
+        break;
+      }
       set_RSMinfo(vm, link_values.data2, /* We dont have block info */ 0);
       (vm->state).domain = VMGM_DOMAIN;
       if(!set_MENU(vm, link_values.data1))
@@ -1588,6 +1615,10 @@ static int process_command(vm_t *vm, lin
       /* set_RSMinfo:data2 */
       assert((vm->state).domain == VTS_DOMAIN); /* ?? */
       /* Must be called before domain is changed */
+      if(vm->vtsi == NULL || vm->vtsi->pgci_ut == NULL) {
+        link_values.command = Exit;
+        break;
+      }
       set_RSMinfo(vm, link_values.data2, /* We dont have block info */ 0);
       (vm->state).domain = VTSM_DOMAIN;
       if(!set_MENU(vm, link_values.data1))
@@ -1599,6 +1630,10 @@ static int process_command(vm_t *vm, lin
       /* set_RSMinfo:data2 */
       assert((vm->state).domain == VTS_DOMAIN); /* ?? */
       /* Must be called before domain is changed */
+      if(vm->vmgi == NULL || vm->vmgi->pgci_ut == NULL) {
+        link_values.command = Exit;
+        break;
+      }
       set_RSMinfo(vm, link_values.data2, /* We dont have block info */ 0);
       (vm->state).domain = VMGM_DOMAIN;
       if(!set_PGCN(vm, link_values.data1))
@@ -1659,7 +1694,9 @@ static int set_VTS_PTT(vm_t *vm, int vts
   (vm->state).TT_PGCN_REG = pgcN;
   (vm->state).PTTN_REG    = part;
   (vm->state).TTN_REG     = get_TT(vm, vtsN, vts_ttn);
-  assert( (vm->state.TTN_REG) != 0 );
+  if( (vm->state.TTN_REG) == 0 )
+    return 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? */


More information about the DVDnav-discuss mailing list