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 //!
24 //! \file decode_pipeline.cpp
25 //! \brief Defines the common interface for decode pipeline
26 //! \details The decode pipeline interface is further sub-divided by codec standard,
27 //! this file is for the base interface which is shared by all codecs.
28 //!
29 #include "decode_pipeline.h"
30 #include "decode_utils.h"
31 #include "decode_status_report.h"
32 #include "media_packet.h"
33 #include "decode_predication_packet.h"
34 #include "decode_marker_packet.h"
35 #include "decode_downsampling_packet.h"
36 #include "codechal_setting.h"
37 #include "decode_basic_feature.h"
38 #include "mos_solo_generic.h"
39 #include "decode_sfc_histogram_postsubpipeline.h"
40 #include "decode_common_feature_defs.h"
41 #include "decode_resource_auto_lock.h"
42
43 namespace decode {
44
DecodePipeline(CodechalHwInterfaceNext * hwInterface,CodechalDebugInterface * debugInterface)45 DecodePipeline::DecodePipeline(
46 CodechalHwInterfaceNext *hwInterface,
47 CodechalDebugInterface *debugInterface):
48 MediaPipeline(hwInterface ? hwInterface->GetOsInterface() : nullptr)
49 {
50 DECODE_FUNC_CALL();
51
52 DECODE_ASSERT(hwInterface != nullptr);
53 m_hwInterface = hwInterface;
54 MOS_STATUS m_status = (InitUserSetting(m_userSettingPtr));
55
56 m_singleTaskPhaseSupported =
57 ReadUserFeature(m_userSettingPtr, "Decode Single Task Phase Enable", MediaUserSetting::Group::Sequence).Get<bool>();
58
59 m_pCodechalOcaDumper = MOS_New(CodechalOcaDumper);
60 if (!m_pCodechalOcaDumper)
61 {
62 MOS_OS_ASSERTMESSAGE("Initialize CodechalOcaDumper failed!");
63 }
64 }
65
CreateStatusReport()66 MOS_STATUS DecodePipeline::CreateStatusReport()
67 {
68 m_statusReport = MOS_New(DecodeStatusReport, m_allocator, true, m_osInterface);
69 DECODE_CHK_NULL(m_statusReport);
70 DECODE_CHK_STATUS(m_statusReport->Create());
71
72 return MOS_STATUS_SUCCESS;
73 }
74
CreatePreSubPipeLines(DecodeSubPipelineManager & subPipelineManager)75 MOS_STATUS DecodePipeline::CreatePreSubPipeLines(DecodeSubPipelineManager &subPipelineManager)
76 {
77 m_bitstream = MOS_New(DecodeInputBitstream, this, m_task, m_numVdbox);
78 DECODE_CHK_NULL(m_bitstream);
79 DECODE_CHK_STATUS(subPipelineManager.Register(*m_bitstream));
80
81 m_streamout = MOS_New(DecodeStreamOut, this, m_task, m_numVdbox);
82 DECODE_CHK_NULL(m_streamout);
83 DECODE_CHK_STATUS(subPipelineManager.Register(*m_streamout));
84 return MOS_STATUS_SUCCESS;
85 }
86
CreatePostSubPipeLines(DecodeSubPipelineManager & subPipelineManager)87 MOS_STATUS DecodePipeline::CreatePostSubPipeLines(DecodeSubPipelineManager &subPipelineManager)
88 {
89 DECODE_FUNC_CALL();
90
91 #ifdef _DECODE_PROCESSING_SUPPORTED
92 auto sfcHistogramPostSubPipeline = MOS_New(DecodeSfcHistogramSubPipeline, this, m_task, m_numVdbox);
93 DECODE_CHK_NULL(sfcHistogramPostSubPipeline);
94 DECODE_CHK_STATUS(m_postSubPipeline->Register(*sfcHistogramPostSubPipeline));
95 #endif
96
97 return MOS_STATUS_SUCCESS;
98 }
99
CreateSubPipeLineManager(CodechalSetting * codecSettings)100 MOS_STATUS DecodePipeline::CreateSubPipeLineManager(CodechalSetting* codecSettings)
101 {
102 m_preSubPipeline = MOS_New(DecodeSubPipelineManager, *this);
103 DECODE_CHK_NULL(m_preSubPipeline);
104 DECODE_CHK_STATUS(CreatePreSubPipeLines(*m_preSubPipeline));
105 DECODE_CHK_STATUS(m_preSubPipeline->Init(*codecSettings));
106
107 m_postSubPipeline = MOS_New(DecodeSubPipelineManager, *this);
108 DECODE_CHK_NULL(m_postSubPipeline);
109 DECODE_CHK_STATUS(CreatePostSubPipeLines(*m_postSubPipeline));
110 DECODE_CHK_STATUS(m_postSubPipeline->Init(*codecSettings));
111
112 return MOS_STATUS_SUCCESS;
113 }
114
CreateSubPackets(DecodeSubPacketManager & subPacketManager,CodechalSetting & codecSettings)115 MOS_STATUS DecodePipeline::CreateSubPackets(DecodeSubPacketManager& subPacketManager, CodechalSetting &codecSettings)
116 {
117 DecodePredicationPkt *predicationPkt = MOS_New(DecodePredicationPkt, this, m_hwInterface);
118 DECODE_CHK_NULL(predicationPkt);
119 DECODE_CHK_STATUS(subPacketManager.Register(
120 DecodePacketId(this, predicationSubPacketId), *predicationPkt));
121
122 DecodeMarkerPkt *markerPkt = MOS_New(DecodeMarkerPkt, this, m_hwInterface);
123 DECODE_CHK_NULL(markerPkt);
124 DECODE_CHK_STATUS(subPacketManager.Register(
125 DecodePacketId(this, markerSubPacketId), *markerPkt));
126 return MOS_STATUS_SUCCESS;
127 }
128
GetSubPacket(uint32_t subPacketId)129 DecodeSubPacket* DecodePipeline::GetSubPacket(uint32_t subPacketId)
130 {
131 return m_subPacketManager->GetSubPacket(subPacketId);
132 }
133
CreateSubPacketManager(CodechalSetting * codecSettings)134 MOS_STATUS DecodePipeline::CreateSubPacketManager(CodechalSetting* codecSettings)
135 {
136 DECODE_CHK_NULL(codecSettings);
137 m_subPacketManager = MOS_New(DecodeSubPacketManager);
138 DECODE_CHK_NULL(m_subPacketManager);
139 DECODE_CHK_STATUS(CreateSubPackets(*m_subPacketManager, *codecSettings));
140 DECODE_CHK_STATUS(m_subPacketManager->Init());
141 return MOS_STATUS_SUCCESS;
142 }
143
Initialize(void * settings)144 MOS_STATUS DecodePipeline::Initialize(void *settings)
145 {
146 DECODE_FUNC_CALL();
147
148 DECODE_CHK_NULL(settings);
149
150 DECODE_CHK_STATUS(MediaPipeline::InitPlatform());
151 DECODE_CHK_STATUS(MediaPipeline::CreateMediaCopyWrapper());
152 DECODE_CHK_NULL(m_mediaCopyWrapper);
153
154 DECODE_CHK_NULL(m_waTable);
155
156 auto *codecSettings = (CodechalSetting*)settings;
157 DECODE_CHK_NULL(m_hwInterface);
158 DECODE_CHK_STATUS(m_hwInterface->Initialize(codecSettings));
159
160 if (m_mediaCopyWrapper->MediaCopyStateIsNull())
161 {
162 m_mediaCopyWrapper->SetMediaCopyState(m_hwInterface->CreateMediaCopy(m_osInterface));
163 }
164
165 CODECHAL_DEBUG_TOOL(
166 m_debugInterface = MOS_New(CodechalDebugInterface);
167 DECODE_CHK_NULL(m_debugInterface);
168 DECODE_CHK_STATUS(
169 m_debugInterface->Initialize(m_hwInterface, codecSettings->codecFunction, m_mediaCopyWrapper));
170 );
171
172 m_mediaContext = MOS_New(MediaContext, scalabilityDecoder, m_hwInterface, m_osInterface);
173 DECODE_CHK_NULL(m_mediaContext);
174
175 m_task = CreateTask(MediaTask::TaskType::cmdTask);
176 DECODE_CHK_NULL(m_task);
177
178 m_numVdbox = GetSystemVdboxNumber();
179
180 bool limitedLMemBar = MEDIA_IS_SKU(m_skuTable, FtrLimitedLMemBar) ? true : false;
181 m_allocator = MOS_New(DecodeAllocator, m_osInterface, limitedLMemBar);
182 DECODE_CHK_NULL(m_allocator);
183
184 DECODE_CHK_STATUS(CreateStatusReport());
185
186 m_decodecp = Create_DecodeCpInterface(codecSettings, m_hwInterface->GetCpInterface(), m_hwInterface->GetOsInterface());
187 if (m_decodecp)
188 {
189 DECODE_CHK_STATUS(m_decodecp->RegisterParams(codecSettings));
190 }
191 DECODE_CHK_STATUS(CreateFeatureManager());
192 DECODE_CHK_STATUS(m_featureManager->Init(codecSettings));
193
194 DECODE_CHK_STATUS(CreateSubPipeLineManager(codecSettings));
195 DECODE_CHK_STATUS(CreateSubPacketManager(codecSettings));
196
197 #if (_DEBUG || _RELEASE_INTERNAL)
198 m_delayMiliseconds = ReadUserFeature(m_userSettingPtr, "Delay Miliseconds", MediaUserSetting::Group::Sequence).Get<uint32_t>();
199 #endif
200
201 return MOS_STATUS_SUCCESS;
202 }
203
Uninitialize()204 MOS_STATUS DecodePipeline::Uninitialize()
205 {
206 DECODE_FUNC_CALL();
207
208 // Wait all cmd completion before delete resource.
209 m_osInterface->pfnWaitAllCmdCompletion(m_osInterface);
210
211 Delete_DecodeCpInterface(m_decodecp);
212 m_decodecp = nullptr;
213
214 MOS_Delete(m_mediaContext);
215
216 MOS_Delete(m_statusReport);
217
218 MOS_Delete(m_featureManager);
219
220 MOS_Delete(m_preSubPipeline);
221 MOS_Delete(m_postSubPipeline);
222 MOS_Delete(m_subPacketManager);
223
224 MOS_Delete(m_allocator);
225
226 CODECHAL_DEBUG_TOOL(MOS_Delete(m_debugInterface););
227
228 return MOS_STATUS_SUCCESS;
229 }
230
UserFeatureReport()231 MOS_STATUS DecodePipeline::UserFeatureReport()
232 {
233 DECODE_FUNC_CALL();
234 return MediaPipeline::UserFeatureReport();
235 }
236
IsFirstProcessPipe(const DecodePipelineParams & pipelineParams)237 bool DecodePipeline::IsFirstProcessPipe(const DecodePipelineParams& pipelineParams)
238 {
239 if (pipelineParams.m_pipeMode != decodePipeModeProcess)
240 {
241 return false;
242 }
243
244 CodechalDecodeParams *decodeParams = pipelineParams.m_params;
245 if (decodeParams == nullptr)
246 {
247 return false;
248 }
249
250 return (decodeParams->m_executeCallIndex == 0);
251 }
252
GetSystemVdboxNumber()253 uint8_t DecodePipeline::GetSystemVdboxNumber()
254 {
255 uint8_t numVdbox = 1;
256
257 MEDIA_ENGINE_INFO mediaSysInfo;
258 MOS_ZeroMemory(&mediaSysInfo, sizeof(MEDIA_ENGINE_INFO));
259 MOS_STATUS eStatus = m_osInterface->pfnGetMediaEngineInfo(m_osInterface, mediaSysInfo);
260 if (eStatus == MOS_STATUS_SUCCESS)
261 {
262 numVdbox = (uint8_t)(mediaSysInfo.VDBoxInfo.NumberOfVDBoxEnabled);
263 }
264 else
265 {
266 DECODE_ASSERTMESSAGE("Failed to query media engine info!!");
267 }
268
269 return numVdbox;
270 }
271
Prepare(void * params)272 MOS_STATUS DecodePipeline::Prepare(void *params)
273 {
274 DECODE_FUNC_CALL();
275
276 DECODE_CHK_NULL(params);
277 DecodePipelineParams *pipelineParams = (DecodePipelineParams *)params;
278 CodechalDecodeParams *decodeParams = pipelineParams->m_params;
279 DECODE_CHK_NULL(decodeParams);
280
281 DECODE_CHK_STATUS(m_task->Clear());
282 m_activePacketList.clear();
283
284 DECODE_CHK_NULL(m_featureManager);
285 DECODE_CHK_STATUS(m_featureManager->CheckFeatures(decodeParams));
286 DECODE_CHK_STATUS(m_featureManager->Update(decodeParams));
287 if (m_decodecp)
288 {
289 DECODE_CHK_STATUS(m_decodecp->UpdateParams(true));
290 }
291 DECODE_CHK_STATUS(m_subPacketManager->Prepare());
292
293 DECODE_CHK_STATUS(Mos_Solo_SetGpuAppTaskEvent(m_osInterface, decodeParams->m_gpuAppTaskEvent));
294
295 return MOS_STATUS_SUCCESS;
296 }
297
ExecuteActivePackets()298 MOS_STATUS DecodePipeline::ExecuteActivePackets()
299 {
300 DECODE_FUNC_CALL();
301 MOS_TraceEventExt(EVENT_PIPE_EXE, EVENT_TYPE_START, nullptr, 0, nullptr, 0);
302
303 // Last element in m_activePacketList must be immediately submitted
304 m_activePacketList.back().immediateSubmit = true;
305
306 for (PacketProperty prop : m_activePacketList)
307 {
308 prop.stateProperty.singleTaskPhaseSupported = m_singleTaskPhaseSupported;
309 prop.stateProperty.statusReport = m_statusReport;
310 MOS_TraceEventExt(EVENT_PIPE_EXE, EVENT_TYPE_INFO, &prop.packetId, sizeof(uint32_t), nullptr, 0);
311
312 MediaTask *task = prop.packet->GetActiveTask();
313 DECODE_CHK_STATUS(task->AddPacket(&prop));
314 if (prop.immediateSubmit)
315 {
316 DECODE_CHK_STATUS(task->Submit(true, m_scalability, m_debugInterface));
317 }
318 }
319
320 m_activePacketList.clear();
321 MOS_TraceEventExt(EVENT_PIPE_EXE, EVENT_TYPE_END, nullptr, 0, nullptr, 0);
322 return MOS_STATUS_SUCCESS;
323 }
324
IsCompleteBitstream()325 bool DecodePipeline::IsCompleteBitstream()
326 {
327 return (m_bitstream == nullptr) ? false : m_bitstream->IsComplete();
328 }
329
330 #ifdef _DECODE_PROCESSING_SUPPORTED
IsDownSamplingSupported()331 bool DecodePipeline::IsDownSamplingSupported()
332 {
333 DECODE_ASSERT(m_subPacketManager != nullptr);
334
335 DecodeDownSamplingPkt *downSamplingPkt = dynamic_cast<DecodeDownSamplingPkt *>(
336 GetSubPacket(DecodePacketId(this, downSamplingSubPacketId)));
337 if (downSamplingPkt == nullptr)
338 {
339 return false;
340 }
341
342 return downSamplingPkt->IsSupported();
343 }
344 #endif
345
GetDummyReference()346 MOS_SURFACE* DecodePipeline::GetDummyReference()
347 {
348 auto* feature = dynamic_cast<DecodeBasicFeature*>(m_featureManager->GetFeature(FeatureIDs::basicFeature));
349 return (feature != nullptr) ? &(feature->m_dummyReference) : nullptr;
350 }
351
GetDummyReferenceStatus()352 CODECHAL_DUMMY_REFERENCE_STATUS DecodePipeline::GetDummyReferenceStatus()
353 {
354 auto* feature = dynamic_cast<DecodeBasicFeature*>(m_featureManager->GetFeature(FeatureIDs::basicFeature));
355 return (feature != nullptr) ? feature->m_dummyReferenceStatus : CODECHAL_DUMMY_REFERENCE_INVALID;
356 }
357
SetDummyReferenceStatus(CODECHAL_DUMMY_REFERENCE_STATUS status)358 void DecodePipeline::SetDummyReferenceStatus(CODECHAL_DUMMY_REFERENCE_STATUS status)
359 {
360 auto* feature = dynamic_cast<DecodeBasicFeature*>(m_featureManager->GetFeature(FeatureIDs::basicFeature));
361 if (feature != nullptr)
362 {
363 feature->m_dummyReferenceStatus = status;
364 }
365 }
366
367 #if USE_CODECHAL_DEBUG_TOOL
368 #ifdef _DECODE_PROCESSING_SUPPORTED
DumpDownSamplingParams(DecodeDownSamplingFeature & downSamplingParams)369 MOS_STATUS DecodePipeline::DumpDownSamplingParams(DecodeDownSamplingFeature &downSamplingParams)
370 {
371 CODECHAL_DEBUG_FUNCTION_ENTER;
372 if (!m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrDecodeProcParams))
373 {
374 return MOS_STATUS_SUCCESS;
375 }
376
377 if(!downSamplingParams.IsEnabled())
378 {
379 return MOS_STATUS_SUCCESS;
380 }
381
382 DECODE_CHK_NULL(downSamplingParams.m_inputSurface);
383
384 std::ostringstream oss;
385 oss.setf(std::ios::showbase | std::ios::uppercase);
386
387 oss << "Input Surface Resolution: "
388 << +downSamplingParams.m_inputSurface->dwWidth << " x " << +downSamplingParams.m_inputSurface->dwHeight << std::endl;
389 oss << "Input Region Resolution: "
390 << +downSamplingParams.m_inputSurfaceRegion.m_width << " x " << +downSamplingParams.m_inputSurfaceRegion.m_height << std::endl;
391 oss << "Input Region Offset: ("
392 << +downSamplingParams.m_inputSurfaceRegion.m_x << "," << +downSamplingParams.m_inputSurfaceRegion.m_y << ")" << std::endl;
393 oss << "Input Surface Format: "
394 << (downSamplingParams.m_inputSurface->Format == Format_NV12 ? "NV12" : "P010" )<< std::endl;
395 oss << "Output Surface Resolution: "
396 << +downSamplingParams.m_outputSurface.dwWidth << " x " << +downSamplingParams.m_outputSurface.dwHeight << std::endl;
397 oss << "Output Region Resolution: "
398 << +downSamplingParams.m_outputSurfaceRegion.m_width << " x " << +downSamplingParams.m_outputSurfaceRegion.m_height << std::endl;
399 oss << "Output Region Offset: ("
400 << +downSamplingParams.m_outputSurfaceRegion.m_x << ", " << +downSamplingParams.m_outputSurfaceRegion.m_y << ")" << std::endl;
401 oss << "Output Surface Format: "
402 << (downSamplingParams.m_outputSurface.Format == Format_NV12 ? "NV12" : "YUY2" )<< std::endl;
403
404 const char* filePath = m_debugInterface->CreateFileName(
405 "_DEC",
406 CodechalDbgBufferType::bufDecProcParams,
407 CodechalDbgExtType::txt);
408
409 std::ofstream ofs(filePath, std::ios::out);
410 ofs << oss.str();
411 ofs.close();
412
413 return MOS_STATUS_SUCCESS;
414 }
415 #endif
416
DumpBitstream(PMOS_RESOURCE pBitstream,uint32_t size,uint32_t offset,const char * attrName)417 MOS_STATUS DecodePipeline::DumpBitstream(PMOS_RESOURCE pBitstream, uint32_t size, uint32_t offset, const char* attrName)
418 {
419 DECODE_FUNC_CALL();
420
421 DECODE_CHK_NULL(pBitstream);
422
423 if(attrName == nullptr)
424 {
425 attrName = CodechalDbgAttr::attrDecodeBitstream;
426 }
427
428 DECODE_CHK_STATUS(m_debugInterface->DumpBuffer(
429 pBitstream,
430 attrName,
431 "_DEC",
432 size,
433 offset,
434 CODECHAL_NUM_MEDIA_STATES));
435
436 if (MOS_TraceKeyEnabled(TR_KEY_DECODE_BITSTREAM_INFO))
437 {
438 MOS_LOCK_PARAMS lockFlags;
439 MOS_ZeroMemory(&lockFlags, sizeof(MOS_LOCK_PARAMS));
440 lockFlags.ReadOnly = 1;
441
442 uint8_t *data = (uint8_t *)m_osInterface->pfnLockResource(m_osInterface, pBitstream, &lockFlags);
443 MEDIA_DEBUG_CHK_NULL(data);
444 data += offset;
445
446 DECODE_EVENTDATA_BITSTREAM eventData;
447 eventData.BitstreamSize = size;
448 for (uint32_t i = 0; i < MOS_MIN(BITSTREAM_INFO_SIZE, size); i++)
449 {
450 eventData.Data[i] = data[i];
451 }
452 MOS_TraceEvent(EVENT_DECODE_INFO_BITSTREAM, EVENT_TYPE_INFO, &eventData, sizeof(eventData));
453
454 m_osInterface->pfnUnlockResource(m_osInterface, pBitstream);
455 }
456
457 return MOS_STATUS_SUCCESS;
458 }
459
DelayForDumpOutput()460 MOS_STATUS DecodePipeline::DelayForDumpOutput()
461 {
462 DECODE_FUNC_CALL();
463
464 if (m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrDelayForDumpOutput))
465 {
466 uint32_t completedCount = m_statusReport->GetCompletedCount();
467 for (uint8_t i = 0; i < 20; i++)
468 {
469 if (completedCount <= m_statusCheckCount)
470 {
471 MosUtilities::MosSleep(5);
472 completedCount = m_statusReport->GetCompletedCount();
473 }
474 else
475 {
476 break;
477 }
478 }
479 }
480
481 return MOS_STATUS_SUCCESS;
482 }
483
DumpOutput(const DecodeStatusReportData & reportData)484 MOS_STATUS DecodePipeline::DumpOutput(const DecodeStatusReportData& reportData)
485 {
486 DECODE_FUNC_CALL();
487
488 if (m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrDecodeOutputSurface))
489 {
490 MOS_SURFACE dstSurface;
491 MOS_ZeroMemory(&dstSurface, sizeof(dstSurface));
492 dstSurface.Format = Format_NV12;
493 dstSurface.OsResource = reportData.currDecodedPicRes;
494 DECODE_CHK_STATUS(m_allocator->GetSurfaceInfo(&dstSurface));
495
496 DECODE_CHK_STATUS(m_debugInterface->DumpYUVSurface(
497 &dstSurface, CodechalDbgAttr::attrDecodeOutputSurface, "DstSurf"));
498 }
499
500 if(m_streamout != nullptr)
501 {
502 m_streamout->DumpOutput(reportData);
503 }
504
505 #ifdef _DECODE_PROCESSING_SUPPORTED
506 DecodeDownSamplingFeature* downSamplingFeature = dynamic_cast<DecodeDownSamplingFeature*>(
507 m_featureManager->GetFeature(DecodeFeatureIDs::decodeDownSampling));
508 if (downSamplingFeature != nullptr && downSamplingFeature->IsEnabled())
509 {
510 if (reportData.currSfcOutputSurface != nullptr &&
511 m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrSfcOutputSurface))
512 {
513 MOS_SURFACE &sfcDstSurface = *reportData.currSfcOutputSurface;
514
515 if (!Mos_ResourceIsNull(&sfcDstSurface.OsResource))
516 {
517 DECODE_CHK_STATUS(m_allocator->GetSurfaceInfo(&sfcDstSurface));
518
519 //rgb format read from reg key
520 uint32_t sfcOutputRgbFormatFlag =
521 ReadUserFeature(m_userSettingPtr, "Decode SFC RGB Format Output", MediaUserSetting::Group::Sequence).Get<uint32_t>();
522 if (sfcOutputRgbFormatFlag)
523 {
524 DECODE_CHK_STATUS(m_debugInterface->DumpRgbDataOnYUVSurface(
525 &sfcDstSurface, CodechalDbgAttr::attrSfcOutputSurface, "SfcDstRgbSurf"));
526 }
527 else
528 {
529 DECODE_CHK_STATUS(m_debugInterface->DumpYUVSurface(
530 &sfcDstSurface, CodechalDbgAttr::attrSfcOutputSurface, "SfcDstSurf"));
531 }
532 }
533 }
534
535 if (reportData.currHistogramOutBuf != nullptr &&
536 !Mos_ResourceIsNull(reportData.currHistogramOutBuf))
537 {
538 DECODE_CHK_STATUS(m_debugInterface->DumpBuffer(
539 reportData.currHistogramOutBuf,
540 CodechalDbgAttr::attrSfcHistogram,
541 "_DEC",
542 HISTOGRAM_BINCOUNT * downSamplingFeature->m_histogramBinWidth));
543 }
544 }
545 #endif
546
547 return MOS_STATUS_SUCCESS;
548 }
549 #endif
550
551 #if (_DEBUG || _RELEASE_INTERNAL)
ReportVdboxIds(const DecodeStatusMfx & status)552 MOS_STATUS DecodePipeline::ReportVdboxIds(const DecodeStatusMfx& status)
553 {
554 DECODE_FUNC_CALL();
555
556 // report the VDBOX IDs to user feature
557 uint32_t vdboxIds = ReadUserFeature(m_userSettingPtr, "Used VDBOX ID", MediaUserSetting::Group::Sequence).Get<uint32_t>();
558 for (auto i = 0; i < csInstanceIdMax; i++)
559 {
560 CsEngineId csEngineId;
561 csEngineId.value = status.m_mmioCsEngineIdReg[i];
562 if (csEngineId.value != 0)
563 {
564 DECODE_ASSERT(csEngineId.fields.classId == classIdVideoEngine);
565 DECODE_ASSERT(csEngineId.fields.instanceId < csInstanceIdMax);
566 vdboxIds |= 1 << ((csEngineId.fields.instanceId) << 2);
567 }
568 }
569
570 if (vdboxIds != 0)
571 {
572 WriteUserFeature(__MEDIA_USER_FEATURE_VALUE_VDBOX_ID_USED, vdboxIds, m_osInterface->pOsContext);
573 }
574
575 return MOS_STATUS_SUCCESS;
576 }
577
578 #ifdef _DECODE_PROCESSING_SUPPORTED
ReportSfcLinearSurfaceUsage(const DecodeStatusReportData & reportData)579 MOS_STATUS DecodePipeline::ReportSfcLinearSurfaceUsage(const DecodeStatusReportData& reportData)
580 {
581 DECODE_FUNC_CALL();
582
583 DecodeDownSamplingFeature *downSamplingFeature = dynamic_cast<DecodeDownSamplingFeature *>(
584 m_featureManager->GetFeature(DecodeFeatureIDs::decodeDownSampling));
585 if (downSamplingFeature != nullptr && downSamplingFeature->IsEnabled())
586 {
587 if (reportData.currSfcOutputSurface != nullptr)
588 {
589 MOS_SURFACE sfcDstSurface = *reportData.currSfcOutputSurface;
590 if (!Mos_ResourceIsNull(&sfcDstSurface.OsResource))
591 {
592 if (sfcDstSurface.TileType == MOS_TILE_LINEAR)
593 {
594 WriteUserFeature(__MEDIA_USER_FEATURE_VALUE_SFC_LINEAR_OUTPUT_USED_ID, 1, m_osInterface->pOsContext);
595 }
596 else
597 {
598 WriteUserFeature(__MEDIA_USER_FEATURE_VALUE_SFC_LINEAR_OUTPUT_USED_ID, 0, m_osInterface->pOsContext);
599 }
600 }
601 }
602 }
603 return MOS_STATUS_SUCCESS;
604 }
605 #endif
606
StatusCheck()607 MOS_STATUS DecodePipeline::StatusCheck()
608 {
609 DECODE_FUNC_CALL();
610
611 #if (_DEBUG || _RELEASE_INTERNAL)
612 if (m_delayMiliseconds > 0)
613 {
614 MosUtilities::MosSleep(m_delayMiliseconds);
615 }
616 #endif
617
618 CODECHAL_DEBUG_TOOL(DECODE_CHK_STATUS(DelayForDumpOutput()));
619
620 uint32_t completedCount = m_statusReport->GetCompletedCount();
621 if (completedCount <= m_statusCheckCount)
622 {
623 DECODE_NORMALMESSAGE("Invalid status check count, completedCount = %d m_statusCheckCount =%d.", completedCount, m_statusCheckCount);
624 return MOS_STATUS_SUCCESS;
625 }
626
627 DecodeStatusReport* statusReport = dynamic_cast<DecodeStatusReport*>(m_statusReport);
628 DECODE_CHK_NULL(statusReport);
629
630 while (m_statusCheckCount < completedCount)
631 {
632 const DecodeStatusMfx& status = statusReport->GetMfxStatus(m_statusCheckCount);
633 if (status.status != DecodeStatusReport::queryEnd)
634 {
635 DECODE_NORMALMESSAGE("Media reset may have occured at frame %d, status is %d, completedCount is %d.",
636 m_statusCheckCount, status.status, completedCount);
637 }
638
639 DECODE_NORMALMESSAGE("hucStatus2 is 0x%x at frame %d.", status.m_hucErrorStatus2, m_statusCheckCount);
640 DECODE_NORMALMESSAGE("hucStatus is 0x%x at frame %d.", status.m_hucErrorStatus, m_statusCheckCount);
641
642 DECODE_CHK_STATUS(HwStatusCheck(status));
643
644 DECODE_CHK_STATUS(ReportVdboxIds(status));
645
646 #if USE_CODECHAL_DEBUG_TOOL
647 const DecodeStatusReportData& reportData = statusReport->GetReportData(m_statusCheckCount);
648
649 auto bufferDumpNumTemp = m_debugInterface->m_bufferDumpFrameNum;
650 auto currPicTemp = m_debugInterface->m_currPic;
651 auto frameTypeTemp = m_debugInterface->m_frameType;
652 auto secondField = m_debugInterface->m_secondField;
653
654 m_debugInterface->m_bufferDumpFrameNum = DecodeOutputIndex;
655 m_debugInterface->m_currPic = reportData.currDecodedPic;
656 m_debugInterface->m_frameType = reportData.frameType;
657 m_debugInterface->m_secondField = reportData.secondField;
658
659 #ifdef _DECODE_PROCESSING_SUPPORTED
660 ReportSfcLinearSurfaceUsage(reportData);
661 #endif
662
663 DECODE_CHK_STATUS(DumpOutput(reportData));
664
665 if ((CodecHal_PictureIsFrame(m_debugInterface->m_currPic)) ||
666 (CodecHal_PictureIsField(m_debugInterface->m_currPic) && m_debugInterface->m_secondField) ||
667 (!CodecHal_PictureIsFrame(m_debugInterface->m_currPic) && !CodecHal_PictureIsField(m_debugInterface->m_currPic)))
668 {
669 DecodeOutputIndex++;
670 }
671
672 m_debugInterface->m_bufferDumpFrameNum = bufferDumpNumTemp;
673 m_debugInterface->m_currPic = currPicTemp;
674 m_debugInterface->m_frameType = frameTypeTemp;
675 m_debugInterface->m_secondField = secondField;
676 #endif
677
678 m_statusCheckCount++;
679 }
680
681 return MOS_STATUS_SUCCESS;
682 }
683 #endif
684
685 }
686