summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--contrib/libdvdnav/A05-forward-seek.patch70
-rw-r--r--libhb/dvdnav.c16
2 files changed, 85 insertions, 1 deletions
diff --git a/contrib/libdvdnav/A05-forward-seek.patch b/contrib/libdvdnav/A05-forward-seek.patch
new file mode 100644
index 000000000..aa4d37654
--- /dev/null
+++ b/contrib/libdvdnav/A05-forward-seek.patch
@@ -0,0 +1,70 @@
+diff -Naur libdvdnav.orig/src/searching.c libdvdnav/src/searching.c
+--- libdvdnav.orig/src/searching.c 2009-01-08 14:57:11.000000000 -0800
++++ libdvdnav/src/searching.c 2009-09-12 12:35:12.483551884 -0700
+@@ -47,7 +47,7 @@
+ /* Return placed in vobu. */
+ /* Returns error status */
+ /* FIXME: Maybe need to handle seeking outside current cell. */
+-static dvdnav_status_t dvdnav_scan_admap(dvdnav_t *this, int32_t domain, uint32_t seekto_block, uint32_t *vobu) {
++static dvdnav_status_t dvdnav_scan_admap(dvdnav_t *this, int32_t domain, uint32_t seekto_block, uint8_t next, uint32_t *vobu) {
+ vobu_admap_t *admap = NULL;
+
+ #ifdef LOG_DEBUG
+@@ -89,7 +89,10 @@
+ vobu_start = next_vobu;
+ address++;
+ }
+- *vobu = vobu_start;
++ if(next)
++ *vobu = next_vobu;
++ else
++ *vobu = vobu_start;
+ return DVDNAV_STATUS_OK;
+ }
+ fprintf(MSG_OUT, "libdvdnav: admap not located\n");
+@@ -160,7 +163,7 @@
+ fprintf(MSG_OUT, "libdvdnav: Seeking to cell %i from choice of %i to %i\n",
+ cell_nr, first_cell_nr, last_cell_nr);
+ #endif
+- if (dvdnav_scan_admap(this, state->domain, target, &vobu) == DVDNAV_STATUS_OK) {
++ if (dvdnav_scan_admap(this, state->domain, target, 0, &vobu) == DVDNAV_STATUS_OK) {
+ uint32_t start = state->pgc->cell_playback[cell_nr-1].first_sector;
+
+ if (vm_jump_cell_block(this->vm, cell_nr, vobu - start)) {
+@@ -270,6 +273,27 @@
+ } else {
+ /* convert the target sector from Cell-relative to absolute physical sector */
+ target += cell->first_sector;
++ if (origin == SEEK_CUR && offset > 0) {
++ uint32_t vobu;
++ /* if we are seeking forward from the current position, make sure
++ * we move to a new position that is after our current position.
++ * simply truncating to the vobu will go backwards */
++ if (dvdnav_scan_admap(this, state->domain, target, 1, &vobu) == DVDNAV_STATUS_OK) {
++ if (vobu > cell->last_sector) {
++ if (cell_nr == last_cell_nr) {
++ break;
++ } else {
++ cell_nr++;
++ cell = &(state->pgc->cell_playback[cell_nr-1]);
++ target = cell->first_sector;
++ }
++ } else {
++ target = vobu;
++ }
++ } else {
++ break;
++ }
++ }
+ found = 1;
+ break;
+ }
+@@ -281,7 +305,7 @@
+ fprintf(MSG_OUT, "libdvdnav: Seeking to cell %i from choice of %i to %i\n",
+ cell_nr, first_cell_nr, last_cell_nr);
+ #endif
+- if (dvdnav_scan_admap(this, state->domain, target, &vobu) == DVDNAV_STATUS_OK) {
++ if (dvdnav_scan_admap(this, state->domain, target, 0, &vobu) == DVDNAV_STATUS_OK) {
+ int32_t start = state->pgc->cell_playback[cell_nr-1].first_sector;
+
+ if (vm_jump_cell_block(this->vm, cell_nr, vobu - start)) {
diff --git a/libhb/dvdnav.c b/libhb/dvdnav.c
index 40587b7ed..4633f1cf6 100644
--- a/libhb/dvdnav.c
+++ b/libhb/dvdnav.c
@@ -982,6 +982,7 @@ static int hb_dvdnav_read( hb_dvd_t * e, hb_buffer_t * b )
hb_dvdnav_t * d = &(e->dvdnav);
int result, event, len;
int chapter = 0;
+ int error_count = 0;
while ( 1 )
{
@@ -993,8 +994,21 @@ static int hb_dvdnav_read( hb_dvd_t * e, hb_buffer_t * b )
if ( result == DVDNAV_STATUS_ERR )
{
hb_log("dvdnav: Read Error, %s", dvdnav_err_to_string(d->dvdnav));
- return 0;
+ if (dvdnav_sector_search(d->dvdnav, 1, SEEK_CUR) != DVDNAV_STATUS_OK)
+ {
+ hb_error( "dvd: dvdnav_sector_search failed - %s",
+ dvdnav_err_to_string(d->dvdnav) );
+ return 0;
+ }
+ error_count++;
+ if (error_count > 10)
+ {
+ hb_log("dvdnav: Error, too many consecutive read errors");
+ return 0;
+ }
+ continue;
}
+ error_count = 0;
switch ( event )
{
case DVDNAV_BLOCK_OK: