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