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