FFmpeg
Loading...
Searching...
No Matches
vf_tonemap_opencl.c
Go to the documentation of this file.
1/*
2 * This file is part of FFmpeg.
3 *
4 * FFmpeg is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * FFmpeg is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with FFmpeg; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18#include <float.h>
19
20#include "libavutil/avassert.h"
21#include "libavutil/common.h"
22#include "libavutil/imgutils.h"
23#include "libavutil/opt.h"
24#include "libavutil/pixdesc.h"
25
26#include "avfilter.h"
27#include "filters.h"
28#include "opencl.h"
29#include "opencl_source.h"
30#include "video.h"
31#include "colorspace.h"
32
33// TODO:
34// - separate peak-detection from tone-mapping kernel to solve
35// one-frame-delay issue.
36// - more format support
37
38#define DETECTION_FRAMES 63
39
50
51typedef struct TonemapOpenCLContext {
53
54 enum AVColorSpace colorspace, colorspace_in, colorspace_out;
57 enum AVColorRange range, range_in, range_out;
59
60 /* enum TonemapAlgorithm */
63 double peak;
64 double param;
69 cl_kernel kernel;
70 cl_command_queue command_queue;
71 cl_mem util_mem;
73
74static const char *const linearize_funcs[] = {
75 [AVCOL_TRC_SMPTE2084] = "eotf_st2084",
76 [AVCOL_TRC_ARIB_STD_B67] = "inverse_oetf_hlg",
77};
78
79static const char *const delinearize_funcs[] = {
80 [AVCOL_TRC_BT709] = "inverse_eotf_bt1886",
81 [AVCOL_TRC_BT2020_10] = "inverse_eotf_bt1886",
82};
83
84static const char *const tonemap_func[TONEMAP_MAX] = {
85 [TONEMAP_NONE] = "direct",
86 [TONEMAP_LINEAR] = "linear",
87 [TONEMAP_GAMMA] = "gamma",
88 [TONEMAP_CLIP] = "clip",
89 [TONEMAP_REINHARD] = "reinhard",
90 [TONEMAP_HABLE] = "hable",
91 [TONEMAP_MOBIUS] = "mobius",
92};
93
95 double rgb2rgb[3][3]) {
96 double rgb2xyz[3][3], xyz2rgb[3][3];
97
100
101 if (!in_primaries || !out_primaries)
102 return AVERROR(EINVAL);
103
104 ff_fill_rgb2xyz_table(&out_primaries->prim, &out_primaries->wp, rgb2xyz);
106 ff_fill_rgb2xyz_table(&in_primaries->prim, &in_primaries->wp, rgb2xyz);
107 ff_matrix_mul_3x3(rgb2rgb, rgb2xyz, xyz2rgb);
108
109 return 0;
110}
111
112#define OPENCL_SOURCE_NB 3
113// Average light level for SDR signals. This is equal to a signal level of 0.5
114// under a typical presentation gamma of about 2.0.
115static const float sdr_avg = 0.25f;
116
118{
119 TonemapOpenCLContext *ctx = avctx->priv;
120 int rgb2rgb_passthrough = 1;
121 double rgb2rgb[3][3], rgb2yuv[3][3], yuv2rgb[3][3];
122 const AVLumaCoefficients *luma_src, *luma_dst;
123 cl_int cle;
124 int err;
125 AVBPrint header;
126 const char *opencl_sources[OPENCL_SOURCE_NB];
127
129
130 switch(ctx->tonemap) {
131 case TONEMAP_GAMMA:
132 if (isnan(ctx->param))
133 ctx->param = 1.8f;
134 break;
135 case TONEMAP_REINHARD:
136 if (!isnan(ctx->param))
137 ctx->param = (1.0f - ctx->param) / ctx->param;
138 break;
139 case TONEMAP_MOBIUS:
140 if (isnan(ctx->param))
141 ctx->param = 0.3f;
142 break;
143 }
144
145 if (isnan(ctx->param))
146 ctx->param = 1.0f;
147
148 // SDR peak is 1.0f
149 ctx->target_peak = 1.0f;
150 av_log(ctx, AV_LOG_DEBUG, "tone mapping transfer from %s to %s\n",
152 av_color_transfer_name(ctx->trc_out));
153 av_log(ctx, AV_LOG_DEBUG, "mapping colorspace from %s to %s\n",
154 av_color_space_name(ctx->colorspace_in),
155 av_color_space_name(ctx->colorspace_out));
156 av_log(ctx, AV_LOG_DEBUG, "mapping primaries from %s to %s\n",
157 av_color_primaries_name(ctx->primaries_in),
158 av_color_primaries_name(ctx->primaries_out));
159 av_log(ctx, AV_LOG_DEBUG, "mapping range from %s to %s\n",
160 av_color_range_name(ctx->range_in),
161 av_color_range_name(ctx->range_out));
162 // checking valid value just because of limited implementation
163 // please remove when more functionalities are implemented
164 av_assert0(ctx->trc_out == AVCOL_TRC_BT709 ||
165 ctx->trc_out == AVCOL_TRC_BT2020_10);
167 ctx->trc_in == AVCOL_TRC_ARIB_STD_B67);
168 av_assert0(ctx->colorspace_in == AVCOL_SPC_BT2020_NCL ||
169 ctx->colorspace_in == AVCOL_SPC_BT709);
170 av_assert0(ctx->primaries_in == AVCOL_PRI_BT2020 ||
171 ctx->primaries_in == AVCOL_PRI_BT709);
172
173 av_bprintf(&header, "__constant const float tone_param = %.4ff;\n",
174 ctx->param);
175 av_bprintf(&header, "__constant const float desat_param = %.4ff;\n",
176 ctx->desat_param);
177 av_bprintf(&header, "__constant const float target_peak = %.4ff;\n",
178 ctx->target_peak);
179 av_bprintf(&header, "__constant const float sdr_avg = %.4ff;\n", sdr_avg);
180 av_bprintf(&header, "__constant const float scene_threshold = %.4ff;\n",
181 ctx->scene_threshold);
182 av_bprintf(&header, "#define TONE_FUNC %s\n", tonemap_func[ctx->tonemap]);
183 av_bprintf(&header, "#define DETECTION_FRAMES %d\n", DETECTION_FRAMES);
184
185 if (ctx->primaries_out != ctx->primaries_in) {
186 if ((err = get_rgb2rgb_matrix(ctx->primaries_in, ctx->primaries_out, rgb2rgb)) < 0)
187 goto fail;
188 rgb2rgb_passthrough = 0;
189 }
190 if (ctx->range_in == AVCOL_RANGE_JPEG)
191 av_bprintf(&header, "#define FULL_RANGE_IN\n");
192
193 if (ctx->range_out == AVCOL_RANGE_JPEG)
194 av_bprintf(&header, "#define FULL_RANGE_OUT\n");
195
196 av_bprintf(&header, "#define chroma_loc %d\n", (int)ctx->chroma_loc);
197
198 if (rgb2rgb_passthrough)
199 av_bprintf(&header, "#define RGB2RGB_PASSTHROUGH\n");
200 else
201 ff_opencl_print_const_matrix_3x3(&header, "rgb2rgb", rgb2rgb);
202
203
204 luma_src = av_csp_luma_coeffs_from_avcsp(ctx->colorspace_in);
205 if (!luma_src) {
206 err = AVERROR(EINVAL);
207 av_log(avctx, AV_LOG_ERROR, "unsupported input colorspace %d (%s)\n",
208 ctx->colorspace_in, av_color_space_name(ctx->colorspace_in));
209 goto fail;
210 }
211
212 luma_dst = av_csp_luma_coeffs_from_avcsp(ctx->colorspace_out);
213 if (!luma_dst) {
214 err = AVERROR(EINVAL);
215 av_log(avctx, AV_LOG_ERROR, "unsupported output colorspace %d (%s)\n",
216 ctx->colorspace_out, av_color_space_name(ctx->colorspace_out));
217 goto fail;
218 }
219
222
226
227 av_bprintf(&header, "constant float3 luma_src = {%.4ff, %.4ff, %.4ff};\n",
228 av_q2d(luma_src->cr), av_q2d(luma_src->cg), av_q2d(luma_src->cb));
229 av_bprintf(&header, "constant float3 luma_dst = {%.4ff, %.4ff, %.4ff};\n",
230 av_q2d(luma_dst->cr), av_q2d(luma_dst->cg), av_q2d(luma_dst->cb));
231
232 av_bprintf(&header, "#define linearize %s\n", linearize_funcs[ctx->trc_in]);
233 av_bprintf(&header, "#define delinearize %s\n",
234 delinearize_funcs[ctx->trc_out]);
235
236 if (ctx->trc_in == AVCOL_TRC_ARIB_STD_B67)
237 av_bprintf(&header, "#define ootf_impl ootf_hlg\n");
238
239 if (ctx->trc_out == AVCOL_TRC_ARIB_STD_B67)
240 av_bprintf(&header, "#define inverse_ootf_impl inverse_ootf_hlg\n");
241
242 av_log(avctx, AV_LOG_DEBUG, "Generated OpenCL header:\n%s\n", header.str);
243 opencl_sources[0] = header.str;
244 opencl_sources[1] = ff_source_tonemap_cl;
245 opencl_sources[2] = ff_source_colorspace_common_cl;
246 err = ff_opencl_filter_load_program(avctx, opencl_sources, OPENCL_SOURCE_NB);
247
249 if (err < 0)
250 goto fail;
251
252 ctx->command_queue = clCreateCommandQueue(ctx->ocf.hwctx->context,
253 ctx->ocf.hwctx->device_id,
254 0, &cle);
255 CL_FAIL_ON_ERROR(AVERROR(EIO), "Failed to create OpenCL "
256 "command queue %d.\n", cle);
257
258 ctx->kernel = clCreateKernel(ctx->ocf.program, "tonemap", &cle);
259 CL_FAIL_ON_ERROR(AVERROR(EIO), "Failed to create kernel %d.\n", cle);
260
261 ctx->util_mem =
262 clCreateBuffer(ctx->ocf.hwctx->context, 0,
263 (2 * DETECTION_FRAMES + 7) * sizeof(unsigned),
264 NULL, &cle);
265 CL_FAIL_ON_ERROR(AVERROR(EIO), "Failed to create util buffer: %d.\n", cle);
266
267 ctx->initialised = 1;
268 return 0;
269
270fail:
272 if (ctx->util_mem)
273 clReleaseMemObject(ctx->util_mem);
274 if (ctx->command_queue)
275 clReleaseCommandQueue(ctx->command_queue);
276 if (ctx->kernel)
277 clReleaseKernel(ctx->kernel);
278 return err;
279}
280
282{
283 AVFilterContext *avctx = outlink->src;
284 TonemapOpenCLContext *s = avctx->priv;
285 int ret;
286 if (s->format == AV_PIX_FMT_NONE)
287 av_log(avctx, AV_LOG_WARNING, "format not set, use default format NV12\n");
288 else {
289 if (s->format != AV_PIX_FMT_P010 &&
290 s->format != AV_PIX_FMT_NV12) {
291 av_log(avctx, AV_LOG_ERROR, "unsupported output format,"
292 "only p010/nv12 supported now\n");
293 return AVERROR(EINVAL);
294 }
295 }
296
297 s->ocf.output_format = s->format == AV_PIX_FMT_NONE ? AV_PIX_FMT_NV12 : s->format;
298 ret = ff_opencl_filter_config_output(outlink);
299 if (ret < 0)
300 return ret;
301
302 return 0;
303}
304
305static int launch_kernel(AVFilterContext *avctx, cl_kernel kernel,
306 AVFrame *output, AVFrame *input, float peak) {
307 TonemapOpenCLContext *ctx = avctx->priv;
308 int err = AVERROR(ENOSYS);
309 size_t global_work[2];
310 size_t local_work[2];
311 cl_int cle;
312
313 CL_SET_KERNEL_ARG(kernel, 0, cl_mem, &output->data[0]);
314 CL_SET_KERNEL_ARG(kernel, 1, cl_mem, &input->data[0]);
315 CL_SET_KERNEL_ARG(kernel, 2, cl_mem, &output->data[1]);
316 CL_SET_KERNEL_ARG(kernel, 3, cl_mem, &input->data[1]);
317 CL_SET_KERNEL_ARG(kernel, 4, cl_mem, &ctx->util_mem);
318 CL_SET_KERNEL_ARG(kernel, 5, cl_float, &peak);
319
320 local_work[0] = 16;
321 local_work[1] = 16;
322 // Note the work size based on uv plane, as we process a 2x2 quad in one workitem
323 err = ff_opencl_filter_work_size_from_image(avctx, global_work, output,
324 1, 16);
325 if (err < 0)
326 return err;
327
328 cle = clEnqueueNDRangeKernel(ctx->command_queue, kernel, 2, NULL,
329 global_work, local_work,
330 0, NULL, NULL);
331 CL_FAIL_ON_ERROR(AVERROR(EIO), "Failed to enqueue kernel: %d.\n", cle);
332 return 0;
333fail:
334 return err;
335}
336
338{
339 AVFilterContext *avctx = inlink->dst;
340 AVFilterLink *outlink = avctx->outputs[0];
341 TonemapOpenCLContext *ctx = avctx->priv;
342 AVFrame *output = NULL;
343 cl_int cle;
344 int err;
345 double peak = ctx->peak;
346
347 AVHWFramesContext *input_frames_ctx;
348
349 av_log(ctx, AV_LOG_DEBUG, "Filter input: %s, %ux%u (%"PRId64").\n",
351 input->width, input->height, input->pts);
352
353 if (!input->hw_frames_ctx)
354 return AVERROR(EINVAL);
355 input_frames_ctx = (AVHWFramesContext*)input->hw_frames_ctx->data;
356
357 output = ff_get_video_buffer(outlink, outlink->w, outlink->h);
358 if (!output) {
359 err = AVERROR(ENOMEM);
360 goto fail;
361 }
362
363 err = av_frame_copy_props(output, input);
364 if (err < 0)
365 goto fail;
366
367 if (!peak)
368 peak = ff_determine_signal_peak(input);
369
370 if (ctx->trc != -1)
371 output->color_trc = ctx->trc;
372 if (ctx->primaries != -1)
373 output->color_primaries = ctx->primaries;
374 if (ctx->colorspace != -1)
375 output->colorspace = ctx->colorspace;
376 if (ctx->range != -1)
377 output->color_range = ctx->range;
378
379 ctx->trc_in = input->color_trc;
380 ctx->trc_out = output->color_trc;
381 ctx->colorspace_in = input->colorspace;
382 ctx->colorspace_out = output->colorspace;
383 ctx->primaries_in = input->color_primaries;
384 ctx->primaries_out = output->color_primaries;
385 ctx->range_in = input->color_range;
386 ctx->range_out = output->color_range;
387 ctx->chroma_loc = output->chroma_location;
388
389 if (!ctx->initialised) {
390 if (!(input->color_trc == AVCOL_TRC_SMPTE2084 ||
392 av_log(ctx, AV_LOG_ERROR, "unsupported transfer function characteristic.\n");
393 err = AVERROR(ENOSYS);
394 goto fail;
395 }
396
397 if (input_frames_ctx->sw_format != AV_PIX_FMT_P010) {
398 av_log(ctx, AV_LOG_ERROR, "unsupported format in tonemap_opencl.\n");
399 err = AVERROR(ENOSYS);
400 goto fail;
401 }
402
403 err = tonemap_opencl_init(avctx);
404 if (err < 0)
405 goto fail;
406 }
407
408 switch(input_frames_ctx->sw_format) {
409 case AV_PIX_FMT_P010:
410 err = launch_kernel(avctx, ctx->kernel, output, input, peak);
411 if (err < 0) goto fail;
412 break;
413 default:
414 err = AVERROR(ENOSYS);
415 goto fail;
416 }
417
418 cle = clFinish(ctx->command_queue);
419 CL_FAIL_ON_ERROR(AVERROR(EIO), "Failed to finish command queue: %d.\n", cle);
420
421 av_frame_free(&input);
422
423 ff_update_hdr_metadata(output, ctx->target_peak);
424
425 av_log(ctx, AV_LOG_DEBUG, "Tone-mapping output: %s, %ux%u (%"PRId64").\n",
427 output->width, output->height, output->pts);
428#ifndef NDEBUG
429 {
430 uint32_t *ptr, *max_total_p, *avg_total_p, *frame_number_p;
431 float peak_detected, avg_detected;
432 unsigned map_size = (2 * DETECTION_FRAMES + 7) * sizeof(unsigned);
433 ptr = (void *)clEnqueueMapBuffer(ctx->command_queue, ctx->util_mem,
434 CL_TRUE, CL_MAP_READ, 0, map_size,
435 0, NULL, NULL, &cle);
436 // For the layout of the util buffer, refer tonemap.cl
437 if (ptr) {
438 max_total_p = ptr + 2 * (DETECTION_FRAMES + 1) + 1;
439 avg_total_p = max_total_p + 1;
440 frame_number_p = avg_total_p + 2;
441 peak_detected = (float)*max_total_p / (REFERENCE_WHITE * (*frame_number_p));
442 avg_detected = (float)*avg_total_p / (REFERENCE_WHITE * (*frame_number_p));
443 av_log(ctx, AV_LOG_DEBUG, "peak %f, avg %f will be used for next frame\n",
444 peak_detected, avg_detected);
445 clEnqueueUnmapMemObject(ctx->command_queue, ctx->util_mem, ptr, 0,
446 NULL, NULL);
447 }
448 }
449#endif
450
451 return ff_filter_frame(outlink, output);
452
453fail:
454 clFinish(ctx->command_queue);
455 av_frame_free(&input);
456 av_frame_free(&output);
457 return err;
458}
459
461{
462 TonemapOpenCLContext *ctx = avctx->priv;
463 cl_int cle;
464
465 if (ctx->util_mem)
466 clReleaseMemObject(ctx->util_mem);
467 if (ctx->kernel) {
468 cle = clReleaseKernel(ctx->kernel);
469 if (cle != CL_SUCCESS)
470 av_log(avctx, AV_LOG_ERROR, "Failed to release "
471 "kernel: %d.\n", cle);
472 }
473
474 if (ctx->command_queue) {
475 cle = clReleaseCommandQueue(ctx->command_queue);
476 if (cle != CL_SUCCESS)
477 av_log(avctx, AV_LOG_ERROR, "Failed to release "
478 "command queue: %d.\n", cle);
479 }
480
482}
483
484#define OFFSET(x) offsetof(TonemapOpenCLContext, x)
485#define FLAGS (AV_OPT_FLAG_FILTERING_PARAM | AV_OPT_FLAG_VIDEO_PARAM)
487 { "tonemap", "tonemap algorithm selection", OFFSET(tonemap), AV_OPT_TYPE_INT, {.i64 = TONEMAP_NONE}, TONEMAP_NONE, TONEMAP_MAX - 1, FLAGS, .unit = "tonemap" },
488 { "none", 0, 0, AV_OPT_TYPE_CONST, {.i64 = TONEMAP_NONE}, 0, 0, FLAGS, .unit = "tonemap" },
489 { "linear", 0, 0, AV_OPT_TYPE_CONST, {.i64 = TONEMAP_LINEAR}, 0, 0, FLAGS, .unit = "tonemap" },
490 { "gamma", 0, 0, AV_OPT_TYPE_CONST, {.i64 = TONEMAP_GAMMA}, 0, 0, FLAGS, .unit = "tonemap" },
491 { "clip", 0, 0, AV_OPT_TYPE_CONST, {.i64 = TONEMAP_CLIP}, 0, 0, FLAGS, .unit = "tonemap" },
492 { "reinhard", 0, 0, AV_OPT_TYPE_CONST, {.i64 = TONEMAP_REINHARD}, 0, 0, FLAGS, .unit = "tonemap" },
493 { "hable", 0, 0, AV_OPT_TYPE_CONST, {.i64 = TONEMAP_HABLE}, 0, 0, FLAGS, .unit = "tonemap" },
494 { "mobius", 0, 0, AV_OPT_TYPE_CONST, {.i64 = TONEMAP_MOBIUS}, 0, 0, FLAGS, .unit = "tonemap" },
495 { "transfer", "set transfer characteristic", OFFSET(trc), AV_OPT_TYPE_INT, {.i64 = AVCOL_TRC_BT709}, -1, INT_MAX, FLAGS, .unit = "transfer" },
496 { "t", "set transfer characteristic", OFFSET(trc), AV_OPT_TYPE_INT, {.i64 = AVCOL_TRC_BT709}, -1, INT_MAX, FLAGS, .unit = "transfer" },
497 { "bt709", 0, 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_BT709}, 0, 0, FLAGS, .unit = "transfer" },
498 { "bt2020", 0, 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_BT2020_10}, 0, 0, FLAGS, .unit = "transfer" },
499 { "matrix", "set colorspace matrix", OFFSET(colorspace), AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX, FLAGS, .unit = "matrix" },
500 { "m", "set colorspace matrix", OFFSET(colorspace), AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX, FLAGS, .unit = "matrix" },
501 { "bt709", 0, 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_BT709}, 0, 0, FLAGS, .unit = "matrix" },
502 { "bt2020", 0, 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_BT2020_NCL}, 0, 0, FLAGS, .unit = "matrix" },
503 { "primaries", "set color primaries", OFFSET(primaries), AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX, FLAGS, .unit = "primaries" },
504 { "p", "set color primaries", OFFSET(primaries), AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX, FLAGS, .unit = "primaries" },
505 { "bt709", 0, 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_PRI_BT709}, 0, 0, FLAGS, .unit = "primaries" },
506 { "bt2020", 0, 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_PRI_BT2020}, 0, 0, FLAGS, .unit = "primaries" },
507 { "range", "set color range", OFFSET(range), AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX, FLAGS, .unit = "range" },
508 { "r", "set color range", OFFSET(range), AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX, FLAGS, .unit = "range" },
509 { "tv", 0, 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_RANGE_MPEG}, 0, 0, FLAGS, .unit = "range" },
510 { "pc", 0, 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_RANGE_JPEG}, 0, 0, FLAGS, .unit = "range" },
511 { "limited", 0, 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_RANGE_MPEG}, 0, 0, FLAGS, .unit = "range" },
512 { "full", 0, 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_RANGE_JPEG}, 0, 0, FLAGS, .unit = "range" },
513 { "format", "output pixel format", OFFSET(format), AV_OPT_TYPE_PIXEL_FMT, {.i64 = AV_PIX_FMT_NONE}, AV_PIX_FMT_NONE, INT_MAX, FLAGS, .unit = "fmt" },
514 { "peak", "signal peak override", OFFSET(peak), AV_OPT_TYPE_DOUBLE, {.dbl = 0}, 0, DBL_MAX, FLAGS },
515 { "param", "tonemap parameter", OFFSET(param), AV_OPT_TYPE_DOUBLE, {.dbl = NAN}, DBL_MIN, DBL_MAX, FLAGS },
516 { "desat", "desaturation parameter", OFFSET(desat_param), AV_OPT_TYPE_DOUBLE, {.dbl = 0.5}, 0, DBL_MAX, FLAGS },
517 { "threshold", "scene detection threshold", OFFSET(scene_threshold), AV_OPT_TYPE_DOUBLE, {.dbl = 0.2}, 0, DBL_MAX, FLAGS },
518 { NULL }
519};
520
521AVFILTER_DEFINE_CLASS(tonemap_opencl);
522
524 {
525 .name = "default",
526 .type = AVMEDIA_TYPE_VIDEO,
527 .filter_frame = &tonemap_opencl_filter_frame,
528 .config_props = &ff_opencl_filter_config_input,
529 },
530};
531
533 {
534 .name = "default",
535 .type = AVMEDIA_TYPE_VIDEO,
536 .config_props = &tonemap_opencl_config_output,
537 },
538};
539
541 .p.name = "tonemap_opencl",
542 .p.description = NULL_IF_CONFIG_SMALL("Perform HDR to SDR conversion with tonemapping."),
543 .p.priv_class = &tonemap_opencl_class,
544 .p.flags = AVFILTER_FLAG_HWDEVICE,
545 .priv_size = sizeof(TonemapOpenCLContext),
551 .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE,
552};
static const char *const format[]
Definition af_aiir.c:444
const FFFilter ff_vf_tonemap_opencl
simple assert() macros that are a bit more flexible than ISO C assert().
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition avassert.h:42
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition avfilter.c:1068
Main libavfilter public API header.
void av_bprintf(AVBPrint *buf, const char *fmt,...)
Definition bprint.c:122
void av_bprint_init(AVBPrint *buf, unsigned size_init, unsigned size_max)
Definition bprint.c:69
#define AV_BPRINT_SIZE_AUTOMATIC
#define s(width, name)
Definition cbs_vp9.c:198
#define FLAGS
Definition cmdutils.c:598
static void fn rgb2yuv(uint8_t *_yuv[3], const ptrdiff_t yuv_stride[3], int16_t *rgb[3], ptrdiff_t s, int w, int h, const int16_t rgb2yuv_coeffs[3][3][8], const int16_t yuv_offset[8])
common internal and external API header
#define NULL
Definition coverity.c:32
int(* init)(AVBSFContext *ctx)
Definition dts2pts.c:608
static void yuv2rgb(uint8_t *out, int ridx, int Y, int U, int V)
Definition g2meet.c:264
#define fail
Definition test.h:479
@ AV_OPT_TYPE_CONST
Special option type for declaring named constants.
Definition opt.h:298
@ AV_OPT_TYPE_PIXEL_FMT
Underlying C type is enum AVPixelFormat.
Definition opt.h:306
@ AV_OPT_TYPE_INT
Underlying C type is int.
Definition opt.h:258
@ AV_OPT_TYPE_DOUBLE
Underlying C type is double.
Definition opt.h:266
#define AVFILTER_FLAG_HWDEVICE
The filter can create hardware frames using AVFilterContext.hw_device_ctx.
Definition avfilter.h:187
int av_bprint_finalize(AVBPrint *buf, char **ret_str)
Finalize a print buffer.
Definition bprint.c:235
#define AVERROR(e)
Definition error.h:45
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition frame.c:64
int av_frame_copy_props(AVFrame *dst, const AVFrame *src)
Copy only "metadata" fields from src to dst.
Definition frame.c:599
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition log.h:231
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition log.h:216
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition log.h:210
const struct AVLumaCoefficients * av_csp_luma_coeffs_from_avcsp(enum AVColorSpace csp)
Retrieves the Luma coefficients necessary to construct a conversion matrix from an enum constant desc...
Definition csp.c:58
const AVColorPrimariesDesc * av_csp_primaries_desc_from_id(enum AVColorPrimaries prm)
Retrieves a complete gamut description from an enum constant describing the color primaries.
Definition csp.c:95
static double av_q2d(AVRational a)
Convert an AVRational to a double.
Definition rational.h:104
@ AVMEDIA_TYPE_VIDEO
Definition avutil.h:200
misc image utilities
static av_cold void uninit(AVBitStreamFilterContext *ctx)
void ff_matrix_mul_3x3(double dst[3][3], const double src1[3][3], const double src2[3][3])
Definition colorspace.c:54
void ff_fill_rgb2xyz_table(const AVPrimaryCoefficients *coeffs, const AVWhitepointCoefficients *wp, double rgb2xyz[3][3])
Definition colorspace.c:79
double ff_determine_signal_peak(AVFrame *in)
Definition colorspace.c:153
void ff_matrix_invert_3x3(const double in[3][3], double out[3][3])
Definition colorspace.c:27
void ff_update_hdr_metadata(AVFrame *in, double peak)
Definition colorspace.c:178
void ff_fill_rgb2yuv_table(const AVLumaCoefficients *coeffs, double rgb2yuv[3][3])
Definition colorspace.c:125
#define REFERENCE_WHITE
Definition colorspace.h:27
#define FILTER_INPUTS(array)
Definition filters.h:264
#define FILTER_OUTPUTS(array)
Definition filters.h:265
#define FF_FILTER_FLAG_HWFRAME_AWARE
The filter is aware of hardware frames, and any hardware frame context should not be automatically pr...
Definition filters.h:208
#define FILTER_SINGLE_PIXFMT(pix_fmt_)
Definition filters.h:254
#define AVFILTER_DEFINE_CLASS(fname)
Definition filters.h:478
#define av_cold
Definition attributes.h:117
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition internal.h:88
#define isnan(x)
Definition libm.h:342
#define NAN
enum AVColorPrimaries primaries
enum AVColorRange range
void ff_opencl_filter_uninit(AVFilterContext *avctx)
Uninitialise an OpenCL filter context.
Definition opencl.c:144
int ff_opencl_filter_load_program(AVFilterContext *avctx, const char **program_source_array, int nb_strings)
Load a new OpenCL program from strings in memory.
Definition opencl.c:159
int ff_opencl_filter_config_input(AVFilterLink *inlink)
Check that the input link contains a suitable hardware frames context and extract the device from it.
Definition opencl.c:46
int ff_opencl_filter_init(AVFilterContext *avctx)
Initialise an OpenCL filter context.
Definition opencl.c:135
int ff_opencl_filter_work_size_from_image(AVFilterContext *avctx, size_t *work_size, AVFrame *frame, int plane, int block_alignment)
Find the work size needed needed for a given plane of an image.
Definition opencl.c:266
int ff_opencl_filter_config_output(AVFilterLink *outlink)
Create a suitable hardware frames context for the output.
Definition opencl.c:83
void ff_opencl_print_const_matrix_3x3(AVBPrint *buf, const char *name_str, double mat[3][3])
Print a 3x3 matrix into a buffer as __constant array, which could be included in an OpenCL program.
Definition opencl.c:329
#define CL_SET_KERNEL_ARG(kernel, arg_num, type, arg)
set argument to specific Kernel.
Definition opencl.h:61
#define CL_FAIL_ON_ERROR(errcode,...)
A helper macro to handle OpenCL errors.
Definition opencl.h:74
const char * ff_source_tonemap_cl
const char * ff_source_colorspace_common_cl
AVOptions.
const char * av_color_space_name(enum AVColorSpace space)
Definition pixdesc.c:3860
const char * av_color_range_name(enum AVColorRange range)
Definition pixdesc.c:3776
const char * av_get_pix_fmt_name(enum AVPixelFormat pix_fmt)
Return the short name for a pixel format, NULL in case pix_fmt is unknown.
Definition pixdesc.c:3380
const char * av_color_transfer_name(enum AVColorTransferCharacteristic transfer)
Definition pixdesc.c:3827
const char * av_color_primaries_name(enum AVColorPrimaries primaries)
Definition pixdesc.c:3794
AVChromaLocation
Location of chroma samples.
Definition pixfmt.h:802
AVColorRange
Visual content value range.
Definition pixfmt.h:748
@ AVCOL_RANGE_MPEG
Narrow or limited range content.
Definition pixfmt.h:766
@ AVCOL_RANGE_JPEG
Full range content.
Definition pixfmt.h:783
#define AV_PIX_FMT_P010
Definition pixfmt.h:608
AVPixelFormat
Pixel format.
Definition pixfmt.h:71
@ AV_PIX_FMT_NV12
planar YUV 4:2:0, 12bpp, 1 plane for Y and 1 plane for the UV components, which are interleaved (firs...
Definition pixfmt.h:96
@ AV_PIX_FMT_NONE
Definition pixfmt.h:72
@ AV_PIX_FMT_OPENCL
Hardware surfaces for OpenCL.
Definition pixfmt.h:358
AVColorPrimaries
Chromaticity coordinates of the source primaries.
Definition pixfmt.h:642
@ AVCOL_PRI_BT709
also ITU-R BT1361 / IEC 61966-2-4 / SMPTE RP 177 Annex B
Definition pixfmt.h:644
@ AVCOL_PRI_BT2020
ITU-R BT2020.
Definition pixfmt.h:653
AVColorTransferCharacteristic
Color Transfer Characteristic.
Definition pixfmt.h:672
@ AVCOL_TRC_SMPTE2084
SMPTE ST 2084 for 10-, 12-, 14- and 16-bit systems.
Definition pixfmt.h:689
@ AVCOL_TRC_ARIB_STD_B67
ARIB STD-B67, known as "Hybrid log-gamma".
Definition pixfmt.h:693
@ AVCOL_TRC_BT2020_10
ITU-R BT2020 for 10-bit system.
Definition pixfmt.h:687
@ AVCOL_TRC_BT709
also ITU-R BT1361
Definition pixfmt.h:674
AVColorSpace
YUV colorspace type.
Definition pixfmt.h:706
@ AVCOL_SPC_BT709
also ITU-R BT1361 / IEC 61966-2-4 xvYCC709 / derived in SMPTE RP 177 Annex B
Definition pixfmt.h:708
@ AVCOL_SPC_BT2020_NCL
ITU-R BT2020 non-constant luminance system.
Definition pixfmt.h:717
static const uint8_t header[24]
Definition sdr2.c:68
uint8_t * data
The data buffer.
Definition buffer.h:90
Struct that contains both white point location and primaries location, providing the complete descrip...
Definition csp.h:78
AVWhitepointCoefficients wp
Definition csp.h:79
AVPrimaryCoefficients prim
Definition csp.h:80
An instance of a filter.
Definition avfilter.h:273
void * priv
private data for use by the filter
Definition avfilter.h:288
AVFilterLink ** outputs
array of pointers to output links
Definition avfilter.h:285
A filter pad used for either input or output.
Definition filters.h:40
This structure describes decoded (raw) audio or video data.
Definition frame.h:472
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
Definition frame.h:574
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition frame.h:493
enum AVChromaLocation chroma_location
Definition frame.h:736
int width
Definition frame.h:544
AVBufferRef * hw_frames_ctx
For hwaccel-format frames, this should be a reference to the AVHWFramesContext describing the frame.
Definition frame.h:769
int height
Definition frame.h:544
enum AVColorPrimaries color_primaries
Definition frame.h:725
enum AVColorRange color_range
MPEG vs JPEG YUV range.
Definition frame.h:723
enum AVColorSpace colorspace
YUV colorspace type.
Definition frame.h:734
enum AVColorTransferCharacteristic color_trc
Definition frame.h:727
int format
format of the frame, -1 if unknown or unset Values correspond to enum AVPixelFormat for video frames,...
Definition frame.h:559
This struct describes a set or pool of "hardware" frames (i.e.
Definition hwcontext.h:118
enum AVPixelFormat sw_format
The pixel format identifying the actual data layout of the hardware frames.
Definition hwcontext.h:213
Struct containing luma coefficients to be used for RGB to YUV/YCoCg, or similar calculations.
Definition csp.h:48
AVRational cb
Definition csp.h:49
AVRational cr
Definition csp.h:49
AVRational cg
Definition csp.h:49
AVOption.
Definition opt.h:428
cl_command_queue command_queue
enum AVColorRange range range_in range_out
enum AVColorTransferCharacteristic trc trc_in trc_out
enum AVChromaLocation chroma_loc
enum AVPixelFormat format
OpenCLFilterContext ocf
enum AVColorPrimaries primaries primaries_in primaries_out
enum AVColorSpace colorspace colorspace_in colorspace_out
#define av_log(a,...)
static FILE * out
Definition movenc.c:55
static AVFormatContext * ctx
Definition movenc.c:49
static const float xyz2rgb[3][3]
Definition tiff.c:1912
TonemapAlgorithm
Definition vf_tonemap.c:42
@ TONEMAP_HABLE
Definition vf_tonemap.c:48
@ TONEMAP_LINEAR
Definition vf_tonemap.c:44
@ TONEMAP_MAX
Definition vf_tonemap.c:50
@ TONEMAP_MOBIUS
Definition vf_tonemap.c:49
@ TONEMAP_REINHARD
Definition vf_tonemap.c:47
@ TONEMAP_NONE
Definition vf_tonemap.c:43
@ TONEMAP_CLIP
Definition vf_tonemap.c:46
@ TONEMAP_GAMMA
Definition vf_tonemap.c:45
static void tonemap(TonemapContext *s, AVFrame *out, const AVFrame *in, const AVPixFmtDescriptor *desc, int x, int y, double peak)
Definition vf_tonemap.c:110
static const char *const delinearize_funcs[]
static int launch_kernel(AVFilterContext *avctx, cl_kernel kernel, AVFrame *output, AVFrame *input, float peak)
static const char *const tonemap_func[TONEMAP_MAX]
static const AVOption tonemap_opencl_options[]
static const char *const linearize_funcs[]
static int tonemap_opencl_filter_frame(AVFilterLink *inlink, AVFrame *input)
static const AVFilterPad tonemap_opencl_outputs[]
static int get_rgb2rgb_matrix(enum AVColorPrimaries in, enum AVColorPrimaries out, double rgb2rgb[3][3])
#define OFFSET(x)
static int tonemap_opencl_config_output(AVFilterLink *outlink)
static const float sdr_avg
static av_cold void tonemap_opencl_uninit(AVFilterContext *avctx)
#define DETECTION_FRAMES
#define OPENCL_SOURCE_NB
static const AVFilterPad tonemap_opencl_inputs[]
static int tonemap_opencl_init(AVFilterContext *avctx)
AVFrame * ff_get_video_buffer(AVFilterLink *link, int w, int h)
Request a picture buffer with a specific set of permissions.
Definition video.c:89