From e00e9d651bf398a311cde1619eaa3a39f8f5b999 Mon Sep 17 00:00:00 2001 From: wm4 Date: Thu, 18 Jun 2015 18:39:46 +0200 Subject: player: make decoding cover art more robust When showing cover art, the decoding logic pretends that the source has an infinite number of frames. This slightly simplifies dealing with filter data flow. It was done by feeding the same packet repeatedly to the decoder (each decode run produces new output). Change this by decoding once at the video initialization. This is easier to follow, and increases robustness in case of broken images. Usually, we try to tolerate decoding errors, so decoding normally continues, but in this case it would just burn the CPU for no reason. Fixes #2056. --- player/video.c | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) (limited to 'player/video.c') diff --git a/player/video.c b/player/video.c index 73891890d0..e1aa19bd00 100644 --- a/player/video.c +++ b/player/video.c @@ -76,6 +76,8 @@ static const char av_desync_help_text[] = " with --no-video, --no-audio, or --no-sub.\n" "If none of this helps you, file a bug report.\n\n"; +static bool decode_coverart(struct dec_video *d_video); + static void set_allowed_vo_formats(struct vf_chain *c, struct vo *vo) { vo_query_formats(vo, c->allowed_output_formats); @@ -301,6 +303,9 @@ int reinit_video_chain(struct MPContext *mpctx) if (!video_init_best_codec(d_video, opts->video_decoders)) goto err_out; + if (!decode_coverart(d_video)) + goto err_out; + bool saver_state = opts->pause || !opts->stop_screensaver; vo_control(mpctx->video_out, saver_state ? VOCTRL_RESTORE_SCREENSAVER : VOCTRL_KILL_SCREENSAVER, NULL); @@ -362,6 +367,17 @@ static int check_framedrop(struct MPContext *mpctx) return 0; } +static bool decode_coverart(struct dec_video *d_video) +{ + d_video->cover_art_mpi = + video_decode(d_video, d_video->header->attached_picture, 0); + // Might need flush. + if (!d_video->cover_art_mpi) + d_video->cover_art_mpi = video_decode(d_video, NULL, 0); + + return !!d_video->cover_art_mpi; +} + // Read a packet, store decoded image into d_video->waiting_decoded_mpi // returns VD_* code static int decode_image(struct MPContext *mpctx) @@ -369,9 +385,8 @@ static int decode_image(struct MPContext *mpctx) struct dec_video *d_video = mpctx->d_video; if (d_video->header->attached_picture) { - d_video->waiting_decoded_mpi = - video_decode(d_video, d_video->header->attached_picture, 0); - return d_video->waiting_decoded_mpi ? VD_EOF : VD_PROGRESS; + d_video->waiting_decoded_mpi = mp_image_new_ref(d_video->cover_art_mpi); + return VD_EOF; } struct demux_packet *pkt; -- cgit v1.2.3