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