Minimize Dav1dRef allocations

In many cases it can be combined with the allocation of the data
being referenced instead of allocating it separately.
This commit is contained in:
Henrik Gramner 2023-05-26 14:06:29 +02:00 committed by Henrik Gramner
parent 74fa5b04a5
commit 253e46604e
6 changed files with 28 additions and 39 deletions

View File

@ -64,8 +64,10 @@ int dav1d_data_wrap_internal(Dav1dData *const buf, const uint8_t *const ptr,
validate_input_or_ret(ptr != NULL, DAV1D_ERR(EINVAL));
validate_input_or_ret(free_callback != NULL, DAV1D_ERR(EINVAL));
buf->ref = dav1d_ref_wrap(ptr, free_callback, cookie);
if (!buf->ref) return DAV1D_ERR(ENOMEM);
Dav1dRef *const ref = malloc(sizeof(Dav1dRef));
if (!ref) return DAV1D_ERR(ENOMEM);
buf->ref = dav1d_ref_init(ref, ptr, free_callback, cookie, 1);
buf->data = ptr;
buf->sz = sz;
dav1d_data_props_set_defaults(&buf->m);
@ -83,8 +85,10 @@ int dav1d_data_wrap_user_data_internal(Dav1dData *const buf,
validate_input_or_ret(buf != NULL, DAV1D_ERR(EINVAL));
validate_input_or_ret(free_callback != NULL, DAV1D_ERR(EINVAL));
buf->m.user_data.ref = dav1d_ref_wrap(user_data, free_callback, cookie);
if (!buf->m.user_data.ref) return DAV1D_ERR(ENOMEM);
Dav1dRef *const ref = malloc(sizeof(Dav1dRef));
if (!ref) return DAV1D_ERR(ENOMEM);
buf->m.user_data.ref = dav1d_ref_init(ref, user_data, free_callback, cookie, 1);
buf->m.user_data.data = user_data;
return 0;

View File

@ -1508,12 +1508,8 @@ int dav1d_parse_obus(Dav1dContext *const c, Dav1dData *const in, const int globa
assert(!c->itut_t35_ref);
itut_t35_ctx = malloc(sizeof(struct itut_t35_ctx_context));
if (!itut_t35_ctx) goto error;
c->itut_t35_ref = dav1d_ref_wrap((uint8_t *)c->itut_t35, dav1d_picture_free_itut_t35,
itut_t35_ctx);
if (!c->itut_t35_ref) {
free(itut_t35_ctx);
goto error;
}
c->itut_t35_ref = dav1d_ref_init(&itut_t35_ctx->ref, c->itut_t35,
dav1d_picture_free_itut_t35, itut_t35_ctx, 0);
} else {
assert(c->itut_t35_ref && atomic_load(&c->itut_t35_ref->ref_cnt) == 1);
itut_t35_ctx = c->itut_t35_ref->user_data;

View File

@ -89,7 +89,8 @@ void dav1d_default_picture_release(Dav1dPicture *const p, void *const cookie) {
struct pic_ctx_context {
Dav1dPicAllocator allocator;
Dav1dPicture pic;
void *extra_ptr; /* MUST BE AT THE END */
Dav1dRef ref;
void *extra_data[];
};
static void free_buffer(const uint8_t *const data, void *const user_data) {
@ -149,13 +150,7 @@ static int picture_alloc_with_edges(Dav1dContext *const c,
pic_ctx->allocator = *p_allocator;
pic_ctx->pic = *p;
if (!(p->ref = dav1d_ref_wrap((const uint8_t *)buf, free_buffer, c->pic_ctx_pool))) {
p_allocator->release_picture_callback(p, p_allocator->cookie);
dav1d_mem_pool_push(c->pic_ctx_pool, buf);
dav1d_log(c, "Failed to wrap picture: %s\n", strerror(errno));
return DAV1D_ERR(ENOMEM);
}
p->ref = dav1d_ref_init(&pic_ctx->ref, buf, free_buffer, c->pic_ctx_pool, 0);
p->seq_hdr_ref = seq_hdr_ref;
if (seq_hdr_ref) dav1d_ref_inc(seq_hdr_ref);
@ -164,7 +159,7 @@ static int picture_alloc_with_edges(Dav1dContext *const c,
if (frame_hdr_ref) dav1d_ref_inc(frame_hdr_ref);
if (extra && extra_ptr)
*extra_ptr = &pic_ctx->extra_ptr;
*extra_ptr = &pic_ctx->extra_data;
return 0;
}

View File

@ -104,6 +104,7 @@ void dav1d_picture_unref_internal(Dav1dPicture *p);
struct itut_t35_ctx_context {
Dav1dITUTT35 *itut_t35;
size_t n_itut_t35;
Dav1dRef ref;
};
void dav1d_picture_free_itut_t35(const uint8_t *data, void *user_data);

View File

@ -71,23 +71,6 @@ Dav1dRef *dav1d_ref_create_using_pool(Dav1dMemPool *const pool, size_t size) {
return res;
}
Dav1dRef *dav1d_ref_wrap(const uint8_t *const ptr,
void (*free_callback)(const uint8_t *data, void *user_data),
void *const user_data)
{
Dav1dRef *res = malloc(sizeof(Dav1dRef));
if (!res) return NULL;
res->data = NULL;
res->const_data = ptr;
atomic_init(&res->ref_cnt, 1);
res->free_ref = 1;
res->free_callback = free_callback;
res->user_data = user_data;
return res;
}
void dav1d_ref_dec(Dav1dRef **const pref) {
assert(pref != NULL);

View File

@ -47,12 +47,22 @@ struct Dav1dRef {
Dav1dRef *dav1d_ref_create(size_t size);
Dav1dRef *dav1d_ref_create_using_pool(Dav1dMemPool *pool, size_t size);
Dav1dRef *dav1d_ref_wrap(const uint8_t *ptr,
void (*free_callback)(const uint8_t *data, void *user_data),
void *user_data);
void dav1d_ref_dec(Dav1dRef **ref);
int dav1d_ref_is_writable(Dav1dRef *ref);
static inline Dav1dRef *dav1d_ref_init(Dav1dRef *const ref, const void *const ptr,
void (*const free_callback)(const uint8_t *data, void *user_data),
void *const user_data, const int free_ref)
{
ref->data = NULL;
ref->const_data = ptr;
atomic_init(&ref->ref_cnt, 1);
ref->free_ref = free_ref;
ref->free_callback = free_callback;
ref->user_data = user_data;
return ref;
}
static inline void dav1d_ref_inc(Dav1dRef *const ref) {
atomic_fetch_add_explicit(&ref->ref_cnt, 1, memory_order_relaxed);
}