diff options
-rw-r--r-- | contrib/libdvdnav/A05-forward-seek.patch | 70 | ||||
-rw-r--r-- | libhb/dvdnav.c | 16 |
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: |