diff --git a/filters/f_decoder_wrapper.c b/filters/f_decoder_wrapper.c index 3253eea95b..397c3a0a98 100644 --- a/filters/f_decoder_wrapper.c +++ b/filters/f_decoder_wrapper.c @@ -226,6 +226,7 @@ struct priv { char *cur_hwdec; char *decoder_desc; bool try_spdif; + bool attached_picture; bool pts_reset; int attempt_framedrops; // try dropping this many frames int dropped_frames; // total frames _probably_ dropped @@ -524,6 +525,14 @@ void mp_decoder_wrapper_set_spdif_flag(struct mp_decoder_wrapper *d, bool spdif) pthread_mutex_unlock(&p->cache_lock); } +void mp_decoder_wrapper_set_coverart_flag(struct mp_decoder_wrapper *d, bool c) +{ + struct priv *p = d->f->priv; + pthread_mutex_lock(&p->cache_lock); + p->attached_picture = c; + pthread_mutex_unlock(&p->cache_lock); +} + bool mp_decoder_wrapper_get_pts_reset(struct mp_decoder_wrapper *d) { struct priv *p = d->f->priv; @@ -974,13 +983,9 @@ static void read_frame(struct priv *p) if (!frame.type) return; - if (p->header->attached_picture && frame.type == MP_FRAME_VIDEO) { - p->decoded_coverart = frame; - mp_filter_internal_mark_progress(p->decf); - return; - } - pthread_mutex_lock(&p->cache_lock); + if (p->attached_picture && frame.type == MP_FRAME_VIDEO) + p->decoded_coverart = frame; if (p->attempt_framedrops) { int dropped = MPMAX(0, p->packets_without_output - 1); p->attempt_framedrops = MPMAX(0, p->attempt_framedrops - dropped); @@ -988,6 +993,11 @@ static void read_frame(struct priv *p) } pthread_mutex_unlock(&p->cache_lock); + if (p->decoded_coverart.type) { + mp_filter_internal_mark_progress(p->decf); + return; + } + p->packets_without_output = 0; if (p->preroll_discard && frame.type != MP_FRAME_EOF) { diff --git a/filters/f_decoder_wrapper.h b/filters/f_decoder_wrapper.h index e6f7705b33..9fa1a4f010 100644 --- a/filters/f_decoder_wrapper.h +++ b/filters/f_decoder_wrapper.h @@ -55,6 +55,9 @@ double mp_decoder_wrapper_get_container_fps(struct mp_decoder_wrapper *d); // Whether to prefer spdif wrapper over real decoders on next reinit. void mp_decoder_wrapper_set_spdif_flag(struct mp_decoder_wrapper *d, bool spdif); +// Whether to decode only 1 frame and then stop, and cache the frame across resets. +void mp_decoder_wrapper_set_coverart_flag(struct mp_decoder_wrapper *d, bool c); + // True if a pts reset was observed (audio only, heuristic). bool mp_decoder_wrapper_get_pts_reset(struct mp_decoder_wrapper *d); diff --git a/player/video.c b/player/video.c index 2b8f03630e..c13bdb4074 100644 --- a/player/video.c +++ b/player/video.c @@ -261,9 +261,12 @@ void reinit_video_chain_src(struct MPContext *mpctx, struct track *track) vo_c->dec_src = track->dec->f->pins[0]; vo_c->filter->container_fps = mp_decoder_wrapper_get_container_fps(track->dec); - vo_c->is_coverart = !!track->stream->attached_picture; + vo_c->is_coverart = !!track->attached_picture; vo_c->is_sparse = track->stream->still_image || vo_c->is_coverart; + if (vo_c->is_coverart) + mp_decoder_wrapper_set_coverart_flag(track->dec, true); + track->vo_c = vo_c; vo_c->track = track;