[FFmpeg-devel] [PATCH] lavfi/testsrc: extend logic in request_frame, support static image output

Nicolas George nicolas.george at normalesup.org
Wed Aug 1 11:11:24 CEST 2012


Le quintidi 15 thermidor, an CCXX, Stefano Sabatini a écrit :
> ---
>  libavfilter/vsrc_testsrc.c |   44 +++++++++++++++++++++++++++++++-------------
>  1 files changed, 31 insertions(+), 13 deletions(-)
> 
> diff --git a/libavfilter/vsrc_testsrc.c b/libavfilter/vsrc_testsrc.c
> index 7006e53..3f9c922 100644
> --- a/libavfilter/vsrc_testsrc.c
> +++ b/libavfilter/vsrc_testsrc.c
> @@ -50,6 +50,8 @@ typedef struct {
>      char *duration;             ///< total duration of the generated video
>      AVRational sar;             ///< sample aspect ratio
>      int nb_decimals;
> +    int draw_once;              ///< draw only the first frame, always put out the same picture
> +    AVFilterBufferRef *picref;  ///< cached picture
>  
>      void (* fill_picture_fn)(AVFilterContext *ctx, AVFilterBufferRef *picref);
>  
> @@ -123,6 +125,7 @@ static av_cold void uninit(AVFilterContext *ctx)
>      TestSourceContext *test = ctx->priv;
>  
>      av_opt_free(test);
> +    avfilter_unref_bufferp(&test->picref);
>  }
>  
>  static int config_props(AVFilterLink *outlink)
> @@ -140,25 +143,39 @@ static int config_props(AVFilterLink *outlink)
>  static int request_frame(AVFilterLink *outlink)
>  {
>      TestSourceContext *test = outlink->src->priv;
> -    AVFilterBufferRef *picref;
> -    int ret;
> +    AVFilterBufferRef *outpicref;
> +    int ret = 0;
>  
>      if (test->max_pts >= 0 && test->pts >= test->max_pts)
>          return AVERROR_EOF;
> -    picref = ff_get_video_buffer(outlink, AV_PERM_WRITE, test->w, test->h);
> -    if (!picref)
> -        return AVERROR(ENOMEM);
>  
> -    picref->pts = test->pts++;
> -    picref->pos = -1;
> -    picref->video->key_frame = 1;
> -    picref->video->interlaced = 0;
> -    picref->video->pict_type = AV_PICTURE_TYPE_I;
> -    picref->video->sample_aspect_ratio = test->sar;
> -    test->fill_picture_fn(outlink->src, picref);
> +    if (test->draw_once) {
> +        if (!test->picref) {
> +            test->picref =
> +                ff_get_video_buffer(outlink, AV_PERM_WRITE|AV_PERM_PRESERVE|AV_PERM_REUSE,
> +                                    test->w, test->h);
> +            if (!test->picref)
> +                return AVERROR(ENOMEM);
> +        }
> +        outpicref = avfilter_ref_buffer(test->picref, ~AV_PERM_WRITE);
> +    } else
> +        outpicref = ff_get_video_buffer(outlink, AV_PERM_WRITE, test->w, test->h);
> +
> +    if (!outpicref)
> +        return AVERROR(ENOMEM);
> +    outpicref->pts = test->pts;
> +    outpicref->pos = -1;
> +    outpicref->video->key_frame = 1;
> +    outpicref->video->interlaced = 0;
> +    outpicref->video->pict_type = AV_PICTURE_TYPE_I;
> +    outpicref->video->sample_aspect_ratio = test->sar;

> +    if (!test->pts || !test->draw_once)
> +        test->fill_picture_fn(outlink->src, outpicref);

Looks fragile. Maybe call fill_picture_fn just after outpicref is created,
on both branches. Or set a flag there.

> +
> +    test->pts++;
>      test->nb_frame++;

Now redundant?

>  
> -    if ((ret = ff_start_frame(outlink, picref)) < 0 ||
> +    if ((ret = ff_start_frame(outlink, outpicref)) < 0 ||
>          (ret = ff_draw_slice(outlink, 0, test->h, 1)) < 0 ||
>          (ret = ff_end_frame(outlink)) < 0)
>          return ret;
> @@ -493,6 +510,7 @@ static av_cold int rgbtest_init(AVFilterContext *ctx, const char *args)
>  {
>      TestSourceContext *test = ctx->priv;
>  
> +    test->draw_once = 1;
>      test->class = &rgbtestsrc_class;
>      test->fill_picture_fn = rgbtest_fill_picture;
>      return init(ctx, args);

Otherwise looks good to me.

Regards,

-- 
  Nicolas George
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: Digital signature
URL: <http://ffmpeg.org/pipermail/ffmpeg-devel/attachments/20120801/741e2dda/attachment.asc>


More information about the ffmpeg-devel mailing list