1 /*
2 * Copyright (c) 2020-2021, 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     encode_vp9_segmentation.h
24 //! \brief    Defines the common interface for vp9 encode segmentation features
25 //!
26 
27 #ifndef __ENCODE_VP9_SEGMENTATION_H__
28 #define __ENCODE_VP9_SEGMENTATION_H__
29 
30 #include "encode_vp9_basic_feature.h"
31 
32 namespace encode
33 {
34 
35 //!
36 //! \enum     VP9_MBBRC_MODE
37 //! \brief    VP9 mbbrc mode
38 //!
39 enum VP9_MBBRC_MODE
40 {
41     //Target usage determines whether MBBRC is enabled or not.
42     //Currently for all the target usages it is enabled.
43     //once the performance is measured for performance TU mode, decision will be taken
44     //whether to enable or disable MBBRC.
45     MBBRC_ENABLED_TU_DEPENDENCY = 0,
46     MBBRC_ENABLED               = 1,
47     MBBRC_DISABLED              = 2
48 };
49 
50 
51 //!
52 //! \struct   Vp9VdencStreamInState
53 //! \brief    VP9 stream in buffer
54 //!
55 struct Vp9VdencStreamInState
56 {
57         union
58         {
59             //!< DWORD 0
60             struct
61             {
62                 uint32_t                 Roi32X32016X1603                                 : MOS_BITFIELD_RANGE( 0,  7)    ; //!< ROI 32x32_0 16x16_03
63                 uint32_t                 Maxtusize                                        : MOS_BITFIELD_RANGE( 8,  9)    ; //!< MaxTUSize
64                 uint32_t                 Maxcusize                                        : MOS_BITFIELD_RANGE(10, 11)    ; //!< MaxCUSize
65                 uint32_t                 Numimepredictors                                 : MOS_BITFIELD_RANGE(12, 15)    ; //!< NUMIMEPREDICTORS
66                 uint32_t                 PuType32X32016X1603                              : MOS_BITFIELD_RANGE(24, 31)    ; //!< PU Type 32x32_0 16x16_03
67             };
68             uint32_t                     Value;
69         } DW0;
70         union
71         {
72             //!< DWORD 1
73             struct
74             {
75                 uint32_t                 ForceMvX32X32016X160                             : MOS_BITFIELD_RANGE( 0, 15)    ; //!< force_mv.x 32x32_0 16x16_0
76                 uint32_t                 ForceMvY32X32016X160                             : MOS_BITFIELD_RANGE(16, 31)    ; //!< force_mv.y 32x32_0 16x16_0
77             };
78             uint32_t                     Value;
79         } DW1;
80         union
81         {
82             //!< DWORD 2
83             struct
84             {
85                 uint32_t                 ForceMvX32X32016X161                             : MOS_BITFIELD_RANGE( 0, 15)    ; //!< force_mv.x 32x32_0 16x16_1
86                 uint32_t                 ForceMvY32X32016X161                             : MOS_BITFIELD_RANGE(16, 31)    ; //!< force_mv.y 32x32_0 16x16_1
87             };
88             uint32_t                     Value;
89         } DW2;
90         union
91         {
92             //!< DWORD 3
93             struct
94             {
95                 uint32_t                 ForceMvX32X32016X162                             : MOS_BITFIELD_RANGE( 0, 15)    ; //!< force_mv.x 32x32_0 16x16_2
96                 uint32_t                 ForceMvY32X32016X162                             : MOS_BITFIELD_RANGE(16, 31)    ; //!< force_mv.y 32x32_0 16x16_2
97             };
98             uint32_t                     Value;
99         } DW3;
100         union
101         {
102             //!< DWORD 4
103             struct
104             {
105                 uint32_t                 ForceMvX32X32016X163                             : MOS_BITFIELD_RANGE( 0, 15)    ; //!< force_mv.x 32x32_0 16x16_3
106                 uint32_t                 ForceMvY32X32016X163                             : MOS_BITFIELD_RANGE(16, 31)    ; //!< force_mv.y 32x32_0 16x16_3
107             };
108             uint32_t                     Value;
109         } DW4;
110         union
111         {
112             //!< DWORD 5
113             struct
114             {
115                 uint32_t                 Reserved160                                                                      ; //!< Reserved
116             };
117             uint32_t                     Value;
118         } DW5;
119         union
120         {
121             //!< DWORD 6
122             struct
123             {
124                 uint32_t                 ForceMvRefidx32X32016X160                        : MOS_BITFIELD_RANGE( 0,  3)    ; //!< force_mv refidx 32x32_0 16x16_0
125                 uint32_t                 ForceMvRefidx32X32016X1613                       : MOS_BITFIELD_RANGE( 4, 15)    ; //!< force_mv refidx 32x32_0 16x16_1-3
126                 uint32_t                 Nummergecandidatecu8X8                           : MOS_BITFIELD_RANGE(16, 19)    ; //!< NumMergeCandidateCU8x8
127                 uint32_t                 Nummergecandidatecu16X16                         : MOS_BITFIELD_RANGE(20, 23)    ; //!< NumMergeCandidateCU16x16
128                 uint32_t                 Nummergecandidatecu32X32                         : MOS_BITFIELD_RANGE(24, 27)    ; //!< NumMergeCandidateCU32x32
129                 uint32_t                 Nummergecandidatecu64X64                         : MOS_BITFIELD_RANGE(28, 31)    ; //!< NumMergeCandidateCU64x64
130             };
131             uint32_t                     Value;
132         } DW6;
133         union
134         {
135             //!< DWORD 7
136             struct
137             {
138                 uint32_t                 Segid32X32016X1603Vp9Only                        : MOS_BITFIELD_RANGE( 0, 15)    ; //!< SegID 32x32_0 16x16_03 (VP9 only)
139                 uint32_t                 QpEn32X32016X1603                                : MOS_BITFIELD_RANGE(16, 19)    ; //!< QP_En 32x32_0 16x16_03
140                 uint32_t                 SegidEnable                                      : MOS_BITFIELD_RANGE(20, 20)    ; //!< SegID Enable
141                 uint32_t                 Reserved245                                      : MOS_BITFIELD_RANGE(21, 22)    ; //!< Reserved
142                 uint32_t                 ForceRefidEnable32X320                           : MOS_BITFIELD_RANGE(23, 23)    ; //!< Force Refid Enable (32x32_0)
143                 uint32_t                 ImePredictorRefidSelect0332X320                  : MOS_BITFIELD_RANGE(24, 31)    ; //!< IME predictor/refid Select0-3  32x32_0
144             };
145             uint32_t                     Value;
146         } DW7;
147         union
148         {
149             //!< DWORD 8
150             struct
151             {
152                 uint32_t                 ImePredictor0X32X320                             : MOS_BITFIELD_RANGE( 0, 15)    ; //!< ime_predictor0.x 32x32_0
153                 uint32_t                 ImePredictor0Y32X320                             : MOS_BITFIELD_RANGE(16, 31)    ; //!< ime_predictor0.y 32x32_0
154             };
155             uint32_t                     Value;
156         } DW8;
157         union
158         {
159             //!< DWORD 9
160             struct
161             {
162                 uint32_t                 ImePredictor0X32X321                             : MOS_BITFIELD_RANGE( 0, 15)    ; //!< ime_predictor0.x 32x32_1
163                 uint32_t                 ImePredictor0Y32X321                             : MOS_BITFIELD_RANGE(16, 31)    ; //!< ime_predictor0.y 32x32_1
164             };
165             uint32_t                     Value;
166         } DW9;
167         union
168         {
169             //!< DWORD 10
170             struct
171             {
172                 uint32_t                 ImePredictor0X32X322                             : MOS_BITFIELD_RANGE( 0, 15)    ; //!< ime_predictor0.x 32x32_2
173                 uint32_t                 ImePredictor0Y32X322                             : MOS_BITFIELD_RANGE(16, 31)    ; //!< ime_predictor0.y 32x32_2
174             };
175             uint32_t                     Value;
176         } DW10;
177         union
178         {
179             //!< DWORD 11
180             struct
181             {
182                 uint32_t                 ImePredictor0X32X323                             : MOS_BITFIELD_RANGE( 0, 15)    ; //!< ime_predictor0.x 32x32_3
183                 uint32_t                 ImePredictor0Y32X323                             : MOS_BITFIELD_RANGE(16, 31)    ; //!< ime_predictor0.y 32x32_3
184             };
185             uint32_t                     Value;
186         } DW11;
187         union
188         {
189             //!< DWORD 12
190             struct
191             {
192                 uint32_t                 ImePredictor0Refidx32X320                        : MOS_BITFIELD_RANGE( 0,  3)    ; //!< ime_predictor0 refidx 32x32_0
193                 uint32_t                 ImePredictor13Refidx32X3213                      : MOS_BITFIELD_RANGE( 4, 15)    ; //!< ime_predictor1-3 refidx 32x32_1-3
194                 uint32_t                 Reserved400                                      : MOS_BITFIELD_RANGE(16, 31)    ; //!< Reserved
195             };
196             uint32_t                     Value;
197         } DW12;
198         union
199         {
200             //!< DWORD 13
201             struct
202             {
203                 uint32_t                 Panicmodelcuthreshold                            : MOS_BITFIELD_RANGE( 0, 15)    ; //!< PanicModeLCUThreshold
204                 uint32_t                 Reserved432                                      : MOS_BITFIELD_RANGE(16, 31)    ; //!< Reserved
205             };
206             uint32_t                     Value;
207         } DW13;
208         union
209         {
210             //!< DWORD 14
211             struct
212             {
213                 uint32_t                 ForceQpValue16X160                               : MOS_BITFIELD_RANGE( 0,  7)    ; //!< Force QP Value 16x16_0
214                 uint32_t                 ForceQpValue16X161                               : MOS_BITFIELD_RANGE( 8, 15)    ; //!< Force QP Value 16x16_1
215                 uint32_t                 ForceQpValue16X162                               : MOS_BITFIELD_RANGE(16, 23)    ; //!< Force QP Value 16x16_2
216                 uint32_t                 ForceQpValue16X163                               : MOS_BITFIELD_RANGE(24, 31)    ; //!< Force QP Value 16x16_3
217             };
218             uint32_t                     Value;
219         } DW14;
220         union
221         {
222             //!< DWORD 15
223             struct
224             {
225                 uint32_t                 Reserved480                                                                      ; //!< Reserved
226             };
227             uint32_t                     Value;
228         } DW15;
229 
230         //! \name Local enumerations
231 
232         //! \brief NUMIMEPREDICTORS
233         //! \details
234         //!     <p>This parameter specifes the number of IME predictors to be processed
235         //!     in stage3 IME.</p>
236         //!     <p></p>
237         enum NUMIMEPREDICTORS
238         {
239             NUMIMEPREDICTORS_UNNAMED0                                        = 0, //!< No additional details
240             NUMIMEPREDICTORS_UNNAMED4                                        = 4, //!< No additional details
241             NUMIMEPREDICTORS_UNNAMED8                                        = 8, //!< No additional details
242             NUMIMEPREDICTORS_UNNAMED12                                       = 12, //!< No additional details
243         };
244 
245         static const size_t dwSize = 16;
246         static const size_t byteSize = 64;
247     };
248 
249 class Vp9Segmentation : public MediaFeature,
250     public mhw::vdbox::hcp::Itf::ParSetting,
251     public mhw::vdbox::vdenc::Itf::ParSetting
252 {
253 public:
254     //!
255     //! \brief  Vp9Segmentation feature constructor
256     //!
257     //! \param  [in] featureManager
258     //!         Pointer to MediaFeatureManager
259     //! \param  [in] allocator
260     //!         Pointer to EncodeAllocator
261     //! \param  [in] hwInterface
262     //!         Pointer to CodechalHwInterface
263     //! \param  [in] constSettings
264     //!         Pointer to const settings
265     //!
266     Vp9Segmentation(
267         MediaFeatureManager *featureManager,
268         EncodeAllocator *    allocator,
269         CodechalHwInterfaceNext *hwInterface,
270         void *               constSettings);
271 
272     //!
273     //! \brief  Vp9Segmentation feature destructor
274     //!
275     virtual ~Vp9Segmentation();
276 
277     //!
278     //! \brief  Init segmentation related parameter
279     //! \param  [in] settings
280     //!         Pointer to settings
281     //! \return MOS_STATUS
282     //!         MOS_STATUS_SUCCESS if success, else fail reason
283     //!
284     MOS_STATUS Init(void *settings) override;
285 
286     //!
287     //! \brief  Update segmentation related parameter
288     //! \param  [in] params
289     //!         Pointer to parameters
290     //! \return MOS_STATUS
291     //!         MOS_STATUS_SUCCESS if success, else fail reason
292     //!
293     MOS_STATUS Update(void *params) override;
294 
295     //!
296     //! \brief  Set Dmem buffer for brc update
297     //! \param  [in] params
298     //!         Pointer to parameters
299     //! \return MOS_STATUS
300     //!         MOS_STATUS_SUCCESS if success, else fail reason
301     //!
302     MOS_STATUS SetDmemForUpdate(void *params);
303 
304     //!
305     //! \brief  Set Dmem buffer for huc prob
306     //! \param  [in] params
307     //!         Pointer to parameters
308     //! \return MOS_STATUS
309     //!         MOS_STATUS_SUCCESS if success, else fail reason
310     //!
311     MOS_STATUS SetDmemForHucProb(void *params);
312 
313     //!
314     //! \brief    Check if segmentation feature is enabled
315     //! \param    [out] enabled
316     //!           Enabled flag
317     //! \return   MOS_STATUS
318     //!           MOS_STATUS_SUCCESS if success, else fail reason
319     //!
IsEnabled(bool & enabled)320     virtual MOS_STATUS IsEnabled(bool &enabled)
321     {
322         enabled = m_enabled;
323         return MOS_STATUS_SUCCESS;
324     }
325 
326     //!
327     //! \brief    Check if APP's segmentation map provided
328     //! \param    [out] provided
329     //!           Flag to indicate APP's segmentation map provided or not
330     //! \return   MOS_STATUS
331     //!           MOS_STATUS_SUCCESS if success, else fail reason
332     //!
IsSegmentMapProvided(bool & provided)333     virtual MOS_STATUS IsSegmentMapProvided(bool &provided)
334     {
335         provided = m_segmentMapProvided;
336         return MOS_STATUS_SUCCESS;
337     }
338 
339     //!
340     //! \brief  Set segment ID
341     //! \param  [in] params
342     //!         Segment ID
343     //! \return MOS_STATUS
344     //!         MOS_STATUS_SUCCESS if success, else fail reason
345     //!
346     MOS_STATUS SetSegmentId(uint8_t segmentId);
347 
348     static constexpr uint32_t m_segmentStateBlockSize = 32;
349 
350     //!
351     //! \brief MHW parameters declaration
352     //!
353     MHW_SETPAR_DECL_HDR(HCP_VP9_SEGMENT_STATE);
354 
355 
356     //!
357     //! \brief MHW parameters declaration VDENC_CMD2
358     //!
359     MHW_SETPAR_DECL_HDR(VDENC_CMD2);
360 
361 protected:
362     //!
363     //! \brief  Free resources
364     //! \return MOS_STATUS
365     //!         MOS_STATUS_SUCCESS if success, else fail reason
366     //!
367     virtual MOS_STATUS FreeResources();
368 
369     //!
370     //! \brief  Set sequence structures
371     //! \return MOS_STATUS
372     //!         MOS_STATUS_SUCCESS if success, else fail reason
373     //!
374     MOS_STATUS SetSequenceStructs();
375 
376     //!
377     //! \brief  Allocate mb brc segment map surface
378     //! \return MOS_STATUS
379     //!         MOS_STATUS_SUCCESS if success, else fail reason
380     //!
381     MOS_STATUS AllocateMbBrcSegMapSurface();
382 
383     //!
384     //! \brief  Setup segmentation stream in
385     //! \return MOS_STATUS
386     //!         MOS_STATUS_SUCCESS if success, else fail reason
387     //!
388     MOS_STATUS SetupSegmentationStreamIn();
389 
390     //!
391     //! \brief  initialize zig-zag to raster LUT per tile
392     //! \param  [in] tileWidth
393     //!         Tile width
394     //! \param  [in] tileHeight
395     //!         Tile height
396     //! \param  [in] currTileStartXInFrame
397     //!         Current tile start X in frame
398     //! \param  [in] currTileStartYInFrame
399     //!         Current tile start Y in frame
400     //! \param  [in/out] blocksRasterized
401     //!         Count of rasterized blocks for this frame
402     //! \return MOS_STATUS
403     //!         MOS_STATUS_SUCCESS if success, else fail reason
404     //!
405     MOS_STATUS InitZigZagToRasterLUTPerTile(
406         uint32_t  tileWidth,
407         uint32_t  tileHeight,
408         uint32_t  currTileStartXInFrame,
409         uint32_t  currTileStartYInFrame,
410         uint32_t &blocksRasterized);
411 
412     //!
413     //! \brief  Returns the offset of 32x32 block in the frame based on
414     //!         current x, y 32 block location in current tile
415     //! \param  [in] frameWidth
416     //!         Frame width
417     //! \param  [in] curr32XInTile
418     //!         Tile height
419     //! \param  [in] curr32YInTile
420     //!         Tile width
421     //! \param  [in] currTileStartX64aligned
422     //!         Current tile start X 64 aligned
423     //! \param  [in] currTileStartY64aligned
424     //!         Current tile start Y 64 aligned
425     //! \return uint32_t
426     //!         Segment block index in frame
427     //!
428     uint32_t GetSegmentBlockIndexInFrame(
429         uint32_t frameWidth,
430         uint32_t curr32XInTile,
431         uint32_t curr32YInTile,
432         uint32_t currTileStartX64aligned,
433         uint32_t currTileStartY64aligned);
434 
435     //!
436     //! \brief  Calculate buffer offset
437     //! \param  [in] idx
438     //!         Index
439     //! \param  [in] width
440     //!         Width
441     //! \param  [in] blockSize
442     //!         Block size
443     //! \param  [in] bufferPitch
444     //!         Buffer pitch
445     //!
446     //! \return uint32_t
447     //!         Return 0 if call success, else -1 if fail
448     //!
449     uint32_t CalculateBufferOffset(
450         uint32_t idx,
451         uint32_t width,
452         uint32_t blockSize,
453         uint32_t bufferPitch);
454 
455     PCODEC_VP9_ENCODE_SEGMENT_PARAMS m_vp9SegmentParams = nullptr;  //!< Pointer to segment parameters
456 
457     EncodeAllocator *    m_allocator    = nullptr;
458     Vp9BasicFeature *    m_basicFeature = nullptr;
459     CodechalHwInterfaceNext *m_hwInterface  = nullptr;
460 
461     bool m_mbBrcEnabled   = false;  //!< MBBRC enable flag
462     bool m_mbStatsEnabled = false;  //!< MB status enabled flag
463     // Segmentation resources
464     bool        m_segmentMapProvided  = false;  //!< Flag to indicate APP's segmentation map provided or not
465     bool        m_segmentMapAllocated = false;
466     MOS_SURFACE m_mbSegmentMapSurface = {0};
467 
468     uint32_t *m_mapBuffer          = nullptr; //!< Use for re-map recreate map buffer
469     uint32_t  m_segStreamInHeight  = 0;
470     uint32_t  m_segStreamInWidth   = 0;
471 
472     uint8_t m_segmentId = 0;
473 
474 MEDIA_CLASS_DEFINE_END(encode__Vp9Segmentation)
475 };
476 
477 }  // namespace encode
478 
479 #endif  // __ENCODE_VP9_SEGMENTATION_H__