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 }