[4/5] avio: Add a function for reusing a dyn buffer

Message ID 1370205623-45186-4-git-send-email-martin@martin.st
State New
Headers show

Commit Message

Martin Storsjö June 2, 2013, 8:40 p.m.
From: Andrey Semashev <andysem@mail.ru>

This avoids having to free and realloc a growing array for cases
where a similar buffer is used repeatedly.
---
 doc/APIchanges        |    3 +++
 libavformat/avio.h    |   10 ++++++++++
 libavformat/aviobuf.c |   24 ++++++++++++++++++++++++
 libavformat/version.h |    2 +-
 4 files changed, 38 insertions(+), 1 deletion(-)

Comments

Luca Barbato June 2, 2013, 10:02 p.m. | #1
On 06/02/2013 10:40 PM, Martin Storsjö wrote:
> From: Andrey Semashev <andysem@mail.ru>
> 
> This avoids having to free and realloc a growing array for cases
> where a similar buffer is used repeatedly.
> ---
>  doc/APIchanges        |    3 +++
>  libavformat/avio.h    |   10 ++++++++++
>  libavformat/aviobuf.c |   24 ++++++++++++++++++++++++
>  libavformat/version.h |    2 +-
>  4 files changed, 38 insertions(+), 1 deletion(-)
> 
> diff --git a/doc/APIchanges b/doc/APIchanges
> index 0957f9e..83bec5b 100644
> --- a/doc/APIchanges
> +++ b/doc/APIchanges
> @@ -13,6 +13,9 @@ libavutil:     2012-10-22
>  
>  API changes, most recent first:
>  
> +2013-06-xx - xxxxxxx - lavf 55.2.0 - avio.h
> +  Add avio_reset_dyn_buf
> +
>  2013-05-xx - xxxxxxx - lavfi 3.10.0 - avfilter.h
>    Add support for slice multithreading to lavfi. Filters supporting threading
>    are marked with AVFILTER_FLAG_SLICE_THREADS.
> diff --git a/libavformat/avio.h b/libavformat/avio.h
> index b6d3cb3..c8a0b63 100644
> --- a/libavformat/avio.h
> +++ b/libavformat/avio.h
> @@ -391,6 +391,16 @@ int avio_open_dyn_buf(AVIOContext **s);
>  int avio_close_dyn_buf(AVIOContext *s, uint8_t **pbuffer);
>  
>  /**
> + * Return the written size and a pointer to the buffer. Sets the
> + * writing position to the beginning of the buffer, so it can be reused.
> + *
> + * @param s IO context
> + * @param pbuffer pointer to a byte buffer
> + * @return the length of the byte buffer
> + */
> +int avio_reset_dyn_buf(AVIOContext *s, uint8_t **pbuffer);
> +
> +/**
>   * Iterate through names of available protocols.
>   *
>   * @param opaque A private pointer representing current protocol.
> diff --git a/libavformat/aviobuf.c b/libavformat/aviobuf.c
> index d2eaf36..09f74b2 100644
> --- a/libavformat/aviobuf.c
> +++ b/libavformat/aviobuf.c
> @@ -963,3 +963,27 @@ int avio_close_dyn_buf(AVIOContext *s, uint8_t **pbuffer)
>      av_free(s);
>      return size - padding;
>  }
> +
> +int avio_reset_dyn_buf(AVIOContext *s, uint8_t **pbuffer)
> +{
> +    DynBuffer *d = s->opaque;
> +    int size;
> +    static const char padbuf[FF_INPUT_BUFFER_PADDING_SIZE] = {0};
> +    int padding = 0;
> +
> +    /* don't attempt to pad fixed-size packet buffers */
> +    if (!s->max_packet_size) {
> +        avio_write(s, padbuf, sizeof(padbuf));
> +        padding = FF_INPUT_BUFFER_PADDING_SIZE;
> +    }

what about using an explicit memset or adding an avio_memset for such
situations while we are at extending the api?

lu

Patch

diff --git a/doc/APIchanges b/doc/APIchanges
index 0957f9e..83bec5b 100644
--- a/doc/APIchanges
+++ b/doc/APIchanges
@@ -13,6 +13,9 @@  libavutil:     2012-10-22
 
 API changes, most recent first:
 
+2013-06-xx - xxxxxxx - lavf 55.2.0 - avio.h
+  Add avio_reset_dyn_buf
+
 2013-05-xx - xxxxxxx - lavfi 3.10.0 - avfilter.h
   Add support for slice multithreading to lavfi. Filters supporting threading
   are marked with AVFILTER_FLAG_SLICE_THREADS.
diff --git a/libavformat/avio.h b/libavformat/avio.h
index b6d3cb3..c8a0b63 100644
--- a/libavformat/avio.h
+++ b/libavformat/avio.h
@@ -391,6 +391,16 @@  int avio_open_dyn_buf(AVIOContext **s);
 int avio_close_dyn_buf(AVIOContext *s, uint8_t **pbuffer);
 
 /**
+ * Return the written size and a pointer to the buffer. Sets the
+ * writing position to the beginning of the buffer, so it can be reused.
+ *
+ * @param s IO context
+ * @param pbuffer pointer to a byte buffer
+ * @return the length of the byte buffer
+ */
+int avio_reset_dyn_buf(AVIOContext *s, uint8_t **pbuffer);
+
+/**
  * Iterate through names of available protocols.
  *
  * @param opaque A private pointer representing current protocol.
diff --git a/libavformat/aviobuf.c b/libavformat/aviobuf.c
index d2eaf36..09f74b2 100644
--- a/libavformat/aviobuf.c
+++ b/libavformat/aviobuf.c
@@ -963,3 +963,27 @@  int avio_close_dyn_buf(AVIOContext *s, uint8_t **pbuffer)
     av_free(s);
     return size - padding;
 }
+
+int avio_reset_dyn_buf(AVIOContext *s, uint8_t **pbuffer)
+{
+    DynBuffer *d = s->opaque;
+    int size;
+    static const char padbuf[FF_INPUT_BUFFER_PADDING_SIZE] = {0};
+    int padding = 0;
+
+    /* don't attempt to pad fixed-size packet buffers */
+    if (!s->max_packet_size) {
+        avio_write(s, padbuf, sizeof(padbuf));
+        padding = FF_INPUT_BUFFER_PADDING_SIZE;
+    }
+
+    avio_flush(s);
+
+    *pbuffer = d->buffer;
+    size = d->size - padding;
+
+    avio_seek(s, 0, SEEK_SET);
+    d->size = 0;
+
+    return size;
+}
diff --git a/libavformat/version.h b/libavformat/version.h
index 8e6c76f..73fb7c1 100644
--- a/libavformat/version.h
+++ b/libavformat/version.h
@@ -30,7 +30,7 @@ 
 #include "libavutil/avutil.h"
 
 #define LIBAVFORMAT_VERSION_MAJOR 55
-#define LIBAVFORMAT_VERSION_MINOR  1
+#define LIBAVFORMAT_VERSION_MINOR  2
 #define LIBAVFORMAT_VERSION_MICRO  0
 
 #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \