summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--demux/demux.c18
-rw-r--r--player/core.h2
-rw-r--r--player/video.c26
-rw-r--r--video/decode/dec_video.c17
-rw-r--r--video/decode/dec_video.h1
5 files changed, 40 insertions, 24 deletions
diff --git a/demux/demux.c b/demux/demux.c
index a94d98e10f..2195246ac8 100644
--- a/demux/demux.c
+++ b/demux/demux.c
@@ -205,6 +205,9 @@ struct demux_stream {
struct demux_packet *head;
struct demux_packet *tail;
+ struct demux_packet *attached_picture;
+ bool attached_picture_added;
+
// for closed captions (demuxer_feed_caption)
struct sh_stream *cc;
};
@@ -243,6 +246,7 @@ static void ds_flush(struct demux_stream *ds)
ds->last_pos = -1;
ds->last_dts = MP_NOPTS_VALUE;
ds->correct_dts = ds->correct_pos = true;
+ ds->attached_picture_added = false;
}
void demux_set_ts_offset(struct demuxer *demuxer, double offset)
@@ -291,6 +295,8 @@ void demux_add_sh_stream(struct demuxer *demuxer, struct sh_stream *sh)
if (!sh->codec->codec)
sh->codec->codec = "";
+ sh->ds->attached_picture = sh->attached_picture;
+
sh->index = in->num_streams;
if (sh->ff_index < 0)
sh->ff_index = sh->index;
@@ -755,6 +761,13 @@ static void *demux_thread(void *pctx)
static struct demux_packet *dequeue_packet(struct demux_stream *ds)
{
+ if (ds->attached_picture) {
+ ds->eof = true;
+ if (ds->attached_picture_added)
+ return NULL;
+ ds->attached_picture_added = true;
+ return demux_copy_packet(ds->attached_picture);
+ }
if (!ds->head)
return NULL;
struct demux_packet *pkt = ds->head;
@@ -800,18 +813,21 @@ static struct demux_packet *dequeue_packet(struct demux_stream *ds)
// Whether to avoid actively demuxing new packets to find a new packet on the
// given stream.
+// Attached pictures (cover art) should never actively read.
// Sparse packets (Subtitles) interleaved with other non-sparse packets (video,
// audio) should never be read actively, meaning the demuxer thread does not
// try to exceed default readahead in order to find a new packet.
static bool use_lazy_packet_reading(struct demux_stream *ds)
{
+ if (ds->attached_picture)
+ return true;
if (ds->type != STREAM_SUB)
return false;
// Subtitles are only lazily read if there's at least 1 other actively read
// stream.
for (int n = 0; n < ds->in->num_streams; n++) {
struct demux_stream *s = ds->in->streams[n]->ds;
- if (s->type != STREAM_SUB && s->selected && !s->eof)
+ if (s->type != STREAM_SUB && s->selected && !s->eof && !s->attached_picture)
return true;
}
return false;
diff --git a/player/core.h b/player/core.h
index d8640d9ef0..d7510a79fe 100644
--- a/player/core.h
+++ b/player/core.h
@@ -178,6 +178,8 @@ struct vo_chain {
// - video consists of a single picture, which should be shown only once
// - do not sync audio to video in any way
bool is_coverart;
+ // Just to avoid decoding the coverart picture again after a seek.
+ struct mp_image *cached_coverart;
};
// Like vo_chain, for audio.
diff --git a/player/video.c b/player/video.c
index 4621d19cb4..78d10fd107 100644
--- a/player/video.c
+++ b/player/video.c
@@ -328,6 +328,10 @@ static void vo_chain_reset_state(struct vo_chain *vo_c)
if (vo_c->video_src)
video_reset(vo_c->video_src);
+
+ // Prepare for continued playback after a seek.
+ if (!vo_c->input_mpi && vo_c->cached_coverart)
+ vo_c->input_mpi = mp_image_new_ref(vo_c->cached_coverart);
}
void reset_video_state(struct MPContext *mpctx)
@@ -381,6 +385,7 @@ static void vo_chain_uninit(struct vo_chain *vo_c)
lavfi_set_connected(vo_c->filter_src, false);
mp_image_unrefp(&vo_c->input_mpi);
+ mp_image_unrefp(&vo_c->cached_coverart);
vf_destroy(vo_c->vf);
talloc_free(vo_c);
// this does not free the VO
@@ -682,14 +687,25 @@ static int video_decode_and_filter(struct MPContext *mpctx)
return r;
if (!vo_c->input_mpi) {
- // Decode a new image, or at least feed the decoder a packet.
- r = decode_image(mpctx);
- if (r == VD_WAIT)
- return r;
+ if (vo_c->cached_coverart) {
+ // Don't ever decode it twice, not even after seek resets.
+ // (On seek resets, input_mpi is set to the cached image.)
+ r = VD_EOF;
+ } else {
+ // Decode a new image, or at least feed the decoder a packet.
+ r = decode_image(mpctx);
+ if (r == VD_WAIT)
+ return r;
+ }
}
- if (vo_c->input_mpi)
+
+ if (vo_c->input_mpi) {
vo_c->input_format = vo_c->input_mpi->params;
+ if (vo_c->is_coverart && !vo_c->cached_coverart)
+ vo_c->cached_coverart = mp_image_new_ref(vo_c->input_mpi);
+ }
+
bool eof = !vo_c->input_mpi && (r == VD_EOF || r < 0);
r = video_filter(mpctx, eof);
if (r == VD_RECONFIG) // retry feeding decoded image
diff --git a/video/decode/dec_video.c b/video/decode/dec_video.c
index d9dbf0f326..95ca49250b 100644
--- a/video/decode/dec_video.c
+++ b/video/decode/dec_video.c
@@ -89,7 +89,6 @@ void video_uninit(struct dec_video *d_video)
if (!d_video)
return;
mp_image_unrefp(&d_video->current_mpi);
- mp_image_unrefp(&d_video->cover_art_mpi);
if (d_video->vd_driver) {
MP_VERBOSE(d_video, "Uninit video.\n");
d_video->vd_driver->uninit(d_video);
@@ -382,22 +381,6 @@ void video_work(struct dec_video *d_video)
if (d_video->current_mpi)
return;
- if (d_video->header->attached_picture) {
- if (d_video->current_state == DATA_AGAIN && !d_video->cover_art_mpi) {
- struct demux_packet *packet =
- demux_copy_packet(d_video->header->attached_picture);
- d_video->cover_art_mpi = decode_packet(d_video, packet, 0);
- // Might need flush.
- if (!d_video->cover_art_mpi)
- d_video->cover_art_mpi = decode_packet(d_video, NULL, 0);
- talloc_free(packet);
- }
- if (d_video->current_state != DATA_EOF)
- d_video->current_mpi = mp_image_new_ref(d_video->cover_art_mpi);
- d_video->current_state = DATA_EOF;
- return;
- }
-
if (!d_video->packet && !d_video->new_segment &&
demux_read_packet_async(d_video->header, &d_video->packet) == 0)
{
diff --git a/video/decode/dec_video.h b/video/decode/dec_video.h
index 1d2b3f087e..9155a76155 100644
--- a/video/decode/dec_video.h
+++ b/video/decode/dec_video.h
@@ -75,7 +75,6 @@ struct dec_video {
struct demux_packet *new_segment;
struct demux_packet *packet;
bool framedrop_enabled;
- struct mp_image *cover_art_mpi;
struct mp_image *current_mpi;
int current_state;
};