demux_mkv: better seeking after video end

This change allows forward seeking even if there are no more video
keyframes in forward direction. This helps with files that e.g. encode
cover art as a single video frame (within a _real_ video stream - ffmpeg
seems to like to produce such files). Seeking backwards will still jump
to the nearest video frame, so this improvement has limited use.

The old code didn't do this because of the logic the min_diff variable
followed. Instead of somehow using the timestamp of the last packet read
for min_diff, use the first index entry for it. This actually makes it
fall back to the first/last index entry as the (removed) comment claims.

Note that last_pts is basically random at this point (because the
demuxer can be far ahead of playback position), so this didn't make
sense in the first place.
This commit is contained in:
wm4 2015-04-23 15:27:04 +02:00
parent daabbe3640
commit 457e2f7e02
1 changed files with 7 additions and 15 deletions

View File

@ -2625,17 +2625,7 @@ static struct mkv_index *seek_with_cues(struct demuxer *demuxer, int seek_id,
struct mkv_demuxer *mkv_d = demuxer->priv;
struct mkv_index *index = NULL;
/* Find the entry in the index closest to the target timecode in the
* give direction. If there are no such entries - we're trying to seek
* backward from a target time before the first entry or forward from a
* target time after the last entry - then still seek to the first/last
* entry if that's further in the direction wanted than mkv_d->last_pts.
*/
int64_t min_diff = target_timecode - (int64_t)(mkv_d->last_pts * 1e9 + 0.5);
if (flags & SEEK_BACKWARD)
min_diff = -min_diff;
min_diff = FFMAX(min_diff, 1);
int64_t min_diff = INT64_MIN;
for (size_t i = 0; i < mkv_d->num_indexes; i++) {
if (seek_id < 0 || mkv_d->indexes[i].tnum == seek_id) {
int64_t diff =
@ -2643,11 +2633,13 @@ static struct mkv_index *seek_with_cues(struct demuxer *demuxer, int seek_id,
(int64_t) (mkv_d->indexes[i].timecode * mkv_d->tc_scale);
if (flags & SEEK_BACKWARD)
diff = -diff;
if (diff <= 0) {
if (min_diff <= 0 && diff <= min_diff)
if (min_diff != INT64_MIN) {
if (diff <= 0) {
if (min_diff <= 0 && diff <= min_diff)
continue;
} else if (diff >= min_diff)
continue;
} else if (diff >= min_diff)
continue;
}
min_diff = diff;
index = mkv_d->indexes + i;
}