#include "libavutil/bprint.h"
#include "libavutil/common.h"
#include "libavutil/imgutils.h"
-#include "libavutil/mastering_display_metadata.h"
#include "libavutil/mem.h"
#include "libavutil/opt.h"
#include "libavutil/pixdesc.h"
#include "colorspace.h"
// TODO:
-// - seperate peak-detection from tone-mapping kernel to solve
+// - separate peak-detection from tone-mapping kernel to solve
// one-frame-delay issue.
// - import colorspace matrix generation from vf_colorspace.c
// - more format support
#define DETECTION_FRAMES 63
-#define REFERENCE_WHITE 100.0f
enum TonemapAlgorithm {
TONEMAP_NONE,
[AVCOL_SPC_BT2020_NCL] = { 0.2627, 0.6780, 0.0593 },
};
-static struct PrimaryCoefficients primaries_table[AVCOL_PRI_NB] = {
+static const struct PrimaryCoefficients primaries_table[AVCOL_PRI_NB] = {
[AVCOL_PRI_BT709] = { 0.640, 0.330, 0.300, 0.600, 0.150, 0.060 },
[AVCOL_PRI_BT2020] = { 0.708, 0.292, 0.170, 0.797, 0.131, 0.046 },
};
-static struct WhitepointCoefficients whitepoint_table[AVCOL_PRI_NB] = {
+static const struct WhitepointCoefficients whitepoint_table[AVCOL_PRI_NB] = {
[AVCOL_PRI_BT709] = { 0.3127, 0.3290 },
[AVCOL_PRI_BT2020] = { 0.3127, 0.3290 },
};
ctx->command_queue = clCreateCommandQueue(ctx->ocf.hwctx->context,
ctx->ocf.hwctx->device_id,
0, &cle);
- if (!ctx->command_queue) {
- av_log(avctx, AV_LOG_ERROR, "Failed to create OpenCL "
- "command queue: %d.\n", cle);
- err = AVERROR(EIO);
- goto fail;
- }
+ CL_FAIL_ON_ERROR(AVERROR(EIO), "Failed to create OpenCL "
+ "command queue %d.\n", cle);
ctx->kernel = clCreateKernel(ctx->ocf.program, "tonemap", &cle);
- if (!ctx->kernel) {
- av_log(avctx, AV_LOG_ERROR, "Failed to create kernel: %d.\n", cle);
- err = AVERROR(EIO);
- goto fail;
- }
+ CL_FAIL_ON_ERROR(AVERROR(EIO), "Failed to create kernel %d.\n", cle);
ctx->util_mem =
clCreateBuffer(ctx->ocf.hwctx->context, 0,
(2 * DETECTION_FRAMES + 7) * sizeof(unsigned),
NULL, &cle);
- if (cle != CL_SUCCESS) {
- av_log(avctx, AV_LOG_ERROR, "Failed to create util buffer: %d.\n", cle);
- err = AVERROR(EIO);
- goto fail;
- }
+ CL_FAIL_ON_ERROR(AVERROR(EIO), "Failed to create util buffer: %d.\n", cle);
ctx->initialised = 1;
return 0;
cle = clEnqueueNDRangeKernel(ctx->command_queue, kernel, 2, NULL,
global_work, local_work,
0, NULL, NULL);
- if (cle != CL_SUCCESS) {
- av_log(avctx, AV_LOG_ERROR, "Failed to enqueue kernel: %d.\n",
- cle);
- return AVERROR(EIO);
- }
+ CL_FAIL_ON_ERROR(AVERROR(EIO), "Failed to enqueue kernel: %d.\n", cle);
return 0;
fail:
return err;
}
-static double determine_signal_peak(AVFrame *in)
-{
- AVFrameSideData *sd = av_frame_get_side_data(in, AV_FRAME_DATA_CONTENT_LIGHT_LEVEL);
- double peak = 0;
-
- if (sd) {
- AVContentLightMetadata *clm = (AVContentLightMetadata *)sd->data;
- peak = clm->MaxCLL / REFERENCE_WHITE;
- }
-
- sd = av_frame_get_side_data(in, AV_FRAME_DATA_MASTERING_DISPLAY_METADATA);
- if (!peak && sd) {
- AVMasteringDisplayMetadata *metadata = (AVMasteringDisplayMetadata *)sd->data;
- if (metadata->has_luminance)
- peak = av_q2d(metadata->max_luminance) / REFERENCE_WHITE;
- }
-
- // For untagged source, use peak of 10000 if SMPTE ST.2084
- // otherwise assume HLG with reference display peak 1000.
- if (!peak)
- peak = in->color_trc == AVCOL_TRC_SMPTE2084 ? 100.0f : 10.0f;
-
- return peak;
-}
-
-static void update_metadata(AVFrame *in, double peak) {
- AVFrameSideData *sd = av_frame_get_side_data(in, AV_FRAME_DATA_CONTENT_LIGHT_LEVEL);
-
- if (sd) {
- AVContentLightMetadata *clm = (AVContentLightMetadata *)sd->data;
- clm->MaxCLL = (unsigned)(peak * REFERENCE_WHITE);
- }
-
- sd = av_frame_get_side_data(in, AV_FRAME_DATA_MASTERING_DISPLAY_METADATA);
- if (sd) {
- AVMasteringDisplayMetadata *metadata = (AVMasteringDisplayMetadata *)sd->data;
- if (metadata->has_luminance)
- metadata->max_luminance =av_d2q(peak * REFERENCE_WHITE, 10000);
- }
-}
-
static int tonemap_opencl_filter_frame(AVFilterLink *inlink, AVFrame *input)
{
AVFilterContext *avctx = inlink->dst;
goto fail;
if (!peak)
- peak = determine_signal_peak(input);
+ peak = ff_determine_signal_peak(input);
if (ctx->trc != -1)
output->color_trc = ctx->trc;
}
cle = clFinish(ctx->command_queue);
- if (cle != CL_SUCCESS) {
- av_log(avctx, AV_LOG_ERROR, "Failed to finish command queue: %d.\n",
- cle);
- err = AVERROR(EIO);
- goto fail;
- }
+ CL_FAIL_ON_ERROR(AVERROR(EIO), "Failed to finish command queue: %d.\n", cle);
av_frame_free(&input);
- update_metadata(output, ctx->target_peak);
+ ff_update_hdr_metadata(output, ctx->target_peak);
av_log(ctx, AV_LOG_DEBUG, "Tone-mapping output: %s, %ux%u (%"PRId64").\n",
av_get_pix_fmt_name(output->format),