[FFmpeg-devel] [PATCH 2/3] lavfi: add a generic API for buffer queues.

Stefano Sabatini stefasab at gmail.com
Tue May 22 01:36:10 CEST 2012


On date Sunday 2012-05-20 21:26:14 +0200, Nicolas George encoded:
> 
> Signed-off-by: Nicolas George <nicolas.george at normalesup.org>
> ---
>  libavfilter/bufferqueue.h |  111 +++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 111 insertions(+)
>  create mode 100644 libavfilter/bufferqueue.h
> 
> diff --git a/libavfilter/bufferqueue.h b/libavfilter/bufferqueue.h
> new file mode 100644
> index 0000000..689ee92
> --- /dev/null
> +++ b/libavfilter/bufferqueue.h
> @@ -0,0 +1,111 @@
> +/*
> + * Generic buffer queue
> + * Copyright (c) 2012 Nicolas George
> + *
> + * 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
> + * Lesser 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
> + */
> +
> +#ifndef AVFILTER_BUFFERQUEUE_H
> +#define AVFILTER_BUFFERQUEUE_H
> +
> +/**
> + * ff_bufqueue: simple AVFilterBufferRef queue API
> + *
> + * Note: this API is not thread-safe. Concurrent access to the same queue
> + * must be protected by a mutex or any synchronization mechanism.
> + */
> +
> +/**
> + * Maximum size of the queue.
> + *
> + * This value can be overridden by definying it before including this
> + * header.
> + * Powers of 2 are recommended.
> + */
> +#ifndef FF_BUFQUEUE_SIZE
> +#define FF_BUFQUEUE_SIZE 32
> +#endif
> +
> +#include "avfilter.h"
> +#include "libavutil/avassert.h"
> +
> +/**
> + * Structure holding the queue
> + */
> +struct ff_bufqueue {

Nit: FFBufQueue but feel free to keep it if you dislike

> +    AVFilterBufferRef *queue[FF_BUFQUEUE_SIZE];
> +    unsigned short head;

> +    unsigned short available; /**< number of available buffers */

Nit: still don't like "available" (looks like a flag, and an
"available" buffer sounds weird, better to explicitely state what the
field represents), anyway this is internal so I won't bicker on this.

> +};
> +
> +#define BUCKET(i) queue->queue[(queue->head + (i)) % FF_BUFQUEUE_SIZE]
> +
> +/**
> + * Add a buffer to the queue.
> + *
> + * If the queue is already full, then the current last buffer is dropped
> + * (and unrefed) with a warning before adding the new buffer.
> + */
> +static inline void ff_bufqueue_add(void *log, struct ff_bufqueue *queue,
> +                                   AVFilterBufferRef *buf)
> +{
> +    if (queue->available == FF_BUFQUEUE_SIZE) {
> +        av_log(log, AV_LOG_WARNING, "Buffer queue overflow, dropping.\n");
> +        avfilter_unref_buffer(BUCKET(--queue->available));
> +    }
> +    BUCKET(queue->available++) = buf;
> +}
> +
> +/**
> + * Get a buffer from the queue without altering it.
> + *

> + * Buffer #0 is the first buffer in the queue.

Nit: #0 -> with index 0, slightly more clear

> + * Return NULL if the queue has not enough buffers.
> + */
> +static inline AVFilterBufferRef *ff_bufqueue_peek(struct ff_bufqueue *queue,
> +                                                  unsigned index)
> +{
> +    return index < queue->available ? BUCKET(index) : NULL;
> +}
> +
> +/**
> + * Get the first buffer from the queue and remove it

Nit: missing dot.

> + *
> + * Do not use on an empty queue.

Is there a reason for this constraint? Shouldn't you just return a
NULL pointer (seems the most natural choice)?

> + */
> +static inline AVFilterBufferRef *ff_bufqueue_get(struct ff_bufqueue *queue)
> +{
> +    AVFilterBufferRef *ret = queue->queue[queue->head];
> +    av_assert0(queue->available);
> +    queue->available--;
> +    queue->queue[queue->head] = NULL;
> +    queue->head = (queue->head + 1) % FF_BUFQUEUE_SIZE;
> +    return ret;
> +}
> +
> +/**
> + * Unref and remove all buffers from the queue.
> + */
> +static inline void ff_bufqueue_discard_all(struct ff_bufqueue *queue)
> +{
> +    while (queue->available)
> +        avfilter_unref_buffer(ff_bufqueue_get(queue));
> +}
> +
> +#undef BUCKET

Looks good otherwise.
-- 
FFmpeg = Foolish and Furious Mysterious Problematic Efficient Gladiator


More information about the ffmpeg-devel mailing list