1 /*
2 * Copyright (c) 2020, 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_preenc_basic_feature.cpp
24 //! \brief    Defines the common interface for encode preenc parameter
25 //!
26 
27 #include "encode_preenc_basic_feature.h"
28 #include "encode_utils.h"
29 #include "encode_allocator.h"
30 #include "media_sfc_interface.h"
31 
32 using namespace mhw::vdbox;
33 
34 namespace encode
35 {
Init(void * setting)36 MOS_STATUS PreEncBasicFeature::Init(void *setting)
37 {
38     ENCODE_FUNC_CALL();
39     ENCODE_CHK_NULL_RETURN(setting);
40     ENCODE_CHK_NULL_RETURN(m_allocator);
41 
42 #if (_DEBUG || _RELEASE_INTERNAL)
43     MediaUserSetting::Value outValue;
44     ReadUserSetting(m_userSettingPtr,
45         outValue,
46         "Set Media Encode Mode",
47         MediaUserSetting::Group::Sequence);
48     m_encodeMode = outValue.Get<uint32_t>();
49 #endif
50 
51     if ((m_encodeMode & PRE_ENC_PASS) == PRE_ENC_PASS)
52     {
53         m_enabled = true;
54     }
55 
56     if (!m_enabled)
57     {
58         return MOS_STATUS_SUCCESS;
59     }
60 
61     ENCODE_CHK_STATUS_RETURN(m_preEncConstSettings->PrepareConstSettings());
62 
63     EncodeBasicFeature::Init(setting);
64 
65     ENCODE_CHK_STATUS_RETURN(InitPreEncSize());
66 
67     if (((m_encodeMode == MediaEncodeMode::AUTO_RES_PRE_ENC) || (m_encodeMode == MediaEncodeMode::SINGLE_PRE_FULL_ENC)) && EncodePreencBasicMember6 > 0)
68     {
69         m_oriFrameWidth  = m_preEncSrcWidth;
70         m_oriFrameHeight = m_preEncSrcHeight;
71         m_frameHeight    = MOS_ALIGN_CEIL(m_oriFrameHeight, CODECHAL_MACROBLOCK_WIDTH);
72         m_frameWidth     = MOS_ALIGN_CEIL(m_oriFrameWidth, CODECHAL_MACROBLOCK_WIDTH);
73     }
74 
75     ENCODE_CHK_STATUS_RETURN(AllocateResources());
76 
77     return MOS_STATUS_SUCCESS;
78 }
79 
~PreEncBasicFeature()80 PreEncBasicFeature::~PreEncBasicFeature()
81 {
82 #if USE_CODECHAL_DEBUG_TOOL
83     if (pfile0 != nullptr)
84     {
85         fclose(pfile0);
86         pfile0 = nullptr;
87     }
88     if (pfile1 != nullptr)
89     {
90         fclose(pfile1);
91         pfile1 = nullptr;
92     }
93 #endif
94     MOS_Delete(m_preEncConstSettings);
95     m_preEncConstSettings = nullptr;
96 };
97 
AllocateResources()98 MOS_STATUS PreEncBasicFeature::AllocateResources()
99 {
100     ENCODE_FUNC_CALL();
101     ENCODE_CHK_NULL_RETURN(m_hcpItf);
102     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
103 
104     MOS_ALLOC_GFXRES_PARAMS allocParamsForBufferLinear;
105     MOS_ZeroMemory(&allocParamsForBufferLinear, sizeof(MOS_ALLOC_GFXRES_PARAMS));
106     allocParamsForBufferLinear.Type     = MOS_GFXRES_BUFFER;
107     allocParamsForBufferLinear.TileType = MOS_TILE_LINEAR;
108     allocParamsForBufferLinear.Format   = Format_Buffer;
109 
110     uint32_t              bufSize       = 0;
111     hcp::HcpBufferSizePar hcpBufSizePar = {};
112     hcpBufSizePar.ucMaxBitDepth         = m_bitDepth;
113     hcpBufSizePar.ucChromaFormat        = m_chromaFormat;
114     // We should move the buffer allocation to picture level if the size is dependent on LCU size
115     hcpBufSizePar.dwCtbLog2SizeY = 6;  //assume Max LCU size
116     hcpBufSizePar.dwPicWidth     = MOS_ALIGN_CEIL(m_frameWidth, m_maxLCUSize);
117     hcpBufSizePar.dwPicHeight    = MOS_ALIGN_CEIL(m_frameHeight, m_maxLCUSize);
118 
119     auto AllocateResource = [&](PMOS_RESOURCE &res, const hcp::HCP_INTERNAL_BUFFER_TYPE bufferType, const char *bufferName) {
120         hcpBufSizePar.bufferType = bufferType;
121         eStatus                  = m_hcpItf->GetHcpBufSize(hcpBufSizePar, bufSize);
122         if (eStatus != MOS_STATUS_SUCCESS)
123         {
124             ENCODE_ASSERTMESSAGE("Failed to get the size for Deblocking Filter Buffer.");
125             return eStatus;
126         }
127         allocParamsForBufferLinear.dwBytes  = bufSize;
128         allocParamsForBufferLinear.pBufName = bufferName;
129         allocParamsForBufferLinear.ResUsageType = MOS_HW_RESOURCE_USAGE_ENCODE_INTERNAL_READ_WRITE_CACHE;
130         res                                 = m_allocator->AllocateResource(allocParamsForBufferLinear, false);
131         return MOS_STATUS_SUCCESS;
132     };
133 
134     // Deblocking Filter Row Store Scratch data surface
135     ENCODE_CHK_STATUS_RETURN(AllocateResource(m_resDeblockingFilterRowStoreScratchBuffer, hcp::HCP_INTERNAL_BUFFER_TYPE::DBLK_LINE, "DeblockingScratchBuffer"));
136     // Deblocking Filter Tile Row Store Scratch data surface
137     ENCODE_CHK_STATUS_RETURN(AllocateResource(m_resDeblockingFilterTileRowStoreScratchBuffer, hcp::HCP_INTERNAL_BUFFER_TYPE::DBLK_TILE_LINE, "DeblockingTileRowScratchBuffer"));
138     // Deblocking Filter Column Row Store Scratch data surface
139     ENCODE_CHK_STATUS_RETURN(AllocateResource(m_resDeblockingFilterColumnRowStoreScratchBuffer, hcp::HCP_INTERNAL_BUFFER_TYPE::DBLK_TILE_COL, "DeblockingColumnScratchBuffer"));
140 
141     if (EncodePreencBasicMember2 > 0)
142     {
143         allocParamsForBufferLinear.dwBytes = EncodePreencBasicMember2 * sizeof(EncodePreencDef1);
144         allocParamsForBufferLinear.pBufName = "pre_Ref0";
145         allocParamsForBufferLinear.ResUsageType = MOS_HW_RESOURCE_USAGE_ENCODE_INTERNAL_READ_WRITE_NOCACHE;
146         ENCODE_CHK_STATUS_RETURN(m_recycleBuf->RegisterResource(encode::RecycleResId::PreEncRef0, allocParamsForBufferLinear));
147         allocParamsForBufferLinear.pBufName = "pre_Ref1";
148         allocParamsForBufferLinear.ResUsageType = MOS_HW_RESOURCE_USAGE_ENCODE_INTERNAL_READ_WRITE_NOCACHE;
149         ENCODE_CHK_STATUS_RETURN(m_recycleBuf->RegisterResource(encode::RecycleResId::PreEncRef1, allocParamsForBufferLinear));
150     }
151 
152     MOS_ALLOC_GFXRES_PARAMS allocParamsForBuffer2D;
153     MOS_ZeroMemory(&allocParamsForBuffer2D, sizeof(MOS_ALLOC_GFXRES_PARAMS));
154     allocParamsForBuffer2D.Type     = MOS_GFXRES_2D;
155     allocParamsForBuffer2D.TileType = MOS_TILE_Y;
156     allocParamsForBuffer2D.Format   = m_is10Bit ? Format_P010 : Format_NV12;
157     allocParamsForBuffer2D.dwWidth  = m_frameWidth;
158     allocParamsForBuffer2D.dwHeight = m_frameHeight;
159     allocParamsForBuffer2D.pBufName = "preRawDsSurface";
160     allocParamsForBuffer2D.ResUsageType = MOS_HW_RESOURCE_USAGE_ENCODE_INPUT_RAW;
161     ENCODE_CHK_STATUS_RETURN(m_recycleBuf->RegisterResource(encode::RecycleResId::PreEncRawSurface, allocParamsForBuffer2D));
162 
163     return eStatus;
164 }
165 
Update(void * params)166 MOS_STATUS PreEncBasicFeature::Update(void *params)
167 {
168     ENCODE_FUNC_CALL();
169     ENCODE_CHK_NULL_RETURN(params);
170 
171     if (!m_enabled)
172     {
173         return MOS_STATUS_SUCCESS;
174     }
175 
176     ENCODE_CHK_STATUS_RETURN(PreparePreEncConfig(params));
177 
178     ENCODE_CHK_STATUS_RETURN(EncodeBasicFeature::Update(params));
179 
180     ENCODE_CHK_STATUS_RETURN(SetPictureStructs());
181     ENCODE_CHK_STATUS_RETURN(SetSliceStructs());
182 
183     if (m_frameNum == 0)
184     {
185         m_resolutionChanged = true;
186     }
187     else
188     {
189         m_resolutionChanged = false;
190     }
191 
192     if (m_resolutionChanged)
193     {
194         ENCODE_CHK_STATUS_RETURN(UpdateTrackedBufferParameters());
195     }
196     ENCODE_CHK_STATUS_RETURN(GetRecycleBuffers());
197     ENCODE_CHK_STATUS_RETURN(GetTrackedBuffers());
198 
199     return MOS_STATUS_SUCCESS;
200 }
201 
202 // This function may be used by fullenc feature.
203 // Please don't use class member variables in the function.
CalculatePreEncInfo(uint32_t width,uint32_t height,PreEncInfo & preEncInfo)204 MOS_STATUS PreEncBasicFeature::CalculatePreEncInfo(uint32_t width, uint32_t height, PreEncInfo &preEncInfo)
205 {
206     ENCODE_FUNC_CALL();
207 
208     preEncInfo.EncodePreEncInfo2 = 0;
209     if (width >= 7680 && height >= 4320)
210         preEncInfo.EncodePreEncInfo2 = 2;  //8x8
211     else if (width >= 3840 && height >= 2160)
212         preEncInfo.EncodePreEncInfo2 = 1;  //16x16
213     else if (width >= 1920 && height >= 1080)
214         preEncInfo.EncodePreEncInfo2 = 0;  //32x32
215 
216     preEncInfo.EncodePreEncInfo3 = 0;
217     if (width >= 7680 && height >= 4320)
218         preEncInfo.EncodePreEncInfo3 = 3;  //8x
219     else if (width >= 3840 && height >= 2160)
220         preEncInfo.EncodePreEncInfo3 = 2;  //4x
221     else //if (width >= 1920 && height >= 1080)
222         preEncInfo.EncodePreEncInfo3 = 1;  //2x
223 
224     preEncInfo.EncodePreEncInfo0 = 0;
225     if (width >= 7680 && height >= 4320)
226         preEncInfo.EncodePreEncInfo0 = 1;  //2x
227     else if (width >= 3840 && height >= 2160)
228         preEncInfo.EncodePreEncInfo0 = 0;  //1x
229     else                                      //if (OrgSrcWidth >= 1920 && OrgSrcHeight >= 1080)
230         preEncInfo.EncodePreEncInfo0 = 3;  //0.5x
231 
232     uint8_t vdencFactor = MAX(0, (5 - preEncInfo.EncodePreEncInfo2) + (preEncInfo.EncodePreEncInfo0 == 3 ? -1 : preEncInfo.EncodePreEncInfo0) - 4);
233 
234     uint32_t offset          = (1 << preEncInfo.EncodePreEncInfo3) - 1;
235     uint32_t preEncSrcWidth  = (width + offset) >> preEncInfo.EncodePreEncInfo3;
236     uint32_t preEncSrcHeight = (height + offset) >> preEncInfo.EncodePreEncInfo3;
237 
238     preEncSrcWidth  = ((preEncSrcWidth + 7) >> 3) << 3;
239     preEncSrcHeight = ((preEncSrcHeight + 7) >> 3) << 3;
240 
241     preEncInfo.preEncSrcWidth  = preEncSrcWidth;
242     preEncInfo.preEncSrcHeight = preEncSrcHeight;
243 
244     //pitch be 64 aligned and height be 64 aligned
245     uint16_t vdencInfoStride = (uint16_t)((((preEncSrcWidth + 63) >> 6) << 6) >> (5 - preEncInfo.EncodePreEncInfo2));
246     uint16_t vdencInfoHeight = (uint16_t)((((preEncSrcHeight + 63) >> 6) << 6) >> (5 - preEncInfo.EncodePreEncInfo2));
247 
248     vdencInfoStride = ((vdencInfoStride + 7) >> 3) << 3;
249 
250     vdencInfoStride <<= vdencFactor;
251     vdencInfoHeight <<= vdencFactor;
252 
253     preEncInfo.EncodePreEncInfo1 = vdencInfoStride * vdencInfoHeight;
254 
255     return MOS_STATUS_SUCCESS;
256 }
257 
InitPreEncSize()258 MOS_STATUS PreEncBasicFeature::InitPreEncSize()
259 {
260     ENCODE_FUNC_CALL();
261 
262     if (m_encodeMode == MediaEncodeMode::MANUAL_RES_PRE_ENC)
263     {
264         MediaUserSetting::Value outValue;
265         ReadUserSetting(m_userSettingPtr,
266             outValue,
267             "Set Media Encode Downscaled Ratio",
268             MediaUserSetting::Group::Sequence);
269         uint32_t downscaledRatio = outValue.Get<uint32_t>();
270         uint32_t orgFrameWidth   = 0;
271         uint32_t orgFrameHeight  = 0;
272         if (downscaledRatio != 0)
273         {
274             orgFrameWidth  = m_frameWidth * downscaledRatio;
275             orgFrameHeight = m_frameHeight * downscaledRatio;
276         }
277         else
278         {
279             orgFrameWidth  = m_frameWidth;
280             orgFrameHeight = m_frameHeight;
281         }
282         ENCODE_CHK_STATUS_RETURN(CalculatePreEncInfo(orgFrameWidth, orgFrameHeight, m_preEncInfo));
283     }
284     else
285     {
286         ENCODE_CHK_STATUS_RETURN(CalculatePreEncInfo(m_frameWidth, m_frameHeight, m_preEncInfo));
287     }
288 
289     EncodePreencBasicMember5 = m_preEncInfo.EncodePreEncInfo2;
290     EncodePreencBasicMember6 = m_preEncInfo.EncodePreEncInfo3;
291     EncodePreencBasicMember1 = m_preEncInfo.EncodePreEncInfo0;
292     EncodePreencBasicMember2 = m_preEncInfo.EncodePreEncInfo1;
293     m_preEncSrcWidth         = m_preEncInfo.preEncSrcWidth;
294     m_preEncSrcHeight        = m_preEncInfo.preEncSrcHeight;
295 
296     return MOS_STATUS_SUCCESS;
297 }
298 
GetPreEncInfo(PreEncInfo & preEncInfo)299 MOS_STATUS PreEncBasicFeature::GetPreEncInfo(PreEncInfo &preEncInfo)
300 {
301     if (!m_enabled)
302         return MOS_STATUS_INVALID_PARAMETER;
303     preEncInfo = m_preEncInfo;
304     return MOS_STATUS_SUCCESS;
305 }
306 
SetPictureStructs()307 MOS_STATUS PreEncBasicFeature::SetPictureStructs()
308 {
309     ENCODE_FUNC_CALL();
310 
311     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
312 
313     //Create flat scaling list
314     memset(&m_hevcIqMatrixParams, 0x10, sizeof(m_hevcIqMatrixParams));
315 
316     m_pictureCodingType = m_preEncConfig.CodingType;
317 
318     uint16_t log2_max_coding_block_size = 6;
319 
320     rawCTUBits = (1 << (2 * log2_max_coding_block_size));
321     rawCTUBits = rawCTUBits * 3 / 2;
322     rawCTUBits = rawCTUBits * (m_preEncConfig.BitDepthLumaMinus8 + 8);
323     rawCTUBits = (5 * rawCTUBits / 3);
324 
325     return eStatus;
326 }
327 
SetSurfaceMMCParams(EncodeMemComp & mmcState,MOS_SURFACE & surf)328 static MOS_STATUS SetSurfaceMMCParams(EncodeMemComp &mmcState, MOS_SURFACE &surf)
329 {
330     ENCODE_CHK_STATUS_RETURN(mmcState.SetSurfaceMmcMode(&surf));
331     ENCODE_CHK_STATUS_RETURN(mmcState.SetSurfaceMmcState(&surf));
332     ENCODE_CHK_STATUS_RETURN(mmcState.SetSurfaceMmcFormat(&surf));
333     surf.bIsCompressed = surf.CompressionMode != MOS_MMC_DISABLED;
334 
335     return MOS_STATUS_SUCCESS;
336 }
337 
UpdateTrackedBufferParameters()338 MOS_STATUS PreEncBasicFeature::UpdateTrackedBufferParameters()
339 {
340     ENCODE_CHK_NULL_RETURN(m_trackedBuf);
341 
342     uint32_t numOfLCU = MOS_ROUNDUP_DIVIDE(m_frameWidth, m_maxLCUSize) * (MOS_ROUNDUP_DIVIDE(m_frameHeight, m_maxLCUSize) + 1);
343 
344     m_mbCodeSize = MOS_ALIGN_CEIL(2 * sizeof(uint32_t) * (numOfLCU * 5 + numOfLCU * 64 * 8), CODECHAL_PAGE_SIZE);
345 
346     uint32_t downscaledWidthInMb4x     = CODECHAL_GET_WIDTH_IN_MACROBLOCKS(m_frameWidth / SCALE_FACTOR_4x);
347     uint32_t downscaledHeightInMb4x    = CODECHAL_GET_HEIGHT_IN_MACROBLOCKS(m_frameHeight / SCALE_FACTOR_4x);
348     uint32_t downscaledSurfaceHeight4x = ((downscaledHeightInMb4x + 1) >> 1) * CODECHAL_MACROBLOCK_HEIGHT;
349     m_downscaledWidth4x                = downscaledWidthInMb4x * CODECHAL_MACROBLOCK_WIDTH;
350     m_downscaledHeight4x               = MOS_ALIGN_CEIL(downscaledSurfaceHeight4x, MOS_YTILE_H_ALIGNMENT) << 1;
351 
352     MOS_ALLOC_GFXRES_PARAMS allocParamsForBuffer2D;
353     MOS_ZeroMemory(&allocParamsForBuffer2D, sizeof(MOS_ALLOC_GFXRES_PARAMS));
354     allocParamsForBuffer2D.Type     = MOS_GFXRES_2D;
355     allocParamsForBuffer2D.TileType = MOS_TILE_Y;
356     allocParamsForBuffer2D.Format   = m_is10Bit ? Format_P010 : Format_NV12;
357 
358     allocParamsForBuffer2D.dwWidth  = m_frameWidth;
359     allocParamsForBuffer2D.dwHeight = m_frameHeight;
360     allocParamsForBuffer2D.pBufName = "preRefSurface";
361     ENCODE_CHK_STATUS_RETURN(m_trackedBuf->RegisterParam(encode::BufferType::preRefSurface, allocParamsForBuffer2D));
362 
363     if (m_downscaledWidth4x > 0 && m_downscaledHeight4x > 0)
364     {
365         allocParamsForBuffer2D.Format   = Format_NV12;
366         allocParamsForBuffer2D.dwWidth  = m_downscaledWidth4x;
367         allocParamsForBuffer2D.dwHeight = m_downscaledHeight4x;
368         allocParamsForBuffer2D.pBufName = "Pre4xDSSurface";
369         ENCODE_CHK_STATUS_RETURN(m_trackedBuf->RegisterParam(encode::BufferType::preDs4xSurface, allocParamsForBuffer2D));
370 
371         allocParamsForBuffer2D.dwWidth  = m_downscaledWidth4x >> 1;
372         allocParamsForBuffer2D.dwHeight = MOS_ALIGN_CEIL(m_downscaledHeight4x >> 1, MOS_YTILE_H_ALIGNMENT) << 1;
373         allocParamsForBuffer2D.pBufName = "Pre8xDSSurface";
374         ENCODE_CHK_STATUS_RETURN(m_trackedBuf->RegisterParam(encode::BufferType::preDs8xSurface, allocParamsForBuffer2D));
375     }
376 
377     return MOS_STATUS_SUCCESS;
378 }
379 
GetRecycleBuffers()380 MOS_STATUS PreEncBasicFeature::GetRecycleBuffers()
381 {
382     ENCODE_CHK_NULL_RETURN(m_recycleBuf);
383     auto bIdx = m_preEncConfig.CurrOriginalPic.FrameIdx;
384     if ((m_encodeMode == MediaEncodeMode::SINGLE_PRE_FULL_ENC || m_encodeMode == MediaEncodeMode::AUTO_RES_PRE_ENC) && (EncodePreencBasicMember6 > 0 || m_preEncConfig.BitDepthLumaMinus8 > 0))
385     {
386         m_rawDsSurface = m_recycleBuf->GetSurface(encode::RecycleResId::PreEncRawSurface, bIdx);
387         ENCODE_CHK_NULL_RETURN(m_rawDsSurface);
388         ENCODE_CHK_STATUS_RETURN(m_allocator->GetSurfaceInfo(m_rawDsSurface));
389     }
390 
391     EncodePreencBasicMember3 = m_recycleBuf->GetBuffer(encode::RecycleResId::PreEncRef0, bIdx);
392     ENCODE_CHK_NULL_RETURN(EncodePreencBasicMember3);
393     EncodePreencBasicMember4 = m_recycleBuf->GetBuffer(encode::RecycleResId::PreEncRef1, bIdx);
394     ENCODE_CHK_NULL_RETURN(EncodePreencBasicMember4);
395 
396     return MOS_STATUS_SUCCESS;
397 }
398 
GetTrackedBuffers()399 MOS_STATUS PreEncBasicFeature::GetTrackedBuffers()
400 {
401     ENCODE_CHK_NULL_RETURN(m_trackedBuf);
402     ENCODE_CHK_NULL_RETURN(m_allocator);
403 
404     PMOS_SURFACE reconSurface = m_trackedBuf->GetSurface(BufferType::preRefSurface, m_trackedBuf->GetCurrIndex());
405     ENCODE_CHK_NULL_RETURN(reconSurface);
406     ENCODE_CHK_STATUS_RETURN(m_allocator->GetSurfaceInfo(reconSurface));
407     m_reconSurface = *(reconSurface);
408 
409     m_4xDSSurface = m_trackedBuf->GetSurface(BufferType::preDs4xSurface, m_trackedBuf->GetCurrIndex());
410     ENCODE_CHK_NULL_RETURN(m_4xDSSurface);
411     ENCODE_CHK_STATUS_RETURN(m_allocator->GetSurfaceInfo(m_4xDSSurface));
412 
413     m_8xDSSurface = m_trackedBuf->GetSurface(BufferType::preDs8xSurface, m_trackedBuf->GetCurrIndex());
414     ENCODE_CHK_NULL_RETURN(m_8xDSSurface);
415     ENCODE_CHK_STATUS_RETURN(m_allocator->GetSurfaceInfo(m_8xDSSurface));
416 
417     return MOS_STATUS_SUCCESS;
418 }
419 
EncodePreencBasicFuntion0(PMOS_RESOURCE & Buffer0,PMOS_RESOURCE & Buffer1)420 MOS_STATUS PreEncBasicFeature::EncodePreencBasicFuntion0(PMOS_RESOURCE& Buffer0, PMOS_RESOURCE& Buffer1)
421 {
422     ENCODE_FUNC_CALL();
423     Buffer0 = EncodePreencBasicMember3;
424     Buffer1 = EncodePreencBasicMember4;
425     return MOS_STATUS_SUCCESS;
426 }
427 
MHW_SETPAR_DECL_SRC(VDENC_PIPE_MODE_SELECT,PreEncBasicFeature)428 MHW_SETPAR_DECL_SRC(VDENC_PIPE_MODE_SELECT, PreEncBasicFeature)
429 {
430     params.bitDepthMinus8    = m_preEncConfig.BitDepthLumaMinus8;
431     params.chromaType        = 1;
432     params.wirelessSessionId = 0;
433     params.randomAccess      = !IsLowDelay();
434 
435     params.VdencPipeModeSelectPar2 = 1;
436     if (m_preEncConfig.CodingType != I_TYPE && !IsLowDelay())
437     {
438         params.VdencPipeModeSelectPar4 = 3;
439     }
440     else
441     {
442         params.VdencPipeModeSelectPar4 = 1;
443     }
444     params.VdencPipeModeSelectPar5 = EncodePreencBasicMember6;
445     params.VdencPipeModeSelectPar7 = EncodePreencBasicMember5;
446     params.VdencPipeModeSelectPar6 = EncodePreencBasicMember1;
447 
448     if (m_preEncConfig.CodingType == I_TYPE)
449     {
450         params.VdencPipeModeSelectPar2 = 0;
451     }
452 
453     return MOS_STATUS_SUCCESS;
454 }
455 
MHW_SETPAR_DECL_SRC(VDENC_SRC_SURFACE_STATE,PreEncBasicFeature)456 MHW_SETPAR_DECL_SRC(VDENC_SRC_SURFACE_STATE, PreEncBasicFeature)
457 {
458     params.pitch                         = m_preEncRawSurface->dwPitch;
459     params.tileType                      = m_preEncRawSurface->TileType;
460     params.tileModeGmm                   = m_preEncRawSurface->TileModeGMM;
461     params.format                        = m_preEncRawSurface->Format;
462     params.gmmTileEn                     = m_preEncRawSurface->bGMMTileEnabled;
463     params.uOffset                       = m_preEncRawSurface->YoffsetForUplane;
464     params.vOffset                       = m_preEncRawSurface->YoffsetForVplane;
465     params.height                        = m_oriFrameHeight;
466     params.width                         = m_oriFrameWidth;
467     params.colorSpaceSelection           = (m_preEncConfig.InputColorSpace == ECOLORSPACE_P709) ? 1 : 0;
468     params.chromaDownsampleFilterControl = 7;
469 
470     return MOS_STATUS_SUCCESS;
471 }
472 
MHW_SETPAR_DECL_SRC(VDENC_REF_SURFACE_STATE,PreEncBasicFeature)473 MHW_SETPAR_DECL_SRC(VDENC_REF_SURFACE_STATE, PreEncBasicFeature)
474 {
475     params.pitch       = m_reconSurface.dwPitch;
476     params.tileType    = m_reconSurface.TileType;
477     params.tileModeGmm = m_reconSurface.TileModeGMM;
478     params.format      = m_reconSurface.Format;
479     params.gmmTileEn   = m_reconSurface.bGMMTileEnabled;
480     params.uOffset     = m_reconSurface.YoffsetForUplane;
481     params.vOffset     = m_reconSurface.YoffsetForVplane;
482     params.height      = m_oriFrameHeight;
483     params.width       = m_oriFrameWidth;
484 
485     if (m_reconSurface.Format == Format_Y410 || m_reconSurface.Format == Format_444P || m_reconSurface.Format == Format_AYUV)
486     {
487         if (m_reconSurface.Format == Format_Y410)
488         {
489             params.pitch = m_reconSurface.dwPitch / 2;
490         }
491         else
492         {
493             params.pitch = m_reconSurface.dwPitch / 4;
494         }
495         params.uOffset = m_preEncRawSurface->dwHeight;
496         params.vOffset = m_preEncRawSurface->dwHeight << 1;
497     }
498     else if (m_reconSurface.Format == Format_Y216 || m_reconSurface.Format == Format_YUY2 || m_reconSurface.Format == Format_YUYV)
499     {
500         params.uOffset = m_preEncRawSurface->dwHeight;
501         params.vOffset = m_preEncRawSurface->dwHeight;
502     }
503 
504     return MOS_STATUS_SUCCESS;
505 }
506 
MHW_SETPAR_DECL_SRC(VDENC_DS_REF_SURFACE_STATE,PreEncBasicFeature)507 MHW_SETPAR_DECL_SRC(VDENC_DS_REF_SURFACE_STATE, PreEncBasicFeature)
508 {
509     params.pitchStage1       = m_8xDSSurface->dwPitch;
510     params.tileTypeStage1    = m_8xDSSurface->TileType;
511     params.tileModeGmmStage1 = m_8xDSSurface->TileModeGMM;
512     params.gmmTileEnStage1   = m_8xDSSurface->bGMMTileEnabled;
513     params.uOffsetStage1     = m_8xDSSurface->YoffsetForUplane;
514     params.vOffsetStage1     = m_8xDSSurface->YoffsetForVplane;
515     params.heightStage1      = m_8xDSSurface->dwHeight;
516     params.widthStage1       = m_8xDSSurface->dwWidth;
517 
518     params.pitchStage2       = m_4xDSSurface->dwPitch;
519     params.tileTypeStage2    = m_4xDSSurface->TileType;
520     params.tileModeGmmStage2 = m_4xDSSurface->TileModeGMM;
521     params.gmmTileEnStage2   = m_4xDSSurface->bGMMTileEnabled;
522     params.uOffsetStage2     = m_4xDSSurface->YoffsetForUplane;
523     params.vOffsetStage2     = m_4xDSSurface->YoffsetForVplane;
524     params.heightStage2      = m_4xDSSurface->dwHeight;
525     params.widthStage2       = m_4xDSSurface->dwWidth;
526 
527     return MOS_STATUS_SUCCESS;
528 }
529 
MHW_SETPAR_DECL_SRC(VDENC_PIPE_BUF_ADDR_STATE,PreEncBasicFeature)530 MHW_SETPAR_DECL_SRC(VDENC_PIPE_BUF_ADDR_STATE, PreEncBasicFeature)
531 {
532     params.surfaceRaw               = m_preEncRawSurface;
533     params.surfaceDsStage1          = m_8xDSSurface;
534     params.surfaceDsStage2          = m_4xDSSurface;
535 
536     params.numActiveRefL0 = 1;
537     params.numActiveRefL1 = 1;
538     if (m_preEncConfig.CodingType == I_TYPE)
539     {
540         params.numActiveRefL0 = 0;
541         params.numActiveRefL1 = 0;
542     }
543 
544     // for reference
545     auto l0RefFrameList = m_preEncConfig.RefPicList[LIST_0];
546 
547     CODEC_PICTURE refPic = l0RefFrameList[0];
548 
549     if (!CodecHal_PictureIsInvalid(refPic) && m_preEncConfig.PicIdx[refPic.FrameIdx].bValid)
550     {
551         // L0 references
552         uint8_t refPicIdx = m_preEncConfig.PicIdx[refPic.FrameIdx].ucPicIdx;
553 
554         // 1x/4x/8x DS surface for VDEnc
555         uint8_t scaledIdx = m_preEncConfig.RefList[refPicIdx]->ucScalingIdx;
556 
557         auto vdencRefSurface = m_trackedBuf->GetSurface(BufferType::preRefSurface, scaledIdx);
558         ENCODE_CHK_NULL_RETURN(vdencRefSurface);
559         auto vdenc4xDsSurface = m_trackedBuf->GetSurface(BufferType::preDs4xSurface, scaledIdx);
560         ENCODE_CHK_NULL_RETURN(vdenc4xDsSurface);
561         auto vdenc8xDsSurface = m_trackedBuf->GetSurface(BufferType::preDs8xSurface, scaledIdx);
562         ENCODE_CHK_NULL_RETURN(vdenc8xDsSurface);
563         params.refs[0]         = &(vdencRefSurface->OsResource);
564         params.refsDsStage2[0] = &vdenc4xDsSurface->OsResource;
565         params.refsDsStage1[0] = &vdenc8xDsSurface->OsResource;
566     }
567 
568     const CODEC_PICTURE *l1RefFrameList = m_preEncConfig.isPToB ? m_preEncConfig.RefPicList[LIST_0] : m_preEncConfig.RefPicList[LIST_1];
569 
570     refPic = l1RefFrameList[0];
571 
572     if (!CodecHal_PictureIsInvalid(refPic) && m_preEncConfig.PicIdx[refPic.FrameIdx].bValid)
573     {
574         // L1 references
575         uint8_t refPicIdx = m_preEncConfig.PicIdx[refPic.FrameIdx].ucPicIdx;
576 
577         // 1x/4x/8x DS surface for VDEnc
578         uint8_t scaledIdx = m_preEncConfig.RefList[refPicIdx]->ucScalingIdx;
579 
580         auto vdencRefSurface = m_trackedBuf->GetSurface(BufferType::preRefSurface, scaledIdx);
581         ENCODE_CHK_NULL_RETURN(vdencRefSurface);
582         auto vdenc4xDsSurface = m_trackedBuf->GetSurface(BufferType::preDs4xSurface, scaledIdx);
583         ENCODE_CHK_NULL_RETURN(vdenc4xDsSurface);
584         auto vdenc8xDsSurface = m_trackedBuf->GetSurface(BufferType::preDs8xSurface, scaledIdx);
585         ENCODE_CHK_NULL_RETURN(vdenc8xDsSurface);
586         params.refs[1]         = &(vdencRefSurface->OsResource);
587         params.refsDsStage2[1] = &vdenc4xDsSurface->OsResource;
588         params.refsDsStage1[1] = &vdenc8xDsSurface->OsResource;
589     }
590 
591     params.lowDelayB = m_lowDelay;
592 
593     params.vdencPipeBufAddrStatePar0 = EncodePreencBasicMember3;
594     params.vdencPipeBufAddrStatePar1 = EncodePreencBasicMember4;
595 
596     return MOS_STATUS_SUCCESS;
597 }
598 
599 #define CLIP3(MIN_, MAX_, X) (((X) < (MIN_)) ? (MIN_) : (((X) > (MAX_)) ? (MAX_) : (X)))
600 
MHW_SETPAR_DECL_SRC(VDENC_CMD1,PreEncBasicFeature)601 MHW_SETPAR_DECL_SRC(VDENC_CMD1, PreEncBasicFeature)
602 {
603     ENCODE_CHK_NULL_RETURN(m_preEncConstSettings);
604     auto settings = static_cast<PreEncFeatureSettings *>(m_preEncConstSettings->GetConstSettings());
605     ENCODE_CHK_NULL_RETURN(settings);
606 
607     for (const auto &lambda : settings->vdencCmd1Settings)
608     {
609         ENCODE_CHK_STATUS_RETURN(lambda(params, IsLowDelay(), m_preEncConfig));
610     }
611 
612     return MOS_STATUS_SUCCESS;
613 }
614 
MHW_SETPAR_DECL_SRC(VDENC_CMD2,PreEncBasicFeature)615 MHW_SETPAR_DECL_SRC(VDENC_CMD2, PreEncBasicFeature)
616 {
617     params.width  = m_oriFrameWidth;
618     params.height = m_oriFrameHeight;
619 
620     params.pictureType = (m_preEncConfig.CodingType == I_TYPE) ? 0 : (IsLowDelay() ? 3 : 2);
621     params.temporalMvp = 0;
622 
623     if (m_preEncConfig.CodingType != I_TYPE)
624     {
625         params.numRefL0 = 1;
626         params.numRefL1 = 1;
627     }
628 
629     params.tiling = 0;
630 
631     if (m_preEncConfig.CodingType != I_TYPE)
632     {
633         uint8_t refFrameId;
634         int8_t  diffPoc;
635 
636         refFrameId                      = m_preEncConfig.RefPicList[0][0].FrameIdx;
637         diffPoc                         = ((refFrameId >= CODEC_MAX_NUM_REF_FRAME_HEVC) ? 0x0 : m_preEncConfig.RefFramePOCList[refFrameId]) - m_preEncConfig.CurrPicOrderCnt;
638         params.pocL0Ref0                = (int8_t)CodecHal_Clip3(-16, 16, -diffPoc);
639         params.longTermReferenceFlagsL0 = (refFrameId >= CODEC_MAX_NUM_REF_FRAME_HEVC) ? 0x0 : CodecHal_PictureIsLongTermRef(m_preEncConfig.RefFrameList[refFrameId]);
640         refFrameId                      = m_preEncConfig.RefPicList[0][1].FrameIdx;
641         diffPoc                         = ((refFrameId >= CODEC_MAX_NUM_REF_FRAME_HEVC) ? 0x0 : m_preEncConfig.RefFramePOCList[refFrameId]) - m_preEncConfig.CurrPicOrderCnt;
642         params.pocL0Ref1                = (int8_t)CodecHal_Clip3(-16, 16, -diffPoc);
643         params.longTermReferenceFlagsL0 |= ((refFrameId >= CODEC_MAX_NUM_REF_FRAME_HEVC) ? 0x0 : CodecHal_PictureIsLongTermRef(m_preEncConfig.RefFrameList[refFrameId])) << 1;
644         refFrameId       = m_preEncConfig.RefPicList[0][2].FrameIdx;
645         diffPoc          = ((refFrameId >= CODEC_MAX_NUM_REF_FRAME_HEVC) ? 0x0 : m_preEncConfig.RefFramePOCList[refFrameId]) - m_preEncConfig.CurrPicOrderCnt;
646         params.pocL0Ref2 = (int8_t)CodecHal_Clip3(-16, 16, -diffPoc);
647         params.longTermReferenceFlagsL0 |= ((refFrameId >= CODEC_MAX_NUM_REF_FRAME_HEVC) ? 0x0 : CodecHal_PictureIsLongTermRef(m_preEncConfig.RefFrameList[refFrameId])) << 2;
648 
649         refFrameId                      = m_preEncConfig.isPToB ? m_preEncConfig.RefPicList[0][0].FrameIdx : m_preEncConfig.RefPicList[1][0].FrameIdx;
650         diffPoc                         = ((refFrameId >= CODEC_MAX_NUM_REF_FRAME_HEVC) ? 0x0 : m_preEncConfig.RefFramePOCList[refFrameId]) - m_preEncConfig.CurrPicOrderCnt;
651         params.pocL1Ref0                = (int8_t)CodecHal_Clip3(-16, 16, -diffPoc);
652         params.longTermReferenceFlagsL1 = (refFrameId >= CODEC_MAX_NUM_REF_FRAME_HEVC) ? 0x0 : CodecHal_PictureIsLongTermRef(m_preEncConfig.RefFrameList[refFrameId]);
653 
654         params.pocL1Ref1 = params.pocL0Ref1;
655         params.pocL1Ref2 = params.pocL0Ref2;
656     }
657     else
658     {
659         params.pocL0Ref0 = params.pocL0Ref1 = params.pocL1Ref0 = params.pocL1Ref1 = 0;
660         params.pocL0Ref2 = params.pocL0Ref3 = params.pocL1Ref2 = params.pocL1Ref3 = 0;
661     }
662     params.minQp = 0x0a;
663     params.maxQp = 0x33;
664 
665     params.qpPrimeYAc = m_QP;
666 
667     uint8_t frameIdxForL0L1[4] = {0x7, 0x7, 0x7, 0x7};
668 
669     MHW_MI_CHK_NULL(m_refIdxMapping);
670     for (int i = 0; i < 1; i++)
671     {
672         uint8_t refFrameIDx = m_preEncConfig.RefPicList[0][i].FrameIdx;
673         if (refFrameIDx < CODEC_MAX_NUM_REF_FRAME_HEVC)
674         {
675             frameIdxForL0L1[i] = *(m_refIdxMapping + refFrameIDx);
676         }
677     }
678 
679     if (!IsLowDelay())
680     {
681         uint8_t refFrameIDx = m_preEncConfig.RefPicList[1][0].FrameIdx;
682         if (refFrameIDx < CODEC_MAX_NUM_REF_FRAME_HEVC)
683         {
684             frameIdxForL0L1[3] = *(m_refIdxMapping + refFrameIDx);
685         }
686     }
687 
688     params.frameIdxL0Ref0 = frameIdxForL0L1[0];
689     params.frameIdxL0Ref1 = frameIdxForL0L1[1];
690     params.frameIdxL0Ref2 = frameIdxForL0L1[2];
691     params.frameIdxL1Ref0 = frameIdxForL0L1[3];
692 
693     ENCODE_CHK_NULL_RETURN(m_preEncConstSettings);
694     auto settings = static_cast<PreEncFeatureSettings *>(m_preEncConstSettings->GetConstSettings());
695     ENCODE_CHK_NULL_RETURN(settings);
696 
697     for (const auto &lambda : settings->vdencCmd2Settings)
698     {
699         ENCODE_CHK_STATUS_RETURN(lambda(params, IsLowDelay(), m_preEncConfig));
700     }
701 
702     return MOS_STATUS_SUCCESS;
703 }
704 
MHW_SETPAR_DECL_SRC(VDENC_WALKER_STATE,PreEncBasicFeature)705 MHW_SETPAR_DECL_SRC(VDENC_WALKER_STATE, PreEncBasicFeature)
706 {
707     uint32_t ctbSize        = 64;
708     uint32_t widthInPix     = m_oriFrameWidth;
709     uint32_t widthInCtb     = (widthInPix / ctbSize) + ((widthInPix % ctbSize) ? 1 : 0);  // round up
710     uint32_t heightInPix    = m_oriFrameHeight;
711     uint32_t heightInCtb    = (heightInPix / ctbSize) + ((heightInPix % ctbSize) ? 1 : 0);  // round up
712     uint32_t numLCUsInSlice = widthInCtb * heightInCtb;
713 
714     params.firstSuperSlice = 0;
715     // No tiling support
716     params.tileSliceStartLcuMbY     = 0;
717     params.nextTileSliceStartLcuMbX = numLCUsInSlice / heightInCtb;
718     params.nextTileSliceStartLcuMbY = numLCUsInSlice / widthInCtb;
719 
720     return MOS_STATUS_SUCCESS;
721 }
722 
MHW_SETPAR_DECL_SRC(VDENC_HEVC_VP9_TILE_SLICE_STATE,PreEncBasicFeature)723 MHW_SETPAR_DECL_SRC(VDENC_HEVC_VP9_TILE_SLICE_STATE, PreEncBasicFeature)
724 {
725     params.ctbSize                    = 64;
726     params.tileWidth                  = m_oriFrameWidth;
727     params.tileHeight                 = m_oriFrameHeight;
728     params.log2WeightDenomLuma        = 0;
729     params.hevcVp9Log2WeightDenomLuma = 0;
730     params.log2WeightDenomChroma      = 0;
731 
732     return MOS_STATUS_SUCCESS;
733 }
734 
MHW_SETPAR_DECL_SRC(VDENC_WEIGHTSOFFSETS_STATE,PreEncBasicFeature)735 MHW_SETPAR_DECL_SRC(VDENC_WEIGHTSOFFSETS_STATE, PreEncBasicFeature)
736 {
737     params.denomLuma = 1;
738 
739     return MOS_STATUS_SUCCESS;
740 }
741 
SetSliceStructs()742 MOS_STATUS PreEncBasicFeature::SetSliceStructs()
743 {
744     ENCODE_FUNC_CALL();
745 
746     m_lowDelay    = true;
747     m_sameRefList = true;
748 
749     for (auto i = 0; i < CODEC_MAX_NUM_REF_FRAME_HEVC; i++)
750     {
751         m_refIdxMapping[i]  = -1;
752         m_currUsedRefPic[i] = false;
753     }
754 
755     // To obtain current "used" reference frames. The number of current used reference frames cannot be greater than 8
756     for (uint8_t ll = 0; ll < 2; ll++)
757     {
758         CODEC_PICTURE refPic = m_preEncConfig.RefPicList[ll][0];
759         if (!CodecHal_PictureIsInvalid(refPic) &&
760             !CodecHal_PictureIsInvalid(m_preEncConfig.RefFrameList[refPic.FrameIdx]))
761         {
762             m_currUsedRefPic[refPic.FrameIdx] = true;
763         }
764     }
765 
766     for (uint8_t i = 0, refIdx = 0; i < CODEC_MAX_NUM_REF_FRAME_HEVC; i++)
767     {
768         if (!m_currUsedRefPic[i])
769         {
770             continue;
771         }
772 
773         uint8_t index         = m_preEncConfig.RefFrameList[i].FrameIdx;
774         bool    duplicatedIdx = false;
775         for (uint8_t ii = 0; ii < i; ii++)
776         {
777             if (m_currUsedRefPic[i] && index == m_preEncConfig.RefFrameList[ii].FrameIdx)
778             {
779                 // We find the same FrameIdx in the ref_frame_list. Multiple reference frames are the same.
780                 // In other words, RefFrameList[i] and RefFrameList[ii] have the same surface Id
781                 duplicatedIdx      = true;
782                 m_refIdxMapping[i] = m_refIdxMapping[ii];
783                 break;
784             }
785         }
786 
787         if (duplicatedIdx)
788         {
789             continue;
790         }
791 
792         if (refIdx >= CODECHAL_MAX_CUR_NUM_REF_FRAME_HEVC)
793         {
794             // Total number of distingushing reference frames cannot be geater than 8.
795             ENCODE_ASSERT(false);
796             return MOS_STATUS_INVALID_PARAMETER;
797         }
798 
799         // Map reference frame index [0-15] into a set of unique IDs within [0-7]
800         m_refIdxMapping[i] = refIdx;
801         refIdx++;
802     }
803 
804     ENCODE_CHK_STATUS_RETURN(ValidateLowDelayBFrame());
805     ENCODE_CHK_STATUS_RETURN(ValidateSameRefInL0L1());
806 
807     if (m_lowDelay && !m_sameRefList)
808     {
809         ENCODE_NORMALMESSAGE("Attention: LDB frame but with different L0/L1 list !");
810     }
811 
812     return MOS_STATUS_SUCCESS;
813 }
814 
ValidateSameRefInL0L1()815 MOS_STATUS PreEncBasicFeature::ValidateSameRefInL0L1()
816 {
817     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
818 
819     ENCODE_FUNC_CALL();
820 
821     if (m_sameRefList)
822     {
823         for (int refIdx = 0; refIdx < 1; refIdx++)
824         {
825             CODEC_PICTURE refPicL0 = m_preEncConfig.RefPicList[0][refIdx];
826             CODEC_PICTURE refPicL1 = m_preEncConfig.RefPicList[1][refIdx];
827 
828             if (!CodecHal_PictureIsInvalid(refPicL0) && !CodecHal_PictureIsInvalid(refPicL1) && refPicL0.FrameIdx != refPicL1.FrameIdx)
829             {
830                 m_sameRefList = false;
831                 break;
832             }
833         }
834     }
835 
836     return eStatus;
837 }
838 
ValidateLowDelayBFrame()839 MOS_STATUS PreEncBasicFeature::ValidateLowDelayBFrame()
840 {
841     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
842 
843     ENCODE_FUNC_CALL();
844 
845     // Examine if now it is B type
846     if (m_preEncConfig.SliceType == encodeHevcBSlice)
847     {
848         // forward
849         for (int refIdx = 0; (refIdx < 1) && m_lowDelay; refIdx++)
850         {
851             CODEC_PICTURE refPic = m_preEncConfig.RefPicList[0][refIdx];
852             if (!CodecHal_PictureIsInvalid(refPic) && m_preEncConfig.RefFramePOCList[refPic.FrameIdx] > m_preEncConfig.CurrPicOrderCnt)
853             {
854                 m_lowDelay = false;
855             }
856         }
857 
858         // backward
859         for (int refIdx = 0; (refIdx < 1) && m_lowDelay; refIdx++)
860         {
861             CODEC_PICTURE refPic = m_preEncConfig.RefPicList[1][refIdx];
862             if (!CodecHal_PictureIsInvalid(refPic) && m_preEncConfig.RefFramePOCList[refPic.FrameIdx] > m_preEncConfig.CurrPicOrderCnt)
863             {
864                 m_lowDelay = false;
865             }
866         }
867     }
868 
869     return eStatus;
870 }
871 
IsCurrentUsedAsRef(uint8_t idx) const872 bool PreEncBasicFeature::IsCurrentUsedAsRef(uint8_t idx) const
873 {
874     ENCODE_FUNC_CALL();
875 
876     if (idx < CODEC_MAX_NUM_REF_FRAME_HEVC &&
877         m_preEncConfig.PicIdx[idx].bValid && m_currUsedRefPic[idx])
878     {
879         return true;
880     }
881     else
882     {
883         return false;
884     }
885 }
886 
MHW_SETPAR_DECL_SRC(HCP_PIPE_BUF_ADDR_STATE,PreEncBasicFeature)887 MHW_SETPAR_DECL_SRC(HCP_PIPE_BUF_ADDR_STATE, PreEncBasicFeature)
888 {
889     ENCODE_FUNC_CALL();
890 
891     //add for B frame support
892     if (m_pictureCodingType != I_TYPE)
893     {
894         for (uint8_t i = 0; i < CODEC_MAX_NUM_REF_FRAME_HEVC; i++)
895         {
896             if (IsCurrentUsedAsRef(i))
897             {
898                 uint8_t idx       = m_preEncConfig.PicIdx[i].ucPicIdx;
899                 uint8_t scaledIdx = m_preEncConfig.RefList[idx]->ucScalingIdx;
900 
901                 uint8_t frameStoreId = m_refIdxMapping[i];
902                 auto    refSurface   = m_trackedBuf->GetSurface(BufferType::preRefSurface, scaledIdx);
903                 ENCODE_CHK_NULL_RETURN(refSurface);
904                 params.presReferences[frameStoreId] = &(refSurface->OsResource);
905                 if (m_preEncConfig.isPToB)
906                 {
907                     params.presReferences[frameStoreId + 1] = &(refSurface->OsResource);
908                 }
909             }
910         }
911     }
912 
913     params.presDeblockingFilterTileRowStoreScratchBuffer   = m_resDeblockingFilterTileRowStoreScratchBuffer;
914     params.presDeblockingFilterColumnRowStoreScratchBuffer = m_resDeblockingFilterColumnRowStoreScratchBuffer;
915     params.presMfdDeblockingFilterRowStoreScratchBuffer    = m_resDeblockingFilterRowStoreScratchBuffer;
916 
917     return MOS_STATUS_SUCCESS;
918 }
919 
MHW_SETPAR_DECL_SRC(HCP_PIPE_MODE_SELECT,PreEncBasicFeature)920 MHW_SETPAR_DECL_SRC(HCP_PIPE_MODE_SELECT, PreEncBasicFeature)
921 {
922     ENCODE_FUNC_CALL();
923 
924     params.bRdoqEnable = true;
925 
926     return MOS_STATUS_SUCCESS;
927 }
928 
MHW_SETPAR_DECL_SRC(HEVC_VP9_RDOQ_STATE,PreEncBasicFeature)929 MHW_SETPAR_DECL_SRC(HEVC_VP9_RDOQ_STATE, PreEncBasicFeature)
930 {
931     uint8_t bitDepthLumaMinus8   = m_preEncConfig.BitDepthLumaMinus8;
932     uint8_t bitDepthChromaMinus8 = m_preEncConfig.BitDepthChromaMinus8;
933     uint8_t codingType           = m_preEncConfig.CodingType;
934     auto    settings             = static_cast<PreEncFeatureSettings *>(m_preEncConstSettings->GetConstSettings());
935     ENCODE_CHK_NULL_RETURN(settings);
936 
937     if (bitDepthLumaMinus8 < 8)
938     {
939         uint32_t sliceTypeIdx = (codingType == I_TYPE) ? 0 : 1;
940 
941         //Intra lambda
942         MOS_ZeroMemory(params.lambdaTab, sizeof(params.lambdaTab));
943         if (bitDepthLumaMinus8 == 0)
944         {
945             std::copy(settings->rdoqLamdas8bits[sliceTypeIdx][0][0].begin(),
946                 settings->rdoqLamdas8bits[sliceTypeIdx][0][0].end(),
947                 std::begin(params.lambdaTab[0][0]));
948 
949             std::copy(settings->rdoqLamdas8bits[sliceTypeIdx][0][1].begin(),
950                 settings->rdoqLamdas8bits[sliceTypeIdx][0][1].end(),
951                 std::begin(params.lambdaTab[0][1]));
952 
953             std::copy(settings->rdoqLamdas8bits[sliceTypeIdx][1][0].begin(),
954                 settings->rdoqLamdas8bits[sliceTypeIdx][1][0].end(),
955                 std::begin(params.lambdaTab[1][0]));
956 
957             std::copy(settings->rdoqLamdas8bits[sliceTypeIdx][1][1].begin(),
958                 settings->rdoqLamdas8bits[sliceTypeIdx][1][1].end(),
959                 std::begin(params.lambdaTab[1][1]));
960         }
961         else if (bitDepthLumaMinus8 == 2)
962         {
963             std::copy(settings->rdoqLamdas10bits[sliceTypeIdx][0][0].begin(),
964                 settings->rdoqLamdas10bits[sliceTypeIdx][0][0].end(),
965                 std::begin(params.lambdaTab[0][0]));
966 
967             std::copy(settings->rdoqLamdas10bits[sliceTypeIdx][0][1].begin(),
968                 settings->rdoqLamdas10bits[sliceTypeIdx][0][1].end(),
969                 std::begin(params.lambdaTab[0][1]));
970 
971             std::copy(settings->rdoqLamdas10bits[sliceTypeIdx][1][0].begin(),
972                 settings->rdoqLamdas10bits[sliceTypeIdx][1][0].end(),
973                 std::begin(params.lambdaTab[1][0]));
974 
975             std::copy(settings->rdoqLamdas10bits[sliceTypeIdx][1][1].begin(),
976                 settings->rdoqLamdas10bits[sliceTypeIdx][1][1].end(),
977                 std::begin(params.lambdaTab[1][1]));
978         }
979         else if (bitDepthLumaMinus8 == 4)
980         {
981             std::copy(settings->rdoqLamdas12bits[sliceTypeIdx][0][0].begin(),
982                 settings->rdoqLamdas12bits[sliceTypeIdx][0][0].end(),
983                 std::begin(params.lambdaTab[0][0]));
984 
985             std::copy(settings->rdoqLamdas12bits[sliceTypeIdx][0][1].begin(),
986                 settings->rdoqLamdas12bits[sliceTypeIdx][0][1].end(),
987                 std::begin(params.lambdaTab[0][1]));
988 
989             std::copy(settings->rdoqLamdas12bits[sliceTypeIdx][1][0].begin(),
990                 settings->rdoqLamdas12bits[sliceTypeIdx][1][0].end(),
991                 std::begin(params.lambdaTab[1][0]));
992 
993             std::copy(settings->rdoqLamdas12bits[sliceTypeIdx][1][1].begin(),
994                 settings->rdoqLamdas12bits[sliceTypeIdx][1][1].end(),
995                 std::begin(params.lambdaTab[1][1]));
996         }
997     }
998     else
999     {
1000         int32_t shiftQP = 12;
1001 #if INTRACONF
1002         double lambdaScale = 1.8;  //Intra
1003 #else
1004         double lambdaScale = 1.0 - 0.35;  //LD or RA
1005 #endif
1006         double   qpTemp       = 0;
1007         double   lambdaDouble = 0;
1008         uint32_t lambda       = 0;
1009         double   qpFactor     = 0.55;
1010 
1011         MOS_ZeroMemory(params.lambdaTab, sizeof(params.lambdaTab));
1012 
1013         int32_t bitdepthLumaQpScaleLuma   = 6 * bitDepthLumaMinus8;
1014         int32_t bitdepthLumaQpScaleChroma = 6 * bitDepthChromaMinus8;
1015 
1016         //Intra lambda
1017         qpFactor = 0.25 * lambdaScale;
1018         for (uint8_t qp = 0; qp < 52 + bitdepthLumaQpScaleLuma; qp++)
1019         {
1020             qpTemp                     = (double)qp - bitdepthLumaQpScaleLuma - shiftQP;
1021             lambdaDouble               = qpFactor * pow(2.0, qpTemp / 3.0);
1022             lambdaDouble               = lambdaDouble * 16 + 0.5;
1023             lambdaDouble               = (lambdaDouble > 65535) ? 65535 : lambdaDouble;
1024             lambda                     = (uint32_t)floor(lambdaDouble);
1025             params.lambdaTab[0][0][qp] = (uint16_t)lambda;
1026         }
1027         for (uint8_t qp = 0; qp < 52 + bitdepthLumaQpScaleChroma; qp++)
1028         {
1029             qpTemp                     = (double)qp - bitdepthLumaQpScaleChroma - shiftQP;
1030             lambdaDouble               = qpFactor * pow(2.0, qpTemp / 3.0);
1031             lambdaDouble               = lambdaDouble * 16 + 0.5;
1032             lambdaDouble               = (lambdaDouble > 65535) ? 65535 : lambdaDouble;
1033             lambda                     = (uint32_t)floor(lambdaDouble);
1034             params.lambdaTab[0][1][qp] = (uint16_t)lambda;
1035         }
1036 
1037         ////Inter lambda
1038         qpFactor = 0.55;
1039         for (uint8_t qp = 0; qp < 52 + bitdepthLumaQpScaleLuma; qp++)
1040         {
1041             qpTemp       = (double)qp - bitdepthLumaQpScaleLuma - shiftQP;
1042             lambdaDouble = qpFactor * pow(2.0, qpTemp / 3.0);
1043             lambdaDouble *= MOS_MAX(1.00, MOS_MIN(1.6, 1.0 + 0.6 / 12.0 * (qpTemp - 10.0)));
1044             lambdaDouble               = lambdaDouble * 16 + 0.5;
1045             lambda                     = (uint32_t)floor(lambdaDouble);
1046             lambda                     = CodecHal_Clip3(0, 0xffff, lambda);
1047             params.lambdaTab[1][0][qp] = (uint16_t)lambda;
1048         }
1049         for (uint8_t qp = 0; qp < 52 + bitdepthLumaQpScaleChroma; qp++)
1050         {
1051             qpTemp       = (double)qp - bitdepthLumaQpScaleChroma - shiftQP;
1052             lambdaDouble = qpFactor * pow(2.0, qpTemp / 3.0);
1053             lambdaDouble *= MOS_MAX(0.95, MOS_MIN(1.20, 0.25 / 12.0 * (qpTemp - 10.0) + 0.95));
1054             lambdaDouble               = lambdaDouble * 16 + 0.5;
1055             lambda                     = (uint32_t)floor(lambdaDouble);
1056             lambda                     = CodecHal_Clip3(0, 0xffff, lambda);
1057             params.lambdaTab[1][1][qp] = (uint16_t)lambda;
1058         }
1059     }
1060 
1061     params.disableHtqPerformanceFix0 = true;
1062     params.disableHtqPerformanceFix1 = true;
1063 
1064     return MOS_STATUS_SUCCESS;
1065 }
1066 
MHW_SETPAR_DECL_SRC(HCP_PIC_STATE,PreEncBasicFeature)1067 MHW_SETPAR_DECL_SRC(HCP_PIC_STATE, PreEncBasicFeature)
1068 {
1069     params.framewidthinmincbminus1         = (uint16_t)(m_oriFrameWidth >> 3) - 1;
1070     params.transformSkipEnabled            = true;
1071     params.frameheightinmincbminus1        = (uint16_t)(m_oriFrameHeight >> 3) - 1;
1072     params.ctbsizeLcusize                  = 3;
1073     params.maxtusize                       = 3;
1074     params.mintusize                       = 0;
1075     params.cuQpDeltaEnabledFlag            = 1;  // In VDENC mode, this field should always be set to 1.
1076     params.diffCuQpDeltaDepth              = 3;
1077     params.pcmLoopFilterDisableFlag        = 1;
1078     params.ampEnabledFlag                  = 1;
1079     params.maxTransformHierarchyDepthIntra = 2;
1080     params.maxTransformHierarchyDepthInter = 2;
1081     params.pcmSampleBitDepthChromaMinus1   = 0;
1082     params.pcmSampleBitDepthLumaMinus1     = 0;
1083     params.bitDepthChromaMinus8            = m_preEncConfig.BitDepthChromaMinus8;
1084     params.bitDepthLumaMinus8              = m_preEncConfig.BitDepthLumaMinus8;
1085     params.lcuMaxBitsizeAllowed            = rawCTUBits & 0xffff;
1086     params.lcuMaxBitSizeAllowedMsb2its     = (rawCTUBits & 0x00030000) >> 16;
1087     params.rdoqEnable                      = true;
1088 
1089     params.chromaSubsampling            = 1;
1090     params.loopFilterAcrossTilesEnabled = 0;
1091 
1092     // Disable HEVC RDOQ for Intra blocks
1093     params.intratucountbasedrdoqdisable = 1;
1094     params.rdoqintratuthreshold         = 0xffff;
1095 
1096     params.partialFrameUpdateMode = false;
1097     params.temporalMvPredDisable  = true;
1098     params.sseEnable              = false;
1099 
1100     return MOS_STATUS_SUCCESS;
1101 }
1102 
MHW_SETPAR_DECL_SRC(HCP_SLICE_STATE,PreEncBasicFeature)1103 MHW_SETPAR_DECL_SRC(HCP_SLICE_STATE, PreEncBasicFeature)
1104 {
1105     params.slicestartctbxOrSliceStartLcuXEncoder = 0;
1106     params.slicestartctbyOrSliceStartLcuYEncoder = 0;
1107 
1108     params.nextslicestartctbxOrNextSliceStartLcuXEncoder = 0;
1109     params.nextslicestartctbyOrNextSliceStartLcuYEncoder = 0;
1110 
1111     params.sliceType          = (m_preEncConfig.SliceType == encodeHevcISlice) ? 2 : 0;
1112     params.lastsliceofpic     = 1;
1113     params.sliceqpSignFlag    = 0;
1114     params.dependentSliceFlag = false;
1115 
1116     params.sliceqp         = m_QP;
1117     params.sliceCbQpOffset = 0;
1118     params.sliceCrQpOffset = 0;
1119 
1120     params.loopFilterAcrossSlicesEnabled = 1;
1121     params.mvdL1ZeroFlag                 = 0;
1122     params.isLowDelay                    = IsLowDelay();
1123 
1124     params.collocatedFromL0Flag  = 0;
1125     params.chromalog2Weightdenom = 0;
1126     params.lumaLog2WeightDenom   = 0;
1127 
1128     params.cabacInitFlag = 0;
1129     params.maxmergeidx   = 4;
1130 
1131     params.collocatedrefidx = 0;
1132 
1133     params.sliceheaderlength = 0;
1134 
1135     params.emulationbytesliceinsertenable = 1;
1136     params.slicedataEnable                = 1;
1137     params.headerInsertionEnable          = 1;
1138 
1139     // Transform skip related parameters
1140 
1141     int slcQP = m_QP;
1142 
1143     int qpIdx = 0;
1144     if (slcQP <= 22)
1145     {
1146         qpIdx = 0;
1147     }
1148     else if (slcQP <= 27)
1149     {
1150         qpIdx = 1;
1151     }
1152     else if (slcQP <= 32)
1153     {
1154         qpIdx = 2;
1155     }
1156     else
1157     {
1158         qpIdx = 3;
1159     }
1160 
1161     auto settings = static_cast<PreEncFeatureSettings *>(m_preEncConstSettings->GetConstSettings());
1162     ENCODE_CHK_NULL_RETURN(settings);
1163 
1164     params.transformskiplambda = settings->transformSkipLambdaTable[slcQP];
1165 
1166     if (m_pictureCodingType == I_TYPE)
1167     {
1168         params.transformskipNumzerocoeffsFactor0    = settings->transformSkipCoeffsTable[qpIdx][0][0][0][0];
1169         params.transformskipNumzerocoeffsFactor1    = settings->transformSkipCoeffsTable[qpIdx][0][0][1][0];
1170         params.transformskipNumnonzerocoeffsFactor0 = settings->transformSkipCoeffsTable[qpIdx][0][0][0][1] + 32;
1171         params.transformskipNumnonzerocoeffsFactor1 = settings->transformSkipCoeffsTable[qpIdx][0][0][1][1] + 32;
1172     }
1173     else
1174     {
1175         params.transformskipNumzerocoeffsFactor0    = settings->transformSkipCoeffsTable[qpIdx][1][0][0][0];
1176         params.transformskipNumzerocoeffsFactor1    = settings->transformSkipCoeffsTable[qpIdx][1][0][1][0];
1177         params.transformskipNumnonzerocoeffsFactor0 = settings->transformSkipCoeffsTable[qpIdx][1][0][0][1] + 32;
1178         params.transformskipNumnonzerocoeffsFactor1 = settings->transformSkipCoeffsTable[qpIdx][1][0][1][1] + 32;
1179     }
1180 
1181     params.roundinter = 4;
1182     params.roundintra = 10;
1183 
1184     return MOS_STATUS_SUCCESS;
1185 }
1186 
MHW_SETPAR_DECL_SRC(HCP_SURFACE_STATE,PreEncBasicFeature)1187 MHW_SETPAR_DECL_SRC(HCP_SURFACE_STATE, PreEncBasicFeature)
1188 {
1189     PMOS_SURFACE psSurface            = nullptr;
1190     uint8_t      ucBitDepthLumaMinus8 = 0;
1191     uint8_t      chromaType           = 0;
1192     uint32_t     reconSurfHeight      = 0;
1193 
1194     ucBitDepthLumaMinus8 = m_preEncConfig.BitDepthLumaMinus8;
1195     chromaType           = m_outputChromaFormat;
1196     switch (params.surfaceStateId)
1197     {
1198     case CODECHAL_HCP_SRC_SURFACE_ID:
1199         psSurface = m_preEncRawSurface;
1200         break;
1201     case CODECHAL_HCP_DECODED_SURFACE_ID:
1202         psSurface       = const_cast<PMOS_SURFACE>(&m_reconSurface);
1203         reconSurfHeight = m_preEncRawSurface->dwHeight;
1204         break;
1205     case CODECHAL_HCP_REF_SURFACE_ID:
1206         psSurface       = const_cast<PMOS_SURFACE>(&m_reconSurface);
1207         reconSurfHeight = m_preEncRawSurface->dwHeight;
1208         break;
1209     }
1210 
1211     ENCODE_CHK_NULL_RETURN(psSurface);
1212     params.surfacePitchMinus1 = psSurface->dwPitch - 1;
1213 
1214     /* Handling of reconstructed surface is different for Y410 & AYUV formats */
1215     if ((params.surfaceStateId != CODECHAL_HCP_SRC_SURFACE_ID) &&
1216         (psSurface->Format == Format_Y410))
1217         params.surfacePitchMinus1 = psSurface->dwPitch / 2 - 1;
1218 
1219     if ((params.surfaceStateId != CODECHAL_HCP_SRC_SURFACE_ID) &&
1220         (psSurface->Format == Format_AYUV))
1221         params.surfacePitchMinus1 = psSurface->dwPitch / 4 - 1;
1222 
1223     bool surf10bit = (psSurface->Format == Format_P010) ||
1224                      (psSurface->Format == Format_P210) ||
1225                      (psSurface->Format == Format_Y210) ||
1226                      (psSurface->Format == Format_Y410) ||
1227                      (psSurface->Format == Format_R10G10B10A2) ||
1228                      (psSurface->Format == Format_B10G10R10A2) ||
1229                      (psSurface->Format == Format_P016) ||
1230                      (psSurface->Format == Format_Y216);
1231 
1232     if (chromaType == HCP_CHROMA_FORMAT_YUV422)
1233     {
1234         if (ucBitDepthLumaMinus8 > 0)
1235         {
1236             if (params.surfaceStateId == CODECHAL_HCP_SRC_SURFACE_ID)
1237             {
1238                 params.surfaceFormat = surf10bit ? hcp::SURFACE_FORMAT::SURFACE_FORMAT_Y216Y210FORMAT : hcp::SURFACE_FORMAT::SURFACE_FORMAT_YUY2FORMAT;
1239             }
1240             else
1241             {
1242                 params.surfaceFormat = hcp::SURFACE_FORMAT::SURFACE_FORMAT_Y216VARIANT;
1243             }
1244         }
1245         else
1246         {
1247             params.surfaceFormat = (params.surfaceStateId == CODECHAL_HCP_SRC_SURFACE_ID) ? hcp::SURFACE_FORMAT::SURFACE_FORMAT_YUY2FORMAT : hcp::SURFACE_FORMAT::SURFACE_FORMAT_YUY2VARIANT;
1248         }
1249     }
1250     else if (chromaType == HCP_CHROMA_FORMAT_YUV444)
1251     {
1252         if (ucBitDepthLumaMinus8 == 0)
1253         {
1254             params.surfaceFormat = params.surfaceStateId == CODECHAL_HCP_SRC_SURFACE_ID ? hcp::SURFACE_FORMAT::SURFACE_FORMAT_AYUV4444FORMAT : hcp::SURFACE_FORMAT::SURFACE_FORMAT_AYUV4444VARIANT;
1255         }
1256         else if (ucBitDepthLumaMinus8 <= 2)
1257         {
1258             if (params.surfaceStateId == CODECHAL_HCP_SRC_SURFACE_ID)
1259             {
1260                 params.surfaceFormat = surf10bit ? hcp::SURFACE_FORMAT::SURFACE_FORMAT_Y410FORMAT : hcp::SURFACE_FORMAT::SURFACE_FORMAT_AYUV4444FORMAT;
1261             }
1262             else
1263             {
1264                 params.surfaceFormat = hcp::SURFACE_FORMAT::SURFACE_FORMAT_Y416VARIANT;
1265             }
1266         }
1267         else
1268         {
1269             params.surfaceFormat = hcp::SURFACE_FORMAT::SURFACE_FORMAT_Y416FORMAT;
1270         }
1271     }
1272     else  //chromaType == HCP_CHROMA_FORMAT_YUV420
1273     {
1274         if (ucBitDepthLumaMinus8 > 0)
1275         {
1276             if (params.surfaceStateId == CODECHAL_HCP_SRC_SURFACE_ID)
1277             {
1278                 params.surfaceFormat = surf10bit ? hcp::SURFACE_FORMAT::SURFACE_FORMAT_P010 : hcp::SURFACE_FORMAT::SURFACE_FORMAT_PLANAR4208;
1279             }
1280             else
1281             {
1282                 params.surfaceFormat = hcp::SURFACE_FORMAT::SURFACE_FORMAT_P010VARIANT;
1283             }
1284         }
1285         else
1286         {
1287             params.surfaceFormat = hcp::SURFACE_FORMAT::SURFACE_FORMAT_PLANAR4208;
1288         }
1289     }
1290 
1291     params.yOffsetForUCbInPixel = params.yOffsetForVCr =
1292         (uint16_t)((psSurface->UPlaneOffset.iSurfaceOffset - psSurface->dwOffset) / psSurface->dwPitch + psSurface->RenderOffset.YUV.U.YOffset);
1293 
1294     //Set U/V offsets for Variant surfaces
1295     if (params.surfaceFormat == hcp::SURFACE_FORMAT::SURFACE_FORMAT_Y416VARIANT ||
1296         params.surfaceFormat == hcp::SURFACE_FORMAT::SURFACE_FORMAT_AYUV4444VARIANT)
1297     {
1298         params.yOffsetForUCbInPixel = (uint16_t)reconSurfHeight;
1299         params.yOffsetForVCr        = (uint16_t)reconSurfHeight << 1;
1300     }
1301     else if (params.surfaceFormat == hcp::SURFACE_FORMAT::SURFACE_FORMAT_Y216VARIANT ||
1302              params.surfaceFormat == hcp::SURFACE_FORMAT::SURFACE_FORMAT_YUY2VARIANT)
1303     {
1304         params.yOffsetForUCbInPixel = params.yOffsetForVCr = (uint16_t)reconSurfHeight;
1305     }
1306 
1307     return MOS_STATUS_SUCCESS;
1308 }
1309 
1310 
1311 #if USE_CODECHAL_DEBUG_TOOL
EncodePreencBasicFuntion1()1312 MOS_STATUS PreEncBasicFeature::EncodePreencBasicFuntion1()
1313 {
1314     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1315 
1316     ENCODE_FUNC_CALL();
1317 
1318     if (!m_enabled)
1319     {
1320         return MOS_STATUS_SUCCESS;
1321     }
1322 
1323     MediaUserSetting::Value outValue;
1324     outValue = std::string();
1325     eStatus = ReadUserSetting(
1326         m_userSettingPtr,
1327         outValue,
1328         "Preenc file0 path",
1329         MediaUserSetting::Group::Sequence);
1330 
1331     int size = outValue.Size();
1332     if (eStatus != MOS_STATUS_SUCCESS)
1333         size = 0;
1334 
1335     if (size == MOS_MAX_PATH_LENGTH + 1)
1336     {
1337         size = 0;
1338     }
1339 
1340     ENCODE_CHK_COND_RETURN(size == 0, "PATH LENGTH OF FILE IS TOO LONG");
1341 
1342     std::string path_file = outValue.Get<std::string>();
1343     if (path_file[size - 2] != MOS_DIRECTORY_DELIMITER)
1344     {
1345         path_file.push_back('\0');
1346     }
1347     std::string filePath0 = path_file;
1348 
1349     outValue = std::string();
1350     eStatus = ReadUserSetting(
1351         m_userSettingPtr,
1352         outValue,
1353         "Preenc file1 path",
1354         MediaUserSetting::Group::Sequence);
1355 
1356     size = outValue.Size();
1357 
1358     if (eStatus != MOS_STATUS_SUCCESS)
1359         size = 0;
1360 
1361     if (size == MOS_MAX_PATH_LENGTH + 1)
1362     {
1363         size = 0;
1364     }
1365 
1366     ENCODE_CHK_COND_RETURN(size == 0, "PATH LENGTH OF FILE IS TOO LONG");
1367 
1368     path_file = outValue.Get<std::string>();
1369     if (path_file[size - 2] != MOS_DIRECTORY_DELIMITER)
1370     {
1371         path_file.push_back('\0');
1372     }
1373     std::string filePath1 = path_file;
1374 
1375     if (m_preEncConfig.CodingType > I_TYPE)
1376     {
1377         void *data0 = m_allocator->LockResourceForRead(EncodePreencBasicMember3);
1378 
1379         if (pfile0 == nullptr)
1380         {
1381             MosUtilities::MosSecureFileOpen(&pfile0, filePath0.c_str(), "wb");
1382         }
1383 
1384         if (pfile0 != nullptr)
1385         {
1386             fwrite(data0, sizeof(EncodePreencDef1), EncodePreencBasicMember2, pfile0);
1387         }
1388 
1389         eStatus = m_allocator->UnLock(EncodePreencBasicMember3);
1390     }
1391 
1392     if (m_preEncConfig.CodingType != I_TYPE && !IsLowDelay())
1393     {
1394         void *data1 = m_allocator->LockResourceForRead(EncodePreencBasicMember4);
1395 
1396         if (pfile1 == nullptr)
1397         {
1398             MosUtilities::MosSecureFileOpen(&pfile1, filePath1.c_str(), "wb");
1399         }
1400 
1401         if (pfile1 != nullptr)
1402         {
1403             fwrite(data1, sizeof(EncodePreencDef1), EncodePreencBasicMember2, pfile1);
1404         }
1405 
1406         eStatus = m_allocator->UnLock(EncodePreencBasicMember4);
1407     }
1408 
1409     return eStatus;
1410 }
1411 #endif
1412 
1413 }  // namespace encode
1414