1 /*
2 * Copyright (c) 2017, 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     codechal_kernel_hme.h
24 //! \brief    Defines the hme kernel base
25 //! \details  Hme kernel base includes all common functions and definitions for HME on all platforms
26 //!
27 
28 #ifndef __CODECHAL_KERNEL_HME_H__
29 #define __CODECHAL_KERNEL_HME_H__
30 #include "codechal_kernel_base.h"
31 
32 // clang-format off
33 static uint8_t genericBMEMethod[NUM_TARGET_USAGE_MODES + 1] =
34 {
35     0, 4, 4, 6, 6, 6, 6, 4, 7
36 };
37 
38 static uint8_t genericMEMethod[NUM_TARGET_USAGE_MODES + 1] =
39 {
40     0, 4, 4, 6, 6, 6, 6, 4, 7
41 };
42 
43 static uint32_t SuperCombineDist[NUM_TARGET_USAGE_MODES + 1] =
44 {
45     0, 1, 1, 5, 5, 5, 9, 9, 0
46 };
47 
48 // SearchPath Table, index [CodingType][MEMethod][]
49 static uint32_t codechalEncodeSearchPath[2][8][16] =
50 {
51     // I-Frame & P-Frame
52     {
53         // MEMethod: 0
54         {
55             0x120FF10F, 0x1E22E20D, 0x20E2FF10, 0x2EDD06FC, 0x11D33FF1, 0xEB1FF33D, 0x4EF1F1F1, 0xF1F21211,
56             0x0DFFFFE0, 0x11201F1F, 0x1105F1CF, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000
57         },
58         // MEMethod: 1
59         {
60             0x120FF10F, 0x1E22E20D, 0x20E2FF10, 0x2EDD06FC, 0x11D33FF1, 0xEB1FF33D, 0x4EF1F1F1, 0xF1F21211,
61             0x0DFFFFE0, 0x11201F1F, 0x1105F1CF, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000
62         },
63         // MEMethod: 2
64         {
65             0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
66             0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000
67         },
68         // MEMethod: 3
69         {
70             0x01010101, 0x11010101, 0x01010101, 0x11010101, 0x01010101, 0x11010101, 0x01010101, 0x11010101,
71             0x01010101, 0x11010101, 0x01010101, 0x00010101, 0x00000000, 0x00000000, 0x00000000, 0x00000000
72         },
73         // MEMethod: 4
74         {
75             0x0101F00F, 0x0F0F1010, 0xF0F0F00F, 0x01010101, 0x10101010, 0x0F0F0F0F, 0xF0F0F00F, 0x0101F0F0,
76             0x01010101, 0x10101010, 0x0F0F1010, 0x0F0F0F0F, 0xF0F0F00F, 0xF0F0F0F0, 0x00000000, 0x00000000
77         },
78         // MEMethod: 5
79         {
80             0x0101F00F, 0x0F0F1010, 0xF0F0F00F, 0x01010101, 0x10101010, 0x0F0F0F0F, 0xF0F0F00F, 0x0101F0F0,
81             0x01010101, 0x10101010, 0x0F0F1010, 0x0F0F0F0F, 0xF0F0F00F, 0xF0F0F0F0, 0x00000000, 0x00000000
82         },
83         // MEMethod: 6
84         {
85             0x120FF10F, 0x1E22E20D, 0x20E2FF10, 0x2EDD06FC, 0x11D33FF1, 0xEB1FF33D, 0x4EF1F1F1, 0xF1F21211,
86             0x0DFFFFE0, 0x11201F1F, 0x1105F1CF, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000
87         },
88         // MEMethod: 7 used for mpeg2 encoding P frames
89         {
90             0x1F11F10F, 0x2E22E2FE, 0x20E220DF, 0x2EDD06FC, 0x11D33FF1, 0xEB1FF33D, 0x02F1F1F1, 0x1F201111,
91             0xF1EFFF0C, 0xF01104F1, 0x10FF0A50, 0x000FF1C0, 0x00000000, 0x00000000, 0x00000000, 0x00000000
92         }
93 
94     },
95     // B-Frame
96     {
97         // MEMethod: 0
98         {
99             0x0101F00F, 0x0F0F1010, 0xF0F0F00F, 0x01010101, 0x10101010, 0x0F0F0F0F, 0xF0F0F00F, 0x0101F0F0,
100             0x01010101, 0x10101010, 0x0F0F1010, 0x0F0F0F0F, 0xF0F0F00F, 0xF0F0F0F0, 0x00000000, 0x00000000
101         },
102         // MEMethod: 1
103         {
104             0x0101F00F, 0x0F0F1010, 0xF0F0F00F, 0x01010101, 0x10101010, 0x0F0F0F0F, 0xF0F0F00F, 0x0101F0F0,
105             0x01010101, 0x10101010, 0x0F0F1010, 0x0F0F0F0F, 0xF0F0F00F, 0xF0F0F0F0, 0x00000000, 0x00000000
106         },
107         // MEMethod: 2
108         {
109             0x0101F00F, 0x0F0F1010, 0xF0F0F00F, 0x01010101, 0x10101010, 0x0F0F0F0F, 0xF0F0F00F, 0x0101F0F0,
110             0x01010101, 0x10101010, 0x0F0F1010, 0x0F0F0F0F, 0xF0F0F00F, 0xF0F0F0F0, 0x00000000, 0x00000000
111 
112         },
113         // MEMethod: 3
114         {
115             0x0101F00F, 0x0F0F1010, 0xF0F0F00F, 0x01010101, 0x10101010, 0x0F0F0F0F, 0xF0F0F00F, 0x0101F0F0,
116             0x01010101, 0x10101010, 0x0F0F1010, 0x0F0F0F0F, 0xF0F0F00F, 0xF0F0F0F0, 0x00000000, 0x00000000
117         },
118         // MEMethod: 4
119         {
120             0x0101F00F, 0x0F0F1010, 0xF0F0F00F, 0x01010101, 0x10101010, 0x0F0F0F0F, 0xF0F0F00F, 0x0101F0F0,
121             0x01010101, 0x10101010, 0x0F0F1010, 0x0F0F0F0F, 0xF0F0F00F, 0xF0F0F0F0, 0x00000000, 0x00000000
122         },
123         // MEMethod: 5
124         {
125             0x0101F00F, 0x0F0F1010, 0xF0F0F00F, 0x01010101, 0x10101010, 0x0F0F0F0F, 0xF0F0F00F, 0x0101F0F0,
126             0x01010101, 0x10101010, 0x0F0F1010, 0x0F0F0F0F, 0xF0F0F00F, 0xF0F0F0F0, 0x00000000, 0x00000000
127         },
128         // MEMethod: 6
129         {
130             0x120FF10F, 0x1E22E20D, 0x20E2FF10, 0x2EDD06FC, 0x11D33FF1, 0xEB1FF33D, 0x4EF1F1F1, 0xF1F21211,
131             0x0DFFFFE0, 0x11201F1F, 0x1105F1CF, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000
132         },
133         // MEMethod: 7 used for mpeg2 encoding B frames
134         {
135             0x1F11F10F, 0x2E22E2FE, 0x20E220DF, 0x2EDD06FC, 0x11D33FF1, 0xEB1FF33D, 0x02F1F1F1, 0x1F201111,
136             0xF1EFFF0C, 0xF01104F1, 0x10FF0A50, 0x000FF1C0, 0x00000000, 0x00000000, 0x00000000, 0x00000000
137         }
138     }
139 };
140 // clang-format on
141 //!
142 //! \class    CodechalKernelHme
143 //! \brief    Codechal kernel hme
144 //!
145 class CodechalKernelHme : public CodechalKernelBase
146 {
147 public:
148     //!
149     //! \enum     HmeLevel
150     //! \brief    Hme level
151     //!
152     enum HmeLevel
153     {
154         hmeLevelNone = 0,
155         hmeLevel4x   = 1,
156         hmeLevel16x  = 1 << 1,
157         hmeLevel32x  = 1 << 2
158     };
159 
160     //!
161     //! \enum     KernelIndex
162     //! \brief    Kernel index
163     //!
164     enum KernelIndex
165     {
166         hmeP = 0,
167         hmeB = 1
168     };
169 
170     //!
171     //! \enum     SurfaceId
172     //! \brief    SurfaceI id
173     //!
174     enum SurfaceId
175     {
176         me4xMvDataBuffer = 0,
177         me16xMvDataBuffer = 1,
178         me32xMvDataBuffer = 2,
179         me4xDistortionBuffer = 3
180     };
181 
182     //!
183     //! \enum     BindingTableOffset
184     //! \brief    Binding table offset
185     //!
186     enum BindingTableOffset
187     {
188         meOutputMvDataSurface = 0,
189         meInputMvDataSurface  = 1,
190         meDistortionSurface   = 2,
191         meBrcDistortion       = 3,
192         meCurrForFwdRef       = 5,
193         meFwdRefIdx0          = 6,
194         meFwdRefIdx1          = 8,
195         meFwdRefIdx2          = 10,
196         meFwdRefIdx3          = 12,
197         meFwdRefIdx4          = 14,
198         meFwdRefIdx5          = 16,
199         meFwdRefIdx6          = 18,
200         meFwdRefIdx7          = 20,
201         meCurrForBwdRef       = 22,
202         meBwdRefIdx0          = 23,
203         meBwdRefIdx1          = 25,
204         meSurfaceNum          = 27
205     };
206 
207     //!
208     //! \struct    CurbeParam
209     //! \brief     Curbe parameter
210     //!
211     struct CurbeParam
212     {
213         bool          brcEnable = false;
214         uint8_t       subPelMode = 3;
215         uint8_t       sumMVThreshold = 0;
216         CODEC_PICTURE currOriginalPic;
217         uint32_t      qpPrimeY;
218         uint32_t      targetUsage;
219         uint32_t      maxMvLen;
220         uint32_t      numRefIdxL1Minus1;
221         uint32_t      numRefIdxL0Minus1;
222         uint8_t*      meMethodTable = nullptr;
223         uint8_t*      bmeMethodTable = nullptr;
224 
225         uint32_t list0RefID0FieldParity : MOS_BITFIELD_BIT(0);
226         uint32_t list0RefID1FieldParity : MOS_BITFIELD_BIT(1);
227         uint32_t list0RefID2FieldParity : MOS_BITFIELD_BIT(2);
228         uint32_t list0RefID3FieldParity : MOS_BITFIELD_BIT(3);
229         uint32_t list0RefID4FieldParity : MOS_BITFIELD_BIT(4);
230         uint32_t list0RefID5FieldParity : MOS_BITFIELD_BIT(5);
231         uint32_t list0RefID6FieldParity : MOS_BITFIELD_BIT(6);
232         uint32_t list0RefID7FieldParity : MOS_BITFIELD_BIT(7);
233         uint32_t list1RefID0FieldParity : MOS_BITFIELD_BIT(8);
234         uint32_t list1RefID1FieldParity : MOS_BITFIELD_BIT(9);
235     };
236 
237     //!
238     //! \struct    SurfaceParams
239     //! \brief     Surface parameters
240     //!
241     struct SurfaceParams
242     {
243         bool                  mbaffEnabled;
244         bool                  vdencStreamInEnabled;
245         uint32_t              numRefIdxL0ActiveMinus1;
246         uint32_t              numRefIdxL1ActiveMinus1;
247         uint32_t              downScaledWidthInMb;
248         uint32_t              downScaledHeightInMb;
249         uint32_t              downScaledBottomFieldOffset;
250         uint32_t              vdencStreamInSurfaceSize;
251         uint32_t              verticalLineStride;
252         uint32_t              verticalLineStrideOffset;
253         uint32_t              meBrcDistortionBottomFieldOffset;
254         PCODEC_REF_LIST *     refList;
255         PCODEC_PIC_ID         picIdx;
256         PCODEC_PICTURE        currOriginalPic;
257         PCODEC_PICTURE        refL0List;
258         PCODEC_PICTURE        refL1List;
259         PMOS_SURFACE          meBrcDistortionBuffer;
260         PMOS_RESOURCE         meVdencStreamInBuffer;
261         CODECHAL_ENCODE_BUFFER meSumMvandDistortionBuffer;
262         CmSurface2D          *meBrcDistortionSurface;
263     };
264 
265     //!
266     //! \brief  Constructor
267     //!
268     //! \param  [in] encoder
269     //!         Codechal encoder state
270     //! \param  [in] me4xDistBufferSupported
271     //!         flag to support 4x Distortion buffer
272     //!
273     CodechalKernelHme(
274         CodechalEncoderState *encoder,
275         bool                 me4xDistBufferSupported);
276 
277     virtual ~CodechalKernelHme();
278 
279     //!
280     //! \brief  Execute HME kernel
281     //!
282     //! \param  [in] curbeParam
283     //!         Reference to CurbeParam
284     //! \param  [in] surfaceParam
285     //!         Reference to SurfaceParams
286     //! \param  [in] hmeLevel
287     //!         current Hme level to run the kernel
288     //!
289     //! \return MOS_STATUS
290     //!         MOS_STATUS_SUCCESS if success
291     //!
292     virtual MOS_STATUS Execute(CurbeParam &curbeParam, SurfaceParams &surfaceParam, HmeLevel hmeLevel);
293 
294     virtual MOS_STATUS AllocateResources() override;
295 
296     virtual MOS_STATUS ReleaseResources() override;
297 
298 
299 
GetBTCount()300     uint32_t GetBTCount() override { return BindingTableOffset::meSurfaceNum; }
301 
Is4xMeEnabled()302     inline bool Is4xMeEnabled()
303     {
304         return m_4xMeSupported && (m_pictureCodingType != I_TYPE);
305     }
306 
Is16xMeEnabled()307     inline bool Is16xMeEnabled()
308     {
309         return m_16xMeSupported && (m_pictureCodingType != I_TYPE);
310     }
311 
Is32xMeEnabled()312     inline bool Is32xMeEnabled()
313     {
314         return m_32xMeSupported && (m_pictureCodingType != I_TYPE);
315     }
316 
Get4xMeMvBottomFieldOffset()317     inline uint32_t Get4xMeMvBottomFieldOffset()
318     {
319         return m_4xMeMvBottomFieldOffset;
320     }
Set4xMeMvBottomFieldOffset(uint32_t offset)321     inline void Set4xMeMvBottomFieldOffset(uint32_t offset)
322     {
323         m_4xMeMvBottomFieldOffset = offset;
324     }
325 
GetDistortionBottomFieldOffset()326     inline uint32_t GetDistortionBottomFieldOffset()
327     {
328         return m_meDistortionBottomFieldOffset;
329     }
SetDistortionBottomFieldOffset(uint32_t offset)330     inline void SetDistortionBottomFieldOffset(uint32_t offset)
331     {
332         m_meDistortionBottomFieldOffset = offset;
333     }
334 
Get16xMeMvBottomFieldOffset()335     inline uint32_t Get16xMeMvBottomFieldOffset()
336     {
337         return m_16xMeMvBottomFieldOffset;
338     }
Set16xMeMvBottomFieldOffset(uint32_t offset)339     inline void Set16xMeMvBottomFieldOffset(uint32_t offset)
340     {
341         m_16xMeMvBottomFieldOffset = offset;
342     }
343 
Get32xMeMvBottomFieldOffset()344     inline uint32_t Get32xMeMvBottomFieldOffset()
345     {
346         return m_32xMeMvBottomFieldOffset;
347     }
Set32xMeMvBottomFieldOffset(uint32_t offset)348     inline void Set32xMeMvBottomFieldOffset(uint32_t offset)
349     {
350         m_32xMeMvBottomFieldOffset = offset;
351     }
setnoMEKernelForPFrame(bool flag)352     inline void setnoMEKernelForPFrame(bool flag)
353     {
354         m_noMEKernelForPFrame = flag;
355     }
356 
357 #if USE_CODECHAL_DEBUG_TOOL
358     MOS_STATUS DumpKernelOutput() override;
359 #endif
360 
361 protected:
362     MOS_STATUS AddPerfTag() override;
363     MHW_KERNEL_STATE * GetActiveKernelState() override;
364     CODECHAL_MEDIA_STATE_TYPE GetMediaStateType() override;
365     MOS_STATUS SendSurfaces(PMOS_COMMAND_BUFFER cmd, MHW_KERNEL_STATE *kernelState) override;
366     MOS_STATUS InitWalkerCodecParams(CODECHAL_WALKER_CODEC_PARAMS &walkerParam) override;
367 
368 protected:
369     bool          &m_4xMeSupported;
370     bool          &m_16xMeSupported;
371     bool          &m_32xMeSupported;
372     bool          &m_noMEKernelForPFrame;
373     bool          &m_useNonLegacyStreamIn;
374     bool          m_4xMeDistortionBufferSupported = false;  //!< 4x Me Distortion buffer supported
375     bool          m_4xMeInUse                     = false;  //!< 4x Me is in use
376     bool          m_16xMeInUse                    = false;  //!< 16x Me is in use
377     bool          m_32xMeInUse                    = false;  //!< 32x Me is in use
378     uint32_t      m_4xMeMvBottomFieldOffset       = 0;      //!< 4x ME mv bottom field offset
379     uint32_t      m_16xMeMvBottomFieldOffset      = 0;      //!< 16x ME mv bottom field offset
380     uint32_t      m_32xMeMvBottomFieldOffset      = 0;      //!< 32x ME mv bottom field offset
381     uint32_t      m_meDistortionBottomFieldOffset = 0;      //!< ME distortion bottom field offset
382     uint8_t *     m_bmeMethodTable = genericBMEMethod;      //!< pointer to BME method table
383     uint8_t *     m_meMethodTable  = genericMEMethod;       //!< pointer to ME method table
384     CurbeParam    m_curbeParam;                             //!< curbe paramters
385     SurfaceParams m_surfaceParam;                           //! surface parameters
386 
387     static const uint32_t scalingFactor4X  = 4;
388     static const uint32_t scalingFactor16X = 16;
389     static const uint32_t scalingFactor32X = 32;
390 };
391 
392 #endif /* __CODECHAL_KERNEL_HME_H__ */
393