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