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