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