summaryrefslogtreecommitdiffstats
path: root/demux
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2017-12-24 01:56:09 +0100
committerMartin Herkt <652892+lachs0r@users.noreply.github.com>2017-12-24 21:49:12 +0100
commit29af78721760e426b920904d44566de482e30709 (patch)
treef54d704d537c065d2bc72ed92ed2e3281d6afed5 /demux
parentc12d897a3a79fbe4531988a3853b67a5e6042668 (diff)
downloadmpv-29af78721760e426b920904d44566de482e30709.tar.bz2
mpv-29af78721760e426b920904d44566de482e30709.tar.xz
player: update duration based on highest timestamp demuxed
This will help with things like livestreams. As a minor detail, subtitles are excluded, because they sometimes have "unused" events after video and audio ends. To avoid this annoying corner case, just ignore them.
Diffstat (limited to 'demux')
-rw-r--r--demux/demux.c23
-rw-r--r--demux/demux.h1
2 files changed, 24 insertions, 0 deletions
diff --git a/demux/demux.c b/demux/demux.c
index 4ea8cce595..8c8600d63b 100644
--- a/demux/demux.c
+++ b/demux/demux.c
@@ -190,6 +190,8 @@ struct demux_internal {
// This is never NULL. This is always ranges[num_ranges - 1].
struct demux_cached_range *current_range;
+ double highest_av_pts; // highest non-subtitle PTS seen - for duration
+
// Cached state.
bool force_cache_update;
struct mp_tags *stream_metadata;
@@ -1198,6 +1200,23 @@ void demux_add_packet(struct sh_stream *stream, demux_packet_t *dp)
adjust_seek_range_on_packet(ds, dp);
+ // Possible update duration based on highest TS demuxed (but ignore subs).
+ if (stream->type != STREAM_SUB) {
+ if (dp->segmented)
+ ts = MP_PTS_MIN(ts, dp->end);
+ if (ts > in->highest_av_pts) {
+ in->highest_av_pts = ts;
+ double duration = in->highest_av_pts - in->d_thread->start_time;
+ if (duration > in->d_thread->duration) {
+ in->d_thread->duration = duration;
+ // (Don't wakeup like like demux_changed(), would be too noisy.)
+ in->d_thread->events |= DEMUX_EVENT_DURATION;
+ in->d_buffer->duration = duration;
+ in->d_buffer->events |= DEMUX_EVENT_DURATION;
+ }
+ }
+ }
+
// Wake up if this was the first packet after start/possible underrun.
if (ds->in->wakeup_cb && ds->reader_head && !ds->reader_head->next)
ds->in->wakeup_cb(ds->in->wakeup_cb_ctx);
@@ -1798,6 +1817,9 @@ static void demux_copy(struct demuxer *dst, struct demuxer *src)
}
}
+ if (src->events & DEMUX_EVENT_DURATION)
+ dst->duration = src->duration;
+
dst->events |= src->events;
src->events = 0;
}
@@ -1968,6 +1990,7 @@ static struct demuxer *open_given_type(struct mpv_global *global,
.max_bytes = opts->max_bytes,
.max_bytes_bw = opts->max_bytes_bw,
.initial_state = true,
+ .highest_av_pts = MP_NOPTS_VALUE,
};
pthread_mutex_init(&in->lock, NULL);
pthread_cond_init(&in->wakeup, NULL);
diff --git a/demux/demux.h b/demux/demux.h
index ab8edb7aa0..85bd5fd626 100644
--- a/demux/demux.h
+++ b/demux/demux.h
@@ -91,6 +91,7 @@ enum demux_event {
DEMUX_EVENT_INIT = 1 << 0, // complete (re-)initialization
DEMUX_EVENT_STREAMS = 1 << 1, // a stream was added
DEMUX_EVENT_METADATA = 1 << 2, // metadata or stream_metadata changed
+ DEMUX_EVENT_DURATION = 1 << 3, // duration updated
DEMUX_EVENT_ALL = 0xFFFF,
};