1 /*
2 * Copyright (c) 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_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 "media_user_settings_mgr_g12.h"
29 #include "codechal_setting.h"
30 #include "decode_mpeg2_feature_manager.h"
31 #include "decode_huc_packet_creator.h"
32
33 namespace decode{
34
Mpeg2Pipeline(CodechalHwInterface * hwInterface,CodechalDebugInterface * debugInterface)35 Mpeg2Pipeline::Mpeg2Pipeline(
36 CodechalHwInterface * hwInterface,
37 CodechalDebugInterface *debugInterface)
38 : DecodePipeline(hwInterface, debugInterface)
39 {
40 }
41
Initialize(void * settings)42 MOS_STATUS Mpeg2Pipeline::Initialize(void *settings)
43 {
44 DECODE_FUNC_CALL();
45
46 DECODE_CHK_STATUS(DecodePipeline::Initialize(settings));
47 m_basicFeature = dynamic_cast<Mpeg2BasicFeature*>(m_featureManager->GetFeature(FeatureIDs::basicFeature));
48 DECODE_CHK_NULL(m_basicFeature);
49
50 // Create basic GPU context
51 DecodeScalabilityPars scalPars;
52 MOS_ZeroMemory(&scalPars, sizeof(scalPars));
53 DECODE_CHK_STATUS(m_mediaContext->SwitchContext(VdboxDecodeFunc, &scalPars, &m_scalability));
54 m_decodeContext = m_osInterface->pfnGetGpuContext(m_osInterface);
55
56 HucPacketCreatorBase *hucPktCreator = dynamic_cast<HucPacketCreatorBase *>(this);
57 DECODE_CHK_NULL(hucPktCreator);
58 m_mpeg2BsCopyPkt = hucPktCreator->CreateHucCopyPkt(this, m_task, m_hwInterface);
59 DECODE_CHK_NULL(m_mpeg2BsCopyPkt);
60 MediaPacket *packet = dynamic_cast<MediaPacket *>(m_mpeg2BsCopyPkt);
61 DECODE_CHK_NULL(packet);
62 DECODE_CHK_STATUS(RegisterPacket(DecodePacketId(this, mpeg2BsCopyPktId), packet));
63 DECODE_CHK_STATUS(packet->Init());
64
65 return MOS_STATUS_SUCCESS;
66 }
67
Prepare(void * params)68 MOS_STATUS Mpeg2Pipeline::Prepare(void *params)
69 {
70 DECODE_FUNC_CALL();
71
72 DECODE_CHK_NULL(params);
73 DECODE_CHK_STATUS(DecodePipeline::Prepare(params));
74 DECODE_CHK_STATUS(CopyBitstreamBuffer());
75
76 return MOS_STATUS_SUCCESS;
77 }
78
CopyDummyBitstream()79 MOS_STATUS Mpeg2Pipeline::CopyDummyBitstream()
80 {
81 DECODE_FUNC_CALL();
82
83 HucCopyPktItf::HucCopyParams copyParams = {};
84
85 for (uint16_t slcIdx = 0; slcIdx < m_basicFeature->m_totalNumSlicesRecv; slcIdx++)
86 {
87 // Copy dummy slice to local buffer
88 if (!m_basicFeature->m_copyDummySlicePresent && ((m_basicFeature->m_sliceRecord[slcIdx].prevSliceMbEnd !=
89 m_basicFeature->m_sliceRecord[slcIdx].sliceStartMbOffset && !m_basicFeature->m_sliceRecord[slcIdx].skip) ||
90 m_basicFeature->m_incompletePicture))
91 {
92 m_basicFeature->m_copyDummySlicePresent = true;
93 copyParams.srcBuffer = &(m_basicFeature->m_resMpeg2DummyBistream->OsResource);
94 copyParams.srcOffset = 0;
95 copyParams.destBuffer = &(m_basicFeature->m_copiedDataBuf->OsResource);
96 copyParams.destOffset = m_basicFeature->m_nextCopiedDataOffset;
97 copyParams.copyLength = sizeof(m_basicFeature->Mpeg2DummyBsBuf);
98 m_mpeg2BsCopyPkt->PushCopyParams(copyParams);
99
100 m_basicFeature->m_dummySliceDataOffset = m_basicFeature->m_nextCopiedDataOffset;
101 }
102 }
103
104 return MOS_STATUS_SUCCESS;
105 }
106
CopyBitstreamBuffer()107 MOS_STATUS Mpeg2Pipeline::CopyBitstreamBuffer()
108 {
109 DECODE_FUNC_CALL();
110
111 HucCopyPktItf::HucCopyParams copyParams = {};
112
113 if (m_basicFeature->m_copiedDataNeeded)
114 {
115 m_basicFeature->m_copiedDataBufferInUse = true;
116 if ((m_basicFeature->m_nextCopiedDataOffset + m_basicFeature->m_dataSize) >
117 m_basicFeature->m_copiedDataBufferSize)
118 {
119 DECODE_ASSERTMESSAGE("Copied data buffer is not large enough.");
120 m_basicFeature->m_slicesInvalid = true;
121 return MOS_STATUS_UNKNOWN;
122 }
123
124 uint32_t size = MOS_ALIGN_CEIL(m_basicFeature->m_dataSize, 16);
125 copyParams.srcBuffer = &(m_basicFeature->m_resDataBuffer.OsResource);
126 copyParams.srcOffset = 0;
127 copyParams.destBuffer = &(m_basicFeature->m_copiedDataBuf->OsResource);
128 copyParams.destOffset = m_basicFeature->m_nextCopiedDataOffset;
129 copyParams.copyLength = m_basicFeature->m_dataSize;
130 m_mpeg2BsCopyPkt->PushCopyParams(copyParams);
131
132 m_basicFeature->m_copiedDataOffset = m_basicFeature->m_nextCopiedDataOffset;
133 m_basicFeature->m_nextCopiedDataOffset += MOS_ALIGN_CEIL(size, MHW_CACHELINE_SIZE);
134
135 bool immediateSubmit = true;
136 DECODE_CHK_STATUS(ActivatePacket(DecodePacketId(this, mpeg2BsCopyPktId), immediateSubmit, 0, 0));
137 m_activePacketList.back().frameTrackingRequested = false;
138 DECODE_CHK_STATUS(ExecuteActivePackets());
139 }
140
141 return MOS_STATUS_SUCCESS;
142 }
143
UserFeatureReport()144 MOS_STATUS Mpeg2Pipeline::UserFeatureReport()
145 {
146 DECODE_FUNC_CALL();
147 DECODE_CHK_STATUS(DecodePipeline::UserFeatureReport());
148 #if (_DEBUG || _RELEASE_INTERNAL)
149 WriteUserFeature(__MEDIA_USER_FEATURE_VALUE_APOGEIOS_MPEG2D_ENABLE_ID, 1, m_osInterface->pOsContext);
150 #endif
151
152 #ifdef _MMC_SUPPORTED
153 CODECHAL_DEBUG_TOOL(
154 if (m_mmcState != nullptr) {
155 m_mmcState->UpdateUserFeatureKey(&(m_basicFeature->m_destSurface));
156 })
157 #endif
158 return MOS_STATUS_SUCCESS;
159 }
160
Uninitialize()161 MOS_STATUS Mpeg2Pipeline::Uninitialize()
162 {
163 DECODE_FUNC_CALL();
164 return DecodePipeline::Uninitialize();
165 }
166
ActivateDecodePackets()167 MOS_STATUS Mpeg2Pipeline::ActivateDecodePackets()
168 {
169 DECODE_FUNC_CALL();
170
171 bool immediateSubmit = false;
172
173 if (m_basicFeature->m_copyDummySlicePresent)
174 {
175 DECODE_CHK_STATUS(ActivatePacket(DecodePacketId(this, mpeg2BsCopyPktId), immediateSubmit, 0, 0));
176 }
177
178 DECODE_CHK_STATUS(ActivatePacket(DecodePacketId(this, mpeg2DecodePacketId), immediateSubmit, 0, 0));
179
180 return MOS_STATUS_SUCCESS;
181 }
182
CreateFeatureManager()183 MOS_STATUS Mpeg2Pipeline::CreateFeatureManager()
184 {
185 DECODE_FUNC_CALL();
186 m_featureManager = MOS_New(DecodeMpeg2FeatureManager, m_allocator, m_hwInterface);
187 DECODE_CHK_NULL(m_featureManager);
188 return MOS_STATUS_SUCCESS;
189 }
190
CreateSubPackets(DecodeSubPacketManager & subPacketManager,CodechalSetting & codecSettings)191 MOS_STATUS Mpeg2Pipeline::CreateSubPackets(DecodeSubPacketManager& subPacketManager, CodechalSetting &codecSettings)
192 {
193 DECODE_FUNC_CALL();
194 DECODE_CHK_STATUS(DecodePipeline::CreateSubPackets(subPacketManager, codecSettings));
195 return MOS_STATUS_SUCCESS;
196 }
197
198 #if USE_CODECHAL_DEBUG_TOOL
DumpPicParams(CodecDecodeMpeg2PicParams * picParams)199 MOS_STATUS Mpeg2Pipeline::DumpPicParams(
200 CodecDecodeMpeg2PicParams *picParams)
201 {
202 DECODE_FUNC_CALL();
203
204 if (!m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrPicParams))
205 {
206 return MOS_STATUS_SUCCESS;
207 }
208
209 DECODE_CHK_NULL(picParams);
210
211 std::ostringstream oss;
212 oss.setf(std::ios::showbase | std::ios::uppercase);
213
214 oss << "m_currPic FrameIdx: " << +picParams->m_currPic.FrameIdx << std::endl;
215 oss << "m_currPic PicFlags: " << +picParams->m_currPic.PicFlags << std::endl;
216 oss << "m_forwardRefIdx: " << +picParams->m_forwardRefIdx << std::endl;
217 oss << "m_backwardRefIdx: " << +picParams->m_backwardRefIdx << std::endl;
218 oss << "m_topFieldFirst: " << +picParams->m_topFieldFirst << std::endl;
219 oss << "m_secondField: " << +picParams->m_secondField << std::endl;
220 oss << "m_statusReportFeedbackNumber: " << +picParams->m_statusReportFeedbackNumber << std::endl;
221 //Dump union w0
222 oss << "w0 m_value: " << +picParams->W0.m_value << std::endl;
223 oss << "m_scanOrder: " << +picParams->W0.m_scanOrder << std::endl;
224 oss << "m_intraVlcFormat: " << +picParams->W0.m_intraVlcFormat << std::endl;
225 oss << "m_quantizerScaleType: " << +picParams->W0.m_quantizerScaleType << std::endl;
226 oss << "m_concealmentMVFlag: " << +picParams->W0.m_concealmentMVFlag << std::endl;
227 oss << "m_frameDctPrediction: " << +picParams->W0.m_frameDctPrediction << std::endl;
228 oss << "m_topFieldFirst: " << +picParams->W0.m_topFieldFirst << std::endl;
229 oss << "m_intraDCPrecision: " << +picParams->W0.m_intraDCPrecision << std::endl;
230 //Dump union w1
231 oss << "w1 m_value: " << +picParams->W1.m_value << std::endl;
232 oss << "m_fcode11: " << +picParams->W1.m_fcode11 << std::endl;
233 oss << "m_fcode10: " << +picParams->W1.m_fcode10 << std::endl;
234 oss << "m_fcode01: " << +picParams->W1.m_fcode01 << std::endl;
235 oss << "m_fcode00: " << +picParams->W1.m_fcode00 << std::endl;
236 oss << "m_horizontalSize: " << +picParams->m_horizontalSize << std::endl;
237 oss << "m_verticalSize: " << +picParams->m_verticalSize << std::endl;
238 oss << "m_pictureCodingType: " << +picParams->m_pictureCodingType << std::endl;
239
240 const char *fileName = m_debugInterface->CreateFileName(
241 "_DEC",
242 CodechalDbgBufferType::bufPicParams,
243 CodechalDbgExtType::txt);
244
245 std::ofstream ofs(fileName, std::ios::out);
246 ofs << oss.str();
247 ofs.close();
248
249 return MOS_STATUS_SUCCESS;
250 }
251
DumpSliceParams(CodecDecodeMpeg2SliceParams * sliceParams,uint32_t numSlices)252 MOS_STATUS Mpeg2Pipeline::DumpSliceParams(
253 CodecDecodeMpeg2SliceParams *sliceParams,
254 uint32_t numSlices)
255 {
256 DECODE_FUNC_CALL();
257
258 if (!m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrSlcParams))
259 {
260 return MOS_STATUS_SUCCESS;
261 }
262
263 DECODE_CHK_NULL(sliceParams);
264
265 const char *fileName = m_debugInterface->CreateFileName(
266 "_DEC",
267 CodechalDbgBufferType::bufSlcParams,
268 CodechalDbgExtType::txt);
269
270 std::ostringstream oss;
271 oss.setf(std::ios::showbase | std::ios::uppercase);
272
273 CodecDecodeMpeg2SliceParams *sliceControl = nullptr;
274
275 for (uint16_t i = 0; i < numSlices; i++)
276 {
277 sliceControl = &sliceParams[i];
278
279 oss << "===================================================================" << std::endl;
280 oss << "Data for Slice number = " << +i << std::endl;
281 oss << "m_sliceDataSize: " << +sliceControl->m_sliceDataSize << std::endl;
282 oss << "m_sliceDataOffset: " << +sliceControl->m_sliceDataOffset << std::endl;
283 oss << "m_macroblockOffset: " << +sliceControl->m_macroblockOffset << std::endl;
284 oss << "m_sliceHorizontalPosition: " << +sliceControl->m_sliceHorizontalPosition << std::endl;
285 oss << "m_sliceVerticalPosition: " << +sliceControl->m_sliceVerticalPosition << std::endl;
286 oss << "m_quantiserScaleCode: " << +sliceControl->m_quantiserScaleCode << std::endl;
287 oss << "m_numMbsForSlice: " << +sliceControl->m_numMbsForSlice << std::endl;
288 oss << "m_numMbsForSliceOverflow: " << +sliceControl->m_numMbsForSliceOverflow << std::endl;
289 oss << "m_reservedBits: " << +sliceControl->m_reservedBits << std::endl;
290 oss << "m_startCodeBitOffset: " << +sliceControl->m_startCodeBitOffset << std::endl;
291
292 std::ofstream ofs;
293 if (i == 0)
294 {
295 ofs.open(fileName, std::ios::out);
296 }
297 else
298 {
299 ofs.open(fileName, std::ios::app);
300 }
301 ofs << oss.str();
302 ofs.close();
303 }
304
305 return MOS_STATUS_SUCCESS;
306 }
307
DumpMbParams(CodecDecodeMpeg2MbParmas * mbParams)308 MOS_STATUS Mpeg2Pipeline::DumpMbParams(
309 CodecDecodeMpeg2MbParmas *mbParams)
310 {
311 DECODE_FUNC_CALL();
312
313 if (!m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrMbParams))
314 {
315 return MOS_STATUS_SUCCESS;
316 }
317
318 DECODE_CHK_NULL(mbParams);
319
320 std::ostringstream oss;
321 oss.setf(std::ios::showbase | std::ios::uppercase);
322
323 oss << "m_mbAddr: " << +mbParams->m_mbAddr << std::endl;
324 //Dump union MBType
325 oss << "MBType.m_intraMb: " << +mbParams->MBType.m_intraMb << std::endl;
326 oss << "MBType.m_motionFwd: " << +mbParams->MBType.m_motionFwd << std::endl;
327 oss << "MBType.m_motionBwd: " << +mbParams->MBType.m_motionBwd << std::endl;
328 oss << "MBType.m_motion4mv: " << +mbParams->MBType.m_motion4mv << std::endl;
329 oss << "MBType.m_h261Lpfilter: " << +mbParams->MBType.m_h261Lpfilter << std::endl;
330 oss << "MBType.m_fieldResidual: " << +mbParams->MBType.m_fieldResidual << std::endl;
331 oss << "MBType.m_mbScanMethod: " << +mbParams->MBType.m_mbScanMethod << std::endl;
332 oss << "MBType.m_motionType: " << +mbParams->MBType.m_motionType << std::endl;
333 oss << "MBType.m_hostResidualDiff: " << +mbParams->MBType.m_hostResidualDiff << std::endl;
334 oss << "MBType.m_mvertFieldSel: " << +mbParams->MBType.m_mvertFieldSel << std::endl;
335 oss << "m_mbSkipFollowing: " << +mbParams->m_mbSkipFollowing << std::endl;
336 oss << "m_mbDataLoc: " << +mbParams->m_mbDataLoc << std::endl;
337 oss << "m_codedBlockPattern: " << +mbParams->m_codedBlockPattern << std::endl;
338
339 //Dump NumCoeff[CODEC_NUM_BLOCK_PER_MB]
340 for (uint16_t i = 0; i < CODEC_NUM_BLOCK_PER_MB; ++i)
341 {
342 oss << "m_numCoeff[" << +i << "]: " << +mbParams->m_numCoeff[i] << std::endl;
343 }
344
345 //Dump motion_vectors[8],printing them in 4 value chunks per line
346 for (uint8_t i = 0; i < 2; ++i)
347 {
348 oss << "m_motionVectors[" << +i * 4 << "-" << (+i * 4) + 3 << "]: ";
349 for (uint8_t j = 0; j < 4; j++)
350 oss << +mbParams->m_motionVectors[i * 4 + j] << " ";
351 oss << std::endl;
352 }
353
354 const char *fileName = m_debugInterface->CreateFileName(
355 "_DEC",
356 CodechalDbgBufferType::bufMbParams,
357 CodechalDbgExtType::txt);
358
359 std::ofstream ofs(fileName, std::ios::out);
360 ofs << oss.str();
361 ofs.close();
362
363 return MOS_STATUS_SUCCESS;
364 }
365
DumpIQParams(CodecMpeg2IqMatrix * matrixData)366 MOS_STATUS Mpeg2Pipeline::DumpIQParams(
367 CodecMpeg2IqMatrix *matrixData)
368 {
369 DECODE_FUNC_CALL();
370
371 if (!m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrIqParams))
372 {
373 return MOS_STATUS_SUCCESS;
374 }
375
376 DECODE_CHK_NULL(matrixData);
377
378 std::ostringstream oss;
379 oss.setf(std::ios::showbase | std::ios::uppercase);
380
381 if (matrixData->m_loadIntraQuantiserMatrix)
382 {
383 oss << "intra_QmatrixData:" << std::endl;
384
385 for (uint8_t i = 0; i < 56; i += 8)
386 {
387 oss << "Qmatrix[" << +i / 8 << "]: ";
388 for (uint8_t j = 0; j < 8; j++)
389 oss << +matrixData->m_intraQuantiserMatrix[i + j] << " ";
390 oss << std::endl;
391 }
392 }
393 if (matrixData->m_loadNonIntraQuantiserMatrix)
394 {
395 oss << "non_intra_QmatrixData:" << std::endl;
396
397 for (uint8_t i = 0; i < 56; i += 8)
398 {
399 oss << "Qmatrix[" << +i / 8 << "]: ";
400 for (uint8_t j = 0; j < 8; j++)
401 oss << +matrixData->m_nonIntraQuantiserMatrix[i + j] << " ";
402 oss << std::endl;
403 }
404 }
405 if (matrixData->m_loadChromaIntraQuantiserMatrix)
406 {
407 oss << "chroma_intra_QmatrixData:" << std::endl;
408
409 for (uint8_t i = 0; i < 56; i += 8)
410 {
411 oss << "Qmatrix[" << +i / 8 << "]: ";
412 for (uint8_t j = 0; j < 8; j++)
413 oss << +matrixData->m_chromaIntraQuantiserMatrix[i + j] << " ";
414 oss << std::endl;
415 }
416 }
417 if (matrixData->m_loadChromaNonIntraQuantiserMatrix)
418 {
419 oss << "chroma_non_intra_QmatrixData:" << std::endl;
420
421 for (uint8_t i = 0; i < 56; i += 8)
422 {
423 oss << "Qmatrix[" << +i / 8 << "]: ";
424 for (uint8_t j = 0; j < 8; j++)
425 oss << +matrixData->m_chromaNonIntraQuantiserMatrix[i + j] << " ";
426 oss << std::endl;
427 }
428 }
429
430 const char *fileName = m_debugInterface->CreateFileName(
431 "_DEC",
432 CodechalDbgBufferType::bufIqParams,
433 CodechalDbgExtType::txt);
434
435 std::ofstream ofs(fileName, std::ios::out);
436 ofs << oss.str();
437 ofs.close();
438 return MOS_STATUS_SUCCESS;
439 }
440 #endif
441
442 }
443