From 6d679c435990281e69a74075eeaba499a35f4a80 Mon Sep 17 00:00:00 2001 From: Nicolas George Date: Wed, 25 Apr 2012 00:31:22 +0200 Subject: [PATCH] lavfi: add a generic API for buffer queues. --- 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 0000000000..a27fb86112 --- /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 + +/** + * FFBufQueue: 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 FFBufQueue { + AVFilterBufferRef *queue[FF_BUFQUEUE_SIZE]; + unsigned short head; + unsigned short available; /**< number of available buffers */ +}; + +#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 FFBufQueue *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 with index 0 is the first buffer in the queue. + * Return NULL if the queue has not enough buffers. + */ +static inline AVFilterBufferRef *ff_bufqueue_peek(struct FFBufQueue *queue, + unsigned index) +{ + return index < queue->available ? BUCKET(index) : NULL; +} + +/** + * Get the first buffer from the queue and remove it. + * + * Do not use on an empty queue. + */ +static inline AVFilterBufferRef *ff_bufqueue_get(struct FFBufQueue *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 FFBufQueue *queue) +{ + while (queue->available) + avfilter_unref_buffer(ff_bufqueue_get(queue)); +} + +#undef BUCKET + +#endif /* AVFILTER_BUFFERQUEUE_H */