1 /*
2 * Copyright (c) 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_encode_jpeg_g11.cpp
24 //! \brief Defines state class for JPEG encoder.
25 //!
26
27 #include "codechal_encode_jpeg.h"
28 #include "codechal_encode_jpeg_g11.h"
29 #if USE_CODECHAL_DEBUG_TOOL
30 #include "mos_util_user_interface.h"
31 #endif
32
33
CodechalEncodeJpegStateG11(CodechalHwInterface * hwInterface,CodechalDebugInterface * debugInterface,PCODECHAL_STANDARD_INFO standardInfo)34 CodechalEncodeJpegStateG11::CodechalEncodeJpegStateG11(
35 CodechalHwInterface* hwInterface,
36 CodechalDebugInterface* debugInterface,
37 PCODECHAL_STANDARD_INFO standardInfo): CodechalEncodeJpegState(hwInterface, debugInterface, standardInfo),
38 m_sinlgePipeVeState(nullptr)
39 {
40 CODECHAL_ENCODE_FUNCTION_ENTER;
41
42 memset(m_refList, 0, sizeof(m_refList));
43
44 CODECHAL_ENCODE_CHK_NULL_NO_STATUS_RETURN(m_osInterface);
45 m_osInterface->pfnVirtualEngineSupported(m_osInterface, false, true);
46 Mos_SetVirtualEngineSupported(m_osInterface, true);
47 }
48
49
~CodechalEncodeJpegStateG11()50 CodechalEncodeJpegStateG11::~CodechalEncodeJpegStateG11()
51 {
52 if (m_sinlgePipeVeState)
53 {
54 MOS_FreeMemAndSetNull(m_sinlgePipeVeState);
55 }
56 }
57
SetAndPopulateVEHintParams(PMOS_COMMAND_BUFFER cmdBuffer)58 MOS_STATUS CodechalEncodeJpegStateG11::SetAndPopulateVEHintParams(
59 PMOS_COMMAND_BUFFER cmdBuffer)
60 {
61 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
62
63 CODECHAL_ENCODE_FUNCTION_ENTER;
64
65 if (!MOS_VE_SUPPORTED(m_osInterface))
66 {
67 return eStatus;
68 }
69
70 if (!MOS_VE_CTXBASEDSCHEDULING_SUPPORTED(m_osInterface))
71 {
72 MOS_VIRTUALENGINE_SET_PARAMS vesetParams;
73 MOS_ZeroMemory(&vesetParams, sizeof(vesetParams));
74 vesetParams.bNeedSyncWithPrevious = true;
75 vesetParams.bSFCInUse = false;
76 CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalEncodeSinglePipeVE_SetHintParams(m_sinlgePipeVeState, &vesetParams));
77 }
78 CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalEncodeSinglePipeVE_PopulateHintParams(m_sinlgePipeVeState, cmdBuffer, true));
79
80 return eStatus;
81 }
82
UserFeatureKeyReport()83 MOS_STATUS CodechalEncodeJpegStateG11::UserFeatureKeyReport()
84 {
85 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
86
87 CODECHAL_ENCODE_FUNCTION_ENTER;
88
89 CODECHAL_ENCODE_CHK_STATUS_RETURN(CodechalEncoderState::UserFeatureKeyReport());
90
91 #if (_DEBUG || _RELEASE_INTERNAL)
92
93 // VE2.0 Reporting
94 CodecHalEncode_WriteKey(__MEDIA_USER_FEATURE_VALUE_ENABLE_ENCODE_VE_CTXSCHEDULING_ID, MOS_VE_CTXBASEDSCHEDULING_SUPPORTED(m_osInterface), m_osInterface->pOsContext);
95
96 #endif // _DEBUG || _RELEASE_INTERNAL
97 return eStatus;
98 }
99
ExecuteSliceLevel()100 MOS_STATUS CodechalEncodeJpegStateG11::ExecuteSliceLevel()
101 {
102 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
103
104 CODECHAL_ENCODE_FUNCTION_ENTER;
105
106 MOS_COMMAND_BUFFER cmdBuffer;
107 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnGetCommandBuffer(m_osInterface, &cmdBuffer, 0));
108
109 if (m_encodeParams.dwNumSlices != 1)
110 {
111 CODECHAL_ENCODE_ASSERTMESSAGE("JPEG encode only one scan is supported.");
112 }
113
114 MOS_SURFACE *surface = &m_rawSurface;
115
116 bool useSingleDefaultQuantTable = (m_jpegQuantMatrixSent == false &&
117 ((surface->Format == Format_A8R8G8B8) ||
118 (surface->Format == Format_X8R8G8B8) ||
119 (surface->Format == Format_A8B8G8R8) ||
120 (surface->Format == Format_X8B8G8R8)));
121
122 CodecJpegQuantMatrix *tempJpegQuantMatrix = (CodecJpegQuantMatrix *)MOS_AllocAndZeroMemory(sizeof(CodecJpegQuantMatrix));
123 CODECHAL_ENCODE_CHK_NULL_RETURN(tempJpegQuantMatrix);
124
125 static_assert(JPEG_MAX_NUM_QUANT_TABLE_INDEX <= JPEG_MAX_NUM_OF_QUANTMATRIX,
126 "access to CodecJpegQuantMatrix is controlled by numQuantTables");
127
128 uint32_t numQuantTables = JPEG_MAX_NUM_QUANT_TABLE_INDEX;
129 for (uint32_t scanCount = 0; scanCount < m_encodeParams.dwNumSlices; scanCount++)
130 {
131 MHW_VDBOX_QM_PARAMS fqmParams;
132 MOS_ZeroMemory(&fqmParams, sizeof(fqmParams));
133
134 // set MFX_FQM_STATE
135 fqmParams.pJpegQuantMatrix = tempJpegQuantMatrix;
136
137 // For monochrome inputs there will be only 1 quantization table and huffman table sent
138 if (m_jpegPicParams->m_inputSurfaceFormat == codechalJpegY8)
139 {
140 numQuantTables = 1;
141 m_encodeParams.dwNumHuffBuffers = 2; //for Y8 only 2 huff tables
142 }
143 // If there is only 1 quantization table copy over the table to 2nd and 3rd table in JPEG state (used for frame header)
144 // OR For RGB input surfaces, if the app does not send quantization tables, then use luma quant table for all 3 components
145 else if (m_jpegPicParams->m_numQuantTable == 1 || useSingleDefaultQuantTable)
146 {
147 for (auto i = 1; i < JPEG_MAX_NUM_QUANT_TABLE_INDEX; i++)
148 {
149 m_jpegQuantTables->m_quantTable[i].m_precision = m_jpegQuantTables->m_quantTable[0].m_precision;
150 m_jpegQuantTables->m_quantTable[i].m_tableID = m_jpegQuantTables->m_quantTable[0].m_tableID;
151
152 eStatus = MOS_SecureMemcpy(&m_jpegQuantTables->m_quantTable[i].m_qm[0], JPEG_NUM_QUANTMATRIX * sizeof(uint16_t),
153 &m_jpegQuantTables->m_quantTable[0].m_qm[0], JPEG_NUM_QUANTMATRIX * sizeof(uint16_t));
154 if (eStatus != MOS_STATUS_SUCCESS)
155 {
156 CODECHAL_ENCODE_ASSERTMESSAGE("Failed to copy memory.");
157 MOS_SafeFreeMemory(tempJpegQuantMatrix);
158 return eStatus;
159 }
160 }
161 }
162 // If there are 2 quantization tables copy over the second table to 3rd table in JPEG state since U and V share the same table (used for frame header)
163 else if (m_jpegPicParams->m_numQuantTable == 2)
164 {
165 m_jpegQuantTables->m_quantTable[2].m_precision = m_jpegQuantTables->m_quantTable[1].m_precision;
166 m_jpegQuantTables->m_quantTable[2].m_tableID = m_jpegQuantTables->m_quantTable[1].m_tableID;
167
168 eStatus = MOS_SecureMemcpy(&m_jpegQuantTables->m_quantTable[2].m_qm[0], JPEG_NUM_QUANTMATRIX * sizeof(uint16_t),
169 &m_jpegQuantTables->m_quantTable[1].m_qm[0], JPEG_NUM_QUANTMATRIX * sizeof(uint16_t));
170 if (eStatus != MOS_STATUS_SUCCESS)
171 {
172 CODECHAL_ENCODE_ASSERTMESSAGE("Failed to copy memory.");
173 MOS_SafeFreeMemory(tempJpegQuantMatrix);
174 return eStatus;
175 }
176
177 }
178 // else 3 quantization tables are sent by the application for non monochrome input formats. In that case, do nothing.
179
180 for (uint32_t i = 0; i < numQuantTables; i++)
181 {
182 fqmParams.pJpegQuantMatrix->m_jpegQMTableType[i] = m_jpegQuantTables->m_quantTable[i].m_tableID; // Used to distinguish between Y,U,V quantization tables for the same scan
183
184 for (auto j = 0; j < JPEG_NUM_QUANTMATRIX; j++)
185 {
186 uint32_t k = jpeg_qm_scan_8x8[j];
187
188 // copy over Quant matrix in raster order from zig zag
189 fqmParams.pJpegQuantMatrix->m_quantMatrix[i][k] = (uint8_t)m_jpegQuantTables->m_quantTable[i].m_qm[j];
190 }
191 }
192
193 eStatus = (MOS_STATUS) m_mfxInterface->AddMfxJpegFqmCmd(&cmdBuffer, &fqmParams, numQuantTables);
194 if (eStatus != MOS_STATUS_SUCCESS)
195 {
196 MOS_SafeFreeMemory(tempJpegQuantMatrix);
197 CODECHAL_ENCODE_CHK_STATUS_RETURN(eStatus);
198 }
199
200 // set MFC_JPEG_HUFF_TABLE - Convert encoded huffman table to actual table for HW
201 // We need a different params struct for JPEG Encode Huffman table because JPEG decode huffman table has Bits and codes,
202 // whereas JPEG encode huffman table has huffman code lengths and values
203 MHW_VDBOX_ENCODE_HUFF_TABLE_PARAMS huffTableParams[JPEG_MAX_NUM_HUFF_TABLE_INDEX] = {};
204 for (uint32_t i = 0; i < m_encodeParams.dwNumHuffBuffers; i++)
205 {
206 CodechalEncodeJpegHuffTable huffmanTable;// intermediate table for each AC/DC component which will be copied to huffTableParams
207 MOS_ZeroMemory(&huffmanTable, sizeof(huffmanTable));
208
209 eStatus = (MOS_STATUS) ConvertHuffDataToTable(m_jpegHuffmanTable->m_huffmanData[i], &huffmanTable);
210 if (eStatus != MOS_STATUS_SUCCESS)
211 {
212 MOS_SafeFreeMemory(tempJpegQuantMatrix);
213 CODECHAL_ENCODE_CHK_STATUS_RETURN(eStatus);
214 }
215
216 huffTableParams[m_jpegHuffmanTable->m_huffmanData[i].m_tableID].HuffTableID = m_jpegHuffmanTable->m_huffmanData[i].m_tableID;
217
218 if (m_jpegHuffmanTable->m_huffmanData[i].m_tableClass == 0) // DC table
219 {
220 eStatus = (MOS_STATUS) MOS_SecureMemcpy(
221 huffTableParams[m_jpegHuffmanTable->m_huffmanData[i].m_tableID].pDCCodeValues,
222 JPEG_NUM_HUFF_TABLE_DC_HUFFVAL * sizeof(uint16_t),
223 &huffmanTable.m_huffCode,
224 JPEG_NUM_HUFF_TABLE_DC_HUFFVAL * sizeof(uint16_t));
225 if (eStatus != MOS_STATUS_SUCCESS)
226 {
227 MOS_SafeFreeMemory(tempJpegQuantMatrix);
228 CODECHAL_ENCODE_CHK_STATUS_RETURN(eStatus);
229 }
230
231 eStatus = (MOS_STATUS) MOS_SecureMemcpy(huffTableParams[m_jpegHuffmanTable->m_huffmanData[i].m_tableID].pDCCodeLength,
232 JPEG_NUM_HUFF_TABLE_DC_HUFFVAL * sizeof(uint8_t),
233 &huffmanTable.m_huffSize,
234 JPEG_NUM_HUFF_TABLE_DC_HUFFVAL * sizeof(uint8_t));
235 if (eStatus != MOS_STATUS_SUCCESS)
236 {
237 MOS_SafeFreeMemory(tempJpegQuantMatrix);
238 CODECHAL_ENCODE_CHK_STATUS_RETURN(eStatus);
239 }
240 }
241 else // AC Table
242 {
243 eStatus = (MOS_STATUS) MOS_SecureMemcpy(huffTableParams[m_jpegHuffmanTable->m_huffmanData[i].m_tableID].pACCodeValues,
244 JPEG_NUM_HUFF_TABLE_AC_HUFFVAL * sizeof(uint16_t),
245 &huffmanTable.m_huffCode,
246 JPEG_NUM_HUFF_TABLE_AC_HUFFVAL * sizeof(uint16_t));
247 if (eStatus != MOS_STATUS_SUCCESS)
248 {
249 MOS_SafeFreeMemory(tempJpegQuantMatrix);
250 CODECHAL_ENCODE_CHK_STATUS_RETURN(eStatus);
251 }
252
253 eStatus = (MOS_STATUS) MOS_SecureMemcpy(huffTableParams[m_jpegHuffmanTable->m_huffmanData[i].m_tableID].pACCodeLength,
254 JPEG_NUM_HUFF_TABLE_AC_HUFFVAL * sizeof(uint8_t),
255 &huffmanTable.m_huffSize,
256 JPEG_NUM_HUFF_TABLE_AC_HUFFVAL * sizeof(uint8_t));
257 if (eStatus != MOS_STATUS_SUCCESS)
258 {
259 MOS_SafeFreeMemory(tempJpegQuantMatrix);
260 CODECHAL_ENCODE_CHK_STATUS_RETURN(eStatus);
261 }
262 }
263 }
264
265 // Send 2 huffman table commands - 1 for Luma and one for chroma for non-monchrome input formats
266 // If only one table is sent by the app (2 buffers), send the same table for Luma and chroma
267 bool repeatHuffTable = false;
268 if ((m_encodeParams.dwNumHuffBuffers / 2 < JPEG_MAX_NUM_HUFF_TABLE_INDEX)
269 && (m_jpegPicParams->m_inputSurfaceFormat != codechalJpegY8))
270 {
271 repeatHuffTable = true;
272
273 // Copy over huffman data to the other two data buffers for JPEG picture header
274 for (uint32_t i = 0; i < m_encodeParams.dwNumHuffBuffers; i++)
275 {
276 m_jpegHuffmanTable->m_huffmanData[i + 2].m_tableClass = m_jpegHuffmanTable->m_huffmanData[i].m_tableClass;
277 m_jpegHuffmanTable->m_huffmanData[i + 2].m_tableID = m_jpegHuffmanTable->m_huffmanData[i].m_tableID;
278
279 eStatus = MOS_SecureMemcpy(&m_jpegHuffmanTable->m_huffmanData[i + 2].m_bits[0],
280 sizeof(uint8_t) * JPEG_NUM_HUFF_TABLE_AC_BITS,
281 &m_jpegHuffmanTable->m_huffmanData[i].m_bits[0],
282 sizeof(uint8_t) * JPEG_NUM_HUFF_TABLE_AC_BITS);
283 if (eStatus != MOS_STATUS_SUCCESS)
284 {
285 CODECHAL_ENCODE_ASSERTMESSAGE("Failed to copy memory.");
286 MOS_SafeFreeMemory(tempJpegQuantMatrix);
287 return eStatus;
288 }
289
290 eStatus = MOS_SecureMemcpy(&m_jpegHuffmanTable->m_huffmanData[i + 2].m_huffVal[0],
291 sizeof(uint8_t) * JPEG_NUM_HUFF_TABLE_AC_HUFFVAL,
292 &m_jpegHuffmanTable->m_huffmanData[i].m_huffVal[0],
293 sizeof(uint8_t) * JPEG_NUM_HUFF_TABLE_AC_HUFFVAL);
294 if (eStatus != MOS_STATUS_SUCCESS)
295 {
296 CODECHAL_ENCODE_ASSERTMESSAGE("Failed to copy memory.");
297 MOS_SafeFreeMemory(tempJpegQuantMatrix);
298 return eStatus;
299 }
300 }
301 }
302
303 // the number of huffman commands is half of the huffman buffers sent by the app, since AC and DC buffers are combined into one command
304 for (uint32_t i = 0; i < m_encodeParams.dwNumHuffBuffers / 2; i++)
305 {
306 if (repeatHuffTable)
307 {
308 eStatus = (MOS_STATUS) (m_mfxInterface->AddMfcJpegHuffTableStateCmd(&cmdBuffer, &huffTableParams[i]));
309 if (eStatus != MOS_STATUS_SUCCESS)
310 {
311 MOS_SafeFreeMemory(tempJpegQuantMatrix);
312 CODECHAL_ENCODE_CHK_STATUS_RETURN(eStatus);
313 }
314 }
315
316 eStatus = (MOS_STATUS) m_mfxInterface->AddMfcJpegHuffTableStateCmd(&cmdBuffer, &huffTableParams[i]);
317 if (eStatus != MOS_STATUS_SUCCESS)
318 {
319 MOS_SafeFreeMemory(tempJpegQuantMatrix);
320 CODECHAL_ENCODE_CHK_STATUS_RETURN(eStatus);
321 }
322 }
323
324 // set MFC_JPEG_SCAN_OBJECT
325 MhwVdboxJpegScanParams scanObjectParams;
326 scanObjectParams.mode = m_mode;
327 scanObjectParams.inputSurfaceFormat = (CodecEncodeJpegInputSurfaceFormat)m_jpegPicParams->m_inputSurfaceFormat;
328 scanObjectParams.dwPicWidth = m_jpegPicParams->m_picWidth;
329 scanObjectParams.dwPicHeight = m_jpegPicParams->m_picHeight;
330 scanObjectParams.pJpegEncodeScanParams = m_jpegScanParams;
331
332 eStatus = (MOS_STATUS) m_mfxInterface->AddMfcJpegScanObjCmd(&cmdBuffer, &scanObjectParams);
333 if (eStatus != MOS_STATUS_SUCCESS)
334 {
335 MOS_SafeFreeMemory(tempJpegQuantMatrix);
336 CODECHAL_ENCODE_CHK_STATUS_RETURN(eStatus);
337 }
338
339 // set MFC_JPEG_PAK_INSERT_OBJECT
340 MHW_VDBOX_PAK_INSERT_PARAMS pakInsertObjectParams;
341 MOS_ZeroMemory(&pakInsertObjectParams, sizeof(pakInsertObjectParams));
342
343 // The largest component written through the MFC_JPEG_PAK_INSERT_OBJECT command is Huffman table
344 pakInsertObjectParams.pBsBuffer = (BSBuffer *)MOS_AllocAndZeroMemory(sizeof(CodechalEncodeJpegFrameHeader));
345 if (pakInsertObjectParams.pBsBuffer == nullptr)
346 {
347 MOS_SafeFreeMemory(tempJpegQuantMatrix);
348 CODECHAL_ENCODE_CHK_NULL_RETURN(nullptr);
349 }
350
351 if(!m_fullHeaderInAppData)
352 {
353 // Add SOI (0xFFD8) (only if it was sent by the application)
354 eStatus = (MOS_STATUS)PackSOI(pakInsertObjectParams.pBsBuffer);
355 if (eStatus != MOS_STATUS_SUCCESS)
356 {
357 MOS_SafeFreeMemory(pakInsertObjectParams.pBsBuffer->pBase);
358 MOS_SafeFreeMemory(pakInsertObjectParams.pBsBuffer);
359 MOS_SafeFreeMemory(tempJpegQuantMatrix);
360 CODECHAL_ENCODE_CHK_STATUS_RETURN(eStatus);
361 }
362 pakInsertObjectParams.dwOffset = 0;
363 pakInsertObjectParams.dwBitSize = pakInsertObjectParams.pBsBuffer->BufferSize;
364 pakInsertObjectParams.bLastHeader = false;
365 pakInsertObjectParams.bEndOfSlice = false;
366 pakInsertObjectParams.bResetBitstreamStartingPos = 1; // from discussion with HW Architect
367 eStatus = (MOS_STATUS) m_mfxInterface->AddMfxPakInsertObject(&cmdBuffer, nullptr, &pakInsertObjectParams);
368 if (eStatus != MOS_STATUS_SUCCESS)
369 {
370 MOS_SafeFreeMemory(pakInsertObjectParams.pBsBuffer->pBase);
371 MOS_SafeFreeMemory(pakInsertObjectParams.pBsBuffer);
372 MOS_SafeFreeMemory(tempJpegQuantMatrix);
373 CODECHAL_ENCODE_CHK_STATUS_RETURN(eStatus);
374 }
375 MOS_FreeMemory(pakInsertObjectParams.pBsBuffer->pBase);
376 }
377
378 // Add Application data if it was sent by application
379 if (m_applicationData != nullptr)
380 {
381 uint8_t* appDataChunk = nullptr;
382 uint32_t appDataChunkSize = m_appDataSize;
383
384 // We can write a maximum of 1020 words per command, so if the size of the app data is
385 // more than 1020 we need to send multiple commands for writing out app data
386 uint32_t numAppDataCmdsNeeded = 1;
387 uint32_t appDataCmdSizeResidue = 0;
388 if (m_appDataSize > 1020)
389 {
390 numAppDataCmdsNeeded = m_appDataSize / 1020;
391 appDataCmdSizeResidue = m_appDataSize % 1020;
392
393 appDataChunkSize = 1020;
394 }
395
396 appDataChunk = (uint8_t*)MOS_AllocAndZeroMemory(appDataChunkSize);
397 if (appDataChunk == nullptr)
398 {
399 MOS_SafeFreeMemory(pakInsertObjectParams.pBsBuffer->pBase);
400 MOS_SafeFreeMemory(pakInsertObjectParams.pBsBuffer);
401 MOS_SafeFreeMemory(tempJpegQuantMatrix);
402 CODECHAL_ENCODE_CHK_NULL_RETURN(nullptr);
403 }
404
405 for (uint32_t i = 0; i < numAppDataCmdsNeeded; i++)
406 {
407 uint8_t *copyAddress = (uint8_t*)(m_applicationData)+(i * appDataChunkSize);
408
409 MOS_SecureMemcpy(appDataChunk, appDataChunkSize,
410 copyAddress, appDataChunkSize);
411
412 eStatus = (MOS_STATUS)PackApplicationData(pakInsertObjectParams.pBsBuffer, appDataChunk, appDataChunkSize);
413 if (eStatus != MOS_STATUS_SUCCESS)
414 {
415 MOS_SafeFreeMemory(pakInsertObjectParams.pBsBuffer->pBase);
416 MOS_SafeFreeMemory(pakInsertObjectParams.pBsBuffer);
417 MOS_SafeFreeMemory(tempJpegQuantMatrix);
418 MOS_SafeFreeMemory(appDataChunk);
419 CODECHAL_ENCODE_CHK_STATUS_RETURN(eStatus);
420 }
421 pakInsertObjectParams.dwOffset = 0;
422 pakInsertObjectParams.dwBitSize = pakInsertObjectParams.pBsBuffer->BufferSize;
423 //if full header is included in application data, it will be the last header to insert and last chunk of it should be marked with EndOfSlice
424 if ((appDataCmdSizeResidue == 0) && m_fullHeaderInAppData && (i == numAppDataCmdsNeeded - 1))
425 {
426 pakInsertObjectParams.bLastHeader = true;
427 pakInsertObjectParams.bEndOfSlice = true;
428 }
429 else
430 {
431 pakInsertObjectParams.bLastHeader = false;
432 pakInsertObjectParams.bEndOfSlice = false;
433 }
434 pakInsertObjectParams.bResetBitstreamStartingPos = 1; // from discussion with HW Architect
435 eStatus = (MOS_STATUS)m_mfxInterface->AddMfxPakInsertObject(&cmdBuffer, nullptr,
436 &pakInsertObjectParams);
437 if (eStatus != MOS_STATUS_SUCCESS)
438 {
439 MOS_SafeFreeMemory(pakInsertObjectParams.pBsBuffer->pBase);
440 MOS_SafeFreeMemory(pakInsertObjectParams.pBsBuffer);
441 MOS_SafeFreeMemory(tempJpegQuantMatrix);
442 MOS_SafeFreeMemory(appDataChunk);
443 CODECHAL_ENCODE_CHK_STATUS_RETURN(eStatus);
444 }
445 }
446
447 if (appDataCmdSizeResidue != 0)
448 {
449 uint8_t* lastAddress = (uint8_t*)(m_applicationData)+(numAppDataCmdsNeeded * appDataChunkSize);
450 appDataChunkSize = appDataCmdSizeResidue;
451
452 MOS_SecureMemcpy(appDataChunk, appDataChunkSize,
453 lastAddress,
454 appDataChunkSize);
455
456 eStatus = (MOS_STATUS)PackApplicationData(pakInsertObjectParams.pBsBuffer, appDataChunk, appDataCmdSizeResidue);
457 if (eStatus != MOS_STATUS_SUCCESS)
458 {
459 MOS_SafeFreeMemory(pakInsertObjectParams.pBsBuffer->pBase);
460 MOS_SafeFreeMemory(pakInsertObjectParams.pBsBuffer);
461 MOS_SafeFreeMemory(tempJpegQuantMatrix);
462 MOS_SafeFreeMemory(appDataChunk);
463 CODECHAL_ENCODE_CHK_STATUS_RETURN(eStatus);
464 }
465 pakInsertObjectParams.dwOffset = 0;
466 pakInsertObjectParams.dwBitSize = pakInsertObjectParams.pBsBuffer->BufferSize;
467 if(m_fullHeaderInAppData)
468 {
469 pakInsertObjectParams.bLastHeader = true;
470 pakInsertObjectParams.bEndOfSlice = true;
471 }
472 else
473 {
474 pakInsertObjectParams.bLastHeader = false;
475 pakInsertObjectParams.bEndOfSlice = false;
476 }
477 pakInsertObjectParams.bResetBitstreamStartingPos = 1; // from discussion with HW Architect
478 eStatus = (MOS_STATUS)m_mfxInterface->AddMfxPakInsertObject(&cmdBuffer, nullptr,
479 &pakInsertObjectParams);
480 if (eStatus != MOS_STATUS_SUCCESS)
481 {
482 MOS_SafeFreeMemory(pakInsertObjectParams.pBsBuffer->pBase);
483 MOS_SafeFreeMemory(pakInsertObjectParams.pBsBuffer);
484 MOS_SafeFreeMemory(tempJpegQuantMatrix);
485 MOS_SafeFreeMemory(appDataChunk);
486 CODECHAL_ENCODE_CHK_STATUS_RETURN(eStatus);
487 }
488 }
489
490 MOS_FreeMemory(appDataChunk);
491 }
492
493 if(!m_fullHeaderInAppData)
494 {
495 // Add Quant Table for Y
496 eStatus = (MOS_STATUS)PackQuantTable(pakInsertObjectParams.pBsBuffer, jpegComponentY);
497 if (eStatus != MOS_STATUS_SUCCESS)
498 {
499 MOS_SafeFreeMemory(pakInsertObjectParams.pBsBuffer->pBase);
500 MOS_SafeFreeMemory(pakInsertObjectParams.pBsBuffer);
501 MOS_SafeFreeMemory(tempJpegQuantMatrix);
502 CODECHAL_ENCODE_CHK_STATUS_RETURN(eStatus);
503 }
504
505 pakInsertObjectParams.dwOffset = 0;
506 pakInsertObjectParams.dwBitSize = pakInsertObjectParams.pBsBuffer->BufferSize;
507 pakInsertObjectParams.bLastHeader = false;
508 pakInsertObjectParams.bEndOfSlice = false;
509 pakInsertObjectParams.bResetBitstreamStartingPos = 1; // from discussion with HW Architect
510 eStatus = (MOS_STATUS)m_mfxInterface->AddMfxPakInsertObject(&cmdBuffer, nullptr,
511 &pakInsertObjectParams);
512 if (eStatus != MOS_STATUS_SUCCESS)
513 {
514 MOS_SafeFreeMemory(pakInsertObjectParams.pBsBuffer->pBase);
515 MOS_SafeFreeMemory(pakInsertObjectParams.pBsBuffer);
516 MOS_SafeFreeMemory(tempJpegQuantMatrix);
517 CODECHAL_ENCODE_CHK_STATUS_RETURN(eStatus);
518 }
519 MOS_FreeMemory(pakInsertObjectParams.pBsBuffer->pBase);
520
521 if (!useSingleDefaultQuantTable)
522 {
523 // Since there is no U and V in monochrome format, donot add Quantization table header for U and V components
524 if (m_jpegPicParams->m_inputSurfaceFormat != codechalJpegY8)
525 {
526 // Add quant table for U
527 eStatus = (MOS_STATUS)PackQuantTable(pakInsertObjectParams.pBsBuffer, jpegComponentU);
528 if (eStatus != MOS_STATUS_SUCCESS)
529 {
530 MOS_SafeFreeMemory(pakInsertObjectParams.pBsBuffer->pBase);
531 MOS_SafeFreeMemory(pakInsertObjectParams.pBsBuffer);
532 MOS_SafeFreeMemory(tempJpegQuantMatrix);
533 CODECHAL_ENCODE_CHK_STATUS_RETURN(eStatus);
534 }
535 pakInsertObjectParams.dwOffset = 0;
536 pakInsertObjectParams.dwBitSize = pakInsertObjectParams.pBsBuffer->BufferSize;
537 pakInsertObjectParams.bLastHeader = false;
538 pakInsertObjectParams.bEndOfSlice = false;
539 pakInsertObjectParams.bResetBitstreamStartingPos = 1; // from discussion with HW Architect
540 eStatus = (MOS_STATUS)m_mfxInterface->AddMfxPakInsertObject(&cmdBuffer, nullptr,
541 &pakInsertObjectParams);
542 if (eStatus != MOS_STATUS_SUCCESS)
543 {
544 MOS_SafeFreeMemory(pakInsertObjectParams.pBsBuffer->pBase);
545 MOS_SafeFreeMemory(pakInsertObjectParams.pBsBuffer);
546 MOS_SafeFreeMemory(tempJpegQuantMatrix);
547 CODECHAL_ENCODE_CHK_STATUS_RETURN(eStatus);
548 }
549 MOS_FreeMemory(pakInsertObjectParams.pBsBuffer->pBase);
550
551 // Add quant table for V
552 eStatus = (MOS_STATUS)PackQuantTable(pakInsertObjectParams.pBsBuffer, jpegComponentV);
553 if (eStatus != MOS_STATUS_SUCCESS)
554 {
555 MOS_SafeFreeMemory(pakInsertObjectParams.pBsBuffer->pBase);
556 MOS_SafeFreeMemory(pakInsertObjectParams.pBsBuffer);
557 MOS_SafeFreeMemory(tempJpegQuantMatrix);
558 CODECHAL_ENCODE_CHK_STATUS_RETURN(eStatus);
559 }
560 pakInsertObjectParams.dwOffset = 0;
561 pakInsertObjectParams.dwBitSize = pakInsertObjectParams.pBsBuffer->BufferSize;
562 pakInsertObjectParams.bLastHeader = false;
563 pakInsertObjectParams.bEndOfSlice = false;
564 pakInsertObjectParams.bResetBitstreamStartingPos = 1; // from discussion with HW Architect
565 eStatus = (MOS_STATUS)m_mfxInterface->AddMfxPakInsertObject(&cmdBuffer, nullptr,
566 &pakInsertObjectParams);
567 if (eStatus != MOS_STATUS_SUCCESS)
568 {
569 MOS_SafeFreeMemory(pakInsertObjectParams.pBsBuffer->pBase);
570 MOS_SafeFreeMemory(pakInsertObjectParams.pBsBuffer);
571 MOS_SafeFreeMemory(tempJpegQuantMatrix);
572 CODECHAL_ENCODE_CHK_STATUS_RETURN(eStatus);
573 }
574 MOS_FreeMemory(pakInsertObjectParams.pBsBuffer->pBase);
575 }
576 }
577
578 // Add Frame Header
579 eStatus = (MOS_STATUS)PackFrameHeader(pakInsertObjectParams.pBsBuffer, useSingleDefaultQuantTable);
580 if (eStatus != MOS_STATUS_SUCCESS)
581 {
582 MOS_SafeFreeMemory(pakInsertObjectParams.pBsBuffer->pBase);
583 MOS_SafeFreeMemory(pakInsertObjectParams.pBsBuffer);
584 MOS_SafeFreeMemory(tempJpegQuantMatrix);
585 CODECHAL_ENCODE_CHK_STATUS_RETURN(eStatus);
586 }
587 pakInsertObjectParams.dwOffset = 0;
588 pakInsertObjectParams.dwBitSize = pakInsertObjectParams.pBsBuffer->BufferSize;
589 pakInsertObjectParams.bLastHeader = false;
590 pakInsertObjectParams.bEndOfSlice = false;
591 pakInsertObjectParams.bResetBitstreamStartingPos = 1; // from discussion with HW Architect
592 eStatus = (MOS_STATUS)m_mfxInterface->AddMfxPakInsertObject(&cmdBuffer, nullptr,
593 &pakInsertObjectParams);
594 if (eStatus != MOS_STATUS_SUCCESS)
595 {
596 MOS_SafeFreeMemory(pakInsertObjectParams.pBsBuffer->pBase);
597 MOS_SafeFreeMemory(pakInsertObjectParams.pBsBuffer);
598 MOS_SafeFreeMemory(tempJpegQuantMatrix);
599 CODECHAL_ENCODE_CHK_STATUS_RETURN(eStatus);
600 }
601 MOS_FreeMemory(pakInsertObjectParams.pBsBuffer->pBase);
602
603 // Add Huffman Table for Y - DC table, Y- AC table, U/V - DC table, U/V - AC table
604 for (uint32_t i = 0; i < m_encodeParams.dwNumHuffBuffers; i++)
605 {
606 eStatus = (MOS_STATUS)PackHuffmanTable(pakInsertObjectParams.pBsBuffer, i);
607 if (eStatus != MOS_STATUS_SUCCESS)
608 {
609 MOS_SafeFreeMemory(pakInsertObjectParams.pBsBuffer->pBase);
610 MOS_SafeFreeMemory(pakInsertObjectParams.pBsBuffer);
611 MOS_SafeFreeMemory(tempJpegQuantMatrix);
612 CODECHAL_ENCODE_CHK_STATUS_RETURN(eStatus);
613 }
614 pakInsertObjectParams.dwOffset = 0;
615 pakInsertObjectParams.dwBitSize = pakInsertObjectParams.pBsBuffer->BufferSize;
616 pakInsertObjectParams.bLastHeader = false;
617 pakInsertObjectParams.bEndOfSlice = false;
618 pakInsertObjectParams.bResetBitstreamStartingPos = 1; // from discussion with HW Architect
619 eStatus = (MOS_STATUS)m_mfxInterface->AddMfxPakInsertObject(&cmdBuffer, nullptr,
620 &pakInsertObjectParams);
621 if (eStatus != MOS_STATUS_SUCCESS)
622 {
623 MOS_SafeFreeMemory(pakInsertObjectParams.pBsBuffer->pBase);
624 MOS_SafeFreeMemory(pakInsertObjectParams.pBsBuffer);
625 MOS_SafeFreeMemory(tempJpegQuantMatrix);
626 CODECHAL_ENCODE_CHK_STATUS_RETURN(eStatus);
627 }
628 MOS_FreeMemory(pakInsertObjectParams.pBsBuffer->pBase);
629 }
630
631 // Restart Interval - Add only if the restart interval is not zero
632 if (m_jpegScanParams->m_restartInterval != 0)
633 {
634 eStatus = (MOS_STATUS)PackRestartInterval(pakInsertObjectParams.pBsBuffer);
635 if (eStatus != MOS_STATUS_SUCCESS)
636 {
637 MOS_SafeFreeMemory(pakInsertObjectParams.pBsBuffer->pBase);
638 MOS_SafeFreeMemory(pakInsertObjectParams.pBsBuffer);
639 MOS_SafeFreeMemory(tempJpegQuantMatrix);
640 CODECHAL_ENCODE_CHK_STATUS_RETURN(eStatus);
641 }
642 pakInsertObjectParams.dwOffset = 0;
643 pakInsertObjectParams.dwBitSize = pakInsertObjectParams.pBsBuffer->BufferSize;
644 pakInsertObjectParams.bLastHeader = false;
645 pakInsertObjectParams.bEndOfSlice = false;
646 pakInsertObjectParams.bResetBitstreamStartingPos = 1; // from discussion with HW Architect
647 eStatus = (MOS_STATUS)m_mfxInterface->AddMfxPakInsertObject(&cmdBuffer, nullptr,
648 &pakInsertObjectParams);
649 if (eStatus != MOS_STATUS_SUCCESS)
650 {
651 MOS_SafeFreeMemory(pakInsertObjectParams.pBsBuffer->pBase);
652 MOS_SafeFreeMemory(pakInsertObjectParams.pBsBuffer);
653 MOS_SafeFreeMemory(tempJpegQuantMatrix);
654 CODECHAL_ENCODE_CHK_STATUS_RETURN(eStatus);
655 }
656 MOS_FreeMemory(pakInsertObjectParams.pBsBuffer->pBase);
657 }
658
659 // Add scan header
660 eStatus = (MOS_STATUS)PackScanHeader(pakInsertObjectParams.pBsBuffer);
661 if (eStatus != MOS_STATUS_SUCCESS)
662 {
663 MOS_SafeFreeMemory(pakInsertObjectParams.pBsBuffer->pBase);
664 MOS_SafeFreeMemory(pakInsertObjectParams.pBsBuffer);
665 MOS_SafeFreeMemory(tempJpegQuantMatrix);
666 CODECHAL_ENCODE_CHK_STATUS_RETURN(eStatus);
667 }
668 pakInsertObjectParams.dwOffset = 0;
669 pakInsertObjectParams.dwBitSize = pakInsertObjectParams.pBsBuffer->BufferSize;
670 pakInsertObjectParams.bLastHeader = true;
671 pakInsertObjectParams.bEndOfSlice = true;
672 pakInsertObjectParams.bResetBitstreamStartingPos = 1; // from discussion with HW Architect
673 eStatus = (MOS_STATUS)m_mfxInterface->AddMfxPakInsertObject(&cmdBuffer, nullptr,
674 &pakInsertObjectParams);
675 if (eStatus != MOS_STATUS_SUCCESS)
676 {
677 MOS_SafeFreeMemory(pakInsertObjectParams.pBsBuffer->pBase);
678 MOS_SafeFreeMemory(pakInsertObjectParams.pBsBuffer);
679 MOS_SafeFreeMemory(tempJpegQuantMatrix);
680 CODECHAL_ENCODE_CHK_STATUS_RETURN(eStatus);
681 }
682 MOS_FreeMemory(pakInsertObjectParams.pBsBuffer->pBase);
683 }
684 MOS_FreeMemory(pakInsertObjectParams.pBsBuffer);
685 }
686
687 eStatus = ReadMfcStatus(&cmdBuffer);
688 if (eStatus != MOS_STATUS_SUCCESS)
689 {
690 MOS_SafeFreeMemory(tempJpegQuantMatrix);
691 CODECHAL_ENCODE_CHK_STATUS_RETURN(eStatus);
692 }
693
694 eStatus = EndStatusReport(&cmdBuffer, CODECHAL_NUM_MEDIA_STATES);
695 if (eStatus != MOS_STATUS_SUCCESS)
696 {
697 MOS_SafeFreeMemory(tempJpegQuantMatrix);
698 CODECHAL_ENCODE_CHK_STATUS_RETURN(eStatus);
699 }
700
701 eStatus = m_miInterface->AddMiBatchBufferEnd(&cmdBuffer, nullptr);
702 if (eStatus != MOS_STATUS_SUCCESS)
703 {
704 MOS_SafeFreeMemory(tempJpegQuantMatrix);
705 CODECHAL_ENCODE_CHK_STATUS_RETURN(eStatus);
706 }
707
708 std::string pakPassName = "PAK_PASS" + std::to_string(static_cast<uint32_t>(m_currPass));
709 CODECHAL_DEBUG_TOOL(
710 eStatus = m_debugInterface->DumpCmdBuffer(
711 &cmdBuffer,
712 CODECHAL_NUM_MEDIA_STATES,
713 pakPassName.data());
714 if (eStatus != MOS_STATUS_SUCCESS)
715 {
716 MOS_SafeFreeMemory(tempJpegQuantMatrix);
717 CODECHAL_ENCODE_CHK_STATUS_RETURN(eStatus);
718 }
719
720 //CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHal_DbgReplaceAllCommands(
721 // m_debugInterface,
722 // &cmdBuffer));
723 )
724
725 m_osInterface->pfnReturnCommandBuffer(m_osInterface, &cmdBuffer, 0);
726
727 eStatus = SetAndPopulateVEHintParams(&cmdBuffer);
728 if (eStatus != MOS_STATUS_SUCCESS)
729 {
730 MOS_SafeFreeMemory(tempJpegQuantMatrix);
731 CODECHAL_ENCODE_CHK_STATUS_RETURN(eStatus);
732 }
733 eStatus = m_osInterface->pfnSubmitCommandBuffer(m_osInterface, &cmdBuffer, m_renderContextUsesNullHw);
734 if (eStatus != MOS_STATUS_SUCCESS)
735 {
736 MOS_SafeFreeMemory(tempJpegQuantMatrix);
737 CODECHAL_ENCODE_CHK_STATUS_RETURN(eStatus);
738 }
739
740 if (tempJpegQuantMatrix != nullptr)
741 {
742 MOS_FreeMemory(tempJpegQuantMatrix);
743 tempJpegQuantMatrix = nullptr;
744 }
745
746 return eStatus;
747 }
748
Initialize(CodechalSetting * settings)749 MOS_STATUS CodechalEncodeJpegStateG11::Initialize(CodechalSetting *settings)
750 {
751 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
752
753 CODECHAL_ENCODE_FUNCTION_ENTER;
754
755 CODECHAL_ENCODE_CHK_NULL_RETURN(m_osInterface);
756 CODECHAL_ENCODE_CHK_NULL_RETURN(m_miInterface);
757 CODECHAL_ENCODE_CHK_NULL_RETURN(settings);
758
759 CODECHAL_ENCODE_CHK_STATUS_RETURN(CodechalEncoderState::Initialize(settings));
760
761 // Picture Level Commands
762 CODECHAL_ENCODE_CHK_STATUS_RETURN(
763 m_hwInterface->GetMfxStateCommandsDataSize(
764 CODECHAL_ENCODE_MODE_JPEG,
765 &m_pictureStatesSize,
766 &m_picturePatchListSize,
767 0));
768
769 // Slice Level Commands (cannot be placed in 2nd level batch)
770 CODECHAL_ENCODE_CHK_STATUS_RETURN(
771 m_hwInterface->GetMfxPrimitiveCommandsDataSize(
772 CODECHAL_ENCODE_MODE_JPEG,
773 &m_sliceStatesSize,
774 &m_slicePatchListSize,
775 0));
776
777 if (MOS_VE_SUPPORTED(m_osInterface))
778 {
779 m_sinlgePipeVeState = (PCODECHAL_ENCODE_SINGLEPIPE_VIRTUALENGINE_STATE)MOS_AllocAndZeroMemory(sizeof(CODECHAL_ENCODE_SINGLEPIPE_VIRTUALENGINE_STATE));
780 CODECHAL_ENCODE_CHK_NULL_RETURN(m_sinlgePipeVeState);
781 eStatus = (MOS_STATUS) CodecHalEncodeSinglePipeVE_InitInterface(m_hwInterface, m_sinlgePipeVeState);
782 if (eStatus != MOS_STATUS_SUCCESS)
783 {
784 MOS_SafeFreeMemory(m_sinlgePipeVeState);
785 CODECHAL_ENCODE_CHK_STATUS_RETURN(eStatus);
786 }
787 }
788
789 return eStatus;
790 }
791
SetGpuCtxCreatOption()792 MOS_STATUS CodechalEncodeJpegStateG11::SetGpuCtxCreatOption()
793 {
794 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
795
796 CODECHAL_ENCODE_FUNCTION_ENTER;
797
798 if (!MOS_VE_CTXBASEDSCHEDULING_SUPPORTED(m_osInterface))
799 {
800 CODECHAL_ENCODE_CHK_STATUS_RETURN(CodechalEncoderState::SetGpuCtxCreatOption());
801 }
802 else
803 {
804 m_gpuCtxCreatOpt = MOS_New(MOS_GPUCTX_CREATOPTIONS_ENHANCED);
805 CODECHAL_ENCODE_CHK_NULL_RETURN(m_gpuCtxCreatOpt);
806
807 CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalEncodeSinglePipeVE_ConstructParmsForGpuCtxCreation(
808 m_sinlgePipeVeState,
809 (PMOS_GPUCTX_CREATOPTIONS_ENHANCED)m_gpuCtxCreatOpt));
810 }
811
812 return eStatus;
813 }
814
815