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

Stefano Sabatini stefasab at gmail.com
Thu Dec 15 00:40:10 CET 2011


On date Wednesday 2011-12-14 21:45:14 +0100, Nicolas George encoded:
> This filter has two inputs, two outputs and just copies the samples from one
> to the other. But it does it in a random order, possibly buffering several
> buffers of samples in the middle.
> 
> The purpose is to help stress-testing filters with several inputs.
> 
> Signed-off-by: Nicolas George <nicolas.george at normalesup.org>
> ---
> 
> 
> I do not know whether it deserves to be committed in the public repository,
> but I had to write it, so I should make it available to other developers if
> they happen to need it.

I wonder if we should disable automatic compilation of debugging
filters (e.g. pixdesctest, copy, this one) and avoid bloating standard
compiles, yet I believe it is not as important since they are not so
many and they are relatively small.

On the other hand I find these testing modules extremely useful for
development/testing purposes, so I'm for including them.

> Regards,
> 
> -- 
>   Nicolas George
> 
> 
>  libavfilter/Makefile        |    1 +
>  libavfilter/af_arandorder.c |  155 +++++++++++++++++++++++++++++++++++++++++++
>  libavfilter/allfilters.c    |    1 +
>  3 files changed, 157 insertions(+), 0 deletions(-)
>  create mode 100644 libavfilter/af_arandorder.c
> 
> diff --git a/libavfilter/Makefile b/libavfilter/Makefile
> index a6fd18f..a04fd15 100644
> --- a/libavfilter/Makefile
> +++ b/libavfilter/Makefile
> @@ -26,6 +26,7 @@ OBJS-$(CONFIG_AVCODEC)                       += avcodec.o
>  OBJS-$(CONFIG_ACONVERT_FILTER)               += af_aconvert.o
>  OBJS-$(CONFIG_AFORMAT_FILTER)                += af_aformat.o
>  OBJS-$(CONFIG_ANULL_FILTER)                  += af_anull.o
> +OBJS-$(CONFIG_ARANDORDER_FILTER)             += af_arandorder.o
>  OBJS-$(CONFIG_ARESAMPLE_FILTER)              += af_aresample.o
>  OBJS-$(CONFIG_ASHOWINFO_FILTER)              += af_ashowinfo.o
>  OBJS-$(CONFIG_EARWAX_FILTER)                 += af_earwax.o
> diff --git a/libavfilter/af_arandorder.c b/libavfilter/af_arandorder.c
> new file mode 100644
> index 0000000..573f387
> --- /dev/null
> +++ b/libavfilter/af_arandorder.c
> @@ -0,0 +1,155 @@
> +/*
> + * Copyright (C) 2011 Nicolas George <nicolas.george at normalesup.org>

Nit+++: Copyright (c)

> + *
> + * This file is part of FFmpeg.
> + *
> + * FFmpeg is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU Lesser General Public
> + * License as published by the Free Software Foundation; either
> + * version 2.1 of the License, or (at your option) any later version.
> + *
> + * FFmpeg is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public
> + * License along with FFmpeg; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
> + */
> +
> +/**
> + * @file
> + * Random reordering filter
> + */
> +

> +#include <stdlib.h>
> +#include "libavcodec/avcodec.h"

are these required?

> +#include "libavutil/avstring.h"
> +#include "libswresample/swresample.h" // only for SWR_CH_MAX
> +#include "avfilter.h"
> +#include "internal.h"
> +
> +#define QUEUE_SIZE 16
> +
> +struct arandorder_context {
> +    unsigned rand_state;

> +    struct {
> +        AVFilterBufferRef *buf[QUEUE_SIZE];
> +        unsigned t, n;
> +    } queue[2];
> +    int req[2];
> +};

please add some comments about these variables

Consistency nit: ARandomOrderContext or something similar (ARandContext
is fine as well).

> +
> +static inline int next_out(struct arandorder_context *ar)
> +{
> +    return !!(ar->rand_state & 0x80000000);
> +}
> +
> +static av_cold int init(AVFilterContext *ctx, const char *args0, void *opaque)
> +{
> +    struct arandorder_context *ar = ctx->priv;
> +

> +    ar->rand_state = MKTAG('R','A','N','D') * 42;

Note: this is a very nice seed, but for testing purposes it may be
useful to make it configurable.

> +    return 0;
> +}
> +
> +static int query_formats(AVFilterContext *ctx)
> +{
> +    avfilter_set_common_sample_formats(ctx, avfilter_make_all_formats(AVMEDIA_TYPE_AUDIO));
> +    avfilter_set_common_packing_formats(ctx, avfilter_make_all_packing_formats());
> +    avfilter_set_common_channel_layouts(ctx, avfilter_make_all_channel_layouts());
> +    return 0;
> +}
> +
> +static int config_output(AVFilterLink *outlink)
> +{
> +    return 0;
> +}
> +
> +static void send_next(AVFilterContext *ctx)
> +{
> +    struct arandorder_context *ar = ctx->priv;
> +    int id;
> +
> +    while (1) {
> +        id = next_out(ar);
> +        if (!ar->queue[id].n)
> +            break;
> +        avfilter_filter_samples(ctx->outputs[id], ar->queue[id].buf[ar->queue[id].t]);
> +        ar->queue[id].n--;
> +        ar->queue[id].t = (ar->queue[id].t + 1) % QUEUE_SIZE;

> +        ar->rand_state = ar->rand_state * 1664525 + 1013904223;

please add a note mentioning "LCG"

> +        if (ar->req[id])
> +            ar->req[id]--;
> +    }
> +    for (id = 0; id < 2; id++) {
> +        if (ar->queue[id].n == QUEUE_SIZE) {
> +            avfilter_filter_samples(ctx->outputs[id], ar->queue[id].buf[ar->queue[id].t]);
> +            ar->queue[id].n--;
> +            ar->queue[id].t = (ar->queue[id].t + 1) % QUEUE_SIZE;
> +            if (ar->req[id])
> +                ar->req[id]--;
> +        }
> +    }
> +}
> +
> +static int request_frame(AVFilterLink *outlink)
> +{
> +    AVFilterContext *ctx = outlink->src;
> +    struct arandorder_context *ar = ctx->priv;
> +    int id = outlink == ctx->outputs[1];
> +    int i;
> +
> +    if (id == next_out(ar) && ar->queue[id].n) {
> +        send_next(ctx);
> +        return 0;
> +    }
> +    ar->req[id]++;
> +    while (ar->req[id])
> +        for (i = 0; i < 2; i++)
> +            if (!ar->queue[i].n)
> +                avfilter_request_frame(ctx->inputs[i]);
> +    return 0;
> +}
> +
> +static void filter_samples(AVFilterLink *inlink, AVFilterBufferRef *insamples)
> +{
> +    AVFilterContext *ctx = inlink->dst;
> +    struct arandorder_context *ar = ctx->priv;
> +    int id = inlink == ctx->inputs[1];
> +
> +    ar->queue[id].buf[(ar->queue[id].t + ar->queue[id].n++) % QUEUE_SIZE] = insamples;
> +    send_next(ctx);
> +}
> +
> +AVFilter avfilter_af_arandorder = {
> +    .name          = "arandorder",

> +    .description   = NULL_IF_CONFIG_SMALL("Copy two streams of audio data in a random order"),

Consistency nit: missing ending dot.
-- 
FFmpeg = Fast Furious Magical Philosofic ExchanGer


More information about the ffmpeg-devel mailing list