1 /* Copyright 2022 Advanced Micro Devices, Inc.
2 *
3 * Permission is hereby granted, free of charge, to any person obtaining a
4 * copy of this software and associated documentation files (the "Software"),
5 * to deal in the Software without restriction, including without limitation
6 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
7 * and/or sell copies of the Software, and to permit persons to whom the
8 * Software is furnished to do so, subject to the following conditions:
9 *
10 * The above copyright notice and this permission notice shall be included in
11 * all copies or substantial portions of the Software.
12 *
13 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
16 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
17 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
18 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
19 * OTHER DEALINGS IN THE SOFTWARE.
20 *
21 * Authors: AMD
22 *
23 */
24
25 #include <string.h>
26 #include "common.h"
27 #include "vpe_priv.h"
28 #include "color.h"
29 #include "color_cs.h"
30 #include "hw_shared.h"
31 #include "conversion.h"
32
33 #define DIVIDER 10000
34 /* S2D13 value in [-3.999...3.999] */
35 #define S2D13_MIN (-39990)
36 #define S2D13_MAX (39990)
37
38 static void translate_blt_to_internal_adjustments(
39 const struct vpe_color_adjust *blt_adjust, struct vpe_color_adjustments *dal_adjust);
40
41 /* these values are defaults: 0 brightness, 1 contrast, 0 hue, 1 saturation*/
42 static struct vpe_color_adjust defaultClrAdjust = {0.0f, 1.0f, 0.0f, 1.0f};
43
vpe_color_set_adjustments_to_default(struct vpe_color_adjust * crt_vpe_adjusts)44 void vpe_color_set_adjustments_to_default(struct vpe_color_adjust *crt_vpe_adjusts)
45 {
46 *crt_vpe_adjusts = defaultClrAdjust;
47 }
48
vpe_color_different_color_adjusts(const struct vpe_color_adjust * new_vpe_adjusts,struct vpe_color_adjust * crt_vpe_adjsuts)49 bool vpe_color_different_color_adjusts(
50 const struct vpe_color_adjust *new_vpe_adjusts, struct vpe_color_adjust *crt_vpe_adjsuts)
51 {
52 if ((crt_vpe_adjsuts->brightness != new_vpe_adjusts->brightness) ||
53 (crt_vpe_adjsuts->saturation != new_vpe_adjusts->saturation) ||
54 (crt_vpe_adjsuts->hue != new_vpe_adjusts->hue) ||
55 (crt_vpe_adjsuts->contrast != new_vpe_adjusts->contrast)) {
56 return true;
57 }
58 return false;
59 }
60
61 /**
62 * Adjustment Min Max default step
63 *
64 * Input range
65 * Brightness -100.0f, 100.0f, 0.0f, 0.1f
66 * Contrast 0.0f, 2.0f, 1.0f, 0.01f
67 * Hue -180.0f, 180.0f, 0.0f, 1.0f
68 * Saturation 0.0f, 3.0f, 1.0f, 0.01f
69 *
70 * DAL range
71 * Brightness -100, 100, 0, 1
72 * Contrast 0, 200, 100, 1
73 * Hue -30, 30, 0, 1
74 * Saturation 0, 200, 100, 1
75 */
76
translate_blt_to_internal_adjustments(const struct vpe_color_adjust * blt_adjust,struct vpe_color_adjustments * dal_adjust)77 static void translate_blt_to_internal_adjustments(
78 const struct vpe_color_adjust *blt_adjust, struct vpe_color_adjustments *dal_adjust)
79 {
80 dal_adjust->brightness.current = (int)(10 * blt_adjust->brightness);
81 dal_adjust->brightness.min = -1000;
82 dal_adjust->brightness.max = 1000;
83
84 dal_adjust->contrast.current = (int)(100 * blt_adjust->contrast);
85 dal_adjust->contrast.min = 0;
86 dal_adjust->contrast.max = 200;
87
88 dal_adjust->saturation.current = (int)(100 * blt_adjust->saturation);
89 dal_adjust->saturation.min = 0;
90 dal_adjust->saturation.max = 300; // assuming input bigger range
91
92 dal_adjust->hue.current = (int)(blt_adjust->hue);
93 dal_adjust->hue.min = -180;
94 dal_adjust->hue.max = 180; // assuming input bigger range
95 }
96
get_hw_value_from_sw_value(int swVal,int swMin,int swMax,int hwMin,int hwMax)97 static int get_hw_value_from_sw_value(int swVal, int swMin, int swMax, int hwMin, int hwMax)
98 {
99 int dSW = swMax - swMin; /*software adjustment range size*/
100 int dHW = hwMax - hwMin; /*hardware adjustment range size*/
101 int hwVal; /*HW adjustment value*/
102
103 /* error case, I preserve the behavior from the predecessor
104 *getHwStepFromSwHwMinMaxValue (removed in Feb 2013)
105 *which was the FP version that only computed SCLF (i.e. dHW/dSW).
106 *it would return 0 in this case so
107 *hwVal = hwMin from the formula given in @brief
108 */
109 if (dSW == 0)
110 return hwMin;
111
112 /*it's quite often that ranges match,
113 *e.g. for overlay colors currently (Feb 2013)
114 *only brightness has a different
115 *HW range, and in this case no multiplication or division is needed,
116 *and if minimums match, no calculation at all
117 */
118
119 if (dSW != dHW) {
120 hwVal = (swVal - swMin) * dHW / dSW + hwMin;
121 } else {
122 hwVal = swVal;
123 if (swMin != hwMin)
124 hwVal += (hwMin - swMin);
125 }
126
127 return hwVal;
128 }
129
color_adjustments_to_fixed_point(const struct vpe_color_adjustments * vpe_adjust,bool icsc,struct fixed31_32 * grph_cont,struct fixed31_32 * grph_sat,struct fixed31_32 * grph_bright,struct fixed31_32 * sin_grph_hue,struct fixed31_32 * cos_grph_hue)130 static void color_adjustments_to_fixed_point(const struct vpe_color_adjustments *vpe_adjust,
131 bool icsc, // input csc or output csc
132 struct fixed31_32 *grph_cont, struct fixed31_32 *grph_sat, struct fixed31_32 *grph_bright,
133 struct fixed31_32 *sin_grph_hue, struct fixed31_32 *cos_grph_hue)
134 {
135 /* Hue adjustment could be negative. -45 ~ +45 */
136 struct fixed31_32 hue;
137 const int hw_hue_min = -30;
138 const int hw_hue_max = 30;
139 const int hw_sat_min = 0;
140 const int hw_sat_max = 200;
141 const int hw_contrast_min = 0;
142 const int hw_contrast_max = 200;
143 const int hw_bright_min = -1000;
144 const int hw_bright_max = 1000;
145 if (icsc) {
146 hue = vpe_fixpt_mul(
147 vpe_fixpt_from_fraction(
148 get_hw_value_from_sw_value(vpe_adjust->hue.current, vpe_adjust->hue.min,
149 vpe_adjust->hue.max, -hw_hue_min, hw_hue_max),
150 180),
151 vpe_fixpt_pi);
152
153 // In MMD is -100 to +100 in 16-235 range; which when scaled to full
154 // range is ~-116 to +116. When normalized this is about 0.4566.
155 *grph_bright = vpe_fixpt_from_fraction(
156 get_hw_value_from_sw_value(vpe_adjust->brightness.current, vpe_adjust->brightness.min,
157 vpe_adjust->brightness.max, hw_bright_min, hw_bright_max),
158 1000);
159
160 *grph_cont = vpe_fixpt_from_fraction(
161 get_hw_value_from_sw_value(vpe_adjust->contrast.current, vpe_adjust->contrast.min,
162 vpe_adjust->contrast.max, hw_contrast_min, hw_contrast_max),
163 100);
164
165 *grph_sat = vpe_fixpt_from_fraction(
166 get_hw_value_from_sw_value(vpe_adjust->saturation.current, vpe_adjust->saturation.min,
167 vpe_adjust->saturation.max, hw_sat_min, hw_sat_max),
168 100);
169 } else {
170 hue = vpe_fixpt_mul(
171 vpe_fixpt_from_fraction(
172 get_hw_value_from_sw_value(vpe_adjust->hue.current, vpe_adjust->hue.min,
173 vpe_adjust->hue.max, -hw_hue_min, hw_hue_max),
174 180),
175 vpe_fixpt_pi);
176
177 *grph_bright = vpe_fixpt_from_fraction(
178 get_hw_value_from_sw_value(vpe_adjust->brightness.current, vpe_adjust->brightness.min,
179 vpe_adjust->brightness.max, hw_bright_min, hw_bright_max),
180 100);
181
182 *grph_cont = vpe_fixpt_from_fraction(
183 get_hw_value_from_sw_value(vpe_adjust->contrast.current, vpe_adjust->contrast.min,
184 vpe_adjust->contrast.max, hw_contrast_min, hw_contrast_max),
185 100);
186
187 *grph_sat = vpe_fixpt_from_fraction(
188 get_hw_value_from_sw_value(vpe_adjust->saturation.current, vpe_adjust->saturation.min,
189 vpe_adjust->saturation.max, hw_sat_min, hw_sat_max),
190 100);
191 }
192
193 *sin_grph_hue = vpe_fixpt_sin(hue);
194 *cos_grph_hue = vpe_fixpt_cos(hue);
195 }
196
calculate_rgb_matrix_legacy(struct vpe_color_adjustments * vpe_adjust,struct fixed31_32 * rgb_matrix)197 static void calculate_rgb_matrix_legacy(
198 struct vpe_color_adjustments *vpe_adjust, struct fixed31_32 *rgb_matrix)
199 {
200 const struct fixed31_32 k1 = vpe_fixpt_from_fraction(787400, 1000000);
201 const struct fixed31_32 k2 = vpe_fixpt_from_fraction(180428, 1000000);
202 const struct fixed31_32 k3 = vpe_fixpt_from_fraction(-715200, 1000000);
203 const struct fixed31_32 k4 = vpe_fixpt_from_fraction(606972, 1000000);
204 const struct fixed31_32 k5 = vpe_fixpt_from_fraction(-72200, 1000000);
205 const struct fixed31_32 k6 = vpe_fixpt_from_fraction(-787400, 1000000);
206 const struct fixed31_32 k7 = vpe_fixpt_from_fraction(-212600, 1000000);
207 const struct fixed31_32 k8 = vpe_fixpt_from_fraction(-147296, 1000000);
208 const struct fixed31_32 k9 = vpe_fixpt_from_fraction(284800, 1000000);
209 const struct fixed31_32 k10 = vpe_fixpt_from_fraction(-95354, 1000000);
210 const struct fixed31_32 k11 = vpe_fixpt_from_fraction(-72200, 1000000);
211 const struct fixed31_32 k12 = vpe_fixpt_from_fraction(242650, 1000000);
212 const struct fixed31_32 k13 = vpe_fixpt_from_fraction(-212600, 1000000);
213 const struct fixed31_32 k14 = vpe_fixpt_from_fraction(927800, 1000000);
214 const struct fixed31_32 k15 = vpe_fixpt_from_fraction(-715200, 1000000);
215 const struct fixed31_32 k16 = vpe_fixpt_from_fraction(-842726, 1000000);
216 const struct fixed31_32 k17 = vpe_fixpt_from_fraction(927800, 1000000);
217 const struct fixed31_32 k18 = vpe_fixpt_from_fraction(-85074, 1000000);
218
219 const struct fixed31_32 luma_r = vpe_fixpt_from_fraction(2126, 10000);
220 const struct fixed31_32 luma_g = vpe_fixpt_from_fraction(7152, 10000);
221 const struct fixed31_32 luma_b = vpe_fixpt_from_fraction(722, 10000);
222
223 struct fixed31_32 grph_cont;
224 struct fixed31_32 grph_sat;
225 struct fixed31_32 grph_bright;
226 struct fixed31_32 sin_grph_hue;
227 struct fixed31_32 cos_grph_hue;
228
229 color_adjustments_to_fixed_point(
230 vpe_adjust, true, &grph_cont, &grph_sat, &grph_bright, &sin_grph_hue, &cos_grph_hue);
231
232 /* COEF_1_1 = GrphCont * (LumaR + GrphSat * (Cos(GrphHue) * K1 +*/
233 /* Sin(GrphHue) * K2))*/
234 /* (Cos(GrphHue) * K1 + Sin(GrphHue) * K2)*/
235 rgb_matrix[0] = vpe_fixpt_add(vpe_fixpt_mul(cos_grph_hue, k1), vpe_fixpt_mul(sin_grph_hue, k2));
236 /* GrphSat * (Cos(GrphHue) * K1 + Sin(GrphHue) * K2 */
237 rgb_matrix[0] = vpe_fixpt_mul(grph_sat, rgb_matrix[0]);
238 /* (LumaR + GrphSat * (Cos(GrphHue) * K1 + Sin(GrphHue) * K2))*/
239 rgb_matrix[0] = vpe_fixpt_add(luma_r, rgb_matrix[0]);
240 /* GrphCont * (LumaR + GrphSat * (Cos(GrphHue) * K1 + Sin(GrphHue)**/
241 /* K2))*/
242 rgb_matrix[0] = vpe_fixpt_mul(grph_cont, rgb_matrix[0]);
243
244 /* COEF_1_2 = GrphCont * (LumaG + GrphSat * (Cos(GrphHue) * K3 +*/
245 /* Sin(GrphHue) * K4))*/
246 /* (Cos(GrphHue) * K3 + Sin(GrphHue) * K4)*/
247 rgb_matrix[1] = vpe_fixpt_add(vpe_fixpt_mul(cos_grph_hue, k3), vpe_fixpt_mul(sin_grph_hue, k4));
248 /* GrphSat * (Cos(GrphHue) * K3 + Sin(GrphHue) * K4)*/
249 rgb_matrix[1] = vpe_fixpt_mul(grph_sat, rgb_matrix[1]);
250 /* (LumaG + GrphSat * (Cos(GrphHue) * K3 + Sin(GrphHue) * K4))*/
251 rgb_matrix[1] = vpe_fixpt_add(luma_g, rgb_matrix[1]);
252 /* GrphCont * (LumaG + GrphSat * (Cos(GrphHue) * K3 + Sin(GrphHue)**/
253 /* K4))*/
254 rgb_matrix[1] = vpe_fixpt_mul(grph_cont, rgb_matrix[1]);
255
256 /* COEF_1_3 = GrphCont * (LumaB + GrphSat * (Cos(GrphHue) * K5 +*/
257 /* Sin(GrphHue) * K6))*/
258 /* (Cos(GrphHue) * K5 + Sin(GrphHue) * K6)*/
259 rgb_matrix[2] = vpe_fixpt_add(vpe_fixpt_mul(cos_grph_hue, k5), vpe_fixpt_mul(sin_grph_hue, k6));
260 /* GrphSat * (Cos(GrphHue) * K5 + Sin(GrphHue) * K6)*/
261 rgb_matrix[2] = vpe_fixpt_mul(grph_sat, rgb_matrix[2]);
262 /* LumaB + GrphSat * (Cos(GrphHue) * K5 + Sin(GrphHue) * K6)*/
263 rgb_matrix[2] = vpe_fixpt_add(luma_b, rgb_matrix[2]);
264 /* GrphCont * (LumaB + GrphSat * (Cos(GrphHue) * K5 + Sin(GrphHue)**/
265 /* K6))*/
266 rgb_matrix[2] = vpe_fixpt_mul(grph_cont, rgb_matrix[2]);
267
268 /* COEF_1_4 = GrphBright*/
269 rgb_matrix[3] = grph_bright;
270
271 /* COEF_2_1 = GrphCont * (LumaR + GrphSat * (Cos(GrphHue) * K7 +*/
272 /* Sin(GrphHue) * K8))*/
273 /* (Cos(GrphHue) * K7 + Sin(GrphHue) * K8)*/
274 rgb_matrix[4] = vpe_fixpt_add(vpe_fixpt_mul(cos_grph_hue, k7), vpe_fixpt_mul(sin_grph_hue, k8));
275 /* GrphSat * (Cos(GrphHue) * K7 + Sin(GrphHue) * K8)*/
276 rgb_matrix[4] = vpe_fixpt_mul(grph_sat, rgb_matrix[4]);
277 /* (LumaR + GrphSat * (Cos(GrphHue) * K7 + Sin(GrphHue) * K8))*/
278 rgb_matrix[4] = vpe_fixpt_add(luma_r, rgb_matrix[4]);
279 /* GrphCont * (LumaR + GrphSat * (Cos(GrphHue) * K7 + Sin(GrphHue)**/
280 /* K8))*/
281 rgb_matrix[4] = vpe_fixpt_mul(grph_cont, rgb_matrix[4]);
282
283 /* COEF_2_2 = GrphCont * (LumaG + GrphSat * (Cos(GrphHue) * K9 +*/
284 /* Sin(GrphHue) * K10))*/
285 /* (Cos(GrphHue) * K9 + Sin(GrphHue) * K10))*/
286 rgb_matrix[5] =
287 vpe_fixpt_add(vpe_fixpt_mul(cos_grph_hue, k9), vpe_fixpt_mul(sin_grph_hue, k10));
288 /* GrphSat * (Cos(GrphHue) * K9 + Sin(GrphHue) * K10))*/
289 rgb_matrix[5] = vpe_fixpt_mul(grph_sat, rgb_matrix[5]);
290 /* (LumaG + GrphSat * (Cos(GrphHue) * K9 + Sin(GrphHue) * K10))*/
291 rgb_matrix[5] = vpe_fixpt_add(luma_g, rgb_matrix[5]);
292 /* GrphCont * (LumaG + GrphSat * (Cos(GrphHue) * K9 + Sin(GrphHue)**/
293 /* K10))*/
294 rgb_matrix[5] = vpe_fixpt_mul(grph_cont, rgb_matrix[5]);
295
296 /* COEF_2_3 = GrphCont * (LumaB + GrphSat * (Cos(GrphHue) * K11 +*/
297 /* Sin(GrphHue) * K12))*/
298 /* (Cos(GrphHue) * K11 + Sin(GrphHue) * K12))*/
299 rgb_matrix[6] =
300 vpe_fixpt_add(vpe_fixpt_mul(cos_grph_hue, k11), vpe_fixpt_mul(sin_grph_hue, k12));
301 /* GrphSat * (Cos(GrphHue) * K11 + Sin(GrphHue) * K12))*/
302 rgb_matrix[6] = vpe_fixpt_mul(grph_sat, rgb_matrix[6]);
303 /* (LumaB + GrphSat * (Cos(GrphHue) * K11 + Sin(GrphHue) * K12))*/
304 rgb_matrix[6] = vpe_fixpt_add(luma_b, rgb_matrix[6]);
305 /* GrphCont * (LumaB + GrphSat * (Cos(GrphHue) * K11 + Sin(GrphHue)**/
306 /* K12))*/
307 rgb_matrix[6] = vpe_fixpt_mul(grph_cont, rgb_matrix[6]);
308
309 /* COEF_2_4 = GrphBright*/
310 rgb_matrix[7] = grph_bright;
311
312 /* COEF_3_1 = GrphCont * (LumaR + GrphSat * (Cos(GrphHue) * K13 +*/
313 /* Sin(GrphHue) * K14))*/
314 /* (Cos(GrphHue) * K13 + Sin(GrphHue) * K14)) */
315 rgb_matrix[8] =
316 vpe_fixpt_add(vpe_fixpt_mul(cos_grph_hue, k13), vpe_fixpt_mul(sin_grph_hue, k14));
317 /* GrphSat * (Cos(GrphHue) * K13 + Sin(GrphHue) * K14)) */
318 rgb_matrix[8] = vpe_fixpt_mul(grph_sat, rgb_matrix[8]);
319 /* (LumaR + GrphSat * (Cos(GrphHue) * K13 + Sin(GrphHue) * K14)) */
320 rgb_matrix[8] = vpe_fixpt_add(luma_r, rgb_matrix[8]);
321 /* GrphCont * (LumaR + GrphSat * (Cos(GrphHue) * K13 + Sin(GrphHue)**/
322 /* K14)) */
323 rgb_matrix[8] = vpe_fixpt_mul(grph_cont, rgb_matrix[8]);
324
325 /* COEF_3_2 = GrphCont * (LumaG + GrphSat * (Cos(GrphHue) * K15 +*/
326 /* Sin(GrphHue) * K16)) */
327 /* GrphSat * (Cos(GrphHue) * K15 + Sin(GrphHue) * K16) */
328 rgb_matrix[9] =
329 vpe_fixpt_add(vpe_fixpt_mul(cos_grph_hue, k15), vpe_fixpt_mul(sin_grph_hue, k16));
330 /* (LumaG + GrphSat * (Cos(GrphHue) * K15 + Sin(GrphHue) * K16)) */
331 rgb_matrix[9] = vpe_fixpt_mul(grph_sat, rgb_matrix[9]);
332 /* (LumaG + GrphSat * (Cos(GrphHue) * K15 + Sin(GrphHue) * K16)) */
333 rgb_matrix[9] = vpe_fixpt_add(luma_g, rgb_matrix[9]);
334 /* GrphCont * (LumaG + GrphSat * (Cos(GrphHue) * K15 + Sin(GrphHue)**/
335 /* K16)) */
336 rgb_matrix[9] = vpe_fixpt_mul(grph_cont, rgb_matrix[9]);
337
338 /* COEF_3_3 = GrphCont * (LumaB + GrphSat * (Cos(GrphHue) * K17 +*/
339 /* Sin(GrphHue) * K18)) */
340 /* (Cos(GrphHue) * K17 + Sin(GrphHue) * K18)) */
341 rgb_matrix[10] =
342 vpe_fixpt_add(vpe_fixpt_mul(cos_grph_hue, k17), vpe_fixpt_mul(sin_grph_hue, k18));
343 /* GrphSat * (Cos(GrphHue) * K17 + Sin(GrphHue) * K18)) */
344 rgb_matrix[10] = vpe_fixpt_mul(grph_sat, rgb_matrix[10]);
345 /* (LumaB + GrphSat * (Cos(GrphHue) * K17 + Sin(GrphHue) * K18)) */
346 rgb_matrix[10] = vpe_fixpt_add(luma_b, rgb_matrix[10]);
347 /* GrphCont * (LumaB + GrphSat * (Cos(GrphHue) * K17 + Sin(GrphHue)**/
348 /* K18)) */
349 rgb_matrix[10] = vpe_fixpt_mul(grph_cont, rgb_matrix[10]);
350
351 /* COEF_3_4 = GrphBright */
352 rgb_matrix[11] = grph_bright;
353 }
354
calculate_rgb_limited_range_matrix_legacy(struct vpe_color_adjustments * vpe_adjust,struct fixed31_32 * rgb_matrix)355 static void calculate_rgb_limited_range_matrix_legacy(
356 struct vpe_color_adjustments *vpe_adjust, struct fixed31_32 *rgb_matrix)
357 {
358 const struct fixed31_32 k1 = vpe_fixpt_from_fraction(701000, 1000000);
359 const struct fixed31_32 k2 = vpe_fixpt_from_fraction(236568, 1000000);
360 const struct fixed31_32 k3 = vpe_fixpt_from_fraction(-587000, 1000000);
361 const struct fixed31_32 k4 = vpe_fixpt_from_fraction(464432, 1000000);
362 const struct fixed31_32 k5 = vpe_fixpt_from_fraction(-114000, 1000000);
363 const struct fixed31_32 k6 = vpe_fixpt_from_fraction(-701000, 1000000);
364 const struct fixed31_32 k7 = vpe_fixpt_from_fraction(-299000, 1000000);
365 const struct fixed31_32 k8 = vpe_fixpt_from_fraction(-292569, 1000000);
366 const struct fixed31_32 k9 = vpe_fixpt_from_fraction(413000, 1000000);
367 const struct fixed31_32 k10 = vpe_fixpt_from_fraction(-92482, 1000000);
368 const struct fixed31_32 k11 = vpe_fixpt_from_fraction(-114000, 1000000);
369 const struct fixed31_32 k12 = vpe_fixpt_from_fraction(385051, 1000000);
370 const struct fixed31_32 k13 = vpe_fixpt_from_fraction(-299000, 1000000);
371 const struct fixed31_32 k14 = vpe_fixpt_from_fraction(886000, 1000000);
372 const struct fixed31_32 k15 = vpe_fixpt_from_fraction(-587000, 1000000);
373 const struct fixed31_32 k16 = vpe_fixpt_from_fraction(-741914, 1000000);
374 const struct fixed31_32 k17 = vpe_fixpt_from_fraction(886000, 1000000);
375 const struct fixed31_32 k18 = vpe_fixpt_from_fraction(-144086, 1000000);
376
377 const struct fixed31_32 luma_r = vpe_fixpt_from_fraction(299, 1000);
378 const struct fixed31_32 luma_g = vpe_fixpt_from_fraction(587, 1000);
379 const struct fixed31_32 luma_b = vpe_fixpt_from_fraction(114, 1000);
380 /*onst struct fixed31_32 luma_scale =
381 vpe_fixpt_from_fraction(875855, 1000000);*/
382
383 const struct fixed31_32 rgb_scale = vpe_fixpt_from_fraction(85546875, 100000000);
384 const struct fixed31_32 rgb_bias = vpe_fixpt_from_fraction(625, 10000);
385
386 struct fixed31_32 grph_cont;
387 struct fixed31_32 grph_sat;
388 struct fixed31_32 grph_bright;
389 struct fixed31_32 sin_grph_hue;
390 struct fixed31_32 cos_grph_hue;
391
392 color_adjustments_to_fixed_point(
393 vpe_adjust, true, &grph_cont, &grph_sat, &grph_bright, &sin_grph_hue, &cos_grph_hue);
394
395 /* COEF_1_1 = GrphCont * (LumaR + GrphSat * (Cos(GrphHue) * K1 +*/
396 /* Sin(GrphHue) * K2))*/
397 /* (Cos(GrphHue) * K1 + Sin(GrphHue) * K2)*/
398 rgb_matrix[0] = vpe_fixpt_add(vpe_fixpt_mul(cos_grph_hue, k1), vpe_fixpt_mul(sin_grph_hue, k2));
399 /* GrphSat * (Cos(GrphHue) * K1 + Sin(GrphHue) * K2 */
400 rgb_matrix[0] = vpe_fixpt_mul(grph_sat, rgb_matrix[0]);
401 /* (LumaR + GrphSat * (Cos(GrphHue) * K1 + Sin(GrphHue) * K2))*/
402 rgb_matrix[0] = vpe_fixpt_add(luma_r, rgb_matrix[0]);
403 /* GrphCont * (LumaR + GrphSat * (Cos(GrphHue) * K1 + Sin(GrphHue)**/
404 /* K2))*/
405 rgb_matrix[0] = vpe_fixpt_mul(grph_cont, rgb_matrix[0]);
406 /* LumaScale * GrphCont * (LumaR + GrphSat * (Cos(GrphHue) * K1 + */
407 /* Sin(GrphHue) * K2))*/
408 rgb_matrix[0] = vpe_fixpt_mul(rgb_scale, rgb_matrix[0]);
409
410 /* COEF_1_2 = GrphCont * (LumaG + GrphSat * (Cos(GrphHue) * K3 +*/
411 /* Sin(GrphHue) * K4))*/
412 /* (Cos(GrphHue) * K3 + Sin(GrphHue) * K4)*/
413 rgb_matrix[1] = vpe_fixpt_add(vpe_fixpt_mul(cos_grph_hue, k3), vpe_fixpt_mul(sin_grph_hue, k4));
414 /* GrphSat * (Cos(GrphHue) * K3 + Sin(GrphHue) * K4)*/
415 rgb_matrix[1] = vpe_fixpt_mul(grph_sat, rgb_matrix[1]);
416 /* (LumaG + GrphSat * (Cos(GrphHue) * K3 + Sin(GrphHue) * K4))*/
417 rgb_matrix[1] = vpe_fixpt_add(luma_g, rgb_matrix[1]);
418 /* GrphCont * (LumaG + GrphSat * (Cos(GrphHue) * K3 + Sin(GrphHue)**/
419 /* K4))*/
420 rgb_matrix[1] = vpe_fixpt_mul(grph_cont, rgb_matrix[1]);
421 /* LumaScale * GrphCont * (LumaG + GrphSat *(Cos(GrphHue) * K3 + */
422 /* Sin(GrphHue) * K4))*/
423 rgb_matrix[1] = vpe_fixpt_mul(rgb_scale, rgb_matrix[1]);
424
425 /* COEF_1_3 = GrphCont * (LumaB + GrphSat * (Cos(GrphHue) * K5 +*/
426 /* Sin(GrphHue) * K6))*/
427 /* (Cos(GrphHue) * K5 + Sin(GrphHue) * K6)*/
428 rgb_matrix[2] = vpe_fixpt_add(vpe_fixpt_mul(cos_grph_hue, k5), vpe_fixpt_mul(sin_grph_hue, k6));
429 /* GrphSat * (Cos(GrphHue) * K5 + Sin(GrphHue) * K6)*/
430 rgb_matrix[2] = vpe_fixpt_mul(grph_sat, rgb_matrix[2]);
431 /* LumaB + GrphSat * (Cos(GrphHue) * K5 + Sin(GrphHue) * K6)*/
432 rgb_matrix[2] = vpe_fixpt_add(luma_b, rgb_matrix[2]);
433 /* GrphCont * (LumaB + GrphSat * (Cos(GrphHue) * K5 + Sin(GrphHue)**/
434 /* K6))*/
435 rgb_matrix[2] = vpe_fixpt_mul(grph_cont, rgb_matrix[2]);
436 /* LumaScale * GrphCont * (LumaB + GrphSat *(Cos(GrphHue) * K5 + */
437 /* Sin(GrphHue) * K6))*/
438 rgb_matrix[2] = vpe_fixpt_mul(rgb_scale, rgb_matrix[2]);
439
440 /* COEF_1_4 = RGBBias + RGBScale * GrphBright*/
441 rgb_matrix[3] = vpe_fixpt_add(rgb_bias, vpe_fixpt_mul(rgb_scale, grph_bright));
442
443 /* COEF_2_1 = GrphCont * (LumaR + GrphSat * (Cos(GrphHue) * K7 +*/
444 /* Sin(GrphHue) * K8))*/
445 /* (Cos(GrphHue) * K7 + Sin(GrphHue) * K8)*/
446 rgb_matrix[4] = vpe_fixpt_add(vpe_fixpt_mul(cos_grph_hue, k7), vpe_fixpt_mul(sin_grph_hue, k8));
447 /* GrphSat * (Cos(GrphHue) * K7 + Sin(GrphHue) * K8)*/
448 rgb_matrix[4] = vpe_fixpt_mul(grph_sat, rgb_matrix[4]);
449 /* (LumaR + GrphSat * (Cos(GrphHue) * K7 + Sin(GrphHue) * K8))*/
450 rgb_matrix[4] = vpe_fixpt_add(luma_r, rgb_matrix[4]);
451 /* GrphCont * (LumaR + GrphSat * (Cos(GrphHue) * K7 + Sin(GrphHue)**/
452 /* K8))*/
453 rgb_matrix[4] = vpe_fixpt_mul(grph_cont, rgb_matrix[4]);
454 /* LumaScale * GrphCont * (LumaR + GrphSat * (Cos(GrphHue) * K7 + */
455 /* Sin(GrphHue) * K8))*/
456 rgb_matrix[4] = vpe_fixpt_mul(rgb_scale, rgb_matrix[4]);
457
458 /* COEF_2_2 = GrphCont * (LumaG + GrphSat * (Cos(GrphHue) * K9 +*/
459 /* Sin(GrphHue) * K10))*/
460 /* (Cos(GrphHue) * K9 + Sin(GrphHue) * K10))*/
461 rgb_matrix[5] =
462 vpe_fixpt_add(vpe_fixpt_mul(cos_grph_hue, k9), vpe_fixpt_mul(sin_grph_hue, k10));
463 /* GrphSat * (Cos(GrphHue) * K9 + Sin(GrphHue) * K10))*/
464 rgb_matrix[5] = vpe_fixpt_mul(grph_sat, rgb_matrix[5]);
465 /* (LumaG + GrphSat * (Cos(GrphHue) * K9 + Sin(GrphHue) * K10))*/
466 rgb_matrix[5] = vpe_fixpt_add(luma_g, rgb_matrix[5]);
467 /* GrphCont * (LumaG + GrphSat * (Cos(GrphHue) * K9 + Sin(GrphHue)**/
468 /* K10))*/
469 rgb_matrix[5] = vpe_fixpt_mul(grph_cont, rgb_matrix[5]);
470 /* LumaScale * GrphCont * (LumaG + GrphSat *(Cos(GrphHue) * K9 + */
471 /* Sin(GrphHue) * K10))*/
472 rgb_matrix[5] = vpe_fixpt_mul(rgb_scale, rgb_matrix[5]);
473
474 /* COEF_2_3 = GrphCont * (LumaB + GrphSat * (Cos(GrphHue) * K11 +*/
475 /* Sin(GrphHue) * K12))*/
476 /* (Cos(GrphHue) * K11 + Sin(GrphHue) * K12))*/
477 rgb_matrix[6] =
478 vpe_fixpt_add(vpe_fixpt_mul(cos_grph_hue, k11), vpe_fixpt_mul(sin_grph_hue, k12));
479 /* GrphSat * (Cos(GrphHue) * K11 + Sin(GrphHue) * K12))*/
480 rgb_matrix[6] = vpe_fixpt_mul(grph_sat, rgb_matrix[6]);
481 /* (LumaB + GrphSat * (Cos(GrphHue) * K11 + Sin(GrphHue) * K12))*/
482 rgb_matrix[6] = vpe_fixpt_add(luma_b, rgb_matrix[6]);
483 /* GrphCont * (LumaB + GrphSat * (Cos(GrphHue) * K11 + Sin(GrphHue)**/
484 /* K12))*/
485 rgb_matrix[6] = vpe_fixpt_mul(grph_cont, rgb_matrix[6]);
486 /* LumaScale * GrphCont * (LumaB + GrphSat *(Cos(GrphHue) * K11 +*/
487 /* Sin(GrphHue) * K12)) */
488 rgb_matrix[6] = vpe_fixpt_mul(rgb_scale, rgb_matrix[6]);
489
490 /* COEF_2_4 = RGBBias + RGBScale * GrphBright*/
491 rgb_matrix[7] = vpe_fixpt_add(rgb_bias, vpe_fixpt_mul(rgb_scale, grph_bright));
492
493 /* COEF_3_1 = GrphCont * (LumaR + GrphSat * (Cos(GrphHue) * K13 +*/
494 /* Sin(GrphHue) * K14))*/
495 /* (Cos(GrphHue) * K13 + Sin(GrphHue) * K14)) */
496 rgb_matrix[8] =
497 vpe_fixpt_add(vpe_fixpt_mul(cos_grph_hue, k13), vpe_fixpt_mul(sin_grph_hue, k14));
498 /* GrphSat * (Cos(GrphHue) * K13 + Sin(GrphHue) * K14)) */
499 rgb_matrix[8] = vpe_fixpt_mul(grph_sat, rgb_matrix[8]);
500 /* (LumaR + GrphSat * (Cos(GrphHue) * K13 + Sin(GrphHue) * K14)) */
501 rgb_matrix[8] = vpe_fixpt_add(luma_r, rgb_matrix[8]);
502 /* GrphCont * (LumaR + GrphSat * (Cos(GrphHue) * K13 + Sin(GrphHue)**/
503 /* K14)) */
504 rgb_matrix[8] = vpe_fixpt_mul(grph_cont, rgb_matrix[8]);
505 /* LumaScale * GrphCont * (LumaR + GrphSat * (Cos(GrphHue) * K13 +*/
506 /* Sin(GrphHue) * K14))*/
507 rgb_matrix[8] = vpe_fixpt_mul(rgb_scale, rgb_matrix[8]);
508
509 /* COEF_3_2 = GrphCont * (LumaG + GrphSat * (Cos(GrphHue) * K15 +*/
510 /* Sin(GrphHue) * K16)) */
511 /* GrphSat * (Cos(GrphHue) * K15 + Sin(GrphHue) * K16) */
512 rgb_matrix[9] =
513 vpe_fixpt_add(vpe_fixpt_mul(cos_grph_hue, k15), vpe_fixpt_mul(sin_grph_hue, k16));
514 /* (LumaG + GrphSat * (Cos(GrphHue) * K15 + Sin(GrphHue) * K16)) */
515 rgb_matrix[9] = vpe_fixpt_mul(grph_sat, rgb_matrix[9]);
516 /* (LumaG + GrphSat * (Cos(GrphHue) * K15 + Sin(GrphHue) * K16)) */
517 rgb_matrix[9] = vpe_fixpt_add(luma_g, rgb_matrix[9]);
518 /* GrphCont * (LumaG + GrphSat * (Cos(GrphHue) * K15 + Sin(GrphHue)**/
519 /* K16)) */
520 rgb_matrix[9] = vpe_fixpt_mul(grph_cont, rgb_matrix[9]);
521 /* LumaScale * GrphCont * (LumaG + GrphSat *(Cos(GrphHue) * K15 + */
522 /* Sin(GrphHue) * K16))*/
523 rgb_matrix[9] = vpe_fixpt_mul(rgb_scale, rgb_matrix[9]);
524
525 /* COEF_3_3 = GrphCont * (LumaB + GrphSat * (Cos(GrphHue) * K17 +*/
526 /* Sin(GrphHue) * K18)) */
527 /* (Cos(GrphHue) * K17 + Sin(GrphHue) * K18)) */
528 rgb_matrix[10] =
529 vpe_fixpt_add(vpe_fixpt_mul(cos_grph_hue, k17), vpe_fixpt_mul(sin_grph_hue, k18));
530 /* GrphSat * (Cos(GrphHue) * K17 + Sin(GrphHue) * K18)) */
531 rgb_matrix[10] = vpe_fixpt_mul(grph_sat, rgb_matrix[10]);
532 /* (LumaB + GrphSat * (Cos(GrphHue) * K17 + Sin(GrphHue) * K18)) */
533 rgb_matrix[10] = vpe_fixpt_add(luma_b, rgb_matrix[10]);
534 /* GrphCont * (LumaB + GrphSat * (Cos(GrphHue) * K17 + Sin(GrphHue)**/
535 /* K18)) */
536 rgb_matrix[10] = vpe_fixpt_mul(grph_cont, rgb_matrix[10]);
537 /* LumaScale * GrphCont * (LumaB + GrphSat *(Cos(GrphHue) * */
538 /* K17 + Sin(GrphHue) * K18))*/
539 rgb_matrix[10] = vpe_fixpt_mul(rgb_scale, rgb_matrix[10]);
540
541 /* COEF_3_4 = RGBBias + RGBScale * GrphBright */
542 rgb_matrix[11] = vpe_fixpt_add(rgb_bias, vpe_fixpt_mul(rgb_scale, grph_bright));
543 }
544
545 /* this function scales the matrix coefficients to fit a maximum integer bit range*/
vpe_scale_csc_matrix(struct fixed31_32 * matrix,unsigned int matrixLength,unsigned int maxIntegerBits,struct fixed31_32 * scalingFactor)546 static bool vpe_scale_csc_matrix(struct fixed31_32 *matrix, unsigned int matrixLength,
547 unsigned int maxIntegerBits, struct fixed31_32 *scalingFactor)
548 {
549 bool ret = false;
550 unsigned int index = 0;
551 long long maxIntegerVal = ((long long)1 << maxIntegerBits);
552 long long maxMatrixVal = 0;
553 unsigned int crtIntPart = 0;
554 struct fixed31_32 divisionFactor = vpe_fixpt_one;
555 long long crtValue = 0;
556 unsigned int posLargestBit = 0;
557 (*scalingFactor) = vpe_fixpt_one; // by default this is initialized to one
558 for (index = 0; index < matrixLength; index++) {
559 crtValue = matrix[index].value;
560 if (crtValue < 0) {
561 crtValue = -crtValue;
562 }
563 crtIntPart = (crtValue >> FIXED31_32_BITS_PER_FRACTIONAL_PART);
564 if (maxMatrixVal < crtIntPart) {
565 maxMatrixVal = crtIntPart;
566 }
567 }
568 if ((maxMatrixVal >= maxIntegerVal) && (maxIntegerVal > 0)) {
569 for (index = 0; index < (FIXED31_32_BITS_PER_FRACTIONAL_PART - 1); index++) {
570 if (maxMatrixVal & ((long long)1 << index)) { // scan all the bits
571 posLargestBit = index;
572 }
573 }
574 divisionFactor.value = (long long)1 << (posLargestBit - maxIntegerBits + 1);
575 divisionFactor.value <<= FIXED31_32_BITS_PER_FRACTIONAL_PART;
576 (*scalingFactor) = divisionFactor;
577 for (index = 0; index < matrixLength; index++) {
578 matrix[index] = vpe_fixpt_div(matrix[index], divisionFactor);
579 }
580 ret = true;
581 }
582 return ret;
583 }
584
calculate_yuv_matrix(struct vpe_color_adjustments * vpe_adjust,enum color_space color_space,struct vpe_csc_matrix * input_cs,struct fixed31_32 * yuv_matrix)585 static void calculate_yuv_matrix(struct vpe_color_adjustments *vpe_adjust,
586 enum color_space color_space, struct vpe_csc_matrix *input_cs, struct fixed31_32 *yuv_matrix)
587 {
588 struct fixed31_32 initialMatrix[12];
589 uint32_t i = 0;
590 bool ovl = true; // if we ever have Output CSC case, we can reuse this function with ovl passed
591 // in as param
592 struct fixed31_32 grph_cont;
593 struct fixed31_32 grph_sat;
594 struct fixed31_32 grph_bright;
595 struct fixed31_32 sin_grph_hue;
596 struct fixed31_32 cos_grph_hue;
597 struct fixed31_32 multiplier;
598 struct fixed31_32 chromaOffset = vpe_fixpt_sub(vpe_fixpt_half, vpe_fixpt_one); // = -0.5
599 struct fixed31_32 lumaOffset = {
600 0x10101010LL}; //=16/255.0 This is an offset applied in the shader, not clear why
601 // to maintain compatibility this offset is still applied in VPE
602
603 /* The input YCbCr to RGB matrix is modified to embed the color adjustments as follows:
604 A = initial YCbCr to RGB conversion matrix
605 s = saturation , h = hue, c = contrast, b = brightness
606
607 | c*s*(a11*cos(h)+a13*sin(h)) a12*c c*s(a13*cos(h)-a11*sin(h)) |
608 |R| | | |Y+b |
609 |G|= | c*s*(a21*cos(h)+a23*sin(h)) a22*c c*s(a23*cos(h)-a21*sin(h)) | * |Cb-0.5|
610 |B| | | |Cr-0.5|
611 | c*s*(a31*cos(h)+a33*sin(h)) a32*c c*s(a33*cos(h)-a31*sin(h)) |
612 */
613
614 for (i = 0; i < 12; i++) {
615 initialMatrix[i] = vpe_convfix31_32(input_cs->regval[i]); // convert from s.2.13 to s.31.32
616 }
617 color_adjustments_to_fixed_point(
618 vpe_adjust, ovl, &grph_cont, &grph_sat, &grph_bright, &sin_grph_hue, &cos_grph_hue);
619 grph_bright = vpe_fixpt_sub(grph_bright, lumaOffset);
620 multiplier = vpe_fixpt_mul(grph_cont, grph_sat); // contSat
621
622 yuv_matrix[0] =
623 vpe_fixpt_mul(multiplier, vpe_fixpt_add(vpe_fixpt_mul(initialMatrix[0], cos_grph_hue),
624 vpe_fixpt_mul(initialMatrix[2], sin_grph_hue)));
625
626 yuv_matrix[1] = vpe_fixpt_mul(initialMatrix[1], grph_cont);
627
628 yuv_matrix[2] =
629 vpe_fixpt_mul(multiplier, vpe_fixpt_sub(vpe_fixpt_mul(initialMatrix[2], cos_grph_hue),
630 vpe_fixpt_mul(initialMatrix[0], sin_grph_hue)));
631
632 yuv_matrix[3] = initialMatrix[3];
633
634 yuv_matrix[4] =
635 vpe_fixpt_mul(multiplier, vpe_fixpt_add(vpe_fixpt_mul(initialMatrix[4], cos_grph_hue),
636 vpe_fixpt_mul(initialMatrix[6], sin_grph_hue)));
637
638 yuv_matrix[5] = vpe_fixpt_mul(initialMatrix[5], grph_cont);
639
640 yuv_matrix[6] =
641 vpe_fixpt_mul(multiplier, vpe_fixpt_sub(vpe_fixpt_mul(initialMatrix[6], cos_grph_hue),
642 vpe_fixpt_mul(initialMatrix[4], sin_grph_hue)));
643
644 yuv_matrix[7] = initialMatrix[7];
645
646 yuv_matrix[8] =
647 vpe_fixpt_mul(multiplier, vpe_fixpt_add(vpe_fixpt_mul(initialMatrix[8], cos_grph_hue),
648 vpe_fixpt_mul(initialMatrix[10], sin_grph_hue)));
649
650 yuv_matrix[9] = vpe_fixpt_mul(initialMatrix[9], grph_cont);
651
652 yuv_matrix[10] =
653 vpe_fixpt_mul(multiplier, vpe_fixpt_sub(vpe_fixpt_mul(initialMatrix[10], cos_grph_hue),
654 vpe_fixpt_mul(initialMatrix[8], sin_grph_hue)));
655
656 yuv_matrix[3] = vpe_fixpt_add(vpe_fixpt_mul(grph_bright, yuv_matrix[1]),
657 vpe_fixpt_add(vpe_fixpt_mul(chromaOffset, yuv_matrix[0]),
658 vpe_fixpt_mul(chromaOffset, yuv_matrix[2])));
659 yuv_matrix[7] = vpe_fixpt_add(vpe_fixpt_mul(grph_bright, yuv_matrix[5]),
660 vpe_fixpt_add(vpe_fixpt_mul(chromaOffset, yuv_matrix[4]),
661 vpe_fixpt_mul(chromaOffset, yuv_matrix[6])));
662 yuv_matrix[11] = vpe_fixpt_add(vpe_fixpt_mul(grph_bright, yuv_matrix[9]),
663 vpe_fixpt_add(vpe_fixpt_mul(chromaOffset, yuv_matrix[8]),
664 vpe_fixpt_mul(chromaOffset, yuv_matrix[10])));
665 }
666
convert_float_matrix(uint16_t * matrix,struct fixed31_32 * flt,uint32_t buffer_size)667 static void convert_float_matrix(uint16_t *matrix, struct fixed31_32 *flt, uint32_t buffer_size)
668 {
669 const struct fixed31_32 min_2_13 = vpe_fixpt_from_fraction(S2D13_MIN, DIVIDER);
670 const struct fixed31_32 max_2_13 = vpe_fixpt_from_fraction(S2D13_MAX, DIVIDER);
671 uint32_t i;
672 uint16_t temp_matrix[12];
673
674 for (i = 0; i < 12; i++)
675 temp_matrix[i] = 0;
676
677 for (i = 0; i < buffer_size; ++i) {
678 uint32_t reg_value =
679 conv_fixed_point_to_int_frac(vpe_fixpt_clamp(flt[i], min_2_13, max_2_13), 2, 13);
680
681 temp_matrix[i] = (uint16_t)reg_value;
682 }
683
684 matrix[4] = temp_matrix[0];
685 matrix[5] = temp_matrix[1];
686 matrix[6] = temp_matrix[2];
687 matrix[7] = temp_matrix[3];
688
689 matrix[8] = temp_matrix[4];
690 matrix[9] = temp_matrix[5];
691 matrix[10] = temp_matrix[6];
692 matrix[11] = temp_matrix[7];
693
694 matrix[0] = temp_matrix[8];
695 matrix[1] = temp_matrix[9];
696 matrix[2] = temp_matrix[10];
697 matrix[3] = temp_matrix[11];
698 }
699
vpe_color_calculate_input_cs(struct vpe_priv * vpe_priv,enum color_space in_cs,const struct vpe_color_adjust * vpe_blt_adjust,struct vpe_csc_matrix * input_cs,struct fixed31_32 * matrix_scaling_factor)700 bool vpe_color_calculate_input_cs(struct vpe_priv *vpe_priv, enum color_space in_cs,
701 const struct vpe_color_adjust *vpe_blt_adjust, struct vpe_csc_matrix *input_cs,
702 struct fixed31_32 *matrix_scaling_factor)
703 {
704 struct fixed31_32 fixed_csc_matrix[12];
705
706 struct vpe_color_adjustments vpe_adjust = {0};
707
708 if (vpe_blt_adjust) {
709 translate_blt_to_internal_adjustments(vpe_blt_adjust, &vpe_adjust);
710 }
711
712 switch (in_cs) {
713 case COLOR_SPACE_SRGB:
714 case COLOR_SPACE_2020_RGB_FULLRANGE:
715 case COLOR_SPACE_MSREF_SCRGB:
716 case COLOR_SPACE_SRGB_LIMITED:
717 case COLOR_SPACE_2020_RGB_LIMITEDRANGE:
718 calculate_rgb_matrix_legacy(&vpe_adjust, fixed_csc_matrix);
719 break;
720
721 case COLOR_SPACE_YCBCR601:
722 case COLOR_SPACE_YCBCR709:
723 case COLOR_SPACE_YCBCR601_LIMITED:
724 case COLOR_SPACE_YCBCR709_LIMITED:
725 case COLOR_SPACE_2020_YCBCR:
726 calculate_yuv_matrix(&vpe_adjust, in_cs, input_cs, fixed_csc_matrix);
727 if (vpe_priv->scale_yuv_matrix) { // in case the coefficitents are too large
728 // they are scaled down to fit the n integer bits, m
729 // fractional bits (for now 2.19)
730 vpe_log("Scale down YUV -> RGB matrix");
731 vpe_scale_csc_matrix(fixed_csc_matrix, 12, 2, matrix_scaling_factor);
732 } else {
733 vpe_log("No scaling on the yuv -> rgb matrix");
734 }
735 break;
736
737 default:
738 calculate_rgb_matrix_legacy(&vpe_adjust, fixed_csc_matrix);
739 break;
740 }
741 conv_convert_float_matrix(&input_cs->regval[0], fixed_csc_matrix, 12);
742
743 return true;
744 }
745