Here are the patches in my tree for libdvdnav. Many of these patches
came from submissions to the mailing list. I intend to push these
patches to svn in short amount of time. But I would like to test them
a bit longer and try to get you to review them.

If you authored any of these patches you should be able to recognize them.
If you don't, let me know - there should be proper attribution in the patch
and the look of the patch should not change much at all.

Thanks

E

-- 
Erik Hovland
[email protected]
http://hovland.org/
From aca45e68882648851f0935056262bf9dc1bad007 Mon Sep 17 00:00:00 2001
From: Erik Hovland <[email protected]>
Date: Mon, 10 Oct 2011 14:47:59 -0700
Subject: [PATCH 01/17] Return 0 instead of an assert

---
 src/vm/vm.c |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/src/vm/vm.c b/src/vm/vm.c
index a6b6dae..95f67e3 100644
--- a/src/vm/vm.c
+++ b/src/vm/vm.c
@@ -1762,7 +1762,8 @@ static int set_PGCN(vm_t *vm, int pgcN) {
   pgcit_t *pgcit;
 
   pgcit = get_PGCIT(vm);
-  assert(pgcit != NULL);  /* ?? Make this return -1 instead */
+  if (pgcit == NULL)
+    return 0;
 
   if(pgcN < 1 || pgcN > pgcit->nr_of_pgci_srp) {
 #ifdef TRACE
-- 
1.7.5.4

From b84378c1fa980d6e24ae782913197f856915cea0 Mon Sep 17 00:00:00 2001
From: Erik Hovland <[email protected]>
Date: Thu, 24 Jun 2010 15:50:46 -0700
Subject: [PATCH 02/17] Pointer validation fixing

The files in question lack pointer checking in some way.
---
 src/highlight.c |   13 +++++++++++--
 src/remap.c     |   20 ++++++++++++++++----
 src/vm/vm.c     |    3 +--
 3 files changed, 28 insertions(+), 8 deletions(-)

diff --git a/src/highlight.c b/src/highlight.c
index f484357..eed913b 100644
--- a/src/highlight.c
+++ b/src/highlight.c
@@ -242,8 +242,13 @@ static btni_t *get_current_button(dvdnav_t *this, pci_t *pci) {
 }
 
 static dvdnav_status_t button_auto_action(dvdnav_t *this, pci_t *pci) {
-  if (get_current_button(this, pci)->auto_action_mode)
+  btni_t *button_ptr;
+  if ((button_ptr = get_current_button(this, pci)) == NULL)
+      return DVDNAV_STATUS_ERR;
+
+  if (button_ptr->auto_action_mode)
     return dvdnav_button_activate(this, pci);
+
   return DVDNAV_STATUS_OK;
 }
 
@@ -366,7 +371,11 @@ dvdnav_status_t dvdnav_button_activate(dvdnav_t *this, pci_t *pci) {
     return DVDNAV_STATUS_ERR;
   }
 
-  button_ptr = get_current_button(this, pci);
+  if ((button_ptr = get_current_button(this, pci)) == NULL) {
+    pthread_mutex_unlock(&this->vm_lock);
+    return DVDNAV_STATUS_ERR;
+  }
+
   /* Finally, make the VM execute the appropriate code and probably
    * schedule a jump */
 #ifdef BUTTON_TESTING
diff --git a/src/remap.c b/src/remap.c
index f1dea93..e8e888e 100644
--- a/src/remap.c
+++ b/src/remap.c
@@ -62,6 +62,9 @@ struct remap_s {
 
 static remap_t* remap_new( char *title) {
     remap_t *map = malloc( sizeof(remap_t));
+    if (map == NULL)
+	return NULL;
+
     map->title = strdup(title);
     map->maxblocks = 0;
     map->nblocks = 0;
@@ -139,8 +142,10 @@ static void remap_add_node( remap_t *map, block_t block) {
     } else {
         /* new block */
 	if (map->nblocks >= map->maxblocks) {
+	    if ((map->blocks = realloc( map->blocks, sizeof( block_t)*( map->maxblocks + 20))) == NULL)
+		return;
+
 	    map->maxblocks += 20;
-	    map->blocks = realloc( map->blocks, sizeof( block_t)*map->maxblocks);
 	}
 	n = map->nblocks++;
 	while (n > 0 && compare_block( &block, &map->blocks[ n-1]) < 0) {
@@ -158,7 +163,9 @@ static int parseblock(char *buf, int *dom, int *tt, int *pg,
     char *epos;
     char *marker[]={"domain", "title", "program", "start", "end"};
     int st = 0;
-    tok = strtok( buf, " ");
+    if ((tok = strtok( buf, " ")) == NULL)
+        return st;
+
     while (st < 5) {
         if (strcmp(tok, marker[st])) return -st-1000;
         tok = strtok( NULL, " ");
@@ -183,7 +190,7 @@ static int parseblock(char *buf, int *dom, int *tt, int *pg,
 		break;
 	}
 	st++;
-        tok = strtok( NULL, " ");
+        if (!(tok = strtok( NULL, " "))) return -st-2000;
     }
     return st;
 }
@@ -214,7 +221,12 @@ remap_t* remap_loadmap( char *title) {
     }
 
     /* Load the map file */
-    map = remap_new( title);
+    if ((map = remap_new( title)) == NULL) {
+	fprintf(MSG_OUT, "libdvdnav: Unable to load map '%s'\n", title);
+        fclose(fp);
+	return NULL;
+    }
+
     while (fgets( buf, sizeof(buf), fp) != NULL) {
         if (buf[0] == '\n' || buf[0] == '#' || buf[0] == 0) continue;
         if (strncasecmp( buf, "debug", 5) == 0) {
diff --git a/src/vm/vm.c b/src/vm/vm.c
index 95f67e3..007a7d0 100644
--- a/src/vm/vm.c
+++ b/src/vm/vm.c
@@ -171,8 +171,7 @@ static void dvd_read_name(char *name, char *serial, const char *device) {
     uint8_t data[DVD_VIDEO_LB_LEN];
 
     /* Read DVD name */
-    fd = open(device, O_RDONLY);
-    if (fd > 0) {
+    if (device && (fd = open(device, O_RDONLY)) > 0) {
       off = lseek( fd, 32 * (off_t) DVD_VIDEO_LB_LEN, SEEK_SET );
       if( off == ( 32 * (off_t) DVD_VIDEO_LB_LEN ) ) {
         off = read( fd, data, DVD_VIDEO_LB_LEN );
-- 
1.7.5.4

From de6248347e094b8a97bee835b87411a02e9be559 Mon Sep 17 00:00:00 2001
From: Erik Hovland <[email protected]>
Date: Tue, 23 Nov 2010 15:38:58 -0800
Subject: [PATCH 03/17] Initialize epos

---
 src/remap.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/src/remap.c b/src/remap.c
index e8e888e..9bbf192 100644
--- a/src/remap.c
+++ b/src/remap.c
@@ -160,7 +160,7 @@ static int parseblock(char *buf, int *dom, int *tt, int *pg,
 		      unsigned long *start, unsigned long *end) {
     long tmp;
     char *tok;
-    char *epos;
+    char *epos = NULL;
     char *marker[]={"domain", "title", "program", "start", "end"};
     int st = 0;
     if ((tok = strtok( buf, " ")) == NULL)
-- 
1.7.5.4

From eb91fb74680d30322461a1b9e425918ad4e2b2df Mon Sep 17 00:00:00 2001
From: Erik Hovland <[email protected]>
Date: Mon, 10 Oct 2011 11:08:03 -0700
Subject: [PATCH 04/17] Always check whether a still is being handled.

When a new cell is encountered dvdnav indicates it should wait
for sync. However it does not advance to the next cell. Instead it
assumes that there are only still frames. By removing the else
part of the if clause dvdnav will always at least advance to the
next cell because it is no longer assuming that it is on a still
---
 src/dvdnav.c |    3 +--
 1 files changed, 1 insertions(+), 2 deletions(-)

diff --git a/src/dvdnav.c b/src/dvdnav.c
index 4d0b4f1..c849b18 100644
--- a/src/dvdnav.c
+++ b/src/dvdnav.c
@@ -733,7 +733,7 @@ dvdnav_status_t dvdnav_get_next_cache_block(dvdnav_t *this, uint8_t **buf,
        * otherwise it might show stills or menus too shortly */
       if ((this->position_current.still || this->pci.hli.hl_gi.hli_ss) && !this->sync_wait_skip) {
         this->sync_wait = 1;
-      } else {
+      }
 	if( this->position_current.still == 0 || this->skip_still ) {
 	  /* no active cell still -> get us to the next cell */
 	  vm_get_next_cell(this->vm);
@@ -741,7 +741,6 @@ dvdnav_status_t dvdnav_get_next_cache_block(dvdnav_t *this, uint8_t **buf,
 	  this->skip_still = 0;
 	  this->sync_wait_skip = 0;
 	}
-      }
       /* handle related state changes in next iteration */
       (*event) = DVDNAV_NOP;
       (*len) = 0;
-- 
1.7.5.4

From faf1165d443295c9604c71c748e76c64a060bc3d Mon Sep 17 00:00:00 2001
From: Erik Hovland <[email protected]>
Date: Mon, 10 Oct 2011 11:12:50 -0700
Subject: [PATCH 05/17] Reformat for proper indentation

---
 src/dvdnav.c |   16 ++++++++--------
 1 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/src/dvdnav.c b/src/dvdnav.c
index c849b18..e054e3f 100644
--- a/src/dvdnav.c
+++ b/src/dvdnav.c
@@ -731,16 +731,16 @@ dvdnav_status_t dvdnav_get_next_cache_block(dvdnav_t *this, uint8_t **buf,
       /* we are about to leave a cell, so a lot of state changes could occur;
        * under certain conditions, the application should get in sync with us before this,
        * otherwise it might show stills or menus too shortly */
-      if ((this->position_current.still || this->pci.hli.hl_gi.hli_ss) && !this->sync_wait_skip) {
+      if ((this->position_current.still || this->pci.hli.hl_gi.hli_ss) && !this->sync_wait_skip)
         this->sync_wait = 1;
+
+      if( this->position_current.still == 0 || this->skip_still ) {
+	/* no active cell still -> get us to the next cell */
+	vm_get_next_cell(this->vm);
+	this->position_current.still = 0; /* still gets activated at end of cell */
+	this->skip_still = 0;
+	this->sync_wait_skip = 0;
       }
-	if( this->position_current.still == 0 || this->skip_still ) {
-	  /* no active cell still -> get us to the next cell */
-	  vm_get_next_cell(this->vm);
-	  this->position_current.still = 0; /* still gets activated at end of cell */
-	  this->skip_still = 0;
-	  this->sync_wait_skip = 0;
-	}
       /* handle related state changes in next iteration */
       (*event) = DVDNAV_NOP;
       (*len) = 0;
-- 
1.7.5.4

From ea573c6069348aca7bdf2e32b3e4c56c4e60aba0 Mon Sep 17 00:00:00 2001
From: Erik Hovland <[email protected]>
Date: Mon, 10 Oct 2011 11:19:55 -0700
Subject: [PATCH 06/17] Test still like a boolean value and not an integer
 value

---
 src/dvdnav.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/src/dvdnav.c b/src/dvdnav.c
index e054e3f..e82df12 100644
--- a/src/dvdnav.c
+++ b/src/dvdnav.c
@@ -734,7 +734,7 @@ dvdnav_status_t dvdnav_get_next_cache_block(dvdnav_t *this, uint8_t **buf,
       if ((this->position_current.still || this->pci.hli.hl_gi.hli_ss) && !this->sync_wait_skip)
         this->sync_wait = 1;
 
-      if( this->position_current.still == 0 || this->skip_still ) {
+      if(!this->position_current.still || this->skip_still ) {
 	/* no active cell still -> get us to the next cell */
 	vm_get_next_cell(this->vm);
 	this->position_current.still = 0; /* still gets activated at end of cell */
-- 
1.7.5.4

From 976df31f2eb082ac6fba10748d4855564d8c4d08 Mon Sep 17 00:00:00 2001
From: Erik Hovland <[email protected]>
Date: Mon, 10 Oct 2011 11:21:18 -0700
Subject: [PATCH 07/17] Remove commented out asserts

---
 src/vm/vm.c |    9 ---------
 1 files changed, 0 insertions(+), 9 deletions(-)

diff --git a/src/vm/vm.c b/src/vm/vm.c
index 007a7d0..57173e7 100644
--- a/src/vm/vm.c
+++ b/src/vm/vm.c
@@ -1186,15 +1186,6 @@ static link_t play_Cell_post(vm_t *vm) {
   if(cell->cell_cmd_nr != 0) {
     link_t link_values;
 
-/*  These asserts are now not needed.
- *  Some DVDs have no cell commands listed in the PGC,
- *  but the Cell itself points to a cell command that does not exist.
- *  For this situation, just ignore the cell command and continue.
- *
- *  assert((vm->state).pgc->command_tbl != NULL);
- *  assert((vm->state).pgc->command_tbl->nr_of_cell >= cell->cell_cmd_nr);
- */
-
     if ((vm->state).pgc->command_tbl != NULL &&
         (vm->state).pgc->command_tbl->nr_of_cell >= cell->cell_cmd_nr) {
 #ifdef TRACE
-- 
1.7.5.4

From 960e8b3f213bd487c18962be2f26cfa6217e60de Mon Sep 17 00:00:00 2001
From: Erik Hovland <[email protected]>
Date: Mon, 31 Oct 2011 13:35:27 -0700
Subject: [PATCH 08/17] Initialize link_values

---
 src/vm/vm.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/src/vm/vm.c b/src/vm/vm.c
index 57173e7..13c006f 100644
--- a/src/vm/vm.c
+++ b/src/vm/vm.c
@@ -1049,7 +1049,7 @@ static link_t play_PGC_PG(vm_t *vm, int pgN) {
 }
 
 static link_t play_PGC_post(vm_t *vm) {
-  link_t link_values;
+  link_t link_values = { LinkNoLink, 0, 0, 0 };
 
 #ifdef TRACE
   fprintf(MSG_OUT, "libdvdnav: play_PGC_post:\n");
-- 
1.7.5.4

From 2c35cb5c1852f49e5fa3372eb55e8be0155bc139 Mon Sep 17 00:00:00 2001
From: Erik Hovland <[email protected]>
Date: Mon, 31 Oct 2011 13:45:15 -0700
Subject: [PATCH 09/17] Remove unused variable and its assignment

---
 src/vm/vm.c |    2 --
 1 files changed, 0 insertions(+), 2 deletions(-)

diff --git a/src/vm/vm.c b/src/vm/vm.c
index 13c006f..cf32e99 100644
--- a/src/vm/vm.c
+++ b/src/vm/vm.c
@@ -1788,10 +1788,8 @@ static int set_PGN(vm_t *vm) {
   (vm->state).pgN = new_pgN;
 
   if((vm->state).domain == VTS_DOMAIN) {
-    playback_type_t *pb_ty;
     if((vm->state).TTN_REG > vm->vmgi->tt_srpt->nr_of_srpts)
       return 0; /* ?? */
-    pb_ty = &vm->vmgi->tt_srpt->title[(vm->state).TTN_REG - 1].pb_ty;
       vm_get_current_title_part(vm, &dummy, &part);
       (vm->state).PTTN_REG = part;
   }
-- 
1.7.5.4

From 309c10c6d37fa9f36162b4b76cb0cef1500ecdab Mon Sep 17 00:00:00 2001
From: Erik Hovland <[email protected]>
Date: Mon, 31 Oct 2011 13:46:03 -0700
Subject: [PATCH 10/17] Reindent a couple of lines to make them more readable

---
 src/vm/vm.c |    5 +++--
 1 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/src/vm/vm.c b/src/vm/vm.c
index cf32e99..d40ab61 100644
--- a/src/vm/vm.c
+++ b/src/vm/vm.c
@@ -1790,8 +1790,9 @@ static int set_PGN(vm_t *vm) {
   if((vm->state).domain == VTS_DOMAIN) {
     if((vm->state).TTN_REG > vm->vmgi->tt_srpt->nr_of_srpts)
       return 0; /* ?? */
-      vm_get_current_title_part(vm, &dummy, &part);
-      (vm->state).PTTN_REG = part;
+
+    vm_get_current_title_part(vm, &dummy, &part);
+    (vm->state).PTTN_REG = part;
   }
   return 1;
 }
-- 
1.7.5.4

From 4688d5856cfd781bd67ff0c73bb65713f9c381e2 Mon Sep 17 00:00:00 2001
From: Erik Hovland <[email protected]>
Date: Mon, 31 Oct 2011 13:57:03 -0700
Subject: [PATCH 11/17] Replace assert w/ a conditional and a null return

---
 src/vm/vm.c |    9 ++++++++-
 1 files changed, 8 insertions(+), 1 deletions(-)

diff --git a/src/vm/vm.c b/src/vm/vm.c
index d40ab61..2a5f057 100644
--- a/src/vm/vm.c
+++ b/src/vm/vm.c
@@ -413,7 +413,8 @@ vm_t *vm_new_copy(vm_t *source) {
   int pgcN = get_PGCN(source);
   int pgN  = (source->state).pgN;
 
-  assert(pgcN);
+  if (target == NULL || pgcN == 0)
+    goto fail;
 
   memcpy(target, source, sizeof(vm_t));
 
@@ -432,6 +433,12 @@ vm_t *vm_new_copy(vm_t *source) {
   }
 
   return target;
+
+fail:
+  if (target != NULL)
+    vm_free_vm(target);
+
+  return NULL;
 }
 
 void vm_merge(vm_t *target, vm_t *source) {
-- 
1.7.5.4

From c1e241ed2b596d8b1a59570d05f66713849a1641 Mon Sep 17 00:00:00 2001
From: Erik Hovland <[email protected]>
Date: Mon, 31 Oct 2011 13:58:06 -0700
Subject: [PATCH 12/17] Replace assert w/ a conditional and a null return

---
 src/vm/vm.c |    5 +++--
 1 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/src/vm/vm.c b/src/vm/vm.c
index 2a5f057..fb09a86 100644
--- a/src/vm/vm.c
+++ b/src/vm/vm.c
@@ -424,11 +424,12 @@ vm_t *vm_new_copy(vm_t *source) {
   if (vtsN > 0) {
     (target->state).vtsN = 0;
     if (!ifoOpenNewVTSI(target, target->dvd, vtsN))
-      assert(0);
+      goto fail;
 
     /* restore pgc pointer into the new vtsi */
     if (!set_PGCN(target, pgcN))
-      assert(0);
+      goto fail;
+
     (target->state).pgN = pgN;
   }
 
-- 
1.7.5.4

From 6490f51b9858a38ac939f6674178d9aa833bd696 Mon Sep 17 00:00:00 2001
From: Erik Hovland <[email protected]>
Date: Mon, 31 Oct 2011 14:07:19 -0700
Subject: [PATCH 13/17] Rework functions that call vm_copy_vm()

Once vm_new_vm() can return NULL and doesn't assert then the functions
that call vm_copy_vm() need to be able to handle this issue.
---
 src/searching.c |   34 ++++++++++++++++++++++++++--------
 1 files changed, 26 insertions(+), 8 deletions(-)

diff --git a/src/searching.c b/src/searching.c
index 66f7adb..f767cb5 100644
--- a/src/searching.c
+++ b/src/searching.c
@@ -403,8 +403,7 @@ dvdnav_status_t dvdnav_next_pg_search(dvdnav_t *this) {
   pthread_mutex_lock(&this->vm_lock);
   if(!this->vm->state.pgc) {
     printerr("No current PGC.");
-    pthread_mutex_unlock(&this->vm_lock);
-    return DVDNAV_STATUS_ERR;
+    goto fail;
   }
 
 #ifdef LOG_DEBUG
@@ -412,17 +411,25 @@ dvdnav_status_t dvdnav_next_pg_search(dvdnav_t *this) {
 #endif
   /* make a copy of current VM and try to navigate the copy to the next PG */
   try_vm = vm_new_copy(this->vm);
+  if (try_vm == NULL) {
+    printerr("Unable to copy the VM.");
+    goto fail;
+  }
+
   if (!vm_jump_next_pg(try_vm) || try_vm->stopped) {
     vm_free_copy(try_vm);
     /* next_pg failed, try to jump at least to the next cell */
     try_vm = vm_new_copy(this->vm);
+    if (try_vm == NULL) {
+      printerr("Unable to copy the VM.");
+      goto fail;
+    }
     vm_get_next_cell(try_vm);
     if (try_vm->stopped) {
       vm_free_copy(try_vm);
       fprintf(MSG_OUT, "libdvdnav: next chapter failed.\n");
       printerr("Skip to next chapter failed.");
-      pthread_mutex_unlock(&this->vm_lock);
-      return DVDNAV_STATUS_ERR;
+      goto fail;
     }
   }
   this->cur_cell_time = 0;
@@ -437,6 +444,10 @@ dvdnav_status_t dvdnav_next_pg_search(dvdnav_t *this) {
   pthread_mutex_unlock(&this->vm_lock);
 
   return DVDNAV_STATUS_OK;
+
+fail:
+  pthread_mutex_unlock(&this->vm_lock);
+  return DVDNAV_STATUS_ERR;
 }
 
 dvdnav_status_t dvdnav_menu_call(dvdnav_t *this, DVDMenuID_t menu) {
@@ -445,13 +456,17 @@ dvdnav_status_t dvdnav_menu_call(dvdnav_t *this, DVDMenuID_t menu) {
   pthread_mutex_lock(&this->vm_lock);
   if(!this->vm->state.pgc) {
     printerr("No current PGC.");
-    pthread_mutex_unlock(&this->vm_lock);
-    return DVDNAV_STATUS_ERR;
+    goto fail;
   }
 
   this->cur_cell_time = 0;
   /* make a copy of current VM and try to navigate the copy to the menu */
   try_vm = vm_new_copy(this->vm);
+  if (try_vm == NULL) {
+    printerr("Unable to copy VM.");
+    goto fail;
+  }
+
   if ( (menu == DVD_MENU_Escape) && (this->vm->state.domain != VTS_DOMAIN)) {
     /* Try resume */
     if (vm_jump_resume(try_vm) && !try_vm->stopped) {
@@ -477,9 +492,12 @@ dvdnav_status_t dvdnav_menu_call(dvdnav_t *this, DVDMenuID_t menu) {
   } else {
     vm_free_copy(try_vm);
     printerr("No such menu or menu not reachable.");
-    pthread_mutex_unlock(&this->vm_lock);
-    return DVDNAV_STATUS_ERR;
+    goto fail;
   }
+
+fail:
+  pthread_mutex_unlock(&this->vm_lock);
+  return DVDNAV_STATUS_ERR;
 }
 
 dvdnav_status_t dvdnav_get_position(dvdnav_t *this, uint32_t *pos,
-- 
1.7.5.4

From 6d08539aa468a3ab3882f8072d4cf84505f9b8fc Mon Sep 17 00:00:00 2001
From: Erik Hovland <[email protected]>
Date: Mon, 31 Oct 2011 14:09:01 -0700
Subject: [PATCH 14/17] Initialize next_vobu.

It is possible (although unlikely) that the while loop will
never execute and next_vobu will be uninitialized at this point.
---
 src/searching.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/src/searching.c b/src/searching.c
index f767cb5..3649e9d 100644
--- a/src/searching.c
+++ b/src/searching.c
@@ -73,7 +73,7 @@ static dvdnav_status_t dvdnav_scan_admap(dvdnav_t *this, int32_t domain, uint32_
   }
   if(admap) {
     uint32_t address = 0;
-    uint32_t vobu_start, next_vobu;
+    uint32_t vobu_start, next_vobu = 0;
     int admap_entries = (admap->last_byte + 1 - VOBU_ADMAP_SIZE)/VOBU_ADMAP_SIZE;
 
     /* Search through ADMAP for best sector */
-- 
1.7.5.4

From 2905259c3b45529b3d8dedba572b6e4f67a2d8f4 Mon Sep 17 00:00:00 2001
From: Erik Hovland <[email protected]>
Date: Wed, 2 Nov 2011 15:08:12 -0700
Subject: [PATCH 15/17] Bit fields for ILVU

---
 src/dvdnav_internal.h |    8 ++++++++
 1 files changed, 8 insertions(+), 0 deletions(-)

diff --git a/src/dvdnav_internal.h b/src/dvdnav_internal.h
index e78470d..089ab14 100644
--- a/src/dvdnav_internal.h
+++ b/src/dvdnav_internal.h
@@ -76,6 +76,14 @@ static inline int _private_gettimeofday( struct timeval *tv, void *tz )
 #define DVD_VIDEO_LB_LEN 2048
 #endif
 
+typedef enum {
+  DSI_ILVU_PRE   = 1 << 15, /* set during the last 3 VOBU preceeding an interleaved block. */
+  DSI_ILVU_BLOCK = 1 << 14, /* set for all VOBU in an interleaved block */
+  DSI_ILVU_FIRST = 1 << 13, /* set for the first VOBU for a given angle or scene within a ILVU, or the first VOBU in the preparation (PREU) sequence */
+  DSI_ILVU_LAST  = 1 << 12, /* set for the last VOBU for a given angle or scene within a ILVU, or the last VOBU in the preparation (PREU) sequence */
+  DSI_ILVU_MASK  = 0xf000
+} DSI_ILVU;
+
 typedef struct read_cache_s read_cache_t;
 
 /*
-- 
1.7.5.4

From 83f1c9256f500285e46f1e44bcc74ffce90159db Mon Sep 17 00:00:00 2001
From: Erik Hovland <[email protected]>
Date: Wed, 2 Nov 2011 15:08:28 -0700
Subject: [PATCH 16/17] Make sure we get nav packets for all cells in multi
 angle features

Currently libdvdnav uses the ILVU information to specify where a vobunit
ends if a feature is multiangled. However since one ILVU can contain
multiple vobunits, this means that libdvdnav never generates NAV events nor
updates highlight information for anything but the first vobunit in the
ILVU. It also causes issues for any player relying on timestamps in nav
packets to flatten the mpeg timestamps.

Patch kindly submitted by Joakim Plate <elupus AT ecce DOT se>. Thanks!
---
 src/dvdnav.c |    5 +++--
 1 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/src/dvdnav.c b/src/dvdnav.c
index e82df12..40d44c7 100644
--- a/src/dvdnav.c
+++ b/src/dvdnav.c
@@ -336,8 +336,9 @@ static int32_t dvdnav_get_vobu(dvdnav_t *this, dsi_t *nav_dsi, pci_t *nav_pci, d
     dvdnav_angle_change(this, 1);
   }
 #endif
-
-  if(num_angle != 0) {
+  /* only use ILVU information if we are at the last vobunit in ILVU */
+  /* otherwise we will miss nav packets from vobunits inbetween */
+  if(num_angle != 0 && (nav_dsi->sml_pbi.category & DSI_ILVU_MASK) == (DSI_ILVU_BLOCK | DSI_ILVU_LAST)) {
 
     if((next = nav_pci->nsml_agli.nsml_agl_dsta[angle-1]) != 0) {
       if((next & 0x3fffffff) != 0) {
-- 
1.7.5.4

From 8e993efd24f5e698ad4550d5b6bc183b8662977f Mon Sep 17 00:00:00 2001
From: Erik Hovland <[email protected]>
Date: Sat, 12 Nov 2011 12:15:44 -0800
Subject: [PATCH 17/17] Remove unneeded address-of of CLUT

The CLUT that is copied in from struct variable palette is an
array of 16 values. So the &(palette) is unnecessary. The size
argument was also changed to use the palette array instead of
the type (just in case palette ever gets changed).

Thanks goes to Lee Essen who originally submitted the patch
way back in 2008 and to Roger Pack who brought the patch to
our attention recently.
---
 src/dvdnav.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/src/dvdnav.c b/src/dvdnav.c
index 40d44c7..9f24e3e 100644
--- a/src/dvdnav.c
+++ b/src/dvdnav.c
@@ -656,7 +656,7 @@ dvdnav_status_t dvdnav_get_next_cache_block(dvdnav_t *this, uint8_t **buf,
     fprintf(MSG_OUT, "libdvdnav: SPU_CLUT_CHANGE\n");
 #endif
     (*len) = 16 * sizeof(uint32_t);
-    memcpy(*buf, &(state->pgc->palette), 16 * sizeof(uint32_t));
+    memcpy(*buf, state->pgc->palette, sizeof(state->pgc->palette));
     this->spu_clut_changed = 0;
     pthread_mutex_unlock(&this->vm_lock);
     return DVDNAV_STATUS_OK;
-- 
1.7.5.4

_______________________________________________
DVDnav-discuss mailing list
[email protected]
https://lists.mplayerhq.hu/mailman/listinfo/dvdnav-discuss

Reply via email to