FFmpeg
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
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/bprint.h"
22 #include "libavutil/common.h"
23 #include "libavutil/imgutils.h"
24 #include "libavutil/mem.h"
25 #include "libavutil/opt.h"
26 #include "libavutil/pixdesc.h"
27 
28 #include "avfilter.h"
29 #include "internal.h"
30 #include "opencl.h"
31 #include "opencl_source.h"
32 #include "video.h"
33 #include "colorspace.h"
34 
35 // TODO:
36 // - separate peak-detection from tone-mapping kernel to solve
37 // one-frame-delay issue.
38 // - import colorspace matrix generation from vf_colorspace.c
39 // - more format support
40 
41 #define DETECTION_FRAMES 63
42 
52 };
53 
54 typedef struct TonemapOpenCLContext {
56 
57  enum AVColorSpace colorspace, colorspace_in, colorspace_out;
59  enum AVColorPrimaries primaries, primaries_in, primaries_out;
60  enum AVColorRange range, range_in, range_out;
62 
65  double peak;
66  double param;
67  double desat_param;
68  double target_peak;
71  cl_kernel kernel;
72  cl_command_queue command_queue;
73  cl_mem util_mem;
75 
76 static const char *yuv_coff[AVCOL_SPC_NB] = {
77  [AVCOL_SPC_BT709] = "rgb2yuv_bt709",
78  [AVCOL_SPC_BT2020_NCL] = "rgb2yuv_bt2020",
79 };
80 
81 static const char *rgb_coff[AVCOL_SPC_NB] = {
82  [AVCOL_SPC_BT709] = "yuv2rgb_bt709",
83  [AVCOL_SPC_BT2020_NCL] = "yuv2rgb_bt2020",
84 };
85 
86 static const char *linearize_funcs[AVCOL_TRC_NB] = {
87  [AVCOL_TRC_SMPTE2084] = "eotf_st2084",
88  [AVCOL_TRC_ARIB_STD_B67] = "inverse_oetf_hlg",
89 };
90 
91 static const char *delinearize_funcs[AVCOL_TRC_NB] = {
92  [AVCOL_TRC_BT709] = "inverse_eotf_bt1886",
93  [AVCOL_TRC_BT2020_10] = "inverse_eotf_bt1886",
94 };
95 
97  [AVCOL_SPC_BT709] = { 0.2126, 0.7152, 0.0722 },
98  [AVCOL_SPC_BT2020_NCL] = { 0.2627, 0.6780, 0.0593 },
99 };
100 
102  [AVCOL_PRI_BT709] = { 0.640, 0.330, 0.300, 0.600, 0.150, 0.060 },
103  [AVCOL_PRI_BT2020] = { 0.708, 0.292, 0.170, 0.797, 0.131, 0.046 },
104 };
105 
107  [AVCOL_PRI_BT709] = { 0.3127, 0.3290 },
108  [AVCOL_PRI_BT2020] = { 0.3127, 0.3290 },
109 };
110 
111 static const char *tonemap_func[TONEMAP_MAX] = {
112  [TONEMAP_NONE] = "direct",
113  [TONEMAP_LINEAR] = "linear",
114  [TONEMAP_GAMMA] = "gamma",
115  [TONEMAP_CLIP] = "clip",
116  [TONEMAP_REINHARD] = "reinhard",
117  [TONEMAP_HABLE] = "hable",
118  [TONEMAP_MOBIUS] = "mobius",
119 };
120 
122  double rgb2rgb[3][3]) {
123  double rgb2xyz[3][3], xyz2rgb[3][3];
124 
125  ff_fill_rgb2xyz_table(&primaries_table[out], &whitepoint_table[out], rgb2xyz);
126  ff_matrix_invert_3x3(rgb2xyz, xyz2rgb);
127  ff_fill_rgb2xyz_table(&primaries_table[in], &whitepoint_table[in], rgb2xyz);
128  ff_matrix_mul_3x3(rgb2rgb, rgb2xyz, xyz2rgb);
129 }
130 
131 #define OPENCL_SOURCE_NB 3
132 // Average light level for SDR signals. This is equal to a signal level of 0.5
133 // under a typical presentation gamma of about 2.0.
134 static const float sdr_avg = 0.25f;
135 
137 {
138  TonemapOpenCLContext *ctx = avctx->priv;
139  int rgb2rgb_passthrough = 1;
140  double rgb2rgb[3][3];
141  struct LumaCoefficients luma_src, luma_dst;
142  cl_int cle;
143  int err;
144  AVBPrint header;
145  const char *opencl_sources[OPENCL_SOURCE_NB];
146 
148 
149  switch(ctx->tonemap) {
150  case TONEMAP_GAMMA:
151  if (isnan(ctx->param))
152  ctx->param = 1.8f;
153  break;
154  case TONEMAP_REINHARD:
155  if (!isnan(ctx->param))
156  ctx->param = (1.0f - ctx->param) / ctx->param;
157  break;
158  case TONEMAP_MOBIUS:
159  if (isnan(ctx->param))
160  ctx->param = 0.3f;
161  break;
162  }
163 
164  if (isnan(ctx->param))
165  ctx->param = 1.0f;
166 
167  // SDR peak is 1.0f
168  ctx->target_peak = 1.0f;
169  av_log(ctx, AV_LOG_DEBUG, "tone mapping transfer from %s to %s\n",
170  av_color_transfer_name(ctx->trc_in),
172  av_log(ctx, AV_LOG_DEBUG, "mapping colorspace from %s to %s\n",
173  av_color_space_name(ctx->colorspace_in),
175  av_log(ctx, AV_LOG_DEBUG, "mapping primaries from %s to %s\n",
176  av_color_primaries_name(ctx->primaries_in),
178  av_log(ctx, AV_LOG_DEBUG, "mapping range from %s to %s\n",
179  av_color_range_name(ctx->range_in),
181  // checking valid value just because of limited implementaion
182  // please remove when more functionalities are implemented
184  ctx->trc_out == AVCOL_TRC_BT2020_10);
185  av_assert0(ctx->trc_in == AVCOL_TRC_SMPTE2084||
186  ctx->trc_in == AVCOL_TRC_ARIB_STD_B67);
187  av_assert0(ctx->colorspace_in == AVCOL_SPC_BT2020_NCL ||
188  ctx->colorspace_in == AVCOL_SPC_BT709);
189  av_assert0(ctx->primaries_in == AVCOL_PRI_BT2020 ||
190  ctx->primaries_in == AVCOL_PRI_BT709);
191 
192  av_bprintf(&header, "__constant const float tone_param = %.4ff;\n",
193  ctx->param);
194  av_bprintf(&header, "__constant const float desat_param = %.4ff;\n",
195  ctx->desat_param);
196  av_bprintf(&header, "__constant const float target_peak = %.4ff;\n",
197  ctx->target_peak);
198  av_bprintf(&header, "__constant const float sdr_avg = %.4ff;\n", sdr_avg);
199  av_bprintf(&header, "__constant const float scene_threshold = %.4ff;\n",
200  ctx->scene_threshold);
201  av_bprintf(&header, "#define TONE_FUNC %s\n", tonemap_func[ctx->tonemap]);
202  av_bprintf(&header, "#define DETECTION_FRAMES %d\n", DETECTION_FRAMES);
203 
204  if (ctx->primaries_out != ctx->primaries_in) {
205  get_rgb2rgb_matrix(ctx->primaries_in, ctx->primaries_out, rgb2rgb);
206  rgb2rgb_passthrough = 0;
207  }
208  if (ctx->range_in == AVCOL_RANGE_JPEG)
209  av_bprintf(&header, "#define FULL_RANGE_IN\n");
210 
211  if (ctx->range_out == AVCOL_RANGE_JPEG)
212  av_bprintf(&header, "#define FULL_RANGE_OUT\n");
213 
214  av_bprintf(&header, "#define chroma_loc %d\n", (int)ctx->chroma_loc);
215 
216  if (rgb2rgb_passthrough)
217  av_bprintf(&header, "#define RGB2RGB_PASSTHROUGH\n");
218  else {
219  av_bprintf(&header, "__constant float rgb2rgb[9] = {\n");
220  av_bprintf(&header, " %.4ff, %.4ff, %.4ff,\n",
221  rgb2rgb[0][0], rgb2rgb[0][1], rgb2rgb[0][2]);
222  av_bprintf(&header, " %.4ff, %.4ff, %.4ff,\n",
223  rgb2rgb[1][0], rgb2rgb[1][1], rgb2rgb[1][2]);
224  av_bprintf(&header, " %.4ff, %.4ff, %.4ff};\n",
225  rgb2rgb[2][0], rgb2rgb[2][1], rgb2rgb[2][2]);
226  }
227 
228  av_bprintf(&header, "#define rgb_matrix %s\n",
229  rgb_coff[ctx->colorspace_in]);
230  av_bprintf(&header, "#define yuv_matrix %s\n",
231  yuv_coff[ctx->colorspace_out]);
232 
233  luma_src = luma_coefficients[ctx->colorspace_in];
234  luma_dst = luma_coefficients[ctx->colorspace_out];
235  av_bprintf(&header, "constant float3 luma_src = {%.4ff, %.4ff, %.4ff};\n",
236  luma_src.cr, luma_src.cg, luma_src.cb);
237  av_bprintf(&header, "constant float3 luma_dst = {%.4ff, %.4ff, %.4ff};\n",
238  luma_dst.cr, luma_dst.cg, luma_dst.cb);
239 
240  av_bprintf(&header, "#define linearize %s\n", linearize_funcs[ctx->trc_in]);
241  av_bprintf(&header, "#define delinearize %s\n",
242  delinearize_funcs[ctx->trc_out]);
243 
244  if (ctx->trc_in == AVCOL_TRC_ARIB_STD_B67)
245  av_bprintf(&header, "#define ootf_impl ootf_hlg\n");
246 
247  if (ctx->trc_out == AVCOL_TRC_ARIB_STD_B67)
248  av_bprintf(&header, "#define inverse_ootf_impl inverse_ootf_hlg\n");
249 
250  av_log(avctx, AV_LOG_DEBUG, "Generated OpenCL header:\n%s\n", header.str);
251  opencl_sources[0] = header.str;
252  opencl_sources[1] = ff_opencl_source_tonemap;
253  opencl_sources[2] = ff_opencl_source_colorspace_common;
254  err = ff_opencl_filter_load_program(avctx, opencl_sources, OPENCL_SOURCE_NB);
255 
256  av_bprint_finalize(&header, NULL);
257  if (err < 0)
258  goto fail;
259 
260  ctx->command_queue = clCreateCommandQueue(ctx->ocf.hwctx->context,
261  ctx->ocf.hwctx->device_id,
262  0, &cle);
263  CL_FAIL_ON_ERROR(AVERROR(EIO), "Failed to create OpenCL "
264  "command queue %d.\n", cle);
265 
266  ctx->kernel = clCreateKernel(ctx->ocf.program, "tonemap", &cle);
267  CL_FAIL_ON_ERROR(AVERROR(EIO), "Failed to create kernel %d.\n", cle);
268 
269  ctx->util_mem =
270  clCreateBuffer(ctx->ocf.hwctx->context, 0,
271  (2 * DETECTION_FRAMES + 7) * sizeof(unsigned),
272  NULL, &cle);
273  CL_FAIL_ON_ERROR(AVERROR(EIO), "Failed to create util buffer: %d.\n", cle);
274 
275  ctx->initialised = 1;
276  return 0;
277 
278 fail:
279  if (ctx->util_mem)
280  clReleaseMemObject(ctx->util_mem);
281  if (ctx->command_queue)
282  clReleaseCommandQueue(ctx->command_queue);
283  if (ctx->kernel)
284  clReleaseKernel(ctx->kernel);
285  return err;
286 }
287 
289 {
290  AVFilterContext *avctx = outlink->src;
291  TonemapOpenCLContext *s = avctx->priv;
292  int ret;
293  if (s->format == AV_PIX_FMT_NONE)
294  av_log(avctx, AV_LOG_WARNING, "format not set, use default format NV12\n");
295  else {
296  if (s->format != AV_PIX_FMT_P010 &&
297  s->format != AV_PIX_FMT_NV12) {
298  av_log(avctx, AV_LOG_ERROR, "unsupported output format,"
299  "only p010/nv12 supported now\n");
300  return AVERROR(EINVAL);
301  }
302  }
303 
305  ret = ff_opencl_filter_config_output(outlink);
306  if (ret < 0)
307  return ret;
308 
309  return 0;
310 }
311 
312 static int launch_kernel(AVFilterContext *avctx, cl_kernel kernel,
313  AVFrame *output, AVFrame *input, float peak) {
314  TonemapOpenCLContext *ctx = avctx->priv;
315  int err = AVERROR(ENOSYS);
316  size_t global_work[2];
317  size_t local_work[2];
318  cl_int cle;
319 
320  CL_SET_KERNEL_ARG(kernel, 0, cl_mem, &output->data[0]);
321  CL_SET_KERNEL_ARG(kernel, 1, cl_mem, &input->data[0]);
322  CL_SET_KERNEL_ARG(kernel, 2, cl_mem, &output->data[1]);
323  CL_SET_KERNEL_ARG(kernel, 3, cl_mem, &input->data[1]);
324  CL_SET_KERNEL_ARG(kernel, 4, cl_mem, &ctx->util_mem);
325  CL_SET_KERNEL_ARG(kernel, 5, cl_float, &peak);
326 
327  local_work[0] = 16;
328  local_work[1] = 16;
329  // Note the work size based on uv plane, as we process a 2x2 quad in one workitem
330  err = ff_opencl_filter_work_size_from_image(avctx, global_work, output,
331  1, 16);
332  if (err < 0)
333  return err;
334 
335  cle = clEnqueueNDRangeKernel(ctx->command_queue, kernel, 2, NULL,
336  global_work, local_work,
337  0, NULL, NULL);
338  CL_FAIL_ON_ERROR(AVERROR(EIO), "Failed to enqueue kernel: %d.\n", cle);
339  return 0;
340 fail:
341  return err;
342 }
343 
345 {
346  AVFilterContext *avctx = inlink->dst;
347  AVFilterLink *outlink = avctx->outputs[0];
348  TonemapOpenCLContext *ctx = avctx->priv;
349  AVFrame *output = NULL;
350  cl_int cle;
351  int err;
352  double peak = ctx->peak;
353 
354  AVHWFramesContext *input_frames_ctx =
356 
357  av_log(ctx, AV_LOG_DEBUG, "Filter input: %s, %ux%u (%"PRId64").\n",
358  av_get_pix_fmt_name(input->format),
359  input->width, input->height, input->pts);
360 
361  if (!input->hw_frames_ctx)
362  return AVERROR(EINVAL);
363 
364  output = ff_get_video_buffer(outlink, outlink->w, outlink->h);
365  if (!output) {
366  err = AVERROR(ENOMEM);
367  goto fail;
368  }
369 
370  err = av_frame_copy_props(output, input);
371  if (err < 0)
372  goto fail;
373 
374  if (!peak)
375  peak = ff_determine_signal_peak(input);
376 
377  if (ctx->trc != -1)
378  output->color_trc = ctx->trc;
379  if (ctx->primaries != -1)
380  output->color_primaries = ctx->primaries;
381  if (ctx->colorspace != -1)
382  output->colorspace = ctx->colorspace;
383  if (ctx->range != -1)
384  output->color_range = ctx->range;
385 
386  ctx->trc_in = input->color_trc;
387  ctx->trc_out = output->color_trc;
388  ctx->colorspace_in = input->colorspace;
389  ctx->colorspace_out = output->colorspace;
390  ctx->primaries_in = input->color_primaries;
391  ctx->primaries_out = output->color_primaries;
392  ctx->range_in = input->color_range;
393  ctx->range_out = output->color_range;
394  ctx->chroma_loc = output->chroma_location;
395 
396  if (!ctx->initialised) {
397  if (!(input->color_trc == AVCOL_TRC_SMPTE2084 ||
398  input->color_trc == AVCOL_TRC_ARIB_STD_B67)) {
399  av_log(ctx, AV_LOG_ERROR, "unsupported transfer function characteristic.\n");
400  err = AVERROR(ENOSYS);
401  goto fail;
402  }
403 
404  if (input_frames_ctx->sw_format != AV_PIX_FMT_P010) {
405  av_log(ctx, AV_LOG_ERROR, "unsupported format in tonemap_opencl.\n");
406  err = AVERROR(ENOSYS);
407  goto fail;
408  }
409 
410  err = tonemap_opencl_init(avctx);
411  if (err < 0)
412  goto fail;
413  }
414 
415  switch(input_frames_ctx->sw_format) {
416  case AV_PIX_FMT_P010:
417  err = launch_kernel(avctx, ctx->kernel, output, input, peak);
418  if (err < 0) goto fail;
419  break;
420  default:
421  err = AVERROR(ENOSYS);
422  goto fail;
423  }
424 
425  cle = clFinish(ctx->command_queue);
426  CL_FAIL_ON_ERROR(AVERROR(EIO), "Failed to finish command queue: %d.\n", cle);
427 
428  av_frame_free(&input);
429 
430  ff_update_hdr_metadata(output, ctx->target_peak);
431 
432  av_log(ctx, AV_LOG_DEBUG, "Tone-mapping output: %s, %ux%u (%"PRId64").\n",
433  av_get_pix_fmt_name(output->format),
434  output->width, output->height, output->pts);
435 #ifndef NDEBUG
436  {
437  uint32_t *ptr, *max_total_p, *avg_total_p, *frame_number_p;
438  float peak_detected, avg_detected;
439  unsigned map_size = (2 * DETECTION_FRAMES + 7) * sizeof(unsigned);
440  ptr = (void *)clEnqueueMapBuffer(ctx->command_queue, ctx->util_mem,
441  CL_TRUE, CL_MAP_READ, 0, map_size,
442  0, NULL, NULL, &cle);
443  // For the layout of the util buffer, refer tonemap.cl
444  if (ptr) {
445  max_total_p = ptr + 2 * (DETECTION_FRAMES + 1) + 1;
446  avg_total_p = max_total_p + 1;
447  frame_number_p = avg_total_p + 2;
448  peak_detected = (float)*max_total_p / (REFERENCE_WHITE * (*frame_number_p));
449  avg_detected = (float)*avg_total_p / (REFERENCE_WHITE * (*frame_number_p));
450  av_log(ctx, AV_LOG_DEBUG, "peak %f, avg %f will be used for next frame\n",
451  peak_detected, avg_detected);
452  clEnqueueUnmapMemObject(ctx->command_queue, ctx->util_mem, ptr, 0,
453  NULL, NULL);
454  }
455  }
456 #endif
457 
458  return ff_filter_frame(outlink, output);
459 
460 fail:
461  clFinish(ctx->command_queue);
462  av_frame_free(&input);
463  av_frame_free(&output);
464  return err;
465 }
466 
468 {
469  TonemapOpenCLContext *ctx = avctx->priv;
470  cl_int cle;
471 
472  if (ctx->util_mem)
473  clReleaseMemObject(ctx->util_mem);
474  if (ctx->kernel) {
475  cle = clReleaseKernel(ctx->kernel);
476  if (cle != CL_SUCCESS)
477  av_log(avctx, AV_LOG_ERROR, "Failed to release "
478  "kernel: %d.\n", cle);
479  }
480 
481  if (ctx->command_queue) {
482  cle = clReleaseCommandQueue(ctx->command_queue);
483  if (cle != CL_SUCCESS)
484  av_log(avctx, AV_LOG_ERROR, "Failed to release "
485  "command queue: %d.\n", cle);
486  }
487 
489 }
490 
491 #define OFFSET(x) offsetof(TonemapOpenCLContext, x)
492 #define FLAGS (AV_OPT_FLAG_FILTERING_PARAM | AV_OPT_FLAG_VIDEO_PARAM)
494  { "tonemap", "tonemap algorithm selection", OFFSET(tonemap), AV_OPT_TYPE_INT, {.i64 = TONEMAP_NONE}, TONEMAP_NONE, TONEMAP_MAX - 1, FLAGS, "tonemap" },
495  { "none", 0, 0, AV_OPT_TYPE_CONST, {.i64 = TONEMAP_NONE}, 0, 0, FLAGS, "tonemap" },
496  { "linear", 0, 0, AV_OPT_TYPE_CONST, {.i64 = TONEMAP_LINEAR}, 0, 0, FLAGS, "tonemap" },
497  { "gamma", 0, 0, AV_OPT_TYPE_CONST, {.i64 = TONEMAP_GAMMA}, 0, 0, FLAGS, "tonemap" },
498  { "clip", 0, 0, AV_OPT_TYPE_CONST, {.i64 = TONEMAP_CLIP}, 0, 0, FLAGS, "tonemap" },
499  { "reinhard", 0, 0, AV_OPT_TYPE_CONST, {.i64 = TONEMAP_REINHARD}, 0, 0, FLAGS, "tonemap" },
500  { "hable", 0, 0, AV_OPT_TYPE_CONST, {.i64 = TONEMAP_HABLE}, 0, 0, FLAGS, "tonemap" },
501  { "mobius", 0, 0, AV_OPT_TYPE_CONST, {.i64 = TONEMAP_MOBIUS}, 0, 0, FLAGS, "tonemap" },
502  { "transfer", "set transfer characteristic", OFFSET(trc), AV_OPT_TYPE_INT, {.i64 = AVCOL_TRC_BT709}, -1, INT_MAX, FLAGS, "transfer" },
503  { "t", "set transfer characteristic", OFFSET(trc), AV_OPT_TYPE_INT, {.i64 = AVCOL_TRC_BT709}, -1, INT_MAX, FLAGS, "transfer" },
504  { "bt709", 0, 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_BT709}, 0, 0, FLAGS, "transfer" },
505  { "bt2020", 0, 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_BT2020_10}, 0, 0, FLAGS, "transfer" },
506  { "matrix", "set colorspace matrix", OFFSET(colorspace), AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX, FLAGS, "matrix" },
507  { "m", "set colorspace matrix", OFFSET(colorspace), AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX, FLAGS, "matrix" },
508  { "bt709", 0, 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_BT709}, 0, 0, FLAGS, "matrix" },
509  { "bt2020", 0, 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_BT2020_NCL}, 0, 0, FLAGS, "matrix" },
510  { "primaries", "set color primaries", OFFSET(primaries), AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX, FLAGS, "primaries" },
511  { "p", "set color primaries", OFFSET(primaries), AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX, FLAGS, "primaries" },
512  { "bt709", 0, 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_PRI_BT709}, 0, 0, FLAGS, "primaries" },
513  { "bt2020", 0, 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_PRI_BT2020}, 0, 0, FLAGS, "primaries" },
514  { "range", "set color range", OFFSET(range), AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX, FLAGS, "range" },
515  { "r", "set color range", OFFSET(range), AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX, FLAGS, "range" },
516  { "tv", 0, 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_RANGE_MPEG}, 0, 0, FLAGS, "range" },
517  { "pc", 0, 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_RANGE_JPEG}, 0, 0, FLAGS, "range" },
518  { "limited", 0, 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_RANGE_MPEG}, 0, 0, FLAGS, "range" },
519  { "full", 0, 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_RANGE_JPEG}, 0, 0, FLAGS, "range" },
520  { "format", "output pixel format", OFFSET(format), AV_OPT_TYPE_PIXEL_FMT, {.i64 = AV_PIX_FMT_NONE}, AV_PIX_FMT_NONE, INT_MAX, FLAGS, "fmt" },
521  { "peak", "signal peak override", OFFSET(peak), AV_OPT_TYPE_DOUBLE, {.dbl = 0}, 0, DBL_MAX, FLAGS },
522  { "param", "tonemap parameter", OFFSET(param), AV_OPT_TYPE_DOUBLE, {.dbl = NAN}, DBL_MIN, DBL_MAX, FLAGS },
523  { "desat", "desaturation parameter", OFFSET(desat_param), AV_OPT_TYPE_DOUBLE, {.dbl = 0.5}, 0, DBL_MAX, FLAGS },
524  { "threshold", "scene detection threshold", OFFSET(scene_threshold), AV_OPT_TYPE_DOUBLE, {.dbl = 0.2}, 0, DBL_MAX, FLAGS },
525  { NULL }
526 };
527 
528 AVFILTER_DEFINE_CLASS(tonemap_opencl);
529 
531  {
532  .name = "default",
533  .type = AVMEDIA_TYPE_VIDEO,
534  .filter_frame = &tonemap_opencl_filter_frame,
535  .config_props = &ff_opencl_filter_config_input,
536  },
537  { NULL }
538 };
539 
541  {
542  .name = "default",
543  .type = AVMEDIA_TYPE_VIDEO,
544  .config_props = &tonemap_opencl_config_output,
545  },
546  { NULL }
547 };
548 
550  .name = "tonemap_opencl",
551  .description = NULL_IF_CONFIG_SMALL("perform HDR to SDR conversion with tonemapping"),
552  .priv_size = sizeof(TonemapOpenCLContext),
553  .priv_class = &tonemap_opencl_class,
557  .inputs = tonemap_opencl_inputs,
558  .outputs = tonemap_opencl_outputs,
559  .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE,
560 };
also ITU-R BT1361 / IEC 61966-2-4 xvYCC709 / SMPTE RP177 Annex B
Definition: pixfmt.h:488
#define NULL
Definition: coverity.c:32
#define FF_FILTER_FLAG_HWFRAME_AWARE
The filter is aware of hardware frames, and any hardware frame context should not be automatically pr...
Definition: internal.h:385
void av_bprintf(AVBPrint *buf, const char *fmt,...)
Definition: bprint.c:94
static const char * format[]
Definition: af_aiir.c:330
This structure describes decoded (raw) audio or video data.
Definition: frame.h:226
static int tonemap_opencl_config_output(AVFilterLink *outlink)
AVOption.
Definition: opt.h:246
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:278
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:60
int ff_opencl_filter_query_formats(AVFilterContext *avctx)
Return that all inputs and outputs support only AV_PIX_FMT_OPENCL.
Definition: opencl.c:28
#define DETECTION_FRAMES
misc image utilities
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:182
Main libavfilter public API header.
Memory handling functions.
static av_cold int init(AVCodecContext *avctx)
Definition: avrndec.c:35
static void get_rgb2rgb_matrix(enum AVColorPrimaries in, enum AVColorPrimaries out, double rgb2rgb[3][3])
static const char * delinearize_funcs[AVCOL_TRC_NB]
enum AVChromaLocation chroma_loc
static int launch_kernel(AVFilterContext *avctx, cl_kernel kernel, AVFrame *output, AVFrame *input, float peak)
AVFrame * ff_get_video_buffer(AVFilterLink *link, int w, int h)
Request a picture buffer with a specific set of permissions.
Definition: video.c:99
enum AVColorSpace colorspace colorspace_in colorspace_out
int ff_opencl_filter_init(AVFilterContext *avctx)
Initialise an OpenCL filter context.
Definition: opencl.c:147
static const struct LumaCoefficients luma_coefficients[AVCOL_SPC_NB]
AVColorTransferCharacteristic
Color Transfer Characteristic.
Definition: pixfmt.h:457
int av_bprint_finalize(AVBPrint *buf, char **ret_str)
Finalize a print buffer.
Definition: bprint.c:235
#define FLAGS
const char * av_color_space_name(enum AVColorSpace space)
Definition: pixdesc.c:2839
AVOpenCLDeviceContext * hwctx
Definition: opencl.h:40
AVBufferRef * hw_frames_ctx
For hwaccel-format frames, this should be a reference to the AVHWFramesContext describing the frame...
Definition: frame.h:564
const char * name
Pad name.
Definition: internal.h:60
#define AV_PIX_FMT_P010
Definition: pixfmt.h:426
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:37
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition: avfilter.c:1080
#define av_cold
Definition: attributes.h:82
static av_cold int uninit(AVCodecContext *avctx)
Definition: crystalhd.c:279
AVOptions.
AVColorSpace
YUV colorspace type.
Definition: pixfmt.h:486
const char * av_color_range_name(enum AVColorRange range)
Definition: pixdesc.c:2772
enum AVColorPrimaries primaries primaries_in primaries_out
cl_device_id device_id
The primary device ID of the device.
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
Definition: frame.h:319
AVFilter ff_vf_tonemap_opencl
static struct PrimaryCoefficients primaries_table[AVCOL_PRI_NB]
AVColorRange
MPEG vs JPEG YUV range.
Definition: pixfmt.h:509
static const uint8_t header[24]
Definition: sdr2.c:67
int ff_opencl_filter_config_output(AVFilterLink *outlink)
Create a suitable hardware frames context for the output.
Definition: opencl.c:96
AVColorPrimaries
Chromaticity coordinates of the source primaries.
Definition: pixfmt.h:433
#define av_log(a,...)
A filter pad used for either input or output.
Definition: internal.h:54
int width
Definition: frame.h:284
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
#define AVERROR(e)
Definition: error.h:43
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:202
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
Definition: internal.h:186
void av_bprint_init(AVBPrint *buf, unsigned size_init, unsigned size_max)
Definition: bprint.c:69
static const AVFilterPad tonemap_opencl_inputs[]
void * priv
private data for use by the filter
Definition: avfilter.h:353
enum AVColorRange color_range
MPEG vs JPEG YUV range.
Definition: frame.h:471
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:197
Not part of ABI.
Definition: pixfmt.h:450
enum AVColorSpace colorspace
YUV colorspace type.
Definition: frame.h:482
planar YUV 4:2:0, 12bpp, 1 plane for Y and 1 plane for the UV components, which are interleaved (firs...
Definition: pixfmt.h:89
also ITU-R BT1361 / IEC 61966-2-4 / SMPTE RP177 Annex B
Definition: pixfmt.h:435
simple assert() macros that are a bit more flexible than ISO C assert().
static struct WhitepointCoefficients whitepoint_table[AVCOL_PRI_NB]
#define fail()
Definition: checkasm.h:117
enum TonemapAlgorithm tonemap
const char * av_color_primaries_name(enum AVColorPrimaries primaries)
Definition: pixdesc.c:2791
enum AVPixelFormat output_format
Definition: opencl.h:44
static int tonemap_opencl_filter_frame(AVFilterLink *inlink, AVFrame *input)
SMPTE ST 2084 for 10-, 12-, 14- and 16-bit systems.
Definition: pixfmt.h:474
#define NAN
Definition: mathematics.h:64
static const float sdr_avg
ITU-R BT2020 non-constant luminance system.
Definition: pixfmt.h:497
static const char * linearize_funcs[AVCOL_TRC_NB]
AVFormatContext * ctx
Definition: movenc.c:48
#define s(width, name)
Definition: cbs_vp9.c:257
static const char * rgb_coff[AVCOL_SPC_NB]
static int tonemap_opencl_init(AVFilterContext *avctx)
static const char * tonemap_func[TONEMAP_MAX]
static const AVFilterPad tonemap_opencl_outputs[]
enum AVColorTransferCharacteristic trc trc_in trc_out
static const AVFilterPad inputs[]
Definition: af_acontrast.c:193
static av_cold void tonemap_opencl_uninit(AVFilterContext *avctx)
#define OPENCL_SOURCE_NB
static const AVFilterPad outputs[]
Definition: af_acontrast.c:203
the normal 2^n-1 "JPEG" YUV ranges
Definition: pixfmt.h:512
void ff_update_hdr_metadata(AVFrame *in, double peak)
Definition: colorspace.c:122
int format
format of the frame, -1 if unknown or unset Values correspond to enum AVPixelFormat for video frames...
Definition: frame.h:299
OpenCLFilterContext ocf
also ITU-R BT1361
Definition: pixfmt.h:459
#define AV_BPRINT_SIZE_AUTOMATIC
#define CL_SET_KERNEL_ARG(kernel, arg_num, type, arg)
set argument to specific Kernel.
Definition: opencl.h:55
uint8_t * data
The data buffer.
Definition: buffer.h:89
uint8_t pi<< 24) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_U8, uint8_t,(*(constuint8_t *) pi-0x80)*(1.0f/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_U8, uint8_t,(*(constuint8_t *) pi-0x80)*(1.0/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S16, int16_t,(*(constint16_t *) pi >>8)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S16, int16_t,*(constint16_t *) pi *(1.0f/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S16, int16_t,*(constint16_t *) pi *(1.0/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S32, int32_t,(*(constint32_t *) pi >>24)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S32, int32_t,*(constint32_t *) pi *(1.0f/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S32, int32_t,*(constint32_t *) pi *(1.0/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_FLT, float, av_clip_uint8(lrintf(*(constfloat *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_FLT, float, av_clip_int16(lrintf(*(constfloat *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_FLT, float, av_clipl_int32(llrintf(*(constfloat *) pi *(1U<< 31)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_DBL, double, av_clip_uint8(lrint(*(constdouble *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_DBL, double, av_clip_int16(lrint(*(constdouble *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_DBL, double, av_clipl_int32(llrint(*(constdouble *) pi *(1U<< 31))))#defineSET_CONV_FUNC_GROUP(ofmt, ifmt) staticvoidset_generic_function(AudioConvert *ac){}voidff_audio_convert_free(AudioConvert **ac){if(!*ac) return;ff_dither_free(&(*ac) ->dc);av_freep(ac);}AudioConvert *ff_audio_convert_alloc(AVAudioResampleContext *avr, enumAVSampleFormatout_fmt, enumAVSampleFormatin_fmt, intchannels, intsample_rate, intapply_map){AudioConvert *ac;intin_planar, out_planar;ac=av_mallocz(sizeof(*ac));if(!ac) returnNULL;ac->avr=avr;ac->out_fmt=out_fmt;ac->in_fmt=in_fmt;ac->channels=channels;ac->apply_map=apply_map;if(avr->dither_method!=AV_RESAMPLE_DITHER_NONE &&av_get_packed_sample_fmt(out_fmt)==AV_SAMPLE_FMT_S16 &&av_get_bytes_per_sample(in_fmt)>2){ac->dc=ff_dither_alloc(avr, out_fmt, in_fmt, channels, sample_rate, apply_map);if(!ac->dc){av_free(ac);returnNULL;}returnac;}in_planar=ff_sample_fmt_is_planar(in_fmt, channels);out_planar=ff_sample_fmt_is_planar(out_fmt, channels);if(in_planar==out_planar){ac->func_type=CONV_FUNC_TYPE_FLAT;ac->planes=in_planar?ac->channels:1;}elseif(in_planar) ac->func_type=CONV_FUNC_TYPE_INTERLEAVE;elseac->func_type=CONV_FUNC_TYPE_DEINTERLEAVE;set_generic_function(ac);if(ARCH_AARCH64) ff_audio_convert_init_aarch64(ac);if(ARCH_ARM) ff_audio_convert_init_arm(ac);if(ARCH_X86) ff_audio_convert_init_x86(ac);returnac;}intff_audio_convert(AudioConvert *ac, AudioData *out, AudioData *in){intuse_generic=1;intlen=in->nb_samples;intp;if(ac->dc){av_log(ac->avr, AV_LOG_TRACE,"%dsamples-audio_convert:%sto%s(dithered)\n", len, av_get_sample_fmt_name(ac->in_fmt), av_get_sample_fmt_name(ac->out_fmt));returnff_convert_dither(ac-> in
TonemapAlgorithm
Definition: vf_tonemap.c:42
Filter definition.
Definition: avfilter.h:144
#define isnan(x)
Definition: libm.h:340
Not part of ABI.
Definition: pixfmt.h:479
This struct describes a set or pool of "hardware" frames (i.e.
Definition: hwcontext.h:123
void ff_matrix_invert_3x3(const double in[3][3], double out[3][3])
Definition: colorspace.c:27
AVFILTER_DEFINE_CLASS(tonemap_opencl)
const char * name
Filter name.
Definition: avfilter.h:148
const char * ff_opencl_source_colorspace_common
enum AVChromaLocation chroma_location
Definition: frame.h:484
AVFilterLink ** outputs
array of pointers to output links
Definition: avfilter.h:350
#define CL_FAIL_ON_ERROR(errcode,...)
A helper macro to handle OpenCL errors.
Definition: opencl.h:68
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:240
the normal 219*2^(n-8) "MPEG" YUV ranges
Definition: pixfmt.h:511
static int query_formats(AVFilterContext *ctx)
Definition: aeval.c:244
common internal and external API header
if(ret< 0)
Definition: vf_mcdeint.c:279
const char * av_color_transfer_name(enum AVColorTransferCharacteristic transfer)
Definition: pixdesc.c:2815
void ff_opencl_filter_uninit(AVFilterContext *avctx)
Uninitialise an OpenCL filter context.
Definition: opencl.c:156
ARIB STD-B67, known as "Hybrid log-gamma".
Definition: pixfmt.h:478
#define OFFSET(x)
void ff_matrix_mul_3x3(double dst[3][3], const double src1[3][3], const double src2[3][3])
Definition: colorspace.c:54
cl_context context
The OpenCL context which will contain all operations and frames on this device.
static const char * yuv_coff[AVCOL_SPC_NB]
static const AVOption tonemap_opencl_options[]
enum AVColorPrimaries color_primaries
Definition: frame.h:473
An instance of a filter.
Definition: avfilter.h:338
ITU-R BT2020 for 10-bit system.
Definition: pixfmt.h:472
ITU-R BT2020.
Definition: pixfmt.h:444
int height
Definition: frame.h:284
FILE * out
Definition: movenc.c:54
const char * ff_opencl_source_tonemap
AVChromaLocation
Location of chroma samples.
Definition: pixfmt.h:531
enum AVColorTransferCharacteristic color_trc
Definition: frame.h:475
cl_program program
Definition: opencl.h:42
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:171
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:2362
internal API functions
enum AVPixelFormat sw_format
The pixel format identifying the actual data layout of the hardware frames.
Definition: hwcontext.h:221
AVPixelFormat
Pixel format.
Definition: pixfmt.h:64
enum AVColorRange range range_in range_out
double ff_determine_signal_peak(AVFrame *in)
Definition: colorspace.c:97
Not part of ABI.
Definition: pixfmt.h:503
static void tonemap(TonemapContext *s, AVFrame *out, const AVFrame *in, const AVPixFmtDescriptor *desc, int x, int y, double peak)
Definition: vf_tonemap.c:130
int av_frame_copy_props(AVFrame *dst, const AVFrame *src)
Copy only "metadata" fields from src to dst.
Definition: frame.c:654
void ff_fill_rgb2xyz_table(const struct PrimaryCoefficients *coeffs, const struct WhitepointCoefficients *wp, double rgb2xyz[3][3])
Definition: colorspace.c:68
#define REFERENCE_WHITE
Definition: colorspace.h:26
cl_command_queue command_queue
enum AVPixelFormat format