X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavfilter%2Fvf_tonemap_opencl.c;h=e85b3bb3ba286993453563d259cc8e9df0fca34d;hb=a04ad248a05e7b613abe09b3bb067f555108d794;hp=5da2333169b888fffad39cab5c53b5bfa39c2124;hpb=14fe81b3a88dfe4dbac12e8715f9a3f05b5ef1bf;p=ffmpeg diff --git a/libavfilter/vf_tonemap_opencl.c b/libavfilter/vf_tonemap_opencl.c index 5da2333169b..e85b3bb3ba2 100644 --- a/libavfilter/vf_tonemap_opencl.c +++ b/libavfilter/vf_tonemap_opencl.c @@ -18,7 +18,6 @@ #include #include "libavutil/avassert.h" -#include "libavutil/bprint.h" #include "libavutil/common.h" #include "libavutil/imgutils.h" #include "libavutil/mem.h" @@ -33,9 +32,8 @@ #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 @@ -73,42 +71,27 @@ typedef struct TonemapOpenCLContext { cl_mem util_mem; } TonemapOpenCLContext; -static const char *yuv_coff[AVCOL_SPC_NB] = { - [AVCOL_SPC_BT709] = "rgb2yuv_bt709", - [AVCOL_SPC_BT2020_NCL] = "rgb2yuv_bt2020", -}; - -static const char *rgb_coff[AVCOL_SPC_NB] = { - [AVCOL_SPC_BT709] = "yuv2rgb_bt709", - [AVCOL_SPC_BT2020_NCL] = "yuv2rgb_bt2020", -}; - -static const char *linearize_funcs[AVCOL_TRC_NB] = { +static const char *const linearize_funcs[AVCOL_TRC_NB] = { [AVCOL_TRC_SMPTE2084] = "eotf_st2084", [AVCOL_TRC_ARIB_STD_B67] = "inverse_oetf_hlg", }; -static const char *delinearize_funcs[AVCOL_TRC_NB] = { +static const char *const delinearize_funcs[AVCOL_TRC_NB] = { [AVCOL_TRC_BT709] = "inverse_eotf_bt1886", [AVCOL_TRC_BT2020_10] = "inverse_eotf_bt1886", }; -static const struct LumaCoefficients luma_coefficients[AVCOL_SPC_NB] = { - [AVCOL_SPC_BT709] = { 0.2126, 0.7152, 0.0722 }, - [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 }, }; -static const char *tonemap_func[TONEMAP_MAX] = { +static const char *const tonemap_func[TONEMAP_MAX] = { [TONEMAP_NONE] = "direct", [TONEMAP_LINEAR] = "linear", [TONEMAP_GAMMA] = "gamma", @@ -137,8 +120,8 @@ static int tonemap_opencl_init(AVFilterContext *avctx) { TonemapOpenCLContext *ctx = avctx->priv; int rgb2rgb_passthrough = 1; - double rgb2rgb[3][3]; - struct LumaCoefficients luma_src, luma_dst; + double rgb2rgb[3][3], rgb2yuv[3][3], yuv2rgb[3][3]; + const struct LumaCoefficients *luma_src, *luma_dst; cl_int cle; int err; AVBPrint header; @@ -215,27 +198,37 @@ static int tonemap_opencl_init(AVFilterContext *avctx) if (rgb2rgb_passthrough) av_bprintf(&header, "#define RGB2RGB_PASSTHROUGH\n"); - else { - av_bprintf(&header, "__constant float rgb2rgb[9] = {\n"); - av_bprintf(&header, " %.4ff, %.4ff, %.4ff,\n", - rgb2rgb[0][0], rgb2rgb[0][1], rgb2rgb[0][2]); - av_bprintf(&header, " %.4ff, %.4ff, %.4ff,\n", - rgb2rgb[1][0], rgb2rgb[1][1], rgb2rgb[1][2]); - av_bprintf(&header, " %.4ff, %.4ff, %.4ff};\n", - rgb2rgb[2][0], rgb2rgb[2][1], rgb2rgb[2][2]); + else + ff_opencl_print_const_matrix_3x3(&header, "rgb2rgb", rgb2rgb); + + + luma_src = ff_get_luma_coefficients(ctx->colorspace_in); + if (!luma_src) { + err = AVERROR(EINVAL); + av_log(avctx, AV_LOG_ERROR, "unsupported input colorspace %d (%s)\n", + ctx->colorspace_in, av_color_space_name(ctx->colorspace_in)); + goto fail; } - av_bprintf(&header, "#define rgb_matrix %s\n", - rgb_coff[ctx->colorspace_in]); - av_bprintf(&header, "#define yuv_matrix %s\n", - yuv_coff[ctx->colorspace_out]); + luma_dst = ff_get_luma_coefficients(ctx->colorspace_out); + if (!luma_dst) { + err = AVERROR(EINVAL); + av_log(avctx, AV_LOG_ERROR, "unsupported output colorspace %d (%s)\n", + ctx->colorspace_out, av_color_space_name(ctx->colorspace_out)); + goto fail; + } + + ff_fill_rgb2yuv_table(luma_dst, rgb2yuv); + ff_opencl_print_const_matrix_3x3(&header, "yuv_matrix", rgb2yuv); + + ff_fill_rgb2yuv_table(luma_src, rgb2yuv); + ff_matrix_invert_3x3(rgb2yuv, yuv2rgb); + ff_opencl_print_const_matrix_3x3(&header, "rgb_matrix", yuv2rgb); - luma_src = luma_coefficients[ctx->colorspace_in]; - luma_dst = luma_coefficients[ctx->colorspace_out]; av_bprintf(&header, "constant float3 luma_src = {%.4ff, %.4ff, %.4ff};\n", - luma_src.cr, luma_src.cg, luma_src.cb); + luma_src->cr, luma_src->cg, luma_src->cb); av_bprintf(&header, "constant float3 luma_dst = {%.4ff, %.4ff, %.4ff};\n", - luma_dst.cr, luma_dst.cg, luma_dst.cb); + luma_dst->cr, luma_dst->cg, luma_dst->cb); av_bprintf(&header, "#define linearize %s\n", linearize_funcs[ctx->trc_in]); av_bprintf(&header, "#define delinearize %s\n", @@ -276,6 +269,7 @@ static int tonemap_opencl_init(AVFilterContext *avctx) return 0; fail: + av_bprint_finalize(&header, NULL); if (ctx->util_mem) clReleaseMemObject(ctx->util_mem); if (ctx->command_queue) @@ -546,9 +540,9 @@ static const AVFilterPad tonemap_opencl_outputs[] = { { NULL } }; -AVFilter ff_vf_tonemap_opencl = { +const AVFilter ff_vf_tonemap_opencl = { .name = "tonemap_opencl", - .description = NULL_IF_CONFIG_SMALL("perform HDR to SDR conversion with tonemapping"), + .description = NULL_IF_CONFIG_SMALL("Perform HDR to SDR conversion with tonemapping."), .priv_size = sizeof(TonemapOpenCLContext), .priv_class = &tonemap_opencl_class, .init = &ff_opencl_filter_init,