1 /*
2 * Copyright (c) 2020-2023, 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_avc_vdenc_packet.h
24 //! \brief    Defines the interface to adapt to AVC VDENC pipeline
25 //!
26 
27 #ifndef __CODECHAL_AVC_VDENC_PACKET_H__
28 #define __CODECHAL_AVC_VDENC_PACKET_H__
29 
30 #include "media_cmd_packet.h"
31 #include "encode_avc_vdenc_pipeline.h"
32 #include "encode_avc_basic_feature.h"
33 #include "encode_status_report.h"
34 #include "mhw_vdbox_vdenc_itf.h"
35 #include "mhw_vdbox_mfx_itf.h"
36 #include "mhw_mi_itf.h"
37 
38 namespace encode
39 {
40 
41 class AvcVdencPkt : public CmdPacket,
42                     public MediaStatusReportObserver,
43                     public mhw::vdbox::vdenc::Itf::ParSetting,
44                     public mhw::vdbox::mfx::Itf::ParSetting,
45                     public mhw::mi::Itf::ParSetting
46 {
47 public:
48 
49     AvcVdencPkt(MediaPipeline *pipeline, MediaTask *task, CodechalHwInterfaceNext *hwInterface);
50 
51     virtual ~AvcVdencPkt();
52 
53     void fill_pad_with_value(PMOS_SURFACE psSurface, uint32_t real_height, uint32_t aligned_height) const;
54 
55     //!
56     //! \brief  Initialize the media packet, allocate required resources
57     //! \return MOS_STATUS
58     //!         MOS_STATUS_SUCCESS if success, else fail reason
59     //!
60     virtual MOS_STATUS Init() override;
61 
62     //!
63     //! \brief  Prepare interal parameters, should be invoked for each frame
64     //! \param  [in] params
65     //!         Pointer to the input parameters
66     //! \return MOS_STATUS
67     //!         MOS_STATUS_SUCCESS if success, else fail reason
68     //!
69     virtual MOS_STATUS Prepare() override;
70 
71     //!
72     //! \brief  Destroy the media packet and release the resources
73     //! \return MOS_STATUS
74     //!         MOS_STATUS_SUCCESS if success, else fail reason
75     //!
76     virtual MOS_STATUS Destroy() override;
77 
78     //!
79     //! \brief  Add the command sequence into the commandBuffer and
80     //!         and return to the caller task
81     //! \param  [in] commandBuffer
82     //!         Pointer to the command buffer which is allocated by caller
83     //! \return MOS_STATUS
84     //!         MOS_STATUS_SUCCESS if success, else fail reason
85     //!
86     virtual MOS_STATUS Submit(MOS_COMMAND_BUFFER *commandBuffer, uint8_t packetPhase = otherPacket) override;
87 
88     //!
89     //! \brief  One frame is completed
90     //! \param  [in] mfxStatus
91     //!         pointer to status buffer which for MFX
92     //! \param  [in] rcsStatus
93     //!         pointer to status buffer which for RCS
94     //! \param  [in, out] statusReport
95     //!         pointer of EncoderStatusReport
96     //! \return MOS_STATUS
97     //!         MOS_STATUS_SUCCESS if success, else fail reason
98     //!
99     virtual MOS_STATUS Completed(void *mfxStatus, void *rcsStatus, void *statusReport) override;
100 
101     //!
102     //! \brief  Calculate Command Size
103     //!
104     //! \param  [in, out] commandBufferSize
105     //!         requested size
106     //! \param  [in, out] requestedPatchListSize
107     //!         requested size
108     //! \return MOS_STATUS
109     //!         status
110     //!
111     virtual MOS_STATUS CalculateCommandSize(
112         uint32_t &commandBufferSize,
113         uint32_t &requestedPatchListSize) override;
114 
115     //!
116     //! \brief  Get Packet Name
117     //! \return std::string
118     //!
GetPacketName()119     virtual std::string GetPacketName() override
120     {
121         return "VDENC_PASS" + std::to_string((uint32_t)m_pipeline->GetCurrentPass());
122     }
123 
124 protected:
125     MOS_STATUS PatchPictureLevelCommands(const uint8_t &packetPhase, MOS_COMMAND_BUFFER  &cmdBuffer);
126     MOS_STATUS PatchSliceLevelCommands(MOS_COMMAND_BUFFER &cmdBuffer, uint8_t packetPhase);
127     MOS_STATUS InsertSeqStreamEnd(MOS_COMMAND_BUFFER &cmdBuffer);
128 
129     //!
130     //! \brief  Calculate Command Buffer Size
131     //!
132     //! \return uint32_t
133     //!         Command buffer size calculated
134     //!
135     virtual uint32_t CalculateCommandBufferSize();
136 
137     //!
138     //! \brief  Calculate Patch List Size
139     //!
140     //! \return uint32_t
141     //!         Patchlist size calculated
142     //!
143     virtual uint32_t CalculatePatchListSize();
144 
145     //!
146     //! \brief    Calculate Vdenc Commands Size
147     //!
148     //! \return   MOS_STATUS
149     //!           MOS_STATUS_SUCCESS if success
150     //!
151     virtual MOS_STATUS CalculateVdencCommandsSize();
152 
153     //!
154     //! \brief    Calculate Mfx Commands Size
155     //!
156     //! \return   MOS_STATUS
157     //!           MOS_STATUS_SUCCESS if success
158     //!
159     virtual MOS_STATUS CalculateMfxCommandsSize();
160 
161     MOS_STATUS GetMfxPrimitiveCommandsDataSize(
162         uint32_t *commandsSize,
163         uint32_t *patchListSize,
164         bool      isModeSpecific);
165 
166     MOS_STATUS GetMfxStateCommandsDataSize(
167         uint32_t *commandsSize,
168         uint32_t *patchListSize,
169         bool      isShortFormat);
170 
171     MmioRegistersMfx *SelectVdboxAndGetMmioRegister(
172         MHW_VDBOX_NODE_IND  index,
173         PMOS_COMMAND_BUFFER pCmdBuffer);
174 
175     virtual MOS_STATUS StartStatusReport(
176         uint32_t srType,
177         MOS_COMMAND_BUFFER *cmdBuffer) override;
178 
179     virtual MOS_STATUS EndStatusReport(
180         uint32_t srType,
181         MOS_COMMAND_BUFFER *cmdBuffer) override;
182 
183     //!
184     //! \brief  Ensure all commands have been executed
185     //! \param  [in] cmdBuffer
186     //!         Pointer to the command buffer which is allocated by caller
187     //! \return MOS_STATUS
188     //!         MOS_STATUS_SUCCESS if success, else fail reason
189     //!
190     virtual MOS_STATUS EnsureAllCommandsExecuted(MOS_COMMAND_BUFFER &cmdBuffer);
191 
192     //!
193     //! \brief    Add command to read Mfc status
194     //!
195     //! \param    [in, out] cmdBuffer
196     //!           Command buffer
197     //!
198     //! \return   MOS_STATUS
199     //!           MOS_STATUS_SUCCESS if success, else fail reason
200     //!
201     MOS_STATUS ReadMfcStatus(MOS_COMMAND_BUFFER &cmdBuffer);
202 
203     //!
204     //! \brief    Read Image status for status report
205     //! \param    vdboxIndex
206     //!           [in] the vdbox index
207     //! \param    params
208     //!           [in] the parameters for Image status read
209     //! \param    cmdBuffer
210     //!           [in, out] the command buffer
211     //! \return   MOS_STATUS
212     //!           MOS_STATUS_SUCCESS if success, else fail reason
213     //!
214     MOS_STATUS ReadImageStatus(
215         const EncodeStatusReadParams &params,
216         PMOS_COMMAND_BUFFER           cmdBuffer);
217 
218     virtual MOS_STATUS AllocateResources();
219 
220     //!
221     //! \brief    Add picture-level MFX commands to command buffer
222     //!
223     //! \param    [in, out] cmdBuffer
224     //!           Pointer to the command buffer
225     //!
226     //! \return   MOS_STATUS
227     //!           MOS_STATUS_SUCCESS if success, else fail reason
228     //!
229     MOS_STATUS AddPictureMfxCommands(MOS_COMMAND_BUFFER &cmdBuffer);
230 
231     //!
232     //! \brief    Add picture-level VDEnc commands to command buffer
233     //!
234     //! \param    [in, out] cmdBuffer
235     //!           Pointer to the command buffer
236     //!
237     //! \return   MOS_STATUS
238     //!           MOS_STATUS_SUCCESS if success, else fail reason
239     //!
240     virtual MOS_STATUS AddPictureVdencCommands(MOS_COMMAND_BUFFER &cmdBuffer);
241 
242     void UpdateParameters();
243 
244     // Inline functions
245     MOS_STATUS ValidateVdboxIdx(const MHW_VDBOX_NODE_IND &vdboxIndex);
246 
247     void SetPerfTag(uint16_t type, uint16_t mode, uint16_t picCodingType);
248 
249     MOS_STATUS SendPrologCmds(
250         MOS_COMMAND_BUFFER &cmdBuffer);
251 
252     //!
253     //! \brief    Allocate Batch Buffer For PakSlice.
254     //!
255     //! \param    [in] numSlices
256     //!           Number of Slice
257     //! \param    [in] numPakPasses
258     //!           Number of PAK pass.
259     //! \param    [in] currRecycledBufIdx
260     //!           Current Recycle Buffer Index.
261     //!
262     //! \return   MOS_STATUS
263     //!           MOS_STATUS_SUCCESS if success
264     //!
265     virtual MOS_STATUS AllocateBatchBufferForPakSlices(
266         uint32_t numSlices,
267         uint16_t numPakPasses,
268         uint8_t currRecycledBufIdx);
269 
270     //!
271     //! \brief    Release Batch Buffer For PakSlice.
272     //!
273     //! \param    [in] currRecycledBufIdx
274     //!           Current Recycle Buffer Index.
275     //!
276     //! \return   MOS_STATUS
277     //!           MOS_STATUS_SUCCESS if success
278     //!
279     virtual MOS_STATUS ReleaseBatchBufferForPakSlices(uint8_t currRecycledBufIdx);
280 
281     //!
282     //! \brief    Build slices with header insertion
283     //! \param    [in] cmdBuffer
284     //!           command buffer
285     //! \return   MOS_STATUS
286     //!           MOS_STATUS_SUCCESS if success, else fail reason
287     //!
288     virtual MOS_STATUS SendSlice(PMOS_COMMAND_BUFFER cmdBuffer);
289 
290     MOS_STATUS SetSliceStateCommonParams(MHW_VDBOX_AVC_SLICE_STATE &sliceState);
291 
292     //!
293     //! \brief    Use to pack slice header related params
294     //!
295     //! \return   MOS_STATUS
296     //!           MOS_STATUS_SUCCESS if success, else fail reason
297     //!
298     MOS_STATUS PackSliceHeader(uint16_t slcCount);
299 
300     MOS_STATUS SetSliceStateParams(
301         MHW_VDBOX_AVC_SLICE_STATE   &sliceState,
302         PCODEC_ENCODER_SLCDATA      slcData,
303         uint16_t                    slcCount);
304 
305     //!
306     //! \brief    Prepare HW MetaData buffer
307     //! \details  Prepare HW MetaData buffer.
308     //! \param    [in] cmdBuffer
309     //!               Pointer to primary cmd buffer
310     //! \return   MOS_STATUS
311     //!           MOS_STATUS_SUCCESS if success, else fail reason
312     //!
313     virtual MOS_STATUS PrepareHWMetaData(PMOS_COMMAND_BUFFER cmdBuffer);
314 
315     //!
316     //! \brief      Store number passes
317     //!
318     //! \param      [in, out] cmdBuffer
319     //!             Command buffer
320     //!
321     //! \return     MOS_STATUS
322     //!             MOS_STATUS_SUCCESS if success, else fail reason
323     //!
324     MOS_STATUS StoreNumPasses(MOS_COMMAND_BUFFER &cmdBuffer);
325 
326     //! \brief    Set Rowstore Cache offset
327     //!
328     //! \return   MOS_STATUS
329     //!           MOS_STATUS_SUCCESS if success, else fail reason
330     //!
331     MOS_STATUS SetRowstoreCachingOffsets();
332 
333     //!
334     //! \brief  Free resources
335     //! \return MOS_STATUS
336     //!         MOS_STATUS_SUCCESS if success, else fail reason
337     //!
338     MOS_STATUS FreeResources();
339 
340     //! \brief    Update and lock BatchBufferForPakSlices
341     //!
342     //! \return   MOS_STATUS
343     //!           MOS_STATUS_SUCCESS if success, else fail reason
344     //!
345     MOS_STATUS LockBatchBufferForPakSlices();
346 
347     //! \brief    Unlock BatchBufferForPakSlices
348     //!
349     //! \return   MOS_STATUS
350     //!           MOS_STATUS_SUCCESS if success, else fail reason
351     //!
352     MOS_STATUS UnlockBatchBufferForPakSlices();
353 
354     //!
355     //! \brief    Report Slice Size to MetaData buffer
356     //! \details  Report Slice Size to MetaData buffer.
357     //! \param    [in] cmdBuffer
358     //!               Pointer to primary cmd buffer
359     //!           [in] slcCount
360     //!               Current slice count
361     //! \return   MOS_STATUS
362     //!           MOS_STATUS_SUCCESS if success, else fail reason
363     //!
364     virtual MOS_STATUS ReportSliceSizeMetaData(
365         PMOS_COMMAND_BUFFER cmdBuffer,
366         uint32_t            slcCount);
367 
368     //! \brief    Get AVC VDenc frame level status extention
369     //!
370     //! \param    [in] cmdBuffer
371     //!           Point to MOS_COMMAND_BUFFER
372     //!           [in] StatusReportFeedbackNumber
373     //!           Status report number
374     //! \return   MOS_STATUS
375     //!           MOS_STATUS_SUCCESS if success, else fail reason
376     //!
GetAvcVdencFrameLevelStatusExt(uint32_t StatusReportFeedbackNumber,MOS_COMMAND_BUFFER * cmdBuffer)377     virtual MOS_STATUS GetAvcVdencFrameLevelStatusExt(uint32_t StatusReportFeedbackNumber, MOS_COMMAND_BUFFER *cmdBuffer)
378     {
379         return MOS_STATUS_SUCCESS;
380     };
381 
382     //! \brief    Report extended statistics
383     //!
384     //! \param    [in] encodeStatusMfx
385     //!           Reference to encoder status for vdbox
386     //! \param    [in, out] statusReportData
387     //!           Reference to encoder status report data
388     //!
389     //! \return   MOS_STATUS
390     //!           MOS_STATUS_SUCCESS if success, else fail reason
391     //!
ReportExtStatistics(EncodeStatusMfx & encodeStatusMfx,EncodeStatusReportData & statusReportData)392     virtual MOS_STATUS ReportExtStatistics(
393         EncodeStatusMfx        &encodeStatusMfx,
394         EncodeStatusReportData &statusReportData)
395     {
396         return MOS_STATUS_SUCCESS;
397     };
398 
399     MHW_SETPAR_DECL_HDR(VDENC_PIPE_BUF_ADDR_STATE);
400 
401     MHW_SETPAR_DECL_HDR(VD_PIPELINE_FLUSH);
402 
403     MOS_STATUS AddAllCmds_MFX_QM_STATE(PMOS_COMMAND_BUFFER cmdBuffer) const;
404 
405     MOS_STATUS AddAllCmds_MFX_FQM_STATE(PMOS_COMMAND_BUFFER cmdBuffer) const;
406 
407     MOS_STATUS AddAllCmds_MFX_SURFACE_STATE(PMOS_COMMAND_BUFFER cmdBuffer) const;
408 
409     MOS_STATUS AddAllCmds_MFX_PAK_INSERT_OBJECT(PMOS_COMMAND_BUFFER cmdBuffer) const;
410 
411     MOS_STATUS AddAllCmds_MFX_AVC_REF_IDX_STATE(PMOS_COMMAND_BUFFER cmdBuffer) const;
412 
413     MOS_STATUS AddAllCmds_MFX_AVC_WEIGHTOFFSET_STATE(PMOS_COMMAND_BUFFER cmdBuffer) const;
414 
415     MHW_SETPAR_DECL_HDR(MFX_SURFACE_STATE);
416 
417     MHW_SETPAR_DECL_HDR(MFX_PIPE_BUF_ADDR_STATE);
418 
419     MHW_SETPAR_DECL_HDR(MFX_BSP_BUF_BASE_ADDR_STATE);
420 
421     MHW_SETPAR_DECL_HDR(MFX_AVC_IMG_STATE);
422 
423     MHW_SETPAR_DECL_HDR(MI_CONDITIONAL_BATCH_BUFFER_END);
424 
425     MHW_SETPAR_DECL_HDR(MI_STORE_REGISTER_MEM);
426 
427     MHW_SETPAR_DECL_HDR(MI_STORE_DATA_IMM);
428 
429 #if USE_CODECHAL_DEBUG_TOOL
430     //! \brief    Dump the output resources in status report callback function
431     //!
432     //! \param    [in] encodeStatusMfx
433     //!           Pointer to encoder status for vdbox
434     //! \param    [in] statusReportData
435     //!           Pointer to encoder status report data
436     //!
437     //! \return   MOS_STATUS
438     //!           MOS_STATUS_SUCCESS if success, else fail reason
439     //!
440     MOS_STATUS DumpResources(
441         EncodeStatusMfx *       encodeStatusMfx,
442         EncodeStatusReportData *statusReportData);
443 
PopulatePakParam(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_BATCH_BUFFER secondLevelBatchBuffer)444     virtual MOS_STATUS PopulatePakParam(
445         PMOS_COMMAND_BUFFER cmdBuffer,
446         PMHW_BATCH_BUFFER   secondLevelBatchBuffer) { return MOS_STATUS_SUCCESS; }
447 
PopulateEncParam(uint8_t meMethod,void * cmd)448     virtual MOS_STATUS PopulateEncParam(uint8_t meMethod, void *cmd) { return MOS_STATUS_SUCCESS; }
449 
450     virtual MOS_STATUS DumpEncodeImgStats(
451         PMOS_COMMAND_BUFFER cmdbuffer);
452 #endif
453 
454     AvcVdencPipeline         *m_pipeline        = nullptr;
455 
456     // Interfaces
457     EncodeAllocator          *m_allocator       = nullptr;
458     CodechalHwInterfaceNext  *m_hwInterface     = nullptr;
459     AvcBasicFeature          *m_basicFeature    = nullptr;
460     EncodeMemComp            *m_mmcState        = nullptr;
461     EncodeCp                 *m_encodecp        = nullptr;
462 
463     std::shared_ptr<mhw::vdbox::vdenc::Itf> m_vdencItf = nullptr;
464     std::shared_ptr<mhw::vdbox::mfx::Itf>   m_mfxItf   = nullptr;
465 
466     std::shared_ptr<MediaFeatureManager::ManagerLite> m_featureManager = nullptr;
467 
468     MediaFeatureManager *m_legacyFeatureManager = nullptr;
469 
470     mutable uint8_t m_curMfxSurfStateId              = 0;
471     PMOS_RESOURCE   m_pResource                      = nullptr;
472     uint32_t        m_dwOffset                       = 0;
473     uint32_t        m_dwValue                        = 0;
474 
475     // Parameters passed from application
476     CODEC_AVC_ENCODE_PIC_PARAMS *      m_picParam    = nullptr;  //!< Pointer to picture parameter
477     CODEC_AVC_ENCODE_SEQUENCE_PARAMS * m_seqParam    = nullptr;  //!< Pointer to sequence parameter
478     CODEC_AVC_ENCODE_SLICE_PARAMS *    m_sliceParams = nullptr;  //!< Pointer to slice parameter
479 
480     MHW_VDBOX_NODE_IND     m_vdboxIndex = MHW_VDBOX_NODE_1;     //!< Index of VDBOX
481 
482     // CMD buffer sizes
483     uint32_t               m_pictureStatesSize = 0;             //!< Picture states size
484     uint32_t               m_sliceStatesSize = 0;               //!< Slice states size
485 
486     // Patch List
487     bool                   m_usePatchList = 0;                  //!< Use Ptach List or not
488     uint32_t               m_picturePatchListSize = 0;          //!< Picture patch list size
489     uint32_t               m_slicePatchListSize = 0;            //!< Slice patch list size
490 
491     // Batch Buffers
492     MHW_BATCH_BUFFER       m_batchBufferForVdencImgStat[CODECHAL_ENCODE_RECYCLED_BUFFER_NUM] = {}; //!< VDEnc image state batch buffers
493 
494     // PAK Scratch Buffers
495     MHW_BATCH_BUFFER       m_batchBufferForPakSlices[CODECHAL_ENCODE_RECYCLED_BUFFER_NUM] = {};  //!< PAK Slice batch buffers
496     bool                   m_useBatchBufferForPakSlices = false;                   //!< use PAK Slice batch buffers
497     uint32_t               m_pakSliceSize = 0;                                     //!< PAK Slice Size
498     uint32_t               m_pakSlicePatchListSize = 0;                            //!< PAK Slice patch list size
499 
500     PMOS_RESOURCE          m_resDeblockingFilterRowStoreScratchBuffer = nullptr;   //!< Handle of De-block row store surface
501     PMOS_RESOURCE          m_intraRowStoreScratchBuffer = nullptr;                 //!< Handle of intra row store surface
502     PMOS_RESOURCE          m_vdencIntraRowStoreScratch = nullptr;                  //!< Handle of intra row store surface
503     PMOS_RESOURCE          m_resMPCRowStoreScratchBuffer = nullptr;                //!< Handle of mpc row store surface
504 
505     bool                   m_vdencBrcImgStatAllocated = false;  //!< Vdenc bitrate control image state allocated flag
506 
507     bool                   m_lastSlice = false;
508     bool                   m_lastPic   = false;
509 
510 MEDIA_CLASS_DEFINE_END(encode__AvcVdencPkt)
511 };
512 
513 }  // namespace encode
514 
515 #endif  // !__CODECHAL_AVC_VDENC_PACKET_H__
516