diff options
Diffstat (limited to 'video/filter')
-rw-r--r-- | video/filter/vf.c | 20 | ||||
-rw-r--r-- | video/filter/vf.h | 5 | ||||
-rw-r--r-- | video/filter/vf_dlopen.c | 3 | ||||
-rw-r--r-- | video/filter/vf_lavfi.c | 2 | ||||
-rw-r--r-- | video/filter/vf_softpulldown.c | 3 | ||||
-rw-r--r-- | video/filter/vf_vapoursynth.c | 3 | ||||
-rw-r--r-- | video/filter/vf_vavpp.c | 2 |
7 files changed, 32 insertions, 6 deletions
diff --git a/video/filter/vf.c b/video/filter/vf.c index 0d8f239721..021a0e21ae 100644 --- a/video/filter/vf.c +++ b/video/filter/vf.c @@ -363,14 +363,17 @@ static struct mp_image *vf_dequeue_output_frame(struct vf_instance *vf) static int vf_do_filter(struct vf_instance *vf, struct mp_image *img) { assert(vf->fmt_in.imgfmt); - vf_fix_img_params(img, &vf->fmt_in); + if (img) + vf_fix_img_params(img, &vf->fmt_in); if (vf->filter_ext) { return vf->filter_ext(vf, img); } else { - if (vf->filter) - img = vf->filter(vf, img); - vf_add_output_frame(vf, img); + if (img) { + if (vf->filter) + img = vf->filter(vf, img); + vf_add_output_frame(vf, img); + } return 0; } } @@ -379,6 +382,7 @@ static int vf_do_filter(struct vf_instance *vf, struct mp_image *img) // Return >= 0 on success, < 0 on failure (even if output frames were produced) int vf_filter_frame(struct vf_chain *c, struct mp_image *img) { + assert(img); if (c->initialized < 1) { talloc_free(img); return -1; @@ -387,13 +391,19 @@ int vf_filter_frame(struct vf_chain *c, struct mp_image *img) } // Output the next queued image (if any) from the full filter chain. -struct mp_image *vf_output_queued_frame(struct vf_chain *c) +// eof: if set, assume there's no more input i.e. vf_filter_frame() will +// not be called (until reset) - flush all internally delayed frames +struct mp_image *vf_output_queued_frame(struct vf_chain *c, bool eof) { if (c->initialized < 1) return NULL; while (1) { struct vf_instance *last = NULL; for (struct vf_instance * cur = c->first; cur; cur = cur->next) { + // Flush remaining frames on EOF, but do that only if the previous + // filters have been flushed (i.e. they have no more output). + if (eof && !last) + vf_do_filter(cur, NULL); if (cur->num_out_queued) last = cur; } diff --git a/video/filter/vf.h b/video/filter/vf.h index d11c6de575..8e73c69256 100644 --- a/video/filter/vf.h +++ b/video/filter/vf.h @@ -70,6 +70,9 @@ typedef struct vf_instance { // Like filter(), but can return an error code ( >= 0 means success). This // callback is also more practical when the filter can return multiple // output images. Use vf_add_output_frame() to queue output frames. + // Warning: this is called with mpi==NULL if there is no more input at + // all (i.e. the video has reached end of file condition). This + // can be used to output delayed or otherwise remaining images. int (*filter_ext)(struct vf_instance *vf, struct mp_image *mpi); void (*uninit)(struct vf_instance *vf); @@ -133,7 +136,7 @@ int vf_reconfig(struct vf_chain *c, const struct mp_image_params *params); int vf_control_any(struct vf_chain *c, int cmd, void *arg); int vf_control_by_label(struct vf_chain *c, int cmd, void *arg, bstr label); int vf_filter_frame(struct vf_chain *c, struct mp_image *img); -struct mp_image *vf_output_queued_frame(struct vf_chain *c); +struct mp_image *vf_output_queued_frame(struct vf_chain *c, bool eof); void vf_seek_reset(struct vf_chain *c); struct vf_instance *vf_append_filter(struct vf_chain *c, const char *name, char **args); diff --git a/video/filter/vf_dlopen.c b/video/filter/vf_dlopen.c index 4eefec150c..70c2c6cf24 100644 --- a/video/filter/vf_dlopen.c +++ b/video/filter/vf_dlopen.c @@ -225,6 +225,9 @@ static int filter(struct vf_instance *vf, struct mp_image *mpi) { int i, k; + if (!mpi) + return 0; + set_imgprop(&vf->priv->filter.inpic, mpi); if (mpi->qscale) { if (mpi->qscale_type != 0) { diff --git a/video/filter/vf_lavfi.c b/video/filter/vf_lavfi.c index b100763e05..8e446cec1d 100644 --- a/video/filter/vf_lavfi.c +++ b/video/filter/vf_lavfi.c @@ -251,6 +251,8 @@ static int query_format(struct vf_instance *vf, unsigned int fmt) static AVFrame *mp_to_av(struct vf_instance *vf, struct mp_image *img) { struct vf_priv_s *p = vf->priv; + if (!img) + return NULL; uint64_t pts = img->pts == MP_NOPTS_VALUE ? AV_NOPTS_VALUE : img->pts * av_q2d(av_inv_q(p->timebase_in)); AVFrame *frame = mp_image_to_av_frame_and_unref(img); diff --git a/video/filter/vf_softpulldown.c b/video/filter/vf_softpulldown.c index eeb2f1c863..afa6bf31f0 100644 --- a/video/filter/vf_softpulldown.c +++ b/video/filter/vf_softpulldown.c @@ -54,6 +54,9 @@ static int filter(struct vf_instance *vf, struct mp_image *mpi) int state = vf->priv->state; struct vf_priv_s *p = vf->priv; + if (!mpi) + return 0; + if (!p->buffer || p->buffer->w != mpi->w || p->buffer->h != mpi->h || p->buffer->imgfmt != mpi->imgfmt) { diff --git a/video/filter/vf_vapoursynth.c b/video/filter/vf_vapoursynth.c index 313b66e26b..a6cf471583 100644 --- a/video/filter/vf_vapoursynth.c +++ b/video/filter/vf_vapoursynth.c @@ -180,6 +180,9 @@ static int filter_ext(struct vf_instance *vf, struct mp_image *mpi) if (!p->out_node) return -1; + if (!mpi) + return 0; + // Try to get new frames until we get rid of the input mpi. pthread_mutex_lock(&p->lock); while (1) { diff --git a/video/filter/vf_vavpp.c b/video/filter/vf_vavpp.c index 9a797990eb..4b6322cbe2 100644 --- a/video/filter/vf_vavpp.c +++ b/video/filter/vf_vavpp.c @@ -222,6 +222,8 @@ static struct mp_image *upload(struct vf_instance *vf, struct mp_image *in) static int filter_ext(struct vf_instance *vf, struct mp_image *in) { struct vf_priv_s *p = vf->priv; + if (!in) + return 0; int rt_format = in->imgfmt == IMGFMT_VAAPI ? va_surface_rt_format(in) : VA_RT_FORMAT_YUV420; if (!p->pool || p->current_rt_format != rt_format) { |