video: try harder to decode cover art picture only once

For cover art, we pretend that the video stream is infinite, but also
stop decoding once we have an image on the VO (this seems advantageous
for the case when strange filters are inserted or the VO image gets
lost). Since a while ago, the video chain started decoding 2 images
though ("Non-monotonic video pts: 0.000000 <= 0.000000"), which is
annoying and wasteful.

Improve this by handling a certain corner case at initialization, which
will decode a second image while the first one is still stuck in the
filter chain. Also, just in case there are filters which buffer a lot,
also force EOF filtering (which means we tell the filters to flush
buffered frames).

CC: @mpv-player/stable
This commit is contained in:
wm4 2014-10-09 17:57:17 +02:00
parent 69673271e8
commit bc6b8caa6d
1 changed files with 7 additions and 2 deletions

View File

@ -55,6 +55,7 @@ enum {
VD_PROGRESS = 1, // progress, but no output; repeat call with no waiting
VD_NEW_FRAME = 2, // the call produced a new frame
VD_WAIT = 3, // no EOF, but no output; wait until wakeup
VD_RECONFIG = 4,
};
static const char av_desync_help_text[] =
@ -450,7 +451,7 @@ static int video_filter(struct MPContext *mpctx, bool eof)
if (vf->initialized < 1)
return VD_ERROR;
init_filter_params(mpctx);
return VD_PROGRESS;
return VD_RECONFIG;
}
// If something was decoded, and the filter chain is ready, filter it.
@ -485,7 +486,10 @@ static int video_decode_and_filter(struct MPContext *mpctx)
}
bool eof = !d_video->waiting_decoded_mpi && (r == VD_EOF || r < 0);
return video_filter(mpctx, eof);
r = video_filter(mpctx, eof);
if (r == VD_RECONFIG) // retry feeding decoded image
r = video_filter(mpctx, eof);
return r;
}
/* Modify video timing to match the audio timeline. There are two main
@ -537,6 +541,7 @@ static int video_output_image(struct MPContext *mpctx, double endpts)
if (mpctx->next_frame[0])
return VD_NEW_FRAME;
int r = video_decode_and_filter(mpctx);
video_filter(mpctx, true); // force EOF filtering (avoid decoding more)
mpctx->next_frame[0] = vf_read_output_frame(mpctx->d_video->vfilter);
if (mpctx->next_frame[0])
mpctx->next_frame[0]->pts = MP_NOPTS_VALUE;