From 102a4a8b0654396de7a6355adcf2292a277b6595 Mon Sep 17 00:00:00 2001 From: wm4 Date: Mon, 28 Sep 2020 00:04:21 +0200 Subject: [PATCH] player: let frontend decide whether to use cover-art mode Essentially, this lets video.c decide whether to consider a video track cover art, instead of having the decoder wrapper use the lower level sh_stream flag. Some pain because of the dumb threading shit. Moving the code further down to make some of it part of the lock should not change behavior, although it could (framedrop nonsense). This commit should not change actual behavior, and is only preparation for the following commit. --- filters/f_decoder_wrapper.c | 22 ++++++++++++++++------ filters/f_decoder_wrapper.h | 3 +++ player/video.c | 5 ++++- 3 files changed, 23 insertions(+), 7 deletions(-) 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;