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