1 /*
2 * Copyright (c) 2009-2017, 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 media_ddi_decode_jpeg.cpp
24 //! \brief The class implementation of DdiDecodeJPEG for JPEG decode
25 //!
26 //!
27
28 #include <va/va_dec_jpeg.h>
29 #include "media_libva_decoder.h"
30 #include "media_libva_util.h"
31 #include "media_ddi_decode_jpeg.h"
32 #include "mos_solo_generic.h"
33 #include "codechal_decode_jpeg.h"
34 #include "media_ddi_decode_const.h"
35 #include "media_ddi_factory.h"
36
37 typedef enum _DDI_DECODE_JPEG_BUFFER_STATE
38 {
39 BUFFER_UNLOADED = 0,
40 BUFFER_LOADED = 1,
41 } DDI_DECODE_JPEG_BUFFER_STATE;
42
43 #define DDI_DECODE_JPEG_MAXIMUM_HUFFMAN_TABLE 2
44 #define DDI_DECODE_JPEG_MAXIMUM_QMATRIX_NUM 4
45 #define DDI_DECODE_JPEG_MAXIMUM_QMATRIX_ENTRIES 64
46
47 #define DDI_DECODE_JPEG_SLICE_PARAM_BUF_NUM 0x4 //According to JPEG SPEC, max slice per frame is 4
48
49 static const uint32_t zigzag_order[64] =
50 {
51 0, 1, 8, 16, 9, 2, 3, 10,
52 17, 24, 32, 25, 18, 11, 4, 5,
53 12, 19, 26, 33, 40, 48, 41, 34,
54 27, 20, 13, 6, 7, 14, 21, 28,
55 35, 42, 49, 56, 57, 50, 43, 36,
56 29, 22, 15, 23, 30, 37, 44, 51,
57 58, 59, 52, 45, 38, 31, 39, 46,
58 53, 60, 61, 54, 47, 55, 62, 63
59 };
60
ParseSliceParams(DDI_MEDIA_CONTEXT * mediaCtx,VASliceParameterBufferJPEGBaseline * slcParam,uint32_t numSlices)61 VAStatus DdiDecodeJPEG::ParseSliceParams(
62 DDI_MEDIA_CONTEXT *mediaCtx,
63 VASliceParameterBufferJPEGBaseline *slcParam,
64 uint32_t numSlices)
65 {
66 CodecDecodeJpegScanParameter *jpegSliceParam =
67 (CodecDecodeJpegScanParameter *)(m_ddiDecodeCtx->DecodeParams.m_sliceParams);
68
69 CodecDecodeJpegPicParams *picParam = (CodecDecodeJpegPicParams *)(m_ddiDecodeCtx->DecodeParams.m_picParams);
70
71 if ((jpegSliceParam == nullptr) ||
72 (picParam == nullptr) ||
73 (slcParam == nullptr))
74 {
75 DDI_ASSERTMESSAGE("Invalid Parameter for Parsing JPEG Slice parameter\n");
76 return VA_STATUS_ERROR_INVALID_PARAMETER;
77 }
78
79 jpegSliceParam->NumScans += numSlices;
80 picParam->m_totalScans += numSlices;
81 if (picParam->m_totalScans == 1 && slcParam[0].num_components > 1)
82 {
83 picParam->m_interleavedData = 1;
84 }
85
86 uint32_t j, i;
87 int32_t startIdx = m_numScans;
88 for (j = 0; j < numSlices; j++)
89 {
90 if (j + startIdx >= jpegNumComponent ||
91 slcParam[j].num_components > jpegNumComponent)
92 {
93 return VA_STATUS_ERROR_INVALID_PARAMETER;
94 }
95
96 for (i = 0; i < slcParam[j].num_components; i++)
97 {
98 jpegSliceParam->ScanHeader[j + startIdx].ComponentSelector[i] = slcParam[j].components[i].component_selector;
99 jpegSliceParam->ScanHeader[j + startIdx].DcHuffTblSelector[i] = slcParam[j].components[i].dc_table_selector;
100 jpegSliceParam->ScanHeader[j + startIdx].AcHuffTblSelector[i] = slcParam[j].components[i].ac_table_selector;
101 }
102 jpegSliceParam->ScanHeader[j + startIdx].NumComponents = slcParam[j].num_components;
103 jpegSliceParam->ScanHeader[j + startIdx].RestartInterval = slcParam[j].restart_interval;
104 jpegSliceParam->ScanHeader[j + startIdx].MCUCount = slcParam[j].num_mcus;
105 jpegSliceParam->ScanHeader[j + startIdx].ScanHoriPosition = slcParam[j].slice_horizontal_position;
106 jpegSliceParam->ScanHeader[j + startIdx].ScanVertPosition = slcParam[j].slice_vertical_position;
107 jpegSliceParam->ScanHeader[j + startIdx].DataOffset = slcParam[j].slice_data_offset;
108 jpegSliceParam->ScanHeader[j + startIdx].DataLength = slcParam[j].slice_data_size;
109 }
110
111 return VA_STATUS_SUCCESS;
112 }
113
ParsePicParams(DDI_MEDIA_CONTEXT * mediaCtx,VAPictureParameterBufferJPEGBaseline * picParam)114 VAStatus DdiDecodeJPEG::ParsePicParams(
115 DDI_MEDIA_CONTEXT *mediaCtx,
116 VAPictureParameterBufferJPEGBaseline *picParam)
117 {
118 CodecDecodeJpegPicParams *jpegPicParam = (CodecDecodeJpegPicParams *)(m_ddiDecodeCtx->DecodeParams.m_picParams);
119
120 if ((jpegPicParam == nullptr) ||
121 (picParam == nullptr))
122 {
123 DDI_ASSERTMESSAGE("Null Parameter for Parsing JPEG Picture parameter\n");
124 return VA_STATUS_ERROR_INVALID_PARAMETER;
125 }
126
127 jpegPicParam->m_frameWidth = picParam->picture_width;
128 jpegPicParam->m_frameHeight = picParam->picture_height;
129 jpegPicParam->m_numCompInFrame = picParam->num_components;
130
131 switch (picParam->rotation)
132 {
133 case VA_ROTATION_NONE:
134 jpegPicParam->m_rotation = jpegRotation0;
135 break;
136 case VA_ROTATION_90:
137 jpegPicParam->m_rotation = jpegRotation90;
138 break;
139 case VA_ROTATION_180:
140 jpegPicParam->m_rotation = jpegRotation180;
141 break;
142 case VA_ROTATION_270:
143 jpegPicParam->m_rotation = jpegRotation270;
144 break;
145 default:
146 /* For the other rotation type, the rotation is disabled. */
147 jpegPicParam->m_rotation = jpegRotation0;
148 break;
149 ;
150 }
151
152 if (jpegPicParam->m_numCompInFrame == 1)
153 {
154 jpegPicParam->m_chromaType = jpegYUV400;
155 }
156 else if (jpegPicParam->m_numCompInFrame == 3)
157 {
158 int32_t h1 = picParam->components[0].h_sampling_factor;
159 int32_t h2 = picParam->components[1].h_sampling_factor;
160 int32_t h3 = picParam->components[2].h_sampling_factor;
161 int32_t v1 = picParam->components[0].v_sampling_factor;
162 int32_t v2 = picParam->components[1].v_sampling_factor;
163 int32_t v3 = picParam->components[2].v_sampling_factor;
164
165 if (h1 == 2 && h2 == 1 && h3 == 1 &&
166 v1 == 2 && v2 == 1 && v3 == 1)
167 {
168 jpegPicParam->m_chromaType = jpegYUV420;
169 }
170 else if (h1 == 2 && h2 == 1 && h3 == 1 &&
171 v1 == 1 && v2 == 1 && v3 == 1)
172 {
173 jpegPicParam->m_chromaType = jpegYUV422H2Y;
174 }
175 else if (h1 == 1 && h2 == 1 && h3 == 1 &&
176 v1 == 1 && v2 == 1 && v3 == 1)
177 {
178 switch (picParam->color_space)
179 {
180 case 0: //YUV
181 jpegPicParam->m_chromaType = jpegYUV444;
182 break;
183 case 1: //RGB
184 jpegPicParam->m_chromaType = jpegRGB;
185 break;
186 case 2: //BGR
187 jpegPicParam->m_chromaType = jpegBGR;
188 break;
189 default:
190 /* For the other type, the default YUV444 is used */
191 jpegPicParam->m_chromaType = jpegYUV444;
192 break;
193 ;
194 }
195 }
196 else if (h1 == 4 && h2 == 1 && h3 == 1 &&
197 v1 == 1 && v2 == 1 && v3 == 1)
198 {
199 jpegPicParam->m_chromaType = jpegYUV411;
200 }
201 else if (h1 == 1 && h2 == 1 && h3 == 1 &&
202 v1 == 2 && v2 == 1 && v3 == 1)
203 {
204 jpegPicParam->m_chromaType = jpegYUV422V2Y;
205 }
206 else if (h1 == 2 && h2 == 1 && h3 == 1 &&
207 v1 == 2 && v2 == 2 && v3 == 2)
208 {
209 jpegPicParam->m_chromaType = jpegYUV422H4Y;
210 }
211 else if (h1 == 2 && h2 == 2 && h3 == 2 &&
212 v1 == 2 && v2 == 1 && v3 == 1)
213 {
214 jpegPicParam->m_chromaType = jpegYUV422V4Y;
215 }
216 else
217 {
218 DDI_NORMALMESSAGE("Unsupported sampling factor in JPEG Picture parameter\n");
219 return VA_STATUS_ERROR_INVALID_PARAMETER;
220 }
221 }
222
223 memset(jpegPicParam->m_componentIdentifier, 0, jpegNumComponent);
224 memset(jpegPicParam->m_quantTableSelector, 0, jpegNumComponent);
225
226 if (picParam->num_components > jpegNumComponent)
227 {
228 DDI_NORMALMESSAGE("Unsupported component num in JPEG Picture parameter\n");
229 return VA_STATUS_ERROR_INVALID_PARAMETER;
230 }
231 for (int32_t i = 0; i < picParam->num_components; i++)
232 {
233 jpegPicParam->m_componentIdentifier[i] = picParam->components[i].component_id;
234 jpegPicParam->m_quantTableSelector[i] = picParam->components[i].quantiser_table_selector;
235 }
236
237 return VA_STATUS_SUCCESS;
238 }
239
ParseHuffmanTbl(DDI_MEDIA_CONTEXT * mediaCtx,VAHuffmanTableBufferJPEGBaseline * huffmanTbl)240 VAStatus DdiDecodeJPEG::ParseHuffmanTbl(
241 DDI_MEDIA_CONTEXT * mediaCtx,
242 VAHuffmanTableBufferJPEGBaseline *huffmanTbl)
243 {
244 PCODECHAL_DECODE_JPEG_HUFFMAN_TABLE jpegHuffTbl = (PCODECHAL_DECODE_JPEG_HUFFMAN_TABLE)(m_ddiDecodeCtx->DecodeParams.m_huffmanTable);
245 int32_t sumBITS = 0;
246
247 if ((jpegHuffTbl == nullptr) ||
248 (huffmanTbl == nullptr))
249 {
250 DDI_ASSERTMESSAGE("Null Parameter for Parsing JPEG Huffman Tableparameter\n");
251 return VA_STATUS_ERROR_INVALID_PARAMETER;
252 }
253
254 memset(jpegHuffTbl, 0, sizeof(CODECHAL_DECODE_JPEG_HUFFMAN_TABLE));
255
256 for (int32_t i = 0; i < DDI_DECODE_JPEG_MAXIMUM_HUFFMAN_TABLE; i++)
257 {
258 if (huffmanTbl->load_huffman_table[i] == BUFFER_LOADED)
259 {
260 sumBITS = 0;
261 for (int32_t j = 0; j < JPEG_NUM_HUFF_TABLE_DC_BITS; j++)
262 {
263 sumBITS += huffmanTbl->huffman_table[i].num_dc_codes[j];
264 }
265
266 if (sumBITS > JPEG_NUM_HUFF_TABLE_DC_HUFFVAL)
267 {
268 DDI_ASSERTMESSAGE("Huffman table DC entries number is out of HW limitation.");
269 return VA_STATUS_ERROR_INVALID_PARAMETER;
270 }
271
272 //the size of jpegHuffTbl->HuffTable[i].DC_BITS is 12 (defined in driver)
273 //the size of huffmanTbl->huffman_table[i].num_dc_codes is 16 (defined in libva)
274 //it is using the size of "DC_BITS" for solve the overflow
275 MOS_SecureMemcpy(jpegHuffTbl->HuffTable[i].DC_BITS,
276 sizeof(jpegHuffTbl->HuffTable[i].DC_BITS),
277 huffmanTbl->huffman_table[i].num_dc_codes,
278 sizeof(jpegHuffTbl->HuffTable[i].DC_BITS));
279 MOS_SecureMemcpy(jpegHuffTbl->HuffTable[i].DC_HUFFVAL,
280 sizeof(jpegHuffTbl->HuffTable[i].DC_HUFFVAL),
281 huffmanTbl->huffman_table[i].dc_values,
282 sizeof(huffmanTbl->huffman_table[i].dc_values));
283 MOS_SecureMemcpy(jpegHuffTbl->HuffTable[i].AC_BITS,
284 sizeof(jpegHuffTbl->HuffTable[i].AC_BITS),
285 huffmanTbl->huffman_table[i].num_ac_codes,
286 sizeof(huffmanTbl->huffman_table[i].num_ac_codes));
287 MOS_SecureMemcpy(jpegHuffTbl->HuffTable[i].AC_HUFFVAL,
288 sizeof(jpegHuffTbl->HuffTable[i].AC_HUFFVAL),
289 huffmanTbl->huffman_table[i].ac_values,
290 sizeof(huffmanTbl->huffman_table[i].ac_values));
291 }
292 }
293
294 return VA_STATUS_SUCCESS;
295 }
296
297 /////////////////////////////////////////////////////////////////////////////////////////
298 //
299 // Function: JpegQMatrixDecode
300 // Description: Parse the QMatrix table from VAAPI, and load the valid Qmatrix to the Buffer used by
301 // CodecHal
302 //
303 /////////////////////////////////////////////////////////////////////////////////////////
ParseIQMatrix(DDI_MEDIA_CONTEXT * mediaCtx,VAIQMatrixBufferJPEGBaseline * matrix)304 VAStatus DdiDecodeJPEG::ParseIQMatrix(
305 DDI_MEDIA_CONTEXT *mediaCtx,
306 VAIQMatrixBufferJPEGBaseline *matrix)
307 {
308 CodecJpegQuantMatrix *jpegQMatrix = (CodecJpegQuantMatrix *)(m_ddiDecodeCtx->DecodeParams.m_iqMatrixBuffer);
309
310 if ((matrix == nullptr) || (jpegQMatrix == nullptr))
311 {
312 DDI_ASSERTMESSAGE("Null Parameter for Parsing JPEG IQMatrix \n");
313 return VA_STATUS_ERROR_INVALID_PARAMETER;
314 }
315
316 memset(jpegQMatrix, 0, sizeof(CodecJpegQuantMatrix));
317
318 int32_t idx, idx2;
319 for (idx = 0; idx < DDI_DECODE_JPEG_MAXIMUM_QMATRIX_NUM; idx++)
320 {
321 if (matrix->load_quantiser_table[idx] == BUFFER_LOADED)
322 {
323 for (idx2 = 0; idx2 < DDI_DECODE_JPEG_MAXIMUM_QMATRIX_ENTRIES; idx2++)
324 {
325 jpegQMatrix->m_quantMatrix[idx][zigzag_order[idx2]] = matrix->quantiser_table[idx][idx2];
326 }
327 }
328 }
329
330 return VA_STATUS_SUCCESS;
331 }
332
SetBufferRendered(VABufferID bufferID)333 VAStatus DdiDecodeJPEG::SetBufferRendered(VABufferID bufferID)
334 {
335 DDI_CODEC_COM_BUFFER_MGR *bufMgr = &(m_ddiDecodeCtx->BufMgr);
336
337 if (bufMgr == nullptr)
338 {
339 DDI_ASSERTMESSAGE("Null Parameter for Parsing Data buffer for JPEG\n");
340 return VA_STATUS_ERROR_INVALID_PARAMETER;
341 }
342
343 bool renderFlag = false;
344 for (uint32_t i = 0; i < bufMgr->dwNumSliceData; i++)
345 {
346 // Depend on the ID we tracked, if application want to rendered one of them
347 // we set some flags
348 if (bufMgr->pSliceData[i].vaBufferId == bufferID)
349 {
350 if (bufMgr->pSliceData[i].bRendered == false)
351 {
352 // set the rendered flags. which will be used when EndPicture.
353 bufMgr->pSliceData[i].bRendered = true;
354 // calculate the size of a bunch of rendered buffers. for endpicture to allocate appropriate memory size of GPU.
355 bufMgr->dwSizeOfRenderedSliceData += bufMgr->pSliceData[i].uiLength;
356 // keep record the render order, so that we can calculate the offset correctly when endpicture.
357 // in this array we save the buffer index in pSliceData which render in sequence. if application create buffers like: 4,3,5,1,2.
358 // but only render 2,3,5. the content in this array is: [4,1,2], which is the index of created buffer.
359 bufMgr->pRenderedOrder[bufMgr->dwNumOfRenderedSliceData] = i;
360 bufMgr->dwNumOfRenderedSliceData++;
361 }
362 renderFlag = true;
363 break;
364 }
365 }
366
367 if (renderFlag)
368 {
369 return VA_STATUS_SUCCESS;
370 }
371 else
372 {
373 return VA_STATUS_ERROR_INVALID_BUFFER;
374 }
375 }
376
RenderPicture(VADriverContextP ctx,VAContextID context,VABufferID * buffers,int32_t numBuffers)377 VAStatus DdiDecodeJPEG::RenderPicture(
378 VADriverContextP ctx,
379 VAContextID context,
380 VABufferID *buffers,
381 int32_t numBuffers)
382 {
383 DDI_FUNCTION_ENTER();
384
385 VAStatus va = VA_STATUS_SUCCESS;
386 PDDI_MEDIA_CONTEXT mediaCtx = DdiMedia_GetMediaContext(ctx);
387
388 void *data = nullptr;
389 for (int32_t i = 0; i < numBuffers; i++)
390 {
391 if (!buffers || (buffers[i] == VA_INVALID_ID))
392 {
393 return VA_STATUS_ERROR_INVALID_BUFFER;
394 }
395
396 DDI_MEDIA_BUFFER *buf = DdiMedia_GetBufferFromVABufferID(mediaCtx, buffers[i]);
397 if (nullptr == buf)
398 {
399 return VA_STATUS_ERROR_INVALID_BUFFER;
400 }
401
402 uint32_t dataSize = buf->iSize;
403 DdiMedia_MapBuffer(ctx, buffers[i], &data);
404
405 if (data == nullptr)
406 {
407 return VA_STATUS_ERROR_INVALID_BUFFER;
408 }
409
410 switch ((int32_t)buf->uiType)
411 {
412 case VASliceDataBufferType:
413 {
414 DDI_CHK_RET(SetBufferRendered(buffers[i]),"SetBufferRendered failed!");
415 m_ddiDecodeCtx->DecodeParams.m_dataSize += dataSize;
416 break;
417 }
418 case VASliceParameterBufferType:
419 {
420 if (buf->uiNumElements == 0)
421 {
422 return VA_STATUS_ERROR_INVALID_BUFFER;
423 }
424
425 uint32_t numSlices = buf->uiNumElements;
426
427 if ((m_numScans + numSlices) > jpegNumComponent)
428 {
429 DDI_NORMALMESSAGE("the total number of JPEG scans are beyond the supported num(4)\n");
430 return VA_STATUS_ERROR_INVALID_PARAMETER;
431 }
432 DDI_CHK_RET(AllocSliceParamContext(numSlices),"AllocSliceParamContext failed!");
433 VASliceParameterBufferJPEGBaseline *slcInfo = (VASliceParameterBufferJPEGBaseline *)data;
434 DDI_CHK_RET(ParseSliceParams(mediaCtx, slcInfo, numSlices),"ParseSliceParams failed!");
435 m_ddiDecodeCtx->BufMgr.pNumOfRenderedSliceParaForOneBuffer[m_ddiDecodeCtx->BufMgr.dwNumOfRenderedSlicePara] = numSlices;
436 m_ddiDecodeCtx->BufMgr.dwNumOfRenderedSlicePara ++;
437
438 m_ddiDecodeCtx->DecodeParams.m_numSlices += numSlices;
439 m_numScans += numSlices;
440 m_groupIndex++;
441 break;
442 }
443 case VAIQMatrixBufferType:
444 {
445 VAIQMatrixBufferJPEGBaseline *imxBuf = (VAIQMatrixBufferJPEGBaseline *)data;
446 DDI_CHK_RET(ParseIQMatrix(mediaCtx, imxBuf),"ParseIQMatrix failed!");
447 break;
448 }
449 case VAPictureParameterBufferType:
450 {
451 VAPictureParameterBufferJPEGBaseline *picParam = (VAPictureParameterBufferJPEGBaseline *)data;
452 DDI_CHK_RET(ParsePicParams(mediaCtx, picParam),"ParsePicParams failed!");
453 break;
454 }
455 case VAHuffmanTableBufferType:
456 {
457 VAHuffmanTableBufferJPEGBaseline *huffTbl = (VAHuffmanTableBufferJPEGBaseline *)data;
458 DDI_CHK_RET(ParseHuffmanTbl(mediaCtx, huffTbl),"ParseHuffmanTbl failed!");
459 break;
460 }
461 case VAProcPipelineParameterBufferType:
462 {
463 DDI_NORMALMESSAGE("ProcPipeline is not supported for JPEGBaseline decoding\n");
464 break;
465 }
466 case VADecodeStreamoutBufferType:
467 {
468 DdiMedia_MediaBufferToMosResource(buf, &m_ddiDecodeCtx->BufMgr.resExternalStreamOutBuffer);
469 m_streamOutEnabled = true;
470 break;
471 }
472 default:
473 va = VA_STATUS_ERROR_UNSUPPORTED_BUFFERTYPE;
474 break;
475 }
476 DdiMedia_UnmapBuffer(ctx, buffers[i]);
477 }
478
479 DDI_FUNCTION_EXIT(va);
480 return va;
481 }
482
BeginPicture(VADriverContextP ctx,VAContextID context,VASurfaceID renderTarget)483 VAStatus DdiDecodeJPEG::BeginPicture(
484 VADriverContextP ctx,
485 VAContextID context,
486 VASurfaceID renderTarget)
487 {
488 VAStatus vaStatus = DdiMediaDecode::BeginPicture(ctx, context, renderTarget);
489
490 if (vaStatus != VA_STATUS_SUCCESS)
491 {
492 return vaStatus;
493 }
494
495 if (m_jpegBitstreamBuf)
496 {
497 DdiMediaUtil_FreeBuffer(m_jpegBitstreamBuf);
498 MOS_FreeMemory(m_jpegBitstreamBuf);
499 m_jpegBitstreamBuf = nullptr;
500 }
501
502 CodecDecodeJpegScanParameter *jpegSliceParam =
503 (CodecDecodeJpegScanParameter *)(m_ddiDecodeCtx->DecodeParams.m_sliceParams);
504 jpegSliceParam->NumScans = 0;
505
506 CodecDecodeJpegPicParams *picParam = (CodecDecodeJpegPicParams *)(m_ddiDecodeCtx->DecodeParams.m_picParams);
507 picParam->m_totalScans = 0;
508
509 m_numScans = 0;
510 return vaStatus;
511 }
512
CheckFormat(MOS_FORMAT format)513 bool DdiDecodeJPEG::CheckFormat(MOS_FORMAT format)
514 {
515 bool isSupported = false;
516 CodecDecodeJpegPicParams *jpegPicParam = (CodecDecodeJpegPicParams *)(m_ddiDecodeCtx->DecodeParams.m_picParams);
517 switch (jpegPicParam->m_chromaType)
518 {
519 case jpegYUV400:
520 if (format == Format_400P || format == Format_A8R8G8B8)
521 {
522 isSupported = true;
523 }
524 break;
525 case jpegYUV420:
526 if (format == Format_NV12 || format == Format_YUY2 || format == Format_UYVY || format == Format_IMC3 || format == Format_A8R8G8B8)
527 {
528 isSupported = true;
529 }
530 break;
531 case jpegYUV411:
532 if (format == Format_411P)
533 {
534 isSupported = true;
535 }
536 break;
537 case jpegYUV422H2Y:
538 case jpegYUV422H4Y:
539 if (format == Format_NV12 || format == Format_YUY2 || format == Format_UYVY || format == Format_422H || format == Format_A8R8G8B8)
540 {
541 isSupported = true;
542 }
543 break;
544 case jpegYUV422V2Y:
545 case jpegYUV422V4Y:
546 if (format == Format_NV12 || format == Format_422V || format == Format_A8R8G8B8)
547 {
548 isSupported = true;
549 }
550 break;
551 case jpegYUV444:
552 if (format == Format_444P || format == Format_A8R8G8B8)
553 {
554 isSupported = true;
555 }
556 break;
557 case jpegRGB:
558 case jpegBGR:
559 if (format == Format_RGBP || format == Format_BGRP ||format == Format_A8R8G8B8)
560 {
561 isSupported = true;
562 }
563 break;
564 default:
565 break;
566 }
567
568 return isSupported;
569 }
570
InitDecodeParams(VADriverContextP ctx,VAContextID context)571 VAStatus DdiDecodeJPEG::InitDecodeParams(
572 VADriverContextP ctx,
573 VAContextID context)
574 {
575 /* skip the mediaCtx check as it is checked in caller */
576 PDDI_MEDIA_CONTEXT mediaCtx;
577 mediaCtx = DdiMedia_GetMediaContext(ctx);
578 DDI_CHK_RET(DecodeCombineBitstream(mediaCtx),"DecodeCombineBitstream failed!");
579 DDI_CODEC_COM_BUFFER_MGR *bufMgr = &(m_ddiDecodeCtx->BufMgr);
580 bufMgr->dwNumSliceControl = 0;
581 memset(&m_destSurface, 0, sizeof(MOS_SURFACE));
582 m_destSurface.dwOffset = 0;
583 DDI_CODEC_RENDER_TARGET_TABLE *rtTbl = &(m_ddiDecodeCtx->RTtbl);
584
585 if ((rtTbl == nullptr) || (rtTbl->pCurrentRT == nullptr))
586 {
587 return VA_STATUS_ERROR_INVALID_PARAMETER;
588 }
589 return VA_STATUS_SUCCESS;
590 }
591
SetDecodeParams()592 VAStatus DdiDecodeJPEG::SetDecodeParams()
593 {
594 DDI_CODEC_COM_BUFFER_MGR *bufMgr = &(m_ddiDecodeCtx->BufMgr);
595
596 // we do not support mismatched usecase.
597 if ((bufMgr->dwNumOfRenderedSlicePara != bufMgr->dwNumOfRenderedSliceData) ||
598 (bufMgr->dwNumOfRenderedSlicePara == 0))
599 {
600 DDI_NORMALMESSAGE("DDI: Unsupported buffer mismatch usage!\n");
601 return VA_STATUS_ERROR_INVALID_PARAMETER;
602 }
603
604 // Allocate GPU Buffer description keeper.
605 m_jpegBitstreamBuf = (DDI_MEDIA_BUFFER *)MOS_AllocAndZeroMemory(sizeof(DDI_MEDIA_BUFFER));
606 if (m_jpegBitstreamBuf == nullptr)
607 {
608 DDI_ASSERTMESSAGE("DDI: Allocate Jpeg Media Buffer Failed!\n");
609 return VA_STATUS_ERROR_UNKNOWN;
610 }
611
612 m_jpegBitstreamBuf->iSize = bufMgr->dwSizeOfRenderedSliceData;
613 m_jpegBitstreamBuf->uiNumElements = bufMgr->dwNumOfRenderedSliceData;
614 m_jpegBitstreamBuf->uiType = VASliceDataBufferType;
615 m_jpegBitstreamBuf->format = Media_Format_Buffer;
616 m_jpegBitstreamBuf->uiOffset = 0;
617 m_jpegBitstreamBuf->bCFlushReq = false;
618 m_jpegBitstreamBuf->pMediaCtx = m_ddiDecodeCtx->pMediaCtx;
619
620 // Create GPU buffer
621 VAStatus va = DdiMediaUtil_CreateBuffer(m_jpegBitstreamBuf, m_ddiDecodeCtx->pMediaCtx->pDrmBufMgr);
622 if (va != VA_STATUS_SUCCESS)
623 {
624 DdiMediaUtil_FreeBuffer(m_jpegBitstreamBuf);
625 MOS_FreeMemory(m_jpegBitstreamBuf);
626 m_jpegBitstreamBuf = nullptr;
627 return va;
628 }
629
630 // For the first time you call DdiMediaUtil_LockBuffer for a fresh GPU memory, it will map GPU address to a virtual address.
631 // and then, DdiMediaUtil_LockBuffer is acutally to increase the reference count. so we used here for 2 resaons:
632 //
633 // 1. Map GPU address to virtual at the beginning when we combine the CPU -> GPU.
634 uint8_t *mappedBuf = (uint8_t *)DdiMediaUtil_LockBuffer(m_jpegBitstreamBuf, MOS_LOCKFLAG_WRITEONLY);
635
636 if (mappedBuf == nullptr)
637 {
638 DdiMediaUtil_FreeBuffer(m_jpegBitstreamBuf);
639 MOS_FreeMemory(m_jpegBitstreamBuf);
640 m_jpegBitstreamBuf = nullptr;
641 return VA_STATUS_ERROR_ALLOCATION_FAILED;
642 }
643
644 // get the JPEG Slice Header Params for offset recaculated.
645 CodecDecodeJpegScanParameter *sliceParam =
646 (CodecDecodeJpegScanParameter *)(m_ddiDecodeCtx->DecodeParams.m_sliceParams);
647
648 uint32_t bufOffset = 0;
649 int32_t orderSlicePara = 0;
650 int32_t orderSliceData = 0;
651 for (uint32_t i = 0; i < bufMgr->dwNumOfRenderedSliceData; i++)
652 {
653 // get the rendered slice data index in rendered order.
654 int32_t renderedBufIdx = bufMgr->pRenderedOrder[i];
655 if (bufMgr->pSliceData[renderedBufIdx].bRendered)
656 {
657 MOS_SecureMemcpy((void *)(mappedBuf + bufOffset),
658 bufMgr->pSliceData[renderedBufIdx].uiLength,
659 bufMgr->pSliceData[renderedBufIdx].pBaseAddress,
660 bufMgr->pSliceData[renderedBufIdx].uiLength);
661
662 // since we assume application must make sure ONE slice parameter buffer ONE slice data buffer, so we recaculate header offset here.
663 for (int32_t j = 0; j < bufMgr->pNumOfRenderedSliceParaForOneBuffer[orderSliceData]; j++)
664 {
665 sliceParam->ScanHeader[orderSlicePara].DataOffset += bufOffset;
666 orderSlicePara++;
667 }
668 bufOffset += bufMgr->pSliceData[renderedBufIdx].uiLength;
669 bufMgr->pNumOfRenderedSliceParaForOneBuffer[orderSliceData] = 0;
670 orderSliceData++;
671 bufMgr->pSliceData[renderedBufIdx].bRendered = false;
672 }
673 }
674 DdiMediaUtil_UnlockBuffer(m_jpegBitstreamBuf);
675 DdiMedia_MediaBufferToMosResource(m_jpegBitstreamBuf, &(bufMgr->resBitstreamBuffer));
676 bufMgr->dwNumOfRenderedSliceData = 0;
677 bufMgr->dwNumOfRenderedSlicePara = 0;
678 bufMgr->dwSizeOfRenderedSliceData = 0;
679
680 m_destSurface.dwOffset = 0;
681 m_destSurface.Format = Format_NV12;
682
683 CodecDecodeJpegPicParams *jpegPicParam = (CodecDecodeJpegPicParams *)(m_ddiDecodeCtx->DecodeParams.m_picParams);
684 if((m_ddiDecodeCtx->RTtbl.pCurrentRT->format == Media_Format_NV12)
685 &&(jpegPicParam->m_chromaType == jpegYUV444))
686 {
687 UnRegisterRTSurfaces(&(m_ddiDecodeCtx->RTtbl), m_ddiDecodeCtx->RTtbl.pCurrentRT);
688 m_ddiDecodeCtx->RTtbl.pCurrentRT = DdiMedia_ReplaceSurfaceWithNewFormat(m_ddiDecodeCtx->RTtbl.pCurrentRT, Media_Format_444P);
689 RegisterRTSurfaces(&(m_ddiDecodeCtx->RTtbl), m_ddiDecodeCtx->RTtbl.pCurrentRT);
690 }
691 if(m_ddiDecodeCtx->RTtbl.pCurrentRT != nullptr)
692 {
693 DdiMedia_MediaSurfaceToMosResource((&(m_ddiDecodeCtx->RTtbl))->pCurrentRT, &(m_destSurface.OsResource));
694 }
695
696 if (!CheckFormat(m_destSurface.OsResource.Format))
697 {
698 DDI_ASSERTMESSAGE("Surface fomrat of decoded surface is inconsistent with Codec bitstream!\n");
699 return VA_STATUS_ERROR_INVALID_PARAMETER;
700 }
701
702 (&m_ddiDecodeCtx->DecodeParams)->m_destSurface = &m_destSurface;
703
704 (&m_ddiDecodeCtx->DecodeParams)->m_deblockSurface = nullptr;
705
706 (&m_ddiDecodeCtx->DecodeParams)->m_dataBuffer = &bufMgr->resBitstreamBuffer;
707 (&m_ddiDecodeCtx->DecodeParams)->m_bitStreamBufData = bufMgr->pBitstreamBuffer;
708 Mos_Solo_OverrideBufferSize((&m_ddiDecodeCtx->DecodeParams)->m_dataSize, (&m_ddiDecodeCtx->DecodeParams)->m_dataBuffer);
709
710 (&m_ddiDecodeCtx->DecodeParams)->m_bitplaneBuffer = nullptr;
711
712 if (m_streamOutEnabled)
713 {
714 (&m_ddiDecodeCtx->DecodeParams)->m_streamOutEnabled = true;
715 (&m_ddiDecodeCtx->DecodeParams)->m_externalStreamOutBuffer = &bufMgr->resExternalStreamOutBuffer;
716 }
717 else
718 {
719 (&m_ddiDecodeCtx->DecodeParams)->m_streamOutEnabled = false;
720 (&m_ddiDecodeCtx->DecodeParams)->m_externalStreamOutBuffer = nullptr;
721 }
722 return VA_STATUS_SUCCESS;
723 }
724
AllocSliceParamContext(uint32_t numSlices)725 VAStatus DdiDecodeJPEG::AllocSliceParamContext(
726 uint32_t numSlices)
727 {
728 uint32_t baseSize = sizeof(CodecDecodeJpegScanParameter);
729
730 if (m_sliceParamBufNum < (m_ddiDecodeCtx->DecodeParams.m_numSlices + numSlices))
731 {
732 // in order to avoid that the buffer is reallocated multi-times,
733 // extra 10 slices are added.
734 uint32_t extraSlices = numSlices + 10;
735
736 m_ddiDecodeCtx->DecodeParams.m_sliceParams = realloc(m_ddiDecodeCtx->DecodeParams.m_sliceParams,
737 baseSize * (m_sliceParamBufNum + extraSlices));
738
739 if (m_ddiDecodeCtx->DecodeParams.m_sliceParams == nullptr)
740 {
741 return VA_STATUS_ERROR_ALLOCATION_FAILED;
742 }
743
744 memset((void *)((uint8_t *)m_ddiDecodeCtx->DecodeParams.m_sliceParams + baseSize * m_sliceParamBufNum), 0, baseSize * extraSlices);
745 m_sliceParamBufNum += extraSlices;
746 }
747
748 return VA_STATUS_SUCCESS;
749 }
750
DestroyContext(VADriverContextP ctx)751 void DdiDecodeJPEG::DestroyContext(
752 VADriverContextP ctx)
753 {
754 FreeResourceBuffer();
755 // explicitly call the base function to do the further clean-up
756 DdiMediaDecode::DestroyContext(ctx);
757 }
758
GetPicParamBuf(DDI_CODEC_COM_BUFFER_MGR * bufMgr)759 uint8_t* DdiDecodeJPEG::GetPicParamBuf(
760 DDI_CODEC_COM_BUFFER_MGR *bufMgr)
761 {
762 return (uint8_t*)(&(bufMgr->Codec_Param.Codec_Param_JPEG.PicParamJPEG));
763 }
764
AllocBsBuffer(DDI_CODEC_COM_BUFFER_MGR * bufMgr,DDI_MEDIA_BUFFER * buf)765 VAStatus DdiDecodeJPEG::AllocBsBuffer(
766 DDI_CODEC_COM_BUFFER_MGR *bufMgr,
767 DDI_MEDIA_BUFFER *buf)
768 {
769 // Allocate JPEG slice data memory from CPU.
770 uint8_t *bsAddr;
771 uint32_t index;
772
773 index = bufMgr->dwNumSliceData;
774
775 /* the pSliceData needs to be reallocated in order to contain more SliceDataBuf */
776 if (index >= bufMgr->m_maxNumSliceData)
777 {
778 /* In theroy it can resize the m_maxNumSliceData one by one. But in order to
779 * avoid calling realloc frequently, it will try to allocate 10 to hold more
780 * SliceDataBuf. This is only for the optimized purpose.
781 */
782 int32_t reallocSize = bufMgr->m_maxNumSliceData + 10;
783
784 bufMgr->pSliceData = (DDI_CODEC_BITSTREAM_BUFFER_INFO *)realloc(bufMgr->pSliceData, sizeof(bufMgr->pSliceData[0]) * reallocSize);
785
786 if (bufMgr->pSliceData == nullptr)
787 {
788 DDI_ASSERTMESSAGE("fail to reallocate pSliceData for JPEG\n.");
789 return VA_STATUS_ERROR_ALLOCATION_FAILED;
790 }
791 memset((void *)(bufMgr->pSliceData + bufMgr->m_maxNumSliceData), 0,
792 sizeof(bufMgr->pSliceData[0]) * 10);
793
794 bufMgr->m_maxNumSliceData += 10;
795 }
796
797 bsAddr = (uint8_t*)MOS_AllocAndZeroMemory(buf->iSize);
798 if(bsAddr == 0)
799 {
800 return VA_STATUS_ERROR_ALLOCATION_FAILED;
801 }
802
803 buf->pData = bsAddr;
804 buf->format = Media_Format_CPU;
805 buf->bCFlushReq = false;
806 buf->uiOffset = 0;
807 bufMgr->pSliceData[index].uiLength = buf->iSize;
808 bufMgr->pSliceData[index].uiOffset = buf->uiOffset;
809 bufMgr->pSliceData[index].pBaseAddress = buf->pData;
810 bufMgr->dwNumSliceData ++;
811 return VA_STATUS_SUCCESS;
812 }
813
AllocSliceControlBuffer(DDI_MEDIA_BUFFER * buf)814 VAStatus DdiDecodeJPEG::AllocSliceControlBuffer(
815 DDI_MEDIA_BUFFER *buf)
816 {
817 DDI_CODEC_COM_BUFFER_MGR *bufMgr;
818 uint32_t availSize;
819 uint32_t newSize;
820
821 bufMgr = &(m_ddiDecodeCtx->BufMgr);
822 availSize = m_sliceCtrlBufNum - bufMgr->dwNumSliceControl;
823
824 if(availSize < buf->uiNumElements)
825 {
826 newSize = sizeof(VASliceParameterBufferJPEGBaseline) * (m_sliceCtrlBufNum - availSize + buf->uiNumElements);
827 bufMgr->Codec_Param.Codec_Param_JPEG.pVASliceParaBufJPEG = (VASliceParameterBufferJPEGBaseline *)realloc(bufMgr->Codec_Param.Codec_Param_JPEG.pVASliceParaBufJPEG, newSize);
828 if(bufMgr->Codec_Param.Codec_Param_JPEG.pVASliceParaBufJPEG == nullptr)
829 {
830 return VA_STATUS_ERROR_ALLOCATION_FAILED;
831 }
832 MOS_ZeroMemory(bufMgr->Codec_Param.Codec_Param_JPEG.pVASliceParaBufJPEG + m_sliceCtrlBufNum, sizeof(VASliceParameterBufferJPEGBaseline) * (buf->uiNumElements - availSize));
833 m_sliceCtrlBufNum = m_sliceCtrlBufNum - availSize + buf->uiNumElements;
834 }
835 buf->pData = (uint8_t*)bufMgr->Codec_Param.Codec_Param_JPEG.pVASliceParaBufJPEG;
836 buf->uiOffset = sizeof(VASliceParameterBufferJPEGBaseline) * bufMgr->dwNumSliceControl;
837
838 bufMgr->dwNumSliceControl += buf->uiNumElements;
839
840 return VA_STATUS_SUCCESS;
841 }
842
ContextInit(int32_t picWidth,int32_t picHeight)843 void DdiDecodeJPEG::ContextInit(
844 int32_t picWidth,
845 int32_t picHeight)
846 {
847 // call the function in base class to initialize it.
848 DdiMediaDecode::ContextInit(picWidth, picHeight);
849
850 m_ddiDecodeCtx->wMode = CODECHAL_DECODE_MODE_JPEG;
851 }
852
InitResourceBuffer()853 VAStatus DdiDecodeJPEG::InitResourceBuffer()
854 {
855 VAStatus vaStatus = VA_STATUS_SUCCESS;
856 DDI_CODEC_COM_BUFFER_MGR *bufMgr = &(m_ddiDecodeCtx->BufMgr);
857 bufMgr->pSliceData = nullptr;
858
859 bufMgr->ui64BitstreamOrder = 0;
860 bufMgr->dwMaxBsSize = m_width *
861 m_height * 3 / 2;
862
863 bufMgr->dwNumSliceData = 0;
864 bufMgr->dwNumSliceControl = 0;
865
866 m_sliceCtrlBufNum = DDI_DECODE_JPEG_SLICE_PARAM_BUF_NUM;
867 bufMgr->m_maxNumSliceData = DDI_DECODE_JPEG_SLICE_PARAM_BUF_NUM;
868 bufMgr->pSliceData = (DDI_CODEC_BITSTREAM_BUFFER_INFO *)MOS_AllocAndZeroMemory(sizeof(bufMgr->pSliceData[0]) * DDI_DECODE_JPEG_SLICE_PARAM_BUF_NUM);
869 if (bufMgr->pSliceData == nullptr)
870 {
871 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
872 goto finish;
873 }
874 bufMgr->dwNumOfRenderedSlicePara = 0;
875 bufMgr->dwNumOfRenderedSliceData = 0;
876 bufMgr->pNumOfRenderedSliceParaForOneBuffer = (int32_t *)MOS_AllocAndZeroMemory(sizeof(bufMgr->pNumOfRenderedSliceParaForOneBuffer[0]) * m_sliceCtrlBufNum);
877 bufMgr->pRenderedOrder = (int32_t *)MOS_AllocAndZeroMemory(sizeof(bufMgr->pRenderedOrder[0]) * m_sliceCtrlBufNum);
878 bufMgr->Codec_Param.Codec_Param_JPEG.pVASliceParaBufJPEG = (VASliceParameterBufferJPEGBaseline *)MOS_AllocAndZeroMemory(sizeof(VASliceParameterBufferJPEGBaseline) * m_sliceCtrlBufNum);
879 if (bufMgr->Codec_Param.Codec_Param_JPEG.pVASliceParaBufJPEG == nullptr)
880 {
881 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
882 goto finish;
883 }
884
885 return VA_STATUS_SUCCESS;
886
887 finish:
888 FreeResourceBuffer();
889 return vaStatus;
890 }
891
FreeResourceBuffer()892 void DdiDecodeJPEG::FreeResourceBuffer()
893 {
894 DDI_CODEC_COM_BUFFER_MGR *bufMgr = &(m_ddiDecodeCtx->BufMgr);
895
896 if (bufMgr->Codec_Param.Codec_Param_JPEG.pVASliceParaBufJPEG)
897 {
898 MOS_FreeMemory(bufMgr->Codec_Param.Codec_Param_JPEG.pVASliceParaBufJPEG);
899 bufMgr->Codec_Param.Codec_Param_JPEG.pVASliceParaBufJPEG = nullptr;
900 }
901 bufMgr->dwNumOfRenderedSlicePara = 0;
902 bufMgr->dwNumOfRenderedSliceData = 0;
903 MOS_FreeMemory(bufMgr->pNumOfRenderedSliceParaForOneBuffer);
904 bufMgr->pNumOfRenderedSliceParaForOneBuffer = nullptr;
905 MOS_FreeMemory(bufMgr->pRenderedOrder);
906 bufMgr->pRenderedOrder = nullptr;
907
908 for (uint32_t i = 0; i < bufMgr->dwNumSliceData && (bufMgr->pSliceData != nullptr); i++)
909 {
910 if (bufMgr->pSliceData[i].pBaseAddress != nullptr)
911 {
912 MOS_FreeMemory(bufMgr->pSliceData[i].pBaseAddress);
913 bufMgr->pSliceData[i].pBaseAddress = nullptr;
914 }
915 }
916
917 bufMgr->dwNumSliceData = 0;
918
919 if (m_jpegBitstreamBuf)
920 {
921 DdiMediaUtil_FreeBuffer(m_jpegBitstreamBuf);
922 MOS_FreeMemory(m_jpegBitstreamBuf);
923 m_jpegBitstreamBuf = nullptr;
924 }
925
926 // free decode bitstream buffer object
927 MOS_FreeMemory(bufMgr->pSliceData);
928 bufMgr->pSliceData = nullptr;
929
930 return;
931 }
932
CodecHalInit(DDI_MEDIA_CONTEXT * mediaCtx,void * ptr)933 VAStatus DdiDecodeJPEG::CodecHalInit(
934 DDI_MEDIA_CONTEXT *mediaCtx,
935 void *ptr)
936 {
937 VAStatus vaStatus = VA_STATUS_SUCCESS;
938 MOS_CONTEXT *mosCtx = (MOS_CONTEXT *)ptr;
939
940 CODECHAL_FUNCTION codecFunction = CODECHAL_FUNCTION_DECODE;
941 m_ddiDecodeCtx->pCpDdiInterface->SetCpParams(m_ddiDecodeAttr->uiEncryptionType, m_codechalSettings);
942
943 CODECHAL_STANDARD_INFO standardInfo;
944 memset(&standardInfo, 0, sizeof(standardInfo));
945
946 standardInfo.CodecFunction = codecFunction;
947 standardInfo.Mode = (CODECHAL_MODE)m_ddiDecodeCtx->wMode;
948
949 m_codechalSettings->codecFunction = codecFunction;
950 m_codechalSettings->width = m_width;
951 m_codechalSettings->height = m_height;
952 m_codechalSettings->intelEntrypointInUse = false;
953
954 m_codechalSettings->lumaChromaDepth = CODECHAL_LUMA_CHROMA_DEPTH_8_BITS;
955
956 m_codechalSettings->shortFormatInUse = m_ddiDecodeCtx->bShortFormatInUse;
957
958 m_codechalSettings->mode = CODECHAL_DECODE_MODE_JPEG;
959 m_codechalSettings->standard = CODECHAL_JPEG;
960
961 #ifdef _DECODE_PROCESSING_SUPPORTED
962 m_codechalSettings->sfcEnablingHinted = true;
963 #endif
964
965 m_ddiDecodeCtx->DecodeParams.m_iqMatrixBuffer = MOS_AllocAndZeroMemory(sizeof(CodecJpegQuantMatrix));
966 if (m_ddiDecodeCtx->DecodeParams.m_iqMatrixBuffer == nullptr)
967 {
968 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
969 goto CleanUpandReturn;
970 }
971 m_ddiDecodeCtx->DecodeParams.m_picParams = MOS_AllocAndZeroMemory(sizeof(CodecDecodeJpegPicParams));
972 if (m_ddiDecodeCtx->DecodeParams.m_picParams == nullptr)
973 {
974 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
975 goto CleanUpandReturn;
976 }
977
978 m_ddiDecodeCtx->DecodeParams.m_huffmanTable = (void*)MOS_AllocAndZeroMemory(sizeof(CODECHAL_DECODE_JPEG_HUFFMAN_TABLE));
979 if (!m_ddiDecodeCtx->DecodeParams.m_huffmanTable)
980 {
981 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
982 goto CleanUpandReturn;
983 }
984
985 m_sliceParamBufNum = DDI_DECODE_JPEG_SLICE_PARAM_BUF_NUM;
986 m_ddiDecodeCtx->DecodeParams.m_sliceParams = (void *)MOS_AllocAndZeroMemory(m_sliceParamBufNum * sizeof(CodecDecodeJpegScanParameter));
987
988 if (m_ddiDecodeCtx->DecodeParams.m_sliceParams == nullptr)
989 {
990 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
991 goto CleanUpandReturn;
992 }
993
994 vaStatus = CreateCodecHal(mediaCtx,
995 ptr,
996 &standardInfo);
997
998 if (vaStatus != VA_STATUS_SUCCESS)
999 {
1000 goto CleanUpandReturn;
1001 }
1002
1003 if (InitResourceBuffer() != VA_STATUS_SUCCESS)
1004 {
1005 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
1006 goto CleanUpandReturn;
1007 }
1008
1009 return vaStatus;
1010
1011 CleanUpandReturn:
1012 FreeResourceBuffer();
1013
1014 if (m_ddiDecodeCtx->pCodecHal)
1015 {
1016 m_ddiDecodeCtx->pCodecHal->Destroy();
1017 MOS_Delete(m_ddiDecodeCtx->pCodecHal);
1018 m_ddiDecodeCtx->pCodecHal = nullptr;
1019 }
1020
1021 MOS_FreeMemory(m_ddiDecodeCtx->DecodeParams.m_iqMatrixBuffer);
1022 m_ddiDecodeCtx->DecodeParams.m_iqMatrixBuffer = nullptr;
1023 MOS_FreeMemory(m_ddiDecodeCtx->DecodeParams.m_picParams);
1024 m_ddiDecodeCtx->DecodeParams.m_picParams = nullptr;
1025 MOS_FreeMemory(m_ddiDecodeCtx->DecodeParams.m_huffmanTable);
1026 m_ddiDecodeCtx->DecodeParams.m_huffmanTable = nullptr;
1027 MOS_FreeMemory(m_ddiDecodeCtx->DecodeParams.m_sliceParams);
1028 m_ddiDecodeCtx->DecodeParams.m_sliceParams = nullptr;
1029
1030 return vaStatus;
1031 }
1032
1033 extern template class MediaDdiFactory<DdiMediaDecode, DDI_DECODE_CONFIG_ATTR>;
1034
1035 static bool jpegRegistered =
1036 MediaDdiFactory<DdiMediaDecode, DDI_DECODE_CONFIG_ATTR>::RegisterCodec<DdiDecodeJPEG>(DECODE_ID_JPEG);
1037