1 /*
2 * Copyright (c) 2019-2023, 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_av1_reference_frames.cpp
24 //! \brief    Defines reference list related logic for encode av1
25 //!
26 
27 #include <algorithm>
28 #include "encode_av1_basic_feature.h"
29 #include "encode_utils.h"
30 #include "encode_av1_reference_frames.h"
31 #include "codec_def_encode_av1.h"
32 #include "codechal_debug.h"
33 #include "encode_av1_vdenc_pipeline.h"
34 
35 namespace encode
36 {
Init(Av1BasicFeature * basicFeature)37 MOS_STATUS Av1ReferenceFrames::Init(Av1BasicFeature *basicFeature)
38 {
39     ENCODE_FUNC_CALL();
40     ENCODE_CHK_NULL_RETURN(basicFeature);
41 
42     m_basicFeature = basicFeature;
43     ENCODE_CHK_STATUS_RETURN(EncodeAllocateDataList(
44         m_refList,
45         CODEC_AV1_NUM_UNCOMPRESSED_SURFACE));
46 
47     return MOS_STATUS_SUCCESS;
48 }
49 
~Av1ReferenceFrames()50 Av1ReferenceFrames::~Av1ReferenceFrames()
51 {
52     ENCODE_FUNC_CALL();
53 
54     EncodeFreeDataList(m_refList, CODEC_AV1_NUM_UNCOMPRESSED_SURFACE);
55 }
56 #if USE_CODECHAL_DEBUG_TOOL
DumpInput(Av1VdencPipeline * pipeline)57 MOS_STATUS Av1ReferenceFrames::DumpInput(Av1VdencPipeline *pipeline)
58 {
59     ENCODE_FUNC_CALL();
60 
61     CodechalDebugInterface *debugInterface = pipeline->GetDebugInterface();
62     ENCODE_CHK_NULL_RETURN(debugInterface);
63 
64     std::stringstream pipeIdxStrStream("");
65     pipeIdxStrStream << "_" << (int)pipeline->GetCurrentPipe();
66     std::string surfacePassName = "Pass" + std::to_string((uint32_t)pipeline->GetCurrentPass());
67     surfacePassName += pipeIdxStrStream.str() + "_input";
68 
69     if (m_refFrameFlags == 0)
70     {
71         ENCODE_VERBOSEMESSAGE("Ref list is empty!.Only keyframe is expected.");
72         return MOS_STATUS_SUCCESS;
73     }
74     //Dump surface
75     {
76         std::string reflagName;
77         for (auto i = 0; i < av1NumInterRefFrames; i++)
78         {
79             if (m_refFrameFlags & (AV1_ENCODE_GET_REF_FALG(i)))
80             {
81                 switch (i+1) {
82                 case lastFrame:
83                     reflagName = "_LastRefSurf";
84                     break;
85                 case last2Frame:
86                     reflagName = "_Last2RefSurf";
87                     break;
88                 case last3Frame:
89                     reflagName = "_Last3RefSurf";
90                     break;
91                 case bwdRefFrame:
92                     reflagName = "_BWDRefSurf";
93                     break;
94                 case goldenFrame:
95                     reflagName = "_GoldenRefSurf";
96                     break;
97                 case altRef2Frame:
98                     reflagName = "_Alt2RefSurf";
99                     break;
100                 case altRefFrame:
101                     reflagName = "_AltRefSurf";
102                     break;
103                 default:
104                     reflagName = "";
105                     break;
106                 }
107                 if (reflagName == "")
108                 {
109                     continue;
110                 }
111                 ENCODE_CHK_STATUS_RETURN(debugInterface->DumpYUVSurface(
112                     m_currRefPic[i],
113                     CodechalDbgAttr::attrReferenceSurfaces,
114                     (surfacePassName + reflagName).data()));
115             }
116         }
117     }
118     return MOS_STATUS_SUCCESS;
119 }
120 #endif
MmcEnabled(MOS_MEMCOMP_STATE state)121 static bool MmcEnabled(MOS_MEMCOMP_STATE state)
122 {
123     return state == MOS_MEMCOMP_RC || state == MOS_MEMCOMP_MC;
124 }
125 
Update()126 MOS_STATUS Av1ReferenceFrames::Update()
127 {
128     ENCODE_FUNC_CALL();
129 
130     // initialize internal structures for current frame before set up
131     m_refFrameFlags = 0;
132     m_numRefFrames = 0;
133     uint32_t compressionFormat = 0;
134 
135     MOS_ZeroMemory(m_currRefPic, sizeof(m_currRefPic));
136     for (auto i = 0; i < CODEC_AV1_NUM_REF_FRAMES; i++)
137     {
138         m_picIdx[i].bValid = false;
139     }
140 
141     auto picParams = m_basicFeature->m_av1PicParams;
142     ENCODE_CHK_NULL_RETURN(picParams);
143 
144     auto seqParams = m_basicFeature->m_av1SeqParams;
145     ENCODE_CHK_NULL_RETURN(seqParams);
146 
147     m_enable_order_hint = seqParams->CodingToolFlags.fields.enable_order_hint;
148     m_orderHintBitsMinus1 = seqParams->order_hint_bits_minus_1;
149     m_refFrameBiasFlagsForPak.value = 0;
150     m_refFrameBiasFlagsForRefManagement.value = 0;
151 
152     // save current frame infomation into m_refList
153     auto currRefIdx = picParams->CurrReconstructedPic.FrameIdx;
154     m_currRefList = m_refList[currRefIdx];
155 
156     // needs to confirm later if this should come from App
157     m_currRefList->bUsedAsRef = true;
158     m_currRefList->sRefReconBuffer = m_basicFeature->m_reconSurface;
159     m_currRefList->sRefRawBuffer = m_basicFeature->m_rawSurface;
160     m_currRefList->RefPic = picParams->CurrOriginalPic;
161     m_currRefList->resBitstreamBuffer = m_basicFeature->m_resBitstreamBuffer;
162     m_currRefList->m_frameWidth = m_refWidth? m_refWidth : picParams->frame_width_minus1 + 1;
163     m_currRefList->m_frameHeight = m_refHeight? m_refHeight : picParams->frame_height_minus1 + 1;
164     m_currRefList->m_orderHint = picParams->order_hint;
165     m_currRefList->m_miCols = m_basicFeature->m_miCols;
166     m_currRefList->m_miRows = m_basicFeature->m_miRows;
167     m_currRefList->m_segmentEnable = picParams->stAV1Segments.SegmentFlags.fields.segmentation_enabled;
168     // m_currRefList->ucScalingIdx also is one critical index
169     // it used to associate temperal mv buffer, down scaling surfaces.
170     // it will be set in m_trackedBuf->Acquire
171 
172     // set up reference related structures
173     if (!AV1_KEY_OR_INRA_FRAME(picParams->PicFlags.fields.frame_type))
174     {
175         ENCODE_CHK_STATUS_RETURN(SetupRefFlag()); // set up m_refFrameFlags
176         ENCODE_CHK_STATUS_RETURN(SetupCurrRefPic()); // set up m_currRefPic
177         ENCODE_CHK_STATUS_RETURN(ValidateLowDelayBFrame()); // validate if low delay mode
178         ENCODE_CHK_STATUS_RETURN(ValidatePFrame());  // validate if P frame, P frame should be Low delay first
179         ENCODE_CHK_STATUS_RETURN(SetupRefIdx()); // set up m_picIdx
180     }
181 
182     m_primaryRefFrame = picParams->primary_ref_frame;
183     if (m_primaryRefFrame > av1PrimaryRefNone)
184     {
185         ENCODE_ASSERTMESSAGE("AV1 primary reference frame number exceeds PRIMARY_REF_NONE.");
186         return MOS_STATUS_INVALID_PARAMETER;
187     }
188     if (m_primaryRefFrame != av1PrimaryRefNone)
189     {
190         uint8_t refPicIndex = picParams->ref_frame_idx[m_primaryRefFrame];
191         auto    refPic      = picParams->RefFrameList[refPicIndex];
192         if (!CodecHal_PictureIsInvalid(refPic))
193         {
194             uint8_t prevFrameIdx = refPic.FrameIdx;
195 
196             m_primaryRefList = m_refList[prevFrameIdx];
197         }
198     }
199 
200 
201 
202     // Save the RefFrameList for current frame
203     uint8_t ii = 0;
204     for (auto i = 0; i < CODEC_AV1_NUM_REF_FRAMES; i++)
205     {
206         if (m_picIdx[i].bValid)
207         {
208             m_currRefList->RefList[ii] = picParams->RefFrameList[i];
209             ii++;
210         }
211     }
212     m_currRefList->ucNumRef = ii;
213 
214     auto currRawOrRecon = seqParams->SeqFlags.fields.UseRawReconRef ? &m_basicFeature->m_rawSurface : &m_basicFeature->m_reconSurface;
215     if (m_firstValidRefPic == nullptr)
216     {
217         m_firstValidRefPic = currRawOrRecon;
218     }
219     m_basicFeature->GetSurfaceMmcInfo(m_firstValidRefPic, m_refMmcState[intraFrame], compressionFormat);
220     m_refCompressionFormat = MmcEnabled(m_refMmcState[intraFrame])? compressionFormat : m_refCompressionFormat;
221     return MOS_STATUS_SUCCESS;
222 
223 }
224 
UpdateRefFrameSize(uint32_t width,uint32_t height)225 MOS_STATUS Av1ReferenceFrames::UpdateRefFrameSize(uint32_t width, uint32_t height)
226 {
227     m_refWidth  = width;
228     m_refHeight = height;
229 
230     return MOS_STATUS_SUCCESS;
231 }
232 
RefFrameL0L1(CODEC_Ref_Frame_Ctrl_AV1 const & ref_frame_ctrl) const233 uint8_t Av1ReferenceFrames::RefFrameL0L1(CODEC_Ref_Frame_Ctrl_AV1 const &ref_frame_ctrl) const
234 {
235     uint8_t Refs = 0;
236     auto    fields = ref_frame_ctrl.RefFrameCtrl.fields;
237     uint32_t tempIndex[7] = {fields.search_idx0,
238                              fields.search_idx1,
239                              fields.search_idx2,
240                              fields.search_idx3,
241                              fields.search_idx4,
242                              fields.search_idx5,
243                              fields.search_idx6};
244     for (int i = 0; i < 7; i++)
245     {
246         if (tempIndex[i] >= 1 && tempIndex[i] <= 7)
247         {
248             Refs |= (1 << (tempIndex[i] - 1));
249         }
250     }
251 
252     return Refs;
253 }
254 
SetupRefFlag()255 MOS_STATUS Av1ReferenceFrames::SetupRefFlag()
256 {
257     ENCODE_FUNC_CALL();
258 
259     auto picParams = m_basicFeature->m_av1PicParams;
260     ENCODE_CHK_NULL_RETURN(picParams);
261     auto ref_frame_ctrl_l0 = RefFrameL0L1(picParams->ref_frame_ctrl_l0);
262     auto ref_frame_ctrl_l1 = RefFrameL0L1(picParams->ref_frame_ctrl_l1);
263 
264     m_refFrameFlags = ref_frame_ctrl_l0 | ref_frame_ctrl_l1;
265 
266     for (auto i = 0; i < av1NumInterRefFrames; i++)
267     {
268         if (CodecHal_PictureIsInvalid(picParams->RefFrameList[picParams->ref_frame_idx[i]]))
269         {
270             m_refFrameFlags &= ~(AV1_ENCODE_GET_REF_FALG(i));
271         }
272     }
273 
274     if (m_refFrameFlags == 0)
275     {
276         ENCODE_ASSERTMESSAGE("Ref list is empty!.");
277         return MOS_STATUS_INVALID_PARAMETER;
278     }
279 
280     return MOS_STATUS_SUCCESS;
281 }
282 
SetupCurrRefPic()283 MOS_STATUS Av1ReferenceFrames::SetupCurrRefPic()
284 {
285     ENCODE_FUNC_CALL();
286 
287     auto picParams = m_basicFeature->m_av1PicParams;
288     ENCODE_CHK_NULL_RETURN(picParams);
289     auto seqParams = m_basicFeature->m_av1SeqParams;
290     ENCODE_CHK_NULL_RETURN(seqParams);
291     auto firstValid = false;
292     uint32_t compressionFormat = 0;
293     for (auto i = 0; i < av1NumInterRefFrames; i++)
294     {
295         if (m_refFrameFlags & (AV1_ENCODE_GET_REF_FALG(i)))
296         {
297             auto index = picParams->ref_frame_idx[i];
298             auto frameIdx = picParams->RefFrameList[index].FrameIdx;
299             m_refList[frameIdx]->sRefBuffer = seqParams->SeqFlags.fields.UseRawReconRef ? m_refList[frameIdx]->sRefRawBuffer :m_refList[frameIdx]->sRefReconBuffer;
300 
301             m_currRefPic[i] = &m_refList[frameIdx]->sRefBuffer;
302             m_currRefPic[i]->dwWidth = m_refList[frameIdx]->m_frameWidth;
303             m_currRefPic[i]->dwHeight = m_refList[frameIdx]->m_frameHeight;
304             m_numRefFrames++;
305 
306             if (firstValid == false)
307             {
308                 m_firstValidRefPic = m_currRefPic[i];
309                 firstValid = true;
310             }
311 
312             m_currRefList->m_refOrderHint[i] = m_refList[frameIdx]->m_orderHint;
313         }
314     }
315 
316     // error concealment for the unset reference and mv buffers addresses
317     for (auto i = 0; i < av1NumInterRefFrames; i++)
318     {
319         if (m_currRefPic[i] == nullptr)
320         {
321             m_currRefPic[i] = m_firstValidRefPic;
322         }
323         m_basicFeature->GetSurfaceMmcInfo(m_currRefPic[i], m_refMmcState[i + 1], compressionFormat);
324         m_refCompressionFormat = MmcEnabled(m_refMmcState[i + 1]) ? compressionFormat : m_refCompressionFormat;
325     }
326 
327     return MOS_STATUS_SUCCESS;
328 }
329 
SetupRefIdx()330 MOS_STATUS Av1ReferenceFrames::SetupRefIdx()
331 {
332     ENCODE_FUNC_CALL();
333 
334     auto picParams = m_basicFeature->m_av1PicParams;
335     ENCODE_CHK_NULL_RETURN(picParams);
336 
337     for (auto i = 0; i < CODEC_AV1_NUM_REF_FRAMES; i++)
338     {
339         if (picParams->RefFrameList[i].PicFlags != PICTURE_INVALID)
340         {
341             auto index = picParams->RefFrameList[i].FrameIdx;
342             bool duplicatedIdx = false;
343             for (auto ii = 0; ii < i; ii++)
344             {
345                 if (m_picIdx[ii].bValid && index == picParams->RefFrameList[ii].FrameIdx)
346                 {
347                     // we find the same FrameIdx in the ref_frame_list. Multiple reference frames are the same.
348                     duplicatedIdx = true;
349                     break;
350                 }
351             }
352             if (duplicatedIdx)
353             {
354                 continue;
355             }
356 
357             // this reference frame in unique. Save it into the full reference list with 127 items
358             m_refList[index]->RefPic.PicFlags =
359                 CodecHal_CombinePictureFlags(m_refList[index]->RefPic, picParams->RefFrameList[i]);
360 
361             m_picIdx[i].bValid = true;
362             m_picIdx[i].ucPicIdx = index;
363         }
364     }
365 
366     return MOS_STATUS_SUCCESS;
367 }
368 
ValidateLowDelayBFrame()369 MOS_STATUS Av1ReferenceFrames::ValidateLowDelayBFrame()
370 {
371     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
372 
373     ENCODE_FUNC_CALL();
374 
375     auto picParams = m_basicFeature->m_av1PicParams;
376     auto seqParams = m_basicFeature->m_av1SeqParams;
377     ENCODE_CHK_NULL_RETURN(picParams);
378     ENCODE_CHK_NULL_RETURN(seqParams);
379     m_lowDelay = true;
380 
381     uint8_t ref_frame_ctrl_l0 = RefFrameL0L1(picParams->ref_frame_ctrl_l0);
382 
383     // Examine if now it is in the low delay mode base on order hint
384     // First step: set up m_refFrameBiasFlags
385     int32_t dist = 0;
386     for (auto i = 0; i < av1NumInterRefFrames; i++)
387     {
388         dist = GetRelativeDist(m_currRefList->m_refOrderHint[i], m_currRefList->m_orderHint);
389         if (dist > 0 && (m_refFrameFlags & (AV1_ENCODE_GET_REF_FALG(i))))
390         {
391             m_refFrameBiasFlagsForPak.value |= AV1_ENCODE_GET_REF_FALG(i);
392             if (seqParams->GopRefDist > 1 && (ref_frame_ctrl_l0 & AV1_ENCODE_GET_REF_FALG(i)) == 0)
393                 m_refFrameBiasFlagsForRefManagement.value |= AV1_ENCODE_GET_REF_FALG(i);
394         }
395     }
396 
397     // collorated RefFrameBiasFlags = 0, means it's before current frame.
398     // collorated RefFrameBiasFlags = 1, means it's after current frame.
399     // if all references' bias flag are false, then it's low delay case.
400     // otherwise, it's random access case
401     if (m_refFrameFlags & m_refFrameBiasFlagsForRefManagement.value)
402     {
403         m_lowDelay = false;
404     }
405 
406     return eStatus;
407 }
408 
ValidatePFrame()409 MOS_STATUS Av1ReferenceFrames::ValidatePFrame()
410 {
411     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
412 
413     ENCODE_FUNC_CALL();
414 
415     auto picParams = m_basicFeature->m_av1PicParams;
416     ENCODE_CHK_NULL_RETURN(picParams);
417 
418     //P frame should be Low delay first
419     if (m_lowDelay && picParams->ref_frame_ctrl_l1.RefFrameCtrl.value == 0)
420     {
421         m_PFrame = true;
422     }
423     else
424     {
425         m_PFrame = false;
426     }
427 
428     return eStatus;
429 }
430 
GetRelativeDist(int32_t a,int32_t b) const431 int32_t Av1ReferenceFrames::GetRelativeDist(int32_t a, int32_t b) const
432 {
433     if (!m_enable_order_hint)
434     {
435         return 0;
436     }
437 
438     int32_t bits = m_orderHintBitsMinus1 + 1;
439 
440     if ((bits < 1) || (a < 0) || (a >= (1 << bits)) || (b < 0) || (b >= (1 << bits)))
441     {
442         ENCODE_ASSERTMESSAGE("Invalid input parameters to get relative distance.");
443         return 0;
444     }
445 
446     int32_t diff = a - b;
447     int32_t m = 1 << (bits - 1);
448     diff = (diff & (m - 1)) - (diff & m);
449     return diff;
450 }
ConsolidateRefFlag(uint8_t & refFlag,const PCODEC_AV1_ENCODE_PICTURE_PARAMS picParams)451 inline void ConsolidateRefFlag(uint8_t &refFlag, const PCODEC_AV1_ENCODE_PICTURE_PARAMS picParams)
452 {
453     ENCODE_CHK_NULL_NO_STATUS_RETURN(picParams);
454     //consilidate the reference flag, becasue two reference frame may have the same index
455     for (auto i = 0; i < av1NumInterRefFrames; i++)
456     {
457         auto basedFrameIdx = picParams->RefFrameList[picParams->ref_frame_idx[i]].FrameIdx;
458         for (auto ii = i + 1; ii < av1NumInterRefFrames; ii++)
459         {
460             if ((refFlag & AV1_ENCODE_GET_REF_FALG(i)) &&
461                 (basedFrameIdx == picParams->RefFrameList[picParams->ref_frame_idx[ii]].FrameIdx))
462             {
463                 // find same frame index for different ref frame type, skip larger ref frame type
464                 refFlag &= ~(AV1_ENCODE_GET_REF_FALG(ii));
465             }
466         }
467     }
468 }
GetFwdBwdRefNum(uint8_t & fwdRefNum,uint8_t & bwdRefNum) const469 MOS_STATUS Av1ReferenceFrames::GetFwdBwdRefNum(uint8_t &fwdRefNum, uint8_t &bwdRefNum) const
470 {
471     ENCODE_FUNC_CALL();
472     auto picParams = m_basicFeature->m_av1PicParams;
473     ENCODE_CHK_NULL_RETURN(picParams);
474     auto    ref_frame_ctrl0 = picParams->ref_frame_ctrl_l0;
475     auto    ref_frame_ctrl1 = picParams->ref_frame_ctrl_l1;
476 
477     uint8_t ref_frame_ctrl_l0 = RefFrameL0L1(ref_frame_ctrl0);
478     uint8_t ref_frame_ctrl_l1 = RefFrameL0L1(ref_frame_ctrl1);
479     uint8_t RefFrameBiasFlags = m_refFrameBiasFlagsForRefManagement.value;
480 
481     fwdRefNum = 0;
482     bwdRefNum = 0;
483 
484     ConsolidateRefFlag(ref_frame_ctrl_l0, picParams);
485 
486     for (auto i = 0; i < av1NumInterRefFrames; i++)
487     {
488         uint8_t mask = AV1_ENCODE_GET_REF_FALG(i);
489         if ((ref_frame_ctrl_l0 & mask) && !(RefFrameBiasFlags & mask))
490         {
491             fwdRefNum++;
492         }
493         if ((ref_frame_ctrl_l1 & mask) && (RefFrameBiasFlags & mask))
494         {
495             bwdRefNum++;
496         }
497     }
498 
499     if (fwdRefNum > 3 || bwdRefNum > 1 || fwdRefNum + bwdRefNum > 3)
500     {
501         return MOS_STATUS_INVALID_PARAMETER;
502     }
503 
504     return MOS_STATUS_SUCCESS;
505 }
506 
507 
508 
SetPostCdefAsEncRef(bool flag)509 MOS_STATUS Av1ReferenceFrames::SetPostCdefAsEncRef(bool flag)
510 {
511     m_encUsePostCdefAsRef = flag;
512 
513     return MOS_STATUS_SUCCESS;
514 }
515 
GetRefScalingIdx() const516 std::vector<uint8_t> Av1ReferenceFrames::GetRefScalingIdx() const
517 {
518     std::vector<uint8_t> idxList;
519 
520     auto picParams = m_basicFeature->m_av1PicParams;
521 
522     for (auto i = 0; i < av1NumInterRefFrames; i++)
523     {
524         if (m_refFrameFlags & (AV1_ENCODE_GET_REF_FALG(i)))
525         {
526             idxList.push_back(m_refList[picParams->RefFrameList[picParams->ref_frame_idx[i]].FrameIdx]->ucScalingIdx);
527         }
528     }
529 
530     return idxList;
531 }
532 
GetEncRefSurface() const533 std::vector<PMOS_SURFACE> Av1ReferenceFrames::GetEncRefSurface() const
534 {
535     if (!m_encUsePostCdefAsRef)
536     {
537         return GetPakRefSurface();
538     }
539 
540     auto idxList = GetRefScalingIdx();
541     std::vector<PMOS_SURFACE> ret;
542 
543     for (auto idx : idxList)
544     {
545         ret.push_back(m_basicFeature->m_trackedBuf->GetSurface(m_encRefBufType, idx));
546     }
547 
548     return ret;
549 }
550 
GetEnc4xRefSurface() const551 std::vector<PMOS_SURFACE> Av1ReferenceFrames::GetEnc4xRefSurface() const
552 {
553     auto idxList = GetRefScalingIdx();
554     std::vector<PMOS_SURFACE> ret;
555 
556     for (auto idx : idxList)
557     {
558         ret.push_back(m_basicFeature->m_trackedBuf->GetSurface(m_enc4xRefBufType, idx));
559     }
560 
561     return ret;
562 }
563 
GetEnc8xRefSurface() const564 std::vector<PMOS_SURFACE> Av1ReferenceFrames::GetEnc8xRefSurface() const
565 {
566     auto idxList = GetRefScalingIdx();
567     std::vector<PMOS_SURFACE> ret;
568 
569     for (auto idx : idxList)
570     {
571         ret.push_back(m_basicFeature->m_trackedBuf->GetSurface(m_enc8xRefBufType, idx));
572     }
573 
574     return ret;
575 }
576 
GetPakRefSurface() const577 std::vector<PMOS_SURFACE> Av1ReferenceFrames::GetPakRefSurface() const
578 {
579     std::vector<PMOS_SURFACE> refs;
580 
581     auto picParams = m_basicFeature->m_av1PicParams;
582 
583     for (auto i = 0; i < av1NumInterRefFrames; i++)
584     {
585         if (m_refFrameFlags & (AV1_ENCODE_GET_REF_FALG(i)))
586         {
587             auto frameIdx = picParams->RefFrameList[picParams->ref_frame_idx[i]].FrameIdx;
588             refs.push_back(&m_refList[frameIdx]->sRefBuffer);
589         }
590     }
591 
592     return refs;
593 }
594 
GetFwdBwdRefPicList(CODEC_PICTURE (& refsPicList)[2][15])595 void Av1ReferenceFrames::GetFwdBwdRefPicList(CODEC_PICTURE (&refsPicList)[2][15])
596 {
597     ENCODE_FUNC_CALL();
598     auto picParams       = m_basicFeature->m_av1PicParams;
599     auto ref_frame_ctrl0 = picParams->ref_frame_ctrl_l0;
600     auto ref_frame_ctrl1 = picParams->ref_frame_ctrl_l1;
601 
602     uint8_t ref_frame_ctrl_l0 = RefFrameL0L1(ref_frame_ctrl0);
603     uint8_t ref_frame_ctrl_l1 = RefFrameL0L1(ref_frame_ctrl1);
604     uint8_t RefFrameBiasFlags = m_refFrameBiasFlagsForRefManagement.value;
605 
606     uint8_t fwdRefNum = 0;
607     uint8_t bwdRefNum = 0;
608 
609     for (auto i = 0; i < av1NumInterRefFrames; i++)
610     {
611         uint8_t mask = AV1_ENCODE_GET_REF_FALG(i);
612         if ((ref_frame_ctrl_l0 & mask) && !(RefFrameBiasFlags & mask))
613         {
614             auto index  = picParams->ref_frame_idx[i];
615             refsPicList[0][fwdRefNum].FrameIdx = index;
616             refsPicList[0][fwdRefNum].PicEntry = picParams->RefFrameList[index].PicEntry;
617             refsPicList[0][fwdRefNum].PicFlags = picParams->RefFrameList[index].PicFlags;
618             fwdRefNum++;
619         }
620         if ((ref_frame_ctrl_l1 & mask) && (RefFrameBiasFlags & mask))
621         {
622             auto index  = picParams->ref_frame_idx[i];
623             refsPicList[1][bwdRefNum].FrameIdx = index;
624             refsPicList[1][bwdRefNum].PicEntry = picParams->RefFrameList[index].PicEntry;
625             refsPicList[1][bwdRefNum].PicFlags = picParams->RefFrameList[index].PicFlags;
626             bwdRefNum++;
627         }
628     }
629     uint8_t CodingType = (m_basicFeature->m_pictureCodingType == I_TYPE) ? I_TYPE : (m_basicFeature->m_ref.IsLowDelay() ? (m_basicFeature->m_ref.IsPFrame() ? P_TYPE : B_TYPE) : B_TYPE);
630     if (CodingType == B_TYPE && m_lowDelay && bwdRefNum == 0)
631     {
632         for (int j = 0; j < fwdRefNum; j++)
633         {
634             refsPicList[1][j] = refsPicList[0][j];
635         }
636     }
637 }
638 
GetRefFramePOC(int32_t (& refsPOCList)[15],int32_t const orderHint)639 void Av1ReferenceFrames::GetRefFramePOC(int32_t (&refsPOCList)[15], int32_t const orderHint)
640 {
641     auto picParams = m_basicFeature->m_av1PicParams;
642     for (auto i = 0; i < av1NumInterRefFrames; i++)
643     {
644         if (picParams->RefFrameList[i].PicFlags != PICTURE_INVALID)
645         {
646             auto frameIdx = picParams->RefFrameList[i].FrameIdx;
647             auto dist = GetRelativeDist(m_refList[frameIdx]->m_orderHint, m_currRefList->m_orderHint);
648             refsPOCList[i] = orderHint + dist;
649         }
650     }
651 }
652 
GetFrameDisplayOrder()653 int32_t Av1ReferenceFrames::GetFrameDisplayOrder()
654 {
655     const auto picParams = m_basicFeature->m_av1PicParams;
656 
657     int32_t displayOrder = 0;
658     if (picParams->PicFlags.fields.frame_type == keyFrame)
659     {
660         displayOrder = m_frameOut;
661     }
662     else
663     {
664         auto dist = GetRelativeDist(m_currRefList->m_orderHint, m_prevFrameOffset);
665         displayOrder = m_prevFrameDisplayerOrder + dist;
666     }
667     m_prevFrameOffset = m_currRefList->m_orderHint;
668     m_prevFrameDisplayerOrder = displayOrder;
669     m_frameOut++;
670     return displayOrder;
671 }
672 
CheckSegmentForPrimeFrame()673 bool Av1ReferenceFrames::CheckSegmentForPrimeFrame()
674 {
675     ENCODE_FUNC_CALL();
676 
677     bool isMatched = false;
678 
679     if (m_basicFeature == nullptr)
680     {
681         ENCODE_ASSERTMESSAGE("Invalid (NULL) Pointer!");
682         return false;
683     }
684 
685     auto picParams = m_basicFeature->m_av1PicParams;
686     if (picParams == nullptr)
687     {
688         ENCODE_ASSERTMESSAGE("Invalid (NULL) Pointer!");
689         return false;
690     }
691 
692     uint8_t refPicIndex = picParams->ref_frame_idx[m_primaryRefFrame];
693     auto refPic = picParams->RefFrameList[refPicIndex];
694     if (!CodecHal_PictureIsInvalid(refPic))
695     {
696         uint8_t prevFrameIdx = refPic.FrameIdx;
697 
698         if (m_currRefList->m_miCols == m_refList[prevFrameIdx]->m_miCols &&
699             m_currRefList->m_miRows == m_refList[prevFrameIdx]->m_miRows &&
700             m_refList[prevFrameIdx]->m_segmentEnable)
701         {
702             isMatched = true;
703         }
704     }
705 
706     return isMatched;
707 }
708 
MHW_SETPAR_DECL_SRC(VDENC_PIPE_BUF_ADDR_STATE,Av1ReferenceFrames)709 MHW_SETPAR_DECL_SRC(VDENC_PIPE_BUF_ADDR_STATE, Av1ReferenceFrames)
710 {
711     auto trackedBuf = m_basicFeature->m_trackedBuf;
712     ENCODE_CHK_NULL_RETURN(trackedBuf);
713 
714     auto picParams = m_basicFeature->m_av1PicParams;
715     ENCODE_CHK_NULL_RETURN(picParams);
716 
717     uint8_t fwdRefNum = 0, bwdRefNum = 0;
718     ENCODE_CHK_STATUS_RETURN(GetFwdBwdRefNum(fwdRefNum, bwdRefNum));
719     params.numActiveRefL0 = fwdRefNum;
720     params.numActiveRefL1 = bwdRefNum;
721 
722     uint8_t refFlag = m_refFrameFlags;
723     ConsolidateRefFlag(refFlag, picParams);
724 
725     uint8_t j = 0;
726     for (auto i = 0; i < av1NumInterRefFrames; i++)
727     {
728         if (refFlag & (AV1_ENCODE_GET_REF_FALG(i)))
729         {
730             auto scalingIdx = m_refList[picParams->RefFrameList[picParams->ref_frame_idx[i]].FrameIdx]->ucScalingIdx;
731 
732             auto dsRefSurface4x = trackedBuf->GetSurface(m_enc4xRefBufType, scalingIdx);
733             ENCODE_CHK_NULL_RETURN(dsRefSurface4x);
734 
735             auto dsRefSurface8x = trackedBuf->GetSurface(m_enc8xRefBufType, scalingIdx);
736             ENCODE_CHK_NULL_RETURN(dsRefSurface8x);
737 
738             if (m_encUsePostCdefAsRef)
739             {
740                 auto refPostCdefReconSurface = trackedBuf->GetSurface(m_encRefBufType, scalingIdx);
741                 ENCODE_CHK_NULL_RETURN(refPostCdefReconSurface);
742                 params.refs[j] = &refPostCdefReconSurface->OsResource;
743             }
744             else
745             {
746                 params.refs[j] = &m_currRefPic[i]->OsResource;
747             }
748 
749             params.refsDsStage1[j] = &dsRefSurface8x->OsResource;
750             params.refsDsStage2[j] = &dsRefSurface4x->OsResource;
751             j++;
752         }
753     }
754 
755     if (j != fwdRefNum + bwdRefNum)
756     {
757         ENCODE_ASSERTMESSAGE("The sum of forward reference frame number and backword reference frame number is incorrect.");
758 
759         return MOS_STATUS_INVALID_PARAMETER;
760     }
761 
762     if (m_basicFeature->m_pictureCodingType != I_TYPE && picParams->primary_ref_frame != av1PrimaryRefNone)
763     {
764         uint8_t frameIdx = picParams->RefFrameList[picParams->ref_frame_idx[picParams->primary_ref_frame]].FrameIdx;
765 
766         uint8_t idxForTempMV = m_refList[frameIdx]->ucScalingIdx;
767 
768         params.colMvTempBuffer[0] = trackedBuf->GetBuffer(BufferType::mvTemporalBuffer, idxForTempMV);
769     }
770 
771     params.lowDelayB = m_lowDelay;
772 
773     return MOS_STATUS_SUCCESS;
774 }
775 
MHW_SETPAR_DECL_SRC(VDENC_CMD2,Av1ReferenceFrames)776 MHW_SETPAR_DECL_SRC(VDENC_CMD2, Av1ReferenceFrames)
777 {
778     ENCODE_FUNC_CALL();
779 
780     uint8_t fwdRefNum = 0;
781     uint8_t bwdRefNum = 0;
782     ENCODE_CHK_STATUS_RETURN(GetFwdBwdRefNum(fwdRefNum, bwdRefNum));
783 
784     params.numRefL0 = fwdRefNum;
785     params.numRefL1 = bwdRefNum;
786 
787     if ((fwdRefNum == 3 && bwdRefNum == 0) || (fwdRefNum == 2 && bwdRefNum == 1) || (fwdRefNum == 3 && bwdRefNum == 3 && m_lowDelay))
788     {
789         m_basicFeature->m_enableNonDefaultMapping = true;
790     }
791 
792     uint8_t pocForL0L1[av1NumInterRefFrames] = { 1, 2, 3, 0xff, 0xff, 0xff, 0xff };
793     uint8_t frameIdxForL0L1[av1NumInterRefFrames] = { 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7 };
794 
795     const auto picParams = m_basicFeature->m_av1PicParams;
796     ENCODE_CHK_NULL_RETURN(picParams);
797 
798     const auto frame_type = static_cast<Av1FrameType>(picParams->PicFlags.fields.frame_type);
799     params.pictureType = (frame_type == keyFrame)
800         ? AV1_I_FRAME : (m_lowDelay ? (m_PFrame ? AV1_P_FRAME : AV1_GPB_FRAME) : AV1_B_FRAME);
801 
802     if (AV1_KEY_OR_INRA_FRAME(frame_type))
803     {
804         std::fill_n(&pocForL0L1[0], av1NumInterRefFrames, (uint8_t)0);
805         std::fill_n(&frameIdxForL0L1[0], av1NumInterRefFrames, (uint8_t)0);
806     }
807     else if (m_enable_order_hint)
808     {
809         auto ref_frame_ctrl0 = picParams->ref_frame_ctrl_l0;
810         auto ref_frame_ctrl1 = picParams->ref_frame_ctrl_l1;
811 
812         uint8_t ref_frame_ctrl_l0 = RefFrameL0L1(ref_frame_ctrl0);
813         uint8_t ref_frame_ctrl_l1 = RefFrameL0L1(ref_frame_ctrl1);
814 
815         auto fwdRef = 0;
816         for (uint8_t i = 0; i < av1NumInterRefFrames; i++)
817         {
818             // Function GetFwdBwdRefNum has already ensured that forward reference number is <= 2 and backward reference number is <= 1
819             if ((ref_frame_ctrl_l0 & AV1_ENCODE_GET_REF_FALG(i)) &&
820                 !(m_refFrameBiasFlagsForRefManagement.value & AV1_ENCODE_GET_REF_FALG(i)))
821             {
822                 auto idx = picParams->ref_frame_idx[i];
823                 auto frameIdx = picParams->RefFrameList[idx].FrameIdx;
824                 frameIdxForL0L1[fwdRef] = frameIdx;
825                 pocForL0L1[fwdRef++] = picParams->order_hint - m_refList[frameIdx]->m_orderHint;
826             }
827             if ((ref_frame_ctrl_l1 & AV1_ENCODE_GET_REF_FALG(i)) &&
828                 (m_refFrameBiasFlagsForRefManagement.value & AV1_ENCODE_GET_REF_FALG(i)))
829             {
830                 auto idx = picParams->ref_frame_idx[i];
831                 auto frameIdx = picParams->RefFrameList[idx].FrameIdx;
832                 frameIdxForL0L1[3] = frameIdx;
833                 pocForL0L1[3] = picParams->order_hint - m_refList[frameIdx]->m_orderHint;
834             }
835         }
836     }
837 
838     params.pocL0Ref0 = pocForL0L1[0];
839     params.pocL0Ref1 = pocForL0L1[1];
840     params.pocL0Ref2 = pocForL0L1[2];
841     params.pocL1Ref0 = pocForL0L1[3];
842     params.frameIdxL0Ref0 = frameIdxForL0L1[0];
843     params.frameIdxL0Ref1 = frameIdxForL0L1[1];
844     params.frameIdxL0Ref2 = frameIdxForL0L1[2];
845     params.frameIdxL1Ref0 = frameIdxForL0L1[3];
846 
847     if (params.pictureType == AV1_P_FRAME)
848     {
849         if (params.numRefL0 == 1)
850         {
851             params.av1RefId[0][0] = lastFrame;
852         }
853         else if (params.numRefL0 == 2)
854         {
855             params.av1RefId[0][0] = lastFrame;
856             params.av1RefId[0][1] = goldenFrame;
857         }
858         else
859         {
860             params.av1RefId[0][0] = lastFrame;
861             params.av1RefId[0][1] = goldenFrame;
862             params.av1RefId[0][2] = altRefFrame;
863         }
864     }
865     else if (params.pictureType == AV1_GPB_FRAME)
866     {
867         params.numRefL1 = params.numRefL0;
868 
869         if (params.numRefL0 == 1)
870         {
871             params.av1RefId[0][0] = bwdRefFrame;
872             params.av1RefId[1][0] = altRefFrame;
873         }
874         else if (params.numRefL0 == 2)
875         {
876             params.av1RefId[0][0] = lastFrame;
877             params.av1RefId[0][1] = last2Frame;
878             params.av1RefId[1][0] = bwdRefFrame;
879             params.av1RefId[1][1] = altRef2Frame;
880         }
881         else
882         {
883             params.av1RefId[0][0] = lastFrame;
884             params.av1RefId[0][1] = last2Frame;
885             params.av1RefId[0][2] = last3Frame;
886             params.av1RefId[1][0] = bwdRefFrame;
887             params.av1RefId[1][1] = altRef2Frame;
888             params.av1RefId[1][2] = altRefFrame;
889         }
890     }
891     else if (params.pictureType == AV1_B_FRAME)
892     {
893         if (params.numRefL0 == 1)
894         {
895             params.av1RefId[0][0] = lastFrame;
896             params.av1RefId[1][0] = bwdRefFrame;
897         }
898         else if (params.numRefL0 == 2)
899         {
900             params.av1RefId[0][0] = lastFrame;
901             params.av1RefId[0][1] = last2Frame;
902             params.av1RefId[1][0] = bwdRefFrame;
903         }
904         else
905         {
906             params.av1RefId[0][0] = lastFrame;
907             params.av1RefId[0][1] = last2Frame;
908             params.av1RefId[0][2] = last3Frame;
909             params.av1RefId[1][0] = bwdRefFrame;
910         }
911     }
912 
913     CODEC_Ref_Frame_Ctrl_AV1 refCtrlL0 = m_basicFeature->m_av1PicParams->ref_frame_ctrl_l0;
914     CODEC_Ref_Frame_Ctrl_AV1 refCtrlL1 = m_basicFeature->m_av1PicParams->ref_frame_ctrl_l1;
915     if (m_basicFeature->m_enableNonDefaultMapping)
916     {
917         params.av1RefId[0][0] = refCtrlL0.RefFrameCtrl.fields.search_idx0;
918         params.av1RefId[0][1] = refCtrlL0.RefFrameCtrl.fields.search_idx1;
919         params.av1RefId[0][2] = refCtrlL0.RefFrameCtrl.fields.search_idx2;
920         params.av1RefId[0][3] = refCtrlL0.RefFrameCtrl.fields.search_idx3;
921         params.av1RefId[1][0] = refCtrlL1.RefFrameCtrl.fields.search_idx0;
922         params.av1RefId[1][1] = refCtrlL1.RefFrameCtrl.fields.search_idx1;
923         params.av1RefId[1][2] = refCtrlL1.RefFrameCtrl.fields.search_idx2;
924         params.av1RefId[1][3] = refCtrlL1.RefFrameCtrl.fields.search_idx3;
925     }
926 
927     return MOS_STATUS_SUCCESS;
928 }
929 
MHW_SETPAR_DECL_SRC(AVP_PIC_STATE,Av1ReferenceFrames)930 MHW_SETPAR_DECL_SRC(AVP_PIC_STATE, Av1ReferenceFrames)
931 {
932     ENCODE_FUNC_CALL();
933 
934     params.postCdefReconPixelStreamoutEn = m_encUsePostCdefAsRef ? true : false;
935 
936     params.refFrameRes[intraFrame]    = CAT2SHORTS(m_currRefList->m_frameWidth - 1, m_currRefList->m_frameHeight - 1);
937     params.refScaleFactor[intraFrame] = CAT2SHORTS(m_av1ScalingFactor, m_av1ScalingFactor);
938     params.refOrderHints[intraFrame]  = m_currRefList->m_orderHint;
939     params.refFrameSide               = 0;
940 
941     uint32_t horizontalScaleFactor, verticalScaleFactor;
942 
943     params.refFrameBiasFlag = m_refFrameBiasFlagsForPak.value << 1;
944 
945     for (auto i = 0; i < av1NumInterRefFrames; i++)
946     {
947         if (!AV1_KEY_OR_INRA_FRAME(m_basicFeature->m_av1PicParams->PicFlags.fields.frame_type))
948         {
949             horizontalScaleFactor = (m_currRefPic[i]->dwWidth * m_av1ScalingFactor + (m_basicFeature->m_oriFrameWidth >> 1)) / m_basicFeature->m_oriFrameWidth;
950             verticalScaleFactor   = (m_currRefPic[i]->dwHeight * m_av1ScalingFactor + (m_basicFeature->m_oriFrameHeight >> 1)) / m_basicFeature->m_oriFrameHeight;
951 
952             params.refFrameRes[i + lastFrame]    = CAT2SHORTS(m_currRefPic[i]->dwWidth - 1, m_currRefPic[i]->dwHeight - 1);
953             params.refScaleFactor[i + lastFrame] = CAT2SHORTS(verticalScaleFactor, horizontalScaleFactor);
954             params.refOrderHints[i + lastFrame]  = m_currRefList->m_refOrderHint[i];
955         }
956         else
957         {
958             params.refFrameRes[i + lastFrame]    = params.refFrameRes[intraFrame];
959             params.refScaleFactor[i + lastFrame] = params.refScaleFactor[intraFrame];
960             params.refOrderHints[i + lastFrame]  = params.refOrderHints[intraFrame];
961         }
962 
963         if (GetRelativeDist(params.refOrderHints[i + lastFrame], m_currRefList->m_orderHint) > 0 ||
964             params.refOrderHints[i + lastFrame] == m_currRefList->m_orderHint)
965         {
966             params.refFrameSide |= 1 << (i + lastFrame);
967         }
968     }
969 
970     const auto picParams = m_basicFeature->m_av1PicParams;
971     ENCODE_CHK_NULL_RETURN(picParams);
972     int skipModeFrame[2] = {0};
973 
974     if ((picParams->PicFlags.fields.frame_type != keyFrame) && !m_lowDelay)
975     {
976         int ref_frame_offset[2] = {-1, INT_MAX};
977         int ref_idx[2]          = {-1, -1};
978 
979         for (int i = lastFrame; i <= av1NumInterRefFrames; i++)
980         {
981             int ref_offset = params.refOrderHints[i];
982             if (m_refFrameFlags & (AV1_ENCODE_GET_REF_FALG((i - 1))))
983             {
984                 if (GetRelativeDist(ref_offset, m_currRefList->m_orderHint) < 0)
985                 {
986                     // Forward reference
987                     if (ref_frame_offset[0] == -1 || GetRelativeDist(ref_offset, ref_frame_offset[0]) > 0)
988                     {
989                         ref_frame_offset[0] = ref_offset;
990                         ref_idx[0]          = i;
991                     }
992                 }
993                 else if (GetRelativeDist(ref_offset, m_currRefList->m_orderHint) > 0)
994                 {
995                     // Backward reference
996                     if (ref_frame_offset[1] == INT_MAX || GetRelativeDist(ref_offset, ref_frame_offset[1]) < 0)
997                     {
998                         ref_frame_offset[1] = ref_offset;
999                         ref_idx[1]          = i;
1000                     }
1001                 }
1002             }
1003         }
1004 
1005         if (ref_idx[0] != -1 && ref_idx[1] != -1)
1006         {
1007             // == Bi-directional prediction ==
1008             skipModeFrame[0] = (uint8_t)(ref_idx[0] < ref_idx[1]) ? ref_idx[0] : ref_idx[1];
1009             skipModeFrame[1] = (uint8_t)(ref_idx[0] > ref_idx[1]) ? ref_idx[0] : ref_idx[1];
1010         }
1011         else if (ref_idx[0] != -1 && ref_idx[1] == -1)
1012         {
1013             // == Forward prediction only ==
1014             // Identify the second nearest forward reference.
1015             ref_frame_offset[1] = -1;
1016             for (int i = lastFrame; i <= av1NumInterRefFrames; i++)
1017             {
1018                 if (m_refFrameFlags & (AV1_ENCODE_GET_REF_FALG((i - 1))))
1019                 {
1020                     int ref_offset = params.refOrderHints[i];
1021                     if ((ref_frame_offset[0] != -1 && (GetRelativeDist(ref_offset, ref_frame_offset[0]) < 0)) &&
1022                         (ref_frame_offset[1] == -1 || (GetRelativeDist(ref_offset, ref_frame_offset[1]) > 0)))
1023                     {
1024                         // Second closest forward reference
1025                         ref_frame_offset[1] = ref_offset;
1026                         ref_idx[1]          = i;
1027                     }
1028                 }
1029             }
1030 
1031             if (ref_frame_offset[1] >= 0)
1032             {
1033                 skipModeFrame[0] = (uint8_t)(ref_idx[0] < ref_idx[1]) ? ref_idx[0] : ref_idx[1];
1034                 skipModeFrame[1] = (uint8_t)(ref_idx[0] > ref_idx[1]) ? ref_idx[0] : ref_idx[1];
1035             }
1036         }
1037     }
1038 
1039     return MOS_STATUS_SUCCESS;
1040 }
1041 
MHW_SETPAR_DECL_SRC(AVP_PIPE_BUF_ADDR_STATE,Av1ReferenceFrames)1042 MHW_SETPAR_DECL_SRC(AVP_PIPE_BUF_ADDR_STATE, Av1ReferenceFrames)
1043 {
1044     ENCODE_CHK_NULL_RETURN(m_basicFeature);
1045     ENCODE_CHK_NULL_RETURN(m_basicFeature->m_trackedBuf);
1046 
1047     const auto picParams = m_basicFeature->m_av1PicParams;
1048     ENCODE_CHK_NULL_RETURN(picParams);
1049 
1050     auto seqParams = m_basicFeature->m_av1SeqParams;
1051     ENCODE_CHK_NULL_RETURN(seqParams);
1052 
1053     auto currRawOrRecon = seqParams->SeqFlags.fields.UseRawReconRef ?
1054         &m_basicFeature->m_rawSurface :
1055         &m_basicFeature->m_reconSurface;
1056 
1057     // fullfill reference frames
1058 
1059     if (!AV1_KEY_OR_INRA_FRAME(picParams->PicFlags.fields.frame_type))
1060     {
1061         //set for INTRA_FRAME
1062         params.refs[0]            = &currRawOrRecon->OsResource;
1063         uint8_t currSlotIndex      = m_basicFeature->m_trackedBuf->GetCurrIndex();
1064         params.colMvTempBuffer[0] = m_basicFeature->m_trackedBuf->GetBuffer(BufferType::mvTemporalBuffer, currSlotIndex);
1065 
1066         //set for reference frames and collated temoral buffer
1067         for (uint8_t i = 0; i < av1NumInterRefFrames; i++)
1068         {
1069             params.refs[i + lastFrame] = &m_currRefPic[i]->OsResource;
1070 
1071             if (m_refFrameFlags & (AV1_ENCODE_GET_REF_FALG(i)))
1072             {
1073                 auto idx      = picParams->ref_frame_idx[i];
1074                 auto frameIdx = picParams->RefFrameList[idx].FrameIdx;
1075 
1076                 uint8_t mvTempBufIdx      = m_refList[frameIdx]->ucScalingIdx;
1077                 auto    mvTempBufferForRef = m_basicFeature->m_trackedBuf->GetBuffer(BufferType::mvTemporalBuffer, mvTempBufIdx);
1078                 ENCODE_CHK_NULL_RETURN(mvTempBufferForRef);
1079                 params.colMvTempBuffer[i + lastFrame] = mvTempBufferForRef;
1080             }
1081         }
1082     }
1083     else
1084     {
1085         // reference surface should be nullptr when key_frame == true or intra only frame
1086         for (auto j = 0; j < av1TotalRefsPerFrame; j++)
1087         {
1088             params.refs[j] = nullptr;
1089         }
1090     }
1091 
1092     // error concealment for the unset reference and mv buffers addresses
1093     for (uint8_t i = 0; i < av1TotalRefsPerFrame; i++)
1094     {
1095         if (params.refs[i] == nullptr)
1096         {
1097             params.refs[i] = &m_firstValidRefPic->OsResource;
1098         }
1099         if (params.colMvTempBuffer[i] == nullptr)
1100         {
1101             // set for collocated MV temporal buffer
1102             auto currRefIdx  = picParams->CurrReconstructedPic.FrameIdx;
1103             auto mvTempBuffer = m_basicFeature->m_trackedBuf->GetBuffer(BufferType::mvTemporalBuffer, m_refList[currRefIdx]->ucScalingIdx);
1104             ENCODE_CHK_NULL_RETURN(mvTempBuffer);
1105             params.colMvTempBuffer[i] = mvTempBuffer;
1106         }
1107     }
1108 
1109     if (picParams->PicFlags.fields.disable_frame_end_update_cdf || m_primaryRefFrame == av1PrimaryRefNone)
1110     {
1111         params.cdfTableInitBuffer       = m_basicFeature->m_defaultCdfBufferInUse;
1112         params.cdfTableInitBufferOffset = m_basicFeature->m_defaultCdfBufferInUseOffset;
1113     }
1114     else
1115     {
1116         ENCODE_CHK_COND_RETURN(m_primaryRefFrame >= av1PrimaryRefNone, "ERROR - primary ref frame is invalid!");
1117         uint8_t refPicIndex = picParams->ref_frame_idx[m_primaryRefFrame];
1118         ENCODE_CHK_COND_RETURN(refPicIndex >= CODEC_AV1_NUM_REF_FRAMES, "ERROR - ref pic idx is invalid!");
1119         auto    refPic      = picParams->RefFrameList[refPicIndex];
1120         if (!CodecHal_PictureIsInvalid(refPic))
1121         {
1122             uint8_t prevFrameIdx             = refPic.FrameIdx;
1123             auto    refScalingIdx            = m_refList[prevFrameIdx]->ucScalingIdx;
1124             params.cdfTableInitBuffer       = m_basicFeature->m_trackedBuf->GetBuffer(BufferType::bwdAdaptCdfBuffer, refScalingIdx);
1125             params.cdfTableInitBufferOffset = 0;
1126         }
1127     }
1128 
1129     params.cdfTableBwdAdaptBuffer = m_basicFeature->m_trackedBuf->GetBuffer(BufferType::bwdAdaptCdfBuffer, m_currRefList->ucScalingIdx);
1130 
1131     return MOS_STATUS_SUCCESS;
1132 }
1133 
MHW_SETPAR_DECL_SRC(AVP_INTER_PRED_STATE,Av1ReferenceFrames)1134 MHW_SETPAR_DECL_SRC(AVP_INTER_PRED_STATE, Av1ReferenceFrames)
1135 {
1136     const auto picParams = m_basicFeature->m_av1PicParams;
1137 
1138     ENCODE_CHK_NULL_RETURN(picParams);
1139 
1140     for (auto ref = 0; ref < av1NumInterRefFrames; ref++)
1141     {
1142         if (m_refFrameFlags & (AV1_ENCODE_GET_REF_FALG(ref)))
1143         {
1144             auto index       = picParams->ref_frame_idx[ref];
1145             auto refFrameIdx = picParams->RefFrameList[index].FrameIdx;
1146             for (auto i = 0; i < 7; i++)
1147             {
1148                 params.savedRefOrderHints[ref][i] = m_refList[refFrameIdx]->m_refOrderHint[i];
1149             }
1150         }
1151     }
1152 
1153     return MOS_STATUS_SUCCESS;
1154 }
1155 
MHW_SETPAR_DECL_SRC(AVP_SURFACE_STATE,Av1ReferenceFrames)1156 MHW_SETPAR_DECL_SRC(AVP_SURFACE_STATE, Av1ReferenceFrames)
1157 {
1158     if (params.surfaceStateId == av1IntraFrame)
1159     {
1160         params.pitch   = m_firstValidRefPic->dwPitch;
1161         params.uOffset = m_firstValidRefPic->YoffsetForUplane;
1162         params.vOffset = m_firstValidRefPic->YoffsetForVplane;
1163 
1164     }
1165     else
1166     {
1167         if (params.surfaceStateId < av1LastRef || params.surfaceStateId > av1AltRef)
1168         {
1169             ENCODE_ASSERTMESSAGE("Incorrect reference passed for AVP_SURFACE_STATE");
1170             return MOS_STATUS_INVALID_PARAMETER;
1171         }
1172         params.pitch   = m_currRefPic[params.surfaceStateId - av1LastRef]->dwPitch;
1173         params.uOffset = m_currRefPic[params.surfaceStateId - av1LastRef]->YoffsetForUplane;
1174         params.vOffset = m_currRefPic[params.surfaceStateId - av1LastRef]->YoffsetForVplane;
1175 
1176     }
1177     std::copy(std::begin(m_refMmcState), std::end(m_refMmcState), params.mmcState);
1178     params.compressionFormat = m_refCompressionFormat;
1179 
1180     return MOS_STATUS_SUCCESS;
1181 }
1182 
1183 }  // namespace encode
1184