1 /*
2 * Copyright (c) 2021, Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included
12 * in all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 */
22 //!
23 //! \file encode_jpeg_basic_feature.cpp
24 //! \brief Defines the common interface for encode jpeg parameter
25 //!
26
27 #include "encode_jpeg_basic_feature.h"
28
29 namespace encode
30 {
31
Init(void * setting)32 MOS_STATUS JpegBasicFeature::Init(void *setting)
33 {
34 ENCODE_FUNC_CALL();
35 ENCODE_CHK_NULL_RETURN(setting);
36
37 ENCODE_CHK_STATUS_RETURN(EncodeBasicFeature::Init(setting));
38
39 ENCODE_CHK_STATUS_RETURN(InitRefFrames());
40
41 return MOS_STATUS_SUCCESS;
42 }
43
InitRefFrames()44 MOS_STATUS JpegBasicFeature::InitRefFrames()
45 {
46 ENCODE_FUNC_CALL();
47
48 /*There is no any reference frame for JPEG. It uses status report.*/
49 m_ref = std::make_shared<JpegReferenceFrames>();
50 ENCODE_CHK_NULL_RETURN(m_ref);
51
52 ENCODE_CHK_STATUS_RETURN(m_ref->Init(this));
53
54 return MOS_STATUS_SUCCESS;
55 }
56
GetTrackedBuffers()57 MOS_STATUS JpegBasicFeature::GetTrackedBuffers()
58 {
59 ENCODE_CHK_NULL_RETURN(m_trackedBuf);
60 ENCODE_CHK_NULL_RETURN(m_allocator);
61
62 auto currRefList = m_ref->GetCurrRefList();
63 ENCODE_CHK_STATUS_RETURN(m_trackedBuf->Acquire(currRefList, false));
64
65 return MOS_STATUS_SUCCESS;
66 }
67
Update(void * params)68 MOS_STATUS JpegBasicFeature::Update(void *params)
69 {
70 ENCODE_FUNC_CALL();
71
72 ENCODE_CHK_NULL_RETURN(params);
73 ENCODE_CHK_STATUS_RETURN(EncodeBasicFeature::Update(params));
74
75 EncoderParams* encodeParams = (EncoderParams*)params;
76 ENCODE_CHK_NULL_RETURN(encodeParams->pPicParams);
77
78 m_jpegPicParams = (CodecEncodeJpegPictureParams *)(encodeParams->pPicParams);
79 m_jpegScanParams = (CodecEncodeJpegScanHeader *)(encodeParams->pSliceParams);
80 m_jpegQuantTables = (CodecEncodeJpegQuantTable *)(encodeParams->pQuantizationTable);
81 m_jpegHuffmanTable = (CodecEncodeJpegHuffmanDataArray *)(encodeParams->pHuffmanTable);
82 m_applicationData = encodeParams->pApplicationData;
83 m_appDataSize = encodeParams->dwAppDataSize;
84 m_jpegQuantMatrixSent = encodeParams->bJpegQuantMatrixSent;
85 m_fullHeaderInAppData = encodeParams->fullHeaderInAppData;
86 m_numHuffBuffers = encodeParams->dwNumHuffBuffers;
87
88 ENCODE_CHK_NULL_RETURN(m_jpegPicParams);
89 ENCODE_CHK_NULL_RETURN(m_jpegScanParams);
90 ENCODE_CHK_NULL_RETURN(m_jpegQuantTables);
91 ENCODE_CHK_NULL_RETURN(m_jpegHuffmanTable);
92
93 ENCODE_CHK_STATUS_RETURN(m_ref->UpdatePicture());
94
95 return MOS_STATUS_SUCCESS;
96 }
97
MHW_SETPAR_DECL_SRC(MFX_PIPE_MODE_SELECT,JpegBasicFeature)98 MHW_SETPAR_DECL_SRC(MFX_PIPE_MODE_SELECT, JpegBasicFeature)
99 {
100 params.standardSelect = CodecHal_GetStandardFromMode(m_mode);
101 params.codecSelect = encoderCodec;
102 params.decoderShortFormatMode = 1;
103
104 return MOS_STATUS_SUCCESS;
105 }
106
GetHwTileType(MOS_TILE_TYPE tileType,MOS_TILE_MODE_GMM tileModeGMM,bool gmmTileEnabled)107 static inline uint32_t GetHwTileType(MOS_TILE_TYPE tileType, MOS_TILE_MODE_GMM tileModeGMM, bool gmmTileEnabled)
108 {
109 uint32_t tileMode = 0;
110
111 if (gmmTileEnabled)
112 {
113 return tileModeGMM;
114 }
115
116 switch (tileType)
117 {
118 case MOS_TILE_LINEAR:
119 tileMode = 0;
120 break;
121 case MOS_TILE_YS:
122 tileMode = 1;
123 break;
124 case MOS_TILE_X:
125 tileMode = 2;
126 break;
127 default:
128 tileMode = 3;
129 break;
130 }
131
132 return tileMode;
133 }
134
MosToMediaStateFormat(MOS_FORMAT format)135 static inline uint8_t MosToMediaStateFormat(MOS_FORMAT format)
136 {
137 switch (format)
138 {
139 case Format_A8R8G8B8:
140 case Format_X8R8G8B8:
141 case Format_A8B8G8R8:
142 return MHW_MEDIASTATE_SURFACEFORMAT_R8G8B8A8_UNORM;
143 case Format_422H:
144 case Format_422V:
145 return MHW_MEDIASTATE_SURFACEFORMAT_PLANAR_422_8;
146 case Format_AYUV:
147 case Format_AUYV:
148 return MHW_MEDIASTATE_SURFACEFORMAT_A8Y8U8V8_UNORM;
149 case Format_NV12:
150 case Format_NV11:
151 case Format_P208:
152 case Format_IMC1:
153 case Format_IMC3:
154 return MHW_MEDIASTATE_SURFACEFORMAT_PLANAR_420_8;
155 case Format_400P:
156 case Format_P8:
157 return MHW_MEDIASTATE_SURFACEFORMAT_Y8_UNORM;
158 case Format_411P:
159 case Format_411R:
160 return MHW_MEDIASTATE_SURFACEFORMAT_PLANAR_411_8;
161 case Format_UYVY:
162 return MHW_MEDIASTATE_SURFACEFORMAT_YCRCB_SWAPY;
163 case Format_YVYU:
164 return MHW_MEDIASTATE_SURFACEFORMAT_YCRCB_SWAPUV;
165 case Format_VYUY:
166 return MHW_MEDIASTATE_SURFACEFORMAT_YCRCB_SWAPUVY;
167 case Format_YUY2:
168 case Format_YUYV:
169 case Format_444P:
170 case Format_IMC2:
171 case Format_IMC4:
172 default:
173 return MHW_MEDIASTATE_SURFACEFORMAT_YCRCB_NORMAL;
174 }
175
176 return MHW_MEDIASTATE_SURFACEFORMAT_YCRCB_NORMAL;
177 }
178
IsVPlanePresent(MOS_FORMAT format)179 static inline bool IsVPlanePresent(MOS_FORMAT format)
180 {
181 switch (format)
182 {
183 case Format_NV12:
184 case Format_NV11:
185 case Format_P208:
186 case Format_IMC1:
187 case Format_IMC3:
188 case Format_YUY2:
189 case Format_YUYV:
190 case Format_YVYU:
191 case Format_UYVY:
192 case Format_VYUY:
193 case Format_422H:
194 case Format_422V:
195 // Adding RGB formats because RGB is treated like YUV for JPEG encode and decode
196 case Format_RGBP:
197 case Format_BGRP:
198 case Format_A8R8G8B8:
199 case Format_X8R8G8B8:
200 case Format_A8B8G8R8:
201 case Format_411P:
202 case Format_411R:
203 case Format_444P:
204 case Format_IMC2:
205 case Format_IMC4:
206 return true;
207 default:
208 return false;
209 }
210 }
211
MHW_SETPAR_DECL_SRC(MFX_SURFACE_STATE,JpegBasicFeature)212 MHW_SETPAR_DECL_SRC(MFX_SURFACE_STATE, JpegBasicFeature)
213 {
214 PMOS_SURFACE psSurface = m_rawSurfaceToPak;
215 uint32_t uvPlaneAlignment = MHW_VDBOX_MFX_RAW_UV_PLANE_ALIGNMENT_GEN9;
216
217 ENCODE_CHK_NULL_RETURN(psSurface);
218
219 params.surfaceId = CODECHAL_MFX_SRC_SURFACE_ID;
220 params.height = psSurface->dwHeight - 1;
221 params.width = psSurface->dwWidth - 1;
222 params.tilemode = GetHwTileType(psSurface->TileType, psSurface->TileModeGMM, psSurface->bGMMTileEnabled);
223 params.surfacePitch = psSurface->dwPitch - 1;
224 params.interleaveChroma = psSurface->Format == Format_P8 ? 0 : 1;
225 params.surfaceFormat = MosToMediaStateFormat(psSurface->Format);
226
227 params.yOffsetForUCb = params.yOffsetForVCr =
228 MOS_ALIGN_CEIL((psSurface->UPlaneOffset.iSurfaceOffset - psSurface->dwOffset)/psSurface->dwPitch + psSurface->RenderOffset.YUV.U.YOffset, uvPlaneAlignment);
229 if (IsVPlanePresent(psSurface->Format))
230 {
231 params.yOffsetForVCr =
232 MOS_ALIGN_CEIL((psSurface->VPlaneOffset.iSurfaceOffset - psSurface->dwOffset)/psSurface->dwPitch + psSurface->RenderOffset.YUV.V.YOffset, uvPlaneAlignment);
233 }
234
235 #ifdef _MMC_SUPPORTED
236 if (m_mmcState && m_mmcState->IsMmcEnabled())
237 {
238 ENCODE_CHK_STATUS_RETURN(m_mmcState->GetSurfaceMmcFormat(psSurface, ¶ms.compressionFormat));
239 }
240 #endif
241 return MOS_STATUS_SUCCESS;
242 }
243
MHW_SETPAR_DECL_SRC(MFX_PIPE_BUF_ADDR_STATE,JpegBasicFeature)244 MHW_SETPAR_DECL_SRC(MFX_PIPE_BUF_ADDR_STATE, JpegBasicFeature)
245 {
246 params.decodeInUse = false;
247 params.psRawSurface = m_rawSurfaceToPak;
248
249 #ifdef _MMC_SUPPORTED
250 ENCODE_CHK_STATUS_RETURN(m_mmcState->GetSurfaceMmcState(m_rawSurfaceToPak, ¶ms.RawSurfMmcState));
251 #endif
252 return MOS_STATUS_SUCCESS;
253 }
254
MHW_SETPAR_DECL_SRC(MFX_IND_OBJ_BASE_ADDR_STATE,JpegBasicFeature)255 MHW_SETPAR_DECL_SRC(MFX_IND_OBJ_BASE_ADDR_STATE, JpegBasicFeature)
256 {
257 params.Mode = CODECHAL_ENCODE_MODE_AVC;
258 params.presPakBaseObjectBuffer = const_cast<PMOS_RESOURCE>(&m_resBitstreamBuffer);
259 params.dwPakBaseObjectSize = m_bitstreamUpperBound;
260
261 return MOS_STATUS_SUCCESS;
262 }
263
GetJpegHorizontalSamplingFactorForY(CodecEncodeJpegInputSurfaceFormat format) const264 uint32_t JpegBasicFeature::GetJpegHorizontalSamplingFactorForY(CodecEncodeJpegInputSurfaceFormat format)const
265 {
266 uint32_t horizontalSamplingFactor = 1;
267
268 if (format == codechalJpegY8)
269 {
270 horizontalSamplingFactor = 1;
271 }
272 else if (format == codechalJpegNV12)
273 {
274 horizontalSamplingFactor = 2;
275 }
276 else if (format == codechalJpegUYVY || format == codechalJpegYUY2)
277 {
278 horizontalSamplingFactor = 2;
279 }
280 else if (format == codechalJpegRGB)
281 {
282 horizontalSamplingFactor = 1;
283 }
284
285 return horizontalSamplingFactor;
286 }
287
GetJpegVerticalSamplingFactorForY(CodecEncodeJpegInputSurfaceFormat format) const288 uint32_t JpegBasicFeature::GetJpegVerticalSamplingFactorForY(CodecEncodeJpegInputSurfaceFormat format)const
289 {
290 uint32_t verticalSamplingFactor = 1;
291
292 if (format == codechalJpegY8)
293 {
294 verticalSamplingFactor = 1;
295 }
296 else if (format == codechalJpegNV12)
297 {
298 verticalSamplingFactor = 2;
299 }
300 else if (format == codechalJpegRGB ||
301 format == codechalJpegUYVY ||
302 format == codechalJpegYUY2)
303 {
304 verticalSamplingFactor = 1;
305 }
306
307 return verticalSamplingFactor;
308 }
309
MHW_SETPAR_DECL_SRC(MFX_JPEG_PIC_STATE,JpegBasicFeature)310 MHW_SETPAR_DECL_SRC(MFX_JPEG_PIC_STATE, JpegBasicFeature)
311 {
312 auto picParams = m_jpegPicParams;
313
314 params.decodeInUse = false;
315 params.inputSurfaceFormatYuv = (uint8_t)picParams->m_inputSurfaceFormat;
316
317 if (picParams->m_inputSurfaceFormat == codechalJpegY8)
318 {
319 params.outputMcuStructure = jpegYUV400;
320 params.pixelsInHorizontalLastMcu = picParams->m_picWidth % 8;
321 params.pixelsInVerticalLastMcu = picParams->m_picHeight % 8;
322 }
323 else if (picParams->m_inputSurfaceFormat == codechalJpegNV12)
324 {
325 params.outputMcuStructure = jpegYUV420;
326
327 if (picParams->m_picWidth % 2 == 0)
328 {
329 params.pixelsInHorizontalLastMcu = picParams->m_picWidth % 16;
330 }
331 else
332 {
333 params.pixelsInHorizontalLastMcu = (picParams->m_picWidth + 1) % 16;
334 }
335
336 if (picParams->m_picHeight % 2 == 0)
337 {
338 params.pixelsInVerticalLastMcu = picParams->m_picHeight % 16;
339 }
340 else
341 {
342 params.pixelsInVerticalLastMcu = (picParams->m_picHeight + 1) % 16;
343 }
344 }
345 else if (picParams->m_inputSurfaceFormat == codechalJpegYUY2 ||
346 picParams->m_inputSurfaceFormat == codechalJpegUYVY)
347 {
348 params.outputMcuStructure = jpegYUV422H2Y;
349
350 if (picParams->m_picWidth % 2 == 0)
351 {
352 params.pixelsInHorizontalLastMcu = picParams->m_picWidth % 16;
353 }
354 else
355 {
356 params.pixelsInHorizontalLastMcu = (picParams->m_picWidth + 1) % 16;
357 }
358
359 params.pixelsInVerticalLastMcu = picParams->m_picHeight % 8;
360 }
361 else if (picParams->m_inputSurfaceFormat == codechalJpegRGB)
362 {
363 params.outputMcuStructure = jpegYUV444;
364 params.pixelsInHorizontalLastMcu = picParams->m_picWidth % 8;
365 params.pixelsInVerticalLastMcu = picParams->m_picHeight % 8;
366 }
367
368 uint32_t horizontalSamplingFactor = GetJpegHorizontalSamplingFactorForY((CodecEncodeJpegInputSurfaceFormat)picParams->m_inputSurfaceFormat);
369 uint32_t verticalSamplingFactor = GetJpegVerticalSamplingFactorForY((CodecEncodeJpegInputSurfaceFormat)picParams->m_inputSurfaceFormat);
370 params.frameWidthInBlocksMinus1 = (((picParams->m_picWidth + (horizontalSamplingFactor * 8 - 1)) / (horizontalSamplingFactor * 8)) * horizontalSamplingFactor) - 1;
371 params.frameHeightInBlocksMinus1 = (((picParams->m_picHeight + (verticalSamplingFactor * 8 - 1)) / (verticalSamplingFactor * 8)) * verticalSamplingFactor) - 1;
372
373 return MOS_STATUS_SUCCESS;
374 }
375
MHW_SETPAR_DECL_SRC(MFC_JPEG_SCAN_OBJECT,JpegBasicFeature)376 MHW_SETPAR_DECL_SRC(MFC_JPEG_SCAN_OBJECT, JpegBasicFeature)
377 {
378 uint32_t horizontalSamplingFactor = GetJpegHorizontalSamplingFactorForY((CodecEncodeJpegInputSurfaceFormat)m_jpegPicParams->m_inputSurfaceFormat);
379 uint32_t verticalSamplingFactor = GetJpegVerticalSamplingFactorForY((CodecEncodeJpegInputSurfaceFormat)m_jpegPicParams->m_inputSurfaceFormat);
380 params.mcuCount =
381 ((m_jpegPicParams->m_picWidth + (horizontalSamplingFactor * 8 - 1)) / (horizontalSamplingFactor * 8)) *
382 ((m_jpegPicParams->m_picHeight + (verticalSamplingFactor * 8 - 1)) / (verticalSamplingFactor * 8));
383 params.restartInterval = (uint16_t)m_jpegScanParams->m_restartInterval;
384
385 for (auto i = 0; i < jpegNumComponent; i++)
386 {
387 params.huffmanDcTable |= (m_jpegScanParams->m_dcCodingTblSelector[i] << i);
388 params.huffmanAcTable |= (m_jpegScanParams->m_acCodingTblSelector[i] << i);
389 }
390
391 return MOS_STATUS_SUCCESS;
392 }
393
MHW_SETPAR_DECL_SRC(MI_FORCE_WAKEUP,JpegBasicFeature)394 MHW_SETPAR_DECL_SRC(MI_FORCE_WAKEUP, JpegBasicFeature)
395 {
396 params.bMFXPowerWellControl = true;
397 params.bMFXPowerWellControlMask = true;
398 params.bHEVCPowerWellControl = false;
399 params.bHEVCPowerWellControlMask = true;
400
401 return MOS_STATUS_SUCCESS;
402 }
403
MHW_SETPAR_DECL_SRC(MFX_WAIT,JpegBasicFeature)404 MHW_SETPAR_DECL_SRC(MFX_WAIT, JpegBasicFeature)
405 {
406 params.iStallVdboxPipeline = true;
407
408 return MOS_STATUS_SUCCESS;
409 }
410
411 } // namespace encode
412