1 /*
2 * Copyright (c) 2022, Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included
12 * in all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 */
22 //!
23 //! \file vp_common.c
24 //! \brief Definition common utilities for vphal
25 //! \details Definition common utilities for vphal including:
26 //! some macro, enum, union, structure, function
27 //!
28
29 #include "vp_common.h"
30 #include "hal_kerneldll_next.h"
31 #include "vp_utils.h"
32
33 //!
34 //! \brief Get CSC matrix in a form usable by Vebox, SFC and IECP kernels
35 //! \param [in] SrcCspace
36 //! Source Cspace
37 //! \param [in] DstCspace
38 //! Destination Cspace
39 //! \param [out] pfCscCoeff
40 //! [3x3] Coefficients matrix
41 //! \param [out] pfCscInOffset
42 //! [3x1] Input Offset matrix
43 //! \param [out] pfCscOutOffset
44 //! [3x1] Output Offset matrix
45 //! \return void
46 //!
VpHal_GetCscMatrix(VPHAL_CSPACE SrcCspace,VPHAL_CSPACE DstCspace,float * pfCscCoeff,float * pfCscInOffset,float * pfCscOutOffset)47 void VpHal_GetCscMatrix(
48 VPHAL_CSPACE SrcCspace, // [in] Source Cspace
49 VPHAL_CSPACE DstCspace, // [in] Destination Cspace
50 float * pfCscCoeff, // [out] [3x3] Coefficients matrix
51 float * pfCscInOffset, // [out] [3x1] Input Offset matrix
52 float * pfCscOutOffset) // [out] [3x1] Output Offset matrix
53 {
54 float fCscMatrix[12] = {0};
55 int32_t i;
56
57 KernelDll_GetCSCMatrix(
58 SrcCspace,
59 DstCspace,
60 fCscMatrix);
61
62 // Copy [3x3] into Coeff
63 for (i = 0; i < 3; i++)
64 {
65 MOS_SecureMemcpy(
66 &pfCscCoeff[i * 3],
67 sizeof(float) * 3,
68 &fCscMatrix[i * 4],
69 sizeof(float) * 3);
70 }
71
72 // Get the input offsets
73 switch (SrcCspace)
74 {
75 CASE_YUV_CSPACE_LIMITEDRANGE:
76 pfCscInOffset[0] = -16.0F;
77 pfCscInOffset[1] = -128.0F;
78 pfCscInOffset[2] = -128.0F;
79 break;
80
81 CASE_YUV_CSPACE_FULLRANGE:
82 pfCscInOffset[0] = 0.0F;
83 pfCscInOffset[1] = -128.0F;
84 pfCscInOffset[2] = -128.0F;
85 break;
86
87 case CSpace_sRGB:
88 pfCscInOffset[0] = 0.0F;
89 pfCscInOffset[1] = 0.0F;
90 pfCscInOffset[2] = 0.0F;
91 break;
92
93 case CSpace_stRGB:
94 pfCscInOffset[0] = -16.0F;
95 pfCscInOffset[1] = -16.0F;
96 pfCscInOffset[2] = -16.0F;
97 break;
98
99 //BT2020 YUV->RGB
100 case CSpace_BT2020:
101 pfCscInOffset[0] = -16.0F;
102 pfCscInOffset[1] = -128.0F;
103 pfCscInOffset[2] = -128.0F;
104 break;
105
106 case CSpace_BT2020_FullRange:
107 pfCscInOffset[0] = 0.0F;
108 pfCscInOffset[1] = -128.0F;
109 pfCscInOffset[2] = -128.0F;
110 break;
111
112 //BT2020 RGB->YUV
113 case CSpace_BT2020_RGB:
114 pfCscInOffset[0] = 0.0F;
115 pfCscInOffset[1] = 0.0F;
116 pfCscInOffset[2] = 0.0F;
117 break;
118
119 //BT2020 RGB->YUV
120 case CSpace_BT2020_stRGB:
121 pfCscInOffset[0] = -16.0F;
122 pfCscInOffset[1] = -16.0F;
123 pfCscInOffset[2] = -16.0F;
124 break;
125
126 default:
127 VP_PUBLIC_NORMALMESSAGE("Unsupported Input ColorSpace for Vebox %d.", (uint32_t)SrcCspace);
128 }
129
130 // Get the output offsets
131 switch (DstCspace)
132 {
133 CASE_YUV_CSPACE_LIMITEDRANGE:
134 pfCscOutOffset[0] = 16.0F;
135 pfCscOutOffset[1] = 128.0F;
136 pfCscOutOffset[2] = 128.0F;
137 break;
138
139 CASE_YUV_CSPACE_FULLRANGE:
140 pfCscOutOffset[0] = 0.0F;
141 pfCscOutOffset[1] = 128.0F;
142 pfCscOutOffset[2] = 128.0F;
143 break;
144
145 case CSpace_sRGB:
146 pfCscOutOffset[0] = 0.0F;
147 pfCscOutOffset[1] = 0.0F;
148 pfCscOutOffset[2] = 0.0F;
149 break;
150
151 case CSpace_stRGB:
152 pfCscOutOffset[0] = 16.0F;
153 pfCscOutOffset[1] = 16.0F;
154 pfCscOutOffset[2] = 16.0F;
155 break;
156
157 //BT2020 RGB->YUV
158 case CSpace_BT2020:
159 pfCscOutOffset[0] = 16.0F;
160 pfCscOutOffset[1] = 128.0F;
161 pfCscOutOffset[2] = 128.0F;
162 break;
163
164 case CSpace_BT2020_FullRange:
165 pfCscOutOffset[0] = 0.0F;
166 pfCscOutOffset[1] = 128.0F;
167 pfCscOutOffset[2] = 128.0F;
168 break;
169
170 case CSpace_BT2020_RGB:
171 pfCscOutOffset[0] = 0.0F;
172 pfCscOutOffset[1] = 0.0F;
173 pfCscOutOffset[2] = 0.0F;
174 break;
175
176 case CSpace_BT2020_stRGB:
177 pfCscOutOffset[0] = 16.0F;
178 pfCscOutOffset[1] = 16.0F;
179 pfCscOutOffset[2] = 16.0F;
180 break;
181
182 default:
183 VP_PUBLIC_NORMALMESSAGE("Unsupported Output ColorSpace for Vebox %d.", (uint32_t)DstCspace);
184 }
185 }
186
187 //! \brief Transfer float type to half precision float type
188 //! \details Transfer float type to half precision float (16bit) type
189 //! \param [in] fInput
190 //! input FP32 number
191 //! \return uint16_t
192 //! half precision float value in bit
193 //!
VpHal_FloatToHalfFloat(float fInput)194 uint16_t VpHal_FloatToHalfFloat(
195 float fInput)
196 {
197 bool Sign;
198 int32_t Exp;
199 bool ExpSign;
200 uint32_t Mantissa;
201 uint32_t dwInput;
202 VPHAL_HALF_PRECISION_FLOAT outFloat;
203
204 dwInput = *((uint32_t *)(&fInput));
205 Sign = (dwInput >> 31) & 0x01;
206 Exp = (dwInput >> 23) & 0x0FF;
207 Mantissa = dwInput & 0x07FFFFF;
208
209 outFloat.Sign = Sign;
210 outFloat.Mantissa = (Mantissa >> 13) & 0x03ff; // truncate to zero
211
212 if (Exp == 0)
213 {
214 outFloat.Exponent = 0;
215 }
216 else if (Exp == 0xff)
217 {
218 // There is one accuracy issue in this fuction.
219 // If FP32 is 0x7C800001(NaN), FP16 should be 0x7C01(NaN), but this function returns 0x7C00 instead of 0x7C01.
220 // VpHal_FloatToHalfFloatA fixes this accuracy issue.
221 outFloat.Exponent = 31;
222 }
223 else
224 {
225 // Transfer 15-bit exponent to 4-bit exponent
226 Exp -= 0x7f;
227 Exp += 0xf;
228
229 if (Exp < 1)
230 {
231 Exp = 1;
232 }
233 else if (Exp > 30)
234 {
235 Exp = 30;
236 }
237
238 outFloat.Exponent = Exp;
239 }
240
241 return outFloat.value;
242 }
243