1 /*
2 * Copyright (c) 2011-2020, 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 codechal_decode_jpeg.cpp
24 //! \brief Implements the decode interface extension for JPEG.
25 //! \details Implements all functions required by CodecHal for JPEG decoding.
26 //!
27
28 #include "codechal_decode_jpeg.h"
29 #include "codechal_mmc_decode_jpeg.h"
30 #include "hal_oca_interface.h"
31 #include "mos_interface.h"
32 #if USE_CODECHAL_DEBUG_TOOL
33 #include <sstream>
34 #include "codechal_debug.h"
35 #endif
36
37 #define CODECHAL_DECODE_JPEG_BLOCK_ALIGN_SIZE 8
38 #define CODECHAL_DECODE_JPEG_BLOCK_ALIGN_SIZE_X2 16
39 #define CODECHAL_DECODE_JPEG_BLOCK_ALIGN_SIZE_X4 32
40 #define CODECHAL_DECODE_JPEG_ERR_FRAME_WIDTH 32
41 #define CODECHAL_DECODE_JPEG_ERR_FRAME_HEIGHT 32
42
~CodechalDecodeJpeg()43 CodechalDecodeJpeg::~CodechalDecodeJpeg()
44 {
45 CODECHAL_DECODE_FUNCTION_ENTER;
46
47 m_osInterface->pfnDestroySyncResource(m_osInterface, &m_resSyncObjectWaContextInUse);
48 m_osInterface->pfnDestroySyncResource(m_osInterface, &m_resSyncObjectVideoContextInUse);
49
50 if (!Mos_ResourceIsNull(&m_resCopiedDataBuffer))
51 {
52 m_osInterface->pfnFreeResource(
53 m_osInterface,
54 &m_resCopiedDataBuffer);
55 }
56
57 #ifdef _DECODE_PROCESSING_SUPPORTED
58 if (m_sfcState)
59 {
60 MOS_Delete(m_sfcState);
61 m_sfcState = nullptr;
62 }
63 #endif
64
65 return;
66 }
67
CodechalDecodeJpeg(CodechalHwInterface * hwInterface,CodechalDebugInterface * debugInterface,PCODECHAL_STANDARD_INFO standardInfo)68 CodechalDecodeJpeg::CodechalDecodeJpeg(
69 CodechalHwInterface * hwInterface,
70 CodechalDebugInterface *debugInterface,
71 PCODECHAL_STANDARD_INFO standardInfo) : CodechalDecode(hwInterface, debugInterface, standardInfo),
72 m_dataSize(0),
73 m_dataOffset(0),
74 m_copiedDataBufferSize(0),
75 m_nextCopiedDataOffset(0),
76 m_totalDataLength(0),
77 m_preNumScans(0),
78 m_copiedDataBufferInUse(false)
79
80 {
81 CODECHAL_DECODE_FUNCTION_ENTER;
82
83 MOS_ZeroMemory(&m_resCopiedDataBuffer, sizeof(m_resCopiedDataBuffer));
84 MOS_ZeroMemory(&m_destSurface, sizeof(m_destSurface));
85 MOS_ZeroMemory(&m_jpegHuffmanTable, sizeof(m_jpegHuffmanTable));
86 MOS_ZeroMemory(&m_resDataBuffer, sizeof(m_resDataBuffer));
87 MOS_ZeroMemory(&m_resSyncObjectWaContextInUse, sizeof(m_resSyncObjectWaContextInUse));
88 MOS_ZeroMemory(&m_resSyncObjectVideoContextInUse, sizeof(m_resSyncObjectVideoContextInUse));
89 #if (_DEBUG || _RELEASE_INTERNAL)
90 m_reportFrameCrc = true;
91 #endif
92 m_hwInterface = hwInterface;
93 }
94
InitializeBeginFrame()95 MOS_STATUS CodechalDecodeJpeg::InitializeBeginFrame()
96 {
97 CODECHAL_DECODE_FUNCTION_ENTER;
98
99 m_incompletePicture = false;
100 m_incompleteJpegScan = false;
101 m_copiedDataBufferInUse = false;
102 m_nextCopiedDataOffset = 0;
103 m_totalDataLength = 0;
104 m_preNumScans = 0;
105
106 return MOS_STATUS_SUCCESS;
107 }
108
CopyDataSurface()109 MOS_STATUS CodechalDecodeJpeg::CopyDataSurface()
110 {
111 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
112
113 CODECHAL_DECODE_FUNCTION_ENTER;
114
115 if (m_hwInterface->m_noHuC)
116 {
117 uint32_t alignedSize = MOS_ALIGN_CEIL(m_dataSize, 16); // 16 byte aligned
118 CodechalDataCopyParams dataCopyParams;
119 MOS_ZeroMemory(&dataCopyParams, sizeof(CodechalDataCopyParams));
120 dataCopyParams.srcResource = &m_resDataBuffer;
121 dataCopyParams.srcSize = alignedSize;
122 dataCopyParams.srcOffset = 0;
123 dataCopyParams.dstResource = &m_resCopiedDataBuffer;
124 dataCopyParams.dstSize = alignedSize;
125 dataCopyParams.dstOffset = m_nextCopiedDataOffset;
126
127 CODECHAL_DECODE_CHK_STATUS_RETURN(m_hwInterface->CopyDataSourceWithDrv(
128 &dataCopyParams));
129
130 m_nextCopiedDataOffset += MOS_ALIGN_CEIL(m_dataSize, MHW_CACHELINE_SIZE); // 64-byte aligned
131 return MOS_STATUS_SUCCESS;
132 }
133
134 CODECHAL_DECODE_CHK_COND_RETURN(
135 ((m_nextCopiedDataOffset + m_dataSize) > m_copiedDataBufferSize),
136 "Copied data buffer is not large enough.");
137
138 CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnSetGpuContext(
139 m_osInterface,
140 m_videoContextForWa));
141 m_osInterface->pfnResetOsStates(m_osInterface);
142
143 m_osInterface->pfnSetPerfTag(
144 m_osInterface,
145 (uint16_t)(((m_mode << 4) & 0xF0) | COPY_TYPE));
146 m_osInterface->pfnResetPerfBufferID(m_osInterface);
147
148 MOS_COMMAND_BUFFER cmdBuffer;
149 CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnGetCommandBuffer(
150 m_osInterface,
151 &cmdBuffer,
152 0));
153
154 // Send command buffer header at the beginning (OS dependent)
155 CODECHAL_DECODE_CHK_STATUS_RETURN(SendPrologWithFrameTracking(
156 &cmdBuffer,
157 false));
158
159 // Use huc stream out to do the copy
160 CODECHAL_DECODE_CHK_STATUS_RETURN(HucCopy(
161 &cmdBuffer, // pCmdBuffer
162 &m_resDataBuffer, // presSrc
163 &m_resCopiedDataBuffer, // presDst
164 m_dataSize, // u32CopyLength
165 0, // u32CopyInputOffset
166 m_nextCopiedDataOffset)); // u32CopyOutputOffset
167
168 m_nextCopiedDataOffset += MOS_ALIGN_CEIL(m_dataSize, MHW_CACHELINE_SIZE);
169
170 MHW_MI_FLUSH_DW_PARAMS flushDwParams;
171 MOS_ZeroMemory(&flushDwParams, sizeof(flushDwParams));
172 CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiFlushDwCmd(
173 &cmdBuffer,
174 &flushDwParams));
175
176 CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferEnd(
177 &cmdBuffer,
178 nullptr));
179
180 m_osInterface->pfnReturnCommandBuffer(m_osInterface, &cmdBuffer, 0);
181
182 if (!m_incompletePicture)
183 {
184 MOS_SYNC_PARAMS syncParams;
185 syncParams = g_cInitSyncParams;
186 syncParams.GpuContext = m_videoContext;
187 syncParams.presSyncResource = &m_resSyncObjectVideoContextInUse;
188
189 CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnEngineSignal(
190 m_osInterface,
191 &syncParams));
192
193 syncParams = g_cInitSyncParams;
194 syncParams.GpuContext = m_videoContextForWa;
195 syncParams.presSyncResource = &m_resSyncObjectVideoContextInUse;
196
197 CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnEngineWait(
198 m_osInterface,
199 &syncParams));
200 }
201
202 CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnSubmitCommandBuffer(
203 m_osInterface,
204 &cmdBuffer,
205 m_videoContextForWaUsesNullHw));
206
207 CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnSetGpuContext(
208 m_osInterface,
209 m_videoContext));
210
211 return eStatus;
212 }
213
CheckAndCopyIncompleteBitStream()214 MOS_STATUS CodechalDecodeJpeg::CheckAndCopyIncompleteBitStream()
215 {
216 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
217
218 uint32_t maxBufferSize =
219 MOS_ALIGN_CEIL(m_jpegPicParams->m_frameWidth * m_jpegPicParams->m_frameHeight * 3, 64);
220
221 if (m_jpegPicParams->m_totalScans == 1) // Single scan
222 {
223 if (!m_incompleteJpegScan) // The first bitstream buffer
224 {
225 m_totalDataLength =
226 m_jpegScanParams->ScanHeader[0].DataOffset + m_jpegScanParams->ScanHeader[0].DataLength;
227
228 if (m_dataSize < m_totalDataLength) // if the bitstream data is incomplete
229 {
230 CODECHAL_DECODE_CHK_COND_RETURN(
231 m_totalDataLength > maxBufferSize,
232 "The bitstream size exceeds the copied data buffer size.");
233
234 CODECHAL_DECODE_CHK_COND_RETURN(
235 m_dataSize & 0x3f,
236 "The data size of the incomplete bitstream is not aligned with 64.");
237
238 // Allocate the copy data buffer.
239 if (Mos_ResourceIsNull(&m_resCopiedDataBuffer))
240 {
241 CODECHAL_DECODE_CHK_STATUS_MESSAGE_RETURN(AllocateBuffer(
242 &m_resCopiedDataBuffer,
243 maxBufferSize,
244 "CopiedDataBuffer"),
245 "Failed to allocate copied data Buffer.");
246 }
247 m_copiedDataBufferSize = maxBufferSize;
248
249 // copy the bitstream buffer
250 if (m_dataSize)
251 {
252 CODECHAL_DECODE_CHK_STATUS_RETURN(CopyDataSurface());
253 m_copiedDataBufferInUse = true;
254 }
255
256 m_incompleteJpegScan = true;
257 m_incompletePicture = true;
258 }
259 else //the bitstream data is complete
260 {
261 m_incompleteJpegScan = false;
262 m_incompletePicture = false;
263 }
264 }
265 else // the next bitstream buffers
266 {
267 CODECHAL_DECODE_CHK_COND_RETURN(
268 m_nextCopiedDataOffset + m_dataSize > m_copiedDataBufferSize,
269 "The bitstream size exceeds the copied data buffer size.")
270
271 CODECHAL_DECODE_CHK_COND_RETURN(
272 (m_nextCopiedDataOffset + m_dataSize < m_totalDataLength) && (m_dataSize & 0x3f),
273 "The data size of the incomplete bitstream is not aligned with 64.");
274
275 // copy the bitstream
276 if (m_dataSize)
277 {
278 CODECHAL_DECODE_CHK_STATUS_RETURN(CopyDataSurface());
279 }
280
281 if (m_nextCopiedDataOffset >= m_totalDataLength)
282 {
283 m_incompleteJpegScan = false;
284 m_incompletePicture = false;
285 }
286
287 }
288 }
289 else // multi-scans
290 {
291 if (!m_incompleteJpegScan) // The first bitstream buffer of each scan;
292 {
293 for (uint32_t idxScan = m_preNumScans; idxScan < m_jpegScanParams->NumScans; idxScan++)
294 {
295 m_jpegScanParams->ScanHeader[idxScan].DataOffset += m_nextCopiedDataOffset; // modify the data offset for the new incoming scan data
296 }
297 m_totalDataLength = m_jpegScanParams->ScanHeader[m_jpegScanParams->NumScans - 1].DataOffset + m_jpegScanParams->ScanHeader[m_jpegScanParams->NumScans - 1].DataLength;
298 m_preNumScans = m_jpegScanParams->NumScans;
299
300 // judge whether the bitstream is complete in the first execute() call
301 if (IsFirstExecuteCall() &&
302 m_dataSize <= m_jpegScanParams->ScanHeader[0].DataOffset + m_jpegScanParams->ScanHeader[0].DataLength)
303 {
304 CODECHAL_DECODE_CHK_COND_RETURN(
305 (m_nextCopiedDataOffset + m_dataSize < m_totalDataLength) && (m_dataSize & 0x3f),
306 "The buffer size of the incomplete bitstream is not aligned with 64.");
307
308 // Allocate the copy data buffer.
309 if (Mos_ResourceIsNull(&m_resCopiedDataBuffer))
310 {
311 CODECHAL_DECODE_CHK_STATUS_MESSAGE_RETURN(AllocateBuffer(
312 &m_resCopiedDataBuffer,
313 maxBufferSize,
314 "CopiedDataBuffer"),
315 "Failed to allocate copied data Buffer.");
316 }
317 m_copiedDataBufferSize = maxBufferSize;
318
319 // copy the bitstream buffer
320 if (m_dataSize)
321 {
322 CODECHAL_DECODE_CHK_STATUS_RETURN(CopyDataSurface());
323 m_copiedDataBufferInUse = true;
324 }
325
326 m_incompleteJpegScan = m_nextCopiedDataOffset < m_totalDataLength;
327 m_incompletePicture = m_incompleteJpegScan || m_jpegScanParams->NumScans < m_jpegPicParams->m_totalScans;
328 }
329 else // the bitstream is complete
330 {
331 m_incompleteJpegScan = false;
332 if (m_jpegScanParams->NumScans == m_jpegPicParams->m_totalScans)
333 {
334 m_incompletePicture = false;
335 }
336 else
337 {
338 m_incompletePicture = true;
339 }
340 }
341 }
342 else //The next bitstream buffer of each scan
343 {
344 CODECHAL_DECODE_CHK_COND_RETURN(
345 m_nextCopiedDataOffset + m_dataSize > m_copiedDataBufferSize,
346 "The bitstream size exceeds the copied data buffer size.")
347
348 CODECHAL_DECODE_CHK_COND_RETURN(
349 (m_nextCopiedDataOffset + m_dataSize < m_totalDataLength) && (m_dataSize & 0x3f),
350 "The data size of the incomplete bitstream is not aligned with 64.");
351
352 // copy the bitstream buffer
353 if (m_dataSize)
354 {
355 CODECHAL_DECODE_CHK_STATUS_RETURN(CopyDataSurface());
356 }
357
358 if (m_nextCopiedDataOffset >= m_totalDataLength)
359 {
360 m_incompleteJpegScan = false;
361 if (m_jpegScanParams->NumScans >= m_jpegPicParams->m_totalScans)
362 {
363 m_incompletePicture = false;
364 }
365 }
366
367 }
368 }
369
370 return eStatus;
371 }
372
CheckSupportedFormat(PMOS_FORMAT format)373 MOS_STATUS CodechalDecodeJpeg::CheckSupportedFormat(
374 PMOS_FORMAT format)
375 {
376 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
377
378 // App must use 420_OPAQUE as DecodeRT for other JPEG output formats except NV12 and YUY2 due to runtime
379 // restriction, so the real JPEG format is passed to driver in PPS data. The code here is just to get the real output format.
380 // On SKL+, app would use AYUV (instead of 420_OPAQUE) as DecodeRT for direct YUV to ARGB8888 conversion; in such case,
381 // real output format (ARGB8888) should also be from JPEG PPS; MSDK would handle the details of treating AYUV as ARGB.
382 if (*format == Format_420O || *format == Format_AYUV)
383 {
384 CODECHAL_DECODE_CHK_NULL_RETURN(m_osInterface);
385 *format = m_osInterface->pfnOsFmtToMosFmt(m_jpegPicParams->m_renderTargetFormat);
386 }
387
388 //No support for RGBP/BGRP channel swap or YUV/RGB conversion!
389 switch (*format)
390 {
391 case Format_BGRP:
392 if (m_jpegPicParams->m_chromaType == jpegRGB ||
393 m_jpegPicParams->m_chromaType == jpegYUV444)
394 {
395 eStatus = MOS_STATUS_PLATFORM_NOT_SUPPORTED;
396 }
397 break;
398 case Format_RGBP:
399 if (m_jpegPicParams->m_chromaType == jpegYUV444)
400 {
401 eStatus = MOS_STATUS_PLATFORM_NOT_SUPPORTED;
402 }
403 break;
404 case Format_Y416:
405 case Format_AYUV:
406 case Format_AUYV:
407 case Format_Y410:
408 if (m_jpegPicParams->m_chromaType == jpegRGB ||
409 m_jpegPicParams->m_chromaType == jpegBGR)
410 {
411 eStatus = MOS_STATUS_PLATFORM_NOT_SUPPORTED;
412 }
413 break;
414 default:
415 break;
416 }
417
418 return eStatus;
419 }
420
SetFrameStates()421 MOS_STATUS CodechalDecodeJpeg::SetFrameStates()
422 {
423 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
424
425 CODECHAL_DECODE_FUNCTION_ENTER;
426
427 CODECHAL_DECODE_CHK_NULL_RETURN(m_decodeParams.m_destSurface);
428 CODECHAL_DECODE_CHK_NULL_RETURN(m_decodeParams.m_dataBuffer);
429
430 //Set wPerfType as I_TYPE so that PerTag can be recognized by performance reportor
431 m_perfType = I_TYPE;
432
433 m_dataSize = m_decodeParams.m_dataSize;
434 m_dataOffset = m_decodeParams.m_dataOffset;
435 m_resDataBuffer = *(m_decodeParams.m_dataBuffer);
436 m_jpegPicParams = (CodecDecodeJpegPicParams *)m_decodeParams.m_picParams;
437 m_jpegQMatrix = (CodecJpegQuantMatrix *)m_decodeParams.m_iqMatrixBuffer;
438 m_jpegHuffmanTable = (PCODECHAL_DECODE_JPEG_HUFFMAN_TABLE)m_decodeParams.m_huffmanTable;
439 m_jpegScanParams = (CodecDecodeJpegScanParameter *)m_decodeParams.m_sliceParams;
440
441 CODECHAL_DECODE_CHK_NULL_RETURN(m_jpegPicParams);
442
443 CODECHAL_DECODE_CHK_STATUS_RETURN(CheckSupportedFormat(
444 &m_decodeParams.m_destSurface->Format));
445
446 m_hwInterface->GetCpInterface()->SetCpSecurityType();
447
448 if (IsFirstExecuteCall())
449 {
450 CODECHAL_DECODE_CHK_STATUS_RETURN(InitializeBeginFrame());
451 }
452
453 // Check whether the bitstream buffer is completed. If not, allocate a larger buffer and copy the bitstream.
454 CODECHAL_DECODE_CHK_STATUS_RETURN(CheckAndCopyIncompleteBitStream());
455
456 // if the bitstream is not completed, don't do any decoding work.
457 if (m_incompletePicture)
458 {
459 return MOS_STATUS_SUCCESS;
460 }
461
462 uint32_t widthAlign = 0;
463 uint32_t heightAlign = 0;
464
465 // Overwriting surface width and height of destination surface, so it comes from Picture Parameters struct
466 if (!m_jpegPicParams->m_interleavedData)
467 {
468 widthAlign = MOS_ALIGN_CEIL(m_jpegPicParams->m_frameWidth, CODECHAL_DECODE_JPEG_BLOCK_ALIGN_SIZE);
469 heightAlign = MOS_ALIGN_CEIL(m_jpegPicParams->m_frameHeight, CODECHAL_DECODE_JPEG_BLOCK_ALIGN_SIZE);
470 }
471 else
472 {
473 switch (m_jpegPicParams->m_chromaType)
474 {
475 case jpegYUV400:
476 case jpegYUV444:
477 case jpegRGB:
478 case jpegBGR:
479 widthAlign = MOS_ALIGN_CEIL(m_jpegPicParams->m_frameWidth, CODECHAL_DECODE_JPEG_BLOCK_ALIGN_SIZE);
480 heightAlign = MOS_ALIGN_CEIL(m_jpegPicParams->m_frameHeight, CODECHAL_DECODE_JPEG_BLOCK_ALIGN_SIZE);
481 break;
482 case jpegYUV422V2Y:
483 widthAlign = MOS_ALIGN_CEIL(m_jpegPicParams->m_frameWidth, CODECHAL_DECODE_JPEG_BLOCK_ALIGN_SIZE);
484 heightAlign = MOS_ALIGN_CEIL(m_jpegPicParams->m_frameHeight, CODECHAL_DECODE_JPEG_BLOCK_ALIGN_SIZE_X2);
485 break;
486 case jpegYUV422H2Y:
487 widthAlign = MOS_ALIGN_CEIL(m_jpegPicParams->m_frameWidth, CODECHAL_DECODE_JPEG_BLOCK_ALIGN_SIZE_X2);
488 heightAlign = MOS_ALIGN_CEIL(m_jpegPicParams->m_frameHeight, CODECHAL_DECODE_JPEG_BLOCK_ALIGN_SIZE);
489 break;
490 case jpegYUV411:
491 widthAlign = MOS_ALIGN_CEIL(m_jpegPicParams->m_frameWidth, CODECHAL_DECODE_JPEG_BLOCK_ALIGN_SIZE_X4);
492 heightAlign = MOS_ALIGN_CEIL(m_jpegPicParams->m_frameHeight, CODECHAL_DECODE_JPEG_BLOCK_ALIGN_SIZE);
493 break;
494 default: // YUV422H_4Y, YUV422V_4Y & YUV420
495 widthAlign = MOS_ALIGN_CEIL(m_jpegPicParams->m_frameWidth, CODECHAL_DECODE_JPEG_BLOCK_ALIGN_SIZE_X2);
496 heightAlign = MOS_ALIGN_CEIL(m_jpegPicParams->m_frameHeight, CODECHAL_DECODE_JPEG_BLOCK_ALIGN_SIZE_X2);
497 break;
498 }
499 }
500
501 //BDW has a limitation:Height should aligned by 16 when input is YUV422H_2Y and output is NV12.
502 if (MEDIA_IS_WA(m_waTable, WaJPEGHeightAlignYUV422H2YToNV12) &&
503 m_jpegPicParams->m_chromaType == jpegYUV422H2Y &&
504 m_decodeParams.m_destSurface->Format == Format_NV12)
505 {
506 heightAlign = MOS_ALIGN_CEIL(m_jpegPicParams->m_frameHeight, CODECHAL_DECODE_JPEG_BLOCK_ALIGN_SIZE_X2);
507 }
508
509 if ((m_jpegPicParams->m_rotation == jpegRotation90) || (m_jpegPicParams->m_rotation == jpegRotation270))
510 {
511 // Interchanging picture width and height for 90/270 degree rotation
512 m_decodeParams.m_destSurface->dwWidth = heightAlign;
513 m_decodeParams.m_destSurface->dwHeight = widthAlign;
514 }
515 else
516 {
517 m_decodeParams.m_destSurface->dwWidth = widthAlign;
518 m_decodeParams.m_destSurface->dwHeight = heightAlign;
519 }
520
521 m_destSurface = *(m_decodeParams.m_destSurface);
522 if (m_copiedDataBufferInUse)
523 {
524 m_resDataBuffer = m_resCopiedDataBuffer; // set resDataBuffer to copy data buffer
525 }
526
527 m_statusReportFeedbackNumber = m_jpegPicParams->m_statusReportFeedbackNumber;
528
529 #ifdef _DECODE_PROCESSING_SUPPORTED
530 m_sfcState->CheckAndInitialize(&m_destSurface, m_jpegPicParams);
531 #endif
532
533 CODECHAL_DEBUG_TOOL(
534 if (m_jpegPicParams) {
535 CODECHAL_DECODE_CHK_STATUS_RETURN(DumpPicParams(m_jpegPicParams))
536 }
537
538 if (m_jpegScanParams) {
539 CODECHAL_DECODE_CHK_STATUS_RETURN(DumpScanParams(m_jpegScanParams))
540 }
541
542 if (m_jpegHuffmanTable) {
543 CODECHAL_DECODE_CHK_STATUS_RETURN(DumpHuffmanTable(m_jpegHuffmanTable))
544 }
545
546 if (m_jpegQMatrix) {
547 CODECHAL_DECODE_CHK_STATUS_RETURN(DumpIQParams(m_jpegQMatrix))
548 }
549
550 if (&(m_resDataBuffer)) {
551 CODECHAL_DECODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer(
552 &m_resDataBuffer,
553 CodechalDbgAttr::attrDecodeBitstream,
554 "_DEC",
555 (m_copiedDataBufferInUse ? m_nextCopiedDataOffset : m_dataSize),
556 0,
557 CODECHAL_NUM_MEDIA_STATES));
558 })
559
560 return eStatus;
561 }
562
AllocateResources()563 MOS_STATUS CodechalDecodeJpeg::AllocateResources()
564 {
565 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
566
567 CODECHAL_DECODE_FUNCTION_ENTER;
568
569 CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnCreateSyncResource(
570 m_osInterface,
571 &m_resSyncObjectWaContextInUse));
572 CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnCreateSyncResource(
573 m_osInterface,
574 &m_resSyncObjectVideoContextInUse));
575
576 return eStatus;
577 }
578
SetOutputSurfaceLayout(CodecDecodeJpegImageLayout * outputSurfLayout)579 void CodechalDecodeJpeg::SetOutputSurfaceLayout(
580 CodecDecodeJpegImageLayout *outputSurfLayout)
581 {
582 uint32_t ucbOffset = MOS_ALIGN_CEIL(m_destSurface.UPlaneOffset.iYOffset, MHW_VDBOX_MFX_UV_PLANE_ALIGNMENT_LEGACY);
583 uint32_t vcrOffset = MOS_ALIGN_CEIL(m_destSurface.VPlaneOffset.iYOffset, MHW_VDBOX_MFX_UV_PLANE_ALIGNMENT_LEGACY);
584
585 uint32_t ucbOffsetInBytes = ucbOffset * m_destSurface.dwPitch;
586 uint32_t vcrOffsetInBytes = vcrOffset * m_destSurface.dwPitch;
587
588 outputSurfLayout->m_pitch = m_destSurface.dwPitch;
589
590 for (uint32_t scanCount = 0; scanCount < m_jpegScanParams->NumScans; scanCount++)
591 {
592 for (uint32_t scanComponent = 0; scanComponent < m_jpegScanParams->ScanHeader[scanCount].NumComponents; scanComponent++)
593 {
594 if (m_jpegScanParams->ScanHeader[scanCount].ComponentSelector[scanComponent] == m_jpegPicParams->m_componentIdentifier[jpegComponentY])
595 {
596 outputSurfLayout->m_componentDataOffset[jpegComponentY] = 0;
597 }
598 else if (m_jpegScanParams->ScanHeader[scanCount].ComponentSelector[scanComponent] == m_jpegPicParams->m_componentIdentifier[jpegComponentU])
599 {
600 outputSurfLayout->m_componentDataOffset[jpegComponentU] = ucbOffsetInBytes;
601 }
602 else if (m_jpegScanParams->ScanHeader[scanCount].ComponentSelector[scanComponent] == m_jpegPicParams->m_componentIdentifier[jpegComponentV])
603 {
604 outputSurfLayout->m_componentDataOffset[jpegComponentV] = vcrOffsetInBytes;
605 }
606 }
607 }
608 }
609
DecodeStateLevel()610 MOS_STATUS CodechalDecodeJpeg::DecodeStateLevel()
611 {
612 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
613
614 CODECHAL_DECODE_FUNCTION_ENTER;
615
616 MHW_VDBOX_JPEG_DECODE_PIC_STATE jpegPicState;
617 jpegPicState.dwOutputFormat = m_decodeParams.m_destSurface->Format;
618
619 #ifdef _DECODE_PROCESSING_SUPPORTED
620 if (m_sfcState->m_sfcPipeOut)
621 {
622 jpegPicState.dwOutputFormat = m_sfcState->m_sfcInSurface.Format;
623 }
624 #endif
625
626 //Three new formats from HSW C0,HSW ULT can only be supported in specific conditions.
627 if (jpegPicState.dwOutputFormat == Format_NV12 ||
628 jpegPicState.dwOutputFormat == Format_YUY2 ||
629 jpegPicState.dwOutputFormat == Format_UYVY)
630 {
631 //Only interleaved single scan are supported.
632 if (m_jpegPicParams->m_totalScans != 1 ||
633 m_jpegPicParams->m_interleavedData == 0)
634 {
635 return MOS_STATUS_UNKNOWN;
636 }
637
638 switch (m_jpegPicParams->m_chromaType)
639 {
640 case jpegYUV420:
641 case jpegYUV422H2Y:
642 case jpegYUV422H4Y:
643 break;
644 case jpegYUV422V2Y:
645 case jpegYUV422V4Y:
646 if (GFX_IS_GEN_8_OR_LATER(m_hwInterface->GetPlatform()) &&
647 jpegPicState.dwOutputFormat == Format_NV12)
648 {
649 break;
650 }
651 default:
652 return MOS_STATUS_UNKNOWN;
653 }
654 }
655
656 MOS_COMMAND_BUFFER cmdBuffer;
657 CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnGetCommandBuffer(
658 m_osInterface,
659 &cmdBuffer,
660 0));
661
662 auto mmioRegisters = m_hwInterface->GetMfxInterface()->GetMmioRegisters(m_vdboxIndex);
663 HalOcaInterface::On1stLevelBBStart(cmdBuffer, *m_osInterface->pOsContext, m_osInterface->CurrentGpuContextHandle, *m_miInterface, *mmioRegisters);
664
665 CODECHAL_DECODE_CHK_STATUS_RETURN(SendPrologWithFrameTracking(
666 &cmdBuffer, true));
667
668 // Set PIPE_MODE_SELECT
669 MHW_VDBOX_PIPE_MODE_SELECT_PARAMS pipeModeSelectParams;
670 pipeModeSelectParams.Mode = CODECHAL_DECODE_MODE_JPEG;
671 pipeModeSelectParams.bStreamOutEnabled = m_streamOutEnabled;
672 pipeModeSelectParams.bDeblockerStreamOutEnable = false;
673 pipeModeSelectParams.bPostDeblockOutEnable = false;
674 pipeModeSelectParams.bPreDeblockOutEnable = true;
675
676 // Set CMD_MFX_SURFACE_STATE
677 MHW_VDBOX_SURFACE_PARAMS surfaceParams;
678 MOS_ZeroMemory(&surfaceParams, sizeof(surfaceParams));
679 surfaceParams.Mode = CODECHAL_DECODE_MODE_JPEG;
680 surfaceParams.psSurface = &m_destSurface;
681 surfaceParams.ChromaType = m_jpegPicParams->m_chromaType;
682
683 #ifdef _DECODE_PROCESSING_SUPPORTED
684 if (m_sfcState->m_sfcPipeOut)
685 {
686 surfaceParams.psSurface = &m_sfcState->m_sfcInSurface;
687 }
688 #endif
689
690 // Set MFX_PIPE_BUF_ADDR_STATE_CMD
691 MHW_VDBOX_PIPE_BUF_ADDR_PARAMS pipeBufAddrParams;
692 pipeBufAddrParams.Mode = CODECHAL_DECODE_MODE_JPEG;
693 // Predeblock surface is the same as destination surface here because there is no deblocking for JPEG
694 pipeBufAddrParams.psPreDeblockSurface = &m_destSurface;
695
696 #ifdef _MMC_SUPPORTED
697 CODECHAL_DECODE_CHK_STATUS_RETURN(m_mmc->SetPipeBufAddr(&pipeBufAddrParams));
698 #endif
699
700 // Set MFX_IND_OBJ_BASE_ADDR_STATE_CMD
701 MHW_VDBOX_IND_OBJ_BASE_ADDR_PARAMS indObjBaseAddrParams;
702 MOS_ZeroMemory(&indObjBaseAddrParams, sizeof(indObjBaseAddrParams));
703 indObjBaseAddrParams.Mode = CODECHAL_DECODE_MODE_JPEG;
704 indObjBaseAddrParams.dwDataSize = m_copiedDataBufferInUse ? m_nextCopiedDataOffset : m_dataSize;
705 indObjBaseAddrParams.presDataBuffer = &m_resDataBuffer;
706
707 // Set MFX_JPEG_PIC_STATE_CMD
708 jpegPicState.pJpegPicParams = m_jpegPicParams;
709 if ((m_jpegPicParams->m_rotation == jpegRotation90) || (m_jpegPicParams->m_rotation == jpegRotation270))
710 {
711 jpegPicState.dwWidthInBlocks = (m_destSurface.dwHeight / CODECHAL_DECODE_JPEG_BLOCK_SIZE) - 1;
712 jpegPicState.dwHeightInBlocks = (m_destSurface.dwWidth / CODECHAL_DECODE_JPEG_BLOCK_SIZE) - 1;
713 }
714 else
715 {
716 jpegPicState.dwWidthInBlocks = (m_destSurface.dwWidth / CODECHAL_DECODE_JPEG_BLOCK_SIZE) - 1;
717 jpegPicState.dwHeightInBlocks = (m_destSurface.dwHeight / CODECHAL_DECODE_JPEG_BLOCK_SIZE) - 1;
718 }
719
720 // Add commands to command buffer
721 // MI_FLUSH_DW command -> must be before to MFX_PIPE_MODE_SELECT
722 MHW_MI_FLUSH_DW_PARAMS flushDwParams;
723 MOS_ZeroMemory(&flushDwParams, sizeof(flushDwParams));
724 CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiFlushDwCmd(
725 &cmdBuffer,
726 &flushDwParams));
727
728 if (m_statusQueryReportingEnabled)
729 {
730 CODECHAL_DECODE_CHK_STATUS_RETURN(StartStatusReport(
731 &cmdBuffer));
732 }
733
734 // MFX_PIPE_MODE_SELECT_CMD
735 CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxPipeModeSelectCmd(
736 &cmdBuffer,
737 &pipeModeSelectParams));
738
739 #ifdef _DECODE_PROCESSING_SUPPORTED
740 // Output decode result through SFC
741 CODECHAL_DECODE_CHK_STATUS_RETURN(m_sfcState->AddSfcCommands(&cmdBuffer));
742 #endif
743
744 // CMD_MFX_SURFACE_STATE
745 CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxSurfaceCmd(
746 &cmdBuffer,
747 &surfaceParams));
748
749 // MFX_PIPE_BUF_ADDR_STATE_CMD
750 CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxPipeBufAddrCmd(
751 &cmdBuffer,
752 &pipeBufAddrParams));
753
754 // MFX_IND_OBJ_BASE_ADDR_STATE_CMD
755 CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxIndObjBaseAddrCmd(
756 &cmdBuffer,
757 &indObjBaseAddrParams));
758
759 // MFX_JPEG_PIC_STATE_CMD
760 CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxJpegPicCmd(
761 &cmdBuffer,
762 &jpegPicState));
763
764 m_osInterface->pfnReturnCommandBuffer(m_osInterface, &cmdBuffer, 0);
765
766 return eStatus;
767 }
768
DecodePrimitiveLevel()769 MOS_STATUS CodechalDecodeJpeg::DecodePrimitiveLevel()
770 {
771 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
772
773 CODECHAL_DECODE_FUNCTION_ENTER;
774
775 // if the bitstream is not complete, don't do any decoding work.
776 if (m_incompletePicture)
777 {
778 return MOS_STATUS_SUCCESS;
779
780 }
781
782 MOS_COMMAND_BUFFER cmdBuffer;
783 CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnGetCommandBuffer(
784 m_osInterface,
785 &cmdBuffer,
786 0));
787
788 // MFX_QM_STATE_CMD
789 MHW_VDBOX_QM_PARAMS qmParams;
790 MOS_ZeroMemory(&qmParams, sizeof(qmParams));
791 qmParams.Standard = CODECHAL_JPEG;
792 qmParams.pJpegQuantMatrix = m_jpegQMatrix;
793
794 // Swapping QM(x,y) to QM(y,x) for 90/270 degree rotation
795 if ((m_jpegPicParams->m_rotation == jpegRotation90) ||
796 (m_jpegPicParams->m_rotation == jpegRotation270))
797 {
798 qmParams.bJpegQMRotation = true;
799 }
800 else
801 {
802 qmParams.bJpegQMRotation = false;
803 }
804
805 for (uint16_t scanCount = 0; scanCount < m_jpegPicParams->m_numCompInFrame; scanCount++)
806 {
807 // Using scanCount here because the same command is used for JPEG decode and encode
808 uint32_t quantTableSelector = m_jpegPicParams->m_quantTableSelector[scanCount];
809 if (quantTableSelector >= JPEG_MAX_NUM_OF_QUANTMATRIX)
810 {
811 CODECHAL_DECODE_ASSERTMESSAGE("Unsupported QuantTableSelector in JPEG Picture parameter.");
812 return MOS_STATUS_INVALID_PARAMETER;
813 }
814 qmParams.pJpegQuantMatrix->m_jpegQMTableType[quantTableSelector] = scanCount;
815 qmParams.JpegQMTableSelector = quantTableSelector;
816 CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxQmCmd(
817 &cmdBuffer,
818 &qmParams));
819 }
820
821 uint32_t dcCurHuffTblIndex[2] = { 0xff, 0xff };
822 uint32_t acCurHuffTblIndex[2] = { 0xff, 0xff };
823
824 for (uint16_t scanCount = 0; scanCount < m_jpegScanParams->NumScans; scanCount++)
825 {
826 // MFX_JPEG_HUFF_TABLE
827 uint16_t numComponents = m_jpegScanParams->ScanHeader[scanCount].NumComponents;
828 for (uint16_t scanComponent = 0; scanComponent < numComponents; scanComponent++)
829 {
830 // Determine which huffman table we will be writing to
831 // For gray image, componentIdentifier[jpegComponentU] and componentIdentifier[jpegComponentV] are initialized to 0,
832 // and when ComponentSelector[scanComponent] is equal 0, variable huffTableID is set to 1, and wrong Huffman table is used,
833 // so it is more reasonable to use componentIdentifier[jpegComponentY] to determine which huffman table we will be writing to.
834 uint8_t ComponentSelector =
835 m_jpegScanParams->ScanHeader[scanCount].ComponentSelector[scanComponent];
836 uint16_t huffTableID = 0;
837 if (ComponentSelector == m_jpegPicParams->m_componentIdentifier[jpegComponentY])
838 {
839 huffTableID = 0;
840 }
841 else
842 {
843 huffTableID = 1;
844 }
845
846 uint32_t AcTableSelector =
847 m_jpegScanParams->ScanHeader[scanCount].AcHuffTblSelector[scanComponent];
848 uint32_t DcTableSelector =
849 m_jpegScanParams->ScanHeader[scanCount].DcHuffTblSelector[scanComponent];
850
851 // Send the huffman table state command only if the table changed
852 if ((DcTableSelector != dcCurHuffTblIndex[huffTableID]) ||
853 (AcTableSelector != acCurHuffTblIndex[huffTableID]))
854 {
855 MHW_VDBOX_HUFF_TABLE_PARAMS huffmanTableParams;
856 MOS_ZeroMemory(&huffmanTableParams, sizeof(huffmanTableParams));
857
858 huffmanTableParams.HuffTableID = huffTableID;
859
860 huffmanTableParams.pACBits = &m_jpegHuffmanTable->HuffTable[AcTableSelector].AC_BITS[0];
861 huffmanTableParams.pDCBits = &m_jpegHuffmanTable->HuffTable[DcTableSelector].DC_BITS[0];
862 huffmanTableParams.pACValues = &m_jpegHuffmanTable->HuffTable[AcTableSelector].AC_HUFFVAL[0];
863 huffmanTableParams.pDCValues = &m_jpegHuffmanTable->HuffTable[DcTableSelector].DC_HUFFVAL[0];
864
865 CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxJpegHuffTableCmd(
866 &cmdBuffer,
867 &huffmanTableParams));
868
869 // Set the current huffman table indices for the next scan
870 dcCurHuffTblIndex[huffTableID] = DcTableSelector;
871 acCurHuffTblIndex[huffTableID] = AcTableSelector;
872 }
873 }
874
875 MHW_VDBOX_JPEG_BSD_PARAMS jpegBsdObject;
876 MOS_ZeroMemory(&jpegBsdObject, sizeof(jpegBsdObject));
877
878 // MFX_JPEG_BSD_OBJECT
879 jpegBsdObject.dwIndirectDataLength = m_jpegScanParams->ScanHeader[scanCount].DataLength;
880 jpegBsdObject.dwDataStartAddress = m_jpegScanParams->ScanHeader[scanCount].DataOffset;
881 jpegBsdObject.dwScanHorizontalPosition = m_jpegScanParams->ScanHeader[scanCount].ScanHoriPosition;
882 jpegBsdObject.dwScanVerticalPosition = m_jpegScanParams->ScanHeader[scanCount].ScanVertPosition;
883 jpegBsdObject.bInterleaved = (numComponents > 1) ? 1 : 0;
884 jpegBsdObject.dwMCUCount = m_jpegScanParams->ScanHeader[scanCount].MCUCount;
885 jpegBsdObject.dwRestartInterval = m_jpegScanParams->ScanHeader[scanCount].RestartInterval;
886
887 uint16_t scanComponentIndex = 0;
888
889 for (uint16_t scanComponent = 0; scanComponent < numComponents; scanComponent++)
890 {
891 uint8_t ComponentSelector =
892 m_jpegScanParams->ScanHeader[scanCount].ComponentSelector[scanComponent];
893
894 if (ComponentSelector == m_jpegPicParams->m_componentIdentifier[jpegComponentY])
895 {
896 scanComponentIndex = 0;
897 }
898 else if (ComponentSelector == m_jpegPicParams->m_componentIdentifier[jpegComponentU])
899 {
900 scanComponentIndex = 1;
901 }
902 else if (ComponentSelector == m_jpegPicParams->m_componentIdentifier[jpegComponentV])
903 {
904 scanComponentIndex = 2;
905 }
906 // Add logic for component identifier JPEG_A
907
908 jpegBsdObject.sScanComponent |= (1 << scanComponentIndex);
909 }
910
911 CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxJpegBsdObjCmd(
912 &cmdBuffer,
913 &jpegBsdObject));
914 }
915
916 // Check if destination surface needs to be synchronized
917 MOS_SYNC_PARAMS syncParams = g_cInitSyncParams;
918 syncParams.GpuContext = m_videoContext;
919 syncParams.presSyncResource = &m_destSurface.OsResource;
920 syncParams.bReadOnly = false;
921 syncParams.bDisableDecodeSyncLock = m_disableDecodeSyncLock;
922 syncParams.bDisableLockForTranscode = m_disableLockForTranscode;
923
924 CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnPerformOverlaySync(
925 m_osInterface,
926 &syncParams));
927 CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnResourceWait(
928 m_osInterface,
929 &syncParams));
930
931 // Update the resource tag (s/w tag) for On-Demand Sync
932 m_osInterface->pfnSetResourceSyncTag(m_osInterface, &syncParams);
933
934 MHW_MI_FLUSH_DW_PARAMS flushDwParams;
935 MOS_ZeroMemory(&flushDwParams, sizeof(flushDwParams));
936 CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiFlushDwCmd(
937 &cmdBuffer,
938 &flushDwParams));
939
940 // Update the tag in GPU Sync eStatus buffer (H/W Tag) to match the current S/W tag
941 if (m_osInterface->bTagResourceSync)
942 {
943 CODECHAL_DECODE_CHK_STATUS_RETURN(m_hwInterface->WriteSyncTagToResource(
944 &cmdBuffer,
945 &syncParams));
946 }
947
948 if (m_statusQueryReportingEnabled)
949 {
950 CodechalDecodeStatusReport decodeStatusReport;
951 decodeStatusReport.m_statusReportNumber = m_statusReportFeedbackNumber;
952 decodeStatusReport.m_codecStatus = CODECHAL_STATUS_UNAVAILABLE;
953 decodeStatusReport.m_currDecodedPicRes = m_destSurface.OsResource;
954
955 CODECHAL_DECODE_CHK_STATUS_RETURN(EndStatusReport(
956 decodeStatusReport,
957 &cmdBuffer));
958 }
959
960 CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferEnd(
961 &cmdBuffer,
962 nullptr));
963
964 m_osInterface->pfnReturnCommandBuffer(m_osInterface, &cmdBuffer, 0);
965
966 CODECHAL_DEBUG_TOOL(
967 CODECHAL_DECODE_CHK_STATUS_RETURN(m_debugInterface->DumpCmdBuffer(
968 &cmdBuffer,
969 CODECHAL_NUM_MEDIA_STATES,
970 "_DEC"));
971 )
972
973 if (m_copiedDataBufferInUse)
974 {
975 //Sync up complete frame
976 syncParams = g_cInitSyncParams;
977 syncParams.GpuContext = m_videoContextForWa;
978 syncParams.presSyncResource = &m_resSyncObjectWaContextInUse;
979
980 CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnEngineSignal(
981 m_osInterface,
982 &syncParams));
983
984 syncParams = g_cInitSyncParams;
985 syncParams.GpuContext = m_videoContext;
986 syncParams.presSyncResource = &m_resSyncObjectWaContextInUse;
987
988 CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnEngineWait(
989 m_osInterface,
990 &syncParams));
991 }
992
993 HalOcaInterface::On1stLevelBBEnd(cmdBuffer, *m_osInterface);
994
995 CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnSubmitCommandBuffer(
996 m_osInterface,
997 &cmdBuffer,
998 m_videoContextUsesNullHw));
999
1000 CODECHAL_DEBUG_TOOL(
1001 m_mmc->UpdateUserFeatureKey(&m_destSurface);)
1002
1003 if (m_statusQueryReportingEnabled)
1004 {
1005 CODECHAL_DECODE_CHK_STATUS_RETURN(ResetStatusReport(
1006 m_videoContextUsesNullHw));
1007 }
1008
1009 // Set output surface layout
1010 SetOutputSurfaceLayout(&m_decodeParams.m_outputSurfLayout);
1011
1012 // Send the signal to indicate decode completion, in case On-Demand Sync is not present
1013 CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnResourceSignal(
1014 m_osInterface,
1015 &syncParams));
1016
1017 CODECHAL_DEBUG_TOOL(
1018 CODECHAL_DECODE_CHK_STATUS_RETURN(m_debugInterface->DumpYUVSurface(
1019 &m_destSurface,
1020 CodechalDbgAttr::attrDecodeOutputSurface,
1021 "DstSurf"));)
1022 return eStatus;
1023 }
1024
InitMmcState()1025 MOS_STATUS CodechalDecodeJpeg::InitMmcState()
1026 {
1027 #ifdef _MMC_SUPPORTED
1028 m_mmc = MOS_New(CodechalMmcDecodeJpeg, m_hwInterface, this);
1029 CODECHAL_DECODE_CHK_NULL_RETURN(m_mmc);
1030 #endif
1031
1032 return MOS_STATUS_SUCCESS;
1033 }
1034
1035 #ifdef _DECODE_PROCESSING_SUPPORTED
InitSfcState()1036 MOS_STATUS CodechalDecodeJpeg::InitSfcState()
1037 {
1038 m_sfcState = MOS_New(CodechalJpegSfcState);
1039 CODECHAL_DECODE_CHK_NULL_RETURN(m_sfcState);
1040
1041 return MOS_STATUS_SUCCESS;
1042 }
1043 #endif
1044
AllocateStandard(CodechalSetting * settings)1045 MOS_STATUS CodechalDecodeJpeg::AllocateStandard(
1046 CodechalSetting *settings)
1047 {
1048 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1049
1050 CODECHAL_DECODE_FUNCTION_ENTER;
1051
1052 CODECHAL_DECODE_CHK_NULL_RETURN(settings);
1053
1054 CODECHAL_DECODE_CHK_STATUS_RETURN(InitMmcState());
1055 #ifdef _DECODE_PROCESSING_SUPPORTED
1056 CODECHAL_DECODE_CHK_STATUS_RETURN(InitSfcState());
1057 #endif
1058
1059 m_width = settings->width;
1060 m_height = settings->height;
1061
1062 #ifdef _DECODE_PROCESSING_SUPPORTED
1063 CODECHAL_DECODE_CHK_STATUS_RETURN(m_sfcState->InitializeSfcState(
1064 this,
1065 m_hwInterface,
1066 m_osInterface));
1067 #endif
1068
1069 CODECHAL_DECODE_CHK_STATUS_RETURN(AllocateResources());
1070
1071 return eStatus;
1072 }
1073
1074 #if USE_CODECHAL_DEBUG_TOOL
DumpIQParams(CodecJpegQuantMatrix * matrixData)1075 MOS_STATUS CodechalDecodeJpeg::DumpIQParams(
1076 CodecJpegQuantMatrix *matrixData)
1077 {
1078 CODECHAL_DEBUG_FUNCTION_ENTER;
1079
1080 if (!m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrIqParams))
1081 {
1082 return MOS_STATUS_SUCCESS;
1083 }
1084
1085 CODECHAL_DEBUG_CHK_NULL(matrixData);
1086
1087 std::ostringstream oss;
1088 oss.setf(std::ios::showbase | std::ios::uppercase);
1089
1090 for (uint32_t j = 0; j < jpegNumComponent; j++)
1091 {
1092 oss << "Qmatrix " << std::dec << +j << ": " << std::endl;
1093
1094 for (int8_t i = 0; i < 56; i += 8)
1095 {
1096 oss << "Qmatrix[" << std::dec << +i / 8 << "]:";
1097 for (uint8_t k = 0; k < 8; k++)
1098 oss << std::hex << +matrixData->m_quantMatrix[j][i + k]<< " ";
1099 oss << std::endl;
1100 }
1101 }
1102
1103 const char *fileName = m_debugInterface->CreateFileName(
1104 "_DEC",
1105 CodechalDbgBufferType::bufIqParams,
1106 CodechalDbgExtType::txt);
1107
1108 std::ofstream ofs(fileName, std::ios::out);
1109 ofs << oss.str();
1110 ofs.close();
1111
1112 return MOS_STATUS_SUCCESS;
1113 }
1114
DumpPicParams(CodecDecodeJpegPicParams * picParams)1115 MOS_STATUS CodechalDecodeJpeg::DumpPicParams(
1116 CodecDecodeJpegPicParams *picParams)
1117 {
1118 CODECHAL_DEBUG_FUNCTION_ENTER;
1119
1120 if (!m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrPicParams))
1121 {
1122 return MOS_STATUS_SUCCESS;
1123 }
1124
1125 CODECHAL_DEBUG_CHK_NULL(picParams);
1126
1127 std::ostringstream oss;
1128 oss.setf(std::ios::showbase | std::ios::uppercase);
1129 oss.setf(std::ios::hex, std::ios::basefield);
1130
1131 oss << "destPic.FrameIdx: " << +picParams->m_destPic.FrameIdx << std::endl;
1132 oss << "destPic.PicFlags: " << +picParams->m_destPic.PicFlags << std::endl;
1133 oss << "frameWidth: " << +picParams->m_frameWidth << std::endl;
1134 oss << "frameHeight: " << +picParams->m_frameHeight << std::endl;
1135 oss << "numCompInFrame: " << +picParams->m_numCompInFrame << std::endl;
1136
1137 //Dump componentIdentifier[jpegNumComponent]
1138 for (uint32_t i = 0; i < jpegNumComponent; ++i)
1139 {
1140 oss << "componentIdentifier[" << +i << "]: " << +picParams->m_componentIdentifier[i] << std::endl;
1141 }
1142
1143 //Dump quantTableSelector[jpegNumComponent]
1144 for (uint32_t i = 0; i < jpegNumComponent; ++i)
1145 {
1146 oss << "quantTableSelector[" << +i << "]: " << +picParams->m_quantTableSelector[i] << std::endl;
1147 }
1148 oss << "chromaType: " << +picParams->m_chromaType << std::endl;
1149 oss << "rotation: " << +picParams->m_rotation << std::endl;
1150 oss << "totalScans: " << +picParams->m_totalScans << std::endl;
1151 oss << "interleavedData: " << +picParams->m_interleavedData << std::endl;
1152 oss << "reserved: " << +picParams->m_reserved << std::endl;
1153 oss << "statusReportFeedbackNumber: " << +picParams->m_statusReportFeedbackNumber << std::endl;
1154
1155 const char *fileName = m_debugInterface->CreateFileName(
1156 "_DEC",
1157 CodechalDbgBufferType::bufPicParams,
1158 CodechalDbgExtType::txt);
1159
1160 std::ofstream ofs(fileName, std::ios::out);
1161 ofs << oss.str();
1162 ofs.close();
1163
1164 return MOS_STATUS_SUCCESS;
1165 }
1166
DumpScanParams(CodecDecodeJpegScanParameter * scanParams)1167 MOS_STATUS CodechalDecodeJpeg::DumpScanParams(
1168 CodecDecodeJpegScanParameter *scanParams)
1169 {
1170 CODECHAL_DEBUG_FUNCTION_ENTER;
1171
1172 if (!m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrScanParams))
1173 {
1174 return MOS_STATUS_SUCCESS;
1175 }
1176 CODECHAL_DEBUG_CHK_NULL(scanParams);
1177
1178 std::ostringstream oss;
1179 oss.setf(std::ios::showbase | std::ios::uppercase);
1180
1181 //Dump ScanHeader[jpegNumComponent]
1182 for (uint32_t i = 0; i < jpegNumComponent; ++i)
1183 {
1184 oss << "ScanHeader[" << +i << "].NumComponents: " << +scanParams->ScanHeader[i].NumComponents << std::endl;
1185 //Dump ComponentSelector[jpegNumComponent]
1186 for (uint32_t j = 0; j < jpegNumComponent; ++j)
1187 {
1188 oss << "ScanHeader[" << +i << "].ComponentSelector[" << +j << "]: " << +scanParams->ScanHeader[i].ComponentSelector[j] << std::endl;
1189 }
1190
1191 //Dump DcHuffTblSelector[jpegNumComponent]
1192 for (uint32_t j = 0; j < jpegNumComponent; ++j)
1193 {
1194 oss << "ScanHeader[" << +i << "].DcHuffTblSelector[" << +j << "]: " << +scanParams->ScanHeader[i].DcHuffTblSelector[j] << std::endl;
1195 }
1196
1197 //Dump AcHuffTblSelector[jpegNumComponent]
1198 for (uint32_t j = 0; j < jpegNumComponent; ++j)
1199 {
1200 oss << "ScanHeader[" << +i << "].AcHuffTblSelector[" << +j << "]: " << +scanParams->ScanHeader[i].AcHuffTblSelector[j] << std::endl;
1201 }
1202 oss << "ScanHeader[" << +i << "].RestartInterval: " << +scanParams->ScanHeader[i].RestartInterval << std::endl;
1203 oss << "ScanHeader[" << +i << "].MCUCount: " << +scanParams->ScanHeader[i].MCUCount << std::endl;
1204 oss << "ScanHeader[" << +i << "].ScanHoriPosition: " << +scanParams->ScanHeader[i].ScanHoriPosition << std::endl;
1205 oss << "ScanHeader[" << +i << "].ScanVertPosition: " << +scanParams->ScanHeader[i].ScanVertPosition << std::endl;
1206 oss << "ScanHeader[" << +i << "].DataOffset: " << +scanParams->ScanHeader[i].DataOffset << std::endl;
1207 oss << "ScanHeader[" << +i << "].DataLength: " << +scanParams->ScanHeader[i].DataLength << std::endl;
1208 }
1209
1210 oss << "NumScans: " << +scanParams->NumScans << std::endl;
1211
1212 const char *fileName = m_debugInterface->CreateFileName(
1213 "_DEC",
1214 CodechalDbgBufferType::bufScanParams,
1215 CodechalDbgExtType::txt);
1216
1217 std::ofstream ofs(fileName, std::ios::out);
1218 ofs << oss.str();
1219 ofs.close();
1220 return MOS_STATUS_SUCCESS;
1221 }
1222
DumpHuffmanTable(PCODECHAL_DECODE_JPEG_HUFFMAN_TABLE huffmanTable)1223 MOS_STATUS CodechalDecodeJpeg::DumpHuffmanTable(
1224 PCODECHAL_DECODE_JPEG_HUFFMAN_TABLE huffmanTable)
1225 {
1226 CODECHAL_DEBUG_FUNCTION_ENTER;
1227 if (!m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrHuffmanTbl))
1228 {
1229 return MOS_STATUS_SUCCESS;
1230 }
1231 CODECHAL_DEBUG_CHK_NULL(huffmanTable);
1232
1233 std::ostringstream oss;
1234 oss.setf(std::ios::showbase | std::ios::uppercase);
1235
1236 //Dump HuffTable[JPEG_MAX_NUM_HUFF_TABLE_INDEX]
1237 for (uint32_t i = 0; i < JPEG_MAX_NUM_HUFF_TABLE_INDEX; ++i)
1238 {
1239 //Dump DC_BITS[JPEG_NUM_HUFF_TABLE_DC_BITS]
1240 oss << "HuffTable[" << +i << "].DC_BITS[0-" << (JPEG_NUM_HUFF_TABLE_DC_BITS - 1) << "]: " << std::endl;
1241
1242 for (uint32_t j = 0; j < JPEG_NUM_HUFF_TABLE_DC_BITS; ++j)
1243 {
1244 oss << +huffmanTable->HuffTable[i].DC_BITS[j] << " ";
1245 if (j % 6 == 5 || j == JPEG_NUM_HUFF_TABLE_DC_BITS - 1)
1246 {
1247 oss << std::endl;
1248 }
1249 }
1250 //Dump DC_HUFFVAL[JPEG_NUM_HUFF_TABLE_DC_HUFFVAL]
1251 oss << "HuffTable[" << +i << "].DC_HUFFVAL[0-" << (JPEG_NUM_HUFF_TABLE_DC_HUFFVAL - 1) << "]: " << std::endl;
1252 for (uint32_t j = 0; j < JPEG_NUM_HUFF_TABLE_DC_HUFFVAL; ++j)
1253 {
1254 oss << +huffmanTable->HuffTable[i].DC_HUFFVAL[j] << ' ';
1255 if (j % 6 == 5 || j == JPEG_NUM_HUFF_TABLE_DC_HUFFVAL - 1)
1256 {
1257 oss << std::endl;
1258 }
1259 }
1260 //Dump AC_BITS[JPEG_NUM_HUFF_TABLE_AC_BITS]
1261 oss << "HuffTable[" << +i << "].AC_BITS[0-" << (JPEG_NUM_HUFF_TABLE_AC_BITS - 1) << "]: " << std::endl;
1262
1263 for (uint32_t j = 0; j < JPEG_NUM_HUFF_TABLE_AC_BITS; ++j)
1264 {
1265 oss << +huffmanTable->HuffTable[i].AC_BITS[j] << ' ';
1266 if (j % 8 == 7 || j == JPEG_NUM_HUFF_TABLE_AC_BITS - 1)
1267 {
1268 oss << std::endl;
1269 }
1270 }
1271
1272 //Dump AC_HUFFVAL[JPEG_NUM_HUFF_TABLE_AC_HUFFVAL]
1273 oss << "HuffTable[" << +i << "].AC_HUFFVAL[0-" << (JPEG_NUM_HUFF_TABLE_AC_HUFFVAL - 1) << "]: " << std::endl;
1274
1275 for (uint32_t j = 0; j < JPEG_NUM_HUFF_TABLE_AC_HUFFVAL; ++j)
1276 {
1277 oss << +huffmanTable->HuffTable[i].AC_HUFFVAL[j] << ' ';
1278 if (j % 9 == 8 || j == JPEG_NUM_HUFF_TABLE_AC_HUFFVAL - 1)
1279 {
1280 oss << std::endl;
1281 }
1282 }
1283 }
1284
1285 const char *fileName = m_debugInterface->CreateFileName(
1286 "_DEC",
1287 CodechalDbgBufferType::bufHuffmanTbl,
1288 CodechalDbgExtType::txt);
1289
1290 std::ofstream ofs(fileName, std::ios::out);
1291 ofs << oss.str();
1292 ofs.close();
1293 return MOS_STATUS_SUCCESS;
1294 }
1295
1296 #endif
1297