xref: /aosp_15_r20/external/intel-media-driver/media_softlet/agnostic/common/vp/hal/vp_common.c (revision ba62d9d3abf0e404f2022b4cd7a85e107f48596f)
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