1 /*
2 * Copyright (c) 2018-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     decode_avc_pipeline_m12.cpp
24 //! \brief    Defines the interface for avc decode pipeline
25 //!
26 #include "decode_avc_pipeline_m12.h"
27 #include "decode_utils.h"
28 #include "decode_mem_compression_g12.h"
29 #include "decode_avc_packet_m12.h"
30 #include "decode_avc_slice_packet_m12.h"
31 #include "decode_avc_picture_packet_m12.h"
32 #include "decode_common_feature_defs.h"
33 #include "decode_avc_downsampling_packet.h"
34 #include "decode_sfc_histogram_postsubpipeline_m12.h"
35 #include "decode_avc_feature_manager.h"
36 #include "decode_input_bitstream_m12.h"
37 #include "decode_cp_bitstream_m12.h"
38 #include "decode_marker_packet_g12.h"
39 #include "decode_predication_packet_g12.h"
40 
41 namespace decode {
AvcPipelineM12(CodechalHwInterface * hwInterface,CodechalDebugInterface * debugInterface)42 AvcPipelineM12::AvcPipelineM12(
43     CodechalHwInterface    *hwInterface,
44     CodechalDebugInterface *debugInterface)
45     : AvcPipeline(hwInterface ? hwInterface->m_hwInterfaceNext : nullptr, debugInterface)
46 {
47     m_hwInterface = hwInterface;
48 }
49 
Init(void * settings)50 MOS_STATUS AvcPipelineM12::Init(void *settings)
51 {
52     DECODE_FUNC_CALL();
53 
54     DECODE_CHK_NULL(settings);
55     DECODE_CHK_STATUS(Initialize(settings));
56 
57     m_avcDecodePkt = MOS_New(AvcDecodePktM12, this, m_task, m_hwInterface);
58     DECODE_CHK_STATUS(RegisterPacket(DecodePacketId(this, avcDecodePacketId), m_avcDecodePkt));
59     DECODE_CHK_STATUS(m_avcDecodePkt->Init());
60 
61     if (m_numVdbox == 2)
62     {
63         m_allowVirtualNodeReassign = true;
64     }
65 
66     return MOS_STATUS_SUCCESS;
67 }
68 
GetStatusReport(void * status,uint16_t numStatus)69 MOS_STATUS AvcPipelineM12::GetStatusReport(void *status, uint16_t numStatus)
70 {
71     DECODE_FUNC_CALL();
72 
73      m_statusReport->GetReport(numStatus, status);
74 
75     return MOS_STATUS_SUCCESS;
76 }
77 
GetCompletedReport()78 uint32_t AvcPipelineM12::GetCompletedReport()
79 {
80     DECODE_FUNC_CALL();
81 
82     uint32_t completedCount = m_statusReport->GetCompletedCount();
83     uint32_t reportedCount = m_statusReport->GetReportedCount();
84 
85     if (reportedCount > completedCount)
86     {
87         DECODE_ASSERTMESSAGE("No report available at all");
88         return 0;
89     }
90     else
91     {
92         uint32_t availableCount = completedCount - reportedCount;
93         return availableCount;
94     }
95 }
96 
Destroy()97 MOS_STATUS AvcPipelineM12::Destroy()
98 {
99     DECODE_FUNC_CALL();
100 
101     Uninitialize();
102 
103     return MOS_STATUS_SUCCESS;
104 }
105 
CreateFeatureManager()106 MOS_STATUS AvcPipelineM12::CreateFeatureManager()
107 {
108     DECODE_FUNC_CALL();
109     m_featureManager = MOS_New(DecodeAvcFeatureManager, m_allocator, m_hwInterface, m_osInterface);
110     DECODE_CHK_NULL(m_featureManager);
111     return MOS_STATUS_SUCCESS;
112 }
113 
Initialize(void * settings)114 MOS_STATUS AvcPipelineM12::Initialize(void *settings)
115 {
116     DECODE_FUNC_CALL();
117     DECODE_CHK_STATUS(MediaPipeline::InitPlatform());
118     DECODE_CHK_STATUS(MediaPipeline::CreateMediaCopyWrapper());
119     DECODE_CHK_NULL(m_mediaCopyWrapper);
120 
121     DECODE_CHK_NULL(m_waTable);
122 
123     auto *codecSettings = (CodechalSetting *)settings;
124     DECODE_CHK_NULL(m_hwInterface);
125     DECODE_CHK_STATUS(m_hwInterface->Initialize(codecSettings));
126 
127     if (m_mediaCopyWrapper->MediaCopyStateIsNull())
128     {
129         m_mediaCopyWrapper->SetMediaCopyState(m_hwInterface->CreateMediaCopy(m_osInterface));
130     }
131 
132     CODECHAL_DEBUG_TOOL(
133         m_debugInterface = MOS_New(CodechalDebugInterface);
134         DECODE_CHK_NULL(m_debugInterface);
135         DECODE_CHK_STATUS(
136             m_debugInterface->Initialize(m_hwInterface, codecSettings->codecFunction, m_mediaCopyWrapper)););
137 
138     if (m_hwInterface->m_hwInterfaceNext)
139     {
140         m_hwInterface->m_hwInterfaceNext->legacyHwInterface = m_hwInterface;
141     }
142     m_mediaContext = MOS_New(MediaContext, scalabilityDecoder, m_hwInterface->m_hwInterfaceNext, m_osInterface);
143     DECODE_CHK_NULL(m_mediaContext);
144 
145     m_task = CreateTask(MediaTask::TaskType::cmdTask);
146     DECODE_CHK_NULL(m_task);
147 
148     m_numVdbox = GetSystemVdboxNumber();
149 
150     bool limitedLMemBar = MEDIA_IS_SKU(m_skuTable, FtrLimitedLMemBar) ? true : false;
151     m_allocator         = MOS_New(DecodeAllocator, m_osInterface, limitedLMemBar);
152     DECODE_CHK_NULL(m_allocator);
153 
154     DECODE_CHK_STATUS(CreateStatusReport());
155 
156     m_decodecp = Create_DecodeCpInterface(codecSettings, m_hwInterface->GetCpInterface(), m_hwInterface->GetOsInterface());
157     if (m_decodecp)
158     {
159         DECODE_CHK_STATUS(m_decodecp->RegisterParams(codecSettings));
160     }
161     DECODE_CHK_STATUS(CreateFeatureManager());
162     DECODE_CHK_STATUS(m_featureManager->Init(codecSettings));
163 
164     DECODE_CHK_STATUS(CreateSubPipeLineManager(codecSettings));
165     DECODE_CHK_STATUS(CreateSubPacketManager(codecSettings));
166 
167     m_basicFeature = dynamic_cast<AvcBasicFeature *>(m_featureManager->GetFeature(FeatureIDs::basicFeature));
168     DECODE_CHK_NULL(m_basicFeature);
169 
170     // Create basic GPU context
171     DecodeScalabilityPars scalPars;
172     MOS_ZeroMemory(&scalPars, sizeof(scalPars));
173     DECODE_CHK_STATUS(m_mediaContext->SwitchContext(VdboxDecodeFunc, &scalPars, &m_scalability));
174 
175     m_decodeContext = m_osInterface->pfnGetGpuContext(m_osInterface);
176 
177     m_intelEntrypointInUse = (codecSettings->intelEntrypointInUse) ? true : false;
178     m_shortFormatInUse     = (codecSettings->shortFormatInUse) ? true : false;
179 
180     HucPacketCreatorG12 *hucPktCreator = dynamic_cast<HucPacketCreatorG12 *>(this);
181     DECODE_CHK_NULL(hucPktCreator);
182     m_formatMonoPicPkt = hucPktCreator->CreateHucCopyPkt(this, m_task, m_hwInterface);
183     DECODE_CHK_NULL(m_formatMonoPicPkt);
184     MediaPacket *packet = dynamic_cast<MediaPacket *>(m_formatMonoPicPkt);
185     DECODE_CHK_NULL(packet);
186     DECODE_CHK_STATUS(RegisterPacket(DecodePacketId(this, avcFormatMonoPicPktId), packet));
187     DECODE_CHK_STATUS(packet->Init());
188     DECODE_CHK_STATUS(InitMmcState());
189 
190     return MOS_STATUS_SUCCESS;
191 }
192 
CreateSubPackets(DecodeSubPacketManager & subPacketManager,CodechalSetting & codecSettings)193 MOS_STATUS AvcPipelineM12::CreateSubPackets(DecodeSubPacketManager &subPacketManager, CodechalSetting &codecSettings)
194 {
195     DecodePredicationPktG12 *predicationPkt = MOS_New(DecodePredicationPktG12, this, m_hwInterface);
196     DECODE_CHK_NULL(predicationPkt);
197     DECODE_CHK_STATUS(subPacketManager.Register(
198         DecodePacketId(this, predicationSubPacketId), *predicationPkt));
199 
200     DecodeMarkerPktG12 *markerPkt = MOS_New(DecodeMarkerPktG12, this, m_hwInterface);
201     DECODE_CHK_NULL(markerPkt);
202     DECODE_CHK_STATUS(subPacketManager.Register(
203         DecodePacketId(this, markerSubPacketId), *markerPkt));
204 
205 #ifdef _DECODE_PROCESSING_SUPPORTED
206     AvcDownSamplingPkt *downSamplingPkt = MOS_New(AvcDownSamplingPkt, this, *m_hwInterface);
207     DECODE_CHK_NULL(downSamplingPkt);
208     DECODE_CHK_STATUS(subPacketManager.Register(
209         DecodePacketId(this, downSamplingSubPacketId), *downSamplingPkt));
210 #endif
211 
212     AvcDecodePicPktM12 *pictureDecodePkt = MOS_New(AvcDecodePicPktM12, this, m_hwInterface);
213     DECODE_CHK_NULL(pictureDecodePkt);
214     DECODE_CHK_STATUS(subPacketManager.Register(
215                         DecodePacketId(this, avcPictureSubPacketId), *pictureDecodePkt));
216 
217     AvcDecodeSlcPktM12 *sliceDecodePkt = MOS_New(AvcDecodeSlcPktM12, this, m_hwInterface);
218     DECODE_CHK_NULL(sliceDecodePkt);
219     DECODE_CHK_STATUS(subPacketManager.Register(
220                         DecodePacketId(this, avcSliceSubPacketId), *sliceDecodePkt));
221 
222     return MOS_STATUS_SUCCESS;
223 }
224 
Uninitialize()225 MOS_STATUS AvcPipelineM12::Uninitialize()
226 {
227     DECODE_FUNC_CALL();
228 
229     for (auto pair : m_packetList)
230     {
231         pair.second->Destroy();
232     }
233 
234     if (m_mmcState != nullptr)
235     {
236         MOS_Delete(m_mmcState);
237     }
238 
239     return DecodePipeline::Uninitialize();
240 }
241 
InitContext()242 MOS_STATUS AvcPipelineM12::InitContext()
243 {
244     DECODE_FUNC_CALL();
245 
246     DecodeScalabilityPars scalPars;
247     MOS_ZeroMemory(&scalPars, sizeof(scalPars));
248     scalPars.disableScalability = true;
249     scalPars.disableRealTile = true;
250     scalPars.enableVE = MOS_VE_SUPPORTED(m_osInterface);
251     scalPars.numVdbox = m_numVdbox;
252 #ifdef _DECODE_PROCESSING_SUPPORTED
253     DecodeDownSamplingFeature* downSamplingFeature = dynamic_cast<DecodeDownSamplingFeature*>(
254         m_featureManager->GetFeature(DecodeFeatureIDs::decodeDownSampling));
255      if (downSamplingFeature != nullptr && downSamplingFeature->IsEnabled())
256     {
257         scalPars.usingSfc = true;
258     }
259 #endif
260 
261     if (m_allowVirtualNodeReassign)
262     {
263         // reassign decoder virtual node at the first frame for each stream
264         DECODE_CHK_STATUS(m_mediaContext->ReassignContextForDecoder(m_basicFeature->m_frameNum, &scalPars, &m_scalability));
265         m_mediaContext->SetLatestDecoderVirtualNode();
266     }
267     else
268     {
269         DECODE_CHK_STATUS(m_mediaContext->SwitchContext(VdboxDecodeFunc, &scalPars, &m_scalability));
270     }
271     DECODE_CHK_NULL(m_scalability);
272 
273     if (scalPars.disableScalability)
274         m_osInterface->pfnSetMultiEngineEnabled(m_osInterface, COMPONENT_Decode, false);
275 
276     return MOS_STATUS_SUCCESS;
277 }
278 
Prepare(void * params)279 MOS_STATUS AvcPipelineM12::Prepare(void *params)
280 {
281     DecodePipelineParams *pipelineParams = (DecodePipelineParams *)params;
282     m_pipeMode = pipelineParams->m_pipeMode;
283 
284     PERF_UTILITY_AUTO((__FUNCTION__ + std::to_string((int)m_pipeMode)).c_str(), PERF_DECODE, PERF_LEVEL_HAL);
285 
286     if (IsFirstProcessPipe(*pipelineParams))
287     {
288         DECODE_CHK_STATUS(AvcPipeline::Prepare(params));
289     }
290 
291     DECODE_CHK_STATUS(m_preSubPipeline->Prepare(*pipelineParams));
292     DECODE_CHK_STATUS(m_postSubPipeline->Prepare(*pipelineParams));
293 
294     if (m_pipeMode == decodePipeModeProcess)
295     {
296         if (IsCompleteBitstream())
297         {
298             if (m_pCodechalOcaDumper)
299             {
300                 m_pCodechalOcaDumper->SetAvcDecodeParam(
301                     m_basicFeature->m_avcPicParams,
302                     m_basicFeature->m_avcSliceParams,
303                     m_basicFeature->m_numSlices);
304             }
305 
306             CODECHAL_DEBUG_TOOL(DECODE_CHK_STATUS(DumpParams(*m_basicFeature)));
307 
308             DecodeStatusParameters inputParameters = {};
309             MOS_ZeroMemory(&inputParameters, sizeof(DecodeStatusParameters));
310             inputParameters.statusReportFeedbackNumber = m_basicFeature->m_avcPicParams->StatusReportFeedbackNumber;
311             inputParameters.codecFunction              = m_basicFeature->m_codecFunction;
312             inputParameters.picWidthInMb               = m_basicFeature->m_picWidthInMb;
313             inputParameters.pictureCodingType          = m_basicFeature->m_pictureCodingType;
314             inputParameters.currOriginalPic            = m_basicFeature->m_curRenderPic;
315             inputParameters.currDecodedPicRes          = m_basicFeature->m_destSurface.OsResource;
316             inputParameters.isSecondField              = m_basicFeature->m_secondField;
317             inputParameters.numUsedVdbox               = m_numVdbox;
318 
319             CODECHAL_DEBUG_TOOL(
320                 if (m_streamout != nullptr)
321                 {
322                     DECODE_CHK_STATUS(m_streamout->InitStatusReportParam(inputParameters));
323                 }
324             );
325 
326 #ifdef _DECODE_PROCESSING_SUPPORTED
327             CODECHAL_DEBUG_TOOL(
328                 DecodeDownSamplingFeature* downSamplingFeature = dynamic_cast<DecodeDownSamplingFeature*>(
329                     m_featureManager->GetFeature(DecodeFeatureIDs::decodeDownSampling));
330                 if (downSamplingFeature != nullptr)
331                 {
332                     auto frameIdx = m_basicFeature->m_curRenderPic.FrameIdx;
333                     inputParameters.sfcOutputSurface = &downSamplingFeature->m_outputSurfaceList[frameIdx];
334                     DumpDownSamplingParams(*downSamplingFeature);
335                 });
336 #endif
337 
338             m_statusReport->Init(&inputParameters);
339         }
340     }
341 
342     return MOS_STATUS_SUCCESS;
343 }
344 
Execute()345 MOS_STATUS AvcPipelineM12::Execute()
346 {
347     PERF_UTILITY_AUTO((__FUNCTION__ + std::to_string((int)m_pipeMode)).c_str(), PERF_DECODE, PERF_LEVEL_HAL);
348 
349     if (m_pipeMode == decodePipeModeProcess)
350     {
351         DECODE_CHK_STATUS(m_preSubPipeline->Execute());
352 
353         if (IsCompleteBitstream())
354         {
355             DECODE_CHK_STATUS(InitContext());
356             DECODE_CHK_STATUS(ActivateDecodePackets());
357             DECODE_CHK_STATUS(ExecuteActivePackets());
358 
359 #if (_DEBUG || _RELEASE_INTERNAL)
360             DECODE_CHK_STATUS(StatusCheck());
361 #endif
362             // Only update user features for the first frame.
363             if (m_basicFeature->m_frameNum == 0)
364             {
365                 DECODE_CHK_STATUS(UserFeatureReport());
366             }
367 
368             if (m_basicFeature->m_avcPicParams)
369             {
370                 if (m_basicFeature->m_secondField || CodecHal_PictureIsFrame(m_basicFeature->m_avcPicParams->CurrPic))
371                 {
372                     DecodeFrameIndex++;
373                     m_basicFeature->m_frameNum = DecodeFrameIndex;
374                 }
375             }
376             DECODE_CHK_STATUS(m_statusReport->Reset());
377         }
378         DECODE_CHK_STATUS(m_postSubPipeline->Execute());
379     }
380 
381     return MOS_STATUS_SUCCESS;
382 }
383 
InitMmcState()384 MOS_STATUS AvcPipelineM12::InitMmcState()
385 {
386 #ifdef _MMC_SUPPORTED
387     DECODE_CHK_NULL(m_hwInterface);
388     m_mmcState = MOS_New(DecodeMemCompG12, m_hwInterface);
389     DECODE_CHK_NULL(m_mmcState);
390 
391     DECODE_CHK_STATUS(m_basicFeature->SetMmcState(m_mmcState->IsMmcEnabled()));
392 #endif
393     return MOS_STATUS_SUCCESS;
394 }
395 
UserFeatureReport()396 MOS_STATUS AvcPipelineM12::UserFeatureReport()
397 {
398     DECODE_FUNC_CALL();
399 
400     return AvcPipeline::UserFeatureReport();
401 }
402 
CreatePostSubPipeLines(DecodeSubPipelineManager & subPipelineManager)403 MOS_STATUS AvcPipelineM12::CreatePostSubPipeLines(DecodeSubPipelineManager &subPipelineManager)
404 {
405     DECODE_FUNC_CALL();
406 
407 #ifdef _DECODE_PROCESSING_SUPPORTED
408     auto sfcHistogramPostSubPipeline = MOS_New(DecodeSfcHistogramSubPipelineM12, this, m_task, m_numVdbox, m_hwInterface);
409     DECODE_CHK_NULL(sfcHistogramPostSubPipeline);
410     DECODE_CHK_STATUS(m_postSubPipeline->Register(*sfcHistogramPostSubPipeline));
411 #endif
412 
413     return MOS_STATUS_SUCCESS;
414 }
415 
CreatePreSubPipeLines(DecodeSubPipelineManager & subPipelineManager)416 MOS_STATUS AvcPipelineM12::CreatePreSubPipeLines(DecodeSubPipelineManager &subPipelineManager)
417 {
418     m_bitstream = MOS_New(DecodeInputBitstreamM12, this, m_task, m_numVdbox, m_hwInterface);
419     DECODE_CHK_NULL(m_bitstream);
420     DECODE_CHK_STATUS(subPipelineManager.Register(*m_bitstream));
421 
422     m_streamout = MOS_New(DecodeStreamOutM12, this, m_task, m_numVdbox, m_hwInterface);
423     DECODE_CHK_NULL(m_streamout);
424     DECODE_CHK_STATUS(subPipelineManager.Register(*m_streamout));
425     return MOS_STATUS_SUCCESS;
426 }
427 
428 #if USE_CODECHAL_DEBUG_TOOL
DumpParams(AvcBasicFeature & basicFeature)429 MOS_STATUS AvcPipelineM12::DumpParams(AvcBasicFeature &basicFeature)
430 {
431     m_debugInterface->m_frameType = m_basicFeature->m_avcPicParams->pic_fields.IntraPicFlag ? I_TYPE: MIXED_TYPE;
432     m_debugInterface->m_currPic   = m_basicFeature->m_avcPicParams->CurrPic;
433     m_debugInterface->m_secondField = m_basicFeature->m_secondField;
434     m_debugInterface->m_bufferDumpFrameNum = m_basicFeature->m_frameNum;
435 
436     DECODE_CHK_STATUS(DumpPicParams(basicFeature.m_avcPicParams));
437     DECODE_CHK_STATUS(DumpSliceParams(basicFeature.m_avcSliceParams, basicFeature.m_numSlices, basicFeature.m_shortFormatInUse));
438     DECODE_CHK_STATUS(DumpIQParams(basicFeature.m_avcIqMatrixParams));
439     DECODE_CHK_STATUS(DumpBitstream(&basicFeature.m_resDataBuffer.OsResource, basicFeature.m_dataSize, 0));
440 
441     return MOS_STATUS_SUCCESS;
442 }
443 #endif
444 }
445