From b55b9cb98cf76443a24c7f7deae5853a4151e86d Mon Sep 17 00:00:00 2001 From: wm4 Date: Sun, 7 Jul 2019 17:40:33 +0200 Subject: demux: move a seek helper to a separate function It makes some slight sense and helps with one of the following commits. Also rename that other function to make it sound less similar to find_seek_target(). --- demux/demux.c | 82 ++++++++++++++++++++++++++++++++++------------------------- 1 file changed, 47 insertions(+), 35 deletions(-) (limited to 'demux/demux.c') diff --git a/demux/demux.c b/demux/demux.c index 2056c12d11..8195e5bd17 100644 --- a/demux/demux.c +++ b/demux/demux.c @@ -3461,9 +3461,10 @@ static struct demux_packet *find_seek_target(struct demux_queue *queue, return target; } +// Return a cache range for the given pts/flags, or NULL if none available. // must be called locked -static struct demux_cached_range *find_cache_seek_target(struct demux_internal *in, - double pts, int flags) +static struct demux_cached_range *find_cache_seek_range(struct demux_internal *in, + double pts, int flags) { // Note about queued low level seeks: in->seeking can be true here, and it // might come from a previous resume seek to the current range. If we end @@ -3472,6 +3473,8 @@ static struct demux_cached_range *find_cache_seek_target(struct demux_internal * if ((flags & SEEK_FACTOR) || !in->seekable_cache) return NULL; + struct demux_cached_range *res = NULL; + for (int n = 0; n < in->num_ranges; n++) { struct demux_cached_range *r = in->ranges[n]; if (r->seek_start != MP_NOPTS_VALUE) { @@ -3482,50 +3485,59 @@ static struct demux_cached_range *find_cache_seek_target(struct demux_internal * (pts <= r->seek_end || r->is_eof)) { MP_VERBOSE(in, "...using this range for in-cache seek.\n"); - return r; + res = r; + break; } } } - return NULL; + return res; +} + +// Adjust the seek target to the found video key frames. Otherwise the +// video will undershoot the seek target, while audio will be closer to it. +// The player frontend will play the additional video without audio, so +// you get silent audio for the amount of "undershoot". Adjusting the seek +// target will make the audio seek to the video target or before. +// (If hr-seeks are used, it's better to skip this, as it would only mean +// that more audio data than necessary would have to be decoded.) +static void adjust_cache_seek_target(struct demux_internal *in, + struct demux_cached_range *range, + double *pts, int *flags) +{ + if (*flags & SEEK_HR) + return; + + for (int n = 0; n < in->num_streams; n++) { + struct demux_stream *ds = in->streams[n]->ds; + struct demux_queue *queue = range->streams[n]; + if (ds->selected && ds->type == STREAM_VIDEO) { + struct demux_packet *target = find_seek_target(queue, *pts, *flags); + if (target) { + double target_pts; + compute_keyframe_times(target, &target_pts, NULL); + if (target_pts != MP_NOPTS_VALUE) { + MP_VERBOSE(in, "adjust seek target %f -> %f\n", + *pts, target_pts); + // (We assume the find_seek_target() call will return + // the same target for the video stream.) + *pts = target_pts; + *flags &= ~SEEK_FORWARD; + } + } + break; + } + } } // must be called locked -// range must be non-NULL and from find_cache_seek_target() using the same pts +// range must be non-NULL and from find_cache_seek_range() using the same pts // and flags, before any other changes to the cached state static void execute_cache_seek(struct demux_internal *in, struct demux_cached_range *range, double pts, int flags) { - // Adjust the seek target to the found video key frames. Otherwise the - // video will undershoot the seek target, while audio will be closer to it. - // The player frontend will play the additional video without audio, so - // you get silent audio for the amount of "undershoot". Adjusting the seek - // target will make the audio seek to the video target or before. - // (If hr-seeks are used, it's better to skip this, as it would only mean - // that more audio data than necessary would have to be decoded.) - if (!(flags & SEEK_HR)) { - for (int n = 0; n < in->num_streams; n++) { - struct demux_stream *ds = in->streams[n]->ds; - struct demux_queue *queue = range->streams[n]; - if (ds->selected && ds->type == STREAM_VIDEO) { - struct demux_packet *target = find_seek_target(queue, pts, flags); - if (target) { - double target_pts; - compute_keyframe_times(target, &target_pts, NULL); - if (target_pts != MP_NOPTS_VALUE) { - MP_VERBOSE(in, "adjust seek target %f -> %f\n", - pts, target_pts); - // (We assume the find_seek_target() call will return - // the same target for the video stream.) - pts = target_pts; - flags &= ~SEEK_FORWARD; - } - } - break; - } - } - } + adjust_cache_seek_target(in, range, &pts, &flags); for (int n = 0; n < in->num_streams; n++) { struct demux_stream *ds = in->streams[n]->ds; @@ -3624,7 +3636,7 @@ static bool queue_seek(struct demux_internal *in, double seek_pts, int flags, flags &= ~(unsigned)SEEK_SATAN; struct demux_cached_range *cache_target = - find_cache_seek_target(in, seek_pts, flags); + find_cache_seek_range(in, seek_pts, flags); if (!cache_target) { if (require_cache) { -- cgit v1.2.3