summaryrefslogtreecommitdiffstats
path: root/demux
diff options
context:
space:
mode:
authorAman Gupta <aman@tmm1.net>2018-05-02 19:29:11 -0700
committerAman Gupta <aman@tmm1.net>2018-05-24 10:26:41 -0700
commit814869759c59ed3ce16604837fbf55e4f5ff7392 (patch)
treef629e0e87226074c486c9e1f81a96e063f187fd4 /demux
parentb24bd4e57075e116a5ce0c2d7a69f436776eae8f (diff)
downloadmpv-814869759c59ed3ce16604837fbf55e4f5ff7392.tar.bz2
mpv-814869759c59ed3ce16604837fbf55e4f5ff7392.tar.xz
demux, player: fix playback of sparse video streams (w/ still images)
Fixes several issues playing back mpegts with video streams marked as having "still images". For example, see this video which has frames only every 6s: https://s3.amazonaws.com/tmm1/music-choice.ts Changes include: - start playback right away, without waiting for first video frame - do not consider the sparse video stream in demuxer underrun detection - do not require multiple video frames for the VO - use audio as the master stream for demuxer metadata events - use audio stream for playback time Signed-off-by: Aman Gupta <aman@tmm1.net>
Diffstat (limited to 'demux')
-rw-r--r--demux/demux.c6
-rw-r--r--demux/demux_lavf.c5
-rw-r--r--demux/stheader.h1
3 files changed, 10 insertions, 2 deletions
diff --git a/demux/demux.c b/demux/demux.c
index afe8d2b51f..40a68eacae 100644
--- a/demux/demux.c
+++ b/demux/demux.c
@@ -282,6 +282,7 @@ struct demux_stream {
bool eager; // try to keep at least 1 packet queued
// if false, this stream is disabled, or passively
// read (like subtitles)
+ bool still_image; // stream has still video images
bool refreshing; // finding old position after track switches
bool eof; // end of demuxed stream? (true if no more packets)
@@ -703,8 +704,9 @@ static void update_stream_selection_state(struct demux_internal *in,
for (int n = 0; n < in->num_streams; n++) {
struct demux_stream *s = in->streams[n]->ds;
+ s->still_image = s->sh->still_image;
s->eager = s->selected && !s->sh->attached_picture;
- if (s->eager) {
+ if (s->eager && !s->still_image) {
any_av_streams |= s->type != STREAM_SUB;
if (!master ||
(master->type == STREAM_VIDEO && s->type == STREAM_AUDIO))
@@ -2994,7 +2996,7 @@ static int cached_demux_control(struct demux_internal *in, int cmd, void *arg)
struct demux_stream *ds = in->streams[n]->ds;
if (ds->eager && !(!ds->queue->head && ds->eof) && !ds->ignore_eof)
{
- r->underrun |= !ds->reader_head && !ds->eof;
+ r->underrun |= !ds->reader_head && !ds->eof && !ds->still_image;
r->ts_reader = MP_PTS_MAX(r->ts_reader, ds->base_ts);
r->ts_end = MP_PTS_MAX(r->ts_end, ds->queue->last_ts);
any_packets |= !!ds->reader_head;
diff --git a/demux/demux_lavf.c b/demux/demux_lavf.c
index 2049cf6c47..555df9406d 100644
--- a/demux/demux_lavf.c
+++ b/demux/demux_lavf.c
@@ -53,6 +53,9 @@
#ifndef AV_DISPOSITION_TIMED_THUMBNAILS
#define AV_DISPOSITION_TIMED_THUMBNAILS 0
#endif
+#ifndef AV_DISPOSITION_STILL_IMAGE
+#define AV_DISPOSITION_STILL_IMAGE 0
+#endif
#define INITIAL_PROBE_SIZE STREAM_BUFFER_SIZE
#define PROBE_BUF_SIZE FFMIN(STREAM_MAX_BUFFER_SIZE, 2 * 1024 * 1024)
@@ -717,6 +720,8 @@ static void handle_new_stream(demuxer_t *demuxer, int i)
sh->forced_track = true;
if (st->disposition & AV_DISPOSITION_DEPENDENT)
sh->dependent_track = true;
+ if (st->disposition & AV_DISPOSITION_STILL_IMAGE)
+ sh->still_image = true;
if (priv->format_hack.use_stream_ids)
sh->demuxer_id = st->id;
AVDictionaryEntry *title = av_dict_get(st->metadata, "title", NULL, 0);
diff --git a/demux/stheader.h b/demux/stheader.h
index 700ded89fa..63744487bf 100644
--- a/demux/stheader.h
+++ b/demux/stheader.h
@@ -46,6 +46,7 @@ struct sh_stream {
bool default_track; // container default track flag
bool forced_track; // container forced track flag
bool dependent_track; // container dependent track flag
+ bool still_image; // video stream contains still images
int hls_bitrate;
struct mp_tags *tags;