diff options
-rw-r--r-- | libavfilter/colorspace.c | 32 | ||||
-rw-r--r-- | libavfilter/colorspace.h | 6 | ||||
-rw-r--r-- | 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 { |