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