1 /*
2 * Copyright (c) 2018-2022, 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_avc_pipeline.cpp
24 //! \brief Defines the interface for avc decode pipeline
25 //!
26 #include "decode_avc_pipeline.h"
27 #include "decode_utils.h"
28 #include "codechal_setting.h"
29 #include "decode_avc_feature_manager.h"
30 #include "decode_huc_packet_creator_base.h"
31 #include "mos_os_cp_interface_specific.h"
32 #include "media_debug_fast_dump.h"
33
34 namespace decode
35 {
AvcPipeline(CodechalHwInterfaceNext * hwInterface,CodechalDebugInterface * debugInterface)36 AvcPipeline::AvcPipeline(
37 CodechalHwInterfaceNext *hwInterface,
38 CodechalDebugInterface *debugInterface)
39 : DecodePipeline(hwInterface, debugInterface)
40 {
41 MOS_STATUS m_status = InitUserSetting(m_userSettingPtr);
42 }
43
Initialize(void * settings)44 MOS_STATUS AvcPipeline::Initialize(void *settings)
45 {
46 DECODE_FUNC_CALL();
47 DECODE_CHK_STATUS(DecodePipeline::Initialize(settings));
48
49 m_basicFeature = dynamic_cast<AvcBasicFeature*>(m_featureManager->GetFeature(FeatureIDs::basicFeature));
50 DECODE_CHK_NULL(m_basicFeature);
51
52 // Create basic GPU context
53 DecodeScalabilityPars scalPars;
54 MOS_ZeroMemory(&scalPars, sizeof(scalPars));
55 DECODE_CHK_STATUS(m_mediaContext->SwitchContext(VdboxDecodeFunc, &scalPars, &m_scalability));
56 m_decodeContext = m_osInterface->pfnGetGpuContext(m_osInterface);
57 m_decodeContextHandle = m_osInterface->CurrentGpuContextHandle;
58
59 auto *codecSettings = (CodechalSetting*)settings;
60 DECODE_CHK_NULL(codecSettings);
61 m_intelEntrypointInUse = (codecSettings->intelEntrypointInUse) ? true : false;
62 m_shortFormatInUse = (codecSettings->shortFormatInUse) ? true : false;
63
64 HucPacketCreatorBase *hucPktCreator = dynamic_cast<HucPacketCreatorBase *>(this);
65 DECODE_CHK_NULL(hucPktCreator);
66 m_formatMonoPicPkt = hucPktCreator->CreateHucCopyPkt(this, m_task, m_hwInterface);
67 DECODE_CHK_NULL(m_formatMonoPicPkt);
68 MediaPacket *packet = dynamic_cast<MediaPacket *>(m_formatMonoPicPkt);
69 DECODE_CHK_NULL(packet);
70 DECODE_CHK_STATUS(RegisterPacket(DecodePacketId(this, avcFormatMonoPicPktId), packet));
71 DECODE_CHK_STATUS(packet->Init());
72
73 return MOS_STATUS_SUCCESS;
74 }
75
LinearToYTiledAddress(uint32_t x,uint32_t y,uint32_t pitch)76 static uint32_t LinearToYTiledAddress(
77 uint32_t x,
78 uint32_t y,
79 uint32_t pitch)
80 {
81 uint32_t tileW = 128;
82 uint32_t tileH = 32;
83
84 uint32_t tileSize = tileW * tileH;
85
86 uint32_t rowSize = (pitch / tileW) * tileSize;
87
88 uint32_t xOffWithinTile = x % tileW;
89 uint32_t yOffWithinTile = y % tileH;
90
91 uint32_t tileNumberInX = x / tileW;
92 uint32_t tileNumberInY = y / tileH;
93
94 uint32_t tileOffset =
95 rowSize * tileNumberInY +
96 tileSize * tileNumberInX +
97 tileH * 16 * (xOffWithinTile / 16) +
98 yOffWithinTile * 16 +
99 (xOffWithinTile % 16);
100
101 return tileOffset;
102 }
103
Prepare(void * params)104 MOS_STATUS AvcPipeline::Prepare(void *params)
105 {
106 DECODE_FUNC_CALL();
107 DECODE_CHK_NULL(params);
108
109 DECODE_CHK_STATUS(DecodePipeline::Prepare(params));
110
111 if (m_basicFeature->m_avcPicParams->seq_fields.chroma_format_idc == avcChromaFormatMono)
112 {
113 uint32_t height = m_basicFeature->m_destSurface.dwHeight;
114 uint32_t pitch = m_basicFeature->m_destSurface.dwPitch;
115 uint32_t chromaHeight = height >> 1;
116 uint32_t frameHeight = MOS_ALIGN_CEIL(height, 16);
117 uint32_t alignedFrameHeight = MOS_ALIGN_CEIL(frameHeight, MOS_YTILE_H_ALIGNMENT);
118 uint32_t frameSize = pitch * MOS_ALIGN_CEIL((frameHeight + chromaHeight), MOS_YTILE_H_ALIGNMENT);
119
120 uint32_t uvblockHeight = CODECHAL_MACROBLOCK_HEIGHT;
121 uint32_t uvrowSize = pitch * uvblockHeight * 2;
122 uint32_t dstOffset = 0, x = 0, uvsize = 0;
123
124 //update decode output surface's cpTag before decode submitbuffer, pfnMediaCopyResource2D can decide clear/secure workload by output surface's cptag.
125 if (m_osInterface->osCpInterface && m_osInterface->osCpInterface->IsHMEnabled())
126 {
127 DECODE_CHK_STATUS(m_osInterface->osCpInterface->SetResourceEncryption(&m_basicFeature->m_destSurface.OsResource, true));
128 }
129
130 HucCopyPktItf::HucCopyParams copyParams = {};
131
132 if (frameHeight % MOS_YTILE_H_ALIGNMENT)
133 {
134 dstOffset = LinearToYTiledAddress(x, frameHeight, pitch);
135
136 if (!m_basicFeature->m_usingVeRing)
137 {
138 copyParams.srcBuffer = &(m_basicFeature->m_resMonoPicChromaBuffer->OsResource);
139 copyParams.srcOffset = 0;
140 copyParams.destBuffer = &(m_basicFeature->m_destSurface.OsResource);
141 copyParams.destOffset = dstOffset;
142 copyParams.copyLength = uvrowSize;
143 m_formatMonoPicPkt->PushCopyParams(copyParams);
144 }
145 else
146 {
147 m_osInterface->pfnMonoSurfaceCopy(
148 m_osInterface,
149 &m_basicFeature->m_resMonoPicChromaBuffer->OsResource,
150 &m_basicFeature->m_destSurface.OsResource,
151 pitch,
152 uvblockHeight * 2,
153 0,
154 dstOffset,
155 false);
156 }
157 }
158
159 dstOffset = m_basicFeature->m_destSurface.UPlaneOffset.iSurfaceOffset;
160 uvsize = frameSize - pitch * alignedFrameHeight;
161
162 if (!m_basicFeature->m_usingVeRing)
163 {
164 copyParams.srcBuffer = &(m_basicFeature->m_resMonoPicChromaBuffer->OsResource);
165 copyParams.srcOffset = 0;
166 copyParams.destBuffer = &(m_basicFeature->m_destSurface.OsResource);
167 copyParams.destOffset = dstOffset;
168 copyParams.copyLength = uvsize;
169 m_formatMonoPicPkt->PushCopyParams(copyParams);
170 }
171 else
172 {
173 m_osInterface->pfnMonoSurfaceCopy(
174 m_osInterface,
175 &m_basicFeature->m_resMonoPicChromaBuffer->OsResource,
176 &m_basicFeature->m_destSurface.OsResource,
177 pitch,
178 uvsize / pitch,
179 0,
180 dstOffset,
181 false);
182 }
183 }
184
185 return MOS_STATUS_SUCCESS;
186 }
187
UserFeatureReport()188 MOS_STATUS AvcPipeline::UserFeatureReport()
189 {
190 DECODE_FUNC_CALL();
191 DECODE_CHK_STATUS(DecodePipeline::UserFeatureReport());
192 #if (_DEBUG || _RELEASE_INTERNAL)
193 WriteUserFeature(__MEDIA_USER_FEATURE_VALUE_APOGEIOS_AVCD_ENABLE_ID, 1, m_osInterface->pOsContext);
194 #endif
195 return MOS_STATUS_SUCCESS;
196 }
197
Uninitialize()198 MOS_STATUS AvcPipeline::Uninitialize()
199 {
200 DECODE_FUNC_CALL();
201
202 return DecodePipeline::Uninitialize();
203 }
204
ActivateDecodePackets()205 MOS_STATUS AvcPipeline::ActivateDecodePackets()
206 {
207 DECODE_FUNC_CALL();
208
209 bool immediateSubmit = false;
210
211 if (m_basicFeature->m_avcPicParams->seq_fields.chroma_format_idc == avcChromaFormatMono && !m_basicFeature->m_usingVeRing)
212 {
213 DECODE_CHK_STATUS(ActivatePacket(DecodePacketId(this, avcFormatMonoPicPktId), immediateSubmit, 0, 0));
214 }
215
216 for (uint8_t curPass = 0; curPass < GetPassNum(); curPass++)
217 {
218 DECODE_CHK_STATUS(ActivatePacket(DecodePacketId(this, avcDecodePacketId), immediateSubmit, curPass, 0));
219 }
220
221 return MOS_STATUS_SUCCESS;
222 }
223
CreateFeatureManager()224 MOS_STATUS AvcPipeline::CreateFeatureManager()
225 {
226 DECODE_FUNC_CALL();
227 m_featureManager = MOS_New(DecodeAvcFeatureManager, m_allocator, m_hwInterface, m_osInterface);
228 DECODE_CHK_NULL(m_featureManager);
229 return MOS_STATUS_SUCCESS;
230 }
231
CreateSubPackets(DecodeSubPacketManager & subPacketManager,CodechalSetting & codecSettings)232 MOS_STATUS AvcPipeline::CreateSubPackets(DecodeSubPacketManager& subPacketManager, CodechalSetting &codecSettings)
233 {
234 DECODE_FUNC_CALL();
235
236 DECODE_CHK_STATUS(DecodePipeline::CreateSubPackets(subPacketManager, codecSettings));
237
238 return MOS_STATUS_SUCCESS;
239 }
240
GetDecodeMode()241 AvcPipeline::AvcDecodeMode AvcPipeline::GetDecodeMode()
242 {
243 return m_decodeMode;
244 }
245
IsShortFormat()246 bool AvcPipeline::IsShortFormat()
247 {
248 return m_shortFormatInUse;
249 }
250
SetDecodeFormat(bool isShortFormat)251 MOS_STATUS AvcPipeline::SetDecodeFormat(bool isShortFormat)
252 {
253 DECODE_FUNC_CALL();
254 DECODE_CHK_NULL(m_basicFeature);
255 m_basicFeature->m_shortFormatInUse = isShortFormat;
256 m_shortFormatInUse = isShortFormat;
257 return MOS_STATUS_SUCCESS;
258 }
259
260 #if USE_CODECHAL_DEBUG_TOOL
DumpPicParams(PCODEC_AVC_PIC_PARAMS picParams)261 MOS_STATUS AvcPipeline::DumpPicParams(
262 PCODEC_AVC_PIC_PARAMS picParams)
263 {
264 DECODE_FUNC_CALL();
265
266 if (picParams == nullptr)
267 {
268 return MOS_STATUS_SUCCESS;
269 }
270
271 if (m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrPicParams))
272 {
273 const char *fileName = m_debugInterface->CreateFileName(
274 "_DEC",
275 CodechalDbgBufferType::bufPicParams,
276 CodechalDbgExtType::txt);
277
278 if (m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrEnableFastDump))
279 {
280 MediaDebugFastDump::Dump(
281 (uint8_t *)picParams,
282 fileName,
283 sizeof(CODEC_AVC_PIC_PARAMS),
284 0,
285 MediaDebugSerializer<CODEC_AVC_PIC_PARAMS>());
286 }
287 else
288 {
289 DumpDecodeAvcPicParams(picParams, fileName);
290 }
291 }
292
293 return MOS_STATUS_SUCCESS;
294 }
295
DumpSliceParams(PCODEC_AVC_SLICE_PARAMS slcParams,uint32_t numSlices,bool shortFormatInUse)296 MOS_STATUS AvcPipeline::DumpSliceParams(
297 PCODEC_AVC_SLICE_PARAMS slcParams,
298 uint32_t numSlices,
299 bool shortFormatInUse)
300 {
301 DECODE_FUNC_CALL();
302
303 if (slcParams == nullptr)
304 {
305 return MOS_STATUS_SUCCESS;
306 }
307
308 if (m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrSlcParams))
309 {
310 const char *fileName = m_debugInterface->CreateFileName(
311 "_DEC",
312 CodechalDbgBufferType::bufSlcParams,
313 CodechalDbgExtType::txt);
314
315 if (m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrEnableFastDump))
316 {
317 if (shortFormatInUse)
318 {
319 PCODEC_AVC_SF_SLICE_PARAMS slcParamsSF =
320 (PCODEC_AVC_SF_SLICE_PARAMS)MOS_AllocMemory(sizeof(PCODEC_AVC_SF_SLICE_PARAMS) * numSlices);
321
322 for (uint16_t i = 0; i < numSlices; i++)
323 {
324 slcParamsSF[i] = reinterpret_cast<CODEC_AVC_SF_SLICE_PARAMS &>(slcParams[i]);
325 }
326
327 MediaDebugFastDump::Dump(
328 (uint8_t *)slcParamsSF,
329 fileName,
330 sizeof(CODEC_AVC_SF_SLICE_PARAMS) * numSlices,
331 0,
332 MediaDebugSerializer<CODEC_AVC_SF_SLICE_PARAMS>());
333 }
334 else
335 {
336 MediaDebugFastDump::Dump(
337 (uint8_t *)slcParams,
338 fileName,
339 sizeof(CODEC_AVC_SLICE_PARAMS) * numSlices,
340 0,
341 MediaDebugSerializer<CODEC_AVC_SLICE_PARAMS>());
342 }
343 }
344 else
345 {
346 DumpDecodeAvcSliceParams(slcParams, numSlices, fileName, shortFormatInUse);
347 }
348 }
349
350 return MOS_STATUS_SUCCESS;
351 }
352
DumpIQParams(PCODEC_AVC_IQ_MATRIX_PARAMS iqParams)353 MOS_STATUS AvcPipeline::DumpIQParams(
354 PCODEC_AVC_IQ_MATRIX_PARAMS iqParams)
355 {
356 DECODE_FUNC_CALL();
357
358 if (iqParams == nullptr)
359 {
360 return MOS_STATUS_SUCCESS;
361 }
362
363 if (m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrIqParams))
364 {
365 const char *fileName = m_debugInterface->CreateFileName(
366 "_DEC",
367 CodechalDbgBufferType::bufIqParams,
368 CodechalDbgExtType::txt);
369
370 if (m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrEnableFastDump))
371 {
372 MediaDebugFastDump::Dump(
373 (uint8_t *)iqParams,
374 fileName,
375 sizeof(CODEC_AVC_IQ_MATRIX_PARAMS),
376 0,
377 MediaDebugSerializer<CODEC_AVC_IQ_MATRIX_PARAMS>());
378 }
379 else
380 {
381 DumpDecodeAvcIQParams(iqParams, fileName);
382 }
383 }
384
385 return MOS_STATUS_SUCCESS;
386 }
387 #endif
388 }
389