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, &params.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, &params.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