1 /*
2 * Copyright (c) 2019-2022, 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_vp9_basic_feature.cpp
24 //! \brief    Defines the common interface for encode vp9 parameter
25 //!
26 
27 #include "encode_utils.h"
28 #include "encode_allocator.h"
29 
30 #include "encode_vp9_basic_feature.h"
31 #include "encode_vp9_vdenc_const_settings.h"
32 #include "encode_vp9_brc.h"
33 #include "encode_vp9_segmentation.h"
34 
35 #include "media_feature_manager.h"
36 #include "media_vp9_feature_defs.h"
37 
38 namespace encode
39 {
Init(void * setting)40 MOS_STATUS Vp9BasicFeature::Init(void *setting)
41 {
42     ENCODE_FUNC_CALL();
43     ENCODE_CHK_NULL_RETURN(setting);
44 
45     EncodeBasicFeature::Init(setting);
46     CodechalSetting *codecSettings = (CodechalSetting *)setting;
47 
48     // Need to convert from VP9_ENCODE_CHROMA_FORMAT to HCP_CHROMA_FORMAT_IDC type
49     m_chromaFormat += 1;
50 
51     if (CodecHalUsesVideoEngine(m_codecFunction))
52     {
53         m_pakEnabled = true;
54     }
55 
56     if (CodecHalUsesRenderEngine(m_codecFunction, m_standard))
57     {
58         m_encEnabled = true;
59     }
60 
61     m_adaptiveRepakSupported  = true;
62 
63     // HME Scaling WxH
64     m_downscaledWidthInMb4x   = CODECHAL_GET_WIDTH_IN_MACROBLOCKS(m_frameWidth   / SCALE_FACTOR_4x);
65     m_downscaledHeightInMb4x  = CODECHAL_GET_HEIGHT_IN_MACROBLOCKS(m_frameHeight / SCALE_FACTOR_4x);
66     m_downscaledWidth4x       = m_downscaledWidthInMb4x  * CODECHAL_MACROBLOCK_WIDTH;
67     m_downscaledHeight4x      = m_downscaledHeightInMb4x * CODECHAL_MACROBLOCK_HEIGHT;
68 
69     // SuperHME Scaling WxH
70     m_downscaledWidthInMb16x  = CODECHAL_GET_WIDTH_IN_MACROBLOCKS(m_frameWidth   / SCALE_FACTOR_16x);
71     m_downscaledHeightInMb16x = CODECHAL_GET_HEIGHT_IN_MACROBLOCKS(m_frameHeight / SCALE_FACTOR_16x);
72     m_downscaledWidth16x      = m_downscaledWidthInMb16x  * CODECHAL_MACROBLOCK_WIDTH;
73     m_downscaledHeight16x     = m_downscaledHeightInMb16x * CODECHAL_MACROBLOCK_HEIGHT;
74 
75     m_minScaledDimension      = CODECHAL_ENCODE_MIN_SCALED_SURFACE_SIZE;
76     m_minScaledDimensionInMb  = (CODECHAL_ENCODE_MIN_SCALED_SURFACE_SIZE + 15) >> 4;
77 
78     // Max tile numbers = max of number tiles for single pipe or max number of tiles for scalable pipes
79     m_maxTileNumber = CODECHAL_GET_WIDTH_IN_BLOCKS(m_frameWidth,   CODECHAL_ENCODE_VP9_MIN_TILE_SIZE_WIDTH) *
80                       CODECHAL_GET_HEIGHT_IN_BLOCKS(m_frameHeight, CODECHAL_ENCODE_VP9_MIN_TILE_SIZE_HEIGHT);
81 
82     // Picture (width, height, size) in SB units
83     m_picWidthInSb  = MOS_ROUNDUP_DIVIDE(m_oriFrameWidth,  CODEC_VP9_SUPER_BLOCK_WIDTH);
84     m_picHeightInSb = MOS_ROUNDUP_DIVIDE(m_oriFrameHeight, CODEC_VP9_SUPER_BLOCK_HEIGHT);
85     m_picSizeInSb   = m_picWidthInSb * m_picHeightInSb;
86 
87     // Application needs to pass the maxinum frame width/height
88     m_maxPicWidth      = m_frameWidth;
89     m_maxPicHeight     = m_frameHeight;
90     m_maxPicWidthInSb  = MOS_ROUNDUP_DIVIDE(m_maxPicWidth,  CODEC_VP9_SUPER_BLOCK_WIDTH);
91     m_maxPicHeightInSb = MOS_ROUNDUP_DIVIDE(m_maxPicHeight, CODEC_VP9_SUPER_BLOCK_HEIGHT);
92     m_maxPicSizeInSb   = m_maxPicWidthInSb * m_maxPicHeightInSb;
93 
94     if (m_pakEnabled)
95     {
96         // m_mvoffset looks not correct here, and corresponding setting of buffer offset in HCP_IND_OBJ, need to check with HW team.
97         // keep current logic unchanged but increase the buffer size for now in case regression before we know how to correctly program these.
98         m_mvOffset = MOS_ALIGN_CEIL((m_maxPicSizeInSb * 4 * sizeof(uint32_t)), CODECHAL_PAGE_SIZE);  // 3 uint32_t for HCP_PAK_OBJECT and 1 uint32_t for padding zero in kernel
99 
100         // We need additional buffer for
101         // (1) 1 CL for size info at the beginning of each tile column (max of 4 vdbox in scalability mode)
102         // (2) CL alignment at the end of every tile column for every SB of width
103         // As a result, increase the height by 1 for allocation purposes
104         uint32_t numOfLCU      = m_maxPicSizeInSb + m_maxPicWidthInSb;
105         uint32_t maxNumCUInLCU = (m_maxLCUSize / m_minLCUSize) * (m_maxLCUSize / m_minLCUSize);
106         m_mbCodeSize           = MOS_ALIGN_CEIL(2 * sizeof(uint32_t) * numOfLCU * (NUM_PAK_DWS_PER_LCU + 64 * NUM_DWS_PER_CU), CODECHAL_PAGE_SIZE);
107     }
108 
109 #if (_DEBUG || _RELEASE_INTERNAL)
110     MediaUserSetting::Value outValue;
111 
112     // HUC enabled by default for VP9
113     ReadUserSettingForDebug(
114         m_userSettingPtr,
115         outValue,
116         "VP9 Encode HUC Enable",
117         MediaUserSetting::Group::Sequence);
118     m_hucEnabled = outValue.Get<bool>();
119 
120     // Single pass dynamic scaling enabled by default
121     ReadUserSettingForDebug(
122         m_userSettingPtr,
123         outValue,
124         "VP9 Encode Single Pass Dys Enable",
125         MediaUserSetting::Group::Sequence);
126     m_dysVdencMultiPassEnabled = !outValue.Get<bool>();
127 
128     // HME enabled by default for VP9
129     ReadUserSettingForDebug(
130         m_userSettingPtr,
131         outValue,
132         "VP9 Encode HME",
133         MediaUserSetting::Group::Sequence);
134     m_hmeSupported = outValue.Get<bool>();
135 
136     ReadUserSettingForDebug(
137         m_userSettingPtr,
138         outValue,
139         "VP9 Encode SuperHME",
140         MediaUserSetting::Group::Sequence);
141     m_16xMeSupported = outValue.Get<bool>();
142 #endif
143 
144     // Disable superHME when HME is disabled
145     if (m_hmeSupported == false)
146     {
147         m_16xMeSupported = false;
148     }
149 
150     ENCODE_CHK_STATUS_RETURN(m_ref.Init(this));
151 
152     return MOS_STATUS_SUCCESS;
153 }
154 
Update(void * params)155 MOS_STATUS Vp9BasicFeature::Update(void *params)
156 {
157     ENCODE_FUNC_CALL();
158     ENCODE_CHK_NULL_RETURN(params);
159 
160     ENCODE_CHK_STATUS_RETURN(EncodeBasicFeature::Update(params));
161 
162     EncoderParams *encodeParams = (EncoderParams *)params;
163 
164     m_vp9SeqParams = static_cast<PCODEC_VP9_ENCODE_SEQUENCE_PARAMS>(encodeParams->pSeqParams);
165     ENCODE_CHK_NULL_RETURN(m_vp9SeqParams);
166     m_vp9PicParams = static_cast<PCODEC_VP9_ENCODE_PIC_PARAMS>(encodeParams->pPicParams);
167     ENCODE_CHK_NULL_RETURN(m_vp9PicParams);
168     m_vp9SegmentParams = static_cast<PCODEC_VP9_ENCODE_SEGMENT_PARAMS>(encodeParams->pSegmentParams);
169     ENCODE_CHK_NULL_RETURN(m_vp9SegmentParams);
170 
171     m_nalUnitParams = encodeParams->ppNALUnitParams;
172     ENCODE_CHK_NULL_RETURN(m_nalUnitParams);
173     m_NumNalUnits = encodeParams->uiNumNalUnits;
174     ENCODE_ASSERT(m_NumNalUnits == 1);
175 
176     m_targetUsage          = m_vp9SeqParams->TargetUsage;
177     m_currOriginalPic      = m_vp9PicParams->CurrOriginalPic;
178     m_currReconstructedPic = m_vp9PicParams->CurrReconstructedPic;
179     m_pictureCodingType    = m_vp9PicParams->PicFlags.fields.frame_type == 0 ? I_TYPE : P_TYPE;
180 
181     m_bitstreamUpperBound = encodeParams->dwBitstreamSize;
182 
183     if (m_newSeq)
184     {
185         ENCODE_CHK_STATUS_RETURN(SetSequenceStructs());
186     }
187 
188     // Set picture structs here
189     ENCODE_CHK_STATUS_RETURN(SetPictureStructs())
190 
191     if (m_resolutionChanged)
192     {
193         ENCODE_CHK_STATUS_RETURN(UpdateTrackedBufferParameters());
194     }
195 
196     ENCODE_CHK_STATUS_RETURN(GetTrackedBuffers());
197 
198     return MOS_STATUS_SUCCESS;
199 }
200 
GetProfileLevelMaxFrameSize()201 uint32_t Vp9BasicFeature::GetProfileLevelMaxFrameSize()
202 {
203     ENCODE_FUNC_CALL();
204 
205     uint32_t profileLevelMaxFrame = m_frameWidth * m_frameHeight;
206     if (m_vp9SeqParams->UserMaxFrameSize > 0)
207     {
208         profileLevelMaxFrame = MOS_MIN(profileLevelMaxFrame, m_vp9SeqParams->UserMaxFrameSize);
209     }
210 
211     return profileLevelMaxFrame;
212 }
213 
Resize4x8xforDS(uint8_t bufIdx)214 MOS_STATUS Vp9BasicFeature::Resize4x8xforDS(uint8_t bufIdx)
215 {
216     ENCODE_FUNC_CALL();
217 
218     // Calculate the expected 4x dimensions
219     uint32_t downscaledSurfaceWidth4x  = m_downscaledWidthInMb4x * CODECHAL_MACROBLOCK_WIDTH;
220     uint32_t downscaledSurfaceHeight4x = ((m_downscaledHeightInMb4x + 1) >> 1) * CODECHAL_MACROBLOCK_HEIGHT;
221     downscaledSurfaceHeight4x          = MOS_ALIGN_CEIL(downscaledSurfaceHeight4x, MOS_YTILE_H_ALIGNMENT) << 1;
222 
223     // Calculate the expected 8x dimensions
224     uint32_t downscaledSurfaceWidth8x  = downscaledSurfaceWidth4x >> 1;
225     uint32_t downscaledSurfaceHeight8x = downscaledSurfaceHeight4x >> 1;
226 
227     ENCODE_CHK_NULL_RETURN(m_trackedBuf);
228 
229     // Get the 8x and 4x ds downscaled surfaces from tracked buffers
230     auto trackedBuf8xDsReconSurface = m_trackedBuf->GetSurface(BufferType::ds8xSurface, bufIdx);
231     auto trackedBuf4xDsReconSurface = m_trackedBuf->GetSurface(BufferType::ds4xSurface, bufIdx);
232 
233     ENCODE_CHK_NULL_RETURN(trackedBuf8xDsReconSurface);
234     ENCODE_CHK_NULL_RETURN(trackedBuf4xDsReconSurface);
235 
236     MOS_ALLOC_GFXRES_PARAMS allocParamsForBuffer2D;
237     MOS_ZeroMemory(&allocParamsForBuffer2D, sizeof(MOS_ALLOC_GFXRES_PARAMS));
238     allocParamsForBuffer2D.Type     = MOS_GFXRES_2D;
239     allocParamsForBuffer2D.TileType = MOS_TILE_Y;
240     allocParamsForBuffer2D.Format   = Format_NV12;
241 
242     // If any dimensions of allocated surface are smaller, reallocation is needed
243     if (trackedBuf8xDsReconSurface->dwWidth < downscaledSurfaceWidth8x || trackedBuf8xDsReconSurface->dwHeight < downscaledSurfaceHeight8x)
244     {
245         // Get the previously assigned dimensions to make sure we do not lower any dimension
246         auto previous8xWidth  = trackedBuf8xDsReconSurface->dwWidth;
247         auto previous8xHeight = trackedBuf8xDsReconSurface->dwHeight;
248 
249         auto new8xWidth  = MOS_MAX(previous8xWidth, downscaledSurfaceWidth8x);
250         auto new8xHeight = MOS_MAX(previous8xHeight, downscaledSurfaceHeight8x);
251 
252         allocParamsForBuffer2D.dwWidth  = new8xWidth;
253         allocParamsForBuffer2D.dwHeight = new8xHeight;
254         allocParamsForBuffer2D.pBufName = "8xDSSurface";
255         allocParamsForBuffer2D.ResUsageType = MOS_HW_RESOURCE_USAGE_ENCODE_INTERNAL_READ_WRITE_CACHE;
256         ENCODE_CHK_STATUS_RETURN(m_trackedBuf->RegisterParam(encode::BufferType::ds8xSurface, allocParamsForBuffer2D));
257     }
258 
259     if (trackedBuf4xDsReconSurface->dwWidth < downscaledSurfaceWidth4x || trackedBuf4xDsReconSurface->dwHeight < downscaledSurfaceHeight4x)
260     {
261         // Get the previously assigned dimensions to make sure we do not lower any dimension
262         auto previous4xWidth  = trackedBuf4xDsReconSurface->dwWidth;
263         auto previous4xHeight = trackedBuf4xDsReconSurface->dwHeight;
264 
265         auto new4xWidth  = MOS_MAX(previous4xWidth, downscaledSurfaceWidth4x);
266         auto new4xHeight = MOS_MAX(previous4xHeight, downscaledSurfaceHeight4x);
267 
268         allocParamsForBuffer2D.dwWidth  = new4xWidth;
269         allocParamsForBuffer2D.dwHeight = new4xHeight;
270         allocParamsForBuffer2D.pBufName = "4xDSSurface";
271         allocParamsForBuffer2D.ResUsageType = MOS_HW_RESOURCE_USAGE_ENCODE_INTERNAL_READ_WRITE_CACHE;
272         ENCODE_CHK_STATUS_RETURN(m_trackedBuf->RegisterParam(encode::BufferType::ds4xSurface, allocParamsForBuffer2D));
273     }
274 
275     return MOS_STATUS_SUCCESS;
276 }
277 
UpdateParameters()278 MOS_STATUS Vp9BasicFeature::UpdateParameters()
279 {
280     ENCODE_FUNC_CALL();
281 
282     m_prevFrameInfo.KeyFrame    = !m_vp9PicParams->PicFlags.fields.frame_type;
283     m_prevFrameInfo.IntraOnly   = (m_vp9PicParams->PicFlags.fields.frame_type == CODEC_VP9_KEY_FRAME) || m_vp9PicParams->PicFlags.fields.intra_only;
284     m_prevFrameInfo.ShowFrame   = m_vp9PicParams->PicFlags.fields.show_frame;
285     m_prevFrameInfo.FrameWidth  = m_oriFrameWidth;
286     m_prevFrameInfo.FrameHeight = m_oriFrameHeight;
287 
288     m_lastMvTemporalBufferIndex = m_currMvTemporalBufferIndex;
289 
290     return MOS_STATUS_SUCCESS;
291 }
292 
UpdateTrackedBufferParameters()293 MOS_STATUS Vp9BasicFeature::UpdateTrackedBufferParameters()
294 {
295     ENCODE_FUNC_CALL();
296     ENCODE_CHK_NULL_RETURN(m_trackedBuf);
297 
298     ENCODE_CHK_STATUS_RETURN(m_trackedBuf->OnSizeChange());
299 
300     m_mvDataSize = 0;
301 
302     uint32_t downscaledWidthInMb4x  = CODECHAL_GET_WIDTH_IN_MACROBLOCKS(m_frameWidth   / SCALE_FACTOR_4x);
303     uint32_t downscaledHeightInMb4x = CODECHAL_GET_HEIGHT_IN_MACROBLOCKS(m_frameHeight / SCALE_FACTOR_4x);
304 
305     m_downscaledWidth4x = downscaledWidthInMb4x * CODECHAL_MACROBLOCK_WIDTH;
306 
307     // Account for field case, offset needs to be 4K aligned if tiled for DI surface state
308     // Width will be allocated tile Y aligned, so also tile align height
309     uint32_t downscaledSurfaceHeight4x = ((downscaledHeightInMb4x + 1) >> 1) * CODECHAL_MACROBLOCK_HEIGHT;
310 
311     m_downscaledHeight4x = MOS_ALIGN_CEIL(downscaledSurfaceHeight4x, MOS_YTILE_H_ALIGNMENT) << 1;
312 
313     MOS_ALLOC_GFXRES_PARAMS allocParams;
314     MOS_ZeroMemory(&allocParams, sizeof(MOS_ALLOC_GFXRES_PARAMS));
315     allocParams.Type     = MOS_GFXRES_BUFFER;
316     allocParams.TileType = MOS_TILE_LINEAR;
317     allocParams.Format   = Format_Buffer;
318 
319     // Segment ID buffer
320     uint32_t sizeOfSegmentIdMap = m_maxPicSizeInSb * CODECHAL_CACHELINE_SIZE;
321     if (sizeOfSegmentIdMap > 0)
322     {
323         allocParams.dwBytes  = sizeOfSegmentIdMap;
324         allocParams.pBufName = "SegmentIdBuffer";
325         allocParams.ResUsageType = MOS_HW_RESOURCE_USAGE_ENCODE_INTERNAL_READ_WRITE_CACHE;
326         ENCODE_CHK_STATUS_RETURN(m_trackedBuf->RegisterParam(encode::BufferType::segmentIdStreamOutBuffer, allocParams));
327     }
328 
329     // Current MV temporal buffer
330     uint32_t sizeOfMvTemporalBuffer = m_maxPicSizeInSb * 9 * CODECHAL_CACHELINE_SIZE;
331     if (sizeOfMvTemporalBuffer > 0)
332     {
333         allocParams.dwBytes  = sizeOfMvTemporalBuffer;
334         allocParams.pBufName = "mvTemporalBuffer";
335         allocParams.ResUsageType = MOS_HW_RESOURCE_USAGE_ENCODE_INTERNAL_READ_WRITE_NOCACHE;
336         ENCODE_CHK_STATUS_RETURN(m_trackedBuf->RegisterParam(encode::BufferType::mvTemporalBuffer, allocParams));
337     }
338 
339     ENCODE_CHK_STATUS_RETURN(EncodeBasicFeature::UpdateTrackedBufferParameters());
340 
341     ENCODE_CHK_STATUS_RETURN(ResizeDsReconSurfacesVdenc());
342 
343     return MOS_STATUS_SUCCESS;
344 }
345 
GetTrackedBuffers()346 MOS_STATUS Vp9BasicFeature::GetTrackedBuffers()
347 {
348     ENCODE_FUNC_CALL();
349 
350     ENCODE_CHK_NULL_RETURN(m_trackedBuf);
351     ENCODE_CHK_NULL_RETURN(m_vp9PicParams);
352     ENCODE_CHK_NULL_RETURN(m_allocator);
353 
354     auto currRefList = m_ref.GetCurrRefList();
355     ENCODE_CHK_STATUS_RETURN(m_trackedBuf->Acquire(currRefList, false, true));
356 
357     auto currIndex = m_trackedBuf->GetCurrIndex();
358 
359     m_resMbCodeBuffer = m_trackedBuf->GetBuffer(BufferType::mbCodedBuffer, currIndex);
360     ENCODE_CHK_NULL_RETURN(m_resMbCodeBuffer);
361 
362     currRefList->ucMbCodeIdx        = currIndex;
363     currRefList->resRefMbCodeBuffer = *m_resMbCodeBuffer;
364 
365     m_4xDSSurface = m_trackedBuf->GetSurface(BufferType::ds4xSurface, currIndex);
366     ENCODE_CHK_NULL_RETURN(m_4xDSSurface);
367     ENCODE_CHK_STATUS_RETURN(m_allocator->GetSurfaceInfo(m_4xDSSurface));
368 
369     m_8xDSSurface = m_trackedBuf->GetSurface(BufferType::ds8xSurface, currIndex);
370     ENCODE_CHK_NULL_RETURN(m_8xDSSurface);
371     ENCODE_CHK_STATUS_RETURN(m_allocator->GetSurfaceInfo(m_8xDSSurface));
372 
373     m_resMvTemporalBuffer = m_trackedBuf->GetBuffer(BufferType::mvTemporalBuffer, currIndex);
374     ENCODE_CHK_NULL_RETURN(m_resMvTemporalBuffer);
375     m_currMvTemporalBufferIndex = currIndex;
376 
377     m_resSegmentIdBuffer = m_trackedBuf->GetBuffer(BufferType::segmentIdStreamOutBuffer, currIndex);
378     ENCODE_CHK_NULL_RETURN(m_resSegmentIdBuffer);
379 
380     return MOS_STATUS_SUCCESS;
381 }
382 
SetSequenceStructs()383 MOS_STATUS Vp9BasicFeature::SetSequenceStructs()
384 {
385     ENCODE_FUNC_CALL();
386 
387     if (m_adaptiveRepakSupported)
388     {
389         ENCODE_CHK_STATUS_RETURN(CalculateRePakThresholds());
390     }
391 
392     return MOS_STATUS_SUCCESS;
393 }
394 
SetPictureStructs()395 MOS_STATUS Vp9BasicFeature::SetPictureStructs()
396 {
397     ENCODE_FUNC_CALL();
398 
399     if (false == isHmeEnabledForTargetUsage(m_vp9SeqParams->TargetUsage))
400     {
401         m_hmeEnabled = m_16xMeSupported = m_32xMeSupported = false;
402         m_16xMeEnabled                                     = false;
403     }
404 
405     // Setup internal parameters
406     uint32_t frameWidth  = m_vp9PicParams->SrcFrameWidthMinus1  + 1;
407     uint32_t frameHeight = m_vp9PicParams->SrcFrameHeightMinus1 + 1;
408 
409     // dwOriFrameWidth and dwOriFrameHeight are encoded by resolution.
410     // If dynamic scaling is enabled, current resolution may differ from the source resolution.
411     // Only for the first frame
412     if (m_frameNum == 0)
413     {
414         m_oriFrameWidth     = frameWidth;
415         m_oriFrameHeight    = frameHeight;
416         m_resolutionChanged = true;
417     }
418     else
419     {
420         // Check if there is a dynamic resolution change
421         if ((m_oriFrameWidth  && (m_oriFrameWidth  != frameWidth)) ||
422             (m_oriFrameHeight && (m_oriFrameHeight != frameHeight)))
423         {
424             m_resolutionChanged = true;
425             m_oriFrameWidth     = frameWidth;
426             m_oriFrameHeight    = frameHeight;
427         }
428         else
429         {
430             m_resolutionChanged = false;
431         }
432     }
433 
434     if (m_oriFrameWidth  == 0 || m_oriFrameWidth  > m_maxPicWidth ||
435         m_oriFrameHeight == 0 || m_oriFrameHeight > m_maxPicHeight)
436     {
437         return MOS_STATUS_INVALID_PARAMETER;
438     }
439 
440     // Picture (width, height, size) in SB units
441     m_picWidthInSb  = MOS_ROUNDUP_DIVIDE(m_oriFrameWidth,  CODEC_VP9_SUPER_BLOCK_WIDTH);
442     m_picHeightInSb = MOS_ROUNDUP_DIVIDE(m_oriFrameHeight, CODEC_VP9_SUPER_BLOCK_HEIGHT);
443     m_picSizeInSb   = m_picWidthInSb * m_picHeightInSb;
444 
445     // Picture (width, height) in MB units
446     m_picWidthInMb  = (uint16_t)CODECHAL_GET_WIDTH_IN_MACROBLOCKS(m_oriFrameWidth);
447     m_picHeightInMb = (uint16_t)CODECHAL_GET_HEIGHT_IN_MACROBLOCKS(m_oriFrameHeight);
448     m_frameWidth    = m_picWidthInMb  * CODECHAL_MACROBLOCK_WIDTH;
449     m_frameHeight   = m_picHeightInMb * CODECHAL_MACROBLOCK_HEIGHT;
450 
451     // HME Scaling WxH
452     m_downscaledWidthInMb4x  = CODECHAL_GET_WIDTH_IN_MACROBLOCKS(m_frameWidth   / SCALE_FACTOR_4x);
453     m_downscaledHeightInMb4x = CODECHAL_GET_HEIGHT_IN_MACROBLOCKS(m_frameHeight / SCALE_FACTOR_4x);
454     m_downscaledWidth4x      = m_downscaledWidthInMb4x  * CODECHAL_MACROBLOCK_WIDTH;
455     m_downscaledHeight4x     = m_downscaledHeightInMb4x * CODECHAL_MACROBLOCK_HEIGHT;
456 
457     // SuperHME Scaling WxH
458     m_downscaledWidthInMb16x  = CODECHAL_GET_WIDTH_IN_MACROBLOCKS(m_frameWidth   / SCALE_FACTOR_16x);
459     m_downscaledHeightInMb16x = CODECHAL_GET_HEIGHT_IN_MACROBLOCKS(m_frameHeight / SCALE_FACTOR_16x);
460     m_downscaledWidth16x      = m_downscaledWidthInMb16x  * CODECHAL_MACROBLOCK_WIDTH;
461     m_downscaledHeight16x     = m_downscaledHeightInMb16x * CODECHAL_MACROBLOCK_HEIGHT;
462 
463     m_frameFieldHeight                  = m_frameHeight;
464     m_frameFieldHeightInMb              = m_picHeightInMb;
465     m_downscaledFrameFieldHeightInMb4x  = m_downscaledHeightInMb4x;
466     m_downscaledFrameFieldHeightInMb16x = m_downscaledHeightInMb16x;
467 
468     MotionEstimationDisableCheck();
469 
470     if (m_vp9SeqParams->SeqFlags.fields.EnableDynamicScaling)
471     {
472         m_rawSurface.dwWidth  = MOS_ALIGN_CEIL(m_vp9PicParams->SrcFrameWidthMinus1  + 1, CODEC_VP9_MIN_BLOCK_WIDTH);
473         m_rawSurface.dwHeight = MOS_ALIGN_CEIL(m_vp9PicParams->SrcFrameHeightMinus1 + 1, CODEC_VP9_MIN_BLOCK_HEIGHT);
474     }
475 
476     if (Mos_ResourceIsNull(&m_reconSurface.OsResource) &&
477         (!m_vp9SeqParams->SeqFlags.fields.bUseRawReconRef || m_codecFunction != CODECHAL_FUNCTION_ENC))
478     {
479         return MOS_STATUS_INVALID_PARAMETER;
480     }
481 
482     m_dysBrc = false;
483     m_dysCqp = false;
484 
485     // Update reference frames
486     ENCODE_CHK_STATUS_RETURN(m_ref.Update());
487 
488     m_vdencPakonlyMultipassEnabled   = false;
489 
490     m_txMode = CODEC_VP9_TX_SELECTABLE;
491 
492     // For VDEnc disable HME if HME hasn't been disabled by reg key AND TU != TU1
493     m_hmeSupported   = m_hmeSupported && isHmeEnabledForTargetUsage(m_vp9SeqParams->TargetUsage);
494     m_16xMeSupported = m_16xMeSupported && m_hmeSupported;
495     // Enable HME/SHME for frame
496     m_hmeEnabled   = m_hmeSupported && m_pictureCodingType != I_TYPE && !m_vp9PicParams->PicFlags.fields.intra_only;
497     m_16xMeEnabled = m_16xMeSupported && m_hmeEnabled;
498 
499     // We cannot use refresh_frame_context if HuC isn't enabled to update probs
500     if (m_vp9PicParams->PicFlags.fields.refresh_frame_context && !m_hucEnabled)
501     {
502         ENCODE_ASSERTMESSAGE("Refresh_frame_context cannot be enabled while HuC is disabled.  HuC is needed for refresh_frame_context to be enabled.");
503         return MOS_STATUS_INVALID_PARAMETER;
504     }
505 
506     return MOS_STATUS_SUCCESS;
507 }
508 
MotionEstimationDisableCheck()509 void Vp9BasicFeature::MotionEstimationDisableCheck()
510 {
511     ENCODE_FUNC_CALL();
512 
513     if (m_downscaledWidth4x < m_minScaledDimension || m_downscaledWidthInMb4x < m_minScaledDimensionInMb ||
514         m_downscaledHeight4x < m_minScaledDimension || m_downscaledHeightInMb4x < m_minScaledDimensionInMb)
515     {
516         m_32xMeSupported = false;
517         m_16xMeSupported = false;
518         if (m_downscaledWidth4x < m_minScaledDimension || m_downscaledWidthInMb4x < m_minScaledDimensionInMb)
519         {
520             m_downscaledWidth4x     = m_minScaledDimension;
521             m_downscaledWidthInMb4x = CODECHAL_GET_WIDTH_IN_MACROBLOCKS(m_downscaledWidth4x);
522         }
523         if (m_downscaledHeight4x < m_minScaledDimension || m_downscaledHeightInMb4x < m_minScaledDimensionInMb)
524         {
525             m_downscaledHeight4x     = m_minScaledDimension;
526             m_downscaledHeightInMb4x = CODECHAL_GET_HEIGHT_IN_MACROBLOCKS(m_downscaledHeight4x);
527         }
528     }
529     else if (m_downscaledWidth16x < m_minScaledDimension || m_downscaledWidthInMb16x < m_minScaledDimensionInMb ||
530              m_downscaledHeight16x < m_minScaledDimension || m_downscaledHeightInMb16x < m_minScaledDimensionInMb)
531     {
532         m_32xMeSupported = false;
533         if (m_downscaledWidth16x < m_minScaledDimension || m_downscaledWidthInMb16x < m_minScaledDimensionInMb)
534         {
535             m_downscaledWidth16x     = m_minScaledDimension;
536             m_downscaledWidthInMb16x = CODECHAL_GET_WIDTH_IN_MACROBLOCKS(m_downscaledWidth16x);
537         }
538         if (m_downscaledHeight16x < m_minScaledDimension || m_downscaledHeightInMb16x < m_minScaledDimensionInMb)
539         {
540             m_downscaledHeight16x     = m_minScaledDimension;
541             m_downscaledHeightInMb16x = CODECHAL_GET_HEIGHT_IN_MACROBLOCKS(m_downscaledHeight16x);
542         }
543     }
544     else
545     {
546         if (m_downscaledWidth32x < m_minScaledDimension || m_downscaledWidthInMb32x < m_minScaledDimensionInMb)
547         {
548             m_downscaledWidth32x     = m_minScaledDimension;
549             m_downscaledWidthInMb32x = CODECHAL_GET_WIDTH_IN_MACROBLOCKS(m_downscaledWidth32x);
550         }
551         if (m_downscaledHeight32x < m_minScaledDimension || m_downscaledHeightInMb32x < m_minScaledDimensionInMb)
552         {
553             m_downscaledHeight32x     = m_minScaledDimension;
554             m_downscaledHeightInMb32x = CODECHAL_GET_HEIGHT_IN_MACROBLOCKS(m_downscaledHeight32x);
555         }
556     }
557 }
558 
ResizeDsReconSurfacesVdenc()559 MOS_STATUS Vp9BasicFeature::ResizeDsReconSurfacesVdenc()
560 {
561     ENCODE_FUNC_CALL();
562 
563     ENCODE_CHK_NULL_RETURN(m_trackedBuf);
564 
565     auto allocated8xWidth  = m_downscaledWidth4x >> 1;
566     auto allocated8xHeight = MOS_ALIGN_CEIL(m_downscaledHeight4x >> 1, MOS_YTILE_H_ALIGNMENT) << 1;
567 
568     // Calculate the expected 4x dimensions
569     uint32_t downscaledSurfaceWidth4x  = m_downscaledWidthInMb4x * CODECHAL_MACROBLOCK_WIDTH;
570 
571     // Account for field case, offset needs to be 4K aligned if tiled for DI surface state.
572     // Width will be allocated tile Y aligned, so also tile align height.
573     uint32_t downscaledSurfaceHeight4x = ((m_downscaledHeightInMb4x + 1) >> 1) * CODECHAL_MACROBLOCK_HEIGHT;
574     downscaledSurfaceHeight4x          = MOS_ALIGN_CEIL(downscaledSurfaceHeight4x, MOS_YTILE_H_ALIGNMENT) << 1;
575 
576     // Calculate the expected 8x dimensions
577     uint32_t downscaledSurfaceWidth8x  = downscaledSurfaceWidth4x >> 1;
578     uint32_t downscaledSurfaceHeight8x = downscaledSurfaceHeight4x >> 1;
579 
580     MOS_ALLOC_GFXRES_PARAMS allocParamsForBuffer2D;
581     MOS_ZeroMemory(&allocParamsForBuffer2D, sizeof(MOS_ALLOC_GFXRES_PARAMS));
582     allocParamsForBuffer2D.Type     = MOS_GFXRES_2D;
583     allocParamsForBuffer2D.TileType = MOS_TILE_Y;
584     allocParamsForBuffer2D.Format   = Format_NV12;
585 
586     // If any dimensions of allocated surface are smaller, reallocation is needed
587     if ((downscaledSurfaceHeight4x != m_downscaledHeight4x) || (downscaledSurfaceWidth4x != m_downscaledWidth4x))
588     {
589         allocParamsForBuffer2D.dwWidth  = downscaledSurfaceWidth4x;
590         allocParamsForBuffer2D.dwHeight = downscaledSurfaceHeight4x;
591         allocParamsForBuffer2D.pBufName = "4xDSSurface";
592         ENCODE_CHK_STATUS_RETURN(m_trackedBuf->RegisterParam(encode::BufferType::ds4xSurface, allocParamsForBuffer2D));
593     }
594 
595     if ((downscaledSurfaceHeight8x != allocated8xHeight) || (downscaledSurfaceWidth8x != allocated8xWidth))
596     {
597         allocParamsForBuffer2D.dwWidth  = downscaledSurfaceWidth8x;
598         allocParamsForBuffer2D.dwHeight = downscaledSurfaceHeight8x;
599         allocParamsForBuffer2D.pBufName = "8xDSSurface";
600         ENCODE_CHK_STATUS_RETURN(m_trackedBuf->RegisterParam(encode::BufferType::ds8xSurface, allocParamsForBuffer2D));
601     }
602 
603     return MOS_STATUS_SUCCESS;
604 }
605 
CalculateRePakThresholds()606 MOS_STATUS Vp9BasicFeature::CalculateRePakThresholds()
607 {
608     ENCODE_FUNC_CALL();
609 
610     ENCODE_CHK_NULL_RETURN(m_vp9SeqParams);
611 
612     int32_t repakSavingThreshold = 0;
613 
614     if (m_prevFrameInfo.FrameWidth  != m_oriFrameWidth ||
615         m_prevFrameInfo.FrameHeight != m_oriFrameHeight)
616     {
617         if (TargetUsage::isQuality(m_oriTargetUsage))
618         {
619             repakSavingThreshold =  2; // Quality mode
620         }
621         else if (TargetUsage::isSpeed(m_oriTargetUsage))
622         {
623             repakSavingThreshold = 80; // Speed mode
624         }
625         else
626         {
627             repakSavingThreshold = 10; // Normal mode
628         }
629 
630         int32_t scale = (m_oriFrameWidth * m_oriFrameHeight) / (176 * 144);
631         if (!scale)
632         {
633             scale = 1;
634         }
635 
636         for (auto i = 0; i < CODEC_VP9_QINDEX_RANGE; ++i)
637         {
638             double tempQp = i - 144.0;
639 
640             int32_t b                              = (int32_t)(92.5 * i);
641             int32_t c                              = (int32_t)(1.6 * tempQp * tempQp);
642             int32_t d                              = (int32_t)(0.01 * tempQp * tempQp * tempQp);
643             int32_t threshold                      = (int32_t)((18630 - b + c - d) / 10);
644             int32_t calculatedRepakSavingThreshold = repakSavingThreshold * scale;
645 
646             // To avoid overflow of the integer threshold, it must be (RepakSavingThreshold * scale) <= 40342
647             if (calculatedRepakSavingThreshold > CODEC_VP9_MAX_REPAK_THRESHOLD)
648             {
649                 calculatedRepakSavingThreshold = CODEC_VP9_MAX_REPAK_THRESHOLD;
650             }
651             m_rePakThreshold[i] = calculatedRepakSavingThreshold * threshold;
652         }
653     }
654 
655     return MOS_STATUS_SUCCESS;
656 }
657 
Convert2SignMagnitude(int32_t val,uint32_t signBitPos) const658 uint32_t Vp9BasicFeature::Convert2SignMagnitude(int32_t val, uint32_t signBitPos) const
659 {
660     uint32_t retVal        = 0;
661     uint32_t magnitudeMask = (1 << (signBitPos - 1)) - 1;
662 
663     if (val < 0)
664     {
665         retVal = ((magnitudeMask + 1) | (-val & magnitudeMask));
666     }
667     else
668     {
669         retVal = val & magnitudeMask;
670     }
671     return retVal;
672 }
673 
isHmeEnabledForTargetUsage(uint8_t targetUsage) const674 bool Vp9BasicFeature::isHmeEnabledForTargetUsage(uint8_t targetUsage) const
675 {
676     if (TargetUsage::QUALITY == targetUsage)
677     {
678         return true;
679     }
680     return false;
681 }
682 
MHW_SETPAR_DECL_SRC(HCP_VP9_PIC_STATE,Vp9BasicFeature)683 MHW_SETPAR_DECL_SRC(HCP_VP9_PIC_STATE, Vp9BasicFeature)
684 {
685     ENCODE_FUNC_CALL();
686 
687     uint32_t curFrameWidth  = m_vp9PicParams->SrcFrameWidthMinus1  + 1;
688     uint32_t curFrameHeight = m_vp9PicParams->SrcFrameHeightMinus1 + 1;
689 
690     params.frameWidthInPixelsMinus1   = MOS_ALIGN_CEIL(curFrameWidth,  CODEC_VP9_MIN_BLOCK_WIDTH) - 1;
691     params.frameHeightInPixelsMinus1  = MOS_ALIGN_CEIL(curFrameHeight, CODEC_VP9_MIN_BLOCK_WIDTH) - 1;
692 
693     params.frameType                  = m_vp9PicParams->PicFlags.fields.frame_type;
694     params.adaptProbabilitiesFlag     = !m_vp9PicParams->PicFlags.fields.error_resilient_mode && !m_vp9PicParams->PicFlags.fields.frame_parallel_decoding_mode;
695     params.intraOnlyFlag              = m_vp9PicParams->PicFlags.fields.intra_only;
696     params.allowHiPrecisionMv         = m_vp9PicParams->PicFlags.fields.allow_high_precision_mv;
697     params.mcompFilterType            = m_vp9PicParams->PicFlags.fields.mcomp_filter_type;
698     params.hybridPredictionMode       = m_vp9PicParams->PicFlags.fields.comp_prediction_mode == 2;
699     params.selectableTxMode           = m_txMode == 4;
700     params.refreshFrameContext        = m_vp9PicParams->PicFlags.fields.refresh_frame_context;
701     params.errorResilientMode         = m_vp9PicParams->PicFlags.fields.error_resilient_mode;
702     params.frameParallelDecodingMode  = m_vp9PicParams->PicFlags.fields.frame_parallel_decoding_mode;
703     params.filterLevel                = m_vp9PicParams->filter_level;
704     params.sharpnessLevel             = m_vp9PicParams->sharpness_level;
705     params.segmentationEnabled        = m_vp9PicParams->PicFlags.fields.segmentation_enabled;
706     params.segmentationUpdateMap      = m_vp9PicParams->PicFlags.fields.segmentation_update_map;
707     params.segmentationTemporalUpdate = m_vp9PicParams->PicFlags.fields.segmentation_temporal_update;
708     params.losslessMode               = m_vp9PicParams->PicFlags.fields.LosslessFlag;
709 
710     params.log2TileRow                = m_vp9PicParams->log2_tile_rows;
711     params.log2TileColumn             = m_vp9PicParams->log2_tile_columns;
712 
713     params.chromaSamplingFormat       = m_vp9SeqParams->SeqFlags.fields.EncodedFormat;
714     params.bitdepthMinus8             = (m_vp9SeqParams->SeqFlags.fields.EncodedBitDepth == VP9_ENCODED_BIT_DEPTH_10) ? 2 : 0;
715 
716     params.baseQIndexSameAsLumaAc     = m_vp9PicParams->LumaACQIndex;
717     params.headerInsertionEnable      = 1;
718 
719     params.chromaAcQIndexDelta        = Convert2SignMagnitude(m_vp9PicParams->ChromaACQIndexDelta, 5);
720     params.chromaDcQIndexDelta        = Convert2SignMagnitude(m_vp9PicParams->ChromaDCQIndexDelta, 5);
721     params.lumaDcQIndexDelta          = Convert2SignMagnitude(m_vp9PicParams->LumaDCQIndexDelta, 5);
722 
723     params.bitOffsetForLfRefDelta         = m_vp9PicParams->BitOffsetForLFRefDelta;
724     params.bitOffsetForLfModeDelta        = m_vp9PicParams->BitOffsetForLFModeDelta;
725     params.bitOffsetForLfLevel            = m_vp9PicParams->BitOffsetForLFLevel;
726     params.bitOffsetForQIndex             = m_vp9PicParams->BitOffsetForQIndex;
727     params.bitOffsetForFirstPartitionSize = m_vp9PicParams->BitOffsetForFirstPartitionSize;
728 
729     params.vdencPakOnlyPass = m_vdencPakonlyMultipassEnabled;
730 
731     m_ref.MHW_SETPAR_F(HCP_VP9_PIC_STATE)(params);
732 
733     return MOS_STATUS_SUCCESS;
734 }
735 
736 ////////////////////////////////////////////////////////////////////////////////
737 
getNumRefFrames(uint8_t frameType,uint8_t numRefFrames)738 static inline uint8_t getNumRefFrames(uint8_t frameType, uint8_t numRefFrames)
739 {
740     return (frameType ? numRefFrames : 0);  // frame_type == 1 ? NON_KEY_FRAME : KEY_FRAME
741 }
742 
refIdxEqual(PCODEC_VP9_ENCODE_PIC_PARAMS vp9PicParams)743 static inline bool refIdxEqual(PCODEC_VP9_ENCODE_PIC_PARAMS vp9PicParams)
744 {
745     uint32_t lastRefIdx   = vp9PicParams->RefFlags.fields.LastRefIdx;
746     uint32_t altRefIdx    = vp9PicParams->RefFlags.fields.AltRefIdx;
747     uint32_t goldenRefIdx = vp9PicParams->RefFlags.fields.GoldenRefIdx;
748 
749     if (lastRefIdx == altRefIdx && altRefIdx == goldenRefIdx)
750     {
751         return true;
752     }
753     return false;
754 }
755 
isTemporalMvpEnabledForTargetUsage(uint8_t targetUsage)756 static inline bool isTemporalMvpEnabledForTargetUsage(uint8_t targetUsage)
757 {
758     if (TargetUsage::QUALITY == targetUsage)
759     {
760         return false;
761     }
762     return true;
763 }
764 
isTemporalMvpEnabled(uint8_t targetUsage,uint32_t frameType,uint32_t lastFrameType,PCODEC_VP9_ENCODE_PIC_PARAMS vp9PicParams)765 static inline bool isTemporalMvpEnabled(uint8_t targetUsage, uint32_t frameType, uint32_t lastFrameType, PCODEC_VP9_ENCODE_PIC_PARAMS vp9PicParams)
766 {
767     return frameType && !lastFrameType;  // frame_type == 1 ? NON_KEY_FRAME : KEY_FRAME
768 }
769 
770 ////////////////////////////////////////////////////////////////////////////////
771 
MHW_SETPAR_DECL_SRC(VDENC_CMD1,Vp9BasicFeature)772 MHW_SETPAR_DECL_SRC(VDENC_CMD1, Vp9BasicFeature)
773 {
774     ENCODE_FUNC_CALL();
775     auto settings = static_cast<Vp9VdencFeatureSettings *>(m_constSettings);
776     ENCODE_CHK_NULL_RETURN(settings);
777 
778     for (const auto &lambda : settings->vdencCmd1Settings)
779     {
780         ENCODE_CHK_STATUS_RETURN(lambda(params, false));
781     }
782     return MOS_STATUS_SUCCESS;
783 }
784 
MHW_SETPAR_DECL_SRC(VDENC_SRC_SURFACE_STATE,Vp9BasicFeature)785 MHW_SETPAR_DECL_SRC(VDENC_SRC_SURFACE_STATE, Vp9BasicFeature)
786 {
787     ENCODE_FUNC_CALL();
788 
789     MHW_MI_CHK_NULL(m_vp9SeqParams);
790     MHW_MI_CHK_NULL(m_rawSurfaceToPak);
791 
792     // DW2..5 - DW0
793 
794     params.width = MOS_ALIGN_CEIL(m_oriFrameWidth, CODEC_VP9_MIN_BLOCK_WIDTH);
795     params.height = MOS_ALIGN_CEIL(m_oriFrameHeight, CODEC_VP9_MIN_BLOCK_HEIGHT);
796     params.displayFormatSwizzle = m_vp9SeqParams->SeqFlags.fields.DisplayFormatSwizzle;
797 
798     auto waTable = m_osInterface == nullptr ? nullptr : m_osInterface->pfnGetWaTable(m_osInterface);
799     if (waTable)
800     {
801         if (!MEDIA_IS_WA(waTable, Wa_Vp9UnalignedHeight))
802         {
803             params.height = m_oriFrameHeight;
804         }
805     }
806     // DW2..5 - DW1
807 
808     params.tileType             = m_rawSurfaceToPak->TileType;
809     params.tileModeGmm          = m_rawSurfaceToPak->TileModeGMM;
810     params.format               = m_rawSurfaceToPak->Format;
811     params.gmmTileEn            = m_rawSurfaceToPak->bGMMTileEnabled;
812     params.pitch                = m_rawSurfaceToPak->dwPitch;
813     params.chromaDownsampleFilterControl = 7;
814 
815     // DW2..5 - DW2
816 
817     params.uOffset              = m_rawSurfaceToPak->YoffsetForUplane;
818 
819     // DW2..5 - DW3
820 
821     params.vOffset              = m_rawSurfaceToPak->YoffsetForVplane;
822 
823     return MOS_STATUS_SUCCESS;
824 }
825 
MHW_SETPAR_DECL_SRC(VDENC_DS_REF_SURFACE_STATE,Vp9BasicFeature)826 MHW_SETPAR_DECL_SRC(VDENC_DS_REF_SURFACE_STATE, Vp9BasicFeature)
827 {
828     ENCODE_FUNC_CALL();
829 
830     MHW_MI_CHK_NULL(m_8xDSSurface);
831 
832     // DW2..5
833 
834     params.pitchStage1       = m_8xDSSurface->dwPitch;
835     params.tileTypeStage1    = m_8xDSSurface->TileType;
836     params.tileModeGmmStage1 = m_8xDSSurface->TileModeGMM;
837     params.gmmTileEnStage1   = m_8xDSSurface->bGMMTileEnabled;
838     params.uOffsetStage1     = m_8xDSSurface->YoffsetForUplane;
839     params.vOffsetStage1     = m_8xDSSurface->YoffsetForVplane;
840     params.heightStage1      = m_8xDSSurface->dwHeight;
841     params.widthStage1       = m_8xDSSurface->dwWidth;
842 
843     MHW_MI_CHK_NULL(m_4xDSSurface);
844 
845     // DW 6..9
846 
847     params.pitchStage2       = m_4xDSSurface->dwPitch;
848     params.tileTypeStage2    = m_4xDSSurface->TileType;
849     params.tileModeGmmStage2 = m_4xDSSurface->TileModeGMM;
850     params.gmmTileEnStage2   = m_4xDSSurface->bGMMTileEnabled;
851     params.uOffsetStage2     = m_4xDSSurface->YoffsetForUplane;
852     params.vOffsetStage2     = m_4xDSSurface->YoffsetForVplane;
853     params.heightStage2      = m_4xDSSurface->dwHeight;
854     params.widthStage2       = m_4xDSSurface->dwWidth;
855 
856     return MOS_STATUS_SUCCESS;
857 }
858 
MHW_SETPAR_DECL_SRC(VDENC_CMD2,Vp9BasicFeature)859 MHW_SETPAR_DECL_SRC(VDENC_CMD2, Vp9BasicFeature)
860 {
861     ENCODE_FUNC_CALL();
862 
863     MHW_MI_CHK_NULL(m_vp9PicParams);
864     auto vp9PicParams = m_vp9PicParams;
865     uint8_t frameType = vp9PicParams->PicFlags.fields.frame_type; // frame_type == 1 ? NON_KEY_FRAME : KEY_FRAME
866 
867     MHW_MI_CHK_NULL(m_vp9SeqParams);
868     uint8_t targetUsage = m_vp9SeqParams->TargetUsage;
869 
870     ENCODE_CHK_COND_RETURN(!TargetUsage::isValid(targetUsage), "TargetUsage is invalid");
871 
872     uint32_t lastFrameType = m_prevFrameInfo.KeyFrame; // frame_type == 1 ? NON_KEY_FRAME : KEY_FRAME
873 
874     uint8_t numRefFrames = getNumRefFrames(frameType, m_ref.NumRefFrames());
875 
876     bool segmentationEnabled = vp9PicParams->PicFlags.fields.segmentation_enabled;
877 
878     // DW1
879     params.width  = MOS_ALIGN_CEIL(vp9PicParams->SrcFrameWidthMinus1  + 1, CODEC_VP9_MIN_BLOCK_WIDTH) - 1; // FrameWidthInPixelsMinusOne
880     params.height = MOS_ALIGN_CEIL(vp9PicParams->SrcFrameHeightMinus1 + 1, CODEC_VP9_MIN_BLOCK_WIDTH) - 1; // FrameHeightInPixelsMinusOne
881 
882     // DW2
883     params.transformSkip = 0;
884     params.temporalMvp   = isTemporalMvpEnabled(targetUsage, frameType, lastFrameType, vp9PicParams);
885     params.pictureType   = frameType;
886 
887     // DW3
888     params.pocL1Ref1 = 0; // PocNumberForRefid1InL1
889     params.pocL0Ref1 = 0; // PocNumberForRefid1InL0
890     params.pocL1Ref0 = 0; // BwdPocNumberForRefid0InL1
891     params.pocL0Ref0 = 0; // FwdPocNumberForRefid0InL0
892 
893     // DW4
894     params.pocL1Ref3 = 0; // PocNumberForRefid3InL1
895     params.pocL0Ref3 = 0; // PocNumberForRefid3InL0
896     params.pocL1Ref2 = 0; // PocNumberForRefid2InL1
897     params.pocL0Ref2 = 0; // PocNumberForRefid2InL0
898 
899     // DW5
900     params.numRefL1 = 0;             // NumRefIdxL1Minus1 + 1
901     params.numRefL0 = numRefFrames;  // NumRefIdxL0Minus1 + 1
902 
903     // DW7
904     params.pakOnlyMultiPass     = m_vdencPakonlyMultipassEnabled;
905     params.tiling               = (vp9PicParams->log2_tile_columns != 0) || (vp9PicParams->log2_tile_rows != 0); // TilingEnable
906     params.segmentationTemporal = frameType ? m_prevFrameSegEnabled : 0;                                         // SegmentationMapTemporalPredictionEnable
907     params.segmentation         = segmentationEnabled;                                                           // SegmentationEnable
908 
909     // DW16
910     params.maxQp = 0xff; // MaxQp
911     params.minQp = 0;    // MinQp
912 
913     // DW17
914     params.temporalMvEnableForIntegerSearch = params.temporalMvp; // TemporalMVEnableForIntegerSearch
915 
916     // DW21
917     params.qpAdjustmentForRollingI  = 0;
918     params.intraRefresh             = 0;
919     params.intraRefreshMbSizeMinus1 = 1;
920 
921     // DW26
922     params.vp9DynamicSlice = ((m_ref.DysRefFrameFlags() != DYS_REF_NONE) && !m_dysVdencMultiPassEnabled);
923 
924     // DW27
925     params.qpPrimeYAc = vp9PicParams->LumaACQIndex;
926     params.qpPrimeYDc = params.qpPrimeYAc + vp9PicParams->LumaDCQIndexDelta;
927 
928     // DW61
929     params.av1RefId[0][0] = 0;
930     params.av1RefId[0][1] = 0;
931     params.av1RefId[0][2] = 0;
932     params.av1RefId[0][3] = 0;
933     params.av1RefId[1][0] = 0;
934     params.av1RefId[1][1] = 0;
935     params.av1RefId[1][2] = 0;
936     params.av1RefId[1][3] = 0;
937 
938     auto settings = static_cast<Vp9VdencFeatureSettings *>(m_constSettings);
939     ENCODE_CHK_NULL_RETURN(settings);
940 
941     for (const auto &lambda : settings->vdencCmd2Settings)
942     {
943         ENCODE_CHK_STATUS_RETURN(lambda(params, false));
944     }
945 
946     return MOS_STATUS_SUCCESS;
947 }
948 
MHW_SETPAR_DECL_SRC(VDENC_PIPE_MODE_SELECT,Vp9BasicFeature)949 MHW_SETPAR_DECL_SRC(VDENC_PIPE_MODE_SELECT, Vp9BasicFeature)
950 {
951     ENCODE_FUNC_CALL();
952 
953     MHW_MI_CHK_NULL(m_vp9SeqParams);
954 
955     // DW1
956 
957     params.chromaType = m_vp9SeqParams->SeqFlags.fields.EncodedFormat + 1;
958 
959     params.bitDepthMinus8 = 0;
960     if (m_vp9SeqParams->SeqFlags.fields.EncodedBitDepth == VP9_ENCODED_BIT_DEPTH_10)
961     {
962         params.bitDepthMinus8 = 2;
963     }
964 
965     return MOS_STATUS_SUCCESS;
966 }
967 
MHW_SETPAR_DECL_SRC(VDENC_PIPE_BUF_ADDR_STATE,Vp9BasicFeature)968 MHW_SETPAR_DECL_SRC(VDENC_PIPE_BUF_ADDR_STATE, Vp9BasicFeature)
969 {
970     ENCODE_FUNC_CALL();
971 
972     params.surfaceRaw      = m_rawSurfaceToPak;
973     params.surfaceDsStage1 = m_8xDSSurface;
974     params.surfaceDsStage2 = m_4xDSSurface;
975 
976     params.streamInBuffer  = m_recycleBuf->GetBuffer(RecycleResId::StreamInBuffer, m_frameNum);
977 
978 #ifdef _MMC_SUPPORTED
979     ENCODE_CHK_NULL_RETURN(m_mmcState);
980 
981     if (m_mmcState->IsMmcEnabled())
982     {
983         params.mmcEnabled = true;
984         ENCODE_CHK_STATUS_RETURN(m_mmcState->GetSurfaceMmcState(const_cast<PMOS_SURFACE>(&m_rawSurface), &params.mmcStateRaw));
985     }
986     else
987     {
988         params.mmcEnabled = false;
989         params.mmcStateRaw         = MOS_MEMCOMP_DISABLED;
990     }
991 #endif
992 
993     return MOS_STATUS_SUCCESS;
994 }
995 
MHW_SETPAR_DECL_SRC(MFX_WAIT,Vp9BasicFeature)996 MHW_SETPAR_DECL_SRC(MFX_WAIT, Vp9BasicFeature)
997 {
998     ENCODE_FUNC_CALL();
999 
1000     params.iStallVdboxPipeline = true;
1001 
1002     return MOS_STATUS_SUCCESS;
1003 }
1004 
MHW_SETPAR_DECL_SRC(MFX_PIPE_MODE_SELECT,Vp9BasicFeature)1005 MHW_SETPAR_DECL_SRC(MFX_PIPE_MODE_SELECT, Vp9BasicFeature)
1006 {
1007     ENCODE_FUNC_CALL();
1008 
1009     params.decoderShortFormatMode = 1;
1010 
1011     if (m_decodeInUse)
1012     {
1013         params.Mode        = CODECHAL_DECODE_MODE_AVCVLD;
1014         params.codecSelect = decoderCodec;
1015     }
1016     else
1017     {
1018         params.Mode                           = m_mode;
1019         params.codecSelect                    = encoderCodec;
1020         params.vdencMode                      = 1;
1021         params.scaledSurfaceEnable            = true;
1022         params.frameStatisticsStreamoutEnable = true;
1023     }
1024 
1025     params.standardSelect = CodecHal_GetStandardFromMode(params.Mode);
1026 
1027     return MOS_STATUS_SUCCESS;
1028 }
1029 
1030 }  // namespace encode
1031