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_jpeg_picture_xe_m_base_packet.cpp
24 //! \brief    Defines the interface for jpeg decode picture packet
25 //!
26 #include "codechal_utilities.h"
27 #include "decode_jpeg_picture_xe_m_base_packet.h"
28 #include "codechal_debug.h"
29 #include "decode_common_feature_defs.h"
30 
31 namespace decode{
32 
Init()33 MOS_STATUS JpegDecodePicPktXe_M_Base::Init()
34 {
35     DECODE_FUNC_CALL();
36 
37     DECODE_CHK_NULL(m_featureManager);
38     DECODE_CHK_NULL(m_hwInterface);
39     DECODE_CHK_NULL(m_osInterface);
40     DECODE_CHK_NULL(m_miInterface);
41     DECODE_CHK_NULL(m_jpegPipeline);
42     DECODE_CHK_NULL(m_mfxInterface);
43 
44     m_jpegBasicFeature = dynamic_cast<JpegBasicFeature*>(m_featureManager->GetFeature(FeatureIDs::basicFeature));
45     DECODE_CHK_NULL(m_jpegBasicFeature);
46 
47 #ifdef _DECODE_PROCESSING_SUPPORTED
48     m_downSamplingFeature      = dynamic_cast<DecodeDownSamplingFeature *>(m_featureManager->GetFeature(DecodeFeatureIDs::decodeDownSampling));
49     DecodeSubPacket *subPacket = m_jpegPipeline->GetSubPacket(DecodePacketId(m_jpegPipeline, downSamplingSubPacketId));
50     m_downSamplingPkt          = dynamic_cast<DecodeDownSamplingPkt *>(subPacket);
51 #endif
52 
53     m_allocator = m_pipeline ->GetDecodeAllocator();
54     DECODE_CHK_NULL(m_allocator);
55 
56     DECODE_CHK_STATUS(AllocateFixedResources());
57 
58     return MOS_STATUS_SUCCESS;
59 }
60 
Prepare()61 MOS_STATUS JpegDecodePicPktXe_M_Base::Prepare()
62 {
63     DECODE_FUNC_CALL();
64 
65     m_jpegPicParams = m_jpegBasicFeature->m_jpegPicParams;
66     DECODE_CHK_NULL(m_jpegPicParams);
67 
68 #ifdef _MMC_SUPPORTED
69     m_mmcState = m_jpegPipeline->GetMmcState();
70     DECODE_CHK_NULL(m_mmcState);
71 #endif
72 
73     return MOS_STATUS_SUCCESS;
74 }
75 
AllocateFixedResources()76 MOS_STATUS JpegDecodePicPktXe_M_Base::AllocateFixedResources()
77 {
78     DECODE_FUNC_CALL();
79 
80     return MOS_STATUS_SUCCESS;
81 }
82 
SetMfxPipeModeSelectParams(MHW_VDBOX_PIPE_MODE_SELECT_PARAMS_G12 & pipeModeSelectParams)83 void JpegDecodePicPktXe_M_Base::SetMfxPipeModeSelectParams(MHW_VDBOX_PIPE_MODE_SELECT_PARAMS_G12 &pipeModeSelectParams)
84 {
85     DECODE_FUNC_CALL();
86 
87     pipeModeSelectParams.Mode                      = m_jpegBasicFeature->m_mode;
88     pipeModeSelectParams.bStreamOutEnabled         = false; //Is here correct?
89     pipeModeSelectParams.bDeblockerStreamOutEnable = false;
90     pipeModeSelectParams.bPostDeblockOutEnable     = false;
91     pipeModeSelectParams.bPreDeblockOutEnable      = true;
92 }
93 
SetMfxSurfaceParams(MHW_VDBOX_SURFACE_PARAMS & dstSurfaceParams)94 MOS_STATUS JpegDecodePicPktXe_M_Base::SetMfxSurfaceParams(MHW_VDBOX_SURFACE_PARAMS &dstSurfaceParams)
95 {
96     DECODE_FUNC_CALL();
97 
98     MOS_ZeroMemory(&dstSurfaceParams, sizeof(dstSurfaceParams));
99     dstSurfaceParams.Mode      = m_jpegBasicFeature->m_mode;
100     dstSurfaceParams.psSurface = &m_jpegBasicFeature->m_destSurface;
101     dstSurfaceParams.ChromaType = m_jpegBasicFeature->m_chromaFormat;
102 
103 #ifdef _MMC_SUPPORTED
104     DECODE_CHK_STATUS(m_mmcState->SetSurfaceMmcState(&(m_jpegBasicFeature->m_destSurface)));
105     DECODE_CHK_STATUS(m_mmcState->GetSurfaceMmcState(dstSurfaceParams.psSurface, &dstSurfaceParams.mmcState));
106     DECODE_CHK_STATUS(m_mmcState->GetSurfaceMmcFormat(dstSurfaceParams.psSurface, &dstSurfaceParams.dwCompressionFormat));
107 #endif
108 
109     return MOS_STATUS_SUCCESS;
110 }
111 
AddMfxSurfacesCmd(MOS_COMMAND_BUFFER & cmdBuffer)112 MOS_STATUS JpegDecodePicPktXe_M_Base::AddMfxSurfacesCmd(MOS_COMMAND_BUFFER &cmdBuffer)
113 {
114     DECODE_FUNC_CALL();
115 
116     MHW_VDBOX_SURFACE_PARAMS dstSurfaceParams;
117     DECODE_CHK_STATUS(SetMfxSurfaceParams(dstSurfaceParams));
118     DECODE_CHK_STATUS(m_mfxInterface->AddMfxSurfaceCmd(&cmdBuffer, &dstSurfaceParams));
119 
120     return MOS_STATUS_SUCCESS;
121 }
122 
SetMfxPipeBufAddrParams(MHW_VDBOX_PIPE_BUF_ADDR_PARAMS & pipeBufAddrParams)123 MOS_STATUS JpegDecodePicPktXe_M_Base::SetMfxPipeBufAddrParams(MHW_VDBOX_PIPE_BUF_ADDR_PARAMS &pipeBufAddrParams)
124 {
125     DECODE_FUNC_CALL();
126 
127     pipeBufAddrParams.Mode = m_jpegBasicFeature->m_mode;
128     //Predeblock surface is the same as destination surface here because there is no deblocking for JPEG
129     pipeBufAddrParams.psPreDeblockSurface = &m_jpegBasicFeature->m_destSurface;
130 
131 #ifdef _MMC_SUPPORTED
132     DECODE_CHK_STATUS(m_mmcState->GetSurfaceMmcState(pipeBufAddrParams.psPreDeblockSurface, &pipeBufAddrParams.PreDeblockSurfMmcState));
133     if (m_mmcState->IsMmcEnabled())
134     {
135         pipeBufAddrParams.bMmcEnabled = true;
136     }
137 #endif
138 
139     CODECHAL_DEBUG_TOOL(DumpResources(pipeBufAddrParams));
140 
141     return MOS_STATUS_SUCCESS;
142 }
143 
SetMfxIndObjBaseAddrParams(MHW_VDBOX_IND_OBJ_BASE_ADDR_PARAMS & indObjBaseAddrParams)144 void JpegDecodePicPktXe_M_Base::SetMfxIndObjBaseAddrParams(MHW_VDBOX_IND_OBJ_BASE_ADDR_PARAMS &indObjBaseAddrParams)
145 {
146     DECODE_FUNC_CALL();
147 
148     MOS_ZeroMemory(&indObjBaseAddrParams, sizeof(indObjBaseAddrParams));
149     indObjBaseAddrParams.Mode            = m_jpegBasicFeature->m_mode;;
150     indObjBaseAddrParams.dwDataSize      = m_jpegBasicFeature->m_dataSize;
151     indObjBaseAddrParams.presDataBuffer  = &(m_jpegBasicFeature->m_resDataBuffer.OsResource);
152 }
153 
AddMfxIndObjBaseAddrCmd(MOS_COMMAND_BUFFER & cmdBuffer)154 MOS_STATUS JpegDecodePicPktXe_M_Base::AddMfxIndObjBaseAddrCmd(MOS_COMMAND_BUFFER &cmdBuffer)
155 {
156     DECODE_FUNC_CALL();
157 
158     MHW_VDBOX_IND_OBJ_BASE_ADDR_PARAMS indObjBaseAddrParams;
159     SetMfxIndObjBaseAddrParams(indObjBaseAddrParams);
160     DECODE_CHK_STATUS(m_mfxInterface->AddMfxIndObjBaseAddrCmd(&cmdBuffer, &indObjBaseAddrParams));
161 
162     return MOS_STATUS_SUCCESS;
163 }
164 
SetMfxJpegPicStateParams(MHW_VDBOX_JPEG_DECODE_PIC_STATE & jpegPicState)165 void JpegDecodePicPktXe_M_Base::SetMfxJpegPicStateParams(MHW_VDBOX_JPEG_DECODE_PIC_STATE &jpegPicState)
166 {
167     DECODE_FUNC_CALL();
168 
169     MOS_ZeroMemory(&jpegPicState, sizeof(jpegPicState));
170     jpegPicState.Mode           = m_jpegBasicFeature->m_mode;
171     jpegPicState.pJpegPicParams = m_jpegBasicFeature->m_jpegPicParams;
172     jpegPicState.dwOutputFormat = m_jpegBasicFeature->m_destSurface.Format;
173 
174     if (m_jpegBasicFeature->m_jpegPicParams->m_rotation == jpegRotation90 || m_jpegBasicFeature->m_jpegPicParams->m_rotation == jpegRotation270)
175     {
176         jpegPicState.dwWidthInBlocks = (m_jpegBasicFeature->m_destSurface.dwHeight / CODEC_DECODE_JPEG_BLOCK_SIZE) - 1;
177         jpegPicState.dwHeightInBlocks = (m_jpegBasicFeature->m_destSurface.dwWidth / CODEC_DECODE_JPEG_BLOCK_SIZE) - 1;
178     }
179     else
180     {
181         jpegPicState.dwWidthInBlocks  = (m_jpegBasicFeature->m_destSurface.dwWidth / CODEC_DECODE_JPEG_BLOCK_SIZE) - 1;
182         jpegPicState.dwHeightInBlocks = (m_jpegBasicFeature->m_destSurface.dwHeight / CODEC_DECODE_JPEG_BLOCK_SIZE) - 1;
183     }
184 }
185 
AddMfxJpegPicCmd(MOS_COMMAND_BUFFER & cmdBuffer)186 MOS_STATUS JpegDecodePicPktXe_M_Base::AddMfxJpegPicCmd(MOS_COMMAND_BUFFER &cmdBuffer)
187 {
188     DECODE_FUNC_CALL();
189 
190     MHW_VDBOX_JPEG_DECODE_PIC_STATE jpegPicState;
191     SetMfxJpegPicStateParams(jpegPicState);
192     DECODE_CHK_STATUS(m_mfxInterface->AddMfxJpegPicCmd(&cmdBuffer, &jpegPicState));
193 
194     return MOS_STATUS_SUCCESS;
195 }
196 
SetMfxQmParams(MHW_VDBOX_QM_PARAMS & qmParams)197 void JpegDecodePicPktXe_M_Base::SetMfxQmParams(MHW_VDBOX_QM_PARAMS &qmParams)
198 {
199     DECODE_FUNC_CALL();
200 
201     MOS_ZeroMemory(&qmParams, sizeof(qmParams));
202     qmParams.Standard = CODECHAL_JPEG;
203     qmParams.pJpegQuantMatrix = m_jpegBasicFeature->m_jpegQMatrix;
204 
205     // Swapping QM(x,y) to QM(y,x) for 90/270 degree rotation
206     if (m_jpegBasicFeature->m_jpegPicParams->m_rotation == jpegRotation90 ||
207         m_jpegBasicFeature->m_jpegPicParams->m_rotation == jpegRotation270)
208     {
209         qmParams.bJpegQMRotation = true;
210     }
211     else
212     {
213         qmParams.bJpegQMRotation = false;
214     }
215 }
216 
AddMfxQmCmd(MOS_COMMAND_BUFFER & cmdBuffer)217 MOS_STATUS JpegDecodePicPktXe_M_Base::AddMfxQmCmd(MOS_COMMAND_BUFFER &cmdBuffer)
218 {
219     DECODE_FUNC_CALL();
220 
221     MHW_VDBOX_QM_PARAMS qmParams;
222     SetMfxQmParams(qmParams);
223 
224     if (m_jpegPicParams->m_numCompInFrame > jpegNumComponent)
225     {
226         DECODE_ASSERTMESSAGE("Unsupported Component Number in JPEG Picture parameter.");
227         return MOS_STATUS_INVALID_PARAMETER;
228     }
229 
230     for (uint16_t scanCount = 0; scanCount < m_jpegPicParams->m_numCompInFrame; scanCount++)
231     {
232         // Using scanCount here because the same command is used for JPEG decode and encode
233         uint32_t quantTableSelector                                      = m_jpegPicParams->m_quantTableSelector[scanCount];
234         if (quantTableSelector >= JPEG_MAX_NUM_OF_QUANTMATRIX)
235         {
236             DECODE_ASSERTMESSAGE("Unsupported QuantTableSelector in JPEG Picture parameter.");
237             return MOS_STATUS_INVALID_PARAMETER;
238         }
239         qmParams.pJpegQuantMatrix->m_jpegQMTableType[quantTableSelector] = scanCount;
240         qmParams.JpegQMTableSelector                                     = quantTableSelector;
241         DECODE_CHK_STATUS(m_mfxInterface->AddMfxQmCmd(
242             &cmdBuffer,
243             &qmParams));
244     }
245     return MOS_STATUS_SUCCESS;
246 }
247 
AddMfxJpegHuffTableCmd(MOS_COMMAND_BUFFER & cmdBuffer)248 MOS_STATUS JpegDecodePicPktXe_M_Base::AddMfxJpegHuffTableCmd(MOS_COMMAND_BUFFER &cmdBuffer)
249 {
250     DECODE_FUNC_CALL();
251 
252     uint32_t dcCurHuffTblIndex[2] = {0xff, 0xff};
253     uint32_t acCurHuffTblIndex[2] = {0xff, 0xff};
254 
255     if (m_jpegBasicFeature->m_jpegScanParams->NumScans > jpegNumComponent)
256     {
257         DECODE_ASSERTMESSAGE("Unsupported Component Number in JPEG Scan parameter.");
258         return MOS_STATUS_INVALID_PARAMETER;
259     }
260 
261     for (uint16_t scanCount = 0; scanCount < m_jpegBasicFeature->m_jpegScanParams->NumScans; scanCount++)
262     {
263         // MFX_JPEG_HUFF_TABLE
264         uint16_t numComponents = m_jpegBasicFeature->m_jpegScanParams->ScanHeader[scanCount].NumComponents;
265         if (numComponents > jpegNumComponent)
266         {
267             DECODE_ASSERTMESSAGE("Unsupported Component Number in JPEG Scan parameter.");
268             return MOS_STATUS_INVALID_PARAMETER;
269         }
270 
271         for (uint16_t scanComponent = 0; scanComponent < numComponents; scanComponent++)
272         {
273             // Determine which huffman table we will be writing to
274             // For gray image, componentIdentifier[jpegComponentU] and componentIdentifier[jpegComponentV] are initialized to 0,
275             // and when componentSelector[scanComponent] is equal 0, variable huffTableID is set to 1, and wrong Huffman table is used,
276             // so it is more reasonable to use componentIdentifier[jpegComponentY] to determine which huffman table we will be writing to.
277             uint8_t componentSelector =
278                 m_jpegBasicFeature->m_jpegScanParams->ScanHeader[scanCount].ComponentSelector[scanComponent];
279             uint16_t huffTableID = 0;
280             if (componentSelector == m_jpegBasicFeature->m_jpegPicParams->m_componentIdentifier[jpegComponentY])
281             {
282                 huffTableID = 0;
283             }
284             else
285             {
286                 huffTableID = 1;
287             }
288 
289             int32_t acTableSelector =
290                 m_jpegBasicFeature->m_jpegScanParams->ScanHeader[scanCount].AcHuffTblSelector[scanComponent];
291             int32_t dcTableSelector =
292                 m_jpegBasicFeature->m_jpegScanParams->ScanHeader[scanCount].DcHuffTblSelector[scanComponent];
293 
294             // Send the huffman table state command only if the table changed
295             if ((dcTableSelector != dcCurHuffTblIndex[huffTableID]) ||
296                 (acTableSelector != acCurHuffTblIndex[huffTableID]))
297             {
298                 MHW_VDBOX_HUFF_TABLE_PARAMS huffmanTableParams;
299                 MOS_ZeroMemory(&huffmanTableParams, sizeof(huffmanTableParams));
300                 huffmanTableParams.HuffTableID = huffTableID;
301 
302                 if (acTableSelector >= JPEG_MAX_NUM_HUFF_TABLE_INDEX || dcTableSelector >= JPEG_MAX_NUM_HUFF_TABLE_INDEX)
303                 {
304                     MEDIA_ASSERTMESSAGE("acTableSelector and dcTableSelector cannot exceed 2 by spec.");
305                     return MOS_STATUS_INVALID_PARAMETER;
306                 }
307 
308                 huffmanTableParams.pACBits   = &m_jpegBasicFeature->m_jpegHuffmanTable->HuffTable[acTableSelector].AC_BITS[0];
309                 huffmanTableParams.pDCBits   = &m_jpegBasicFeature->m_jpegHuffmanTable->HuffTable[dcTableSelector].DC_BITS[0];
310                 huffmanTableParams.pACValues = &m_jpegBasicFeature->m_jpegHuffmanTable->HuffTable[acTableSelector].AC_HUFFVAL[0];
311                 huffmanTableParams.pDCValues = &m_jpegBasicFeature->m_jpegHuffmanTable->HuffTable[dcTableSelector].DC_HUFFVAL[0];
312 
313                 DECODE_CHK_STATUS(m_mfxInterface->AddMfxJpegHuffTableCmd(
314                     &cmdBuffer,
315                     &huffmanTableParams));
316 
317                 // Set the current huffman table indices for the next scan
318                 dcCurHuffTblIndex[huffTableID] = dcTableSelector;
319                 acCurHuffTblIndex[huffTableID] = acTableSelector;
320             }
321         }
322     }
323     return MOS_STATUS_SUCCESS;
324 }
325 
AddMfxBsdObjectParams(MOS_COMMAND_BUFFER & cmdBuffer)326 MOS_STATUS JpegDecodePicPktXe_M_Base::AddMfxBsdObjectParams(MOS_COMMAND_BUFFER &cmdBuffer)
327 {
328     DECODE_FUNC_CALL();
329     MHW_VDBOX_JPEG_BSD_PARAMS bsdParams;
330     for (uint16_t scanCount = 0; scanCount < m_jpegBasicFeature->m_jpegScanParams->NumScans; scanCount++)
331     {
332         uint16_t numComponents = m_jpegBasicFeature->m_jpegScanParams->ScanHeader[scanCount].NumComponents;
333         MOS_ZeroMemory(&bsdParams, sizeof(bsdParams));
334         // MFX_JPEG_BSD_OBJECT
335         bsdParams.dwIndirectDataLength         = m_jpegBasicFeature->m_jpegScanParams->ScanHeader[scanCount].DataLength;
336         bsdParams.dwDataStartAddress           = m_jpegBasicFeature->m_jpegScanParams->ScanHeader[scanCount].DataOffset;
337         bsdParams.dwScanHorizontalPosition     = m_jpegBasicFeature->m_jpegScanParams->ScanHeader[scanCount].ScanHoriPosition;
338         bsdParams.dwScanVerticalPosition       = m_jpegBasicFeature->m_jpegScanParams->ScanHeader[scanCount].ScanVertPosition;
339         bsdParams.bInterleaved                 = (numComponents > 1) ? 1 : 0;
340         bsdParams.dwMCUCount                   = m_jpegBasicFeature->m_jpegScanParams->ScanHeader[scanCount].MCUCount;
341         bsdParams.dwRestartInterval            = m_jpegBasicFeature->m_jpegScanParams->ScanHeader[scanCount].RestartInterval;
342 
343         uint16_t scanComponentIndex = 0;
344 
345         for (uint16_t scanComponent = 0; scanComponent < numComponents; scanComponent++)
346         {
347             uint8_t componentSelector =
348                 m_jpegBasicFeature->m_jpegScanParams->ScanHeader[scanCount].ComponentSelector[scanComponent];
349 
350             if (componentSelector == m_jpegBasicFeature->m_jpegPicParams->m_componentIdentifier[jpegComponentY])
351             {
352                 scanComponentIndex = 0;
353             }
354             else if (componentSelector == m_jpegBasicFeature->m_jpegPicParams->m_componentIdentifier[jpegComponentU])
355             {
356                 scanComponentIndex = 1;
357             }
358             else if (componentSelector == m_jpegBasicFeature->m_jpegPicParams->m_componentIdentifier[jpegComponentV])
359             {
360                 scanComponentIndex = 2;
361             }
362             // Add logic for component identifier JPEG_A
363 
364             bsdParams.sScanComponent |= (1 << scanComponentIndex);
365         }
366 
367         DECODE_CHK_STATUS(m_mfxInterface->AddMfxJpegBsdObjCmd(
368             &cmdBuffer,
369             &bsdParams));
370     }
371     return MOS_STATUS_SUCCESS;
372 }
373 
CalculateCommandSize(uint32_t & commandBufferSize,uint32_t & requestedPatchListSize)374 MOS_STATUS JpegDecodePicPktXe_M_Base::CalculateCommandSize(uint32_t &commandBufferSize, uint32_t &requestedPatchListSize)
375 {
376     DECODE_FUNC_CALL();
377 
378     commandBufferSize = m_pictureStatesSize;
379     requestedPatchListSize = m_picturePatchListSize;
380 
381     return MOS_STATUS_SUCCESS;
382 }
383 
384 #if USE_CODECHAL_DEBUG_TOOL
DumpResources(MHW_VDBOX_PIPE_BUF_ADDR_PARAMS & pipeBufAddrParams)385 MOS_STATUS JpegDecodePicPktXe_M_Base::DumpResources(MHW_VDBOX_PIPE_BUF_ADDR_PARAMS& pipeBufAddrParams)
386 {
387     DECODE_FUNC_CALL();
388 
389     return MOS_STATUS_SUCCESS;
390 }
391 #endif
392 
393 }