1 /*
2 * Copyright (c) 2020-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 //! \file decode_vp9_pipeline.cpp
24 //! \brief Defines the interface for vp9 decode pipeline
25 //!
26 #include "decode_vp9_pipeline.h"
27 #include "decode_utils.h"
28 #include "codechal_setting.h"
29 #include "decode_vp9_phase_single.h"
30 #include "decode_vp9_phase_front_end.h"
31 #include "decode_vp9_phase_back_end.h"
32 #include "decode_vp9_feature_manager.h"
33 #include "decode_vp9_buffer_update.h"
34 #include "media_debug_fast_dump.h"
35
36 namespace decode
37 {
Vp9Pipeline(CodechalHwInterfaceNext * hwInterface,CodechalDebugInterface * debugInterface)38 Vp9Pipeline::Vp9Pipeline(
39 CodechalHwInterfaceNext *hwInterface,
40 CodechalDebugInterface *debugInterface)
41 : DecodePipeline(hwInterface, debugInterface)
42 {
43 MOS_STATUS m_status = InitUserSetting(m_userSettingPtr);
44 }
45
Initialize(void * settings)46 MOS_STATUS Vp9Pipeline::Initialize(void *settings)
47 {
48 DECODE_FUNC_CALL();
49 DECODE_CHK_STATUS(DecodePipeline::Initialize(settings));
50
51 // Create basic GPU context
52 DecodeScalabilityPars scalPars;
53 MOS_ZeroMemory(&scalPars, sizeof(scalPars));
54 DECODE_CHK_STATUS(m_mediaContext->SwitchContext(VdboxDecodeFunc, &scalPars, &m_scalability));
55 m_decodeContext = m_osInterface->pfnGetGpuContext(m_osInterface);
56 m_decodeContextHandle = m_osInterface->CurrentGpuContextHandle;
57
58 m_basicFeature = dynamic_cast<Vp9BasicFeature *>(m_featureManager->GetFeature(FeatureIDs::basicFeature));
59 DECODE_CHK_NULL(m_basicFeature);
60
61 auto *codecSettings = (CodechalSetting *)settings;
62 DECODE_CHK_NULL(codecSettings);
63
64 auto *bufferUpdatePipeline = MOS_New(DecodeVp9BufferUpdate, this, m_task, m_numVdbox);
65 DECODE_CHK_NULL(bufferUpdatePipeline);
66 DECODE_CHK_STATUS(m_preSubPipeline->Register(*bufferUpdatePipeline));
67 DECODE_CHK_STATUS(bufferUpdatePipeline->Init(*codecSettings));
68
69 return MOS_STATUS_SUCCESS;
70 }
71
Prepare(void * params)72 MOS_STATUS Vp9Pipeline::Prepare(void *params)
73 {
74 DECODE_FUNC_CALL();
75 DECODE_CHK_NULL(params);
76
77 auto basicFeature = dynamic_cast<Vp9BasicFeature *>(m_featureManager->GetFeature(FeatureIDs::basicFeature));
78 DECODE_CHK_NULL(basicFeature);
79 DECODE_CHK_STATUS(DecodePipeline::Prepare(params));
80
81 return MOS_STATUS_SUCCESS;
82 }
83
Uninitialize()84 MOS_STATUS Vp9Pipeline::Uninitialize()
85 {
86 DECODE_FUNC_CALL();
87
88 #if (_DEBUG || _RELEASE_INTERNAL)
89 // Report real tile frame count and virtual tile frame count
90 ReportUserSettingForDebug(
91 m_userSettingPtr,
92 "VT Decoded Count",
93 m_vtFrameCount,
94 MediaUserSetting::Group::Sequence);
95 #endif
96
97 DECODE_CHK_STATUS(DestoryPhaseList());
98 return DecodePipeline::Uninitialize();
99 }
100
UserFeatureReport()101 MOS_STATUS Vp9Pipeline::UserFeatureReport()
102 {
103 DECODE_FUNC_CALL();
104 DECODE_CHK_STATUS(DecodePipeline::UserFeatureReport());
105 #if (_DEBUG || _RELEASE_INTERNAL)
106 WriteUserFeature(__MEDIA_USER_FEATURE_VALUE_APOGEIOS_VP9D_ENABLE_ID, 1, m_osInterface->pOsContext);
107 #endif
108
109 #ifdef _MMC_SUPPORTED
110 CODECHAL_DEBUG_TOOL(
111 if (m_mmcState != nullptr) {
112 m_mmcState->UpdateUserFeatureKey(&(m_basicFeature->m_destSurface));
113 })
114 #endif
115 return MOS_STATUS_SUCCESS;
116 }
117
Execute()118 MOS_STATUS Vp9Pipeline::Execute()
119 {
120 DECODE_FUNC_CALL();
121
122 #if (_DEBUG || _RELEASE_INTERNAL)
123 if (GetDecodeMode() == virtualTileDecodeMode)
124 {
125 m_vtFrameCount++;
126 }
127 #endif
128
129 for (auto &phase : m_phaseList)
130 {
131 DECODE_ASSERT(phase != nullptr);
132 if (phase->RequiresContextSwitch())
133 {
134 // switch context
135 DecodeScalabilityOption *scalabOption = phase->GetDecodeScalabilityOption();
136 DECODE_CHK_NULL(scalabOption);
137 DECODE_CHK_STATUS(m_mediaContext->SwitchContext(VdboxDecodeFunc, *scalabOption, &m_scalability));
138 if (scalabOption->IsScalabilityOptionMatched(m_scalabOption))
139 {
140 m_decodeContext = m_osInterface->pfnGetGpuContext(m_osInterface);
141 m_decodeContextHandle = m_osInterface->CurrentGpuContextHandle;
142 }
143 }
144
145 StateParams stateProperty;
146 stateProperty.currentPipe = phase->GetPipe();
147 stateProperty.currentPass = phase->GetPass();
148 stateProperty.pipeIndexForSubmit = phase->GetPipe() + 1;
149 stateProperty.componentState = phase;
150 DECODE_CHK_STATUS(ActivatePacket(phase->GetPktId(), phase->ImmediateSubmit(), stateProperty));
151
152 if (phase->ImmediateSubmit())
153 {
154 m_scalability->SetPassNumber(phase->GetPass() + 1);
155 DECODE_CHK_STATUS(ExecuteActivePackets());
156 }
157 }
158
159 return MOS_STATUS_SUCCESS;
160 }
161
CreateFeatureManager()162 MOS_STATUS Vp9Pipeline::CreateFeatureManager()
163 {
164 DECODE_FUNC_CALL();
165 m_featureManager = MOS_New(DecodeVp9FeatureManager, m_allocator, m_hwInterface, m_osInterface);
166 DECODE_CHK_NULL(m_featureManager);
167 return MOS_STATUS_SUCCESS;
168 }
169
CreateSubPackets(DecodeSubPacketManager & subPacketManager,CodechalSetting & codecSettings)170 MOS_STATUS Vp9Pipeline::CreateSubPackets(DecodeSubPacketManager &subPacketManager, CodechalSetting &codecSettings)
171 {
172 DECODE_FUNC_CALL();
173
174 DECODE_CHK_STATUS(DecodePipeline::CreateSubPackets(subPacketManager, codecSettings));
175
176 return MOS_STATUS_SUCCESS;
177 }
178
GetDecodeMode()179 Vp9Pipeline::Vp9DecodeMode Vp9Pipeline::GetDecodeMode()
180 {
181 return m_decodeMode;
182 }
183
InitContexOption(Vp9BasicFeature & basicFeature)184 MOS_STATUS Vp9Pipeline::InitContexOption(Vp9BasicFeature &basicFeature)
185 {
186 DecodeScalabilityPars scalPars;
187 MOS_ZeroMemory(&scalPars, sizeof(scalPars));
188
189 scalPars.usingHcp = true;
190 scalPars.enableVE = MOS_VE_SUPPORTED(m_osInterface);
191 scalPars.disableScalability = m_hwInterface->IsDisableScalability();
192 scalPars.surfaceFormat = basicFeature.m_destSurface.Format;
193 scalPars.frameWidth = basicFeature.m_frameWidthAlignedMinBlk;
194 scalPars.frameHeight = basicFeature.m_frameHeightAlignedMinBlk;
195 scalPars.numVdbox = m_numVdbox;
196 if (m_osInterface->pfnIsMultipleCodecDevicesInUse(m_osInterface))
197 {
198 scalPars.disableScalability = true;
199 }
200 #if (_DEBUG || _RELEASE_INTERNAL)
201 if (m_osInterface->bHcpDecScalabilityMode == MOS_SCALABILITY_ENABLE_MODE_FALSE)
202 {
203 scalPars.disableScalability = true;
204 }
205 else if (m_osInterface->bHcpDecScalabilityMode == MOS_SCALABILITY_ENABLE_MODE_USER_FORCE)
206 {
207 scalPars.disableScalability = false;
208 }
209 scalPars.modeSwithThreshold1 =
210 ReadUserFeature(m_userSettingPtr, "HCP Decode Mode Switch TH1", MediaUserSetting::Group::Sequence).Get<uint32_t>();
211 scalPars.modeSwithThreshold2 =
212 ReadUserFeature(m_userSettingPtr, "HCP Decode Mode Switch TH2", MediaUserSetting::Group::Sequence).Get<uint32_t>();
213 scalPars.forceMultiPipe =
214 ReadUserFeature(m_userSettingPtr, "HCP Decode Always Frame Split", MediaUserSetting::Group::Sequence).Get<bool>();
215 scalPars.userPipeNum =
216 ReadUserFeature(m_userSettingPtr, "HCP Decode User Pipe Num", MediaUserSetting::Group::Sequence).Get<uint8_t>();
217 #endif
218
219 #ifdef _DECODE_PROCESSING_SUPPORTED
220 DecodeDownSamplingFeature *downSamplingFeature = dynamic_cast<DecodeDownSamplingFeature *>(
221 m_featureManager->GetFeature(DecodeFeatureIDs::decodeDownSampling));
222 if (downSamplingFeature != nullptr && downSamplingFeature->IsEnabled())
223 {
224 scalPars.usingSfc = true;
225 if (!MEDIA_IS_SKU(m_skuTable, FtrSfcScalability))
226 {
227 scalPars.disableScalability = true;
228 }
229 }
230 //Disable Scalability when histogram is enabled
231 if (downSamplingFeature != nullptr && (downSamplingFeature->m_histogramDestSurf || downSamplingFeature->m_histogramDebug))
232 {
233 scalPars.disableScalability = true;
234 }
235 #endif
236
237 if (MEDIA_IS_SKU(m_skuTable, FtrVirtualTileScalabilityDisable))
238 {
239 scalPars.disableScalability = true;
240 scalPars.disableVirtualTile = true;
241 }
242
243 DECODE_CHK_STATUS(m_scalabOption.SetScalabilityOption(&scalPars));
244 return MOS_STATUS_SUCCESS;
245 }
246
InitDecodeMode(ScalabilityMode scalabMode)247 MOS_STATUS Vp9Pipeline::InitDecodeMode(ScalabilityMode scalabMode)
248 {
249 if (scalabMode == scalabilityVirtualTileMode)
250 {
251 m_decodeMode = virtualTileDecodeMode;
252 }
253 else if (scalabMode == scalabilitySingleMode)
254 {
255 m_decodeMode = baseDecodeMode;
256 }
257 else
258 {
259 return MOS_STATUS_INVALID_PARAMETER;
260 }
261
262 return MOS_STATUS_SUCCESS;
263 }
264
265 template <typename T>
CreatePhase(uint8_t pass,uint8_t pipe,uint8_t activePipeNum)266 MOS_STATUS Vp9Pipeline::CreatePhase(uint8_t pass, uint8_t pipe, uint8_t activePipeNum)
267 {
268 DECODE_FUNC_CALL();
269 T *phase = MOS_New(T, *this, m_scalabOption);
270 DECODE_CHK_NULL(phase);
271 MOS_STATUS status = phase->Initialize(pass, pipe, activePipeNum);
272 if (status != MOS_STATUS_SUCCESS)
273 {
274 MOS_Delete(phase);
275 return status;
276 }
277 m_phaseList.push_back(phase);
278 return MOS_STATUS_SUCCESS;
279 }
280
CreatePhaseList(const ScalabilityMode scalabMode,const uint8_t numPipe)281 MOS_STATUS Vp9Pipeline::CreatePhaseList(const ScalabilityMode scalabMode, const uint8_t numPipe)
282 {
283 DECODE_FUNC_CALL();
284 DECODE_ASSERT(m_phaseList.empty());
285
286 if (scalabMode == scalabilityVirtualTileMode)
287 {
288 DECODE_CHK_STATUS(CreatePhase<Vp9PhaseFrontEnd>());
289 for (uint8_t i = 0; i < numPipe; i++)
290 {
291 DECODE_CHK_STATUS(CreatePhase<Vp9PhaseBackEnd>(0, i, numPipe));
292 }
293 }
294 else
295 {
296 DECODE_CHK_STATUS(CreatePhase<Vp9PhaseSingle>());
297 }
298
299 return MOS_STATUS_SUCCESS;
300 }
301
DestoryPhaseList()302 MOS_STATUS Vp9Pipeline::DestoryPhaseList()
303 {
304 for (auto &phase : m_phaseList)
305 {
306 MOS_Delete(phase);
307 }
308 m_phaseList.clear();
309 return MOS_STATUS_SUCCESS;
310 }
311
312 #if USE_CODECHAL_DEBUG_TOOL
DumpPicParams(CODEC_VP9_PIC_PARAMS * picParams)313 MOS_STATUS Vp9Pipeline::DumpPicParams(CODEC_VP9_PIC_PARAMS *picParams)
314 {
315 CODECHAL_DEBUG_FUNCTION_ENTER;
316
317 if (picParams == nullptr)
318 {
319 return MOS_STATUS_SUCCESS;
320 }
321
322 if (m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrPicParams))
323 {
324 const char *fileName = m_debugInterface->CreateFileName(
325 "_DEC",
326 CodechalDbgBufferType::bufPicParams,
327 CodechalDbgExtType::txt);
328
329 if (m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrEnableFastDump))
330 {
331 MediaDebugFastDump::Dump(
332 (uint8_t *)picParams,
333 fileName,
334 sizeof(CODEC_VP9_PIC_PARAMS),
335 0,
336 MediaDebugSerializer<CODEC_VP9_PIC_PARAMS>());
337 }
338 else
339 {
340 DumpDecodeVp9PicParams(picParams, fileName);
341 }
342 }
343
344 return MOS_STATUS_SUCCESS;
345 }
346
DumpSliceParams(CODEC_VP9_SLICE_PARAMS * slcParams)347 MOS_STATUS Vp9Pipeline::DumpSliceParams(CODEC_VP9_SLICE_PARAMS *slcParams)
348 {
349 CODECHAL_DEBUG_FUNCTION_ENTER;
350
351 if (slcParams == nullptr)
352 {
353 return MOS_STATUS_SUCCESS;
354 }
355
356 if (m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrSlcParams))
357 {
358 const char *fileName = m_debugInterface->CreateFileName(
359 "_DEC",
360 CodechalDbgBufferType::bufSlcParams,
361 CodechalDbgExtType::txt);
362
363 if (m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrEnableFastDump))
364 {
365 MediaDebugFastDump::Dump(
366 (uint8_t *)slcParams,
367 fileName,
368 sizeof(CODEC_VP9_SLICE_PARAMS),
369 0,
370 MediaDebugSerializer<CODEC_VP9_SLICE_PARAMS>());
371 }
372 else
373 {
374 DumpDecodeVp9SliceParams(slcParams, fileName);
375 }
376 }
377
378 return MOS_STATUS_SUCCESS;
379 }
380
DumpSegmentParams(CODEC_VP9_SEGMENT_PARAMS * segmentParams)381 MOS_STATUS Vp9Pipeline::DumpSegmentParams(CODEC_VP9_SEGMENT_PARAMS *segmentParams)
382 {
383 CODECHAL_DEBUG_FUNCTION_ENTER;
384
385 if (segmentParams == nullptr)
386 {
387 return MOS_STATUS_SUCCESS;
388 }
389
390 if (m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrSegmentParams))
391 {
392 const char *fileName = m_debugInterface->CreateFileName(
393 "_DEC",
394 CodechalDbgBufferType::bufSegmentParams,
395 CodechalDbgExtType::txt);
396
397 if (m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrEnableFastDump))
398 {
399 MediaDebugFastDump::Dump(
400 (uint8_t *)segmentParams,
401 fileName,
402 sizeof(CODEC_VP9_SEGMENT_PARAMS),
403 0,
404 MediaDebugSerializer<CODEC_VP9_SEGMENT_PARAMS>());
405 }
406 else
407 {
408 DumpDecodeVp9SegmentParams(segmentParams, fileName);
409 }
410 }
411
412 return MOS_STATUS_SUCCESS;
413 }
414 #endif
415
416 } // namespace decode
417