1 /*
2 * Copyright (c) 2018-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 //!
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(CodechalHwInterface * hwInterface,CodechalDebugInterface * debugInterface)45 DecodePipeline::DecodePipeline(
46 CodechalHwInterface *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
55 m_singleTaskPhaseSupported =
56 ReadUserFeature(__MEDIA_USER_FEATURE_VALUE_SINGLE_TASK_PHASE_ENABLE_ID, m_osInterface ? m_osInterface->pOsContext : nullptr).i32Data ? true : false;
57
58 CODECHAL_DEBUG_TOOL(
59 DECODE_ASSERT(debugInterface != nullptr);
60 m_debugInterface = debugInterface;
61 );
62 }
63
CreateStatusReport()64 MOS_STATUS DecodePipeline::CreateStatusReport()
65 {
66 m_statusReport = MOS_New(DecodeStatusReport, m_allocator, true);
67 DECODE_CHK_NULL(m_statusReport);
68 DECODE_CHK_STATUS(m_statusReport->Create());
69
70 return MOS_STATUS_SUCCESS;
71 }
72
CreatePreSubPipeLines(DecodeSubPipelineManager & subPipelineManager)73 MOS_STATUS DecodePipeline::CreatePreSubPipeLines(DecodeSubPipelineManager &subPipelineManager)
74 {
75 m_bitstream = MOS_New(DecodeInputBitstream, this, m_task, m_numVdbox);
76 DECODE_CHK_NULL(m_bitstream);
77 DECODE_CHK_STATUS(subPipelineManager.Register(*m_bitstream));
78
79 m_streamout = MOS_New(DecodeStreamOut, this, m_task, m_numVdbox);
80 DECODE_CHK_NULL(m_streamout);
81 DECODE_CHK_STATUS(subPipelineManager.Register(*m_streamout));
82 return MOS_STATUS_SUCCESS;
83 }
84
CreatePostSubPipeLines(DecodeSubPipelineManager & subPipelineManager)85 MOS_STATUS DecodePipeline::CreatePostSubPipeLines(DecodeSubPipelineManager &subPipelineManager)
86 {
87 DECODE_FUNC_CALL();
88
89 #ifdef _DECODE_PROCESSING_SUPPORTED
90 auto sfcHistogramPostSubPipeline = MOS_New(DecodeSfcHistogramSubPipeline, this, m_task, m_numVdbox);
91 DECODE_CHK_NULL(sfcHistogramPostSubPipeline);
92 DECODE_CHK_STATUS(m_postSubPipeline->Register(*sfcHistogramPostSubPipeline));
93 #endif
94
95 return MOS_STATUS_SUCCESS;
96 }
97
CreateSubPipeLineManager(CodechalSetting * codecSettings)98 MOS_STATUS DecodePipeline::CreateSubPipeLineManager(CodechalSetting* codecSettings)
99 {
100 m_preSubPipeline = MOS_New(DecodeSubPipelineManager, *this);
101 DECODE_CHK_NULL(m_preSubPipeline);
102 DECODE_CHK_STATUS(CreatePreSubPipeLines(*m_preSubPipeline));
103 DECODE_CHK_STATUS(m_preSubPipeline->Init(*codecSettings));
104
105 m_postSubPipeline = MOS_New(DecodeSubPipelineManager, *this);
106 DECODE_CHK_NULL(m_postSubPipeline);
107 DECODE_CHK_STATUS(CreatePostSubPipeLines(*m_postSubPipeline));
108 DECODE_CHK_STATUS(m_postSubPipeline->Init(*codecSettings));
109
110 return MOS_STATUS_SUCCESS;
111 }
112
CreateSubPackets(DecodeSubPacketManager & subPacketManager,CodechalSetting & codecSettings)113 MOS_STATUS DecodePipeline::CreateSubPackets(DecodeSubPacketManager& subPacketManager, CodechalSetting &codecSettings)
114 {
115 DecodePredicationPkt *predicationPkt = MOS_New(DecodePredicationPkt, this, m_hwInterface);
116 DECODE_CHK_NULL(predicationPkt);
117 DECODE_CHK_STATUS(subPacketManager.Register(
118 DecodePacketId(this, predicationSubPacketId), *predicationPkt));
119
120 DecodeMarkerPkt *markerPkt = MOS_New(DecodeMarkerPkt, this, m_hwInterface);
121 DECODE_CHK_NULL(markerPkt);
122 DECODE_CHK_STATUS(subPacketManager.Register(
123 DecodePacketId(this, markerSubPacketId), *markerPkt));
124 return MOS_STATUS_SUCCESS;
125 }
126
GetSubPacket(uint32_t subPacketId)127 DecodeSubPacket* DecodePipeline::GetSubPacket(uint32_t subPacketId)
128 {
129 return m_subPacketManager->GetSubPacket(subPacketId);
130 }
131
CreateSubPacketManager(CodechalSetting * codecSettings)132 MOS_STATUS DecodePipeline::CreateSubPacketManager(CodechalSetting* codecSettings)
133 {
134 DECODE_CHK_NULL(codecSettings);
135 m_subPacketManager = MOS_New(DecodeSubPacketManager);
136 DECODE_CHK_NULL(m_subPacketManager);
137 DECODE_CHK_STATUS(CreateSubPackets(*m_subPacketManager, *codecSettings));
138 DECODE_CHK_STATUS(m_subPacketManager->Init());
139 return MOS_STATUS_SUCCESS;
140 }
141
Initialize(void * settings)142 MOS_STATUS DecodePipeline::Initialize(void *settings)
143 {
144 DECODE_FUNC_CALL();
145
146 DECODE_CHK_NULL(settings);
147
148 DECODE_CHK_STATUS(MediaPipeline::InitPlatform());
149 DECODE_CHK_STATUS(MediaPipeline::CreateMediaCopy());
150
151 DECODE_CHK_NULL(m_waTable);
152
153 auto *codecSettings = (CodechalSetting*)settings;
154 DECODE_CHK_NULL(m_hwInterface);
155 DECODE_CHK_STATUS(m_hwInterface->Initialize(codecSettings));
156
157 m_mediaContext = MOS_New(MediaContext, scalabilityDecoder, m_hwInterface, m_osInterface);
158 DECODE_CHK_NULL(m_mediaContext);
159
160 m_task = CreateTask(MediaTask::TaskType::cmdTask);
161 DECODE_CHK_NULL(m_task);
162
163 m_numVdbox = GetSystemVdboxNumber();
164
165 bool limitedLMemBar = MEDIA_IS_SKU(m_skuTable, FtrLimitedLMemBar) ? true : false;
166 m_allocator = MOS_New(DecodeAllocator, m_osInterface, limitedLMemBar);
167 DECODE_CHK_NULL(m_allocator);
168
169 DECODE_CHK_STATUS(CreateStatusReport());
170
171 m_decodecp = Create_DecodeCpInterface(codecSettings, m_hwInterface);
172 if (m_decodecp)
173 {
174 m_decodecp->RegisterParams(codecSettings);
175 }
176 DECODE_CHK_STATUS(CreateFeatureManager());
177 DECODE_CHK_STATUS(m_featureManager->Init(codecSettings));
178
179 DECODE_CHK_STATUS(CreateSubPipeLineManager(codecSettings));
180 DECODE_CHK_STATUS(CreateSubPacketManager(codecSettings));
181
182 return MOS_STATUS_SUCCESS;
183 }
184
Uninitialize()185 MOS_STATUS DecodePipeline::Uninitialize()
186 {
187 DECODE_FUNC_CALL();
188
189 Delete_DecodeCpInterface(m_decodecp);
190 m_decodecp = nullptr;
191
192 MOS_Delete(m_mediaContext);
193
194 MOS_Delete(m_statusReport);
195
196 MOS_Delete(m_featureManager);
197
198 MOS_Delete(m_preSubPipeline);
199 MOS_Delete(m_postSubPipeline);
200 MOS_Delete(m_subPacketManager);
201
202 MOS_Delete(m_allocator);
203
204 return MOS_STATUS_SUCCESS;
205 }
206
UserFeatureReport()207 MOS_STATUS DecodePipeline::UserFeatureReport()
208 {
209 DECODE_FUNC_CALL();
210 return MediaPipeline::UserFeatureReport();
211 }
212
IsFirstProcessPipe(const DecodePipelineParams & pipelineParams)213 bool DecodePipeline::IsFirstProcessPipe(const DecodePipelineParams& pipelineParams)
214 {
215 if (pipelineParams.m_pipeMode != decodePipeModeProcess)
216 {
217 return false;
218 }
219
220 CodechalDecodeParams *decodeParams = pipelineParams.m_params;
221 if (decodeParams == nullptr)
222 {
223 return false;
224 }
225
226 return (decodeParams->m_executeCallIndex == 0);
227 }
228
GetSystemVdboxNumber()229 uint8_t DecodePipeline::GetSystemVdboxNumber()
230 {
231 uint8_t numVdbox = 1;
232
233 MEDIA_SYSTEM_INFO *gtSystemInfo = m_osInterface->pfnGetGtSystemInfo(m_osInterface);
234 if (gtSystemInfo != nullptr)
235 {
236 // Both VE mode and media solo mode should be able to get the VDBOX number via the same interface
237 numVdbox = (uint8_t)(gtSystemInfo->VDBoxInfo.NumberOfVDBoxEnabled);
238 }
239
240 return numVdbox;
241 }
242
Prepare(void * params)243 MOS_STATUS DecodePipeline::Prepare(void *params)
244 {
245 DECODE_FUNC_CALL();
246
247 DECODE_CHK_NULL(params);
248 DecodePipelineParams *pipelineParams = (DecodePipelineParams *)params;
249 CodechalDecodeParams *decodeParams = pipelineParams->m_params;
250 DECODE_CHK_NULL(decodeParams);
251
252 DECODE_CHK_STATUS(m_task->Clear());
253 m_activePacketList.clear();
254
255 DECODE_CHK_NULL(m_featureManager);
256 DECODE_CHK_STATUS(m_featureManager->CheckFeatures(decodeParams));
257 DECODE_CHK_STATUS(m_featureManager->Update(decodeParams));
258 if (m_decodecp)
259 {
260 m_decodecp->UpdateParams(true);
261 }
262 DECODE_CHK_STATUS(m_subPacketManager->Prepare());
263
264 DECODE_CHK_STATUS(Mos_Solo_SetGpuAppTaskEvent(m_osInterface, decodeParams->m_gpuAppTaskEvent));
265
266 return MOS_STATUS_SUCCESS;
267 }
268
ExecuteActivePackets()269 MOS_STATUS DecodePipeline::ExecuteActivePackets()
270 {
271 DECODE_FUNC_CALL();
272 MOS_TraceEventExt(EVENT_PIPE_EXE, EVENT_TYPE_START, nullptr, 0, nullptr, 0);
273
274 // Last element in m_activePacketList must be immediately submitted
275 m_activePacketList.back().immediateSubmit = true;
276
277 for (PacketProperty prop : m_activePacketList)
278 {
279 prop.stateProperty.singleTaskPhaseSupported = m_singleTaskPhaseSupported;
280 prop.stateProperty.statusReport = m_statusReport;
281 MOS_TraceEventExt(EVENT_PIPE_EXE, EVENT_TYPE_INFO, &prop.packetId, sizeof(uint32_t), nullptr, 0);
282
283 MediaTask *task = prop.packet->GetActiveTask();
284 DECODE_CHK_STATUS(task->AddPacket(&prop));
285 if (prop.immediateSubmit)
286 {
287 DECODE_CHK_STATUS(task->Submit(true, m_scalability, m_debugInterface));
288 }
289 }
290
291 m_activePacketList.clear();
292 MOS_TraceEventExt(EVENT_PIPE_EXE, EVENT_TYPE_END, nullptr, 0, nullptr, 0);
293 return MOS_STATUS_SUCCESS;
294 }
295
IsCompleteBitstream()296 bool DecodePipeline::IsCompleteBitstream()
297 {
298 return (m_bitstream == nullptr) ? false : m_bitstream->IsComplete();
299 }
300
301 #ifdef _DECODE_PROCESSING_SUPPORTED
IsDownSamplingSupported()302 bool DecodePipeline::IsDownSamplingSupported()
303 {
304 DECODE_ASSERT(m_subPacketManager != nullptr);
305
306 DecodeDownSamplingPkt *downSamplingPkt = dynamic_cast<DecodeDownSamplingPkt *>(
307 GetSubPacket(DecodePacketId(this, downSamplingSubPacketId)));
308 if (downSamplingPkt == nullptr)
309 {
310 return false;
311 }
312
313 return downSamplingPkt->IsSupported();
314 }
315 #endif
316
GetDummyReference()317 MOS_SURFACE* DecodePipeline::GetDummyReference()
318 {
319 auto* feature = dynamic_cast<DecodeBasicFeature*>(m_featureManager->GetFeature(FeatureIDs::basicFeature));
320 return (feature != nullptr) ? &(feature->m_dummyReference) : nullptr;
321 }
322
GetDummyReferenceStatus()323 CODECHAL_DUMMY_REFERENCE_STATUS DecodePipeline::GetDummyReferenceStatus()
324 {
325 auto* feature = dynamic_cast<DecodeBasicFeature*>(m_featureManager->GetFeature(FeatureIDs::basicFeature));
326 return (feature != nullptr) ? feature->m_dummyReferenceStatus : CODECHAL_DUMMY_REFERENCE_INVALID;
327 }
328
SetDummyReferenceStatus(CODECHAL_DUMMY_REFERENCE_STATUS status)329 void DecodePipeline::SetDummyReferenceStatus(CODECHAL_DUMMY_REFERENCE_STATUS status)
330 {
331 auto* feature = dynamic_cast<DecodeBasicFeature*>(m_featureManager->GetFeature(FeatureIDs::basicFeature));
332 if (feature != nullptr)
333 {
334 feature->m_dummyReferenceStatus = status;
335 }
336 }
337
338 #if USE_CODECHAL_DEBUG_TOOL
339 #ifdef _DECODE_PROCESSING_SUPPORTED
DumpDownSamplingParams(DecodeDownSamplingFeature & downSamplingParams)340 MOS_STATUS DecodePipeline::DumpDownSamplingParams(DecodeDownSamplingFeature &downSamplingParams)
341 {
342 CODECHAL_DEBUG_FUNCTION_ENTER;
343 if (!m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrDecodeProcParams))
344 {
345 return MOS_STATUS_SUCCESS;
346 }
347
348 if(!downSamplingParams.IsEnabled())
349 {
350 return MOS_STATUS_SUCCESS;
351 }
352
353 DECODE_CHK_NULL(downSamplingParams.m_inputSurface);
354
355 std::ostringstream oss;
356 oss.setf(std::ios::showbase | std::ios::uppercase);
357
358 oss << "Input Surface Resolution: "
359 << +downSamplingParams.m_inputSurface->dwWidth << " x " << +downSamplingParams.m_inputSurface->dwHeight << std::endl;
360 oss << "Input Region Resolution: "
361 << +downSamplingParams.m_inputSurfaceRegion.m_width << " x " << +downSamplingParams.m_inputSurfaceRegion.m_height << std::endl;
362 oss << "Input Region Offset: ("
363 << +downSamplingParams.m_inputSurfaceRegion.m_x << "," << +downSamplingParams.m_inputSurfaceRegion.m_y << ")" << std::endl;
364 oss << "Input Surface Format: "
365 << (downSamplingParams.m_inputSurface->Format == Format_NV12 ? "NV12" : "P010" )<< std::endl;
366 oss << "Output Surface Resolution: "
367 << +downSamplingParams.m_outputSurface.dwWidth << " x " << +downSamplingParams.m_outputSurface.dwHeight << std::endl;
368 oss << "Output Region Resolution: "
369 << +downSamplingParams.m_outputSurfaceRegion.m_width << " x " << +downSamplingParams.m_outputSurfaceRegion.m_height << std::endl;
370 oss << "Output Region Offset: ("
371 << +downSamplingParams.m_outputSurfaceRegion.m_x << ", " << +downSamplingParams.m_outputSurfaceRegion.m_y << ")" << std::endl;
372 oss << "Output Surface Format: "
373 << (downSamplingParams.m_outputSurface.Format == Format_NV12 ? "NV12" : "YUY2" )<< std::endl;
374
375 const char* filePath = m_debugInterface->CreateFileName(
376 "_DEC",
377 CodechalDbgBufferType::bufDecProcParams,
378 CodechalDbgExtType::txt);
379
380 std::ofstream ofs(filePath, std::ios::out);
381 ofs << oss.str();
382 ofs.close();
383
384 return MOS_STATUS_SUCCESS;
385 }
386 #endif
387
DumpOutput(const DecodeStatusReportData & reportData)388 MOS_STATUS DecodePipeline::DumpOutput(const DecodeStatusReportData& reportData)
389 {
390 DECODE_FUNC_CALL();
391
392 if (m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrDecodeOutputSurface))
393 {
394 MOS_SURFACE dstSurface;
395 MOS_ZeroMemory(&dstSurface, sizeof(dstSurface));
396 dstSurface.Format = Format_NV12;
397 dstSurface.OsResource = reportData.currDecodedPicRes;
398 DECODE_CHK_STATUS(m_allocator->GetSurfaceInfo(&dstSurface));
399
400 DECODE_CHK_STATUS(m_debugInterface->DumpYUVSurface(
401 &dstSurface, CodechalDbgAttr::attrDecodeOutputSurface, "DstSurf"));
402 }
403
404 #ifdef _DECODE_PROCESSING_SUPPORTED
405 DecodeDownSamplingFeature* downSamplingFeature = dynamic_cast<DecodeDownSamplingFeature*>(
406 m_featureManager->GetFeature(DecodeFeatureIDs::decodeDownSampling));
407 if (downSamplingFeature != nullptr && downSamplingFeature->IsEnabled())
408 {
409 if (reportData.currSfcOutputPicRes != nullptr &&
410 m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrSfcOutputSurface))
411 {
412 MOS_SURFACE sfcDstSurface;
413 MOS_ZeroMemory(&sfcDstSurface, sizeof(sfcDstSurface));
414 sfcDstSurface.Format = Format_NV12;
415 sfcDstSurface.OsResource = *reportData.currSfcOutputPicRes;
416
417 if (!Mos_ResourceIsNull(&sfcDstSurface.OsResource))
418 {
419 DECODE_CHK_STATUS(m_allocator->GetSurfaceInfo(&sfcDstSurface));
420 DECODE_CHK_STATUS(m_debugInterface->DumpYUVSurface(
421 &sfcDstSurface, CodechalDbgAttr::attrSfcOutputSurface, "SfcDstSurf"));
422
423 #if (_DEBUG || _RELEASE_INTERNAL)
424 //rgb format read from reg key
425 uint32_t sfcOutputRgbFormatFlag =
426 ReadUserFeature(__MEDIA_USER_FEATURE_VALUE_DECODE_SFC_RGBFORMAT_OUTPUT_DEBUG_ID, m_osInterface->pOsContext).u32Data;
427
428 if (sfcOutputRgbFormatFlag)
429 {
430 DECODE_CHK_STATUS(m_debugInterface->DumpRgbDataOnYUVSurface(
431 &sfcDstSurface, CodechalDbgAttr::attrSfcOutputSurface, "SfcDstRgbSurf"));
432 }
433 #endif
434 }
435 }
436
437 if (reportData.currHistogramOutBuf != nullptr &&
438 !Mos_ResourceIsNull(reportData.currHistogramOutBuf))
439 {
440 DECODE_CHK_STATUS(m_debugInterface->DumpBuffer(
441 reportData.currHistogramOutBuf,
442 CodechalDbgAttr::attrSfcHistogram,
443 "_DEC",
444 HISTOGRAM_BINCOUNT * downSamplingFeature->m_histogramBinWidth));
445 }
446 }
447 #endif
448
449 return MOS_STATUS_SUCCESS;
450 }
451 #endif
452
453 #if MOS_EVENT_TRACE_DUMP_SUPPORTED
TraceDataDumpOutput(const DecodeStatusReportData & reportData)454 MOS_STATUS DecodePipeline::TraceDataDumpOutput(const DecodeStatusReportData &reportData)
455 {
456 bool bAllocate = false;
457 MOS_SURFACE dstSurface;
458 MOS_ZeroMemory(&dstSurface, sizeof(dstSurface));
459 dstSurface.OsResource = reportData.currDecodedPicRes;
460 DECODE_CHK_STATUS(m_allocator->GetSurfaceInfo(&dstSurface));
461
462 DECODE_EVENTDATA_YUV_SURFACE_INFO eventData =
463 {
464 (uint32_t)reportData.currDecodedPic.PicFlags,
465 dstSurface.dwOffset,
466 dstSurface.YPlaneOffset.iYOffset,
467 dstSurface.dwPitch,
468 dstSurface.dwWidth,
469 dstSurface.dwHeight,
470 (uint32_t)dstSurface.Format,
471 dstSurface.UPlaneOffset.iLockSurfaceOffset,
472 dstSurface.VPlaneOffset.iLockSurfaceOffset,
473 dstSurface.UPlaneOffset.iSurfaceOffset,
474 dstSurface.VPlaneOffset.iSurfaceOffset,
475 };
476 MOS_TraceEvent(EVENT_DECODE_SURFACE_DUMPINFO, EVENT_TYPE_INFO, &eventData, sizeof(eventData), NULL, 0);
477
478 if (!m_allocator->ResourceIsNull(&dstSurface.OsResource))
479 {
480 if (m_tempOutputSurf == nullptr || m_allocator->ResourceIsNull(&m_tempOutputSurf->OsResource))
481 {
482 bAllocate = true;
483 }
484 else if (m_tempOutputSurf->dwWidth < dstSurface.dwWidth ||
485 m_tempOutputSurf->dwHeight < dstSurface.dwHeight)
486 {
487 bAllocate = true;
488 }
489 else
490 {
491 bAllocate = false;
492 }
493
494 if (bAllocate)
495 {
496 if (!m_allocator->ResourceIsNull(&m_tempOutputSurf->OsResource))
497 {
498 m_allocator->Destroy(m_tempOutputSurf);
499 }
500
501 m_tempOutputSurf = m_allocator->AllocateLinearSurface(
502 dstSurface.dwWidth,
503 dstSurface.dwHeight,
504 "Decode Output Surf",
505 dstSurface.Format,
506 dstSurface.bIsCompressed,
507 resourceOutputPicture,
508 lockableSystemMem,
509 MOS_TILE_LINEAR_GMM);
510 }
511
512 DECODE_CHK_STATUS(m_osInterface->pfnDoubleBufferCopyResource(
513 m_osInterface,
514 &dstSurface.OsResource,
515 &m_tempOutputSurf->OsResource,
516 false));
517
518 ResourceAutoLock resLock(m_allocator, &m_tempOutputSurf->OsResource);
519 auto pData = (uint8_t *)resLock.LockResourceForRead();
520
521 MOS_TraceDataDump(
522 "Decode_OutputSurf",
523 0,
524 pData,
525 (uint32_t)m_tempOutputSurf->OsResource.pGmmResInfo->GetSizeMainSurface());
526 }
527
528 return MOS_STATUS_SUCCESS;
529 }
530
TraceDataDump2ndLevelBB(PMHW_BATCH_BUFFER batchBuffer)531 MOS_STATUS DecodePipeline::TraceDataDump2ndLevelBB(PMHW_BATCH_BUFFER batchBuffer)
532 {
533 DECODE_FUNC_CALL();
534
535 DECODE_CHK_NULL(batchBuffer);
536 batchBuffer->iLastCurrent = batchBuffer->iSize * batchBuffer->count;
537 batchBuffer->dwOffset = 0;
538
539 DECODE_CHK_STATUS(m_osInterface->pfnDumpTraceGpuData(
540 m_osInterface,
541 "Decode_2ndLevelCmdBB",
542 0,
543 &batchBuffer->OsResource,
544 batchBuffer->iLastCurrent));
545
546 return MOS_STATUS_SUCCESS;
547 }
548 #endif
549
550 #if (_DEBUG || _RELEASE_INTERNAL)
ReportVdboxIds(const DecodeStatusMfx & status)551 MOS_STATUS DecodePipeline::ReportVdboxIds(const DecodeStatusMfx& status)
552 {
553 DECODE_FUNC_CALL();
554
555 // report the VDBOX IDs to user feature
556 uint32_t vdboxIds = ReadUserFeature(__MEDIA_USER_FEATURE_VALUE_VDBOX_ID_USED, m_osInterface->pOsContext).u32Data;
557
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.currSfcOutputPicRes != nullptr)
588 {
589 MOS_SURFACE sfcDstSurface;
590 MOS_ZeroMemory(&sfcDstSurface, sizeof(sfcDstSurface));
591 sfcDstSurface.Format = Format_NV12;
592 sfcDstSurface.OsResource = *reportData.currSfcOutputPicRes;
593 if (!Mos_ResourceIsNull(&sfcDstSurface.OsResource))
594 {
595 DECODE_CHK_STATUS(m_allocator->GetSurfaceInfo(&sfcDstSurface));
596 if (sfcDstSurface.TileType == MOS_TILE_LINEAR)
597 {
598 WriteUserFeature(__MEDIA_USER_FEATURE_VALUE_SFC_LINEAR_OUTPUT_USED_ID, 1, m_osInterface->pOsContext);
599 }
600 else
601 {
602 WriteUserFeature(__MEDIA_USER_FEATURE_VALUE_SFC_LINEAR_OUTPUT_USED_ID, 0, m_osInterface->pOsContext);
603 }
604 }
605 }
606 }
607 return MOS_STATUS_SUCCESS;
608 }
609 #endif
610
StatusCheck()611 MOS_STATUS DecodePipeline::StatusCheck()
612 {
613 DECODE_FUNC_CALL();
614
615 uint32_t completedCount = m_statusReport->GetCompletedCount();
616 if (completedCount <= m_statusCheckCount)
617 {
618 DECODE_CHK_COND(completedCount < m_statusCheckCount, "Invalid status check count");
619 return MOS_STATUS_SUCCESS;
620 }
621
622 DecodeStatusReport* statusReport = dynamic_cast<DecodeStatusReport*>(m_statusReport);
623 DECODE_CHK_NULL(statusReport);
624
625 while (m_statusCheckCount < completedCount)
626 {
627 const DecodeStatusMfx& status = statusReport->GetMfxStatus(m_statusCheckCount);
628 if (status.status != DecodeStatusReport::queryEnd)
629 {
630 DECODE_NORMALMESSAGE("Media reset may have occured at frame %d, status is %d, completedCount is %d.",
631 m_statusCheckCount, status.status, completedCount);
632 }
633
634 DECODE_NORMALMESSAGE("hucStatus2 is 0x%x at frame %d.", status.m_hucErrorStatus2, m_statusCheckCount);
635 DECODE_NORMALMESSAGE("hucStatus is 0x%x at frame %d.", status.m_hucErrorStatus, m_statusCheckCount);
636
637 DECODE_CHK_STATUS(HwStatusCheck(status));
638
639 DECODE_CHK_STATUS(ReportVdboxIds(status));
640
641 #if USE_CODECHAL_DEBUG_TOOL
642 const DecodeStatusReportData& reportData = statusReport->GetReportData(m_statusCheckCount);
643
644 auto bufferDumpNumTemp = m_debugInterface->m_bufferDumpFrameNum;
645 auto currPicTemp = m_debugInterface->m_currPic;
646 auto frameTypeTemp = m_debugInterface->m_frameType;
647
648 m_debugInterface->m_bufferDumpFrameNum = m_statusCheckCount;
649 m_debugInterface->m_currPic = reportData.currDecodedPic;
650 m_debugInterface->m_frameType = reportData.frameType;
651 #ifdef _DECODE_PROCESSING_SUPPORTED
652 ReportSfcLinearSurfaceUsage(reportData);
653 #endif
654 DECODE_CHK_STATUS(DumpOutput(reportData));
655
656 m_debugInterface->m_bufferDumpFrameNum = bufferDumpNumTemp;
657 m_debugInterface->m_currPic = currPicTemp;
658 m_debugInterface->m_frameType = frameTypeTemp;
659 #endif
660
661 #if MOS_EVENT_TRACE_DUMP_SUPPORTED
662 if (MOS_GetTraceEventKeyword() & EVENT_DECODE_DSTYUV_KEYWORD)
663 {
664 DECODE_CHK_STATUS(TraceDataDumpOutput(reportData));
665 }
666 #endif
667
668 m_statusCheckCount++;
669 }
670
671 return MOS_STATUS_SUCCESS;
672 }
673 #endif
674
675 }
676