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