PR #24834 opened by dhalsimax URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24834 Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24834.patch
# Summary of changes Adds a fast option, off by default, that builds the kernel with -cl-fast-relaxed-math. On an Intel HD Graphics 500 a 4K HDR10 film tone mapped to 1080p goes from 0.86x to 2.67x real time, and the output differs by PSNR 54.5 dB / SSIM 0.9977. 🤖 Generated with [Claude Code](https://claude.com/claude-code) From 87f00151b44f8b6c80a2b70ea42de2fa031fc85a Mon Sep 17 00:00:00 2001 From: dhalsimax <[email protected]> Date: Thu, 1 Oct 2026 08:38:55 +0200 Subject: [PATCH] avfilter/vf_tonemap_opencl: add an option to use relaxed math The tonemap kernel spends most of its time in powr() and the other transcendental functions of the PQ/HLG and BT.709 transfer curves, four pixels per work item. Built with -cl-fast-relaxed-math it can use the native versions. On an Intel HD Graphics 500 (Gen9, Apollo Lake J3455, compute-runtime 24.35), tone mapping a minute of a 3840x1604 HDR10 film to 1920x802, with VAAPI decode and h264_vaapi encode, runs at 0.86x real time with fast=0 and at 2.67x with fast=1. The two encodes compared give PSNR 54.5 dB, SSIM 0.9977. Add a fast option, off by default, for devices where speed matters more than the last bit of precision. It reaches clBuildProgram() through a new build_opts field in OpenCLFilterContext, NULL for every other filter. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01LnW49Xq639xegtVtMcLNR4 --- doc/filters.texi | 6 ++++++ libavfilter/opencl.c | 2 +- libavfilter/opencl.h | 4 ++++ libavfilter/vf_tonemap_opencl.c | 7 +++++++ 4 files changed, 18 insertions(+), 1 deletion(-) diff --git a/doc/filters.texi b/doc/filters.texi index e8c8b23481..d86fcd09f7 100644 --- a/doc/filters.texi +++ b/doc/filters.texi @@ -28855,6 +28855,12 @@ the current frame average brightness and the current running average exceeds a threshold value, we would re-calculate scene average and peak brightness. The default value is 0.2. +@item fast +Build the OpenCL kernel with relaxed math (@code{-cl-fast-relaxed-math}), so +that the compiler can use faster and less precise versions of the functions of +the transfer curves. On slow devices this can be much faster, at the cost of a +small loss of precision. Disabled by default. + @item format Specify the output pixel format. diff --git a/libavfilter/opencl.c b/libavfilter/opencl.c index e91610a10e..ab851911e7 100644 --- a/libavfilter/opencl.c +++ b/libavfilter/opencl.c @@ -172,7 +172,7 @@ int ff_opencl_filter_load_program(AVFilterContext *avctx, } cle = clBuildProgram(ctx->program, 1, &ctx->hwctx->device_id, - NULL, NULL, NULL); + ctx->build_opts, NULL, NULL); if (cle != CL_SUCCESS) { av_log(avctx, AV_LOG_ERROR, "Failed to build program: %d.\n", cle); diff --git a/libavfilter/opencl.h b/libavfilter/opencl.h index dec376766e..3d02d65e57 100644 --- a/libavfilter/opencl.h +++ b/libavfilter/opencl.h @@ -45,6 +45,10 @@ typedef struct OpenCLFilterContext { enum AVPixelFormat output_format; int output_width; int output_height; + + // Options passed to clBuildProgram() by ff_opencl_filter_load_program(), + // NULL for none. + const char *build_opts; } OpenCLFilterContext; // Groups together information about a kernel argument diff --git a/libavfilter/vf_tonemap_opencl.c b/libavfilter/vf_tonemap_opencl.c index 2f47cfd49f..42d55aa867 100644 --- a/libavfilter/vf_tonemap_opencl.c +++ b/libavfilter/vf_tonemap_opencl.c @@ -65,6 +65,7 @@ typedef struct TonemapOpenCLContext { double desat_param; double target_peak; double scene_threshold; + int fast; int initialised; cl_kernel kernel; cl_command_queue command_queue; @@ -243,6 +244,11 @@ static int tonemap_opencl_init(AVFilterContext *avctx) opencl_sources[0] = header.str; opencl_sources[1] = ff_source_tonemap_cl; opencl_sources[2] = ff_source_colorspace_common_cl; + // The kernel is dominated by powr() and the other transcendental + // functions of the transfer curves, and relaxed math lets the compiler + // use the native ones. + if (ctx->fast) + ctx->ocf.build_opts = "-cl-fast-relaxed-math"; err = ff_opencl_filter_load_program(avctx, opencl_sources, OPENCL_SOURCE_NB); av_bprint_finalize(&header, NULL); @@ -515,6 +521,7 @@ static const AVOption tonemap_opencl_options[] = { { "param", "tonemap parameter", OFFSET(param), AV_OPT_TYPE_DOUBLE, {.dbl = NAN}, DBL_MIN, DBL_MAX, FLAGS }, { "desat", "desaturation parameter", OFFSET(desat_param), AV_OPT_TYPE_DOUBLE, {.dbl = 0.5}, 0, DBL_MAX, FLAGS }, { "threshold", "scene detection threshold", OFFSET(scene_threshold), AV_OPT_TYPE_DOUBLE, {.dbl = 0.2}, 0, DBL_MAX, FLAGS }, + { "fast", "build the kernel with relaxed math", OFFSET(fast), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, FLAGS }, { NULL } }; -- 2.52.0 _______________________________________________ ffmpeg-devel mailing list -- [email protected] To unsubscribe send an email to [email protected]
