summaryrefslogtreecommitdiff
path: root/libavfilter/colorspace.c
diff options
context:
space:
mode:
authorLeo Izen <leo.izen@gmail.com>2022-05-28 09:30:36 -0400
committerRonald S. Bultje <rsbultje@gmail.com>2022-06-01 13:52:38 -0400
commitd42b410e05ad1c4d6e74aa981b4a4423103291fb (patch)
treeef3a78871469fd303caa770e888d78779998d030 /libavfilter/colorspace.c
parent77b529fbd228fe30a870e3157f051885b436ad92 (diff)
downloadffmpeg-d42b410e05ad1c4d6e74aa981b4a4423103291fb.tar.gz
avutil/csp: create public API for colorspace structs
This commit moves some of the functionality from avfilter/colorspace into avutil/csp and exposes it as a public API so it can be used by libavcodec and/or libavformat. It also converts those structs from double values to AVRational to make regression testing easier and more consistent. Signed-off-by: Ronald S. Bultje <rsbultje@gmail.com>
Diffstat (limited to 'libavfilter/colorspace.c')
-rw-r--r--libavfilter/colorspace.c143
1 files changed, 30 insertions, 113 deletions
diff --git a/libavfilter/colorspace.c b/libavfilter/colorspace.c
index 8d7b882375..7f74fe5113 100644
--- a/libavfilter/colorspace.c
+++ b/libavfilter/colorspace.c
@@ -65,24 +65,28 @@ void ff_matrix_mul_3x3(double dst[3][3],
/*
* see e.g. http://www.brucelindbloom.com/index.html?Eqn_RGB_XYZ_Matrix.html
*/
-void ff_fill_rgb2xyz_table(const struct PrimaryCoefficients *coeffs,
- const struct WhitepointCoefficients *wp,
+void ff_fill_rgb2xyz_table(const AVPrimaryCoefficients *coeffs,
+ const AVWhitepointCoefficients *wp,
double rgb2xyz[3][3])
{
double i[3][3], sr, sg, sb, zw;
-
- rgb2xyz[0][0] = coeffs->xr / coeffs->yr;
- rgb2xyz[0][1] = coeffs->xg / coeffs->yg;
- rgb2xyz[0][2] = coeffs->xb / coeffs->yb;
+ double xr = av_q2d(coeffs->r.x), yr = av_q2d(coeffs->r.y);
+ double xg = av_q2d(coeffs->g.x), yg = av_q2d(coeffs->g.y);
+ double xb = av_q2d(coeffs->b.x), yb = av_q2d(coeffs->b.y);
+ double xw = av_q2d(wp->x), yw = av_q2d(wp->y);
+
+ rgb2xyz[0][0] = xr / yr;
+ rgb2xyz[0][1] = xg / yg;
+ rgb2xyz[0][2] = xb / yb;
rgb2xyz[1][0] = rgb2xyz[1][1] = rgb2xyz[1][2] = 1.0;
- rgb2xyz[2][0] = (1.0 - coeffs->xr - coeffs->yr) / coeffs->yr;
- rgb2xyz[2][1] = (1.0 - coeffs->xg - coeffs->yg) / coeffs->yg;
- rgb2xyz[2][2] = (1.0 - coeffs->xb - coeffs->yb) / coeffs->yb;
+ rgb2xyz[2][0] = (1.0 - xr - yr) / yr;
+ rgb2xyz[2][1] = (1.0 - xg - yg) / yg;
+ rgb2xyz[2][2] = (1.0 - xb - yb) / yb;
ff_matrix_invert_3x3(rgb2xyz, i);
- zw = 1.0 - wp->xw - wp->yw;
- sr = i[0][0] * wp->xw + i[0][1] * wp->yw + i[0][2] * zw;
- sg = i[1][0] * wp->xw + i[1][1] * wp->yw + i[1][2] * zw;
- sb = i[2][0] * wp->xw + i[2][1] * wp->yw + i[2][2] * zw;
+ zw = 1.0 - xw - yw;
+ sr = i[0][0] * xw + i[0][1] * yw + i[0][2] * zw;
+ sg = i[1][0] * xw + i[1][1] * yw + i[1][2] * zw;
+ sb = i[2][0] * xw + i[2][1] * yw + i[2][2] * zw;
rgb2xyz[0][0] *= sr;
rgb2xyz[0][1] *= sg;
rgb2xyz[0][2] *= sb;
@@ -107,119 +111,32 @@ static const double gbr_matrix[3][3] =
{ 0.5, -0.5, 0 },
};
-/*
- * All constants explained in e.g. https://linuxtv.org/downloads/v4l-dvb-apis/ch02s06.html
- * The older ones (bt470bg/m) are also explained in their respective ITU docs
- * (e.g. https://www.itu.int/dms_pubrec/itu-r/rec/bt/R-REC-BT.470-5-199802-S!!PDF-E.pdf)
- * whereas the newer ones can typically be copied directly from wikipedia :)
- */
-static const struct LumaCoefficients luma_coefficients[AVCOL_SPC_NB] = {
- [AVCOL_SPC_FCC] = { 0.30, 0.59, 0.11 },
- [AVCOL_SPC_BT470BG] = { 0.299, 0.587, 0.114 },
- [AVCOL_SPC_SMPTE170M] = { 0.299, 0.587, 0.114 },
- [AVCOL_SPC_BT709] = { 0.2126, 0.7152, 0.0722 },
- [AVCOL_SPC_SMPTE240M] = { 0.212, 0.701, 0.087 },
- [AVCOL_SPC_YCOCG] = { 0.25, 0.5, 0.25 },
- [AVCOL_SPC_RGB] = { 1, 1, 1 },
- [AVCOL_SPC_BT2020_NCL] = { 0.2627, 0.6780, 0.0593 },
- [AVCOL_SPC_BT2020_CL] = { 0.2627, 0.6780, 0.0593 },
-};
-
-const struct LumaCoefficients *ff_get_luma_coefficients(enum AVColorSpace csp)
-{
- const struct LumaCoefficients *coeffs;
-
- if (csp >= AVCOL_SPC_NB)
- return NULL;
- coeffs = &luma_coefficients[csp];
- if (!coeffs->cr)
- return NULL;
-
- 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;
-}
-
-enum AVColorPrimaries ff_detect_color_primaries(const struct ColorPrimaries *prm)
-{
- double delta;
-
- for (enum AVColorPrimaries p = 0; p < AVCOL_PRI_NB; p++) {
- const struct ColorPrimaries *ref = &color_primaries[p];
- if (!ref->prim.xr)
- continue;
-
- delta = fabs(prm->prim.xr - ref->prim.xr) +
- fabs(prm->prim.yr - ref->prim.yr) +
- fabs(prm->prim.yg - ref->prim.yg) +
- fabs(prm->prim.yg - ref->prim.yg) +
- fabs(prm->prim.yb - ref->prim.yb) +
- fabs(prm->prim.yb - ref->prim.yb) +
- fabs(prm->wp.xw - ref->wp.xw) +
- fabs(prm->wp.yw - ref->wp.yw);
-
- if (delta < 0.001)
- return p;
- }
-
- return AVCOL_PRI_UNSPECIFIED;
-}
-
-void ff_fill_rgb2yuv_table(const struct LumaCoefficients *coeffs,
+void ff_fill_rgb2yuv_table(const AVLumaCoefficients *coeffs,
double rgb2yuv[3][3])
{
double bscale, rscale;
+ double cr = av_q2d(coeffs->cr), cg = av_q2d(coeffs->cg), cb = av_q2d(coeffs->cb);
// special ycgco matrix
- if (coeffs->cr == 0.25 && coeffs->cg == 0.5 && coeffs->cb == 0.25) {
+ if (cr == 0.25 && cg == 0.5 && cb == 0.25) {
memcpy(rgb2yuv, ycgco_matrix, sizeof(double) * 9);
return;
- } else if (coeffs->cr == 1 && coeffs->cg == 1 && coeffs->cb == 1) {
+ } else if (cr == 1 && cg == 1 && cb == 1) {
memcpy(rgb2yuv, gbr_matrix, sizeof(double) * 9);
return;
}
- rgb2yuv[0][0] = coeffs->cr;
- rgb2yuv[0][1] = coeffs->cg;
- rgb2yuv[0][2] = coeffs->cb;
- bscale = 0.5 / (coeffs->cb - 1.0);
- rscale = 0.5 / (coeffs->cr - 1.0);
- rgb2yuv[1][0] = bscale * coeffs->cr;
- rgb2yuv[1][1] = bscale * coeffs->cg;
+ rgb2yuv[0][0] = cr;
+ rgb2yuv[0][1] = cg;
+ rgb2yuv[0][2] = cb;
+ bscale = 0.5 / (cb - 1.0);
+ rscale = 0.5 / (cr - 1.0);
+ rgb2yuv[1][0] = bscale * cr;
+ rgb2yuv[1][1] = bscale * cg;
rgb2yuv[1][2] = 0.5;
rgb2yuv[2][0] = 0.5;
- rgb2yuv[2][1] = rscale * coeffs->cg;
- rgb2yuv[2][2] = rscale * coeffs->cb;
+ rgb2yuv[2][1] = rscale * cg;
+ rgb2yuv[2][2] = rscale * cb;
}
double ff_determine_signal_peak(AVFrame *in)