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), ¶ms.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