Commit f53749e1 authored by Ronald S. Bultje's avatar Ronald S. Bultje

Wrappable data structure

parent f4e88f25
......@@ -44,6 +44,18 @@ typedef struct Dav1dData {
*/
DAV1D_API int dav1d_data_create(Dav1dData *data, size_t sz);
/**
* Wrap an existing data packet.
* $ptr/$sz are the pointer and size of the data to be wrapped.
* $free_callback/$user_data are a function and function argument to be
* called when we release our last reference to this data. In this callback,
* $data will be the $ptr argument to this function, and $user_data will be
* the $user_data input argument to this function.
*/
DAV1D_API int dav1d_data_wrap(Dav1dData *data, uint8_t *ptr, size_t sz,
void (*free_callback)(uint8_t *data, void *user_data),
void *user_data);
/**
* Free data.
*/
......
......@@ -48,6 +48,22 @@ int dav1d_data_create(Dav1dData *const buf, const size_t sz) {
return 0;
}
int dav1d_data_wrap(Dav1dData *const buf, uint8_t *const ptr, const size_t sz,
void (*free_callback)(uint8_t *data, void *user_data),
void *user_data)
{
validate_input_or_ret(buf != NULL, -EINVAL);
validate_input_or_ret(ptr != NULL, -EINVAL);
validate_input_or_ret(free_callback != NULL, -EINVAL);
buf->ref = dav1d_ref_wrap(ptr, sz, free_callback, user_data);
if (!buf->ref) return -ENOMEM;
buf->data = ptr;
buf->sz = sz;
return 0;
}
void dav1d_data_unref(Dav1dData *const buf) {
dav1d_ref_dec(buf->ref);
memset(buf, 0, sizeof(*buf));
......
......@@ -31,6 +31,10 @@
#include "src/ref.h"
static void default_free_callback(uint8_t *const data, void *const user_data) {
dav1d_free_aligned(data);
}
Dav1dRef *dav1d_ref_create(const size_t size) {
Dav1dRef *res = malloc(sizeof(Dav1dRef));
void *data = dav1d_alloc_aligned(size, 32);
......@@ -44,6 +48,23 @@ Dav1dRef *dav1d_ref_create(const size_t size) {
res->size = size;
atomic_init(&res->ref_cnt, 1);
res->data = data;
res->free_callback = default_free_callback;
return res;
}
Dav1dRef *dav1d_ref_wrap(uint8_t *const ptr, const size_t sz,
void (*free_callback)(uint8_t *data, void *user_data),
void *user_data)
{
Dav1dRef *res = malloc(sizeof(Dav1dRef));
if (!res) return NULL;
res->data = ptr;
res->size = sz;
atomic_init(&res->ref_cnt, 1);
res->free_callback = free_callback;
res->user_data = user_data;
return res;
}
......@@ -54,7 +75,7 @@ void dav1d_ref_inc(Dav1dRef *const ref) {
void dav1d_ref_dec(Dav1dRef *const ref) {
if (atomic_fetch_sub(&ref->ref_cnt, 1) == 1) {
dav1d_free_aligned(ref->data);
ref->free_callback(ref->data, ref->user_data);
free(ref);
}
}
......@@ -37,9 +37,14 @@ struct Dav1dRef {
void *data;
size_t size;
atomic_int ref_cnt;
void (*free_callback)(uint8_t *data, void *user_data);
void *user_data;
};
Dav1dRef *dav1d_ref_create(size_t size);
Dav1dRef *dav1d_ref_wrap(uint8_t *ptr, size_t sz,
void (*free_callback)(uint8_t *data, void *user_data),
void *user_data);
void dav1d_ref_inc(Dav1dRef *ref);
void dav1d_ref_dec(Dav1dRef *ref);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment