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_hevc_pipeline_m12.cpp
24 //! \brief    Defines the interface for hevc decode pipeline
25 //!
26 #include "decode_hevc_pipeline_m12.h"
27 #include "decode_huc_s2l_packet_m12.h"
28 #include "decode_hevc_packet_front_end_m12.h"
29 #include "decode_hevc_packet_back_end_m12.h"
30 #include "decode_hevc_packet_real_tile_m12.h"
31 #include "decode_hevc_picture_packet_m12.h"
32 #include "decode_hevc_slice_packet_m12.h"
33 #include "decode_utils.h"
34 #include "decode_common_feature_defs.h"
35 #include "decode_hevc_mem_compression_m12.h"
36 #include "decode_sfc_histogram_postsubpipeline_m12.h"
37 #include "decode_hevc_feature_manager.h"
38 #include "decode_input_bitstream_m12.h"
39 #include "decode_cp_bitstream_m12.h"
40 #include "decode_hevc_downsampling_packet.h"
41 #include "decode_marker_packet_g12.h"
42 #include "decode_predication_packet_g12.h"
43 #include "mos_interface.h"
44 
45 namespace decode {
46 
HevcPipelineM12(CodechalHwInterface * hwInterface,CodechalDebugInterface * debugInterface)47 HevcPipelineM12::HevcPipelineM12(CodechalHwInterface *hwInterface, CodechalDebugInterface *debugInterface)
48     : HevcPipeline(*hwInterface, debugInterface)
49 {
50     m_hwInterface = hwInterface;
51 }
52 
Init(void * settings)53 MOS_STATUS HevcPipelineM12::Init(void *settings)
54 {
55     DECODE_FUNC_CALL();
56     DECODE_CHK_NULL(settings);
57 
58     DECODE_CHK_STATUS(Initialize(settings));
59 
60     if (m_basicFeature->m_shortFormatInUse)
61     {
62         HucS2lPktM12 *hucS2lPkt = MOS_New(HucS2lPktM12, this, m_task, m_hwInterface);
63         DECODE_CHK_NULL(hucS2lPkt);
64         DECODE_CHK_STATUS(RegisterPacket(DecodePacketId(this, hucS2lPacketId), hucS2lPkt));
65         DECODE_CHK_STATUS(hucS2lPkt->Init());
66     }
67 
68     m_hevcDecodePktLong = MOS_New(HevcDecodeLongPktM12, this, m_task, m_hwInterface);
69     DECODE_CHK_NULL(m_hevcDecodePktLong);
70     DECODE_CHK_STATUS(RegisterPacket(DecodePacketId(this, hevcLongPacketId), m_hevcDecodePktLong));
71     DECODE_CHK_STATUS(m_hevcDecodePktLong->Init());
72 
73     auto hevcDecodePktFrontEnd = MOS_New(HevcDecodeFrontEndPktM12, this, m_task, m_hwInterface);
74     DECODE_CHK_NULL(hevcDecodePktFrontEnd);
75     DECODE_CHK_STATUS(RegisterPacket(DecodePacketId(this, hevcFrontEndPacketId), hevcDecodePktFrontEnd));
76     DECODE_CHK_STATUS(hevcDecodePktFrontEnd->Init());
77 
78     auto hevcDecodePktBackEnd = MOS_New(HevcDecodeBackEndPktM12, this, m_task, m_hwInterface);
79     DECODE_CHK_NULL(hevcDecodePktBackEnd);
80     DECODE_CHK_STATUS(RegisterPacket(DecodePacketId(this, hevcBackEndPacketId), hevcDecodePktBackEnd));
81     DECODE_CHK_STATUS(hevcDecodePktBackEnd->Init());
82 
83     auto hevcDecodePktRealTile = MOS_New(HevcDecodeRealTilePktM12, this, m_task, m_hwInterface);
84     DECODE_CHK_NULL(hevcDecodePktRealTile);
85     DECODE_CHK_STATUS(RegisterPacket(DecodePacketId(this, hevcRealTilePacketId), hevcDecodePktRealTile));
86     DECODE_CHK_STATUS(hevcDecodePktRealTile->Init());
87 
88     if (m_numVdbox == 2)
89     {
90         m_allowVirtualNodeReassign = true;
91     }
92 
93     return MOS_STATUS_SUCCESS;
94 }
95 
InitContexOption(HevcScalabilityPars & scalPars)96 MOS_STATUS HevcPipelineM12::InitContexOption(HevcScalabilityPars &scalPars)
97 {
98     scalPars.usingHcp           = true;
99     scalPars.enableVE           = MOS_VE_SUPPORTED(m_osInterface);
100     scalPars.disableScalability = m_hwInterface->IsDisableScalability();
101     bool isMultiDevices = false, isMultiEngine = false;
102     m_osInterface->pfnGetMultiEngineStatus(m_osInterface, nullptr, COMPONENT_Encode, isMultiDevices, isMultiEngine);
103     if (isMultiDevices && !isMultiEngine)
104     {
105         scalPars.disableScalability = true;
106     }
107 
108 #if (_DEBUG || _RELEASE_INTERNAL)
109     if (m_osInterface->bHcpDecScalabilityMode == MOS_SCALABILITY_ENABLE_MODE_FALSE)
110     {
111         scalPars.disableScalability = true;
112     }
113     else if (m_osInterface->bHcpDecScalabilityMode == MOS_SCALABILITY_ENABLE_MODE_USER_FORCE)
114     {
115         scalPars.disableScalability = false;
116     }
117     scalPars.modeSwithThreshold1 =
118         ReadUserFeature(m_userSettingPtr, "HCP Decode Mode Switch TH1", MediaUserSetting::Group::Sequence).Get<uint32_t>();
119     scalPars.modeSwithThreshold2 =
120         ReadUserFeature(m_userSettingPtr, "HCP Decode Mode Switch TH2", MediaUserSetting::Group::Sequence).Get<uint32_t>();
121     scalPars.forceMultiPipe =
122         ReadUserFeature(m_userSettingPtr, "HCP Decode Always Frame Split", MediaUserSetting::Group::Sequence).Get<bool>();
123 #endif
124 
125     if (!scalPars.disableScalability)
126         m_osInterface->pfnSetMultiEngineEnabled(m_osInterface, COMPONENT_Decode, true);
127 
128     return MOS_STATUS_SUCCESS;
129 }
130 
131 #if (_DEBUG || _RELEASE_INTERNAL)
HwStatusCheck(const DecodeStatusMfx & status)132 MOS_STATUS HevcPipelineM12::HwStatusCheck(const DecodeStatusMfx &status)
133 {
134     DECODE_FUNC_CALL();
135 
136     if (m_basicFeature->m_shortFormatInUse)
137     {
138         // Check HuC_status2 Imem loaded bit, if 0, return error
139         if (((status.m_hucErrorStatus2 >> 32) && (m_hwInterface->GetHucInterface()->GetHucStatus2ImemLoadedMask())) == 0)
140         {
141             if (!m_reportHucStatus)
142             {
143                 WriteUserFeature(__MEDIA_USER_FEATURE_VALUE_HUC_LOAD_STATUS_ID, 1, m_osInterface->pOsContext);
144                 m_reportHucStatus = true;
145             }
146             DECODE_ASSERTMESSAGE("Huc IMEM Loaded fails");
147             MT_ERR1(MT_DEC_HEVC, MT_DEC_HUC_ERROR_STATUS2, (status.m_hucErrorStatus2 >> 32));
148         }
149 
150         // Check Huc_status None Critical Error bit, bit 15. If 0, return error.
151         if (((status.m_hucErrorStatus >> 32) & m_hwInterface->GetHucInterface()->GetHucStatusHevcS2lFailureMask()) == 0)
152         {
153             if (!m_reportHucCriticalError)
154             {
155                 WriteUserFeature(__MEDIA_USER_FEATURE_VALUE_HUC_REPORT_CRITICAL_ERROR_ID, 1, m_osInterface->pOsContext);
156                 m_reportHucCriticalError = true;
157             }
158             DECODE_ASSERTMESSAGE("Huc Report Critical Error!");
159             MT_ERR1(MT_DEC_HEVC, MT_DEC_HUC_STATUS_CRITICAL_ERROR, (status.m_hucErrorStatus >> 32));
160         }
161     }
162 
163     return MOS_STATUS_SUCCESS;
164 }
165 #endif
166 
InitScalabOption(HevcBasicFeature & basicFeature)167 MOS_STATUS HevcPipelineM12::InitScalabOption(HevcBasicFeature &basicFeature)
168 {
169     DECODE_FUNC_CALL();
170 
171     PCODEC_HEVC_PIC_PARAMS picParams = basicFeature.m_hevcPicParams;
172     DECODE_CHK_NULL(picParams);
173 
174     HevcScalabilityPars scalPars;
175     MOS_ZeroMemory(&scalPars, sizeof(scalPars));
176     DECODE_CHK_STATUS(InitContexOption(scalPars));
177     scalPars.isSCC         = (basicFeature.m_hevcSccPicParams != nullptr);
178 #ifdef _DECODE_PROCESSING_SUPPORTED
179     DecodeDownSamplingFeature* downSamplingFeature = dynamic_cast<DecodeDownSamplingFeature*>(
180         m_featureManager->GetFeature(DecodeFeatureIDs::decodeDownSampling));
181     if (downSamplingFeature != nullptr && downSamplingFeature->IsEnabled())
182     {
183         scalPars.usingSfc = true;
184         if (!MEDIA_IS_SKU(m_skuTable, FtrSfcScalability))
185         {
186             scalPars.disableScalability = true;
187         }
188     }
189     //Disable Scalability when histogram is enabled
190     if (downSamplingFeature != nullptr && (downSamplingFeature->m_histogramDestSurf || downSamplingFeature->m_histogramDebug))
191     {
192         scalPars.disableScalability = true;
193     }
194 #endif
195     scalPars.maxTileColumn = HEVC_NUM_MAX_TILE_COLUMN;
196     scalPars.maxTileRow    = HEVC_NUM_MAX_TILE_ROW;
197 #if (_DEBUG || _RELEASE_INTERNAL)
198     scalPars.disableRealTile =
199         ReadUserFeature(m_userSettingPtr, "Disable HEVC Real Tile Decode", MediaUserSetting::Group::Sequence).Get<bool>();
200     bool enableRealTileMultiPhase =
201         ReadUserFeature(m_userSettingPtr, "Enable HEVC Real Tile Multi Phase Decode", MediaUserSetting::Group::Sequence).Get<bool>();
202         if (!enableRealTileMultiPhase)
203     {
204         scalPars.maxTileColumn = 2;
205     }
206 
207     scalPars.userPipeNum =
208         uint8_t(ReadUserFeature(m_userSettingPtr, "HCP Decode User Pipe Num", MediaUserSetting::Group::Sequence).Get<uint32_t>());
209 #endif
210     // Long format real tile requires subset params
211     if (!basicFeature.m_shortFormatInUse && basicFeature.m_hevcSubsetParams == nullptr)
212     {
213         scalPars.disableRealTile = true;
214     }
215 
216     if (MEDIA_IS_SKU(m_skuTable, FtrVirtualTileScalabilityDisable))
217     {
218         scalPars.disableVirtualTile = true;
219     }
220 
221     scalPars.surfaceFormat  = basicFeature.m_destSurface.Format;
222     scalPars.frameWidth     = basicFeature.m_width;
223     scalPars.frameHeight    = basicFeature.m_height;
224     scalPars.numVdbox       = m_numVdbox;
225     scalPars.numTileRows    = picParams->tiles_enabled_flag ?
226                                 (picParams->num_tile_rows_minus1 + 1) : 0;
227     scalPars.numTileColumns = picParams->tiles_enabled_flag ?
228                                 (picParams->num_tile_columns_minus1 + 1) : 0;
229 
230     // HEVC 422 8b/10b && <8k - disable virtual tile sclability
231     if (MEDIA_IS_SKU(m_skuTable, FtrDecodeHEVC422VTScalaDisable))
232     {
233         if ((scalPars.surfaceFormat == Format_YUY2 || scalPars.surfaceFormat == Format_Y210) &&
234             ((scalPars.frameWidth * scalPars.frameHeight) < (7680 * 4320)))
235         {
236             scalPars.disableVirtualTile = true;
237             SCALABILITY_VERBOSEMESSAGE("HEVC 422 && Resolution < 8k - Disable VT Scalability ");
238         }
239     }
240 
241     DECODE_CHK_STATUS(m_scalabOption.SetScalabilityOption(&scalPars));
242 
243     return MOS_STATUS_SUCCESS;
244 }
245 
AllocateResources(HevcBasicFeature & basicFeature)246 MOS_STATUS HevcPipelineM12::AllocateResources(HevcBasicFeature &basicFeature)
247 {
248     DECODE_FUNC_CALL();
249 
250     PCODEC_HEVC_PIC_PARAMS picParams = basicFeature.m_hevcPicParams;
251     DECODE_CHK_NULL(picParams);
252 
253     uint32_t sliceStatesSize    = 0;
254     uint32_t slicePatchListSize = 0;
255     DECODE_CHK_STATUS(m_hwInterface->GetHcpPrimitiveCommandSize(
256         CODECHAL_DECODE_MODE_HEVCVLD, &sliceStatesSize, &slicePatchListSize, false));
257 
258     uint32_t count, size;
259     if (realTileDecodeMode == m_decodeMode)
260     {
261         count = picParams->num_tile_columns_minus1 + 1;
262         size = sliceStatesSize * (basicFeature.m_numSlices + 1 + picParams->num_tile_rows_minus1);
263     }
264     else if (separateTileDecodeMode == m_decodeMode)
265     {
266         count = 1;
267         uint32_t tileNum = (1 + picParams->num_tile_rows_minus1) *
268                            (1 + picParams->num_tile_columns_minus1);
269         size = sliceStatesSize * (basicFeature.m_numSlices + tileNum);
270     }
271     else
272     {
273         count = 1;
274         size = sliceStatesSize * basicFeature.m_numSlices;
275     }
276 
277     // In hevc short format decode, second level command buffer is programmed by Huc, so not need lock it.
278     // In against hevc long format decode driver have to program second level command buffer, so it should
279     // be lockable.
280     if (m_secondLevelBBArray == nullptr)
281     {
282         m_secondLevelBBArray = m_allocator->AllocateBatchBufferArray(
283             size, count, m_secondLevelBBNum, true, basicFeature.m_shortFormatInUse ? notLockableVideoMem : lockableVideoMem);
284         DECODE_CHK_NULL(m_secondLevelBBArray);
285         PMHW_BATCH_BUFFER &batchBuf = m_secondLevelBBArray->Fetch();
286         DECODE_CHK_NULL(batchBuf);
287     }
288     else
289     {
290         PMHW_BATCH_BUFFER &batchBuf = m_secondLevelBBArray->Fetch();
291         DECODE_CHK_NULL(batchBuf);
292         DECODE_CHK_STATUS(m_allocator->Resize(
293             batchBuf, size, count, basicFeature.m_shortFormatInUse ? notLockableVideoMem : lockableVideoMem));
294     }
295 
296     return MOS_STATUS_SUCCESS;
297 }
298 
Prepare(void * params)299 MOS_STATUS HevcPipelineM12::Prepare(void *params)
300 {
301     DECODE_FUNC_CALL();
302 
303     DECODE_CHK_NULL(params);
304     DecodePipelineParams *pipelineParams = (DecodePipelineParams *)params;
305     m_pipeMode = pipelineParams->m_pipeMode;
306 
307     PERF_UTILITY_AUTO((__FUNCTION__ + std::to_string((int)m_pipeMode)).c_str(), PERF_DECODE, PERF_LEVEL_HAL);
308 
309     if (IsFirstProcessPipe(*pipelineParams))
310     {
311         DECODE_CHK_STATUS(HevcPipeline::Prepare(params));
312         DECODE_CHK_STATUS(HevcPipeline::DestoryPhaseList());
313     }
314 
315     DECODE_CHK_STATUS(m_preSubPipeline->Prepare(*pipelineParams));
316     DECODE_CHK_STATUS(m_postSubPipeline->Prepare(*pipelineParams));
317 
318     if (m_pipeMode == decodePipeModeProcess)
319     {
320         if (IsCompleteBitstream())
321         {
322             if (m_pCodechalOcaDumper)
323             {
324                 m_pCodechalOcaDumper->SetHevcDecodeParam(
325                     m_basicFeature->m_hevcPicParams,
326                     m_basicFeature->m_hevcRextPicParams,
327                     m_basicFeature->m_hevcSccPicParams,
328                     m_basicFeature->m_hevcSliceParams,
329                     m_basicFeature->m_hevcRextSliceParams,
330                     m_basicFeature->m_numSlices,
331                     m_basicFeature->m_shortFormatInUse);
332             }
333 
334             CODECHAL_DEBUG_TOOL(
335                 m_debugInterface->m_bufferDumpFrameNum = m_basicFeature->m_frameNum;
336                 DECODE_CHK_STATUS(DumpParams(*m_basicFeature))
337                 );
338 
339             DecodeStatusParameters inputParameters = {};
340             MOS_ZeroMemory(&inputParameters, sizeof(DecodeStatusParameters));
341             inputParameters.statusReportFeedbackNumber = m_basicFeature->m_hevcPicParams->StatusReportFeedbackNumber;
342             inputParameters.pictureCodingType          = m_basicFeature->m_pictureCodingType;
343             inputParameters.codecFunction              = m_basicFeature->m_codecFunction;
344             inputParameters.picWidthInMb               = m_basicFeature->m_picWidthInMb;
345             inputParameters.currOriginalPic            = m_basicFeature->m_curRenderPic;
346             inputParameters.numUsedVdbox               = m_numVdbox;
347             inputParameters.numSlices                  = m_basicFeature->m_numSlices;
348             inputParameters.currDecodedPicRes          = m_basicFeature->m_destSurface.OsResource;
349 
350             CODECHAL_DEBUG_TOOL(
351                 if (m_streamout != nullptr)
352                 {
353                     DECODE_CHK_STATUS(m_streamout->InitStatusReportParam(inputParameters));
354                 }
355             );
356 
357 #if (_DEBUG || _RELEASE_INTERNAL)
358 #ifdef _DECODE_PROCESSING_SUPPORTED
359             DecodeDownSamplingFeature* downSamplingFeature = dynamic_cast<DecodeDownSamplingFeature*>(
360                 m_featureManager->GetFeature(DecodeFeatureIDs::decodeDownSampling));
361             if (downSamplingFeature != nullptr)
362             {
363                 auto frameIdx = m_basicFeature->m_curRenderPic.FrameIdx;
364                 inputParameters.sfcOutputSurface = &downSamplingFeature->m_outputSurfaceList[frameIdx];
365                 if (downSamplingFeature->m_histogramBuffer != nullptr)
366                 {
367                     inputParameters.histogramOutputBuf = &downSamplingFeature->m_histogramBuffer->OsResource;
368                 }
369                 CODECHAL_DEBUG_TOOL(DumpDownSamplingParams(*downSamplingFeature));
370             }
371 #endif
372 #endif
373             m_statusReport->Init(&inputParameters);
374         }
375     }
376 
377     return MOS_STATUS_SUCCESS;
378 }
379 
Execute()380 MOS_STATUS HevcPipelineM12::Execute()
381 {
382     DECODE_FUNC_CALL();
383 
384     PERF_UTILITY_AUTO((__FUNCTION__ + std::to_string((int)m_pipeMode)).c_str(), PERF_DECODE, PERF_LEVEL_HAL);
385 
386     if (m_pipeMode == decodePipeModeProcess)
387     {
388         DECODE_CHK_STATUS(m_preSubPipeline->Execute());
389 
390         if (IsCompleteBitstream())
391         {
392             DECODE_CHK_STATUS(InitScalabOption(*m_basicFeature));
393             DECODE_CHK_STATUS(InitDecodeMode(m_scalabOption.GetMode(), *m_basicFeature));
394             if (m_decodeMode == realTileDecodeMode || m_decodeMode == separateTileDecodeMode)
395             {
396                 DECODE_CHK_STATUS(m_basicFeature->m_tileCoding.UpdateSliceTileInfo());
397             }
398 
399             DECODE_CHK_STATUS(AllocateResources(*m_basicFeature));
400             DECODE_CHK_STATUS(HevcPipeline::CreatePhaseList(
401                 *m_basicFeature, m_scalabOption.GetMode(), m_scalabOption.GetNumPipe()));
402             DECODE_CHK_STATUS(HevcPipeline::Execute());
403 
404 #if (_DEBUG || _RELEASE_INTERNAL)
405             DECODE_CHK_STATUS(StatusCheck());
406 #endif
407 
408             // Recover RefList for SCC IBC mode
409             DECODE_CHK_STATUS(StoreDestToRefList(*m_basicFeature));
410 
411             CODECHAL_DEBUG_TOOL(DECODE_CHK_STATUS(DumpSecondLevelBatchBuffer()));
412 
413             // Only update user features for first frame.
414             if (m_basicFeature->m_frameNum == 0)
415             {
416                 DECODE_CHK_STATUS(UserFeatureReport());
417             }
418 
419             DecodeFrameIndex++;
420             m_basicFeature->m_frameNum = DecodeFrameIndex;
421 
422             DECODE_CHK_STATUS(m_statusReport->Reset());
423 
424             DECODE_CHK_STATUS(DestoryPhaseList());
425         }
426         DECODE_CHK_STATUS(m_postSubPipeline->Execute());
427     }
428 
429     return MOS_STATUS_SUCCESS;
430 }
431 
GetStatusReport(void * status,uint16_t numStatus)432 MOS_STATUS HevcPipelineM12::GetStatusReport(void *status, uint16_t numStatus)
433 {
434     DECODE_FUNC_CALL();
435     m_statusReport->GetReport(numStatus, status);
436 
437     return MOS_STATUS_SUCCESS;
438 }
439 
Destroy()440 MOS_STATUS HevcPipelineM12::Destroy()
441 {
442     DECODE_FUNC_CALL();
443     DECODE_CHK_STATUS(m_allocator->Destroy(m_secondLevelBBArray));
444     DECODE_CHK_STATUS(Uninitialize());
445 
446     m_osInterface->pfnSetMultiEngineEnabled(m_osInterface, COMPONENT_Decode, false);
447 
448     return MOS_STATUS_SUCCESS;
449 }
450 
CreateFeatureManager()451 MOS_STATUS HevcPipelineM12::CreateFeatureManager()
452 {
453     DECODE_FUNC_CALL();
454     m_featureManager = MOS_New(DecodeHevcFeatureManager, m_allocator, m_hwInterface, m_osInterface);
455     DECODE_CHK_NULL(m_featureManager);
456     return MOS_STATUS_SUCCESS;
457 }
458 
Initialize(void * settings)459 MOS_STATUS HevcPipelineM12::Initialize(void *settings)
460 {
461     DECODE_FUNC_CALL();
462 
463     DECODE_CHK_NULL(settings);
464 
465     DECODE_CHK_STATUS(MediaPipeline::InitPlatform());
466     DECODE_CHK_STATUS(MediaPipeline::CreateMediaCopyWrapper());
467     DECODE_CHK_NULL(m_mediaCopyWrapper);
468 
469     DECODE_CHK_NULL(m_waTable);
470 
471     auto *codecSettings = (CodechalSetting *)settings;
472     DECODE_CHK_NULL(m_hwInterface);
473     DECODE_CHK_STATUS(m_hwInterface->Initialize(codecSettings));
474 
475     if (m_mediaCopyWrapper->MediaCopyStateIsNull())
476     {
477         m_mediaCopyWrapper->SetMediaCopyState(m_hwInterface->CreateMediaCopy(m_osInterface));
478     }
479 
480     CODECHAL_DEBUG_TOOL(
481         m_debugInterface = MOS_New(CodechalDebugInterface);
482         DECODE_CHK_NULL(m_debugInterface);
483         DECODE_CHK_STATUS(
484             m_debugInterface->Initialize(m_hwInterface, codecSettings->codecFunction, m_mediaCopyWrapper)););
485 
486     if (m_hwInterface->m_hwInterfaceNext)
487     {
488         m_hwInterface->m_hwInterfaceNext->legacyHwInterface = m_hwInterface;
489     }
490     m_mediaContext = MOS_New(MediaContext, scalabilityDecoder, m_hwInterface->m_hwInterfaceNext, m_osInterface);
491     DECODE_CHK_NULL(m_mediaContext);
492 
493     m_task = CreateTask(MediaTask::TaskType::cmdTask);
494     DECODE_CHK_NULL(m_task);
495 
496     m_numVdbox = GetSystemVdboxNumber();
497 
498     bool limitedLMemBar = MEDIA_IS_SKU(m_skuTable, FtrLimitedLMemBar) ? true : false;
499     m_allocator         = MOS_New(DecodeAllocator, m_osInterface, limitedLMemBar);
500     DECODE_CHK_NULL(m_allocator);
501 
502     DECODE_CHK_STATUS(CreateStatusReport());
503 
504     m_decodecp = Create_DecodeCpInterface(codecSettings, m_hwInterface->GetCpInterface(), m_hwInterface->GetOsInterface());
505     if (m_decodecp)
506     {
507         DECODE_CHK_STATUS(m_decodecp->RegisterParams(codecSettings));
508     }
509     DECODE_CHK_STATUS(CreateFeatureManager());
510     DECODE_CHK_STATUS(m_featureManager->Init(codecSettings));
511 
512     DECODE_CHK_STATUS(CreateSubPipeLineManager(codecSettings));
513     DECODE_CHK_STATUS(CreateSubPacketManager(codecSettings));
514 
515     // Create basic GPU context
516     DecodeScalabilityPars scalPars;
517     MOS_ZeroMemory(&scalPars, sizeof(scalPars));
518     DECODE_CHK_STATUS(m_mediaContext->SwitchContext(VdboxDecodeFunc, &scalPars, &m_scalability));
519     m_decodeContext = m_osInterface->pfnGetGpuContext(m_osInterface);
520 
521     m_basicFeature = dynamic_cast<HevcBasicFeature *>(m_featureManager->GetFeature(FeatureIDs::basicFeature));
522     DECODE_CHK_NULL(m_basicFeature);
523 
524 #ifdef _MMC_SUPPORTED
525     DECODE_CHK_STATUS(InitMmcState());
526 #endif
527 
528     return MOS_STATUS_SUCCESS;
529 }
530 
Uninitialize()531 MOS_STATUS HevcPipelineM12::Uninitialize()
532 {
533     DECODE_FUNC_CALL();
534 
535 #if (_DEBUG || _RELEASE_INTERNAL)
536     // Report real tile frame count and virtual tile frame count
537     MOS_USER_FEATURE_VALUE_WRITE_DATA userFeatureWriteData = __NULL_USER_FEATURE_VALUE_WRITE_DATA__;
538 
539     userFeatureWriteData.Value.i32Data = m_rtFrameCount;
540     userFeatureWriteData.ValueID = __MEDIA_USER_FEATURE_VALUE_ENABLE_HEVC_DECODE_RT_FRAME_COUNT_ID;
541     MOS_UserFeature_WriteValues_ID(nullptr, &userFeatureWriteData, 1, m_osInterface->pOsContext);
542 
543     userFeatureWriteData.Value.i32Data = m_vtFrameCount;
544     userFeatureWriteData.ValueID = __MEDIA_USER_FEATURE_VALUE_ENABLE_HEVC_DECODE_VT_FRAME_COUNT_ID;
545     MOS_UserFeature_WriteValues_ID(nullptr, &userFeatureWriteData, 1, m_osInterface->pOsContext);
546 
547     userFeatureWriteData.Value.i32Data = m_spFrameCount;
548     userFeatureWriteData.ValueID = __MEDIA_USER_FEATURE_VALUE_ENABLE_HEVC_DECODE_SP_FRAME_COUNT_ID;
549     MOS_UserFeature_WriteValues_ID(nullptr, &userFeatureWriteData, 1, m_osInterface->pOsContext);
550 #endif
551 
552     for (auto pair : m_packetList)
553     {
554         pair.second->Destroy();
555     }
556 
557 #ifdef _MMC_SUPPORTED
558     if (m_mmcState != nullptr)
559     {
560         MOS_Delete(m_mmcState);
561     }
562 #endif
563 
564     return HevcPipeline::Uninitialize();
565 }
566 
UserFeatureReport()567 MOS_STATUS HevcPipelineM12::UserFeatureReport()
568 {
569     DECODE_FUNC_CALL();
570     return HevcPipeline::UserFeatureReport();
571 }
572 
GetCompletedReport()573 uint32_t HevcPipelineM12::GetCompletedReport()
574 {
575     DECODE_FUNC_CALL();
576 
577     uint32_t completedCount = m_statusReport->GetCompletedCount();
578     uint32_t reportedCount = m_statusReport->GetReportedCount();
579 
580     if (reportedCount > completedCount)
581     {
582         DECODE_ASSERTMESSAGE("No report available at all");
583         return 0;
584     }
585     else
586     {
587         uint32_t availableCount = completedCount - reportedCount;
588         return availableCount;
589     }
590 }
591 
CreateSubPackets(DecodeSubPacketManager & subPacketManager,CodechalSetting & codecSettings)592 MOS_STATUS HevcPipelineM12::CreateSubPackets(DecodeSubPacketManager& subPacketManager, CodechalSetting &codecSettings)
593 {
594     DecodePredicationPktG12 *predicationPkt = MOS_New(DecodePredicationPktG12, this, m_hwInterface);
595     DECODE_CHK_NULL(predicationPkt);
596     DECODE_CHK_STATUS(subPacketManager.Register(
597         DecodePacketId(this, predicationSubPacketId), *predicationPkt));
598 
599     DecodeMarkerPktG12 *markerPkt = MOS_New(DecodeMarkerPktG12, this, m_hwInterface);
600     DECODE_CHK_NULL(markerPkt);
601     DECODE_CHK_STATUS(subPacketManager.Register(
602         DecodePacketId(this, markerSubPacketId), *markerPkt));
603 
604 #ifdef _DECODE_PROCESSING_SUPPORTED
605     HevcDownSamplingPkt *downSamplingPkt = MOS_New(HevcDownSamplingPkt, this, *m_hwInterface);
606     DECODE_CHK_NULL(downSamplingPkt);
607     DECODE_CHK_STATUS(subPacketManager.Register(
608         DecodePacketId(this, downSamplingSubPacketId), *downSamplingPkt));
609 #endif
610 
611     HevcDecodePicPktM12 *pictureDecodePkt = MOS_New(HevcDecodePicPktM12, this, m_hwInterface);
612     DECODE_CHK_NULL(pictureDecodePkt);
613     DECODE_CHK_STATUS(subPacketManager.Register(
614                         DecodePacketId(this, hevcPictureSubPacketId), *pictureDecodePkt));
615 
616     HevcDecodeSlcPktM12 *sliceDecodePkt = MOS_New(HevcDecodeSlcPktM12, this, m_hwInterface);
617     DECODE_CHK_NULL(sliceDecodePkt);
618     DECODE_CHK_STATUS(subPacketManager.Register(
619                         DecodePacketId(this, hevcSliceSubPacketId), *sliceDecodePkt));
620 
621     HevcDecodeTilePktM12 *tileDecodePkt = MOS_New(HevcDecodeTilePktM12, this, m_hwInterface);
622     DECODE_CHK_NULL(tileDecodePkt);
623     DECODE_CHK_STATUS(subPacketManager.Register(
624                         DecodePacketId(this, hevcTileSubPacketId), *tileDecodePkt));
625 
626     return MOS_STATUS_SUCCESS;
627 }
628 
CreatePostSubPipeLines(DecodeSubPipelineManager & subPipelineManager)629 MOS_STATUS HevcPipelineM12::CreatePostSubPipeLines(DecodeSubPipelineManager &subPipelineManager)
630 {
631     DECODE_FUNC_CALL();
632 
633 #ifdef _DECODE_PROCESSING_SUPPORTED
634     auto sfcHistogramPostSubPipeline = MOS_New(DecodeSfcHistogramSubPipelineM12, this, m_task, m_numVdbox, m_hwInterface);
635     DECODE_CHK_NULL(sfcHistogramPostSubPipeline);
636     DECODE_CHK_STATUS(m_postSubPipeline->Register(*sfcHistogramPostSubPipeline));
637 #endif
638 
639     return MOS_STATUS_SUCCESS;
640 }
641 
CreatePreSubPipeLines(DecodeSubPipelineManager & subPipelineManager)642 MOS_STATUS HevcPipelineM12::CreatePreSubPipeLines(DecodeSubPipelineManager &subPipelineManager)
643 {
644     m_bitstream = MOS_New(DecodeInputBitstreamM12, this, m_task, m_numVdbox, m_hwInterface);
645     DECODE_CHK_NULL(m_bitstream);
646     DECODE_CHK_STATUS(subPipelineManager.Register(*m_bitstream));
647 
648     m_streamout = MOS_New(DecodeStreamOutM12, this, m_task, m_numVdbox, m_hwInterface);
649     DECODE_CHK_NULL(m_streamout);
650     DECODE_CHK_STATUS(subPipelineManager.Register(*m_streamout));
651     return MOS_STATUS_SUCCESS;
652 }
653 
654 #ifdef _MMC_SUPPORTED
InitMmcState()655 MOS_STATUS HevcPipelineM12::InitMmcState()
656 {
657     DECODE_FUNC_CALL();
658 
659     m_mmcState = MOS_New(HevcDecodeMemCompM12, m_hwInterface);
660     DECODE_CHK_NULL(m_mmcState);
661 
662     DECODE_CHK_STATUS(m_basicFeature->SetMmcState(m_mmcState->IsMmcEnabled()));
663     return MOS_STATUS_SUCCESS;
664 }
665 #endif
666 
667 #if USE_CODECHAL_DEBUG_TOOL
DumpParams(HevcBasicFeature & basicFeature)668 MOS_STATUS HevcPipelineM12::DumpParams(HevcBasicFeature &basicFeature)
669 {
670     m_debugInterface->m_bufferDumpFrameNum = basicFeature.m_frameNum;
671     m_debugInterface->m_currPic            = basicFeature.m_curRenderPic;
672     m_debugInterface->m_secondField        = basicFeature.m_secondField;
673     m_debugInterface->m_frameType          = basicFeature.m_pictureCodingType;
674 
675     DECODE_CHK_STATUS(DumpPicParams(
676         basicFeature.m_hevcPicParams,
677         basicFeature.m_hevcRextPicParams,
678         basicFeature.m_hevcSccPicParams));
679 
680     DECODE_CHK_STATUS(DumpSliceParams(
681         basicFeature.m_hevcSliceParams,
682         basicFeature.m_hevcRextSliceParams,
683         basicFeature.m_numSlices,
684         basicFeature.m_shortFormatInUse));
685 
686     DECODE_CHK_STATUS(DumpIQParams(basicFeature.m_hevcIqMatrixParams));
687 
688     DECODE_CHK_STATUS(DumpBitstream(&basicFeature.m_resDataBuffer.OsResource, basicFeature.m_dataSize, 0));
689 
690     if (!basicFeature.m_shortFormatInUse)
691     {
692         DECODE_CHK_STATUS(DumpSubsetsParams(basicFeature.m_hevcSubsetParams));
693     }
694 
695     return MOS_STATUS_SUCCESS;
696 }
697 
DumpSecondLevelBatchBuffer()698 MOS_STATUS HevcPipelineM12::DumpSecondLevelBatchBuffer()
699 {
700     DECODE_CHK_STATUS(HevcPipeline::DumpSecondLevelBatchBuffer());
701 
702     if (m_basicFeature->m_shortFormatInUse)
703     {
704         // Dump HuC auth chained BB
705         auto hucS2LPkt = dynamic_cast<HucS2lPktM12 *>(GetOrCreate(DecodePacketId(this, hucS2lPacketId)));
706         DECODE_CHK_NULL(hucS2LPkt);
707 
708         PMHW_BATCH_BUFFER batchBuffer = hucS2LPkt->GetHucAuthCmdBuffer();
709 
710         if (batchBuffer != nullptr)
711         {
712             batchBuffer->iLastCurrent = batchBuffer->iSize * batchBuffer->count;
713             batchBuffer->dwOffset     = 0;
714             DECODE_CHK_STATUS(m_debugInterface->Dump2ndLvlBatch(
715                 batchBuffer,
716                 CODECHAL_NUM_MEDIA_STATES,
717                 "HEVC_DEC_HucAuth"));
718         }
719     }
720 
721     return MOS_STATUS_SUCCESS;
722 }
723 #endif
724 
725 }
726