FFmpeg
Loading...
Searching...
No Matches
colorspace.c
Go to the documentation of this file.
1/*
2 * Copyright (c) 2016 Ronald S. Bultje <rsbultje@gmail.com>
3 * This file is part of FFmpeg.
4 *
5 * FFmpeg is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
9 *
10 * FFmpeg is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with FFmpeg; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20#include "libavutil/frame.h"
22#include "libavutil/pixdesc.h"
23
24#include "colorspace.h"
25
26
27void ff_matrix_invert_3x3(const double in[3][3], double out[3][3])
28{
29 double m00 = in[0][0], m01 = in[0][1], m02 = in[0][2],
30 m10 = in[1][0], m11 = in[1][1], m12 = in[1][2],
31 m20 = in[2][0], m21 = in[2][1], m22 = in[2][2];
32 int i, j;
33 double det;
34
35 out[0][0] = (m11 * m22 - m21 * m12);
36 out[0][1] = -(m01 * m22 - m21 * m02);
37 out[0][2] = (m01 * m12 - m11 * m02);
38 out[1][0] = -(m10 * m22 - m20 * m12);
39 out[1][1] = (m00 * m22 - m20 * m02);
40 out[1][2] = -(m00 * m12 - m10 * m02);
41 out[2][0] = (m10 * m21 - m20 * m11);
42 out[2][1] = -(m00 * m21 - m20 * m01);
43 out[2][2] = (m00 * m11 - m10 * m01);
44
45 det = m00 * out[0][0] + m10 * out[0][1] + m20 * out[0][2];
46 det = 1.0 / det;
47
48 for (i = 0; i < 3; i++) {
49 for (j = 0; j < 3; j++)
50 out[i][j] *= det;
51 }
52}
53
54void ff_matrix_mul_3x3(double dst[3][3],
55 const double src1[3][3], const double src2[3][3])
56{
57 int m, n;
58
59 for (m = 0; m < 3; m++)
60 for (n = 0; n < 3; n++)
61 dst[m][n] = src2[m][0] * src1[0][n] +
62 src2[m][1] * src1[1][n] +
63 src2[m][2] * src1[2][n];
64}
65
66void ff_matrix_mul_3x3_vec(double dst[3], const double vec[3], const double mat[3][3])
67{
68 int m;
69
70 for (m = 0; m < 3; m++)
71 dst[m] = vec[0] * mat[m][0] +
72 vec[1] * mat[m][1] +
73 vec[2] * mat[m][2];
74}
75
76/*
77 * see e.g. http://www.brucelindbloom.com/index.html?Eqn_RGB_XYZ_Matrix.html
78 */
81 double rgb2xyz[3][3])
82{
83 double i[3][3], sr, sg, sb, zw;
84 double xr = av_q2d(coeffs->r.x), yr = av_q2d(coeffs->r.y);
85 double xg = av_q2d(coeffs->g.x), yg = av_q2d(coeffs->g.y);
86 double xb = av_q2d(coeffs->b.x), yb = av_q2d(coeffs->b.y);
87 double xw = av_q2d(wp->x), yw = av_q2d(wp->y);
88
89 rgb2xyz[0][0] = xr / yr;
90 rgb2xyz[0][1] = xg / yg;
91 rgb2xyz[0][2] = xb / yb;
92 rgb2xyz[1][0] = rgb2xyz[1][1] = rgb2xyz[1][2] = 1.0;
93 rgb2xyz[2][0] = (1.0 - xr - yr) / yr;
94 rgb2xyz[2][1] = (1.0 - xg - yg) / yg;
95 rgb2xyz[2][2] = (1.0 - xb - yb) / yb;
96 ff_matrix_invert_3x3(rgb2xyz, i);
97 zw = 1.0 - xw - yw;
98 sr = i[0][0] * xw + i[0][1] * yw + i[0][2] * zw;
99 sg = i[1][0] * xw + i[1][1] * yw + i[1][2] * zw;
100 sb = i[2][0] * xw + i[2][1] * yw + i[2][2] * zw;
101 rgb2xyz[0][0] *= sr;
102 rgb2xyz[0][1] *= sg;
103 rgb2xyz[0][2] *= sb;
104 rgb2xyz[1][0] *= sr;
105 rgb2xyz[1][1] *= sg;
106 rgb2xyz[1][2] *= sb;
107 rgb2xyz[2][0] *= sr;
108 rgb2xyz[2][1] *= sg;
109 rgb2xyz[2][2] *= sb;
110}
111static const double ycgco_matrix[3][3] =
112{
113 { 0.25, 0.5, 0.25 },
114 { -0.25, 0.5, -0.25 },
115 { 0.5, 0, -0.5 },
116};
117
118static const double gbr_matrix[3][3] =
119{
120 { 0, 1, 0 },
121 { 0, -0.5, 0.5 },
122 { 0.5, -0.5, 0 },
123};
124
126 double rgb2yuv[3][3])
127{
128 double bscale, rscale;
129 double cr = av_q2d(coeffs->cr), cg = av_q2d(coeffs->cg), cb = av_q2d(coeffs->cb);
130
131 // special ycgco matrix
132 if (cr == 0.25 && cg == 0.5 && cb == 0.25) {
133 memcpy(rgb2yuv, ycgco_matrix, sizeof(double) * 9);
134 return;
135 } else if (cr == 1 && cg == 1 && cb == 1) {
136 memcpy(rgb2yuv, gbr_matrix, sizeof(double) * 9);
137 return;
138 }
139
140 rgb2yuv[0][0] = cr;
141 rgb2yuv[0][1] = cg;
142 rgb2yuv[0][2] = cb;
143 bscale = 0.5 / (cb - 1.0);
144 rscale = 0.5 / (cr - 1.0);
145 rgb2yuv[1][0] = bscale * cr;
146 rgb2yuv[1][1] = bscale * cg;
147 rgb2yuv[1][2] = 0.5;
148 rgb2yuv[2][0] = 0.5;
149 rgb2yuv[2][1] = rscale * cg;
150 rgb2yuv[2][2] = rscale * cb;
151}
152
154{
156 double peak = 0;
157
158 if (sd) {
160 peak = clm->MaxCLL / REFERENCE_WHITE;
161 }
162
164 if (!peak && sd) {
166 if (metadata->has_luminance)
167 peak = av_q2d(metadata->max_luminance) / REFERENCE_WHITE;
168 }
169
170 // For untagged source, use peak of 10000 if SMPTE ST.2084
171 // otherwise assume HLG with reference display peak 1000.
172 if (!peak)
173 peak = in->color_trc == AVCOL_TRC_SMPTE2084 ? 100.0f : 10.0f;
174
175 return peak;
176}
177
178void ff_update_hdr_metadata(AVFrame *in, double peak)
179{
181
182 if (sd) {
184 clm->MaxCLL = (unsigned)(peak * REFERENCE_WHITE);
185 }
186
188 if (sd) {
190 if (metadata->has_luminance)
191 metadata->max_luminance = av_d2q(peak * REFERENCE_WHITE, 10000);
192 }
193}
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
Definition dsp.h:87
static FILE * out
static int FUNC metadata(CodedBitstreamContext *ctx, RWContext *rw, APVRawMetadata *current)
#define i(width, name, range_min, range_max)
Definition cbs_h264.c:63
static void fn rgb2yuv(uint8_t *_yuv[3], const ptrdiff_t yuv_stride[3], int16_t *rgb[3], ptrdiff_t s, int w, int h, const int16_t rgb2yuv_coeffs[3][3][8], const int16_t yuv_offset[8])
reference-counted frame API
AVFrameSideData * av_frame_get_side_data(const AVFrame *frame, enum AVFrameSideDataType type)
Definition frame.c:659
@ AV_FRAME_DATA_CONTENT_LIGHT_LEVEL
Content light level (based on CTA-861.3).
Definition frame.h:137
@ AV_FRAME_DATA_MASTERING_DISPLAY_METADATA
Mastering display metadata associated with a video frame.
Definition frame.h:120
AVCIExy AVWhitepointCoefficients
Struct defining white point location in terms of CIE 1931 chromaticity x and y.
Definition csp.h:72
AVRational av_d2q(double d, int max)
Convert a double precision floating point number to a rational.
Definition rational.c:110
static double av_q2d(AVRational a)
Convert an AVRational to a double.
Definition rational.h:104
const pixel * src2
void ff_matrix_mul_3x3(double dst[3][3], const double src1[3][3], const double src2[3][3])
Definition colorspace.c:54
void ff_fill_rgb2xyz_table(const AVPrimaryCoefficients *coeffs, const AVWhitepointCoefficients *wp, double rgb2xyz[3][3])
Definition colorspace.c:79
void ff_matrix_mul_3x3_vec(double dst[3], const double vec[3], const double mat[3][3])
Definition colorspace.c:66
double ff_determine_signal_peak(AVFrame *in)
Definition colorspace.c:153
void ff_matrix_invert_3x3(const double in[3][3], double out[3][3])
Definition colorspace.c:27
void ff_update_hdr_metadata(AVFrame *in, double peak)
Definition colorspace.c:178
static const double gbr_matrix[3][3]
Definition colorspace.c:118
static const double ycgco_matrix[3][3]
Definition colorspace.c:111
void ff_fill_rgb2yuv_table(const AVLumaCoefficients *coeffs, double rgb2yuv[3][3])
Definition colorspace.c:125
#define REFERENCE_WHITE
Definition colorspace.h:27
@ AVCOL_TRC_SMPTE2084
SMPTE ST 2084 for 10-, 12-, 14- and 16-bit systems.
Definition pixfmt.h:689
AVRational x
Definition csp.h:57
AVRational y
Definition csp.h:57
Content light level needed by to transmit HDR over HDMI (CTA-861.3).
unsigned MaxCLL
Max content light level (cd/m^2).
Structure to hold side data for an AVFrame.
Definition frame.h:327
uint8_t * data
Definition frame.h:329
This structure describes decoded (raw) audio or video data.
Definition frame.h:472
enum AVColorTransferCharacteristic color_trc
Definition frame.h:727
Struct containing luma coefficients to be used for RGB to YUV/YCoCg, or similar calculations.
Definition csp.h:48
AVRational cb
Definition csp.h:49
AVRational cr
Definition csp.h:49
AVRational cg
Definition csp.h:49
Mastering display metadata capable of representing the color volume of the display used to master the...
Struct defining the red, green, and blue primary locations in terms of CIE 1931 chromaticity x and y.
Definition csp.h:64
#define src1
Definition h264pred.c:141
static double cr(void *priv, double x, double y)
Definition vf_geq.c:248
static double cb(void *priv, double x, double y)
Definition vf_geq.c:247