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