From patchwork Mon Apr 11 15:36:50 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Niklas Haas X-Patchwork-Id: 35255 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a20:671c:b0:7c:62c8:b2d1 with SMTP id q28csp1111539pzh; Mon, 11 Apr 2022 08:37:11 -0700 (PDT) X-Google-Smtp-Source: ABdhPJyvj7TNRpf9vh/oo9wPgCEVK/6jF6S+sYpgIgBQbHylzkKJZ5r24FWpkVofddBK93Ar1DCl X-Received: by 2002:a05:6402:5254:b0:41d:7abe:3e08 with SMTP id t20-20020a056402525400b0041d7abe3e08mr6233908edd.153.1649691431522; Mon, 11 Apr 2022 08:37:11 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1649691431; cv=none; d=google.com; s=arc-20160816; b=SqyAxkIR2E2N6XLCyho8ZFA/Vn9SqcAyPlcxJANPpWyRzag1utpkBXiLulbhWrG9Uc iUhjID9EeKLQdutKgNe/C9lJySlum50U5x2n/RMp4EI6+wYFuJCBJSYVUprqHFjIRBUd nMXInz/oXZ94abaP00wmjXM4eMt05wVWR++oHF5vqvR8tAcIkgl2aK/XT+M20u5edUSx GmmUwx2AOKvvGFnYPLWKUUMAuz1JAvSoLPKgw+bynkNPAcUJbyi8GTjUowyFeZTItKjX iVaKjxoxiXA/WWs+f7OHiYj0Tiv+5Wgxbw4Up78Xj7JluaRjdwbZK6YQTL2cC1NwgGdE IScA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:cc:reply-to :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:subject:mime-version:message-id:date:to:from :dkim-signature:delivered-to; bh=lNwQTipKoMTDXVsuS2gKUfRN5nI0G0ZcU8so/MjKVjI=; b=YJ77sWzuMUbnVP2/vpbv4Kn5HeLqcFlOXEdQO0xvGLBUgeHb9mvlMIaYMjuhayrNRz AX/GJVQ39KSayTdceH+4unt3r5aW0sfJtqVr27avcXLTnuB277sTieXIw3pOHeb8gklp 5sMaWR4BEeE1gWmIwYp0QI1oNRI9HmiLwoy/tiFcKnhgQ9+cFqCHO04nhPtm92Umn4oC 0h0uHlSufXarIVQ4pCCpHoG1dI4TiL6DU4tcZD7X8a4aedNFXpU2Dg/iL43W1jn7NS0x 9GMkVrQ0T0ISvhOtiG4jwXdwuixx6WFIqw7niT2LKcxEmpEhKip+3vbbHkLxckQM4HW1 k/sw== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@haasn.xyz header.s=mail header.b=E1t+S91L; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id v3-20020a1709062f0300b006e093439ce5si7450064eji.644.2022.04.11.08.37.11; Mon, 11 Apr 2022 08:37:11 -0700 (PDT) Received-SPF: pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) client-ip=79.124.17.100; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@haasn.xyz header.s=mail header.b=E1t+S91L; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 6F7F468B295; Mon, 11 Apr 2022 18:37:08 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from haasn.dev (haasn.dev [78.46.187.166]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 0682068B221 for ; Mon, 11 Apr 2022 18:37:02 +0300 (EEST) Received: from haasn.dev (unknown [10.30.0.2]) by haasn.dev (Postfix) with ESMTP id BE88049DED; Mon, 11 Apr 2022 17:37:01 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=haasn.xyz; s=mail; t=1649691421; bh=wDbzAjxGCshjtUMXen7XPRU8AbVxoqhSJF3cLhxGkK0=; h=From:To:Cc:Subject:Date:From; b=E1t+S91LFK4XNAVOxSTNMu5bQfCkXc6ni4UP3/U0wWdQjhJScc5dcGYkumJHO2vNu Cvdv8i8qVdHC0JV5rA8Vd8PHiFPd6MrzdoKmYtZEk0gdiDG9A9EuKE+HGx3t5Pu++t Lygls9UWhd/qN2/cO6i3oiJZalAqBXH6lH0ssJ+U= From: Niklas Haas To: ffmpeg-devel@ffmpeg.org Date: Mon, 11 Apr 2022 17:36:50 +0200 Message-Id: <20220411153654.116722-1-ffmpeg@haasn.xyz> X-Mailer: git-send-email 2.35.1 MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 1/5] lavfi: generalize colorspace coefficent helpers X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches Cc: Niklas Haas Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: 7/vvsKHQF55P From: Niklas Haas These are needed beyond just vf_colorspace, so give them a new home in colorspace.h. In addition to moving code around, also merge the white point and primary coefficients into a single struct to slightly increase the convenience and shrink the size of the new API by avoiding the need to introduce an extra function just to look up the white point as well. The only place the distinction matters is in a single enum comparison, which can just as well be a single memcpy - the difference is negligible. Signed-off-by: Niklas Haas --- libavfilter/colorspace.c | 32 +++++++++++++++++ libavfilter/colorspace.h | 6 ++++ libavfilter/vf_colorspace.c | 70 ++++++------------------------------- 3 files changed, 49 insertions(+), 59 deletions(-) diff --git a/libavfilter/colorspace.c b/libavfilter/colorspace.c index 19616e4f12..25e99f4759 100644 --- a/libavfilter/colorspace.c +++ b/libavfilter/colorspace.c @@ -138,6 +138,38 @@ const struct LumaCoefficients *ff_get_luma_coefficients(enum AVColorSpace csp) return coeffs; } +#define WP_D65 { 0.3127, 0.3290 } +#define WP_C { 0.3100, 0.3160 } +#define WP_DCI { 0.3140, 0.3510 } +#define WP_E { 1/3.0f, 1/3.0f } + +static const struct ColorPrimaries color_primaries[AVCOL_PRI_NB] = { + [AVCOL_PRI_BT709] = { WP_D65, { 0.640, 0.330, 0.300, 0.600, 0.150, 0.060 } }, + [AVCOL_PRI_BT470M] = { WP_C, { 0.670, 0.330, 0.210, 0.710, 0.140, 0.080 } }, + [AVCOL_PRI_BT470BG] = { WP_D65, { 0.640, 0.330, 0.290, 0.600, 0.150, 0.060 } }, + [AVCOL_PRI_SMPTE170M] = { WP_D65, { 0.630, 0.340, 0.310, 0.595, 0.155, 0.070 } }, + [AVCOL_PRI_SMPTE240M] = { WP_D65, { 0.630, 0.340, 0.310, 0.595, 0.155, 0.070 } }, + [AVCOL_PRI_SMPTE428] = { WP_E, { 0.735, 0.265, 0.274, 0.718, 0.167, 0.009 } }, + [AVCOL_PRI_SMPTE431] = { WP_DCI, { 0.680, 0.320, 0.265, 0.690, 0.150, 0.060 } }, + [AVCOL_PRI_SMPTE432] = { WP_D65, { 0.680, 0.320, 0.265, 0.690, 0.150, 0.060 } }, + [AVCOL_PRI_FILM] = { WP_C, { 0.681, 0.319, 0.243, 0.692, 0.145, 0.049 } }, + [AVCOL_PRI_BT2020] = { WP_D65, { 0.708, 0.292, 0.170, 0.797, 0.131, 0.046 } }, + [AVCOL_PRI_JEDEC_P22] = { WP_D65, { 0.630, 0.340, 0.295, 0.605, 0.155, 0.077 } }, +}; + +const struct ColorPrimaries *ff_get_color_primaries(enum AVColorPrimaries prm) +{ + const struct ColorPrimaries *p; + + if (prm >= AVCOL_PRI_NB) + return NULL; + p = &color_primaries[prm]; + if (!p->prim.xr) + return NULL; + + return p; +} + void ff_fill_rgb2yuv_table(const struct LumaCoefficients *coeffs, double rgb2yuv[3][3]) { diff --git a/libavfilter/colorspace.h b/libavfilter/colorspace.h index a4c5078d5f..fc415fed05 100644 --- a/libavfilter/colorspace.h +++ b/libavfilter/colorspace.h @@ -37,6 +37,11 @@ struct WhitepointCoefficients { double xw, yw; }; +struct ColorPrimaries { + struct WhitepointCoefficients wp; + struct PrimaryCoefficients prim; +}; + void ff_matrix_invert_3x3(const double in[3][3], double out[3][3]); void ff_matrix_mul_3x3(double dst[3][3], const double src1[3][3], const double src2[3][3]); @@ -44,6 +49,7 @@ void ff_fill_rgb2xyz_table(const struct PrimaryCoefficients *coeffs, const struct WhitepointCoefficients *wp, double rgb2xyz[3][3]); +const struct ColorPrimaries *ff_get_color_primaries(enum AVColorPrimaries prm); const struct LumaCoefficients *ff_get_luma_coefficients(enum AVColorSpace csp); void ff_fill_rgb2yuv_table(const struct LumaCoefficients *coeffs, double rgb2yuv[3][3]); diff --git a/libavfilter/vf_colorspace.c b/libavfilter/vf_colorspace.c index 0bd8e2b0cf..3c8b3b20eb 100644 --- a/libavfilter/vf_colorspace.c +++ b/libavfilter/vf_colorspace.c @@ -55,14 +55,6 @@ enum Colorspace { CS_NB, }; -enum Whitepoint { - WP_D65, - WP_C, - WP_DCI, - WP_E, - WP_NB, -}; - enum WhitepointAdaptation { WP_ADAPT_BRADFORD, WP_ADAPT_VON_KRIES, @@ -110,11 +102,6 @@ static const enum AVColorSpace default_csp[CS_NB + 1] = { [CS_NB] = AVCOL_SPC_UNSPECIFIED, }; -struct ColorPrimaries { - enum Whitepoint wp; - struct PrimaryCoefficients coeff; -}; - struct TransferCharacteristics { double alpha, beta, gamma, delta; }; @@ -201,40 +188,6 @@ static const struct TransferCharacteristics * return coeffs; } -static const struct WhitepointCoefficients whitepoint_coefficients[WP_NB] = { - [WP_D65] = { 0.3127, 0.3290 }, - [WP_C] = { 0.3100, 0.3160 }, - [WP_DCI] = { 0.3140, 0.3510 }, - [WP_E] = { 1/3.0f, 1/3.0f }, -}; - -static const struct ColorPrimaries color_primaries[AVCOL_PRI_NB] = { - [AVCOL_PRI_BT709] = { WP_D65, { 0.640, 0.330, 0.300, 0.600, 0.150, 0.060 } }, - [AVCOL_PRI_BT470M] = { WP_C, { 0.670, 0.330, 0.210, 0.710, 0.140, 0.080 } }, - [AVCOL_PRI_BT470BG] = { WP_D65, { 0.640, 0.330, 0.290, 0.600, 0.150, 0.060 } }, - [AVCOL_PRI_SMPTE170M] = { WP_D65, { 0.630, 0.340, 0.310, 0.595, 0.155, 0.070 } }, - [AVCOL_PRI_SMPTE240M] = { WP_D65, { 0.630, 0.340, 0.310, 0.595, 0.155, 0.070 } }, - [AVCOL_PRI_SMPTE428] = { WP_E, { 0.735, 0.265, 0.274, 0.718, 0.167, 0.009 } }, - [AVCOL_PRI_SMPTE431] = { WP_DCI, { 0.680, 0.320, 0.265, 0.690, 0.150, 0.060 } }, - [AVCOL_PRI_SMPTE432] = { WP_D65, { 0.680, 0.320, 0.265, 0.690, 0.150, 0.060 } }, - [AVCOL_PRI_FILM] = { WP_C, { 0.681, 0.319, 0.243, 0.692, 0.145, 0.049 } }, - [AVCOL_PRI_BT2020] = { WP_D65, { 0.708, 0.292, 0.170, 0.797, 0.131, 0.046 } }, - [AVCOL_PRI_JEDEC_P22] = { WP_D65, { 0.630, 0.340, 0.295, 0.605, 0.155, 0.077 } }, -}; - -static const struct ColorPrimaries *get_color_primaries(enum AVColorPrimaries prm) -{ - const struct ColorPrimaries *p; - - if (prm >= AVCOL_PRI_NB) - return NULL; - p = &color_primaries[prm]; - if (!p->coeff.xr) - return NULL; - - return p; -} - static int fill_gamma_table(ColorSpaceContext *s) { int n; @@ -280,7 +233,8 @@ static int fill_gamma_table(ColorSpaceContext *s) * This function uses the Bradford mechanism. */ static void fill_whitepoint_conv_table(double out[3][3], enum WhitepointAdaptation wp_adapt, - enum Whitepoint src, enum Whitepoint dst) + const struct WhitepointCoefficients *wp_src, + const struct WhitepointCoefficients *wp_dst) { static const double ma_tbl[NB_WP_ADAPT_NON_IDENTITY][3][3] = { [WP_ADAPT_BRADFORD] = { @@ -294,9 +248,7 @@ static void fill_whitepoint_conv_table(double out[3][3], enum WhitepointAdaptati }, }; const double (*ma)[3] = ma_tbl[wp_adapt]; - const struct WhitepointCoefficients *wp_src = &whitepoint_coefficients[src]; double zw_src = 1.0 - wp_src->xw - wp_src->yw; - const struct WhitepointCoefficients *wp_dst = &whitepoint_coefficients[dst]; double zw_dst = 1.0 - wp_dst->xw - wp_dst->yw; double mai[3][3], fac[3][3], tmp[3][3]; double rs, gs, bs, rd, gd, bd; @@ -486,7 +438,7 @@ static int create_filtergraph(AVFilterContext *ctx, s->in_prm = default_prm[FFMIN(s->user_iall, CS_NB)]; if (s->user_iprm != AVCOL_PRI_UNSPECIFIED) s->in_prm = s->user_iprm; - s->in_primaries = get_color_primaries(s->in_prm); + s->in_primaries = ff_get_color_primaries(s->in_prm); if (!s->in_primaries) { av_log(ctx, AV_LOG_ERROR, "Unsupported input primaries %d (%s)\n", @@ -494,7 +446,7 @@ static int create_filtergraph(AVFilterContext *ctx, return AVERROR(EINVAL); } s->out_prm = out->color_primaries; - s->out_primaries = get_color_primaries(s->out_prm); + s->out_primaries = ff_get_color_primaries(s->out_prm); if (!s->out_primaries) { if (s->out_prm == AVCOL_PRI_UNSPECIFIED) { if (s->user_all == CS_UNSPECIFIED) { @@ -516,17 +468,17 @@ static int create_filtergraph(AVFilterContext *ctx, double rgb2xyz[3][3], xyz2rgb[3][3], rgb2rgb[3][3]; const struct WhitepointCoefficients *wp_out, *wp_in; - wp_out = &whitepoint_coefficients[s->out_primaries->wp]; - wp_in = &whitepoint_coefficients[s->in_primaries->wp]; - ff_fill_rgb2xyz_table(&s->out_primaries->coeff, wp_out, rgb2xyz); + wp_out = &s->out_primaries->wp; + wp_in = &s->in_primaries->wp; + ff_fill_rgb2xyz_table(&s->out_primaries->prim, wp_out, rgb2xyz); ff_matrix_invert_3x3(rgb2xyz, xyz2rgb); - ff_fill_rgb2xyz_table(&s->in_primaries->coeff, wp_in, rgb2xyz); - if (s->out_primaries->wp != s->in_primaries->wp && + ff_fill_rgb2xyz_table(&s->in_primaries->prim, wp_in, rgb2xyz); + if (memcmp(wp_in, wp_out, sizeof(*wp_in)) != 0 && s->wp_adapt != WP_ADAPT_IDENTITY) { double wpconv[3][3], tmp[3][3]; - fill_whitepoint_conv_table(wpconv, s->wp_adapt, s->in_primaries->wp, - s->out_primaries->wp); + fill_whitepoint_conv_table(wpconv, s->wp_adapt, &s->in_primaries->wp, + &s->out_primaries->wp); ff_matrix_mul_3x3(tmp, rgb2xyz, wpconv); ff_matrix_mul_3x3(rgb2rgb, tmp, xyz2rgb); } else {