1 /*
2 * Copyright (c) 2018-2024, 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_pipeline.h
24 //! \brief    Defines the common interface for decode pipeline
25 //! \details  The decode pipeline interface is further sub-divided by codec standard,
26 //!           this file is for the base interface which is shared by all codecs.
27 //!
28 #ifndef __DECODE_PIPELINE_H__
29 #define __DECODE_PIPELINE_H__
30 
31 #include "media_pipeline.h"
32 
33 #include "codec_hw_next.h"
34 #include "codechal_debug.h"
35 #include "codec_def_decode.h"
36 #include "decode_allocator.h"
37 #include "decode_sub_pipeline_manager.h"
38 #include "decode_sub_packet_manager.h"
39 #include "decode_input_bitstream.h"
40 #include "decodecp_interface.h"
41 #include "decode_cp_bitstream.h"
42 #include "decode_mem_compression.h"
43 #include "decode_downsampling_feature.h"
44 #include "codechal_oca_debug.h"
45 
46 namespace decode {
47 
48 enum DecodePipeMode
49 {
50     decodePipeModeBegin = 0,
51     decodePipeModeProcess,
52     decodePipeModeEnd
53 };
54 
55 struct DecodePipelineParams
56 {
57     CodechalDecodeParams *m_params = nullptr;
58     DecodePipeMode m_pipeMode = decodePipeModeBegin;
59 };
60 
61 class DecodeSubPacket;
62 class DecodeSubPacketManager;
63 
64 class DecodePipeline : public MediaPipeline
65 {
66 public:
67     //!
68     //! \brief  DecodePipeline constructor
69     //! \param  [in] hwInterface
70     //!         Pointer to CodechalHwInterface
71     //! \param  [in] debugInterface
72     //!         Pointer to CodechalDebugInterface
73     //!
74     DecodePipeline(
75         CodechalHwInterfaceNext *hwInterface,
76         CodechalDebugInterface *debugInterface);
77 
~DecodePipeline()78     virtual ~DecodePipeline()
79     {
80         MOS_Delete(m_pCodechalOcaDumper);
81     };
82 
83     //!
84     //! \brief  Prepare interal parameters, should be invoked for each frame
85     //! \param  [in] params
86     //!         Pointer to the input parameters
87     //! \return MOS_STATUS
88     //!         MOS_STATUS_SUCCESS if success, else fail reason
89     //!
90     virtual MOS_STATUS Prepare(void *params) override;
91 
92     //!
93     //! \brief  Indicates whether input bitstream is complete for current frame
94     //! \return bool
95     //!         true for compelte, false for incompelte
96     //!
97     bool IsCompleteBitstream();
98 
99     //!
100     //! \brief    Help function to get sub packet
101     //!
102     //! \return   Sub packet if success, else nullptr
103     //!
104     DecodeSubPacket* GetSubPacket(uint32_t subPacketId);
105 
106     //!
107     //! \brief  Get if SingleTaskPhaseSupported
108     //! \return bool
109     //!         value of SingleTaskPhaseSupported
110     //!
IsSingleTaskPhaseSupported()111     bool IsSingleTaskPhaseSupported() { return m_singleTaskPhaseSupported; };
112 
113     //!
114     //! \brief  Get the resource allocator for decode
115     //! \return DecodeAllocator *
116     //!         pointer of decode allocator
117     //!
GetDecodeAllocator()118     DecodeAllocator *GetDecodeAllocator() const { return m_allocator; }
119 
120     //!
121     //! \brief  Get decode cp interface
122     //! \return DecodeCpInterface *
123     //!         pointer of DecodeCpInterface
124     //!
GetDecodeCp()125     DecodeCpInterface *GetDecodeCp() const { return m_decodecp; }
126 
127     //!
128     //! \brief  Get the debug interface
129     //! \return CodechalDebugInterface *
130     //!         pointer of m_debugInterface
131     //!
GetDebugInterface()132     CodechalDebugInterface *GetDebugInterface() const { return m_debugInterface; }
133 
134     //!
135     //! \brief  Get the HW interface
136     //! \return CodechalHwInterface *
137     //!         pointer of m_hwInterface
138     //!
GetHwInterface()139     CodechalHwInterfaceNext *GetHwInterface() const { return m_hwInterface; }
140 
141     //!
142     //! \brief    Help function to get pipe number
143     //!
144     //! \return   Pipe number
145     //!
GetPipeNum()146     virtual uint8_t GetPipeNum() { return m_scalability->GetPipeNumber(); }
147 
148     //!
149     //! \brief    Help function to get current pipe
150     //!
151     //! \return   Pass index
152     //!
GetCurrentPipe()153     virtual uint8_t GetCurrentPipe() { return m_scalability->GetCurrentPipe(); }
154 
155     //!
156     //! \brief    Help function to check if current pipe is first pipe
157     //!
158     //! \return   True if current pipe is first pipe, otherwise return false
159     //!
IsFirstPipe()160     virtual bool IsFirstPipe()
161     {
162         return GetCurrentPipe() == 0 ? true : false;
163     }
164 
165     //!
166     //! \brief    Help function to check if current pipe is last pipe
167     //!
168     //! \return   True if current pipe is last pipe, otherwise return false
169     //!
IsLastPipe()170     virtual bool IsLastPipe()
171     {
172         return GetCurrentPipe() == GetPipeNum() - 1 ? true : false;
173     }
174 
175     //!
176     //! \brief    Help function to get pass number
177     //!
178     //! \return   Pass number
179     //!
GetPassNum()180     virtual uint16_t GetPassNum() { return m_scalability->GetPassNumber(); }
181 
182     //!
183     //! \brief    Help function to get current pass
184     //!
185     //! \return   Pass index
186     //!
GetCurrentPass()187     virtual uint16_t GetCurrentPass() { return m_scalability->GetCurrentPass(); }
188 
189     //!
190     //! \brief    Help function to check if current PAK pass is first pass
191     //!
192     //! \return   True if current PAK pass is first pass, otherwise return false
193     //!
IsFirstPass()194     virtual bool IsFirstPass()
195     {
196         return GetCurrentPass() == 0 ? true : false;
197     }
198 
199     //!
200     //! \brief    Help function to check if current PAK pass is last pass
201     //!
202     //! \return   True if current PAK pass is last pass, otherwise return false
203     //!
IsLastPass()204     virtual bool IsLastPass()
205     {
206         return GetCurrentPass() == GetPassNum() - 1 ? true : false;
207     }
208 
209     //!
210     //! \brief    Help function to get component state
211     //!
212     //! \return   Point to component state
213     //!
GetComponentState()214     virtual ComponentState *GetComponentState()
215     {
216         return m_scalability->GetComponentState();
217     }
218 
219     //!
220     //! \brief    Help function to check if phased submission mode
221     //!
222     //! \return   True if phased submission mode, otherwise return false
223     //!
IsPhasedSubmission()224     virtual bool IsPhasedSubmission()
225     {
226         return m_osInterface->phasedSubmission;
227     }
228 
229     //!
230     //! \brief    Help function to check if guc submission mode
231     //!
232     //! \return   True if guc submission mode, otherwise return false
233     //!
IsParallelSubmission()234     virtual bool IsParallelSubmission()
235     {
236         return m_osInterface->bParallelSubmission;
237     }
238 
239 #ifdef _DECODE_PROCESSING_SUPPORTED
240     //!
241     //! \brief  Check if down sampling supported for current frame
242     //! \return Return if down sampling supported for current frame
243     //!
244     bool IsDownSamplingSupported();
245 #endif
246 
247     //!
248     //! \brief  Get dummy reference surface
249     //! \return Pointer of reference surface
250     //!
251     MOS_SURFACE* GetDummyReference();
252 
253     //!
254     //! \brief  Get dummy reference status
255     //! \return CODECHAL_DUMMY_REFERENCE_STATUS
256     //!
257     CODECHAL_DUMMY_REFERENCE_STATUS GetDummyReferenceStatus();
258 
259     //!
260     //! \brief  Set dummy reference status
261     //! \return void
262     //!
263     void SetDummyReferenceStatus(CODECHAL_DUMMY_REFERENCE_STATUS status);
264 
265     //!
266     //! \brief  Get mmc state
267     //! \return Pointer of mmc state
268     //!
GetMmcState()269     DecodeMemComp *GetMmcState() { return m_mmcState; }
270 
271     //!
272     //! \brief  Get Wa table
273     //! \return Pointer of Wa table
274     //!
GetWaTable()275     MEDIA_WA_TABLE *GetWaTable() { return m_waTable; }
276 
277     //!
278     //! \brief Get Sku table
279     //! \return Pointer of SKU table
280     //!
GetSkuTable()281     MEDIA_FEATURE_TABLE *GetSkuTable() { return m_skuTable; }
282 
283     DeclareDecodePacketId(hucCopyPacketId);
284     DeclareDecodePacketId(hucCpStreamOutPacketId);
285     DeclareDecodePacketId(predicationSubPacketId);
286     DeclareDecodePacketId(markerSubPacketId);
287     DeclareDecodePacketId(downSamplingSubPacketId);
288 
289     //!
290     //! \brief  Get decode context
291     //! \return decode context
292     //!
GetDecodeContext()293     MOS_GPU_CONTEXT GetDecodeContext() { return m_decodeContext; }
294 
295     //!
296     //! \brief  Get decode context handle
297     //! \return decode context handle
298     //!
GetDecodeContextHandle()299     GPU_CONTEXT_HANDLE GetDecodeContextHandle() { return m_decodeContextHandle; }
300 
301     //!
302     //! \brief  Indicates whether current process pipe is first process pipe of current frame
303     //! \return bool
304     //!         true for first process pipe, false for other process pipe
305     //!
306     bool IsFirstProcessPipe(const DecodePipelineParams &pipelineParams);
307 
308     //!
309     //! \brief    Gets oca dump interface.
310     //! \return   CodechalOcaDumper
311     //!           return oca debug interface
312     //!
GetCodechalOcaDumper()313     CodechalOcaDumper *GetCodechalOcaDumper() { return m_pCodechalOcaDumper; }
314 
315     //!
316     //! \brief    Set decode short/long format during runtime.
317     //! \return   MOS_STATUS
318     //!           MOS_STATUS_SUCCESS if success, else fail reason
319     //!
SetDecodeFormat(bool isShortFormat)320     virtual MOS_STATUS SetDecodeFormat(bool isShortFormat ){ return MOS_STATUS_UNIMPLEMENTED; };
321 
322 protected:
323     //!
324     //! \brief  Initialize the decode pipeline
325     //! \param  [in] settings
326     //!         Pointer to the initialize settings
327     //! \return MOS_STATUS
328     //!         MOS_STATUS_SUCCESS if success, else fail reason
329     //!
330     virtual MOS_STATUS Initialize(void *settings);
331 
332     //!
333     //! \brief  Uninitialize the decode pipeline
334     //! \return MOS_STATUS
335     //!         MOS_STATUS_SUCCESS if success, else fail reason
336     //!
337     virtual MOS_STATUS Uninitialize();
338 
339     //!
340     //! \brief  User Feature Key Report
341     //! \return MOS_STATUS
342     //!         MOS_STATUS_SUCCESS if success, else fail reason
343     //!
344     virtual MOS_STATUS UserFeatureReport() override;
345 
346     //!
347     //! \brief  Get the number of Vdbox
348     //! \return uint8_t
349     //!         Return the number of Vdbox
350     //!
351     virtual uint8_t GetSystemVdboxNumber();
352 
353     //!
354     //! \brief  Create status report
355     //! \return MOS_STATUS
356     //!         MOS_STATUS_SUCCESS if success, else fail reason
357     //!
358     virtual MOS_STATUS CreateStatusReport();
359 
360     //!
361     //! \brief  Finish the active packets execution
362     //! \return MOS_STATUS
363     //!         MOS_STATUS_SUCCESS if success, else fail reason
364     //!
365     MOS_STATUS ExecuteActivePackets() override;
366 
367     //!
368     //! \brief  Create pre sub pipelines
369     //! \param  [in] subPipelineManager
370     //!         Point to subPipeline manager
371     //! \return MOS_STATUS
372     //!         MOS_STATUS_SUCCESS if success, else fail reason
373     //!
374     virtual MOS_STATUS CreatePreSubPipeLines(DecodeSubPipelineManager &subPipelineManager);
375 
376     //!
377     //! \brief  Create Post sub pipelines
378     //! \param  [in] subPipelineManager
379     //!         Point to subPipeline manager
380     //! \return MOS_STATUS
381     //!         MOS_STATUS_SUCCESS if success, else fail reason
382     //!
383     virtual MOS_STATUS CreatePostSubPipeLines(DecodeSubPipelineManager &subPipelineManager);
384 
385     //!
386     //! \brief  Create sub packets
387     //! \param  [in] subPacketManager
388     //!         Sub packet manager
389     //! \param  [in] codecSettings
390     //!         Codechal settings
391     //! \return MOS_STATUS
392     //!         MOS_STATUS_SUCCESS if success, else fail reason
393     //!
394     virtual MOS_STATUS CreateSubPackets(DecodeSubPacketManager& subPacketManager, CodechalSetting &codecSettings);
395     //!
396     //! \brief  Declare Regkeys in the scope of decode
397     //! \return MOS_STATUS
398     //!         MOS_STATUS_SUCCESS if success, else fail reason
399     virtual MOS_STATUS InitUserSetting(MediaUserSettingSharedPtr userSettingPtr) override;
400 
401 #if USE_CODECHAL_DEBUG_TOOL
402 #ifdef _DECODE_PROCESSING_SUPPORTED
403     MOS_STATUS DumpDownSamplingParams(DecodeDownSamplingFeature &downSamplingParams);
404 #endif
405 
406     //!
407     //! \brief  Dump Bitstream
408     //! \param  [in] pBitstream
409     //!         Bitstream Resource
410     //! \param  [in] size
411     //!         Bitstream Size
412     //! \param  [in] offset
413     //!         Bitstream Offset
414     //! \param  [in] attrName
415     //!         Bitstream Name
416     //! \return MOS_STATUS
417     //!         MOS_STATUS_SUCCESS if success, else fail reason
418     //!
419     virtual MOS_STATUS DumpBitstream(PMOS_RESOURCE pBitstream, uint32_t size, uint32_t offset, const char* attrName = nullptr);
420 
421     //!
422     //! \brief  Add delay for dump render targets
423     //! \return MOS_STATUS
424     //!         MOS_STATUS_SUCCESS if success, else fail reason
425     //!
426     virtual MOS_STATUS DelayForDumpOutput();
427 
428     //!
429     //! \brief  Dump render targets
430     //! \param  [in] reportData
431     //!         Decode report data
432     //! \return MOS_STATUS
433     //!         MOS_STATUS_SUCCESS if success, else fail reason
434     //!
435     virtual MOS_STATUS DumpOutput(const DecodeStatusReportData& reportData);
436 #endif
437 
438 #if (_DEBUG || _RELEASE_INTERNAL)
439     //!
440     //! \brief  User feature key report for Vdbox IDs
441     //! \param  [in] status
442     //!         Status report from HW
443     //! \return MOS_STATUS
444     //!         MOS_STATUS_SUCCESS if success, else fail reason
445     //!
446     MOS_STATUS ReportVdboxIds(const DecodeStatusMfx& status);
447 
448     //!
449     //! \brief  Earlier stop for hw error status
450     //! \param  [in] status
451     //!         Status report from HW
452     //! \return MOS_STATUS
453     //!         MOS_STATUS_SUCCESS if success, else fail reason
454     //!
HwStatusCheck(const DecodeStatusMfx & status)455     virtual MOS_STATUS HwStatusCheck(const DecodeStatusMfx &status)
456     {
457         return MOS_STATUS_SUCCESS;
458     }
459 
460 #ifdef _DECODE_PROCESSING_SUPPORTED
461     //!
462     //! \brief  User feature key report for Sfc Linear Usage Status
463     //! \param  [in] status
464     //!         Status report from HW
465     //! \return MOS_STATUS
466     //!         MOS_STATUS_SUCCESS if success, else fail reason
467     //!
468     MOS_STATUS ReportSfcLinearSurfaceUsage(const DecodeStatusReportData &reportData);
469 #endif
470 
471     //!
472     //! \brief  Internal status check after each frame
473     //! \return MOS_STATUS
474     //!         MOS_STATUS_SUCCESS if success, else fail reason
475     //!
476     virtual MOS_STATUS StatusCheck();
477 #endif
478 
479 protected:
480     //!
481     //! \brief  Create sub pipeline manager
482     //! \param  [in] codecSettings
483     //!         Point to codechal settings
484     //! \return MOS_STATUS
485     //!         MOS_STATUS_SUCCESS if success, else fail reason
486     //!
487     MOS_STATUS CreateSubPipeLineManager(CodechalSetting* codecSettings);
488 
489     //!
490     //! \brief  Create sub packet manager
491     //! \param  [in] codecSettings
492     //!         Point to codechal settings
493     //! \return MOS_STATUS
494     //!         MOS_STATUS_SUCCESS if success, else fail reason
495     //!
496     MOS_STATUS CreateSubPacketManager(CodechalSetting* codecSettings);
497 
498     friend class DecodeSubPipelineManager;
499     friend class DecodeStreamOut;
500 
501     CodechalHwInterfaceNext *m_hwInterface        = nullptr;  //!< Codechal HwInterface
502     CodechalOcaDumper      *m_pCodechalOcaDumper = nullptr;
503     CodechalDebugInterface* m_debugInterface = nullptr; //!< Debug Interface
504     MediaTask *             m_task           = nullptr; //!< Command task
505 
506     DecodeSubPipelineManager* m_preSubPipeline = nullptr; //!< PreExecution sub pipeline
507     DecodeSubPipelineManager *m_postSubPipeline = nullptr;  //!< PostExecution sub pipeline
508     DecodeSubPacketManager*   m_subPacketManager = nullptr; //!< Sub packet manager
509 
510     DecodePipeMode          m_pipeMode = decodePipeModeBegin; //!< pipe mode
511 
512     DecodeAllocator *       m_allocator = nullptr;      //!< Resource allocator
513     DecodeInputBitstream*   m_bitstream = nullptr;      //!< Decode input bitstream
514     DecodeMemComp*          m_mmcState  = nullptr;      //!< Decode mmc state
515     DecodeCpInterface*      m_decodecp = nullptr;       //!< DecodeCp interface
516     DecodeStreamOut*        m_streamout = nullptr;      //!< Decode input bitstream
517 
518     uint8_t                 m_numVdbox  = 0;            //!< Number of Vdbox
519 
520     bool                    m_singleTaskPhaseSupported = true; //!< Indicates whether sumbit packets in single phase
521 
522     MOS_GPU_CONTEXT         m_decodeContext = MOS_GPU_CONTEXT_INVALID_HANDLE;    //!< decode context inuse
523     GPU_CONTEXT_HANDLE      m_decodeContextHandle = MOS_GPU_CONTEXT_INVALID_HANDLE;    //!< handle of decode context inuse
524 
525 #if (_DEBUG || _RELEASE_INTERNAL)
526     uint32_t                m_statusCheckCount = 0;     //!< count for status check
527     uint32_t                m_delayMiliseconds = 0;     //!< miliseconds delay after each frame
528 #endif
529 
530     PMOS_SURFACE            m_tempOutputSurf = nullptr;
531 
532 MEDIA_CLASS_DEFINE_END(decode__DecodePipeline)
533 };
534 
535 }//decode
536 
537 #endif // !__DECODE_PIPELINE_H__
538