Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/videolan/dav1d.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNiklas Haas <git@haasn.xyz>2021-01-26 20:04:21 +0300
committerJean-Baptiste Kempf <jb@videolan.org>2021-02-06 12:50:52 +0300
commit61b654567826d3d9ecf358edcb51e7d0985c4f66 (patch)
tree67220170fad4bb6fea053e308be749889595d40b /examples
parent06e8ed37d32c6bf2b37d8a67d7445181c946a9ca (diff)
dav1dplay: Update/modernize placebo-based renderer
Upstream libplacebo added support for dav1d integration directly, allowing us to vastly simplify all of this code. In order to take advantage of new optimizations, I had to allow update_frame to unref the Dav1dPicture. (This is fine, since double unref is a no-op) In addition, some of the functions we use were deprecated in recent libplacebo versions, so since we're taking a new dependency we might as well fix the deprecation warnings.
Diffstat (limited to 'examples')
-rw-r--r--examples/dav1dplay.c2
-rw-r--r--examples/dp_renderer.h2
-rw-r--r--examples/dp_renderer_placebo.c358
-rw-r--r--examples/meson.build2
4 files changed, 33 insertions, 331 deletions
diff --git a/examples/dav1dplay.c b/examples/dav1dplay.c
index b3ab40e..e5379f4 100644
--- a/examples/dav1dplay.c
+++ b/examples/dav1dplay.c
@@ -317,8 +317,8 @@ static void dp_rd_ctx_post_event(Dav1dPlayRenderContext *rd_ctx, uint32_t type)
static void dp_rd_ctx_update_with_dav1d_picture(Dav1dPlayRenderContext *rd_ctx,
Dav1dPicture *dav1d_pic)
{
- renderer_info->update_frame(rd_ctx->rd_priv, dav1d_pic, &rd_ctx->settings);
rd_ctx->current_ts = dav1d_pic->m.timestamp;
+ renderer_info->update_frame(rd_ctx->rd_priv, dav1d_pic, &rd_ctx->settings);
}
/**
diff --git a/examples/dp_renderer.h b/examples/dp_renderer.h
index 19dcf07..75276da 100644
--- a/examples/dp_renderer.h
+++ b/examples/dp_renderer.h
@@ -87,7 +87,7 @@ typedef struct rdr_info
void (*destroy_renderer)(void *cookie);
// Callback to the render function that renders a prevously sent frame
void (*render)(void *cookie, const Dav1dPlaySettings *settings);
- // Callback to the send frame function
+ // Callback to the send frame function, _may_ also unref dav1d_pic!
int (*update_frame)(void *cookie, Dav1dPicture *dav1d_pic,
const Dav1dPlaySettings *settings);
// Callback for alloc/release pictures (optional)
diff --git a/examples/dp_renderer_placebo.c b/examples/dp_renderer_placebo.c
index cca532f..320df4e 100644
--- a/examples/dp_renderer_placebo.c
+++ b/examples/dp_renderer_placebo.c
@@ -30,7 +30,7 @@
#include <assert.h>
#include <libplacebo/renderer.h>
-#include <libplacebo/utils/upload.h>
+#include <libplacebo/utils/dav1d.h>
#ifdef HAVE_PLACEBO_VULKAN
# include <libplacebo/vulkan.h>
@@ -72,7 +72,7 @@ typedef struct renderer_priv_ctx
// Lock protecting access to the texture
SDL_mutex *lock;
// Image to render, and planes backing them
- struct pl_image image;
+ struct pl_frame image;
const struct pl_tex *plane_tex[3];
} Dav1dPlayRendererPrivateContext;
@@ -319,22 +319,15 @@ static void placebo_render(void *cookie, const Dav1dPlaySettings *settings)
if (settings->highquality)
render_params = pl_render_default_params;
- struct pl_render_target target;
- pl_render_target_from_swapchain(&target, &frame);
- target.profile = (struct pl_icc_profile) {
- .data = NULL,
- .len = 0,
- };
-
-#if PL_API_VER >= 66
- pl_rect2df_aspect_copy(&target.dst_rect, &rd_priv_ctx->image.src_rect, 0.0);
- if (pl_render_target_partial(&target))
- pl_tex_clear(rd_priv_ctx->gpu, target.fbo, (float[4]){ 0.0 });
-#endif
+ struct pl_frame target;
+ pl_frame_from_swapchain(&target, &frame);
+ pl_rect2df_aspect_copy(&target.crop, &rd_priv_ctx->image.crop, 0.0);
+ if (pl_frame_is_cropped(&target))
+ pl_tex_clear(rd_priv_ctx->gpu, frame.fbo, (float[4]){ 0.0 });
if (!pl_render_image(rd_priv_ctx->renderer, &rd_priv_ctx->image, &target, &render_params)) {
fprintf(stderr, "Failed rendering frame!\n");
- pl_tex_clear(rd_priv_ctx->gpu, target.fbo, (float[4]){ 1.0 });
+ pl_tex_clear(rd_priv_ctx->gpu, frame.fbo, (float[4]){ 1.0 });
}
ok = pl_swapchain_submit_frame(rd_priv_ctx->swapchain);
@@ -351,320 +344,37 @@ static void placebo_render(void *cookie, const Dav1dPlaySettings *settings)
static int placebo_upload_image(void *cookie, Dav1dPicture *dav1d_pic,
const Dav1dPlaySettings *settings)
{
- Dav1dPlayRendererPrivateContext *rd_priv_ctx = cookie;
- assert(rd_priv_ctx != NULL);
-
- SDL_LockMutex(rd_priv_ctx->lock);
-
- if (dav1d_pic == NULL) {
- SDL_UnlockMutex(rd_priv_ctx->lock);
- return 0;
- }
-
- int width = dav1d_pic->p.w;
- int height = dav1d_pic->p.h;
- int sub_x = 0, sub_y = 0;
- int bytes = (dav1d_pic->p.bpc + 7) / 8; // rounded up
- enum pl_chroma_location chroma_loc = PL_CHROMA_UNKNOWN;
-
- struct pl_image *image = &rd_priv_ctx->image;
- *image = (struct pl_image) {
- .num_planes = 3,
- .width = width,
- .height = height,
- .src_rect = {0, 0, width, height},
-
- .repr = {
- .bits = {
- .sample_depth = bytes * 8,
- .color_depth = dav1d_pic->p.bpc,
- },
- },
- };
-
- // Figure out the correct plane dimensions/count
- switch (dav1d_pic->p.layout) {
- case DAV1D_PIXEL_LAYOUT_I400:
- image->num_planes = 1;
- break;
- case DAV1D_PIXEL_LAYOUT_I420:
- sub_x = sub_y = 1;
- break;
- case DAV1D_PIXEL_LAYOUT_I422:
- sub_x = 1;
- break;
- case DAV1D_PIXEL_LAYOUT_I444:
- break;
- }
-
- // Set the right colorspace metadata etc.
- switch (dav1d_pic->seq_hdr->pri) {
- case DAV1D_COLOR_PRI_UNKNOWN: image->color.primaries = PL_COLOR_PRIM_UNKNOWN; break;
- case DAV1D_COLOR_PRI_BT709: image->color.primaries = PL_COLOR_PRIM_BT_709; break;
- case DAV1D_COLOR_PRI_BT470M: image->color.primaries = PL_COLOR_PRIM_BT_470M; break;
- case DAV1D_COLOR_PRI_BT470BG: image->color.primaries = PL_COLOR_PRIM_BT_601_625; break;
- case DAV1D_COLOR_PRI_BT601: image->color.primaries = PL_COLOR_PRIM_BT_601_625; break;
- case DAV1D_COLOR_PRI_BT2020: image->color.primaries = PL_COLOR_PRIM_BT_2020; break;
-
- case DAV1D_COLOR_PRI_XYZ:
- // Handled below
- assert(dav1d_pic->seq_hdr->mtrx == DAV1D_MC_IDENTITY);
- break;
-
- default:
- printf("warning: unknown dav1d color primaries %d.. ignoring, picture "
- "may be very incorrect\n", dav1d_pic->seq_hdr->pri);
- break;
- }
-
- switch (dav1d_pic->seq_hdr->trc) {
- case DAV1D_TRC_BT709:
- case DAV1D_TRC_BT470M:
- case DAV1D_TRC_BT470BG:
- case DAV1D_TRC_BT601:
- case DAV1D_TRC_SMPTE240:
- case DAV1D_TRC_BT2020_10BIT:
- case DAV1D_TRC_BT2020_12BIT:
- // These all map to the effective "SDR" CRT-based EOTF, BT.1886
- image->color.transfer = PL_COLOR_TRC_BT_1886;
- break;
-
- case DAV1D_TRC_UNKNOWN: image->color.transfer = PL_COLOR_TRC_UNKNOWN; break;
- case DAV1D_TRC_LINEAR: image->color.transfer = PL_COLOR_TRC_LINEAR; break;
- case DAV1D_TRC_SRGB: image->color.transfer = PL_COLOR_TRC_SRGB; break;
- case DAV1D_TRC_SMPTE2084: image->color.transfer = PL_COLOR_TRC_PQ; break;
- case DAV1D_TRC_HLG: image->color.transfer = PL_COLOR_TRC_HLG; break;
-
- default:
- printf("warning: unknown dav1d color transfer %d.. ignoring, picture "
- "may be very incorrect\n", dav1d_pic->seq_hdr->trc);
- break;
- }
-
- switch (dav1d_pic->seq_hdr->mtrx) {
- case DAV1D_MC_IDENTITY:
- // This is going to be either RGB or XYZ
- if (dav1d_pic->seq_hdr->pri == DAV1D_COLOR_PRI_XYZ) {
- image->repr.sys = PL_COLOR_SYSTEM_XYZ;
- } else {
- image->repr.sys = PL_COLOR_SYSTEM_RGB;
- }
- break;
-
- case DAV1D_MC_UNKNOWN:
- // PL_COLOR_SYSTEM_UNKNOWN maps to RGB, so hard-code this one
- image->repr.sys = pl_color_system_guess_ycbcr(width, height);
- break;
-
- case DAV1D_MC_BT709: image->repr.sys = PL_COLOR_SYSTEM_BT_709; break;
- case DAV1D_MC_BT601: image->repr.sys = PL_COLOR_SYSTEM_BT_601; break;
- case DAV1D_MC_SMPTE240: image->repr.sys = PL_COLOR_SYSTEM_SMPTE_240M; break;
- case DAV1D_MC_SMPTE_YCGCO: image->repr.sys = PL_COLOR_SYSTEM_YCGCO; break;
- case DAV1D_MC_BT2020_NCL: image->repr.sys = PL_COLOR_SYSTEM_BT_2020_NC; break;
- case DAV1D_MC_BT2020_CL: image->repr.sys = PL_COLOR_SYSTEM_BT_2020_C; break;
-
- case DAV1D_MC_ICTCP:
- // This one is split up based on the actual HDR curve in use
- if (dav1d_pic->seq_hdr->trc == DAV1D_TRC_HLG) {
- image->repr.sys = PL_COLOR_SYSTEM_BT_2100_HLG;
- } else {
- image->repr.sys = PL_COLOR_SYSTEM_BT_2100_PQ;
- }
- break;
-
- default:
- printf("warning: unknown dav1d color matrix %d.. ignoring, picture "
- "may be very incorrect\n", dav1d_pic->seq_hdr->mtrx);
- break;
- }
-
- if (dav1d_pic->seq_hdr->color_range) {
- image->repr.levels = PL_COLOR_LEVELS_PC;
- } else {
- image->repr.levels = PL_COLOR_LEVELS_TV;
- }
-
- switch (dav1d_pic->seq_hdr->chr) {
- case DAV1D_CHR_UNKNOWN: chroma_loc = PL_CHROMA_UNKNOWN; break;
- case DAV1D_CHR_VERTICAL: chroma_loc = PL_CHROMA_LEFT; break;
- case DAV1D_CHR_COLOCATED: chroma_loc = PL_CHROMA_TOP_LEFT; break;
- }
-
-#if PL_API_VER >= 63
- if (settings->gpugrain && dav1d_pic->frame_hdr->film_grain.present) {
- Dav1dFilmGrainData *src = &dav1d_pic->frame_hdr->film_grain.data;
- struct pl_av1_grain_data *dst = &image->av1_grain;
- *dst = (struct pl_av1_grain_data) {
- .grain_seed = src->seed,
- .num_points_y = src->num_y_points,
- .chroma_scaling_from_luma = src->chroma_scaling_from_luma,
- .num_points_uv = { src->num_uv_points[0], src->num_uv_points[1] },
- .scaling_shift = src->scaling_shift,
- .ar_coeff_lag = src->ar_coeff_lag,
- .ar_coeff_shift = (int)src->ar_coeff_shift,
- .grain_scale_shift = src->grain_scale_shift,
- .uv_mult = { src->uv_mult[0], src->uv_mult[1] },
- .uv_mult_luma = { src->uv_luma_mult[0], src->uv_luma_mult[1] },
- .uv_offset = { src->uv_offset[0], src->uv_offset[1] },
- .overlap = src->overlap_flag,
- };
-
- assert(sizeof(dst->points_y) == sizeof(src->y_points));
- assert(sizeof(dst->points_uv) == sizeof(src->uv_points));
- assert(sizeof(dst->ar_coeffs_y) == sizeof(src->ar_coeffs_y));
- memcpy(dst->points_y, src->y_points, sizeof(src->y_points));
- memcpy(dst->points_uv, src->uv_points, sizeof(src->uv_points));
- memcpy(dst->ar_coeffs_y, src->ar_coeffs_y, sizeof(src->ar_coeffs_y));
-
- // this one has different row sizes for alignment
- for (int c = 0; c < 2; c++) {
- for (int i = 0; i < 25; i++)
- dst->ar_coeffs_uv[c][i] = src->ar_coeffs_uv[c][i];
- }
- }
-#endif
-
- // Upload the actual planes
- struct pl_plane_data data[3] = {
- {
- // Y plane
- .type = PL_FMT_UNORM,
- .width = width,
- .height = height,
- .pixel_stride = bytes,
- .row_stride = dav1d_pic->stride[0],
- .component_size = {bytes * 8},
- .component_map = {0},
- }, {
- // U plane
- .type = PL_FMT_UNORM,
- .width = width >> sub_x,
- .height = height >> sub_y,
- .pixel_stride = bytes,
- .row_stride = dav1d_pic->stride[1],
- .component_size = {bytes * 8},
- .component_map = {1},
- }, {
- // V plane
- .type = PL_FMT_UNORM,
- .width = width >> sub_x,
- .height = height >> sub_y,
- .pixel_stride = bytes,
- .row_stride = dav1d_pic->stride[1],
- .component_size = {bytes * 8},
- .component_map = {2},
- },
+ Dav1dPlayRendererPrivateContext *p = cookie;
+ assert(p != NULL);
+ int ret = 0;
+
+ if (!dav1d_pic)
+ return ret;
+
+ struct pl_dav1d_upload_params params = {
+ .picture = dav1d_pic,
+ .film_grain = settings->gpugrain,
+ .gpu_allocated = settings->zerocopy,
+ .asynchronous = true,
};
- bool ok = true;
-
- for (int i = 0; i < image->num_planes; i++) {
- if (settings->zerocopy) {
- const struct pl_buf *buf = dav1d_pic->allocator_data;
- assert(buf);
- data[i].buf = buf;
- data[i].buf_offset = (uintptr_t) dav1d_pic->data[i] - (uintptr_t) buf->data;
- } else {
- data[i].pixels = dav1d_pic->data[i];
- }
-
- ok &= pl_upload_plane(rd_priv_ctx->gpu, &image->planes[i], &rd_priv_ctx->plane_tex[i], &data[i]);
- }
-
- // Apply the correct chroma plane shift. This has to be done after pl_upload_plane
-#if PL_API_VER >= 67
- pl_image_set_chroma_location(image, chroma_loc);
-#else
- pl_chroma_location_offset(chroma_loc, &image->planes[1].shift_x, &image->planes[1].shift_y);
- pl_chroma_location_offset(chroma_loc, &image->planes[2].shift_x, &image->planes[2].shift_y);
-#endif
-
- if (!ok) {
+ SDL_LockMutex(p->lock);
+ if (!pl_upload_dav1dpicture(p->gpu, &p->image, p->plane_tex, &params)) {
fprintf(stderr, "Failed uploading planes!\n");
- *image = (struct pl_image) {0};
+ p->image = (struct pl_frame) {0};
+ ret = -1;
}
-
- SDL_UnlockMutex(rd_priv_ctx->lock);
- return !ok;
+ SDL_UnlockMutex(p->lock);
+ return ret;
}
-// Align to power of 2
-#define ALIGN2(x, align) (((x) + (align) - 1) & ~((align) - 1))
-
-static int placebo_alloc_pic(Dav1dPicture *const p, void *cookie)
+static int placebo_alloc_pic(Dav1dPicture *const pic, void *cookie)
{
Dav1dPlayRendererPrivateContext *rd_priv_ctx = cookie;
assert(rd_priv_ctx != NULL);
- SDL_LockMutex(rd_priv_ctx->lock);
- const struct pl_gpu *gpu = rd_priv_ctx->gpu;
- int ret = DAV1D_ERR(ENOMEM);
-
- // Copied from dav1d_default_picture_alloc
- const int hbd = p->p.bpc > 8;
- const int aligned_w = ALIGN2(p->p.w, 128);
- const int aligned_h = ALIGN2(p->p.h, 128);
- const int has_chroma = p->p.layout != DAV1D_PIXEL_LAYOUT_I400;
- const int ss_ver = p->p.layout == DAV1D_PIXEL_LAYOUT_I420;
- const int ss_hor = p->p.layout != DAV1D_PIXEL_LAYOUT_I444;
- p->stride[0] = aligned_w << hbd;
- p->stride[1] = has_chroma ? (aligned_w >> ss_hor) << hbd : 0;
-
- // Align strides up to multiples of the GPU performance hints
- p->stride[0] = ALIGN2(p->stride[0], gpu->limits.align_tex_xfer_stride);
- p->stride[1] = ALIGN2(p->stride[1], gpu->limits.align_tex_xfer_stride);
-
- // Aligning offsets to 4 also implicity aligns to the texel size (1 or 2)
- size_t off_align = ALIGN2(gpu->limits.align_tex_xfer_offset, 4);
- const size_t y_sz = ALIGN2(p->stride[0] * aligned_h, off_align);
- const size_t uv_sz = ALIGN2(p->stride[1] * (aligned_h >> ss_ver), off_align);
-
- // The extra DAV1D_PICTURE_ALIGNMENTs are to brute force plane alignment,
- // even in the case that the driver gives us insane alignments
- const size_t pic_size = y_sz + 2 * uv_sz;
- const size_t total_size = pic_size + DAV1D_PICTURE_ALIGNMENT * 4;
-
- // Validate size limitations
- if (total_size > gpu->limits.max_xfer_size) {
- printf("alloc of %zu bytes exceeds limits\n", total_size);
- goto err;
- }
-
- const struct pl_buf *buf = pl_buf_create(gpu, &(struct pl_buf_params) {
- .type = PL_BUF_TEX_TRANSFER,
- .host_mapped = true,
- .size = total_size,
- .memory_type = PL_BUF_MEM_HOST,
- .user_data = p,
- });
-
- if (!buf) {
- printf("alloc of GPU mapped buffer failed\n");
- goto err;
- }
-
- assert(buf->data);
- uintptr_t base = (uintptr_t) buf->data, data[3];
- data[0] = ALIGN2(base, DAV1D_PICTURE_ALIGNMENT);
- data[1] = ALIGN2(data[0] + y_sz, DAV1D_PICTURE_ALIGNMENT);
- data[2] = ALIGN2(data[1] + uv_sz, DAV1D_PICTURE_ALIGNMENT);
-
- // Sanity check offset alignment for the sake of debugging
- if (data[0] - base != ALIGN2(data[0] - base, off_align) ||
- data[1] - base != ALIGN2(data[1] - base, off_align) ||
- data[2] - base != ALIGN2(data[2] - base, off_align))
- {
- printf("GPU buffer horribly misaligned, expect slowdown!\n");
- }
-
- p->allocator_data = (void *) buf;
- p->data[0] = (void *) data[0];
- p->data[1] = (void *) data[1];
- p->data[2] = (void *) data[2];
- ret = 0;
-
- // fall through
-err:
+ SDL_LockMutex(rd_priv_ctx->lock);
+ int ret = pl_allocate_dav1dpicture(pic, rd_priv_ctx->gpu);
SDL_UnlockMutex(rd_priv_ctx->lock);
return ret;
}
@@ -673,11 +383,9 @@ static void placebo_release_pic(Dav1dPicture *pic, void *cookie)
{
Dav1dPlayRendererPrivateContext *rd_priv_ctx = cookie;
assert(rd_priv_ctx != NULL);
- assert(pic->allocator_data);
SDL_LockMutex(rd_priv_ctx->lock);
- const struct pl_gpu *gpu = rd_priv_ctx->gpu;
- pl_buf_destroy(gpu, (const struct pl_buf **) &pic->allocator_data);
+ pl_release_dav1dpicture(pic, rd_priv_ctx->gpu);
SDL_UnlockMutex(rd_priv_ctx->lock);
}
@@ -690,10 +398,7 @@ const Dav1dPlayRenderInfo rdr_placebo_vk = {
.update_frame = placebo_upload_image,
.alloc_pic = placebo_alloc_pic,
.release_pic = placebo_release_pic,
-
-# if PL_API_VER >= 63
.supports_gpu_grain = 1,
-# endif
};
#else
const Dav1dPlayRenderInfo rdr_placebo_vk = { NULL };
@@ -706,10 +411,7 @@ const Dav1dPlayRenderInfo rdr_placebo_gl = {
.destroy_renderer = placebo_renderer_destroy,
.render = placebo_render,
.update_frame = placebo_upload_image,
-
-# if PL_API_VER >= 63
.supports_gpu_grain = 1,
-# endif
};
#else
const Dav1dPlayRenderInfo rdr_placebo_gl = { NULL };
diff --git a/examples/meson.build b/examples/meson.build
index 50e097a..9bca088 100644
--- a/examples/meson.build
+++ b/examples/meson.build
@@ -46,7 +46,7 @@ if sdl2_dependency.found()
dav1dplay_deps = [sdl2_dependency]
dav1dplay_cflags = []
- placebo_dependency = dependency('libplacebo', version: '>= 1.18.0', required: false)
+ placebo_dependency = dependency('libplacebo', version: '>= 3.110.0', required: false)
if placebo_dependency.found()
dav1dplay_deps += placebo_dependency