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_reference_frames.cpp
24 //! \brief Defines reference list related logic for encode vp9
25 //!
26
27 #include "encode_vp9_reference_frames.h"
28 #include "encode_utils.h"
29 #include "encode_vp9_basic_feature.h"
30 #include "encode_vp9_vdenc_pipeline.h"
31
32 namespace encode
33 {
~Vp9ReferenceFrames()34 Vp9ReferenceFrames::~Vp9ReferenceFrames()
35 {
36 ENCODE_FUNC_CALL();
37
38 EncodeFreeDataList(m_refList, CODECHAL_NUM_UNCOMPRESSED_SURFACE_VP9);
39 }
40
Init(Vp9BasicFeature * basicFeature)41 MOS_STATUS Vp9ReferenceFrames::Init(Vp9BasicFeature *basicFeature)
42 {
43 ENCODE_FUNC_CALL();
44 ENCODE_CHK_NULL_RETURN(basicFeature);
45
46 m_basicFeature = basicFeature;
47 ENCODE_CHK_STATUS_RETURN(EncodeAllocateDataList(
48 m_refList,
49 CODECHAL_NUM_UNCOMPRESSED_SURFACE_VP9));
50
51 return MOS_STATUS_SUCCESS;
52 }
53
Update()54 MOS_STATUS Vp9ReferenceFrames::Update()
55 {
56 ENCODE_FUNC_CALL();
57
58 // initialize internal structures for current frame before set up
59
60 // m_refFrameFlags is to indicate which frames to be used as reference
61 // m_refFrameFlags & 0x01 != 0: Last ref frames used as reference
62 // m_refFrameFlags & 0x02 != 0: Golden ref frames used as reference
63 // m_refFrameFlags & 0x04 != 0: Alternate ref frames used as reference
64 m_refFrameFlags = 0;
65 m_numRefFrames = 0;
66 m_lastRefPic = nullptr;
67 m_goldenRefPic = nullptr;
68 m_altRefPic = nullptr;
69
70 m_dysRefFrameFlags = DYS_REF_NONE;
71 m_currDysRefList = nullptr;
72 m_dysRefIndex = 0;
73
74 for (auto i = 0; i < CODEC_VP9_NUM_REF_FRAMES; ++i)
75 {
76 m_picIdx[i].bValid = false;
77 }
78
79 auto picParams = m_basicFeature->m_vp9PicParams;
80 ENCODE_CHK_NULL_RETURN(picParams);
81
82 // Save current frame information into m_refList
83 auto currRefIdx = picParams->CurrReconstructedPic.FrameIdx;
84 m_currRefList = m_refList[currRefIdx];
85
86 m_currRefList->sRefReconBuffer = m_basicFeature->m_reconSurface;
87 m_currRefList->sRefRawBuffer = m_basicFeature->m_rawSurface;
88 m_currRefList->RefPic = picParams->CurrReconstructedPic;
89 m_currRefList->bUsedAsRef = true;
90 m_currRefList->resBitstreamBuffer = m_basicFeature->m_resBitstreamBuffer;
91 m_currRefList->dwFrameWidth = m_basicFeature->m_oriFrameWidth;
92 m_currRefList->dwFrameHeight = m_basicFeature->m_oriFrameHeight;
93 // m_currRefList->ucScalingIdx also is one critical index,
94 // It used to associate temperal mv buffer, down scaling surfaces.
95 // It will be set in m_trackBuf->Acquire(...).
96
97 // Setup reference related structures.
98 if ((picParams->PicFlags.fields.frame_type != 0) && !picParams->PicFlags.fields.intra_only)
99 {
100 ENCODE_CHK_STATUS_RETURN(SetupRefFlags()); // setup m_refFrameFlags
101 ENCODE_CHK_STATUS_RETURN(SetupRefPic()); // setup reference pictures (m_lastRefPic, m_goldenRefPic, m_altRefPic
102 ENCODE_CHK_STATUS_RETURN(SetupRefIndex()); // setup m_picIdx
103 }
104 m_dysCurrFrameFlag = m_dysRefFrameFlags;
105 ENCODE_CHK_STATUS_RETURN(SetupDysRefPic()); // setup dynamic scaling reference picture
106
107 // Save the RefFrameList for current frame
108 uint8_t ii = 0;
109 for (auto i = 0; i < CODEC_VP9_NUM_REF_FRAMES; ++i)
110 {
111 if (m_picIdx[i].bValid)
112 {
113 m_currRefList->RefList[ii] = picParams->RefFrameList[i];
114 ii++;
115 }
116 }
117 m_currRefList->ucNumRef = ii;
118
119 // In case there is overflow
120 if ((picParams->LumaACQIndex + picParams->LumaDCQIndexDelta) < 0)
121 {
122 picParams->LumaACQIndex = MOS_ABS(picParams->LumaDCQIndexDelta) + 1;
123 }
124 m_currRefList->ucQPValue[0] = picParams->LumaACQIndex + picParams->LumaDCQIndexDelta;
125
126 return MOS_STATUS_SUCCESS;
127 }
128
SetHcpSurfaceParams(MHW_VDBOX_SURFACE_PARAMS * surfaceParams)129 MOS_STATUS Vp9ReferenceFrames::SetHcpSurfaceParams(MHW_VDBOX_SURFACE_PARAMS *surfaceParams)
130 {
131 ENCODE_FUNC_CALL();
132 ENCODE_CHK_NULL_RETURN(surfaceParams);
133 ENCODE_CHK_NULL_RETURN(m_basicFeature);
134
135 // For PAK engine, we do NOT use scaled reference images even if dynamic scaling is enabled
136 for (auto i = 0; i < maxReferenceIds; ++i)
137 {
138 m_refSurface[i] = m_refSurfaceNonScaled[i] = m_dsRefSurface4x[i] = m_dsRefSurface8x[i] = nullptr;
139 }
140
141 if (m_basicFeature->m_pictureCodingType == I_TYPE)
142 {
143 return MOS_STATUS_SUCCESS;
144 }
145
146 auto trackedBuf = m_basicFeature->m_trackedBuf;
147 ENCODE_CHK_NULL_RETURN(trackedBuf);
148 auto allocator = m_basicFeature->GetAllocator();
149 ENCODE_CHK_NULL_RETURN(allocator);
150 auto picParams = m_basicFeature->m_vp9PicParams;
151 ENCODE_CHK_NULL_RETURN(picParams);
152
153 if (m_refFrameFlags & 0x01)
154 {
155 auto refPicIdx = picParams->RefFlags.fields.LastRefIdx;
156 ENCODE_ASSERT((refPicIdx < CODEC_VP9_NUM_REF_FRAMES) &&
157 (!CodecHal_PictureIsInvalid(picParams->RefFrameList[refPicIdx])));
158
159 auto frameIdx = picParams->RefFrameList[refPicIdx].FrameIdx;
160
161 m_refSurfaceNonScaled[lastFrame] = &(m_refList[frameIdx]->sRefBuffer);
162 m_refSurface[lastFrame] =
163 (m_dysRefFrameFlags & DYS_REF_LAST) ? &(m_refList[frameIdx]->sDysSurface)
164 : m_refSurfaceNonScaled[lastFrame];
165
166 auto scalingIdx = m_refList[frameIdx]->ucScalingIdx;
167 ENCODE_CHK_STATUS_RETURN(m_basicFeature->Resize4x8xforDS(scalingIdx));
168
169 m_dsRefSurface4x[lastFrame] = trackedBuf->GetSurface(BufferType::ds4xSurface, scalingIdx);
170 ENCODE_CHK_NULL_RETURN(m_dsRefSurface4x[lastFrame]);
171 ENCODE_CHK_STATUS_RETURN(allocator->GetSurfaceInfo(m_dsRefSurface4x[lastFrame]));
172
173 m_dsRefSurface8x[lastFrame] = trackedBuf->GetSurface(BufferType::ds8xSurface, scalingIdx);
174 ENCODE_CHK_NULL_RETURN(m_dsRefSurface8x[lastFrame]);
175 ENCODE_CHK_STATUS_RETURN(allocator->GetSurfaceInfo(m_dsRefSurface8x[lastFrame]));
176 }
177
178 if (m_refFrameFlags & 0x02)
179 {
180 auto refPicIdx = picParams->RefFlags.fields.GoldenRefIdx;
181 ENCODE_ASSERT((refPicIdx < CODEC_VP9_NUM_REF_FRAMES) &&
182 (!CodecHal_PictureIsInvalid(picParams->RefFrameList[refPicIdx])));
183
184 auto frameIdx = picParams->RefFrameList[refPicIdx].FrameIdx;
185
186 m_refSurfaceNonScaled[goldenFrame] = &(m_refList[frameIdx]->sRefBuffer);
187 m_refSurface[goldenFrame] =
188 (m_dysRefFrameFlags & DYS_REF_GOLDEN) ? &(m_refList[frameIdx]->sDysSurface)
189 : m_refSurfaceNonScaled[goldenFrame];
190
191 auto scalingIdx = m_refList[frameIdx]->ucScalingIdx;
192 ENCODE_CHK_STATUS_RETURN(m_basicFeature->Resize4x8xforDS(scalingIdx));
193
194 m_dsRefSurface4x[goldenFrame] = trackedBuf->GetSurface(BufferType::ds4xSurface, scalingIdx);
195 ENCODE_CHK_NULL_RETURN(m_dsRefSurface4x[goldenFrame]);
196 ENCODE_CHK_STATUS_RETURN(allocator->GetSurfaceInfo(m_dsRefSurface4x[goldenFrame]));
197
198 m_dsRefSurface8x[goldenFrame] = trackedBuf->GetSurface(BufferType::ds8xSurface, scalingIdx);
199 ENCODE_CHK_NULL_RETURN(m_dsRefSurface8x[goldenFrame]);
200 ENCODE_CHK_STATUS_RETURN(allocator->GetSurfaceInfo(m_dsRefSurface8x[goldenFrame]));
201 }
202
203 if (m_refFrameFlags & 0x04)
204 {
205 auto refPicIdx = picParams->RefFlags.fields.AltRefIdx;
206 ENCODE_ASSERT((refPicIdx < CODEC_VP9_NUM_REF_FRAMES) &&
207 (!CodecHal_PictureIsInvalid(picParams->RefFrameList[refPicIdx])));
208
209 auto frameIdx = picParams->RefFrameList[refPicIdx].FrameIdx;
210
211 m_refSurfaceNonScaled[altFrame] = &(m_refList[frameIdx]->sRefBuffer);
212 m_refSurface[altFrame] =
213 (m_dysRefFrameFlags & DYS_REF_ALT) ? &(m_refList[frameIdx]->sDysSurface)
214 : m_refSurfaceNonScaled[altFrame];
215
216 auto scalingIdx = m_refList[frameIdx]->ucScalingIdx;
217 ENCODE_CHK_STATUS_RETURN(m_basicFeature->Resize4x8xforDS(scalingIdx));
218
219 m_dsRefSurface4x[altFrame] = trackedBuf->GetSurface(BufferType::ds4xSurface, scalingIdx);
220 ENCODE_CHK_NULL_RETURN(m_dsRefSurface4x[altFrame]);
221 ENCODE_CHK_STATUS_RETURN(allocator->GetSurfaceInfo(m_dsRefSurface4x[altFrame]));
222
223 m_dsRefSurface8x[altFrame] = trackedBuf->GetSurface(BufferType::ds8xSurface, scalingIdx);
224 ENCODE_CHK_NULL_RETURN(m_dsRefSurface8x[altFrame]);
225 ENCODE_CHK_STATUS_RETURN(allocator->GetSurfaceInfo(m_dsRefSurface8x[altFrame]));
226 }
227
228 if (!m_refSurface[lastFrame])
229 {
230 m_refSurface[lastFrame] = (m_refSurface[goldenFrame]) ? m_refSurface[goldenFrame]
231 : m_refSurface[altFrame];
232
233 m_refSurfaceNonScaled[lastFrame] = (m_refSurfaceNonScaled[goldenFrame]) ? m_refSurfaceNonScaled[goldenFrame]
234 : m_refSurfaceNonScaled[altFrame];
235
236 m_dsRefSurface4x[lastFrame] = (m_dsRefSurface4x[goldenFrame]) ? m_dsRefSurface4x[goldenFrame]
237 : m_dsRefSurface4x[altFrame];
238
239 m_dsRefSurface8x[lastFrame] = (m_dsRefSurface8x[goldenFrame]) ? m_dsRefSurface8x[goldenFrame]
240 : m_dsRefSurface8x[altFrame];
241 }
242
243 if (!m_refSurface[goldenFrame])
244 {
245 m_refSurface[goldenFrame] = (m_refSurface[lastFrame]) ? m_refSurface[lastFrame]
246 : m_refSurface[altFrame];
247
248 m_refSurfaceNonScaled[goldenFrame] = (m_refSurfaceNonScaled[lastFrame]) ? m_refSurfaceNonScaled[lastFrame]
249 : m_refSurfaceNonScaled[altFrame];
250
251 m_dsRefSurface4x[goldenFrame] = (m_dsRefSurface4x[lastFrame]) ? m_dsRefSurface4x[lastFrame]
252 : m_dsRefSurface4x[altFrame];
253
254 m_dsRefSurface8x[goldenFrame] = (m_dsRefSurface8x[lastFrame]) ? m_dsRefSurface8x[lastFrame]
255 : m_dsRefSurface8x[altFrame];
256 }
257
258 if (!m_refSurface[altFrame])
259 {
260 m_refSurface[altFrame] = (m_refSurface[lastFrame]) ? m_refSurface[lastFrame]
261 : m_refSurface[goldenFrame];
262
263 m_refSurfaceNonScaled[altFrame] = (m_refSurfaceNonScaled[lastFrame]) ? m_refSurfaceNonScaled[lastFrame]
264 : m_refSurfaceNonScaled[goldenFrame];
265
266 m_dsRefSurface4x[altFrame] = (m_dsRefSurface4x[lastFrame]) ? m_dsRefSurface4x[lastFrame]
267 : m_dsRefSurface4x[goldenFrame];
268
269 m_dsRefSurface8x[altFrame] = (m_dsRefSurface8x[lastFrame]) ? m_dsRefSurface8x[lastFrame]
270 : m_dsRefSurface8x[goldenFrame];
271 }
272
273 // Program Surface params for Reference surfaces
274 if ((m_dysRefFrameFlags != DYS_REF_NONE) && !m_basicFeature->m_dysVdencMultiPassEnabled)
275 {
276 surfaceParams[CODECHAL_HCP_LAST_SURFACE_ID].psSurface = m_refSurfaceNonScaled[lastFrame];
277 surfaceParams[CODECHAL_HCP_LAST_SURFACE_ID].bVdencDynamicScaling = true;
278
279 surfaceParams[CODECHAL_HCP_GOLDEN_SURFACE_ID].psSurface = m_refSurfaceNonScaled[goldenFrame];
280 surfaceParams[CODECHAL_HCP_GOLDEN_SURFACE_ID].bVdencDynamicScaling = true;
281
282 surfaceParams[CODECHAL_HCP_ALTREF_SURFACE_ID].psSurface = m_refSurfaceNonScaled[altFrame];
283 surfaceParams[CODECHAL_HCP_ALTREF_SURFACE_ID].bVdencDynamicScaling = true;
284 }
285 else
286 {
287 surfaceParams[CODECHAL_HCP_LAST_SURFACE_ID].psSurface = m_refSurface[lastFrame];
288 surfaceParams[CODECHAL_HCP_GOLDEN_SURFACE_ID].psSurface = m_refSurface[goldenFrame];
289 surfaceParams[CODECHAL_HCP_ALTREF_SURFACE_ID].psSurface = m_refSurface[altFrame];
290 }
291
292 if (m_dysCurrFrameFlag)
293 {
294 if (m_basicFeature->m_dysVdencMultiPassEnabled)
295 {
296 surfaceParams[CODECHAL_HCP_LAST_SURFACE_ID].dwReconSurfHeight =
297 MOS_ALIGN_CEIL(
298 (m_refSurface[lastFrame] ? m_refSurface[lastFrame]->dwHeight : 0),
299 CODEC_VP9_MIN_BLOCK_WIDTH);
300
301 surfaceParams[CODECHAL_HCP_GOLDEN_SURFACE_ID].dwReconSurfHeight =
302 MOS_ALIGN_CEIL(
303 (m_refSurface[goldenFrame] ? m_refSurface[goldenFrame]->dwHeight : 0),
304 CODEC_VP9_MIN_BLOCK_WIDTH);
305
306 surfaceParams[CODECHAL_HCP_ALTREF_SURFACE_ID].dwReconSurfHeight =
307 MOS_ALIGN_CEIL(
308 (m_refSurface[altFrame] ? m_refSurface[altFrame]->dwHeight : 0),
309 CODEC_VP9_MIN_BLOCK_WIDTH);
310 }
311 else
312 {
313 surfaceParams[CODECHAL_HCP_LAST_SURFACE_ID].dwReconSurfHeight =
314 MOS_ALIGN_CEIL(
315 (m_refSurfaceNonScaled[lastFrame] ? m_refSurfaceNonScaled[lastFrame]->dwHeight : 0),
316 CODEC_VP9_MIN_BLOCK_WIDTH);
317
318 surfaceParams[CODECHAL_HCP_GOLDEN_SURFACE_ID].dwReconSurfHeight =
319 MOS_ALIGN_CEIL((m_refSurfaceNonScaled[goldenFrame] ? m_refSurfaceNonScaled[goldenFrame]->dwHeight : 0),
320 CODEC_VP9_MIN_BLOCK_WIDTH);
321
322 surfaceParams[CODECHAL_HCP_ALTREF_SURFACE_ID].dwReconSurfHeight =
323 MOS_ALIGN_CEIL((m_refSurfaceNonScaled[altFrame] ? m_refSurfaceNonScaled[altFrame]->dwHeight : 0),
324 CODEC_VP9_MIN_BLOCK_WIDTH);
325 }
326 }
327 else
328 {
329 surfaceParams[CODECHAL_HCP_LAST_SURFACE_ID].dwReconSurfHeight =
330 surfaceParams[CODECHAL_HCP_GOLDEN_SURFACE_ID].dwReconSurfHeight =
331 surfaceParams[CODECHAL_HCP_ALTREF_SURFACE_ID].dwReconSurfHeight = m_basicFeature->m_rawSurfaceToPak->dwHeight;
332 }
333
334 return MOS_STATUS_SUCCESS;
335 }
336
SetDysHcpSurfaceParams(MHW_VDBOX_SURFACE_PARAMS * surfaceParams)337 MOS_STATUS Vp9ReferenceFrames::SetDysHcpSurfaceParams(MHW_VDBOX_SURFACE_PARAMS *surfaceParams)
338 {
339 ENCODE_FUNC_CALL();
340 ENCODE_CHK_NULL_RETURN(surfaceParams);
341 ENCODE_CHK_NULL_RETURN(m_basicFeature);
342
343 // For PAK engine, we do NOT use scaled reference images even if dynamic scaling is enabled
344 for (auto i = 0; i < maxReferenceIds; ++i)
345 {
346 m_dysRefSurface[i] = nullptr;
347 }
348
349 if (m_basicFeature->m_pictureCodingType == I_TYPE)
350 {
351 return MOS_STATUS_SUCCESS;
352 }
353
354 auto picParams = m_basicFeature->m_vp9PicParams;
355 ENCODE_CHK_NULL_RETURN(picParams);
356
357 if (m_refFrameFlags & 0x01)
358 {
359 auto refPicIdx = picParams->RefFlags.fields.LastRefIdx;
360 ENCODE_ASSERT((refPicIdx < CODEC_VP9_NUM_REF_FRAMES) &&
361 (!CodecHal_PictureIsInvalid(picParams->RefFrameList[refPicIdx])));
362
363 auto frameIdx = picParams->RefFrameList[refPicIdx].FrameIdx;
364
365 m_dysRefSurface[lastFrame] = &(m_refList[frameIdx]->sRefBuffer);
366 }
367
368 if (m_refFrameFlags & 0x02)
369 {
370 auto refPicIdx = picParams->RefFlags.fields.GoldenRefIdx;
371 ENCODE_ASSERT((refPicIdx < CODEC_VP9_NUM_REF_FRAMES) &&
372 (!CodecHal_PictureIsInvalid(picParams->RefFrameList[refPicIdx])));
373
374 auto frameIdx = picParams->RefFrameList[refPicIdx].FrameIdx;
375
376 m_dysRefSurface[goldenFrame] = &(m_refList[frameIdx]->sRefBuffer);
377 }
378
379 if (m_refFrameFlags & 0x04)
380 {
381 auto refPicIdx = picParams->RefFlags.fields.AltRefIdx;
382 ENCODE_ASSERT((refPicIdx < CODEC_VP9_NUM_REF_FRAMES) &&
383 (!CodecHal_PictureIsInvalid(picParams->RefFrameList[refPicIdx])));
384
385 auto frameIdx = picParams->RefFrameList[refPicIdx].FrameIdx;
386
387 m_dysRefSurface[altFrame] = &(m_refList[frameIdx]->sRefBuffer);
388 }
389
390 if (!m_dysRefSurface[lastFrame])
391 {
392 m_dysRefSurface[lastFrame] = (m_dysRefSurface[goldenFrame]) ? m_dysRefSurface[goldenFrame]
393 : m_dysRefSurface[altFrame];
394 }
395
396 if (!m_dysRefSurface[goldenFrame])
397 {
398 m_dysRefSurface[goldenFrame] = (m_dysRefSurface[lastFrame]) ? m_dysRefSurface[lastFrame]
399 : m_dysRefSurface[altFrame];
400 }
401
402 if (!m_dysRefSurface[altFrame])
403 {
404 m_dysRefSurface[altFrame] = (m_dysRefSurface[lastFrame]) ? m_dysRefSurface[lastFrame]
405 : m_dysRefSurface[goldenFrame];
406 }
407
408 // Program Surface params for Last/Golden/Al Reference surfaces
409 surfaceParams[CODECHAL_HCP_LAST_SURFACE_ID].psSurface = m_dysRefSurface[lastFrame];
410 surfaceParams[CODECHAL_HCP_GOLDEN_SURFACE_ID].psSurface = m_dysRefSurface[goldenFrame];
411 surfaceParams[CODECHAL_HCP_ALTREF_SURFACE_ID].psSurface = m_dysRefSurface[altFrame];
412
413 surfaceParams[CODECHAL_HCP_LAST_SURFACE_ID].dwReconSurfHeight =
414 MOS_ALIGN_CEIL((m_dysRefSurface[lastFrame] ? m_dysRefSurface[lastFrame]->dwHeight : 0),
415 CODEC_VP9_MIN_BLOCK_WIDTH);
416
417 surfaceParams[CODECHAL_HCP_GOLDEN_SURFACE_ID].dwReconSurfHeight =
418 MOS_ALIGN_CEIL((m_dysRefSurface[goldenFrame] ? m_dysRefSurface[goldenFrame]->dwHeight : 0),
419 CODEC_VP9_MIN_BLOCK_WIDTH);
420
421 surfaceParams[CODECHAL_HCP_ALTREF_SURFACE_ID].dwReconSurfHeight =
422 MOS_ALIGN_CEIL((m_dysRefSurface[altFrame] ? m_dysRefSurface[altFrame]->dwHeight : 0),
423 CODEC_VP9_MIN_BLOCK_WIDTH);
424
425 return MOS_STATUS_SUCCESS;
426 }
427
SetDysHcpPipeBufAddrParams(MHW_VDBOX_PIPE_BUF_ADDR_PARAMS * pipeBufAddrParams)428 MOS_STATUS Vp9ReferenceFrames::SetDysHcpPipeBufAddrParams(MHW_VDBOX_PIPE_BUF_ADDR_PARAMS *pipeBufAddrParams)
429 {
430 ENCODE_FUNC_CALL();
431
432 ENCODE_CHK_NULL_RETURN(pipeBufAddrParams);
433 ENCODE_CHK_NULL_RETURN(m_basicFeature);
434 auto trackedBuf = m_basicFeature->m_trackedBuf;
435 ENCODE_CHK_NULL_RETURN(trackedBuf);
436
437 if (m_basicFeature->m_pictureCodingType != I_TYPE)
438 {
439 for (auto i = 0; i < maxReferenceIds; ++i)
440 {
441 ENCODE_CHK_NULL_RETURN(m_dysRefSurface[i]);
442
443 pipeBufAddrParams->presReferences[i] = &m_dysRefSurface[i]->OsResource;
444 }
445
446 pipeBufAddrParams->presColMvTempBuffer[0] =
447 trackedBuf->GetBuffer(
448 BufferType::mvTemporalBuffer,
449 m_basicFeature->m_lastMvTemporalBufferIndex);
450 }
451
452 return MOS_STATUS_SUCCESS;
453 }
454
SetVdencSurfaceParams(MHW_VDBOX_SURFACE_PARAMS * surfaceParams)455 MOS_STATUS Vp9ReferenceFrames::SetVdencSurfaceParams(MHW_VDBOX_SURFACE_PARAMS *surfaceParams)
456 {
457 ENCODE_FUNC_CALL();
458
459 // Change ref surfaces to scaled for VDENC for DYS
460 if ((m_dysRefFrameFlags != DYS_REF_NONE) && !m_basicFeature->m_dysVdencMultiPassEnabled)
461 {
462 surfaceParams[CODECHAL_HCP_LAST_SURFACE_ID].psSurface = m_refSurface[lastFrame];
463 surfaceParams[CODECHAL_HCP_GOLDEN_SURFACE_ID].psSurface = m_refSurface[goldenFrame];
464 surfaceParams[CODECHAL_HCP_ALTREF_SURFACE_ID].psSurface = m_refSurface[altFrame];
465 }
466
467 return MOS_STATUS_SUCCESS;
468 }
469
SetVdencPipeBufAddrParams(MHW_VDBOX_PIPE_BUF_ADDR_PARAMS * pipeBufAddrParams)470 MOS_STATUS Vp9ReferenceFrames::SetVdencPipeBufAddrParams(MHW_VDBOX_PIPE_BUF_ADDR_PARAMS *pipeBufAddrParams)
471 {
472 ENCODE_FUNC_CALL();
473
474 ENCODE_CHK_NULL_RETURN(pipeBufAddrParams);
475 ENCODE_CHK_NULL_RETURN(m_basicFeature);
476 auto trackedBuf = m_basicFeature->m_trackedBuf;
477 ENCODE_CHK_NULL_RETURN(trackedBuf);
478
479 pipeBufAddrParams->bDynamicScalingEnable = (m_dysRefFrameFlags != DYS_REF_NONE) && !m_basicFeature->m_dysVdencMultiPassEnabled;
480 pipeBufAddrParams->dwNumRefIdxL0ActiveMinus1 = (m_basicFeature->m_vp9PicParams->PicFlags.fields.frame_type) ? m_numRefFrames - 1 : 0;
481 pipeBufAddrParams->dwNumRefIdxL1ActiveMinus1 = 0;
482
483 return MOS_STATUS_SUCCESS;
484 }
485
SetupRefFlags()486 MOS_STATUS Vp9ReferenceFrames::SetupRefFlags()
487 {
488 ENCODE_FUNC_CALL();
489
490 auto picParams = m_basicFeature->m_vp9PicParams;
491 ENCODE_CHK_NULL_RETURN(picParams);
492
493 auto lastRefIdx = picParams->RefFlags.fields.LastRefIdx;
494 auto goldenRefIdx = picParams->RefFlags.fields.GoldenRefIdx;
495 auto altRefIdx = picParams->RefFlags.fields.AltRefIdx;
496
497 m_refFrameFlags = picParams->RefFlags.fields.ref_frame_ctrl_l0 | picParams->RefFlags.fields.ref_frame_ctrl_l1;
498
499 if (CodecHal_PictureIsInvalid(picParams->RefFrameList[lastRefIdx]))
500 {
501 m_refFrameFlags &= ~0x1;
502 }
503 if (CodecHal_PictureIsInvalid(picParams->RefFrameList[goldenRefIdx]))
504 {
505 m_refFrameFlags &= ~0x2;
506 }
507 if (CodecHal_PictureIsInvalid(picParams->RefFrameList[altRefIdx]))
508 {
509 m_refFrameFlags &= ~0x4;
510 }
511
512 // Consolidate the reference flag, because two reference frame may have the same index
513 if ((m_refFrameFlags & 0x01) &&
514 (picParams->RefFrameList[lastRefIdx].FrameIdx == picParams->RefFrameList[altRefIdx].FrameIdx))
515 {
516 m_refFrameFlags &= ~0x4; // Skip alt frame
517 }
518 if ((m_refFrameFlags & 0x02) &&
519 (picParams->RefFrameList[goldenRefIdx].FrameIdx == picParams->RefFrameList[altRefIdx].FrameIdx))
520 {
521 m_refFrameFlags &= ~0x4; // Skip alt frame
522 }
523
524 if (m_refFrameFlags == 7 && !m_basicFeature->m_16xMeSupported)
525 {
526 // Can support max 2 reference frames when SHME disabled, so ignore alt frame
527 m_refFrameFlags &= ~0x4;
528 }
529
530 // Max number of reference is 1 for TU7
531 if (m_refFrameFlags != 1 && TargetUsage::isSpeed(m_basicFeature->m_vp9SeqParams->TargetUsage))
532 {
533 m_refFrameFlags = 1;
534 }
535
536 if (m_refFrameFlags == 0)
537 {
538 ENCODE_ASSERTMESSAGE("Ref list is empty!");
539 return MOS_STATUS_INVALID_PARAMETER;
540 }
541
542 return MOS_STATUS_SUCCESS;
543 }
544
SetupRefPic()545 MOS_STATUS Vp9ReferenceFrames::SetupRefPic()
546 {
547 ENCODE_FUNC_CALL();
548
549 auto allocator = m_basicFeature->GetAllocator();
550 ENCODE_CHK_NULL_RETURN(allocator);
551
552 auto picParams = m_basicFeature->m_vp9PicParams;
553 ENCODE_CHK_NULL_RETURN(picParams);
554 auto seqParams = m_basicFeature->m_vp9SeqParams;
555 ENCODE_CHK_NULL_RETURN(seqParams);
556
557 // Last reference frame
558 if (m_refFrameFlags & 0x01)
559 {
560 auto refIdx = picParams->RefFlags.fields.LastRefIdx;
561 auto index = picParams->RefFrameList[refIdx].FrameIdx;
562
563 m_refList[index]->sRefBuffer =
564 seqParams->SeqFlags.fields.bUseRawReconRef ? m_refList[index]->sRefRawBuffer
565 : m_refList[index]->sRefReconBuffer;
566
567 m_lastRefPic = &m_refList[index]->sRefBuffer;
568 ENCODE_CHK_STATUS_RETURN(allocator->GetSurfaceInfo(m_lastRefPic));
569 m_lastRefPic->dwWidth = m_refList[index]->dwFrameWidth;
570 m_lastRefPic->dwHeight = m_refList[index]->dwFrameHeight;
571 m_numRefFrames++;
572
573 if (seqParams->SeqFlags.fields.EnableDynamicScaling &&
574 ((m_refList[index]->dwFrameWidth != m_basicFeature->m_oriFrameWidth) ||
575 (m_refList[index]->dwFrameHeight != m_basicFeature->m_oriFrameHeight)))
576 {
577 m_dysRefFrameFlags |= DYS_REF_LAST;
578 }
579 }
580
581 // Golden reference frame
582 if (m_refFrameFlags & 0x02)
583 {
584 auto refIdx = picParams->RefFlags.fields.GoldenRefIdx;
585 auto index = picParams->RefFrameList[refIdx].FrameIdx;
586
587 m_refList[index]->sRefBuffer =
588 seqParams->SeqFlags.fields.bUseRawReconRef ? m_refList[index]->sRefRawBuffer
589 : m_refList[index]->sRefReconBuffer;
590
591 m_goldenRefPic = &m_refList[index]->sRefBuffer;
592 ENCODE_CHK_STATUS_RETURN(allocator->GetSurfaceInfo(m_goldenRefPic));
593 m_goldenRefPic->dwWidth = m_refList[index]->dwFrameWidth;
594 m_goldenRefPic->dwHeight = m_refList[index]->dwFrameHeight;
595 m_numRefFrames++;
596
597 if (seqParams->SeqFlags.fields.EnableDynamicScaling &&
598 ((m_refList[index]->dwFrameWidth != m_basicFeature->m_oriFrameWidth) ||
599 (m_refList[index]->dwFrameHeight != m_basicFeature->m_oriFrameHeight)))
600 {
601 m_dysRefFrameFlags |= DYS_REF_GOLDEN;
602 }
603 }
604
605 // Alter reference frame
606 if (m_refFrameFlags & 0x04)
607 {
608 auto refIdx = picParams->RefFlags.fields.AltRefIdx;
609 auto index = picParams->RefFrameList[refIdx].FrameIdx;
610
611 m_refList[index]->sRefBuffer =
612 seqParams->SeqFlags.fields.bUseRawReconRef ? m_refList[index]->sRefRawBuffer
613 : m_refList[index]->sRefReconBuffer;
614
615 m_altRefPic = &m_refList[index]->sRefBuffer;
616 ENCODE_CHK_STATUS_RETURN(allocator->GetSurfaceInfo(m_altRefPic));
617 m_altRefPic->dwWidth = m_refList[index]->dwFrameWidth;
618 m_altRefPic->dwHeight = m_refList[index]->dwFrameHeight;
619 m_numRefFrames++;
620
621 if (seqParams->SeqFlags.fields.EnableDynamicScaling &&
622 ((m_refList[index]->dwFrameWidth != m_basicFeature->m_oriFrameWidth) ||
623 (m_refList[index]->dwFrameHeight != m_basicFeature->m_oriFrameHeight)))
624 {
625 m_dysRefFrameFlags |= DYS_REF_ALT;
626 }
627 }
628
629 return MOS_STATUS_SUCCESS;
630 }
631
SetupDysRefPic()632 MOS_STATUS Vp9ReferenceFrames::SetupDysRefPic()
633 {
634 ENCODE_FUNC_CALL();
635
636 if (m_dysRefFrameFlags == DYS_REF_NONE)
637 {
638 return MOS_STATUS_SUCCESS;
639 }
640
641 auto allocator = m_basicFeature->GetAllocator();
642 ENCODE_CHK_NULL_RETURN(allocator);
643
644 auto picParams = m_basicFeature->m_vp9PicParams;
645 ENCODE_CHK_NULL_RETURN(picParams);
646
647 // Allocate dynamic scaled surfaces if needed
648 uint8_t frameIdx = 0, dysRefIdx = 0, numDysRefFrames = 0;
649
650 if (m_dysRefFrameFlags & DYS_REF_LAST)
651 {
652 auto refIndex = picParams->RefFlags.fields.LastRefIdx;
653 frameIdx = picParams->RefFrameList[refIndex].FrameIdx;
654 dysRefIdx = 1;
655 numDysRefFrames++;
656 }
657 if (m_dysRefFrameFlags & DYS_REF_GOLDEN) {
658 auto refIndex = picParams->RefFlags.fields.GoldenRefIdx;
659 frameIdx = picParams->RefFrameList[refIndex].FrameIdx;
660 dysRefIdx = 2;
661 numDysRefFrames++;
662 }
663 if (m_dysRefFrameFlags & DYS_REF_ALT)
664 {
665 auto refIndex = picParams->RefFlags.fields.AltRefIdx;
666 frameIdx = picParams->RefFrameList[refIndex].FrameIdx;
667 dysRefIdx = 3;
668 numDysRefFrames++;
669 }
670 if (numDysRefFrames > 1)
671 {
672 // For performance reason, we only support single reference for dynamic scaling
673 ENCODE_ASSERTMESSAGE("Only single reference is suppored for dynamic scaling!");
674 return MOS_STATUS_INVALID_PARAMETER;
675 }
676
677 PCODEC_REF_LIST *refList = &m_refList[0];
678 if (Mos_ResourceIsNull(&refList[frameIdx]->sDysSurface.OsResource) ||
679 (refList[frameIdx]->sDysSurface.dwWidth != m_basicFeature->m_reconSurface.dwWidth) ||
680 (refList[frameIdx]->sDysSurface.dwHeight != m_basicFeature->m_reconSurface.dwHeight))
681 {
682 // free existing resource first if resolution changes
683 if (!Mos_ResourceIsNull(&refList[frameIdx]->sDysSurface.OsResource))
684 {
685 ENCODE_CHK_STATUS_RETURN(allocator->DestroyResource(&refList[frameIdx]->sDysSurface.OsResource));
686 }
687
688 MOS_ALLOC_GFXRES_PARAMS allocParamsForBuffer;
689 MOS_ZeroMemory(&allocParamsForBuffer, sizeof(MOS_ALLOC_GFXRES_PARAMS));
690 allocParamsForBuffer.Type = MOS_GFXRES_2D;
691 allocParamsForBuffer.TileType = MOS_TILE_Y;
692 allocParamsForBuffer.Format = m_basicFeature->m_reconSurface.Format;
693 allocParamsForBuffer.bIsCompressible = m_basicFeature->m_mmcState ? m_basicFeature->m_mmcState->IsMmcEnabled() : false;
694
695 allocParamsForBuffer.dwWidth = MOS_ALIGN_CEIL(m_basicFeature->m_reconSurface.dwWidth, CODEC_VP9_SUPER_BLOCK_WIDTH);
696 allocParamsForBuffer.dwHeight = MOS_ALIGN_CEIL(m_basicFeature->m_reconSurface.dwHeight, CODEC_VP9_SUPER_BLOCK_HEIGHT);
697 allocParamsForBuffer.pBufName = "Dynamic Scaled Surface for VP9";
698
699 auto allocatedResource = allocator->AllocateResource(allocParamsForBuffer, false);
700 ENCODE_CHK_NULL_RETURN(allocatedResource);
701 refList[frameIdx]->sDysSurface.OsResource = *allocatedResource;
702 ENCODE_CHK_STATUS_RETURN(allocator->GetSurfaceInfo(&refList[frameIdx]->sDysSurface));
703 }
704
705 refList[frameIdx]->sDysSurface.dwWidth = m_basicFeature->m_oriFrameWidth;
706 refList[frameIdx]->sDysSurface.dwHeight = m_basicFeature->m_oriFrameHeight;
707
708 m_currDysRefList = refList[frameIdx];
709 m_dysRefIndex = dysRefIdx;
710
711 return MOS_STATUS_SUCCESS;
712 }
713
SetupRefIndex()714 MOS_STATUS Vp9ReferenceFrames::SetupRefIndex()
715 {
716 ENCODE_FUNC_CALL();
717
718 auto picParams = m_basicFeature->m_vp9PicParams;
719 ENCODE_CHK_NULL_RETURN(picParams);
720
721 for (auto i = 0; i < CODEC_VP9_NUM_REF_FRAMES; ++i)
722 {
723 if (picParams->RefFrameList[i].PicFlags != PICTURE_INVALID)
724 {
725 auto index = picParams->RefFrameList[i].FrameIdx;
726 bool duplicatedIdx = false;
727 for (auto j = 0; j < i; ++j)
728 {
729 if (m_picIdx[j].bValid && index == picParams->RefFrameList[j].FrameIdx)
730 {
731 // We find the same FrameIdx in the ref_frame_list. Multiple reference frames are the same.
732 duplicatedIdx = true;
733 break;
734 }
735 }
736 if (duplicatedIdx)
737 {
738 continue;
739 }
740
741 // This reference frame is unique. Save it into the full reference list with 127 items
742 m_refList[index]->RefPic.PicFlags =
743 CodecHal_CombinePictureFlags(m_refList[index]->RefPic, picParams->RefFrameList[i]);
744
745 m_picIdx[i].bValid = true;
746 m_picIdx[i].ucPicIdx = index;
747 }
748 }
749
750 return MOS_STATUS_SUCCESS;
751 }
752
DumpInput(Vp9VdencPipeline * pipeline)753 MOS_STATUS Vp9ReferenceFrames::DumpInput(Vp9VdencPipeline *pipeline)
754 {
755 ENCODE_FUNC_CALL();
756
757 #if USE_CODECHAL_DEBUG_TOOL
758 CodechalDebugInterface *debugInterface = pipeline->GetDebugInterface();
759 ENCODE_CHK_NULL_RETURN(debugInterface);
760
761 std::stringstream pipeIdxStrStream;
762 pipeIdxStrStream << "_" << (int)pipeline->GetCurrentPipe();
763
764 std::string surfacePassName = "Pass" + std::to_string((uint32_t)pipeline->GetCurrentPass());
765 surfacePassName += pipeIdxStrStream.str() + "_input";
766
767 // Last reference
768 if ((m_refFrameFlags & 0x01) && m_lastRefPic)
769 {
770 ENCODE_CHK_STATUS_RETURN(debugInterface->DumpYUVSurface(
771 m_lastRefPic,
772 CodechalDbgAttr::attrReferenceSurfaces,
773 (surfacePassName + "_LastRefSurf").data()));
774 }
775
776 // Golden reference
777 if (m_refFrameFlags & 0x02 && m_goldenRefPic)
778 {
779 ENCODE_CHK_STATUS_RETURN(debugInterface->DumpYUVSurface(
780 m_goldenRefPic,
781 CodechalDbgAttr::attrReferenceSurfaces,
782 (surfacePassName + "_GoldenRefSurf").data()));
783 }
784
785 // Alt reference
786 if (m_refFrameFlags & 0x04 && m_altRefPic)
787 {
788 ENCODE_CHK_STATUS_RETURN(debugInterface->DumpYUVSurface(
789 m_altRefPic,
790 CodechalDbgAttr::attrReferenceSurfaces,
791 (surfacePassName + "_AltRefSurf").data()));
792 }
793 #endif
794
795 return MOS_STATUS_SUCCESS;
796 }
797
usePrevInFindMvRef() const798 uint32_t Vp9ReferenceFrames::usePrevInFindMvRef() const
799 {
800 auto picParams = m_basicFeature->m_vp9PicParams;
801 auto prevFrameInfo = m_basicFeature->m_prevFrameInfo;
802
803 if (picParams->PicFlags.fields.error_resilient_mode ||
804 prevFrameInfo.KeyFrame || prevFrameInfo.IntraOnly || !prevFrameInfo.ShowFrame ||
805 (prevFrameInfo.FrameWidth != (picParams->SrcFrameWidthMinus1 + 1)) ||
806 (prevFrameInfo.FrameHeight != (picParams->SrcFrameHeightMinus1 + 1)))
807 {
808 return 0;
809 }
810
811 return 1;
812 }
813
SetDysValue(bool value)814 MOS_STATUS Vp9ReferenceFrames::SetDysValue(bool value)
815 {
816 m_dysEnabled = value;
817
818 return MOS_STATUS_SUCCESS;
819 }
820
MHW_SETPAR_DECL_SRC(HCP_VP9_PIC_STATE,Vp9ReferenceFrames)821 MHW_SETPAR_DECL_SRC(HCP_VP9_PIC_STATE, Vp9ReferenceFrames)
822 {
823 ENCODE_FUNC_CALL();
824
825 auto picParams = m_basicFeature->m_vp9PicParams;
826
827 params.refFrameSignBias02 = picParams->RefFlags.fields.LastRefSignBias |
828 (picParams->RefFlags.fields.GoldenRefSignBias << 1) |
829 (picParams->RefFlags.fields.AltRefSignBias << 2);
830
831 if (picParams->PicFlags.fields.frame_type && !picParams->PicFlags.fields.intra_only)
832 {
833 uint32_t curFrameWidth = picParams->SrcFrameWidthMinus1 + 1;
834 uint32_t curFrameHeight = picParams->SrcFrameHeightMinus1 + 1;
835
836 uint32_t m_vp9ScalingFactor = (1 << 14);
837
838 bool useDysRefSurface = (m_dysRefFrameFlags != DYS_REF_NONE) && m_basicFeature->m_dysVdencMultiPassEnabled;
839
840 PCODEC_PICTURE refFrameList = &(picParams->RefFrameList[0]);
841
842 params.lastFrameType = !m_basicFeature->m_prevFrameInfo.KeyFrame;
843
844 params.usePrevInFindMvReferences = usePrevInFindMvRef();
845
846 if ((picParams->RefFlags.fields.ref_frame_ctrl_l0 & 0x01) || (picParams->RefFlags.fields.ref_frame_ctrl_l1 & 0x01))
847 {
848 uint8_t lastRefPicIndex = refFrameList[picParams->RefFlags.fields.LastRefIdx].FrameIdx;
849 uint32_t lastRefFrameWidth = m_refList[lastRefPicIndex]->dwFrameWidth;
850 uint32_t lastRefFrameHeight = m_refList[lastRefPicIndex]->dwFrameHeight;
851
852 if (useDysRefSurface)
853 {
854 lastRefFrameWidth = curFrameWidth;
855 lastRefFrameHeight = curFrameWidth;
856 }
857
858 params.horizontalScaleFactorForLast = (lastRefFrameWidth * m_vp9ScalingFactor) / curFrameWidth;
859 params.verticalScaleFactorForLast = (lastRefFrameHeight * m_vp9ScalingFactor) / curFrameHeight;
860 params.lastFrameWidthInPixelsMinus1 = lastRefFrameWidth - 1;
861 params.lastFrameHeightInPixelsMinus1 = lastRefFrameHeight - 1;
862 }
863
864 if ((picParams->RefFlags.fields.ref_frame_ctrl_l0 & 0x02) || (picParams->RefFlags.fields.ref_frame_ctrl_l1 & 0x02))
865 {
866 uint8_t goldenRefPicIndex = refFrameList[picParams->RefFlags.fields.GoldenRefIdx].FrameIdx;
867 uint32_t goldenRefFrameWidth = m_refList[goldenRefPicIndex]->dwFrameWidth;
868 uint32_t goldenRefFrameHeight = m_refList[goldenRefPicIndex]->dwFrameHeight;
869
870 if (useDysRefSurface)
871 {
872 goldenRefFrameWidth = curFrameWidth;
873 goldenRefFrameHeight = curFrameHeight;
874 }
875
876 params.horizontalScaleFactorForGolden = (goldenRefFrameWidth * m_vp9ScalingFactor) / curFrameWidth;
877 params.verticalScaleFactorForGolden = (goldenRefFrameHeight * m_vp9ScalingFactor) / curFrameHeight;
878
879 params.goldenFrameWidthInPixelsMinus1 = goldenRefFrameWidth - 1;
880 params.goldenFrameHeightInPixelsMinus1 = goldenRefFrameHeight - 1;
881 }
882
883 if ((picParams->RefFlags.fields.ref_frame_ctrl_l0 & 0x04) || (picParams->RefFlags.fields.ref_frame_ctrl_l1 & 0x04))
884 {
885 uint8_t altRefPicIndex = refFrameList[picParams->RefFlags.fields.AltRefIdx].FrameIdx;
886 uint32_t altRefFrameWidth = m_refList[altRefPicIndex]->dwFrameWidth;
887 uint32_t altRefFrameHeight = m_refList[altRefPicIndex]->dwFrameHeight;
888
889 if (useDysRefSurface)
890 {
891 altRefFrameWidth = curFrameWidth;
892 altRefFrameHeight = curFrameHeight;
893 }
894
895 params.horizontalScaleFactorForAltref = (altRefFrameWidth * m_vp9ScalingFactor) / curFrameWidth;
896 params.verticalScaleFactorForAltref = (altRefFrameHeight * m_vp9ScalingFactor) / curFrameHeight;
897
898 params.altrefFrameWidthInPixelsMinus1 = altRefFrameWidth - 1;
899 params.altrefFrameHeightInPixelsMinus1 = altRefFrameHeight - 1;
900 }
901 }
902
903 char *lfRefDelta = &(picParams->LFRefDelta[0]);
904 char *lfModeDelta = &(picParams->LFModeDelta[0]);
905
906 params.lfRefDelta0 = m_basicFeature->Convert2SignMagnitude((lfRefDelta[0]), 7);
907 params.lfRefDelta1 = m_basicFeature->Convert2SignMagnitude((lfRefDelta[1]), 7);
908 params.lfRefDelta2 = m_basicFeature->Convert2SignMagnitude((lfRefDelta[2]), 7);
909 params.lfRefDelta3 = m_basicFeature->Convert2SignMagnitude((lfRefDelta[3]), 7);
910
911 params.lfModeDelta0 = m_basicFeature->Convert2SignMagnitude((lfModeDelta[0]), 7);
912 params.lfModeDelta1 = m_basicFeature->Convert2SignMagnitude((lfModeDelta[1]), 7);
913
914 return MOS_STATUS_SUCCESS;
915 }
916
MHW_SETPAR_DECL_SRC(HCP_PIPE_BUF_ADDR_STATE,Vp9ReferenceFrames)917 MHW_SETPAR_DECL_SRC(HCP_PIPE_BUF_ADDR_STATE, Vp9ReferenceFrames)
918 {
919 ENCODE_FUNC_CALL();
920
921 auto trackedBuf = m_basicFeature->m_trackedBuf;
922 ENCODE_CHK_NULL_RETURN(trackedBuf);
923
924 if (!m_dysEnabled)
925 {
926 params.bDynamicScalingEnable = (m_dysRefFrameFlags != DYS_REF_NONE) && !m_basicFeature->m_dysVdencMultiPassEnabled;
927 params.dwNumRefIdxL0ActiveMinus1 = (m_basicFeature->m_vp9PicParams->PicFlags.fields.frame_type) ? m_numRefFrames - 1 : 0;
928 params.dwNumRefIdxL1ActiveMinus1 = 0;
929
930 // Add for P frame support
931 if (m_basicFeature->m_pictureCodingType != I_TYPE)
932 {
933 for (auto i = 0; i < maxReferenceIds; ++i)
934 {
935 ENCODE_CHK_NULL_RETURN(m_refSurface[i]);
936 ENCODE_CHK_NULL_RETURN(m_dsRefSurface4x[i]);
937 ENCODE_CHK_NULL_RETURN(m_dsRefSurface8x[i]);
938
939 if ((m_dysRefFrameFlags != DYS_REF_NONE) && !m_basicFeature->m_dysVdencMultiPassEnabled)
940 {
941 params.presReferences[i] = &m_refSurfaceNonScaled[i]->OsResource;
942 params.presReferences[i + 4] = &m_refSurfaceNonScaled[i]->OsResource;
943 }
944 else
945 {
946 params.presReferences[i] = &m_refSurface[i]->OsResource;
947 }
948 params.presVdencReferences[i] = &m_refSurface[i]->OsResource;
949
950 // 4x/8x DS surface for VDEnc
951 params.presVdenc4xDsSurface[i] = &m_dsRefSurface4x[i]->OsResource;
952 params.presVdenc8xDsSurface[i] = &m_dsRefSurface8x[i]->OsResource;
953 }
954
955 if ((m_dysRefFrameFlags != DYS_REF_NONE) && !m_basicFeature->m_dysVdencMultiPassEnabled)
956 {
957 params.psFwdRefSurface0 = m_refSurface[lastFrame];
958 params.psFwdRefSurface1 = m_refSurface[goldenFrame];
959 params.psFwdRefSurface2 = m_refSurface[altFrame];
960 }
961 }
962 }
963 else
964 {
965 if (m_basicFeature->m_pictureCodingType != I_TYPE)
966 {
967 for (auto i = 0; i < maxReferenceIds; ++i)
968 {
969 ENCODE_CHK_NULL_RETURN(m_dysRefSurface[i]);
970
971 params.presReferences[i] = &m_dysRefSurface[i]->OsResource;
972 }
973 }
974
975 m_dysEnabled = false;
976 }
977
978 if (m_basicFeature->m_pictureCodingType != I_TYPE)
979 {
980 params.presColMvTempBuffer[0] = trackedBuf->GetBuffer(BufferType::mvTemporalBuffer, m_basicFeature->m_lastMvTemporalBufferIndex);
981 }
982
983 return MOS_STATUS_SUCCESS;
984 }
985
MHW_SETPAR_DECL_SRC(VDENC_PIPE_BUF_ADDR_STATE,Vp9ReferenceFrames)986 MHW_SETPAR_DECL_SRC(VDENC_PIPE_BUF_ADDR_STATE, Vp9ReferenceFrames)
987 {
988 ENCODE_FUNC_CALL();
989
990 auto trackedBuf = m_basicFeature->m_trackedBuf;
991 ENCODE_CHK_NULL_RETURN(trackedBuf);
992
993 params.numActiveRefL0 = (m_basicFeature->m_vp9PicParams->PicFlags.fields.frame_type) ? m_numRefFrames : 1;
994 params.numActiveRefL1 = 0;
995
996 // Add for P frame support
997 if (m_basicFeature->m_pictureCodingType != I_TYPE)
998 {
999 for (auto i = 0; i < maxReferenceIds; ++i)
1000 {
1001 ENCODE_CHK_NULL_RETURN(m_refSurface[i]);
1002 ENCODE_CHK_NULL_RETURN(m_dsRefSurface4x[i]);
1003 ENCODE_CHK_NULL_RETURN(m_dsRefSurface8x[i]);
1004
1005 params.refs[i] = &m_refSurface[i]->OsResource;
1006 params.refsDsStage2[i] = &m_dsRefSurface4x[i]->OsResource;
1007 params.refsDsStage1[i] = &m_dsRefSurface8x[i]->OsResource;
1008 }
1009
1010 params.colMvTempBuffer[0] = trackedBuf->GetBuffer(BufferType::mvTemporalBuffer, m_basicFeature->m_lastMvTemporalBufferIndex);
1011 }
1012
1013 return MOS_STATUS_SUCCESS;
1014 }
1015
1016 } // namespace encode
1017