[FFmpeg-devel] lavfi noise generator

Stefano Sabatini stefano.sabatini-lala
Tue Dec 30 19:14:37 CET 2008


On date Monday 2008-12-29 16:27:04 +0100, Vitor Sessak encoded:
> Stefano Sabatini wrote:
>> On date Monday 2008-12-29 12:06:20 +0100, Vitor Sessak encoded:
[...]
>>> Indeed, we are lacking good examples of filters in the SoC tree. But  
>>> exactly for this reason, I think vf_noise.c should fill one slice at 
>>> a time to give the good example. After this is done, IMO it is 
>>> welcome to soc svn, at least to serve as a template.
>>
>> Hi Vitor, vsrc_noise.c is a *source* rather than a filter, so I don't
>> think it is possible to use the the draw_slice() API.
>
> Indeed, it should not be possible, at least not with the current svn  
> code. See my attached patch.
>
>> What I'm currently doing is:
>>
>> static int request_frame(AVFilterLink *link)
>> {
>>     NoiseContext *ctx = link->src->priv;
>>     AVFilterPicRef *picref = avfilter_get_video_buffer(link, AV_PERM_WRITE);
>>
>>     fill_picture(ctx, picref);
>>     picref->pts = av_rescale_q(ctx->pts++, (AVRational){ ctx->frame_rate.den, ctx->frame_rate.num }, AV_TIME_BASE_Q);
>>
>>     avfilter_start_frame(link, avfilter_ref_pic(picref, ~0));
>>     avfilter_draw_slice(link, 0, picref->h);
>>     avfilter_end_frame(link);
>>
>>     avfilter_unref_pic(picref);
>>
>>     return 0;
>> }
>
> Could something like the following work?
>
> #define SLICE_SIZE 32
>
> static int request_frame(AVFilterLink *link)
> {
>     NoiseContext *ctx = link->src->priv;
>     AVFilterPicRef *picref = avfilter_get_video_buffer(link,  
> AV_PERM_WRITE);
>     int h;
>
>     picref->pts = av_rescale_q(ctx->pts++, (AVRational) {  
> ctx->frame_rate.den, ctx->frame_rate.num }, AV_TIME_BASE_Q);
>
>     avfilter_start_frame(link, avfilter_ref_pic(picref, ~0));
>     for(h=0; h < ctx->h; h += SLICE_SIZE) {
>        fill_picture(ctx, picref, h, FFMIN(h+SLICE_SIZE, ctx->h));
>        avfilter_draw_slice(link, h, FFMIN(h+SLICE_SIZE, ctx->h));
>     }
>     avfilter_end_frame(link);
>
>     avfilter_unref_pic(picref);
>
>     return 0;
> }

It should work, the only thing I don't like is that in this way the
code *needs* to know about the picture structure (it needs to know how
to access the slice), while before I was simply filling the whole
buffer, and this consideration leads to this (maybe silly) question:
what's the advantage of per-slice filling in this case?

> But maybe an even cleaner solution would be to use draw_slice() and  
> change the function avfilter_request_frame() as in the completely  
> untested attached patch.

[...]

> Index: libavfilter/avfilter.c
> ===================================================================
> --- libavfilter/avfilter.c	(revision 16243)
> +++ libavfilter/avfilter.c	(working copy)
> @@ -179,7 +179,18 @@
>          return link_spad(link).request_frame(link);
>      else if(link->src->inputs[0])
>          return avfilter_request_frame(link->src->inputs[0]);
> +    else if (link_spad(link).draw_slice) {
> +        int h;
> +        for (h=0; h < link->h; h += SLICE_SIZE) {
> +            AVFilterPicRef *picref = avfilter_get_video_buffer(link, AV_PERM_WRITE);
> +            avfilter_start_frame(link, avfilter_ref_pic(picref, ~0));
> +            link_spad(link).draw_slice(link, h, FFMIN(h+SLICE_SIZE, link->h));
> +        }
> +        avfilter_end_frame(link);
> +        avfilter_unref_pic(picref);
> +    }
>      else return -1;
> +    return 0;
>  }
>  
>  int avfilter_poll_frame(AVFilterLink *link)

Looks reasonable to me, let's look at what Michael thinks about it.

Regards.
-- 
FFmpeg = Frenzy and Fantastic Majestic Pure Elaborated Gargoyle




More information about the ffmpeg-devel mailing list