1 /*
2 * Copyright (c) 2020, 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     decode_av1_filmgrain_feature_g12.h
24 //! \brief    Defines the film grain feature for decode av1
25 //!
26 #ifndef __DECODE_AV1_FILMGRAIN_FEATURE_G12_H__
27 #define __DECODE_AV1_FILMGRAIN_FEATURE_G12_H__
28 
29 #include "decode_resource_array.h"
30 #include "decode_allocator.h"
31 #include "decode_basic_feature.h"
32 #include "codec_def_decode_av1.h"
33 #include "codechal_hw_g12_X.h"
34 #include "decode_av1_basic_feature_g12.h"
35 
36 namespace decode
37 {
38 //!
39 //! \enum     FilmGrainKernelStateIdx
40 //! \brief    Film Grain kernel state index indicating the 4 stages of kernel
41 //!
42 enum FilmGrainKernelStateIdx
43 {
44     getRandomValues = 0,  //!< Film Grain kernel index for GetRandomValues
45     regressPhase1,        //!< Film Grain kernel index for RegressPhase1
46     regressPhase2,        //!< Film Grain kernel index for RegressPhase2
47     applyNoise,           //!< Film Grain kernel index for ApplyNoise
48     kernelNum             //!< Total kernel number for one Film Grain execution
49 };
50 
51 //!
52 //! \enum PerfTagCallType
53 //!
54 enum
55 {
56     PERFTAG_CALL_FILM_GRAIN_KERNEL = 1,
57     PERFTAG_CALL_FILM_GRAIN_GRV_KERNEL,
58     PERFTAG_CALL_FILM_GRAIN_RP1_KERNEL,
59     PERFTAG_CALL_FILM_GRAIN_RP2_KERNEL,
60     PERFTAG_CALL_FILM_GRAIN_AN_KERNEL
61 };
62 
63 struct CodecKernelHeader
64 {
65     union
66     {
67         struct
68         {
69             uint32_t                    : 6;
70             uint32_t KernelStartPointer : 26;  // GTT 31:6
71         };
72         struct
73         {
74             uint32_t Value;
75         };
76     };
77 };
78 
79 class Av1DecodeFilmGrainG12 : public MediaFeature
80 {
81 public:
82     Av1DecodeFilmGrainG12(MediaFeatureManager *featureManager, DecodeAllocator *allocator, CodechalHwInterface *hwInterface);
83 
84     ~Av1DecodeFilmGrainG12();
85 
86     //!
87     //! \brief  Init Film Grain feature related parameter
88     //! \param  [in] settings
89     //!         Pointer to settings
90     //! \return MOS_STATUS
91     //!         MOS_STATUS_SUCCESS if success, else fail reason
92     //!
93     MOS_STATUS Init(void *settings);
94 
95     //!
96     //! \brief  Update Film Grain feature related parameter
97     //! \param  [in] params
98     //!         Pointer to parameters
99     //! \return MOS_STATUS
100     //!         MOS_STATUS_SUCCESS if success, else fail reason
101     //!
102     MOS_STATUS Update(void *params);
103 
104     //!
105     //! \brief    Get common kernel header and size
106     //!
107     //! \param    [in] binary
108     //!           Kernel binary
109     //!
110     //! \param    [in] index
111     //!           kernel stage index
112     //!
113     //! \param    [in] bitDepthIndicator
114     //!           Indication of bit depth, 0-8b, 1-10b
115     //!
116     //! \param    [in] krnHeader
117     //!           Kernel header
118     //!
119     //! \param    [in] krnSize
120     //!           Kernel size
121     //!
122     //! \return   MOS_STATUS
123     //!           MOS_STATUS_SUCCESS if success, else fail reason
124     //!
125     MOS_STATUS GetCommonKernelHeaderAndSize(
126         void                            *binary,
127         FilmGrainKernelStateIdx         index,
128         uint8_t                         bitDepthIndicator,
129         void                            *krnHeader,
130         uint32_t                        *krnSize);
131 
132     //!
133     //! \brief    Initialize Film Grain Kernel State
134     //! \details  Initialize Film Grain Kernel State & Params
135     //! \return   MOS_STATUS
136     //!           MOS_STATUS_SUCCESS if success, else fail reason
137     //!
138     MOS_STATUS InitializeKernelState();
139 
140     //!
141     //! \brief    Send Media VFE cmds
142     //! \details  Send Media VFE cmds to setup VFE for media kernel
143     //! \param    [in] cmdBuffer
144     //!           Pointer to command buffer
145     //! \param    [in] kernelState
146     //!           Pointer to MHW kernel state
147     //! \return   MOS_STATUS
148     //!           MOS_STATUS_SUCCESS if success, else fail reason
149     //!
150     virtual MOS_STATUS SetupMediaVfe(
151         PMOS_COMMAND_BUFFER  cmdBuffer,
152         MHW_KERNEL_STATE     *kernelState);
153 
154     //!
155     //! \brief    Allocate fixed size resources
156     //! \details  Allocate fixed size resources for film grain kernels
157     //! \return   MOS_STATUS
158     //!           MOS_STATUS_SUCCESS if success, else fail reason
159     //!
160     MOS_STATUS AllocateFixedSizeSurfaces();
161 
162     //!
163     //! \brief    Allocate variable size resources
164     //! \details  Allocate variable size resources for film grain kernels
165     //! \return   MOS_STATUS
166     //!           MOS_STATUS_SUCCESS if success, else fail reason
167     //!
168     MOS_STATUS AllocateVariableSizeSurfaces();
169 
170     //!
171     //! \brief    Init scaling function
172     //! \details  Calculate scaling LUT according to scaling points
173     //! \param    [in] pointValue
174     //!           Pointer to scaling point values, corresponding to scaling_points[][0]
175     //! \param    [in] pointScaling
176     //!           Pointer to point scaling, corresponding to scaling_points[][1]
177     //! \param    [in] numPoints
178     //!           scaling point number
179     //! \param    [out] scalingLUT
180     //!           Pointer to scaling LUT
181     //! \return   MOS_STATUS
182     //!           MOS_STATUS_SUCCESS if success, else fail reason
183     //!
184     MOS_STATUS InitScalingFunction(
185         uint8_t *pointValue,
186         uint8_t *pointScaling,
187         uint8_t numPoints,
188         int16_t *scalingLUT);
189 
190     //!
191     //! \brief    Preprocessing scaling points and LUTs
192     //! \return   MOS_STATUS
193     //!           MOS_STATUS_SUCCESS if success, else fail reason
194     //!
195     MOS_STATUS PreProcScalingPointsAndLUTs();
196 
197     //!
198     //! \brief    Preprocessing AR coefficients for Y/U/V
199     //! \param    [out] yCoeff
200     //!           Pointer to y coefficients
201     //! \param    [out] uCoeff
202     //!           Pointer to u coefficients
203     //! \param    [out] vCoeff
204     //!           Pointer to v coefficients
205     //! \return   MOS_STATUS
206     //!           MOS_STATUS_SUCCESS if success, else fail reason
207     //!
208     MOS_STATUS PreProcArCoeffs(
209         int16_t *yCoeff,
210         int16_t *uCoeff,
211         int16_t *vCoeff);
212 
213     //!
214     //! \brief    Set frame states per AV1 picture params
215     //! \param    [in] picParams
216     //!           Pointer to AV1 Decode picture params
217     //!
218     MOS_STATUS SetFrameStates(
219         CodecAv1PicParams *picParams);
220 
221     // Parameters passed from application
222     CodecAv1SegmentsParams *m_segmentParams         = nullptr;          //!< Pointer to AV1 segments parameter
223     CodecAv1TileParams *    m_av1TileParams         = nullptr;          //!< Pointer to AV1 tiles parameter
224     bool                    m_filmGrainEnabled      = false;            //!< Per-frame film grain enable flag
225 
226     static const int32_t    m_filmGrainBindingTableCount[kernelNum];    //!< Binding table count for each kernel
227     static const int32_t    m_filmGrainCurbeSize[kernelNum];            //!< Curbe size for each kernel
228     static const int32_t    m_minLumaLegalRange     = 16;               //!< minimum Luma legal range
229     static const int32_t    m_maxLumaLegalRange     = 235;              //!< max Luma legal range
230     static const int32_t    m_minChromaLegalRange   = 16;               //!< minimum chroma legal range
231     static const int32_t    m_maxChromaLegalRange   = 240;              //!< maximum chroma legal range
232 
233 #if (_DEBUG || _RELEASE_INTERNAL)
234     MOS_SURFACE    m_fgOutputSurfList[DecodeBasicFeature::m_maxFrameIndex] = {}; //! \brief fimm grain applied surfaces
235 #endif
236 
237     enum
238     {
239         fieldTopSrcY        = 0,                                        //!< Binding table offset for Top field input Y
240         fieldTopSrcUV       = 1,                                        //!< Binding table offset for Top field input UV
241         fieldBotSrcY        = 48,                                       //!< Binding table offset for Bottom field input Y
242         fieldBotSrcUV       = 49,                                       //!< Binding table offset for Bottom field input UV
243         dstY                = 24,                                       //!< Binding table offset for output Y
244         dstUV               = 25,                                       //!< Binding table offset for output UV
245         numSurfaces         = 50                                        //!< Number of BT entries for Film Grain
246     };
247 
248     //combined kernel
249     struct FilmGrainCombinedKernelHeader
250     {
251         int nKernelCount;
252         union
253         {
254             struct
255             {
256                 CodecKernelHeader getRandomValues8b;
257                 CodecKernelHeader getRandomValues10b;
258                 CodecKernelHeader regressPhase1;
259                 CodecKernelHeader regressPhase2For8b;
260                 CodecKernelHeader regressPhase2For10b;
261                 CodecKernelHeader applyNoise8b;
262                 CodecKernelHeader applyNoise10b;
263             };
264         };
265     };
266 
267     static const uint32_t           m_maxInputWidth             = 4096;                                 //!< Max input width supported by Film Grain
268     static const uint32_t           m_minInputWidth             = 128;                                  //!< Min input width supported by Film Grain
269     static const uint32_t           m_maxInputHeight            = 4096;                                 //!< Max input height supported by Film Grain
270     static const uint32_t           m_minInputHeight            = 128;                                  //!< Min input height supported by Film Grain
271 
272     static const uint32_t           m_initDshSize               = MHW_PAGE_SIZE;                        //!< Init DSH size for Film Grain kernel
273     static const uint32_t           m_numSyncTags               = 16;                                   //!< Sync tags num of state heap settings
274     static const float              m_maxScaleRatio;                                                    //!< Maximum scaling ratio for both X and Y directions
275     static const float              m_minScaleRatio;                                                    //!< Minimum scaling ratio for both X and Y directions
276     static const int32_t            m_bufferPoolDepth            = 8;
277 
278     CodechalDecode                  *m_decoder                  = nullptr;                              //!< Pointer to Decode Interface
279     MOS_INTERFACE                   *m_osInterface              = nullptr;                              //!< Pointer to OS Interface
280     CodechalHwInterface             *m_hwInterface              = nullptr;                              //!< Pointer to HW Interface
281     MhwRenderInterface              *m_renderInterface          = nullptr;                              //!< Pointer to Render Interface
282     MHW_STATE_HEAP_INTERFACE        *m_stateHeapInterface       = nullptr;                              //!< Pointer to State Heap Interface
283     MhwMiInterface                  *m_miInterface              = nullptr;                              //!< Pointer to MI interface.
284     uint8_t                         *m_kernelBaseCommon         = nullptr;                              //!< combined kernel base address
285     uint32_t                        m_combinedKernelSize        = 0;                                    //!< Combined kernel size
286     uint8_t                         m_bitDepthIndicator         = 0;                                    //!< Flag to indicate bit depth, 0-8b, 1-10b
287 
288     // Frame Parameters
289     CodecAv1PicParams               *m_picParams                 = nullptr;                             //!< Picture Params of AV1
290     int16_t                         m_scalingLutY[256]           = {0};                                 //!< Scaling LUT Y
291     int16_t                         m_scalingLutCb[256]          = {0};                                 //!< Scaling LUT U
292     int16_t                         m_scalingLutCr[256]          = {0};                                 //!< Scaling LUT V
293     uint32_t                        m_coordinateSurfaceSize      = 0;                                   //!< Record the existing coordinates random values surface size
294     uint16_t                        m_prevRandomSeed             = 0;                                   //!< Previous random seed
295 
296     // Surfaces for GetRandomValues
297     MOS_BUFFER *                     m_gaussianSequenceSurface          = nullptr;                      //!< Gaussian Sequence surface, 1D buffer, size = 2048 * sizeof(short)
298     MOS_SURFACE *                    m_yRandomValuesSurface             = nullptr;                      //!< Y random values 2D surface, size = 70 * 70 * sizeof(short)
299     MOS_SURFACE *                    m_uRandomValuesSurface             = nullptr;                      //!< U random values 2D surface, size = 38 * 38 * sizeof(short)
300     MOS_SURFACE *                    m_vRandomValuesSurface             = nullptr;                      //!< V random values 2D surface, size = 38 * 38 * sizeof(short)
301     MOS_BUFFER *                     m_coordinatesRandomValuesSurface   = nullptr;                      //!< Random values for coordinates, 1D buffer, size = RoundUp(ImageWidth / 64) * RoundUp(ImageHeight / 64) * sizeof(int)
302 
303     // Surfaces for RegressPhase1
304     MOS_SURFACE *                    m_yDitheringTempSurface            = nullptr;                      //!< First step in generating dithering noise table for Y, 2D surface, size = 70 * 70 * sizeof(short)
305     MOS_BUFFER *                     m_yCoefficientsSurface             = nullptr;                      //!< Y Coefficients required for generating dithering noise table, 1D buffer, size = 24 * size(short)
306 
307     //Surface for RegressionPhase2
308     MOS_SURFACE *                    m_yDitheringSurface                = nullptr;                      //!< Y Dithering surface, size = 8 bit: 4 * 64 * 64 * sizeof(char), 10 bit:  4 * 64 * 64 * sizeof(short)
309     MOS_SURFACE *                    m_uDitheringSurface                = nullptr;                      //!< U Dithering surface, size = 8 bit:   4 * 32 * 32 * sizeof(char), 10 bit:  4 * 32 * 32 * sizeof(short)
310     MOS_SURFACE *                    m_vDitheringSurface                = nullptr;                      //!< V Dithering surface, size = 8 bit:   4 * 32 * 32 * sizeof(char), 10 bit:  4 * 32 * 32 * sizeof(short)
311     MOS_BUFFER *                     m_yCoeffSurface                    = nullptr;                      //!< Input Y Coeff surface, size = 32 * sizeof(short), 1D buffer
312     MOS_BUFFER *                     m_uCoeffSurface                    = nullptr;                      //!< Input U Coeff surface, size = 32 * sizeof(short), 1D buffer
313     MOS_BUFFER *                     m_vCoeffSurface                    = nullptr;                      //!< Input V Coeff surface, size = 32 * sizeof(short), 1D buffer
314 
315     // Surfaces for ApplyNoise
316     MOS_BUFFER *                     m_yGammaLUTSurface                 = nullptr;                      //!< Input Y Gamma LUT surface, size = 256 * sizeof(short), 1D buffer
317     MOS_BUFFER *                     m_uGammaLUTSurface                 = nullptr;                      //!< Input U Gamma LUT surface, size = 256 * sizeof(short), 1D buffer
318     MOS_BUFFER *                     m_vGammaLUTSurface                 = nullptr;                      //!< Input V Gamma LUT surface, size = 256 * sizeof(short), 1D buffer
319 
320     uint8_t                         *m_kernelBinary[kernelNum];                                         //!< Kernel binary
321     uint32_t                        m_kernelUID[kernelNum];                                             //!< Kernel unique ID
322     uint32_t                        m_kernelSize[kernelNum];                                            //!< Kernel size
323     MHW_KERNEL_STATE                m_kernelStates[kernelNum];                                          //!< Kernel state
324     uint32_t                        m_dshSize[kernelNum];                                               //!< DSH size
325     MOS_RESOURCE                    m_syncObject = {};                                                  //!< Sync Object
326 
327     //!
328     //! \brief    Initialize state heap settings and kernel params
329     //! \details  Initialize Film Grain Kernel State heap settings & params
330     //! \param    [in] hwInterface
331     //!           Pointer to HW Interface
332     //! \return   MOS_STATUS
333     //!           MOS_STATUS_SUCCESS if success, else fail reason
334     //!
335     MOS_STATUS InitInterfaceStateHeapSetting();
336 
337     //!
338     //! \brief    Initialize state heap
339     //! \details  Initialize state heap for film grain
340     //! \param    [in] hwInterface
341     //!           Pointer to HW Interface
342     //! \return   MOS_STATUS
343     //!           MOS_STATUS_SUCCESS if success, else fail reason
344     //!
345     MOS_STATUS AllocateStateHeap(
346         CodechalHwInterface               *hwInterface);
347 
348 protected:
349     DecodeAllocator *    m_allocator         = nullptr;
350     Av1BasicFeatureG12 * m_basicFeature      = nullptr;
351     bool                 m_resourceAllocated = false;
352 
353     // Surfaces arrayfor GetRandomValues
354     BufferArray *                     m_coordinatesRandomValuesSurfaceArray   = nullptr;                      //!< Random values for coordinates, 1D buffer, size = RoundUp(ImageWidth / 64) * RoundUp(ImageHeight / 64) * sizeof(int)
355 
356     // Surfaces array for RegressPhase1
357     BufferArray *                     m_yCoefficientsSurfaceArray             = nullptr;                      //!< Y Coefficients required for generating dithering noise table, 1D buffer, size = 24 * size(short)
358 
359     //Surface array for RegressionPhase2
360     SurfaceArray *                    m_yDitheringSurfaceArray                = nullptr;                      //!< Y Dithering surface, size = 8 bit: 4 * 64 * 64 * sizeof(char), 10 bit:  4 * 64 * 64 * sizeof(short)
361     SurfaceArray *                    m_uDitheringSurfaceArray                = nullptr;                      //!< U Dithering surface, size = 8 bit:   4 * 32 * 32 * sizeof(char), 10 bit:  4 * 32 * 32 * sizeof(short)
362     SurfaceArray *                    m_vDitheringSurfaceArray                = nullptr;                      //!< V Dithering surface, size = 8 bit:   4 * 32 * 32 * sizeof(char), 10 bit:  4 * 32 * 32 * sizeof(short)
363     BufferArray *                     m_yCoeffSurfaceArray                    = nullptr;                      //!< Input Y Coeff surface, size = 32 * sizeof(short), 1D buffer
364     BufferArray *                     m_uCoeffSurfaceArray                    = nullptr;                      //!< Input U Coeff surface, size = 32 * sizeof(short), 1D buffer
365     BufferArray *                     m_vCoeffSurfaceArray                    = nullptr;                      //!< Input V Coeff surface, size = 32 * sizeof(short), 1D buffer
366 
367     // Surfaces array for ApplyNoise
368     BufferArray *                     m_yGammaLUTSurfaceArray                 = nullptr;                      //!< Input Y Gamma LUT surface, size = 256 * sizeof(short), 1D buffer
369     BufferArray *                     m_uGammaLUTSurfaceArray                 = nullptr;                      //!< Input U Gamma LUT surface, size = 256 * sizeof(short), 1D buffer
370     BufferArray *                     m_vGammaLUTSurfaceArray                 = nullptr;                      //!< Input V Gamma LUT surface, size = 256 * sizeof(short), 1D buffer
371 };
372 
373 }  // namespace decode
374 
375 #endif  // !__DECODE_AV1_FILMGRAIN_FEATURE_G12_H__
376 
377