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