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