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_jpeg_pipeline_m12.cpp
24 //! \brief    Defines the interface for jpeg decode pipeline
25 //!
26 #include "decode_jpeg_pipeline_m12.h"
27 #include "decode_utils.h"
28 #include "decode_jpeg_packet_m12.h"
29 #include "decode_jpeg_picture_packet_m12.h"
30 #include "decode_common_feature_defs.h"
31 #include "decode_mem_compression_g12.h"
32 #include "decode_sfc_histogram_postsubpipeline_m12.h"
33 #include "decode_jpeg_feature_manager.h"
34 #include "decode_input_bitstream_m12.h"
35 #include "decode_cp_bitstream_m12.h"
36 #include "decode_marker_packet_g12.h"
37 #include "decode_predication_packet_g12.h"
38 
39 namespace decode
40 {
JpegPipelineM12(CodechalHwInterface * hwInterface,CodechalDebugInterface * debugInterface)41 JpegPipelineM12::JpegPipelineM12(
42     CodechalHwInterface *   hwInterface,
43     CodechalDebugInterface *debugInterface)
44     : JpegPipeline(*hwInterface, debugInterface)
45 {
46     m_hwInterface = hwInterface;
47 }
48 
Init(void * settings)49 MOS_STATUS JpegPipelineM12::Init(void *settings)
50 {
51     DECODE_FUNC_CALL();
52 
53     DECODE_CHK_NULL(settings);
54     DECODE_CHK_STATUS(Initialize(settings));
55 
56     m_jpegDecodePkt = MOS_New(JpegDecodePktM12, this, m_task, m_hwInterface);
57     DECODE_CHK_STATUS(RegisterPacket(DecodePacketId(this, jpegDecodePacketId), m_jpegDecodePkt));
58     DECODE_CHK_STATUS(m_jpegDecodePkt->Init());
59 
60     return MOS_STATUS_SUCCESS;
61 }
62 
GetStatusReport(void * status,uint16_t numStatus)63 MOS_STATUS JpegPipelineM12::GetStatusReport(void *status, uint16_t numStatus)
64 {
65     DECODE_FUNC_CALL();
66 
67     m_statusReport->GetReport(numStatus, status);
68 
69     return MOS_STATUS_SUCCESS;
70 }
71 
GetCompletedReport()72 uint32_t JpegPipelineM12::GetCompletedReport()
73 {
74     DECODE_FUNC_CALL();
75 
76     uint32_t completedCount = m_statusReport->GetCompletedCount();
77     uint32_t reportedCount  = m_statusReport->GetReportedCount();
78 
79     if (reportedCount > completedCount)
80     {
81         DECODE_ASSERTMESSAGE("No report available at all");
82         return 0;
83     }
84     else
85     {
86         uint32_t availableCount = completedCount - reportedCount;
87         return availableCount;
88     }
89 }
90 
Destroy()91 MOS_STATUS JpegPipelineM12::Destroy()
92 {
93     DECODE_FUNC_CALL();
94 
95     Uninitialize();
96 
97     return MOS_STATUS_SUCCESS;
98 }
99 
CreateFeatureManager()100 MOS_STATUS JpegPipelineM12::CreateFeatureManager()
101 {
102     DECODE_FUNC_CALL();
103     m_featureManager = MOS_New(DecodeJpegFeatureManager, m_allocator, m_hwInterface, m_osInterface);
104     DECODE_CHK_NULL(m_featureManager);
105     return MOS_STATUS_SUCCESS;
106 }
107 
Initialize(void * settings)108 MOS_STATUS JpegPipelineM12::Initialize(void *settings)
109 {
110     DECODE_FUNC_CALL();
111 
112     DECODE_CHK_STATUS(MediaPipeline::InitPlatform());
113     DECODE_CHK_STATUS(MediaPipeline::CreateMediaCopyWrapper());
114     DECODE_CHK_NULL(m_mediaCopyWrapper);
115 
116     DECODE_CHK_NULL(m_waTable);
117 
118     auto *codecSettings = (CodechalSetting *)settings;
119     DECODE_CHK_NULL(m_hwInterface);
120     DECODE_CHK_STATUS(m_hwInterface->Initialize(codecSettings));
121 
122     if (m_mediaCopyWrapper->MediaCopyStateIsNull())
123     {
124         m_mediaCopyWrapper->SetMediaCopyState(m_hwInterface->CreateMediaCopy(m_osInterface));
125     }
126 
127     CODECHAL_DEBUG_TOOL(
128         m_debugInterface = MOS_New(CodechalDebugInterface);
129         DECODE_CHK_NULL(m_debugInterface);
130         DECODE_CHK_STATUS(
131             m_debugInterface->Initialize(m_hwInterface, codecSettings->codecFunction, m_mediaCopyWrapper)););
132 
133     if (m_hwInterface->m_hwInterfaceNext)
134     {
135         m_hwInterface->m_hwInterfaceNext->legacyHwInterface = m_hwInterface;
136     }
137     m_mediaContext = MOS_New(MediaContext, scalabilityDecoder, m_hwInterface->m_hwInterfaceNext, m_osInterface);
138     DECODE_CHK_NULL(m_mediaContext);
139 
140     m_task = CreateTask(MediaTask::TaskType::cmdTask);
141     DECODE_CHK_NULL(m_task);
142 
143     m_numVdbox = GetSystemVdboxNumber();
144 
145     bool limitedLMemBar = MEDIA_IS_SKU(m_skuTable, FtrLimitedLMemBar) ? true : false;
146     m_allocator         = MOS_New(DecodeAllocator, m_osInterface, limitedLMemBar);
147     DECODE_CHK_NULL(m_allocator);
148 
149     DECODE_CHK_STATUS(CreateStatusReport());
150 
151     m_decodecp = Create_DecodeCpInterface(codecSettings, m_hwInterface->GetCpInterface(), m_hwInterface->GetOsInterface());
152     if (m_decodecp)
153     {
154         DECODE_CHK_STATUS(m_decodecp->RegisterParams(codecSettings));
155     }
156     DECODE_CHK_STATUS(CreateFeatureManager());
157     DECODE_CHK_STATUS(m_featureManager->Init(codecSettings));
158 
159     DECODE_CHK_STATUS(CreateSubPipeLineManager(codecSettings));
160     DECODE_CHK_STATUS(CreateSubPacketManager(codecSettings));
161 
162     m_basicFeature = dynamic_cast<JpegBasicFeature *>(m_featureManager->GetFeature(FeatureIDs::basicFeature));
163     DECODE_CHK_NULL(m_basicFeature);
164 
165     // Create basic GPU context
166     DecodeScalabilityPars scalPars;
167     MOS_ZeroMemory(&scalPars, sizeof(scalPars));
168     DECODE_CHK_STATUS(m_mediaContext->SwitchContext(VdboxDecodeFunc, &scalPars, &m_scalability));
169     m_decodeContext = m_osInterface->pfnGetGpuContext(m_osInterface);
170 
171 #ifdef _MMC_SUPPORTED
172     DECODE_CHK_STATUS(InitMmcState());
173 #endif
174 
175     return MOS_STATUS_SUCCESS;
176 }
177 
CreateSubPackets(DecodeSubPacketManager & subPacketManager,CodechalSetting & codecSettings)178 MOS_STATUS JpegPipelineM12::CreateSubPackets(DecodeSubPacketManager &subPacketManager, CodechalSetting &codecSettings)
179 {
180     DecodePredicationPktG12 *predicationPkt = MOS_New(DecodePredicationPktG12, this, m_hwInterface);
181     DECODE_CHK_NULL(predicationPkt);
182     DECODE_CHK_STATUS(subPacketManager.Register(
183         DecodePacketId(this, predicationSubPacketId), *predicationPkt));
184 
185     DecodeMarkerPktG12 *markerPkt = MOS_New(DecodeMarkerPktG12, this, m_hwInterface);
186     DECODE_CHK_NULL(markerPkt);
187     DECODE_CHK_STATUS(subPacketManager.Register(
188         DecodePacketId(this, markerSubPacketId), *markerPkt));
189 
190 #ifdef _DECODE_PROCESSING_SUPPORTED
191     JpegDownSamplingPkt *downSamplingPkt = MOS_New(JpegDownSamplingPkt, this, *m_hwInterface);
192     DECODE_CHK_NULL(downSamplingPkt);
193     DECODE_CHK_STATUS(subPacketManager.Register(
194         DecodePacketId(this, downSamplingSubPacketId), *downSamplingPkt));
195 #endif
196 
197     JpegDecodePicPktM12 *pictureDecodePkt = MOS_New(JpegDecodePicPktM12, this, m_hwInterface);
198     DECODE_CHK_NULL(pictureDecodePkt);
199     DECODE_CHK_STATUS(subPacketManager.Register(
200         DecodePacketId(this, jpegPictureSubPacketId), *pictureDecodePkt));
201 
202     return MOS_STATUS_SUCCESS;
203 }
204 
Uninitialize()205 MOS_STATUS JpegPipelineM12::Uninitialize()
206 {
207     DECODE_FUNC_CALL();
208 
209     for (auto pair : m_packetList)
210     {
211         pair.second->Destroy();
212     }
213 
214     if (m_mmcState != nullptr)
215     {
216         MOS_Delete(m_mmcState);
217     }
218 
219     return DecodePipeline::Uninitialize();
220 }
221 
InitContext()222 MOS_STATUS JpegPipelineM12::InitContext()
223 {
224     DECODE_FUNC_CALL();
225 
226     DecodeScalabilityPars scalPars;
227     MOS_ZeroMemory(&scalPars, sizeof(scalPars));
228     scalPars.disableScalability = true;
229     scalPars.disableRealTile    = true;
230     scalPars.enableVE           = MOS_VE_SUPPORTED(m_osInterface);
231     scalPars.numVdbox           = m_numVdbox;
232 #ifdef _DECODE_PROCESSING_SUPPORTED
233     DecodeDownSamplingFeature *downSamplingFeature = dynamic_cast<DecodeDownSamplingFeature *>(
234         m_featureManager->GetFeature(DecodeFeatureIDs::decodeDownSampling));
235     if (downSamplingFeature != nullptr && downSamplingFeature->IsEnabled())
236     {
237         scalPars.usingSfc = true;
238     }
239 #endif
240     m_mediaContext->SwitchContext(VdboxDecodeFunc, &scalPars, &m_scalability);
241     DECODE_CHK_NULL(m_scalability);
242 
243     if (scalPars.disableScalability)
244         m_osInterface->pfnSetMultiEngineEnabled(m_osInterface, COMPONENT_Decode, false);
245 
246     return MOS_STATUS_SUCCESS;
247 }
248 
Prepare(void * params)249 MOS_STATUS JpegPipelineM12::Prepare(void *params)
250 {
251     DecodePipelineParams *pipelineParams = (DecodePipelineParams *)params;
252     m_pipeMode                           = pipelineParams->m_pipeMode;
253 
254     PERF_UTILITY_AUTO((__FUNCTION__ + std::to_string((int)m_pipeMode)).c_str(), PERF_DECODE, PERF_LEVEL_HAL);
255 
256     if (IsFirstProcessPipe(*pipelineParams))
257     {
258         DECODE_CHK_STATUS(JpegPipeline::Prepare(params));
259     }
260 
261     DECODE_CHK_STATUS(m_preSubPipeline->Prepare(*pipelineParams));
262     DECODE_CHK_STATUS(m_postSubPipeline->Prepare(*pipelineParams));
263 
264     if (m_pipeMode == decodePipeModeProcess)
265     {
266         if (IsCompleteBitstream())
267         {
268             CODECHAL_DEBUG_TOOL(DECODE_CHK_STATUS(DumpParams(*m_basicFeature)));
269 
270             DecodeStatusParameters inputParameters = {};
271             MOS_ZeroMemory(&inputParameters, sizeof(DecodeStatusParameters));
272             inputParameters.statusReportFeedbackNumber = m_basicFeature->m_jpegPicParams->m_statusReportFeedbackNumber;
273             inputParameters.codecFunction              = m_basicFeature->m_codecFunction;
274             inputParameters.picWidthInMb               = m_basicFeature->m_picWidthInMb;
275             inputParameters.pictureCodingType          = m_basicFeature->m_pictureCodingType;
276             inputParameters.currOriginalPic            = m_basicFeature->m_curRenderPic;
277             inputParameters.currDecodedPicRes          = m_basicFeature->m_destSurface.OsResource;
278             inputParameters.numUsedVdbox               = m_numVdbox;
279 
280             CODECHAL_DEBUG_TOOL(
281                 if (m_streamout != nullptr)
282                 {
283                     DECODE_CHK_STATUS(m_streamout->InitStatusReportParam(inputParameters));
284                 }
285             );
286 
287 #if (_DEBUG || _RELEASE_INTERNAL)
288 #ifdef _DECODE_PROCESSING_SUPPORTED
289             DecodeDownSamplingFeature *downSamplingFeature = dynamic_cast<DecodeDownSamplingFeature *>(
290                 m_featureManager->GetFeature(DecodeFeatureIDs::decodeDownSampling));
291             if (downSamplingFeature != nullptr)
292             {
293                 auto frameIdx                   = m_basicFeature->m_curRenderPic.FrameIdx;
294                 inputParameters.sfcOutputSurface = &downSamplingFeature->m_outputSurfaceList[frameIdx];
295                 CODECHAL_DEBUG_TOOL(DumpDownSamplingParams(*downSamplingFeature));
296             }
297 #endif
298 #endif
299             m_statusReport->Init(&inputParameters);
300         }
301     }
302 
303     return MOS_STATUS_SUCCESS;
304 }
305 
Execute()306 MOS_STATUS JpegPipelineM12::Execute()
307 {
308     DECODE_FUNC_CALL();
309 
310     PERF_UTILITY_AUTO((__FUNCTION__ + std::to_string((int)m_pipeMode)).c_str(), PERF_DECODE, PERF_LEVEL_HAL);
311 
312     if (m_pipeMode == decodePipeModeProcess)
313     {
314         DECODE_CHK_STATUS(m_preSubPipeline->Execute());
315 
316         if (IsCompleteBitstream())
317         {
318             DECODE_CHK_STATUS(InitContext());
319             DECODE_CHK_STATUS(ActivateDecodePackets());
320             DECODE_CHK_STATUS(ExecuteActivePackets());
321 
322 #if (_DEBUG || _RELEASE_INTERNAL)
323             DECODE_CHK_STATUS(StatusCheck());
324 #endif
325             // Only update user features for the first frame.
326             if (m_basicFeature->m_frameNum == 0)
327             {
328                 DECODE_CHK_STATUS(UserFeatureReport());
329             }
330 
331             DecodeFrameIndex++;
332             m_basicFeature->m_frameNum = DecodeFrameIndex;
333 
334             DECODE_CHK_STATUS(m_statusReport->Reset());
335         }
336         DECODE_CHK_STATUS(m_postSubPipeline->Execute());
337     }
338     return MOS_STATUS_SUCCESS;
339 }
340 
341 #ifdef _MMC_SUPPORTED
InitMmcState()342 MOS_STATUS JpegPipelineM12::InitMmcState()
343 {
344     DECODE_FUNC_CALL();
345 
346     DECODE_CHK_NULL(m_hwInterface);
347     m_mmcState = MOS_New(DecodeMemCompG12, m_hwInterface);
348     DECODE_CHK_NULL(m_mmcState);
349 
350     DECODE_CHK_STATUS(m_basicFeature->SetMmcState(m_mmcState->IsMmcEnabled()));
351 
352     return MOS_STATUS_SUCCESS;
353 }
354 #endif
355 
UserFeatureReport()356 MOS_STATUS JpegPipelineM12::UserFeatureReport()
357 {
358     DECODE_FUNC_CALL();
359     return JpegPipeline::UserFeatureReport();
360 }
361 
CreatePostSubPipeLines(DecodeSubPipelineManager & subPipelineManager)362 MOS_STATUS JpegPipelineM12::CreatePostSubPipeLines(DecodeSubPipelineManager &subPipelineManager)
363 {
364     DECODE_FUNC_CALL();
365 
366 #ifdef _DECODE_PROCESSING_SUPPORTED
367     auto sfcHistogramPostSubPipeline = MOS_New(DecodeSfcHistogramSubPipelineM12, this, m_task, m_numVdbox, m_hwInterface);
368     DECODE_CHK_NULL(sfcHistogramPostSubPipeline);
369     DECODE_CHK_STATUS(m_postSubPipeline->Register(*sfcHistogramPostSubPipeline));
370 #endif
371 
372     return MOS_STATUS_SUCCESS;
373 }
374 
CreatePreSubPipeLines(DecodeSubPipelineManager & subPipelineManager)375 MOS_STATUS JpegPipelineM12::CreatePreSubPipeLines(DecodeSubPipelineManager &subPipelineManager)
376 {
377     m_bitstream = MOS_New(DecodeJpegInputBitstreamM12, this, m_task, m_numVdbox, m_hwInterface);
378     DECODE_CHK_NULL(m_bitstream);
379     DECODE_CHK_STATUS(subPipelineManager.Register(*m_bitstream));
380 
381     return MOS_STATUS_SUCCESS;
382 }
383 
384 #if USE_CODECHAL_DEBUG_TOOL
DumpParams(JpegBasicFeature & basicFeature)385 MOS_STATUS JpegPipelineM12::DumpParams(JpegBasicFeature &basicFeature)
386 {
387     m_debugInterface->m_frameType          = basicFeature.m_pictureCodingType;
388     m_debugInterface->m_currPic            = basicFeature.m_curRenderPic;
389     m_debugInterface->m_secondField        = basicFeature.m_secondField;
390     m_debugInterface->m_bufferDumpFrameNum = basicFeature.m_frameNum;
391 
392     DECODE_CHK_STATUS(DumpPicParams(basicFeature.m_jpegPicParams));
393     DECODE_CHK_STATUS(DumpScanParams(basicFeature.m_jpegScanParams));
394     DECODE_CHK_STATUS(DumpHuffmanTable(basicFeature.m_jpegHuffmanTable));
395     DECODE_CHK_STATUS(DumpIQParams(basicFeature.m_jpegQMatrix));
396     DECODE_CHK_STATUS(DumpBitstream(&basicFeature.m_resDataBuffer.OsResource, basicFeature.m_dataSize, 0));
397 
398     return MOS_STATUS_SUCCESS;
399 }
400 
401 #endif
402 }  // namespace decode
403