[FFmpeg-devel] [PATCH lavfi: add showwaves filter

Clément Bœsch ubitux at gmail.com
Sat Jun 16 10:19:22 CEST 2012


On Sat, Jun 16, 2012 at 01:49:40AM +0200, Stefano Sabatini wrote:
> On date Monday 2012-05-21 00:07:46 +0200, Nicolas George encoded:
> > Le primidi 1er prairial, an CCXX, Stefano Sabatini a écrit :
> > > >From 1a9c356febb48a6f5b4e028728d638b199a40a51 Mon Sep 17 00:00:00 2001
> > > From: Stefano Sabatini <stefasab at gmail.com>
> > > Date: Sun, 25 Dec 2011 17:37:53 +0100
> > > Subject: [PATCH] lavfi: add showwaves filter
> > > 
> > > ---
> > >  doc/filters.texi            |   23 +++++
> > >  libavfilter/Makefile        |    2 +
> > >  libavfilter/allfilters.c    |    3 +
> > >  libavfilter/avf_showwaves.c |  195 +++++++++++++++++++++++++++++++++++++++++++
> > >  4 files changed, 223 insertions(+), 0 deletions(-)
> > >  create mode 100644 libavfilter/avf_showwaves.c
> [...]
> 
> Updated work in progress, with some of the issues addressed.
> -- 
> FFmpeg = Fierce Fierce Monstrous Portable Ecumenical Gorilla

> From 40c0f12fb54449efdddf8d2c0412228464781fd5 Mon Sep 17 00:00:00 2001
> From: Stefano Sabatini <stefasab at gmail.com>
> Date: Sun, 25 Dec 2011 17:37:53 +0100
> Subject: [PATCH] lavfi: add showwaves filter
> 
> ---
>  doc/filters.texi            |   23 ++++
>  libavfilter/Makefile        |    2 +
>  libavfilter/allfilters.c    |    3 +
>  libavfilter/avf_showwaves.c |  235 +++++++++++++++++++++++++++++++++++++++++++
>  4 files changed, 263 insertions(+), 0 deletions(-)
>  create mode 100644 libavfilter/avf_showwaves.c
> 
[...]
> +static int request_frame(AVFilterLink *outlink)
> +{
> +    ShowWavesContext *showwaves = outlink->src->priv;
> +    AVFilterLink *inlink = outlink->src->inputs[0];
> +    AVFilterBufferRef *outpicref = showwaves->outpicref;
> +    int ret;
> +
> +    showwaves->req_fullfilled = 0;
> +    do {
> +        ret = avfilter_request_frame(inlink);
> +    } while (!showwaves->req_fullfilled && ret >= 0);
> +
> +    if (ret == AVERROR_EOF && showwaves->outpicref) {
> +        int j, linesize = showwaves->outpicref->linesize[0];
> +
> +        /* fill last frame with zeroes */
> +        while (showwaves->buf_idx < showwaves->w) {
> +            for (j = 0; j < showwaves->nb_channels; j++)
> +                *(showwaves->outpicref->data[0]
> +                  + showwaves->buf_idx + showwaves->h/2 * linesize) = 255;
> +            showwaves->buf_idx++;
> +        }

The comment looks clumsy; it looks more correct to say "fill gap in the
last frame with a zero signal" or something like that. You clearly are not
creating silence/zero which is then drawn here.

Maybe you can create a function for this so it can be called with either 0
or *p++ (in filter_samples()).

> +
> +        /* push frame */
> +        ff_start_frame(outlink, outpicref);
> +        ff_draw_slice(outlink, 0, outlink->h, 1);
> +        ff_end_frame(outlink);
> +        showwaves->req_fullfilled = 1;
> +        showwaves->outpicref = NULL;
> +        showwaves->buf_idx = 0;

You have the exact same chunk in filter_samples(), can't it be factorized?

> +    }
> +
> +    return ret;
> +}
> +
> +static void filter_samples(AVFilterLink *inlink, AVFilterBufferRef *insamples)
> +{
> +    AVFilterContext *ctx = inlink->dst;
> +    AVFilterLink *outlink = ctx->outputs[0];
> +    ShowWavesContext *showwaves = ctx->priv;
> +    const int nb_samples = insamples->audio->nb_samples;
> +    AVFilterBufferRef *outpicref = showwaves->outpicref;
> +    int linesize = outpicref ? outpicref->linesize[0] : 0;
> +    double *p = (double *)insamples->data[0];
> +    int i, j, h;
> +
> +    showwaves->nb_channels = av_get_channel_layout_nb_channels(insamples->audio->channel_layout);

Can't this be in a config_props() instead? Or just call a second time
av_get_channel_layout_nb_channels() in request_frame()?

> +
> +    /* draw data in the buffer */
> +    for (i = 0; i < nb_samples; i++) {
> +        if (showwaves->buf_idx == 0) {
> +            showwaves->outpicref = outpicref =
> +                ff_get_video_buffer(outlink, AV_PERM_WRITE|AV_PERM_ALIGN,
> +                                    outlink->w, outlink->h);
> +            outpicref->video->w = outlink->w;
> +            outpicref->video->h = outlink->h;
> +            outpicref->pts = insamples->pts;
> +            outlink->out_buf = outpicref;
> +            linesize = outpicref->linesize[0];
> +            memset(outpicref->data[0], 0, showwaves->h*linesize);
> +        }
> +        for (j = 0; j < showwaves->nb_channels; j++) {
> +            h = showwaves->h/2 - (*p++ * showwaves->h/2);
> +            if (h < outlink->h)
> +                *(outpicref->data[0] + showwaves->buf_idx + h * linesize) = 255;
> +        }
> +        showwaves->buf_idx++;
> +
> +        if (showwaves->buf_idx == showwaves->w) {
> +            ff_start_frame(outlink, outpicref);
> +            ff_draw_slice(outlink, 0, outlink->h, 1);
> +            ff_end_frame(outlink);
> +            showwaves->req_fullfilled = 1;
> +            showwaves->outpicref = NULL;
> +            showwaves->buf_idx = 0;
> +        }
> +    }
> +
> +    avfilter_unref_buffer(insamples);
> +}
> +

[...]

-- 
Clément B.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 490 bytes
Desc: not available
URL: <http://ffmpeg.org/pipermail/ffmpeg-devel/attachments/20120616/f1be2ac2/attachment.asc>


More information about the ffmpeg-devel mailing list