[FFmpeg-devel] [PATCH 2/4] avutil/buffer: Add av_fast_malloc equivalent

Hendrik Leppkes h.leppkes at gmail.com
Tue Nov 20 14:05:19 EET 2018


On Tue, Nov 20, 2018 at 12:45 PM Andreas Rheinhardt
<andreas.rheinhardt at googlemail.com> wrote:
>
> A new function, avpriv_buffer_fast_alloc, is added. Its distinguishing
> feature is that the content of the buffer is considered expendable
> for the given reference, so that no data copying is performed.
>
> Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt at googlemail.com>
> ---
>  libavutil/buffer.c | 37 +++++++++++++++++++++++++++++++++++++
>  libavutil/buffer.h | 19 +++++++++++++++++++
>  2 files changed, 56 insertions(+)
>
> diff --git a/libavutil/buffer.c b/libavutil/buffer.c
> index 8d1aa5fa84..8303f2fc80 100644
> --- a/libavutil/buffer.c
> +++ b/libavutil/buffer.c
> @@ -215,6 +215,43 @@ int av_buffer_realloc(AVBufferRef **pbuf, int size)
>      return 0;
>  }
>
> +int avpriv_buffer_fast_alloc(AVBufferRef **pbuf, int min_size)
> +{
> +    AVBufferRef *buf = *pbuf;
> +
> +    if (!buf || !av_buffer_is_writable(buf)) {
> +        av_buffer_unref(pbuf);
> +
> +        buf = av_buffer_alloc(FFMAX(min_size + (min_size >> 4) + 32,
> +                                    min_size));
> +        if (!buf)
> +            return AVERROR(ENOMEM);
> +
> +        *pbuf = buf;
> +        return 0;
> +    }
> +
> +    if (min_size <= buf->buffer->size) {
> +        buf->data = buf->buffer->data;
> +        buf->size = buf->buffer->size;
> +        return 0;
> +    }
> +
> +    min_size = FFMAX(min_size + (min_size >> 4) + 32, min_size);
> +    av_free(buf->buffer->data);
> +    buf->buffer->data = av_malloc(min_size);
> +    if (!buf->buffer->data) {
> +        av_free(buf->buffer);
> +        av_freep(pbuf);
> +        return AVERROR(ENOMEM);
> +    }
> +
> +    buf->data = buf->buffer->data;
> +    buf->size = buf->buffer->size = min_size;
> +
> +    return 0;
> +}
> +
>  AVBufferPool *av_buffer_pool_init2(int size, void *opaque,
>                                     AVBufferRef* (*alloc)(void *opaque, int size),
>                                     void (*pool_free)(void *opaque))
> diff --git a/libavutil/buffer.h b/libavutil/buffer.h
> index 73b6bd0b14..26715275c4 100644
> --- a/libavutil/buffer.h
> +++ b/libavutil/buffer.h
> @@ -197,6 +197,25 @@ int av_buffer_make_writable(AVBufferRef **buf);
>   */
>  int av_buffer_realloc(AVBufferRef **buf, int size);
>
> +/**
> + * Create a writable buffer with given minimum size, reusing the given buffer
> + * if possible. The content of the buffer is considered expendable for the
> + * given reference and might not be preserved at all if the buffer is writable.
> + * The underlying buffer must be compatible with av_free; furthermore, only the
> + * default free callback may be used.
> + *
> + * @param buf      Pointer to NULL or a pointer to a pointer to a buffer reference.
> + *                 On success, **buf will be an AVBufferRef whose size is the
> + *                 allocated size. On failure the reference is unreferenced.
> + *                 If *buf is NULL, a new buffer is allocated.
> + * @param min_size Desired minimal buffer size in bytes.
> + * @return 0 on success, a negative AVERROR on failure.
> + *
> + * @note The function intentionally overallocates in order to reduce the need
> + * for future allocations.
> + */
> +int avpriv_buffer_fast_alloc(AVBufferRef **buf, int min_size);
> +

avpriv functions don't really belong in public headers. Either the
function is deemed to be useful for external callers as well, and
should be av_, or its not and it should be hidden from public headers.
Although I would argue that a key component like the buffer function
really shouldn't have  avpriv functions. If something is so specific
to one component that its not universally useful, then it should
probably be local to that component.

- Hendrik


More information about the ffmpeg-devel mailing list