From c89c057ec2e7601f885aafb830732385ece5c59d Mon Sep 17 00:00:00 2001 From: jstebbins Date: Mon, 11 Aug 2014 18:05:36 +0000 Subject: libhb: Sanitize BD chapter durations It appears some BDs have invalid chapter durations, see https://forum.handbrake.fr/viewtopic.php?f=12&t=30479 This compares chapter start time deltas and title duration to chapter duration to make best guess corrections. Note that chapter events generated by libbluray are based on the chapter start times. So the start time should be trusted more than the duration. git-svn-id: svn://svn.handbrake.fr/HandBrake/trunk@6292 b64f7644-9d1e-0410-96f1-a4d463321fa5 --- libhb/bd.c | 45 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 43 insertions(+), 2 deletions(-) (limited to 'libhb/bd.c') diff --git a/libhb/bd.c b/libhb/bd.c index 75f2b138f..6cef95609 100644 --- a/libhb/bd.c +++ b/libhb/bd.c @@ -491,18 +491,59 @@ hb_title_t * hb_bd_title_scan( hb_bd_t * d, int tt, uint64_t min_duration ) } /* Chapters */ - for ( ii = 0; ii < ti->chapter_count; ii++ ) + for ( ii = 0, jj = 0; ii < ti->chapter_count; ii++ ) { char chapter_title[80]; + + // Sanity check start time of this chapter. + // If it is beyond the end of the title, drop it. + if (ti->chapters[ii].start > ti->duration) + { + hb_log("bd: chapter %d invalid start %ld, dropping", ii+1, + ti->chapters[ii].start); + continue; + } + chapter = calloc( sizeof( hb_chapter_t ), 1 ); - chapter->index = ii + 1; + chapter->index = ++jj; sprintf( chapter_title, "Chapter %d", chapter->index ); hb_chapter_set_title( chapter, chapter_title ); chapter->duration = ti->chapters[ii].duration; chapter->block_start = ti->chapters[ii].offset; + // Sanity check chapter duration and start times + // Have seen some invalid durations in the wild + if (ii < ti->chapter_count - 1) + { + // Validate start time + if (ti->chapters[ii+1].start < ti->chapters[ii].start) + { + hb_log("bd: chapter %d invalid start %ld", ii+1, + ti->chapters[ii+1].start); + ti->chapters[ii+1].start = ti->chapters[ii].start + + chapter->duration; + } + if (ti->chapters[ii+1].start - ti->chapters[ii].start != + chapter->duration) + { + hb_log("bd: chapter %d invalid duration %ld", ii+1, + chapter->duration); + chapter->duration = ti->chapters[ii+1].start - + ti->chapters[ii].start; + } + } + else + { + if (ti->duration - ti->chapters[ii].start != chapter->duration) + { + hb_log("bd: chapter %d invalid duration %ld", ii+1, + chapter->duration); + chapter->duration = ti->duration - ti->chapters[ii].start; + } + } + int seconds = ( chapter->duration + 45000 ) / 90000; chapter->hours = ( seconds / 3600 ); chapter->minutes = ( seconds % 3600 ) / 60; -- cgit v1.2.3