aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLukasz Marek <lukasz.m.luki@gmail.com>2014-02-23 23:19:23 +0100
committerMichael Niedermayer <michaelni@gmx.at>2014-02-25 01:38:52 +0100
commit3144440004941aa22ffea9933f5e5dfe826df654 (patch)
tree2a9ad89a5f6a7ddb3b4c3151f6fa6150842dc746
parent774239be717150909219ad2c0696bfb6a50cf2cb (diff)
downloadffmpeg-3144440004941aa22ffea9933f5e5dfe826df654.tar.gz
lavu/buffer: add release function
new function allows to unref buffer and obtain its data. Signed-off-by: Lukasz Marek <lukasz.m.luki@gmail.com> Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
-rw-r--r--libavutil/buffer.c29
-rw-r--r--libavutil/buffer.h12
2 files changed, 41 insertions, 0 deletions
diff --git a/libavutil/buffer.c b/libavutil/buffer.c
index e9bf54b96c..e8ec2c97e0 100644
--- a/libavutil/buffer.c
+++ b/libavutil/buffer.c
@@ -117,6 +117,35 @@ void av_buffer_unref(AVBufferRef **buf)
}
}
+int av_buffer_release(AVBufferRef **buf, uint8_t **data)
+{
+ AVBuffer *b;
+ int ret = 0;
+
+ if (data)
+ *data = NULL;
+ if (!buf || !*buf)
+ return 0;
+ b = (*buf)->buffer;
+ av_freep(buf);
+
+ if (data && avpriv_atomic_int_get(&b->refcount) > 1) {
+ *data = av_memdup(b->data, b->size);
+ if (!*data)
+ ret = AVERROR(ENOMEM);
+ }
+
+ if (!avpriv_atomic_int_add_and_fetch(&b->refcount, -1)) {
+ if (data && !*data) {
+ ret = 0;
+ *data = b->data;
+ } else
+ b->free(b->opaque, b->data);
+ av_freep(&b);
+ }
+ return ret;
+}
+
int av_buffer_is_writable(const AVBufferRef *buf)
{
if (buf->buffer->flags & AV_BUFFER_FLAG_READONLY)
diff --git a/libavutil/buffer.h b/libavutil/buffer.h
index b4399fd39f..8cf2cbf302 100644
--- a/libavutil/buffer.h
+++ b/libavutil/buffer.h
@@ -155,6 +155,18 @@ AVBufferRef *av_buffer_ref(AVBufferRef *buf);
void av_buffer_unref(AVBufferRef **buf);
/**
+ * Free a given reference and pass underlaying data to user provided pointer.
+ * If there is more than one reference then data is copied.
+ *
+ * @param buf the reference to be released. The pointer is set to NULL on return.
+ * @param data pointer to be passed with underlaying data.
+ * @return 0 on success, a negative AVERROR on failure.
+ *
+ * @note on error buffer is properly released and *data is set to NULL.
+ */
+int av_buffer_release(AVBufferRef **buf, uint8_t **data);
+
+/**
* @return 1 if the caller may write to the data referred to by buf (which is
* true if and only if buf is the only reference to the underlying AVBuffer).
* Return 0 otherwise.