Commit af3a0d16 authored by Steve Lhomme's avatar Steve Lhomme

WIP add support for a external Dav1dPicAllocator allocators

* add documentation on the callbacks
parent 3b5b66ad
Pipeline #969 passed with stage
in 3 minutes and 12 seconds
......@@ -38,6 +38,7 @@ typedef struct Dav1dRef Dav1dRef;
typedef struct Dav1dSettings {
int n_frame_threads;
int n_tile_threads;
Dav1dPicAllocator allocator;
} Dav1dSettings;
/**
......
......@@ -147,6 +147,17 @@ typedef struct Dav1dPicture {
void *allocator_tag; ///< pointer managed by the allocator
} Dav1dPicture;
typedef struct Dav1dPicAllocator {
void *cookie;
/**
* Needs to fill the picture data[0], data[1], data[2].
* The allocator can fill the picture allocator_tag pointer with a custom
* pointer that will be passed to pf_release_picture().
*/
uint8_t* (*pf_alloc_picture)(Dav1dPicture *, void* cookie);
void (*pf_release_picture)(uint8_t *, void *allocator_tag, void* cookie);
} Dav1dPicAllocator;
/**
* Release reference to a picture.
*/
......
......@@ -2785,7 +2785,8 @@ int dav1d_submit_frame(Dav1dContext *const c) {
f->frame_hdr.height,
f->seq_hdr.layout, f->seq_hdr.bpc,
c->n_fc > 1 ? &f->frame_thread.td : NULL,
f->frame_hdr.show_frame)) < 0)
f->frame_hdr.show_frame,
&c->allocator)) < 0)
{
return res;
}
......
......@@ -109,6 +109,8 @@ struct Dav1dContext {
EdgeTip tip_sb128[256];
EdgeTip tip_sb64[64];
} intra_edge;
Dav1dPicAllocator allocator;
};
struct Dav1dFrameContext {
......
......@@ -57,6 +57,9 @@ const char *dav1d_version(void) {
void dav1d_default_settings(Dav1dSettings *const s) {
s->n_frame_threads = 1;
s->n_tile_threads = 1;
s->allocator.cookie = NULL;
s->allocator.pf_alloc_picture = default_picture_allocator;
s->allocator.pf_release_picture = default_picture_release;
}
int dav1d_open(Dav1dContext **const c_out,
......@@ -76,6 +79,12 @@ int dav1d_open(Dav1dContext **const c_out,
if (!c) goto error;
memset(c, 0, sizeof(*c));
c->allocator = s->allocator;
if (!c->allocator.pf_alloc_picture || !c->allocator.pf_release_picture) {
c->allocator.pf_alloc_picture = default_picture_allocator;
c->allocator.pf_release_picture = default_picture_release;
c->allocator.cookie = NULL;
}
c->n_fc = s->n_frame_threads;
c->fc = dav1d_alloc_aligned(sizeof(*c->fc) * s->n_frame_threads, 32);
if (!c->fc) goto error;
......
......@@ -41,7 +41,8 @@
#include "src/ref.h"
#include "src/thread.h"
static uint8_t* default_picture_allocator(Dav1dPicture *const p) {
uint8_t* default_picture_allocator(Dav1dPicture *const p, void *cookie) {
assert(cookie == NULL);
const int ss_ver = p->p.layout == DAV1D_PIXEL_LAYOUT_I420;
const int aligned_h = (p->p.h + 127) & ~127;
const size_t y_sz = p->stride[0] * aligned_h;
......@@ -66,17 +67,35 @@ static uint8_t* default_picture_allocator(Dav1dPicture *const p) {
return data;
}
static void default_picture_release(uint8_t *const data, void *const allocator_tag) {
void default_picture_release(uint8_t *const data, void *const allocator_tag,
void *cookie) {
assert(cookie == NULL);
#ifndef NDEBUG /* safety check */
assert(allocator_tag == data);
#endif
dav1d_free_aligned(data);
}
struct pic_ctx_context {
Dav1dPicAllocator *p_allocator;
void *allocator_tag;
};
static void free_buffer(uint8_t *data, void *user_data)
{
struct pic_ctx_context *pic_ctx = user_data;
pic_ctx->p_allocator->pf_release_picture(data,
pic_ctx->allocator_tag,
pic_ctx->p_allocator->cookie);
free(pic_ctx);
}
static int picture_alloc_with_edges(Dav1dPicture *const p,
const int w, const int h,
const enum Dav1dPixelLayout layout,
const int bpc,
Dav1dPicAllocator *const p_allocator,
const size_t extra, void **const extra_ptr)
{
if (p->data[0]) {
......@@ -85,6 +104,12 @@ static int picture_alloc_with_edges(Dav1dPicture *const p,
}
assert(bpc > 0 && bpc <= 16);
struct pic_ctx_context *pic_ctx = malloc(sizeof(struct pic_ctx_context));
if (pic_ctx == NULL) {
return -ENOMEM;
}
pic_ctx->p_allocator = p_allocator;
const int hbd = bpc > 8;
const int aligned_w = (w + 127) & ~127;
const int has_chroma = layout != DAV1D_PIXEL_LAYOUT_I400;
......@@ -99,14 +124,16 @@ static int picture_alloc_with_edges(Dav1dPicture *const p,
p->p.chr = DAV1D_CHR_UNKNOWN;
p->p.layout = layout;
p->p.bpc = bpc;
uint8_t *data = default_picture_allocator(p);
uint8_t *data = p_allocator->pf_alloc_picture(p, p_allocator->cookie);
if (data == NULL) {
free(pic_ctx);
return -ENOMEM;
}
if (!(p->ref = dav1d_ref_wrap(data, default_picture_release,
p->allocator_tag,
pic_ctx->allocator_tag = p->allocator_tag;
if (!(p->ref = dav1d_ref_wrap(data, free_buffer, pic_ctx,
extra, extra_ptr))) {
default_picture_release(data, p->allocator_tag);
p_allocator->pf_release_picture(data, p->allocator_tag,
p_allocator->cookie);
fprintf(stderr, "Failed to wrap picture: %s\n", strerror(errno));
return -ENOMEM;
}
......@@ -117,12 +144,13 @@ static int picture_alloc_with_edges(Dav1dPicture *const p,
int dav1d_thread_picture_alloc(Dav1dThreadPicture *const p,
const int w, const int h,
const enum Dav1dPixelLayout layout, const int bpc,
struct thread_data *const t, const int visible)
struct thread_data *const t, const int visible,
Dav1dPicAllocator *const p_allocator)
{
p->t = t;
const int res =
picture_alloc_with_edges(&p->p, w, h, layout, bpc,
picture_alloc_with_edges(&p->p, w, h, layout, bpc, p_allocator,
t != NULL ? sizeof(atomic_int) * 2 : 0,
(void **) &p->progress);
......
......@@ -56,7 +56,8 @@ typedef struct Dav1dThreadPicture {
*/
int dav1d_thread_picture_alloc(Dav1dThreadPicture *p, int w, int h,
enum Dav1dPixelLayout layout, int bpc,
struct thread_data *t, int visible);
struct thread_data *t, int visible,
Dav1dPicAllocator *);
/**
* Create a copy of a picture.
......@@ -88,4 +89,7 @@ void dav1d_thread_picture_wait(const Dav1dThreadPicture *p, int y,
void dav1d_thread_picture_signal(const Dav1dThreadPicture *p, int y,
enum PlaneType plane_type);
uint8_t* default_picture_allocator(Dav1dPicture *, void*cookie);
void default_picture_release(uint8_t *, void *allocator_tag, void* cookie);
#endif /* __DAV1D_SRC_PICTURE_H__ */
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