1 /*
2 * Copyright (c) 2017-2018, 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_huc_cmd_initializer.h
24 //! \brief    Defines base class for HUC cmd initializer encoder.
25 //!
26 
27 #ifndef __CODECHAL_CMD_INITIALIZER_H__
28 #define __CODECHAL_CMD_INITIALIZER_H__
29 
30 #if defined (_HEVC_ENCODE_VME_SUPPORTED) || defined (_HEVC_ENCODE_VDENC_SUPPORTED)
31 #include "codechal_encode_hevc_base.h"
32 #endif
33 #include "codechal_encoder_base.h"
34 
35 #ifdef _VP9_ENCODE_VDENC_SUPPORTED
36 class CodechalVdencVp9State;
37 #endif
38 
39 // Command initializer command
40 typedef enum _CODECHAL_CMD_INITIALIZER_CMDTYPE
41 {
42     CODECHAL_CMD1 = 1,
43     CODECHAL_CMD2 = 2,
44     CODECHAL_CMD3 = 3,
45     CODECHAL_CMD5 = 5,
46 } CODECHAL_CMD_INITIALIZER_CMDTYPE;
47 
48 //!
49 //! \struct HucComDmem
50 //! \brief  The struct of Huc Com Dmem
51 //!
52 struct HucComDmem
53 {
54     uint32_t    OutputSize;               //!< Total size in byte of the Output SLB
55     uint32_t    TotalOutputCommands;      //!< Total Commands in the output SLB
56     uint8_t     TargetUsage;              //!< TU number
57     uint8_t     Codec;                    //!< 0-HEVC VDEnc; 1-VP9 VDEnc; 2-AVC VDEnc
58     uint8_t     FrameType;                //!< 0-I Frame; 1-P Frame; 2-B Frame
59     uint8_t     Reserved[37];
60     struct
61     {
62         uint16_t    StartInBytes;        //!< Command starts offset in bytes in Output SLB
63         uint8_t     ID;                  //!< Command ID
64         uint8_t     Type;                //!< Command Type
65         uint32_t    BBEnd;
66     } OutputCOM[50];
67 };
68 
69 //!
70 //! \struct HucComData
71 //! \brief  The struct of Huc commands data
72 //!
73 struct HucComData
74 {
75     uint32_t        TotalCommands;       //!< Total Commands in the Data buffer
76     struct
77     {
78         uint16_t    ID;              //!< Command ID, defined and order must be same as that in DMEM
79         uint16_t    SizeOfData;      //!< data size in uint32_t
80         uint32_t    data[40];
81     } InputCOM[50];
82 };
83 
84 //!
85 //! \struct HucInputCmd1
86 //! \brief  The struct of Huc input command 1
87 //!
88 struct HucInputCmd1
89 {
90     // Shared
91     uint32_t FrameWidthInMinCbMinus1;
92 
93     uint32_t FrameHeightInMinCbMinus1;
94 
95     uint32_t log2_min_coding_block_size_minus3;
96 
97     uint8_t  VdencStreamInEnabled;
98     uint8_t  PakOnlyMultipassEnable;
99     uint16_t num_ref_idx_l0_active_minus1;
100 
101     uint16_t SADQPLambda;
102     uint16_t RDQPLambda;
103 
104     // HEVC
105     uint16_t num_ref_idx_l1_active_minus1;
106     uint8_t  RSVD0;
107     uint8_t  ROIStreamInEnabled;
108 
109     int8_t   ROIDeltaQp[8]; // [-3..3] or [-51..51]
110 
111     uint8_t  FwdPocNumForRefId0inL0;
112     uint8_t  FwdPocNumForRefId0inL1;
113     uint8_t  FwdPocNumForRefId1inL0;
114     uint8_t  FwdPocNumForRefId1inL1;
115 
116     uint8_t  FwdPocNumForRefId2inL0;
117     uint8_t  FwdPocNumForRefId2inL1;
118     uint8_t  FwdPocNumForRefId3inL0;
119     uint8_t  FwdPocNumForRefId3inL1;
120 
121     uint8_t  EnableRollingIntraRefresh;
122     int8_t   QpDeltaForInsertedIntra;
123     uint16_t IntraInsertionSize;
124 
125     uint32_t  IntraInsertionReferenceLocation[3];
126 
127     uint16_t IntraInsertionLocation;
128     int8_t   QpY;
129     uint8_t  RoundingEnabled;
130 
131     uint8_t  UseDefaultQpDeltas;
132     uint8_t  PanicEnabled;
133     uint8_t  TemporalMvpEnableFlag;
134     uint8_t  RSVD[1];
135 
136     // VP9
137     uint16_t SrcFrameWidthMinus1;
138     uint16_t SrcFrameHeightMinus1;
139 
140     uint8_t  SegmentationEnabled;
141     uint8_t  PrevFrameSegEnabled;
142     uint8_t  SegMapStreamInEnabled;
143     uint8_t  LumaACQIndex;
144 
145     int8_t   LumaDCQIndexDelta;
146     uint8_t  RESERVED[3];
147 
148     int16_t  SegmentQIndexDelta[8];
149 };
150 
151 //!
152 //! \struct HucInputCmd2
153 //! \brief  The struct of Huc input command 2
154 //!
155 struct HucInputCmd2
156 {
157     uint32_t SADQPLambda;
158     uint8_t RoiEnabled;
159     uint8_t RSVD[3];
160 };
161 
162 #ifdef _VP9_ENCODE_VDENC_SUPPORTED
163 //!
164 //! \struct Vp9CmdInitializerParams
165 //! \brief  VP9 Params struct for huc initializer
166 //!
167 struct Vp9CmdInitializerParams
168 {
169     uint8_t                             vdencMvCosts[12] = { 0 };
170     uint8_t                             vdencRdMvCosts[12] = { 0 };
171     uint8_t                             vdencHmeMvCosts[8] = { 0 };
172     uint8_t                             vdencModeCosts[CODEC_VDENC_NUM_MODE_COST] = { 0 };
173 
174     uint16_t                            pictureCodingType   = 0;
175 
176     PCODEC_VP9_ENCODE_SEQUENCE_PARAMS   seqParams           = nullptr;
177     PCODEC_VP9_ENCODE_PIC_PARAMS        picParams           = nullptr;
178     bool                                segmentationEnabled = false;
179     bool                                segmentMapProvided  = false;
180     PCODEC_VP9_ENCODE_SEGMENT_PARAMS    segmentParams       = nullptr;
181     bool                                prevFrameSegEnabled = false;
182     uint8_t                             numRefFrames        = 0;
183     bool                                me16Enabled         = false;
184     uint8_t                             dysRefFrameFlags    = 0;
185     bool                                dysVdencMultiPassEnabled    = false;
186     int                                 currentPass                 = 0;
187     bool                                singleTaskPhaseSupported    = false;
188     bool                                lastTaskInPhase             = false;
189     bool                                firstTaskInPhase            = false;
190     uint32_t                            mode                        = 0;
191     bool                                videoContextUsesNullHw      = false;
192     CodechalDebugInterface*             debugInterface              = nullptr;
193     bool                                dynamicScalingEnabled       = false;
194     bool                                bPrevFrameKey               = false;
195     // Common
196     uint16_t                            sadQpLambda                     = 0;
197     uint16_t                            rdQpLambda                      = 0;
198     bool                                vdencPakOnlyMultipassEnabled    = false;
199 
200 };
201 #endif
202 
203 //!
204 //! \class  CodechalCmdInitializer
205 //! \brief  Command Initializer class
206 //!
207 class CodechalCmdInitializer
208 {
209 public:
210     static constexpr uint32_t m_hucCmdInitializerKernelDescriptor = 14; //!< VDBox Huc cmd initializer kernel descriptoer
211 
212     bool                                        m_pakOnlyPass = false;
213     bool                                        m_acqpEnabled = false;
214     bool                                        m_brcEnabled = false;
215     bool                                        m_streamInEnabled = false;
216     bool                                        m_roundingEnabled = false;
217     bool                                        m_panicEnabled = false;
218     bool                                        m_roiStreamInEnabled = false;
219     bool                                        m_brcAdaptiveRegionBoostEnabled = false;
220     int32_t                                     m_currentPass = 0;
221     int32_t                                     m_cmdCount = 0 ;
222 
223     CodechalEncoderState                        *m_encoder = nullptr;                //!< Pointer to ENCODER base class
224     MOS_INTERFACE                               *m_osInterface = nullptr;            //!< OS interface
225     MhwMiInterface                              *m_miInterface = nullptr;            //!< Common Mi Interface
226     MhwVdboxVdencInterface                      *m_vdencInterface = nullptr;
227     void*                                       m_picParams = nullptr;               //!< Pointer to picture parameter
228     void*                                       m_seqParams = nullptr;               //!< Pointer to sequence parameter
229     void*                                       m_sliceParams = nullptr;             //!< Pointer to slice parameter
230 
231 #ifdef _VP9_ENCODE_VDENC_SUPPORTED
232     //VP9 related changes
233     Vp9CmdInitializerParams                     m_vp9Params;
234 #endif
235     CodechalHwInterface*                        m_hwInterface = nullptr;
236     MOS_RESOURCE                                m_cmdInitializerDmemBuffer[CODECHAL_ENCODE_RECYCLED_BUFFER_NUM][3];
237     MOS_RESOURCE                                m_cmdInitializerDataBuffer[CODECHAL_ENCODE_RECYCLED_BUFFER_NUM][3];
238     MOS_RESOURCE                                m_cmdInitializerDysScalingDmemBuffer = {0};
239     MOS_RESOURCE                                m_cmdInitializerDysScalingDataBuffer = {0};
240 
241     static constexpr uint32_t CODECHAL_CMD1_SIZE = 120;
242     static constexpr uint32_t CODECHAL_CMD2_SIZE = 148;
243 
244     bool m_hevcVisualQualityImprovementEnableFlag = false;  //!< VQI enable flag
245 
246 public:
247     //!
248     //! \brief    Constructor
249     //!
250 
251     CodechalCmdInitializer(CodechalEncoderState *encoder);
252 
253     //!
254     //! \brief   Default Constructor
255     //!
CodechalCmdInitializer()256     CodechalCmdInitializer() {};
257     //!
258 
259     //!
260     //! \brief    Destructor
261     //!
~CodechalCmdInitializer()262     virtual ~CodechalCmdInitializer() {};
263 
264     //!
265     //! \brief    Free Resources
266     //!
267     virtual void CmdInitializerFreeResources();
268 
269     //!
270     //! \brief    Allocate resources for VP9
271     //!
272     //! \return   MOS_STATUS
273     //!           MOS_STATUS_SUCCESS if success, else fail reason
274     //!
275     virtual MOS_STATUS CmdInitializerAllocateResources(CodechalHwInterface*    m_hwInterface);
276 
277 #if defined (_HEVC_ENCODE_VME_SUPPORTED) || defined (_HEVC_ENCODE_VDENC_SUPPORTED)
278     //!
279     //! \brief    Set all the data of the InputCom of command initializer HuC FW
280     //!
281     //! \return   MOS_STATUS
282     //!           MOS_STATUS_SUCCESS if success, else fail reason
283     //!
284     MOS_STATUS CmdInitializerSetConstData(
285         PMOS_INTERFACE                              osInterface,
286         MhwMiInterface                              *miInterface,
287         MhwVdboxVdencInterface                      *vdencInterface,
288         void*                                       seqParams,
289         void*                                       picParams,
290         void*                                       sliceParams,
291         bool                                        pakOnlyPass,
292         bool                                        acqpEnabled,
293         bool                                        brcEnabled,
294         bool                                        streaminEnabled,
295         bool                                        roiStreamInEnabled,
296         bool                                        brcAdaptiveRegionBoostEnable,
297         bool                                        roundingEnabled,
298         bool                                        panicEnabled,
299         int32_t                                     currentPass
300         );
301 
302     //!
303     //! \brief    Set DMEM of command initializer HuC FW
304     //!
305     //! \param    [in] brcEnabled
306     //!           Indicate if brc is enabled
307     //!
308     //! \return   MOS_STATUS
309     //!           MOS_STATUS_SUCCESS if success, else fail reason
310     //!
311     virtual MOS_STATUS CmdInitializerSetDmem(bool brcEnabled);
312 
313     //!
314     //! \brief    Executes command initializer HuC FW
315     //!
316     //! \param    [in] brcEnabled
317     //!           Indicate if brc is enabled
318     //! \param    [in] secondlevelBB
319     //!           Second level batch buffer
320     //! \param    [in] cmdBuffer
321     //!           cmdBuffer provided by outside
322     //!
323     //! \return   MOS_STATUS
324     //!           MOS_STATUS_SUCCESS if success, else fail reason
325     //!
326     MOS_STATUS CmdInitializerExecute(
327             bool brcEnabled,
328             PMOS_RESOURCE secondlevelBB,
329             MOS_COMMAND_BUFFER* cmdBuffer = nullptr);
330 #endif
331     //!
332     //! \brief    Set Add Commands to BatchBuffer
333     //!
334     //! \param    [in] commandtype
335     //!           Command type, type 1 or type 2 command
336     //! \param    [in] cmdBuffer
337     //!           Command buffer
338     //! \param    [in] addToBatchBufferHuCBRC
339     //!           Flag to mention if the scenario is BRC or CQP
340     //! \param    [in] isLowDelayB
341     //!           Flag to indicate if it is LDB or not
342     //!
343     //! \return   MOS_STATUS
344     //!           MOS_STATUS_SUCCESS if success, else fail reason
345     //!
346     virtual MOS_STATUS SetAddCommands(uint32_t commandtype, PMOS_COMMAND_BUFFER cmdBuffer, bool addToBatchBufferHuCBRC, uint32_t roundInterValue, uint32_t roundIntraValue, bool isLowDelayB = true, int8_t * pRefIdxMapping = nullptr, int8_t recNotFilteredID = 0)
347     {
348         MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
349         return eStatus;
350     }
351 #ifdef _VP9_ENCODE_VDENC_SUPPORTED
352     //!
353     //! \brief    Set all const VP9 data of the InputCom of command initializer HuC FW
354     //!
355     //! \param    [in] state
356     //!           Pointer to CodechalVdencVp9State
357     //!
358     //! \return   MOS_STATUS
359     //!           MOS_STATUS_SUCCESS if success, else fail reason
360     //!
361     MOS_STATUS CommandInitializerSetVp9Params(CodechalVdencVp9State *state);
362 
363     //!
364     //! \brief    Set DMEM of command initializer HuC FW for VP9
365     //! \return   MOS_STATUS
366     //!           MOS_STATUS_SUCCESS if success, else fail reason
367     //!
368     virtual MOS_STATUS CmdInitializerVp9SetDmem();
369 
370     //!
371     //! \brief    Executes VP9 command initializer HuC FW
372     //!
373     //! \param    [in] cmdBuffer
374     //!           Command buffer
375     //! \param    [in] picStateBuffer
376     //!           Picture state buffer
377     //!
378     //! \return   MOS_STATUS
379     //!           MOS_STATUS_SUCCESS if success, else fail reason
380     //!
381     virtual MOS_STATUS CmdInitializerVp9Execute(PMOS_COMMAND_BUFFER cmdBuffer, PMOS_RESOURCE picStateBuffer);
382 
383     //!
384     //! \brief    Set Add Commands to BatchBuffer for VP9
385     //!
386     //! \param    [in] commandtype
387     //!           Command type, type 1 or type 2 command
388     //!           [in] cmdBuffer
389     //!           Command buffer
390     //!
391     //! \return   MOS_STATUS
392     //!           MOS_STATUS_SUCCESS if success, else fail reason
393     //!
AddCommandsVp9(uint32_t commandtype,PMOS_COMMAND_BUFFER cmdBuffer)394     virtual MOS_STATUS AddCommandsVp9(uint32_t commandtype, PMOS_COMMAND_BUFFER cmdBuffer)
395     {
396         return MOS_STATUS_SUCCESS;
397     }
398 #endif
399 #if USE_CODECHAL_DEBUG_TOOL
400     //!
401     //! \brief    Dump HuC Cmd Initializer
402     //!
403     //! \param    [in] secondlevelBB
404     //!           Kernel output commands is stored in secondlevelBB
405     //!
406     //! \return   MOS_STATUS
407     //!           MOS_STATUS_SUCCESS if success, else fail reason
408     //!
409     MOS_STATUS DumpHucCmdInit(PMOS_RESOURCE secondlevelBB);
410 #endif
411 
412 protected:
413 #if defined (_HEVC_ENCODE_VME_SUPPORTED) || defined (_HEVC_ENCODE_VDENC_SUPPORTED)
414     virtual MOS_STATUS ConstructHevcHucCmd1ConstData(
415         PCODEC_HEVC_ENCODE_SEQUENCE_PARAMS seqParams,
416         PCODEC_HEVC_ENCODE_PICTURE_PARAMS  picParams,
417         PCODEC_HEVC_ENCODE_SLICE_PARAMS    sliceParams,
418         struct HucComData *                hucConstData);
419 
420     virtual MOS_STATUS ConstructHevcHucCmd2ConstData(
421         PCODEC_HEVC_ENCODE_SEQUENCE_PARAMS seqParams,
422         PCODEC_HEVC_ENCODE_PICTURE_PARAMS  picParams,
423         PCODEC_HEVC_ENCODE_SLICE_PARAMS    sliceParams,
424         struct HucComData *                hucConstData);
425 
426     virtual uint16_t GetCmd1StartOffset(bool brcEnabled);
427     virtual uint16_t GetCmd2StartOffset(bool brcEnabled);
428 #endif
429 };
430 using PCODECHAL_CMD_INITIALIZER = class CodechalCmdInitializer*;
431 
432 #endif  //__CODECHAL_CMD_INITIALIZER_H__
433