1 /*
2 * Copyright (c) 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_mpeg2_pipeline.cpp
24 //! \brief    Defines the interface for mpeg2 decode pipeline
25 //!
26 #include "decode_mpeg2_pipeline.h"
27 #include "decode_utils.h"
28 #include "codechal_setting.h"
29 #include "decode_mpeg2_feature_manager.h"
30 #include "decode_huc_packet_creator_base.h"
31 #include "media_debug_fast_dump.h"
32 
33 namespace decode{
34 
Mpeg2Pipeline(CodechalHwInterfaceNext * hwInterface,CodechalDebugInterface * debugInterface)35 Mpeg2Pipeline::Mpeg2Pipeline(
36     CodechalHwInterfaceNext *hwInterface,
37     CodechalDebugInterface *debugInterface)
38     : DecodePipeline(hwInterface, debugInterface)
39 {
40     MOS_STATUS m_status = InitUserSetting(m_userSettingPtr);
41 }
42 
Initialize(void * settings)43 MOS_STATUS Mpeg2Pipeline::Initialize(void *settings)
44 {
45     DECODE_FUNC_CALL();
46 
47     DECODE_CHK_STATUS(DecodePipeline::Initialize(settings));
48     m_basicFeature = dynamic_cast<Mpeg2BasicFeature*>(m_featureManager->GetFeature(FeatureIDs::basicFeature));
49     DECODE_CHK_NULL(m_basicFeature);
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     HucPacketCreatorBase *hucPktCreator = dynamic_cast<HucPacketCreatorBase *>(this);
59     DECODE_CHK_NULL(hucPktCreator);
60     m_mpeg2BsCopyPkt    = hucPktCreator->CreateHucCopyPkt(this, m_task, m_hwInterface);
61     DECODE_CHK_NULL(m_mpeg2BsCopyPkt);
62     MediaPacket *packet = dynamic_cast<MediaPacket *>(m_mpeg2BsCopyPkt);
63     DECODE_CHK_NULL(packet);
64     DECODE_CHK_STATUS(RegisterPacket(DecodePacketId(this, mpeg2BsCopyPktId), packet));
65     DECODE_CHK_STATUS(packet->Init());
66 
67     return MOS_STATUS_SUCCESS;
68 }
69 
Prepare(void * params)70 MOS_STATUS Mpeg2Pipeline::Prepare(void *params)
71 {
72     DECODE_FUNC_CALL();
73 
74     DECODE_CHK_NULL(params);
75     DECODE_CHK_STATUS(DecodePipeline::Prepare(params));
76     DECODE_CHK_STATUS(CopyBitstreamBuffer());
77 
78     return MOS_STATUS_SUCCESS;
79 }
80 
CopyDummyBitstream()81 MOS_STATUS Mpeg2Pipeline::CopyDummyBitstream()
82 {
83     DECODE_FUNC_CALL();
84 
85     HucCopyPktItf::HucCopyParams copyParams = {};
86 
87     for (uint16_t slcIdx = 0; slcIdx < m_basicFeature->m_totalNumSlicesRecv; slcIdx++)
88     {
89         // Copy dummy slice to local buffer
90         if (!m_basicFeature->m_copyDummySlicePresent && ((m_basicFeature->m_sliceRecord[slcIdx].prevSliceMbEnd !=
91             m_basicFeature->m_sliceRecord[slcIdx].sliceStartMbOffset && !m_basicFeature->m_sliceRecord[slcIdx].skip) ||
92             m_basicFeature->m_incompletePicture))
93         {
94             m_basicFeature->m_copyDummySlicePresent = true;
95             copyParams.srcBuffer  = &(m_basicFeature->m_resMpeg2DummyBistream->OsResource);
96             copyParams.srcOffset  = 0;
97             copyParams.destBuffer = &(m_basicFeature->m_copiedDataBuf->OsResource);
98             copyParams.destOffset = m_basicFeature->m_nextCopiedDataOffset;
99             copyParams.copyLength = sizeof(m_basicFeature->Mpeg2DummyBsBuf);
100             m_mpeg2BsCopyPkt->PushCopyParams(copyParams);
101 
102             m_basicFeature->m_dummySliceDataOffset = m_basicFeature->m_nextCopiedDataOffset;
103         }
104     }
105 
106     return MOS_STATUS_SUCCESS;
107 }
108 
CopyBitstreamBuffer()109 MOS_STATUS Mpeg2Pipeline::CopyBitstreamBuffer()
110 {
111     DECODE_FUNC_CALL();
112 
113     HucCopyPktItf::HucCopyParams copyParams = {};
114 
115     if (m_basicFeature->m_copiedDataNeeded)
116     {
117         m_basicFeature->m_copiedDataBufferInUse = true;
118         if ((m_basicFeature->m_nextCopiedDataOffset + m_basicFeature->m_dataSize) >
119             m_basicFeature->m_copiedDataBufferSize)
120         {
121             DECODE_ASSERTMESSAGE("Copied data buffer is not large enough.");
122             m_basicFeature->m_slicesInvalid = true;
123             return MOS_STATUS_UNKNOWN;
124         }
125 
126         uint32_t size = MOS_ALIGN_CEIL(m_basicFeature->m_dataSize, 16);
127         copyParams.srcBuffer  = &(m_basicFeature->m_resDataBuffer.OsResource);
128         copyParams.srcOffset  = 0;
129         copyParams.destBuffer = &(m_basicFeature->m_copiedDataBuf->OsResource);
130         copyParams.destOffset = m_basicFeature->m_nextCopiedDataOffset;
131         copyParams.copyLength = m_basicFeature->m_dataSize;
132         m_mpeg2BsCopyPkt->PushCopyParams(copyParams);
133 
134         m_basicFeature->m_copiedDataOffset = m_basicFeature->m_nextCopiedDataOffset;
135         m_basicFeature->m_nextCopiedDataOffset += MOS_ALIGN_CEIL(size, MHW_CACHELINE_SIZE);
136 
137         bool immediateSubmit = true;
138         DECODE_CHK_STATUS(ActivatePacket(DecodePacketId(this, mpeg2BsCopyPktId), immediateSubmit, 0, 0));
139         m_activePacketList.back().frameTrackingRequested = false;
140         DECODE_CHK_STATUS(ExecuteActivePackets());
141     }
142 
143     return MOS_STATUS_SUCCESS;
144 }
145 
UserFeatureReport()146 MOS_STATUS Mpeg2Pipeline::UserFeatureReport()
147 {
148     DECODE_FUNC_CALL();
149     DECODE_CHK_STATUS(DecodePipeline::UserFeatureReport());
150 #if (_DEBUG || _RELEASE_INTERNAL)
151     WriteUserFeature(__MEDIA_USER_FEATURE_VALUE_APOGEIOS_MPEG2D_ENABLE_ID, 1, m_osInterface->pOsContext);
152 #endif
153 
154 #ifdef _MMC_SUPPORTED
155     CODECHAL_DEBUG_TOOL(
156         if (m_mmcState != nullptr) {
157             m_mmcState->UpdateUserFeatureKey(&(m_basicFeature->m_destSurface));
158         })
159 #endif
160     return MOS_STATUS_SUCCESS;
161 }
162 
Uninitialize()163 MOS_STATUS Mpeg2Pipeline::Uninitialize()
164 {
165     DECODE_FUNC_CALL();
166     return DecodePipeline::Uninitialize();
167 }
168 
ActivateDecodePackets()169 MOS_STATUS Mpeg2Pipeline::ActivateDecodePackets()
170 {
171     DECODE_FUNC_CALL();
172 
173     bool immediateSubmit = false;
174 
175     if (m_basicFeature->m_copyDummySlicePresent)
176     {
177         DECODE_CHK_STATUS(ActivatePacket(DecodePacketId(this, mpeg2BsCopyPktId), immediateSubmit, 0, 0));
178     }
179 
180     DECODE_CHK_STATUS(ActivatePacket(DecodePacketId(this, mpeg2DecodePacketId), immediateSubmit, 0, 0));
181 
182     return MOS_STATUS_SUCCESS;
183 }
184 
CreateFeatureManager()185 MOS_STATUS Mpeg2Pipeline::CreateFeatureManager()
186 {
187     DECODE_FUNC_CALL();
188     m_featureManager = MOS_New(DecodeMpeg2FeatureManager, m_allocator, m_hwInterface, m_osInterface);
189     DECODE_CHK_NULL(m_featureManager);
190     return MOS_STATUS_SUCCESS;
191 }
192 
CreateSubPackets(DecodeSubPacketManager & subPacketManager,CodechalSetting & codecSettings)193 MOS_STATUS Mpeg2Pipeline::CreateSubPackets(DecodeSubPacketManager& subPacketManager, CodechalSetting &codecSettings)
194 {
195     DECODE_FUNC_CALL();
196     DECODE_CHK_STATUS(DecodePipeline::CreateSubPackets(subPacketManager, codecSettings));
197     return MOS_STATUS_SUCCESS;
198 }
199 
200 #if USE_CODECHAL_DEBUG_TOOL
DumpPicParams(CodecDecodeMpeg2PicParams * picParams)201 MOS_STATUS Mpeg2Pipeline::DumpPicParams(
202     CodecDecodeMpeg2PicParams *picParams)
203 {
204     DECODE_FUNC_CALL();
205 
206     if (picParams == nullptr)
207     {
208         return MOS_STATUS_SUCCESS;
209     }
210 
211     if (m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrPicParams))
212     {
213         const char *fileName = m_debugInterface->CreateFileName(
214             "_DEC",
215             CodechalDbgBufferType::bufPicParams,
216             CodechalDbgExtType::txt);
217 
218         if (m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrEnableFastDump))
219         {
220             MediaDebugFastDump::Dump(
221                 (uint8_t *)picParams,
222                 fileName,
223                 sizeof(CodecDecodeMpeg2PicParams),
224                 0,
225                 MediaDebugSerializer<CodecDecodeMpeg2PicParams>());
226         }
227         else
228         {
229             DumpDecodeMpeg2PicParams(picParams, fileName);
230         }
231     }
232 
233     return MOS_STATUS_SUCCESS;
234 }
235 
DumpSliceParams(CodecDecodeMpeg2SliceParams * sliceParams,uint32_t numSlices)236 MOS_STATUS Mpeg2Pipeline::DumpSliceParams(
237     CodecDecodeMpeg2SliceParams *sliceParams,
238     uint32_t                     numSlices)
239 {
240     DECODE_FUNC_CALL();
241 
242     if (sliceParams == nullptr)
243     {
244         return MOS_STATUS_SUCCESS;
245     }
246 
247     if (m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrSlcParams))
248     {
249         const char *fileName = m_debugInterface->CreateFileName(
250             "_DEC",
251             CodechalDbgBufferType::bufSlcParams,
252             CodechalDbgExtType::txt);
253 
254         if (m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrEnableFastDump))
255         {
256             MediaDebugFastDump::Dump(
257                 (uint8_t *)sliceParams,
258                 fileName,
259                 sizeof(CodecDecodeMpeg2SliceParams) * numSlices,
260                 0,
261                 MediaDebugSerializer<CodecDecodeMpeg2SliceParams>());
262         }
263         else
264         {
265             DumpDecodeMpeg2SliceParams(sliceParams, numSlices, fileName);
266         }
267     }
268 
269     return MOS_STATUS_SUCCESS;
270 }
271 
DumpMbParams(CodecDecodeMpeg2MbParams * mbParams,uint32_t numMbs)272 MOS_STATUS Mpeg2Pipeline::DumpMbParams(
273     CodecDecodeMpeg2MbParams *mbParams,
274     uint32_t                  numMbs)
275 {
276     DECODE_FUNC_CALL();
277 
278     if (mbParams == nullptr)
279     {
280         return MOS_STATUS_SUCCESS;
281     }
282 
283     if (m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrMbParams))
284     {
285         const char *fileName = m_debugInterface->CreateFileName(
286             "_DEC",
287             CodechalDbgBufferType::bufMbParams,
288             CodechalDbgExtType::txt);
289 
290         if (m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrEnableFastDump))
291         {
292             MediaDebugFastDump::Dump(
293                 (uint8_t *)mbParams,
294                 fileName,
295                 sizeof(CodecDecodeMpeg2MbParams) * numMbs,
296                 0,
297                 MediaDebugSerializer<CodecDecodeMpeg2MbParams>());
298         }
299         else
300         {
301             DumpDecodeMpeg2MbParams(mbParams, numMbs, fileName);
302         }
303     }
304 
305     return MOS_STATUS_SUCCESS;
306 }
307 
DumpIQParams(CodecMpeg2IqMatrix * iqParams)308 MOS_STATUS Mpeg2Pipeline::DumpIQParams(
309     CodecMpeg2IqMatrix *iqParams)
310 {
311     DECODE_FUNC_CALL();
312 
313     if (iqParams == nullptr)
314     {
315         return MOS_STATUS_SUCCESS;
316     }
317 
318     if (m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrIqParams))
319     {
320         const char *fileName = m_debugInterface->CreateFileName(
321             "_DEC",
322             CodechalDbgBufferType::bufIqParams,
323             CodechalDbgExtType::txt);
324 
325         if (m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrEnableFastDump))
326         {
327             MediaDebugFastDump::Dump(
328                 (uint8_t *)iqParams,
329                 fileName,
330                 sizeof(CodecMpeg2IqMatrix),
331                 0,
332                 MediaDebugSerializer<CodecMpeg2IqMatrix>());
333         }
334         else
335         {
336             DumpDecodeMpeg2IqParams(iqParams, fileName);
337         }
338     }
339 
340     return MOS_STATUS_SUCCESS;
341 }
342 #endif
343 
344 }
345