4 #include <GLvideo_params.h>
8 static const float identity4
[16] = {1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1};
10 /* Prettyprint a 4x4 matrix @m@ */
12 matrix_dump4(float m
[4][4])
14 for (int i
= 0; i
< 4; i
++) {
15 for (int j
= 0; j
< 4; j
++) {
16 printf("%f", m
[i
][j
]);
24 /* Perform 4x4 matrix multiplication:
26 * - @dst@ may be a pointer to @a@ andor @b@
29 matrix_mul4(float dst
[4][4], const float a
[4][4], const float b
[4][4])
31 float tmp
[4][4] = {0};
33 for (int i
= 0; i
< 4; i
++) {
34 for (int j
= 0; j
< 4; j
++) {
35 for (int e
= 0; e
< 4; e
++) {
36 tmp
[i
][j
] += a
[i
][e
] * b
[e
][j
];
41 memcpy(dst
, tmp
, 16*sizeof(float));
45 buildColourMatrix(float dst
[4][4], const GLvideo_params
&p
)
47 const int bitdepth
= 8;
48 const int bitdepth_max
= (1<<bitdepth
) -1;
51 * At this point, everything is in YCbCr
52 * All components are in the range [0,1.0]
54 memcpy(dst
, identity4
, 16*sizeof(float));
56 /* offset required to get input video black to (0.,0.,0.) */
57 const float input_blacklevel
[4][4] = {
58 {1., 0., 0., -p
.input_luma_blacklevel
/(float)bitdepth_max
},
59 {0., 1., 0., -p
.input_chroma_blacklevel
/(float)bitdepth_max
},
60 {0., 0., 1., -p
.input_chroma_blacklevel
/(float)bitdepth_max
},
63 matrix_mul4(dst
, input_blacklevel
, dst
);
65 /* user supplied operations */
66 const float u_lm
= p
.luminance_mul
;
67 const float u_cm
= p
.chrominance_mul
;
68 const float u_lo
= p
.luminance_offset2
;
69 const float u_co
= p
.chrominance_offset2
;
70 const float user_matrix
[4][4] = {
76 matrix_mul4(dst
, user_matrix
, dst
);
78 /* colour matrix, YCbCr -> RGB */
79 /* Requires Y in [0,1.0], Cb&Cr in [-0.5,0.5] */
80 float Kr
= p
.matrix_Kr
;
81 float Kg
= p
.matrix_Kg
;
82 float Kb
= p
.matrix_Kb
;
83 const float colour
[4][4] = {
84 {1., 0., 2*(1-Kr
), 0.},
85 {1., -2*Kb
*(1-Kb
)/Kg
, -2*Kr
*(1-Kr
)/Kg
, 0.},
86 {1., 2*(1-Kb
), 0., 0.},
89 matrix_mul4(dst
, colour
, dst
);
92 * We are now in RGB space
95 /* scale to output range. */
96 /* NB output_max = p.output_blacklevel + p.output_range -1; */
97 const float s
= (p
.output_range
-1) / (float)(p
.input_luma_range
-1);
98 const float output_range
[4][4] = {
104 matrix_mul4(dst
, output_range
, dst
);
106 /* move (0.,0.,0.)rgb to required blacklevel */
107 const float output_blacklevel
[4][4] = {
108 {1., 0., 0., p
.output_blacklevel
/(float)bitdepth_max
},
109 {0., 1., 0., p
.output_blacklevel
/(float)bitdepth_max
},
110 {0., 0., 1., p
.output_blacklevel
/(float)bitdepth_max
},
113 matrix_mul4(dst
, output_blacklevel
, dst
);
115 /* printf("---\n");matrix_dump4(dst); */