summaryrefslogtreecommitdiffstats
path: root/video
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2014-05-01 18:42:53 +0200
committerwm4 <wm4@nowhere>2014-05-02 01:08:05 +0200
commitffde8083f6616deffd3fb2f9ac8a7db99724231b (patch)
tree9f1570d8424b61841a994f74a042ef177b07d719 /video
parentbd230a8d47a789205c0dbdb63cf39130c44498cc (diff)
downloadmpv-ffde8083f6616deffd3fb2f9ac8a7db99724231b.tar.bz2
mpv-ffde8083f6616deffd3fb2f9ac8a7db99724231b.tar.xz
vf_lavfi: reinit after libavfilter EOF
Basically, if we feed the filter a new image even after the EOF state has been reached (e.g. because the input stream "recovered"), we want the filter to restart, instead of returning an error forever.
Diffstat (limited to 'video')
-rw-r--r--video/filter/vf_lavfi.c38
1 files changed, 25 insertions, 13 deletions
diff --git a/video/filter/vf_lavfi.c b/video/filter/vf_lavfi.c
index fd7c1b3001..066afa28dd 100644
--- a/video/filter/vf_lavfi.c
+++ b/video/filter/vf_lavfi.c
@@ -63,6 +63,7 @@ struct vf_priv_s {
AVFilterGraph *graph;
AVFilterContext *in;
AVFilterContext *out;
+ bool eof;
AVRational timebase_in;
AVRational timebase_out;
@@ -89,6 +90,13 @@ static void destroy_graph(struct vf_instance *vf)
struct vf_priv_s *p = vf->priv;
avfilter_graph_free(&p->graph);
p->in = p->out = NULL;
+
+ if (p->metadata) {
+ talloc_free(p->metadata);
+ p->metadata = NULL;
+ }
+
+ p->eof = false;
}
static AVRational par_from_sar_dar(int width, int height,
@@ -214,6 +222,14 @@ error:
return false;
}
+static void reset(vf_instance_t *vf)
+{
+ struct vf_priv_s *p = vf->priv;
+ struct mp_image_params *f = &vf->fmt_in;
+ if (p->graph && f->imgfmt)
+ recreate_graph(vf, f->w, f->h, f->d_w, f->d_h, f->imgfmt);
+}
+
static int config(struct vf_instance *vf, int width, int height,
int d_width, int d_height, unsigned int flags,
unsigned int fmt)
@@ -287,6 +303,13 @@ static int filter_ext(struct vf_instance *vf, struct mp_image *mpi)
{
struct vf_priv_s *p = vf->priv;
+ if (p->eof && mpi) {
+ // Once EOF is reached, libavfilter is "stuck" in the EOF state, and
+ // won't accept new input. Forcefully override it. This helps e.g.
+ // with cover art, where we always want to generate new output.
+ reset(vf);
+ }
+
if (!p->graph)
return -1;
@@ -303,8 +326,9 @@ static int filter_ext(struct vf_instance *vf, struct mp_image *mpi)
if (err == AVERROR(EAGAIN) || err == AVERROR_EOF) {
// Not an error situation - no more output buffers in queue.
// AVERROR_EOF means we shouldn't even give the filter more
- // input, but we don't handle that.
+ // input, but we don't handle that completely correctly.
av_frame_free(&frame);
+ p->eof |= err == AVERROR_EOF;
break;
}
if (err < 0) {
@@ -320,18 +344,6 @@ static int filter_ext(struct vf_instance *vf, struct mp_image *mpi)
return 0;
}
-static void reset(vf_instance_t *vf)
-{
- struct vf_priv_s *p = vf->priv;
- struct mp_image_params *f = &vf->fmt_in;
- if (p->graph && f->imgfmt)
- recreate_graph(vf, f->w, f->h, f->d_w, f->d_h, f->imgfmt);
- if (p->metadata) {
- talloc_free(p->metadata);
- p->metadata = NULL;
- }
-}
-
static int control(vf_instance_t *vf, int request, void *data)
{
switch (request) {