Message ID | 20181120113839.4512-3-andreas.rheinhardt@googlemail.com |
---|---|
State | Superseded |
Headers | show |
On Tue, Nov 20, 2018 at 12:45 PM Andreas Rheinhardt <andreas.rheinhardt@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@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
> If something is so specific to one component that its not universally > useful, then it should probably be local to that component. Ok, I have completely removed the changes to buffer.c and buffer.h and incorporated them into a static function in h2645_parse.c. Thank you. - Andreas Andreas Rheinhardt (3): cbs_h2645: Avoid memcpy when splitting fragment h2645_parse: Make ff_h2645_packet_split reference-compatible cbs_h2645: Avoid memcpy when splitting fragment #2 libavcodec/cbs_h2645.c | 45 +++++++++++++++--------------- libavcodec/cbs_h2645.h | 2 ++ libavcodec/extract_extradata_bsf.c | 4 +-- libavcodec/h2645_parse.c | 43 +++++++++++++++++++++++++--- libavcodec/h2645_parse.h | 15 ++++++++-- libavcodec/h264_parse.c | 4 +-- libavcodec/h264dec.c | 6 ++-- libavcodec/hevc_parse.c | 5 ++-- libavcodec/hevc_parser.c | 4 +-- libavcodec/hevcdec.c | 4 +-- 10 files changed, 90 insertions(+), 42 deletions(-)
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); + /** * @} */
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@googlemail.com> --- libavutil/buffer.c | 37 +++++++++++++++++++++++++++++++++++++ libavutil/buffer.h | 19 +++++++++++++++++++ 2 files changed, 56 insertions(+)