[1/2] aviobuf: Add functions for null buffers

Message ID 1379531242-24353-1-git-send-email-martin@martin.st
State Committed
Headers show

Commit Message

Martin Storsjö Sept. 18, 2013, 7:07 p.m.
Null buffers are useful for simulating writing to a real buffer
for the sake of measuring how many bytes are written.
---
In practice this doesn't reduce the IO work completely, since
the data still is written to the intermediate IO buffer, but it
does avoid having to allocate the output buffer and copy data
into it, and simplifies the code a little for the callers.
---
 libavformat/avio_internal.h |   18 ++++++++++++++++++
 libavformat/aviobuf.c       |   33 +++++++++++++++++++++++++++++++++
 2 files changed, 51 insertions(+)

Comments

Luca Barbato Sept. 18, 2013, 7:40 p.m. | #1
On 18/09/13 21:07, Martin Storsjö wrote:
> Null buffers are useful for simulating writing to a real buffer
> for the sake of measuring how many bytes are written.
> ---
> In practice this doesn't reduce the IO work completely, since
> the data still is written to the intermediate IO buffer, but it
> does avoid having to allocate the output buffer and copy data
> into it, and simplifies the code a little for the callers.
> ---
>  libavformat/avio_internal.h |   18 ++++++++++++++++++
>  libavformat/aviobuf.c       |   33 +++++++++++++++++++++++++++++++++
>  2 files changed, 51 insertions(+)
> 

Looks nice, maybe avio_flush on close is not necessary though.

lu
Martin Storsjö Sept. 18, 2013, 7:45 p.m. | #2
On Wed, 18 Sep 2013, Luca Barbato wrote:

> On 18/09/13 21:07, Martin Storsjö wrote:
>> Null buffers are useful for simulating writing to a real buffer
>> for the sake of measuring how many bytes are written.
>> ---
>> In practice this doesn't reduce the IO work completely, since
>> the data still is written to the intermediate IO buffer, but it
>> does avoid having to allocate the output buffer and copy data
>> into it, and simplifies the code a little for the callers.
>> ---
>>  libavformat/avio_internal.h |   18 ++++++++++++++++++
>>  libavformat/aviobuf.c       |   33 +++++++++++++++++++++++++++++++++
>>  2 files changed, 51 insertions(+)
>> 
>
> Looks nice, maybe avio_flush on close is not necessary though.

It is necessary - otherwise the data will only be written in the normal 
AVIOContext buffer and not visible in d->size. (The fact that we already 
flush in avio_close is irrelevant, avio_close isn't called at all here, 
it's only paired with avio_open.)

// Martin
Luca Barbato Sept. 18, 2013, 8:07 p.m. | #3
On 18/09/13 21:45, Martin Storsjö wrote:
> On Wed, 18 Sep 2013, Luca Barbato wrote:
> 
>> On 18/09/13 21:07, Martin Storsjö wrote:
>>> Null buffers are useful for simulating writing to a real buffer
>>> for the sake of measuring how many bytes are written.
>>> ---
>>> In practice this doesn't reduce the IO work completely, since
>>> the data still is written to the intermediate IO buffer, but it
>>> does avoid having to allocate the output buffer and copy data
>>> into it, and simplifies the code a little for the callers.
>>> ---
>>>  libavformat/avio_internal.h |   18 ++++++++++++++++++
>>>  libavformat/aviobuf.c       |   33 +++++++++++++++++++++++++++++++++
>>>  2 files changed, 51 insertions(+)
>>>
>>
>> Looks nice, maybe avio_flush on close is not necessary though.
> 
> It is necessary - otherwise the data will only be written in the normal
> AVIOContext buffer and not visible in d->size. (The fact that we already
> flush in avio_close is irrelevant, avio_close isn't called at all here,
> it's only paired with avio_open.)
> 

Good call =)

Patch ok then
Diego Biurrun Sept. 19, 2013, 10:07 a.m. | #4
On Wed, Sep 18, 2013 at 10:07:21PM +0300, Martin Storsjö wrote:
> --- a/libavformat/avio_internal.h
> +++ b/libavformat/avio_internal.h
> @@ -119,4 +119,22 @@ int ffio_open_dyn_packet_buf(AVIOContext **s, int max_packet_size);
>  
> +/**
> + * Open a write only fake memory stream. The written data isn't stored

write-only, is not

I would suggest avoiding short forms in any sort of even moderately
formal written English.

Diego

Patch

diff --git a/libavformat/avio_internal.h b/libavformat/avio_internal.h
index 5493163..e3367c8 100644
--- a/libavformat/avio_internal.h
+++ b/libavformat/avio_internal.h
@@ -119,4 +119,22 @@  int ffio_open_dyn_packet_buf(AVIOContext **s, int max_packet_size);
  */
 int ffio_fdopen(AVIOContext **s, URLContext *h);
 
+/**
+ * Open a write only fake memory stream. The written data isn't stored
+ * anywhere - this is only used for measuring the amount of data
+ * written.
+ *
+ * @param s new IO context
+ * @return zero if no error.
+ */
+int ffio_open_null_buf(AVIOContext **s);
+
+/**
+ * Close a null buffer.
+ *
+ * @param s an IO context opened by ffio_open_null_buf
+ * @return the number of bytes written to the null buffer
+ */
+int ffio_close_null_buf(AVIOContext *s);
+
 #endif /* AVFORMAT_AVIO_INTERNAL_H */
diff --git a/libavformat/aviobuf.c b/libavformat/aviobuf.c
index 7d76e0b..3f27d69 100644
--- a/libavformat/aviobuf.c
+++ b/libavformat/aviobuf.c
@@ -975,3 +975,36 @@  int avio_close_dyn_buf(AVIOContext *s, uint8_t **pbuffer)
     av_free(s);
     return size - padding;
 }
+
+static int null_buf_write(void *opaque, uint8_t *buf, int buf_size)
+{
+    DynBuffer *d = opaque;
+
+    d->pos += buf_size;
+    if (d->pos > d->size)
+        d->size = d->pos;
+    return buf_size;
+}
+
+int ffio_open_null_buf(AVIOContext **s)
+{
+    int ret = url_open_dyn_buf_internal(s, 0);
+    if (ret >= 0) {
+        AVIOContext *pb = *s;
+        pb->write_packet = null_buf_write;
+    }
+    return ret;
+}
+
+int ffio_close_null_buf(AVIOContext *s)
+{
+    DynBuffer *d = s->opaque;
+    int size;
+
+    avio_flush(s);
+
+    size = d->size;
+    av_free(d);
+    av_free(s);
+    return size;
+}