1 /*
2 * Copyright (c) 2021-2023, 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_xe_lpm_plus_base.cpp
24 //! \brief    Defines the interface for mpeg2 decode pipeline
25 //!
26 #include "decode_mpeg2_pipeline_xe_lpm_plus_base.h"
27 #include "decode_utils.h"
28 #include "decode_mpeg2_mem_compression_xe_lpm_plus_base.h"
29 #include "decode_mpeg2_packet_xe_lpm_plus_base.h"
30 #include "decode_mpeg2_slice_packet_xe_lpm_plus_base.h"
31 #include "decode_mpeg2_mb_packet_xe_lpm_plus_base.h"
32 #include "decode_mpeg2_picture_packet_xe_lpm_plus_base.h"
33 #include "decode_common_feature_defs.h"
34 
35 namespace decode
36 {
Mpeg2PipelineXe_Lpm_Plus_Base(CodechalHwInterfaceNext * hwInterface,CodechalDebugInterface * debugInterface)37 Mpeg2PipelineXe_Lpm_Plus_Base::Mpeg2PipelineXe_Lpm_Plus_Base(
38     CodechalHwInterfaceNext *   hwInterface,
39     CodechalDebugInterface *debugInterface)
40     : Mpeg2Pipeline(hwInterface, debugInterface)
41 {
42 }
43 
Init(void * settings)44 MOS_STATUS Mpeg2PipelineXe_Lpm_Plus_Base::Init(void *settings)
45 {
46     DECODE_FUNC_CALL();
47 
48     DECODE_CHK_NULL(settings);
49     DECODE_CHK_STATUS(Initialize(settings));
50 
51     m_mpeg2DecodePkt = MOS_New(Mpeg2DecodePktXe_Lpm_Plus_Base, this, m_task, m_hwInterface);
52     DECODE_CHK_STATUS(RegisterPacket(DecodePacketId(this, mpeg2DecodePacketId), m_mpeg2DecodePkt));
53     DECODE_CHK_STATUS(m_mpeg2DecodePkt->Init());
54 
55     return MOS_STATUS_SUCCESS;
56 }
57 
GetStatusReport(void * status,uint16_t numStatus)58 MOS_STATUS Mpeg2PipelineXe_Lpm_Plus_Base::GetStatusReport(void *status, uint16_t numStatus)
59 {
60     DECODE_FUNC_CALL();
61 
62     m_statusReport->GetReport(numStatus, status);
63 
64     return MOS_STATUS_SUCCESS;
65 }
66 
GetCompletedReport()67 uint32_t Mpeg2PipelineXe_Lpm_Plus_Base::GetCompletedReport()
68 {
69     DECODE_FUNC_CALL();
70 
71     uint32_t completedCount = m_statusReport->GetCompletedCount();
72     uint32_t reportedCount  = m_statusReport->GetReportedCount();
73 
74     if (reportedCount > completedCount)
75     {
76         DECODE_ASSERTMESSAGE("No report available at all");
77         return 0;
78     }
79     else
80     {
81         uint32_t availableCount = completedCount - reportedCount;
82         return availableCount;
83     }
84 }
85 
Destroy()86 MOS_STATUS Mpeg2PipelineXe_Lpm_Plus_Base::Destroy()
87 {
88     DECODE_FUNC_CALL();
89 
90     Uninitialize();
91 
92     return MOS_STATUS_SUCCESS;
93 }
94 
Initialize(void * settings)95 MOS_STATUS Mpeg2PipelineXe_Lpm_Plus_Base::Initialize(void *settings)
96 {
97     DECODE_FUNC_CALL();
98 
99     DECODE_CHK_STATUS(Mpeg2Pipeline::Initialize(settings));
100 #ifdef _MMC_SUPPORTED
101     DECODE_CHK_STATUS(InitMmcState());
102 #endif
103 
104     return MOS_STATUS_SUCCESS;
105 }
106 
CreateSubPackets(DecodeSubPacketManager & subPacketManager,CodechalSetting & codecSettings)107 MOS_STATUS Mpeg2PipelineXe_Lpm_Plus_Base::CreateSubPackets(DecodeSubPacketManager &subPacketManager, CodechalSetting &codecSettings)
108 {
109     DECODE_CHK_STATUS(Mpeg2Pipeline::CreateSubPackets(subPacketManager, codecSettings));
110 
111     Mpeg2DecodePicPktXe_Lpm_Plus_Base *pictureDecodePkt = MOS_New(Mpeg2DecodePicPktXe_Lpm_Plus_Base, this, m_hwInterface);
112     DECODE_CHK_NULL(pictureDecodePkt);
113     DECODE_CHK_STATUS(subPacketManager.Register(
114         DecodePacketId(this, mpeg2PictureSubPacketId), *pictureDecodePkt));
115 
116     if (codecSettings.mode == CODECHAL_DECODE_MODE_MPEG2VLD)
117     {
118         Mpeg2DecodeSlcPktXe_Lpm_Plus_Base *sliceDecodePkt = MOS_New(Mpeg2DecodeSlcPktXe_Lpm_Plus_Base, this, m_hwInterface);
119         DECODE_CHK_NULL(sliceDecodePkt);
120         DECODE_CHK_STATUS(subPacketManager.Register(
121             DecodePacketId(this, mpeg2SliceSubPacketId), *sliceDecodePkt));
122     }
123     else
124     {
125         Mpeg2DecodeMbPktXe_Lpm_Plus_Base *mbDecodePkt = MOS_New(Mpeg2DecodeMbPktXe_Lpm_Plus_Base, this, m_hwInterface);
126         DECODE_CHK_NULL(mbDecodePkt);
127         DECODE_CHK_STATUS(subPacketManager.Register(
128             DecodePacketId(this, mpeg2MbSubPacketId), *mbDecodePkt));
129     }
130 
131     return MOS_STATUS_SUCCESS;
132 }
133 
Uninitialize()134 MOS_STATUS Mpeg2PipelineXe_Lpm_Plus_Base::Uninitialize()
135 {
136     DECODE_FUNC_CALL();
137 
138     for (auto pair : m_packetList)
139     {
140         pair.second->Destroy();
141     }
142 
143     if (m_mmcState != nullptr)
144     {
145         MOS_Delete(m_mmcState);
146     }
147 
148     return DecodePipeline::Uninitialize();
149 }
150 
InitContext()151 MOS_STATUS Mpeg2PipelineXe_Lpm_Plus_Base::InitContext()
152 {
153     DECODE_FUNC_CALL();
154 
155     DecodeScalabilityPars scalPars;
156     MOS_ZeroMemory(&scalPars, sizeof(scalPars));
157     scalPars.disableScalability = true;
158     scalPars.disableRealTile    = true;
159     scalPars.enableVE           = MOS_VE_SUPPORTED(m_osInterface);
160     scalPars.numVdbox           = m_numVdbox;
161     m_mediaContext->SwitchContext(VdboxDecodeFunc, &scalPars, &m_scalability);
162     DECODE_CHK_NULL(m_scalability);
163 
164     return MOS_STATUS_SUCCESS;
165 }
166 
Prepare(void * params)167 MOS_STATUS Mpeg2PipelineXe_Lpm_Plus_Base::Prepare(void *params)
168 {
169     DecodePipelineParams *pipelineParams = (DecodePipelineParams *)params;
170     m_pipeMode                           = pipelineParams->m_pipeMode;
171 
172     PERF_UTILITY_AUTO((__FUNCTION__ + std::to_string((int)m_pipeMode)).c_str(), PERF_DECODE, PERF_LEVEL_HAL);
173 
174     if (m_pipeMode == decodePipeModeProcess)
175     {
176         DECODE_CHK_STATUS(Mpeg2Pipeline::Prepare(params));
177     }
178 
179     DECODE_CHK_STATUS(m_preSubPipeline->Prepare(*pipelineParams));
180     DECODE_CHK_STATUS(m_postSubPipeline->Prepare(*pipelineParams));
181 
182     if (IsFirstProcessPipe(*pipelineParams))
183     {
184         CODECHAL_DEBUG_TOOL(DECODE_CHK_STATUS(DumpParams(*m_basicFeature)));
185         DecodeStatusParameters inputParameters = {};
186         MOS_ZeroMemory(&inputParameters, sizeof(DecodeStatusParameters));
187         inputParameters.statusReportFeedbackNumber = m_basicFeature->m_mpeg2PicParams->m_statusReportFeedbackNumber;
188         inputParameters.codecFunction              = m_basicFeature->m_codecFunction;
189         inputParameters.picWidthInMb               = m_basicFeature->m_picWidthInMb;
190         inputParameters.pictureCodingType          = m_basicFeature->m_pictureCodingType;
191         inputParameters.currOriginalPic            = m_basicFeature->m_curRenderPic;
192         inputParameters.currDecodedPicRes          = m_basicFeature->m_destSurface.OsResource;
193         inputParameters.numUsedVdbox               = m_numVdbox;
194 
195         CODECHAL_DEBUG_TOOL(
196             if (m_streamout != nullptr)
197             {
198                 DECODE_CHK_STATUS(m_streamout->InitStatusReportParam(inputParameters));
199             }
200         );
201 
202         m_statusReport->Init(&inputParameters);
203     }
204 
205     return MOS_STATUS_SUCCESS;
206 }
207 
Execute()208 MOS_STATUS Mpeg2PipelineXe_Lpm_Plus_Base::Execute()
209 {
210     DECODE_FUNC_CALL();
211 
212     PERF_UTILITY_AUTO((__FUNCTION__ + std::to_string((int)m_pipeMode)).c_str(), PERF_DECODE, PERF_LEVEL_HAL);
213 
214     if (m_pipeMode == decodePipeModeProcess)
215     {
216         DECODE_CHK_STATUS(m_preSubPipeline->Execute());
217 
218         if (!m_basicFeature->m_incompletePicture)
219         {
220             DECODE_CHK_STATUS(InitContext());
221             DECODE_CHK_STATUS(CopyDummyBitstream());
222             DECODE_CHK_STATUS(ActivateDecodePackets());
223             DECODE_CHK_STATUS(ExecuteActivePackets());
224 
225 #if (_DEBUG || _RELEASE_INTERNAL)
226             DECODE_CHK_STATUS(StatusCheck());
227 #ifdef _MMC_SUPPORTED
228             if (m_mmcState != nullptr)
229             {
230                 m_mmcState->ReportSurfaceMmcMode(&(m_basicFeature->m_destSurface));
231             }
232 #endif
233 #endif
234 
235             // Only update user features for the first frame.
236             if (m_basicFeature->m_frameNum == 0)
237             {
238                 DECODE_CHK_STATUS(UserFeatureReport());
239             }
240 
241             if (m_basicFeature->m_secondField || CodecHal_PictureIsFrame(m_basicFeature->m_curRenderPic))
242             {
243                 DecodeFrameIndex++;
244                 m_basicFeature->m_frameNum = DecodeFrameIndex;
245             }
246 
247             DECODE_CHK_STATUS(m_statusReport->Reset());
248         }
249         DECODE_CHK_STATUS(m_postSubPipeline->Execute());
250     }
251     else if (m_pipeMode == decodePipeModeEnd)
252     {
253         if (m_basicFeature->m_incompletePicture)
254         {
255             // Insert phantom slices in EndFrame call if it is still an incomplete
256             // picture and submit mpeg2 decode command buffer at this time.
257             DECODE_CHK_STATUS(CopyDummyBitstream());
258             DECODE_CHK_STATUS(ActivateDecodePackets());
259             DECODE_CHK_STATUS(ExecuteActivePackets());
260 
261             // Only update user features for the first frame.
262             if (m_basicFeature->m_frameNum == 0)
263             {
264                 DECODE_CHK_STATUS(UserFeatureReport());
265             }
266 
267             if (m_basicFeature->m_secondField || CodecHal_PictureIsFrame(m_basicFeature->m_curRenderPic))
268             {
269                 DecodeFrameIndex++;
270                 m_basicFeature->m_frameNum = DecodeFrameIndex;
271             }
272 
273             DECODE_CHK_STATUS(m_statusReport->Reset());
274         }
275     }
276 
277     return MOS_STATUS_SUCCESS;
278 }
279 
280 #ifdef _MMC_SUPPORTED
InitMmcState()281 MOS_STATUS Mpeg2PipelineXe_Lpm_Plus_Base::InitMmcState()
282 {
283     DECODE_FUNC_CALL();
284 
285     m_mmcState = MOS_New(Mpeg2DecodeMemCompXe_Lpm_Plus_Base, m_hwInterface);
286     DECODE_CHK_NULL(m_mmcState);
287     DECODE_CHK_STATUS(m_basicFeature->SetMmcState(m_mmcState->IsMmcEnabled()));
288 
289     return MOS_STATUS_SUCCESS;
290 }
291 #endif
292 
UserFeatureReport()293 MOS_STATUS Mpeg2PipelineXe_Lpm_Plus_Base::UserFeatureReport()
294 {
295     DECODE_FUNC_CALL();
296     return Mpeg2Pipeline::UserFeatureReport();
297 }
298 
299 #if USE_CODECHAL_DEBUG_TOOL
DumpParams(Mpeg2BasicFeature & basicFeature)300 MOS_STATUS Mpeg2PipelineXe_Lpm_Plus_Base::DumpParams(Mpeg2BasicFeature &basicFeature)
301 {
302     m_debugInterface->m_frameType          = basicFeature.m_pictureCodingType;
303     m_debugInterface->m_currPic            = basicFeature.m_curRenderPic;
304     m_debugInterface->m_secondField        = basicFeature.m_secondField;
305     m_debugInterface->m_bufferDumpFrameNum = basicFeature.m_frameNum;
306 
307     DECODE_CHK_STATUS(DumpPicParams(basicFeature.m_mpeg2PicParams));
308     DECODE_CHK_STATUS(DumpSliceParams(basicFeature.m_mpeg2SliceParams, basicFeature.m_numSlices));
309     DECODE_CHK_STATUS(DumpMbParams(basicFeature.m_mpeg2MbParams, basicFeature.m_numMacroblocks));
310     DECODE_CHK_STATUS(DumpIQParams(basicFeature.m_mpeg2IqMatrixBuffer));
311     DECODE_CHK_STATUS(DumpBitstream(&basicFeature.m_resDataBuffer.OsResource, basicFeature.m_dataSize, 0));
312 
313     return MOS_STATUS_SUCCESS;
314 }
315 
316 #endif
317 }  // namespace decode
318