static void hb_dvdread_close( hb_dvd_t ** _d );
static char * hb_dvdread_name( char * path );
static int hb_dvdread_title_count( hb_dvd_t * d );
-static hb_title_t * hb_dvdread_title_scan( hb_dvd_t * d, int t );
+static hb_title_t * hb_dvdread_title_scan( hb_dvd_t * d, int t, uint64_t min_duration );
static int hb_dvdread_start( hb_dvd_t * d, hb_title_t *title, int chapter );
static void hb_dvdread_stop( hb_dvd_t * d );
static int hb_dvdread_seek( hb_dvd_t * d, float f );
/***********************************************************************
* hb_dvdread_title_scan
**********************************************************************/
-static hb_title_t * hb_dvdread_title_scan( hb_dvd_t * e, int t )
+static hb_title_t * hb_dvdread_title_scan( hb_dvd_t * e, int t, uint64_t min_duration )
{
hb_dvdread_t *d = &(e->dvdread);
d->cell_cur = d->cell_next;
}
- hb_log( "scan: vts=%d, ttn=%d, cells=%d->%d, blocks=%d->%d, "
- "%d blocks", title->vts, title->ttn, title->cell_start,
+ hb_log( "scan: vts=%d, ttn=%d, cells=%d->%d, blocks=%"PRIu64"->%"PRIu64", "
+ "%"PRIu64" blocks", title->vts, title->ttn, title->cell_start,
title->cell_end, title->block_start, title->block_end,
title->block_count );
/* ignore titles under 10 seconds because they're often stills or
* clips with no audio & our preview code doesn't currently handle
* either of these. */
- if( title->duration < 900000LL )
+ if( title->duration < min_duration )
{
hb_log( "scan: ignoring title (too short)" );
goto fail;
chapter->minutes = ( seconds % 3600 ) / 60;
chapter->seconds = seconds % 60;
- hb_log( "scan: chap %d c=%d->%d, b=%d->%d (%d), %"PRId64" ms",
+ hb_log( "scan: chap %d c=%d->%d, b=%"PRIu64"->%"PRIu64" (%"PRIu64"), %"PRId64" ms",
chapter->index, chapter->cell_start, chapter->cell_end,
chapter->block_start, chapter->block_end,
chapter->block_count, chapter->duration / 90 );
{
int block, pack_len, next_vobu, read_retry;
- for( read_retry = 0; read_retry < 3; read_retry++ )
+ for( read_retry = 1; read_retry < 1024; read_retry++ )
{
if( DVDReadBlocks( d->file, d->next_vobu, 1, b->data ) == 1 )
{
/*
* Successful read.
*/
+ if( read_retry > 1 && !is_nav_pack( b->data) )
+ {
+ // But wasn't a nav pack, so carry on looking
+ read_retry = 1;
+ d->next_vobu++;
+ continue;
+ }
break;
- } else {
- hb_log( "dvd: Read Error on blk %d, attempt %d",
- d->next_vobu, read_retry );
+ } else {
+ // First retry the same block, then try the next one,
+ // adjust the skip increment upwards so that we can skip
+ // large sections of bad blocks more efficiently (at the
+ // cost of some missed good blocks at the end).
+ hb_log( "dvd: vobu read error blk %d - skipping to next blk incr %d",
+ d->next_vobu, (read_retry * 10));
+ d->next_vobu += (read_retry * 10);
}
+
}
- if( read_retry == 3 )
+ if( read_retry == 1024 )
{
+ // That's too many bad blocks, jump to the start of the
+ // next cell.
hb_log( "dvd: vobu read error blk %d - skipping to cell %d",
d->next_vobu, d->cell_next );
d->cell_cur = d->cell_next;
hb_log("dvd: Lost sync, searching for NAV pack at blk %d",
d->next_vobu);
d->in_sync = 0;
- }
+ }
continue;
}
}
if( d->in_cell )
{
- hb_error( "dvd: assuming missed end of cell %d", d->cell_cur );
+ hb_error( "dvd: assuming missed end of cell %d at block %d", d->cell_cur, d->block );
d->cell_cur = d->cell_next;
d->next_vobu = d->pgc->cell_playback[d->cell_cur].first_sector;
FindNextCell( d );
return dvd_methods->title_count(d);
}
-hb_title_t * hb_dvd_title_scan( hb_dvd_t * d, int t )
+hb_title_t * hb_dvd_title_scan( hb_dvd_t * d, int t, uint64_t min_duration )
{
- return dvd_methods->title_scan(d, t);
+ return dvd_methods->title_scan(d, t, min_duration);
}
int hb_dvd_start( hb_dvd_t * d, hb_title_t *title, int chapter )