[FFmpeg-devel] [PATCH] lavfi/buffersrc: push the frame deeper if requested.

Nicolas George george at nsup.org
Mon Jul 17 15:58:24 EEST 2017


Le tridi 23 messidor, an CCXXV, Paul B Mahol a écrit :
> You never asked for one.

Indeed, since I forgot to answer your mail. But you know what is
necessary in a bug report.

> Here it is attached just for you.

I think you sent it to the mailing-list, not just to me.

Anyway, I have a working version now, I need to clean it up before
sending. In the meantime, instead of duelling while riding office
chairs, I can point what did not work in this patch:

> From 20d00cead1e47b2e389fde99a3c0f9c36b6587ec Mon Sep 17 00:00:00 2001
> From: Paul B Mahol <onemda at gmail.com>
> Date: Tue, 20 Jun 2017 19:44:54 +0200
> Subject: [PATCH] shit
> 
> Signed-off-by: Paul B Mahol <onemda at gmail.com>
> ---
>  libavfilter/framesync.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++
>  libavfilter/framesync.h |  4 ++++
>  libavfilter/vf_stack.c  |  9 ++++-----
>  3 files changed, 55 insertions(+), 5 deletions(-)
> 
> diff --git a/libavfilter/framesync.c b/libavfilter/framesync.c
> index eb05d66..f2a4450 100644
> --- a/libavfilter/framesync.c
> +++ b/libavfilter/framesync.c
> @@ -23,6 +23,7 @@
>  
>  #include "libavutil/avassert.h"
>  #include "avfilter.h"
> +#include "filters.h"
>  #include "bufferqueue.h"
>  #include "framesync.h"
>  #include "internal.h"
> @@ -224,6 +225,22 @@ void ff_framesync_next(FFFrameSync *fs)
>      framesync_advance(fs);
>  }
>  
> +void ff_framesync_next2(FFFrameSync *fs)
> +{
> +    AVFilterContext *ctx = fs->parent;
> +    unsigned i;
> +
> +    av_assert0(!fs->frame_ready);
> +    for (i = 0; i < fs->nb_in; i++)

> +        if (!fs->in[i].have_next && ff_framequeue_queued_frames(&ctx->inputs[i]->fifo)) {
> +            framesync_inject_frame(fs, i, ff_framequeue_take(&ctx->inputs[i]->fifo));

Do not access link->fifo directly.

> +            ctx->inputs[i]->frame_wanted_out = 1;

This must not be done unconditionally, it must only be done if (1)
frame_wanted_out is set on the output or (2) there are frame queued in
other inputs and a frame is necessary to process them.

> +            ff_filter_set_ready(ctx->inputs[i]->src, 100);

Use ff_inlink_request_frame().

> +        }
> +    fs->frame_ready = 0;
> +    framesync_advance(fs);
> +}
> +
>  void ff_framesync_drop(FFFrameSync *fs)
>  {
>      fs->frame_ready = 0;
> @@ -300,6 +317,27 @@ int ff_framesync_process_frame(FFFrameSync *fs, unsigned all)
>      return count;
>  }
>  
> +int ff_framesync_process_frame2(FFFrameSync *fs, unsigned all)
> +{
> +    int ret, count = 0;
> +
> +    av_assert0(fs->on_event);
> +    while (1) {
> +        ff_framesync_next2(fs);
> +        if (fs->eof || !fs->frame_ready)
> +            break;
> +        if ((ret = fs->on_event(fs)) < 0)
> +            return ret;
> +        ff_framesync_drop(fs);
> +        count++;
> +        if (!all)
> +            break;
> +    }
> +    if (!count && fs->eof)
> +        return AVERROR_EOF;
> +    return count;
> +}
> +
>  int ff_framesync_filter_frame(FFFrameSync *fs, AVFilterLink *inlink,
>                                AVFrame *in)
>  {
> @@ -314,6 +352,15 @@ int ff_framesync_filter_frame(FFFrameSync *fs, AVFilterLink *inlink,
>      return 0;
>  }
>  
> +int ff_framesync_activate(FFFrameSync *fs, AVFilterContext *ctx)
> +{
> +    int ret;
> +

> +    if ((ret = ff_framesync_process_frame2(fs, 1)) < 0)
> +        return ret;

At no point your code calls ff_inlink_acknowledge_status(). Therefore,
it can not detect EOF.

> +    return 0;
> +}
> +
>  int ff_framesync_request_frame(FFFrameSync *fs, AVFilterLink *outlink)
>  {
>      AVFilterContext *ctx = outlink->src;
> diff --git a/libavfilter/framesync.h b/libavfilter/framesync.h
> index 7ba99d5..0f381e3 100644
> --- a/libavfilter/framesync.h
> +++ b/libavfilter/framesync.h
> @@ -250,6 +250,7 @@ int ff_framesync_add_frame(FFFrameSync *fs, unsigned in, AVFrame *frame);
>   * The status of the operation can be found in fs->frame_ready and fs->eof.
>   */
>  void ff_framesync_next(FFFrameSync *fs);
> +void ff_framesync_next2(FFFrameSync *fs);
>  
>  /**
>   * Drop the current frame event.
> @@ -275,6 +276,7 @@ int ff_framesync_get_frame(FFFrameSync *fs, unsigned in, AVFrame **rframe,
>   * @return  number of frames processed or negative error code
>   */
>  int ff_framesync_process_frame(FFFrameSync *fs, unsigned all);
> +int ff_framesync_process_frame2(FFFrameSync *fs, unsigned all);
>  
>  
>  /**
> @@ -286,6 +288,8 @@ int ff_framesync_process_frame(FFFrameSync *fs, unsigned all);
>  int ff_framesync_filter_frame(FFFrameSync *fs, AVFilterLink *inlink,
>                                AVFrame *in);
>  
> +int ff_framesync_activate(FFFrameSync *fs, AVFilterContext *ctx);
> +
>  /**
>   * Request a frame on the filter output.
>   *
> diff --git a/libavfilter/vf_stack.c b/libavfilter/vf_stack.c
> index 03643b6..0e45952 100644
> --- a/libavfilter/vf_stack.c
> +++ b/libavfilter/vf_stack.c
> @@ -58,10 +58,10 @@ static int query_formats(AVFilterContext *ctx)
>      return ff_set_common_formats(ctx, pix_fmts);
>  }
>  
> -static int filter_frame(AVFilterLink *inlink, AVFrame *in)
> +static int activate(AVFilterContext *ctx)
>  {
> -    StackContext *s = inlink->dst->priv;
> -    return ff_framesync_filter_frame(&s->fs, inlink, in);
> +    StackContext *s = ctx->priv;
> +    return ff_framesync_activate(&s->fs, ctx);
>  }
>  
>  static av_cold int init(AVFilterContext *ctx)
> @@ -83,7 +83,6 @@ static av_cold int init(AVFilterContext *ctx)
>          pad.name = av_asprintf("input%d", i);
>          if (!pad.name)
>              return AVERROR(ENOMEM);
> -        pad.filter_frame = filter_frame;
>  
>          if ((ret = ff_insert_inpad(ctx, i, &pad)) < 0) {
>              av_freep(&pad.name);
> @@ -237,7 +236,6 @@ static const AVFilterPad outputs[] = {
>          .name          = "default",
>          .type          = AVMEDIA_TYPE_VIDEO,
>          .config_props  = config_output,
> -        .request_frame = request_frame,
>      },
>      { NULL }
>  };
> @@ -274,6 +272,7 @@ AVFilter ff_vf_vstack = {
>      .query_formats = query_formats,
>      .outputs       = outputs,
>      .init          = init,
> +    .activate      = activate,
>      .uninit        = uninit,
>      .flags         = AVFILTER_FLAG_DYNAMIC_INPUTS,
>  };

Regards,

-- 
  Nicolas George
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: Digital signature
URL: <http://ffmpeg.org/pipermail/ffmpeg-devel/attachments/20170717/4e9bac76/attachment.sig>


More information about the ffmpeg-devel mailing list