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.h
24 //! \brief    Defines reference list related logic for encode av1
25 //!
26 #ifndef __ENCODE_AV1_REFERENCE_FRAMES_H__
27 #define __ENCODE_AV1_REFERENCE_FRAMES_H__
28 
29 #include "codec_def_encode_av1.h"
30 #include "mhw_vdbox.h"
31 #include "mhw_vdbox_vdenc_itf.h"
32 #include "mhw_vdbox_avp_itf.h"
33 #include "encode_tracked_buffer.h"
34 
35 namespace encode
36 {
37 #define AV1_ENCODE_GET_REF_FALG(i) (0x1 << i)
38 
39 class Av1BasicFeature;
40 class Av1VdencPipeline;
41 
42 class Av1ReferenceFrames : public mhw::vdbox::vdenc::Itf::ParSetting, public mhw::vdbox::avp::Itf::ParSetting
43 {
44 public:
45 
46     //!
47     //! \brief  Av1ReferenceFrames constructor
48     //!
Av1ReferenceFrames()49     Av1ReferenceFrames() {};
50 
51     //!
52     //! \brief  Av1ReferenceFrames deconstructor
53     //!
54     ~Av1ReferenceFrames();
55 
56     //!
57     //! \brief  Initialize reference frame
58     //! \param  [in] params
59     //!         Pointer to Av1BasicFeature
60     //! \return  MOS_STATUS
61     //!         MOS_STATUS_SUCCESS if success, else fail reason
62     //!
63     MOS_STATUS Init(Av1BasicFeature *basicFeature);
64 
65     //! \brief   Update reference frame
66     //! \return  MOS_STATUS
67     //!          MOS_STATUS_SUCCESS if success, else fail reason
68     //!
69     MOS_STATUS Update();
70 
71     MOS_STATUS UpdateRefFrameSize(uint32_t width, uint32_t height);
72 
73     //! \brief   Check if low delay mode
74     //! \return  bool
75     //!          true if it's low delay, false random access mode
76     //!
IsLowDelay()77     bool IsLowDelay() const { return m_lowDelay; };
78 
79     //! \brief   Check if is p frame
80     //! \return  bool
81     //!          true if it's p frame, false random access mode
82     //!
IsPFrame()83     bool IsPFrame() const { return m_PFrame; }
84 
85     //!
86     //! \brief  Get current reference list
87     //! \return  PCODEC_REF_LIST
88     //!         Pointer of current reference list
89     //!
GetCurrRefList()90     CODEC_REF_LIST_AV1 *GetCurrRefList() const { return m_currRefList; };
91 
92     //!
93     //! \brief  Get reference list
94     //! \return  PCODEC_REF_LIST *
95     //!         Pointer of current reference list
96     //!
GetRefList()97     PCODEC_REF_LIST_AV1 *GetRefList() { return m_refList; };
98 
99     //!
100     //! \brief  Get picture idx
101     //! \param  [in] idx
102     //!         id of RefFrameList
103     //! \return  CODEC_PIC_ID
104     //!         CODEC_PIC_ID refer to the FrameIdx
105     //!
GetPicId(uint8_t idx)106     CODEC_PIC_ID GetPicId(uint8_t idx) { return m_picIdx[idx]; };
107 
108     //!
109     //! \brief  Get Prime frame's reference list
110     //! \return  PCODEC_REF_LIST
111     //!         Pointer of Prime frame's reference list
112     //!
GetPrimaryRefList()113     CODEC_REF_LIST_AV1 *GetPrimaryRefList() const { return m_primaryRefList; };
114 
115     //!
116     //! \brief  Set whether to use postcdef as ENC ref
117     //! \return MOS_STATUS
118     //!         MOS_STATUS_SUCCESS if success, else fail reason
119     //!
120     MOS_STATUS SetPostCdefAsEncRef(bool flag);
121 
122     //!
123     //! \brief  Get reference scaling idx
124     //! \return std::vector<uint8_t>
125     //!         A vector of reference scaling idx
126     //!
127     std::vector<uint8_t> GetRefScalingIdx() const;
128 
129     //!
130     //! \brief  Get ENC reference surface
131     //! \return std::vector<PMOS_SURFACE>
132     //!         A vector of ENC reference surface
133     //!
134     std::vector<PMOS_SURFACE> GetEncRefSurface() const;
135 
136     //!
137     //! \brief  Get ENC 4x reference surface
138     //! \return std::vector<PMOS_SURFACE>
139     //!         A vector of ENC 4x reference surface
140     //!
141     std::vector<PMOS_SURFACE> GetEnc4xRefSurface() const;
142 
143     //!
144     //! \brief  Get ENC 8x reference surface
145     //! \return std::vector<PMOS_SURFACE>
146     //!         A vector of ENC 8x reference surface
147     //!
148     std::vector<PMOS_SURFACE> GetEnc8xRefSurface() const;
149 
150     //!
151     //! \brief  Get PAK reference surface
152     //! \return std::vector<PMOS_SURFACE>
153     //!         A vector of PAK reference surface
154     //!
155     std::vector<PMOS_SURFACE> GetPakRefSurface() const;
156 
157     //!
158     //! \brief  Get  get the forward and backward reference surface
159     //! \param  [in] refsPicList
160     //!         A vector contain forward and backward reference surface
161     //!
162     void GetFwdBwdRefPicList(CODEC_PICTURE (&refsPicList)[2][15]);
163 
164     //! \brief  Get  get current frame display order
165     //! \return int32_t
166     //!         frame display order
167     //!
168     int32_t GetFrameDisplayOrder();
169 
170     //!
171     //! \brief  Get  get the Picture Order Count values of reference pictures
172     //!          corresponding to the entries of RefFrameList[].
173     //! \param  [in] refsPOCList
174     //!         A vector contain reference frame POC
175     //!         [in] orderHint
176     //!         frame display order
177     //!
178     void GetRefFramePOC(int32_t (&refsPOCList)[15], int32_t const orderHint);
179 
180     bool CheckSegmentForPrimeFrame();
181     uint8_t RefFrameL0L1(CODEC_Ref_Frame_Ctrl_AV1 const &ref_frame_ctrl) const;
182 
183      //!
184     //! \brief  Dump input resources or infomation before submit
185     //! \return MOS_STATUS
186     //!         MOS_STATUS_SUCCESS if success, else fail reason
187     //!
188     MOS_STATUS DumpInput(Av1VdencPipeline *pipeline);
189 
190     MHW_SETPAR_DECL_HDR(VDENC_PIPE_BUF_ADDR_STATE);
191 
192     MHW_SETPAR_DECL_HDR(VDENC_CMD2);
193 
194     MHW_SETPAR_DECL_HDR(AVP_PIC_STATE);
195 
196     MHW_SETPAR_DECL_HDR(AVP_PIPE_BUF_ADDR_STATE);
197 
198     MHW_SETPAR_DECL_HDR(AVP_INTER_PRED_STATE);
199 
200     MHW_SETPAR_DECL_HDR(AVP_SURFACE_STATE);
201 
202 protected:
203     static const uint32_t      m_av1ScalingFactor       = (1 << 14);    //!< AV1 Scaling factor
204     //!
205     //! \brief   Set up internal reference frame flag and reference picture
206     //! \return  MOS_STATUS
207     //!          MOS_STATUS_SUCCESS if success, else fail reason
208     //!
209     MOS_STATUS SetupRefFlag();
210 
211     //!
212     //! \brief   Set up internal reference frame flag and reference picture
213     //! \return  MOS_STATUS
214     //!          MOS_STATUS_SUCCESS if success, else fail reason
215     //!
216     MOS_STATUS SetupCurrRefPic();
217 
218     //!
219     //! \brief   Set up internal reference frame flag and reference picture
220     //! \return  MOS_STATUS
221     //!          MOS_STATUS_SUCCESS if success, else fail reason
222     //!
223     MOS_STATUS SetupRefIdx();
224 
225     //!
226     //! \brief   Set up internal reference frame flag and reference picture
227     //! \return  MOS_STATUS
228     //!          MOS_STATUS_SUCCESS if success, else fail reason
229     //!
230     MOS_STATUS ValidateLowDelayBFrame();
231 
232     //!
233     //! \brief   Set up internal reference frame flag and reference picture
234     //! \return  MOS_STATUS
235     //!          MOS_STATUS_SUCCESS if success, else fail reason
236     //!
237     MOS_STATUS ValidatePFrame();
238 
239     int32_t GetRelativeDist(int32_t a, int32_t b) const;
240 
241     //!
242     //! \brief  Get FWD and BWD reference number
243     //! \return MOS_STATUS
244     //!         MOS_STATUS_SUCCESS if success, else fail reason
245     //!
246     virtual MOS_STATUS GetFwdBwdRefNum(uint8_t &fwdRefNum, uint8_t &bwdRefNum) const;
247 
248     Av1BasicFeature        *m_basicFeature = nullptr;                           //!< AV1 paramter
249     uint8_t                 m_primaryRefFrame = av1PrimaryRefNone;              //!< AV1 primary reference frame
250     PCODEC_REF_LIST_AV1     m_refList[CODEC_AV1_NUM_UNCOMPRESSED_SURFACE] = {}; //!< Pointer to all reference pictures
251     PCODEC_REF_LIST_AV1     m_currRefList = nullptr;                            //!< Current reference list
252     PCODEC_REF_LIST_AV1     m_primaryRefList = nullptr;                            //!< prime frame's reference list
253 
254     // m_refFrameFlags & 0x01 != 0: Last ref frames used as reference
255     // m_refFrameFlags & 0x02 != 0: Last2 ref frames used as reference
256     // m_refFrameFlags & 0x04 != 0: Last3 ref frames used as reference
257     // m_refFrameFlags & 0x08 != 0: Golden ref frames used as reference
258     // m_refFrameFlags & 0x10 != 0: Bwd ref frames used as reference
259     // m_refFrameFlags & 0x20 != 0: Alt ref frames used as reference
260     // m_refFrameFlags & 0x40 != 0: Alt2 ref frames used as reference
261     uint8_t                 m_refFrameFlags = 0;                     //!< m_refFrameFlags is to indicate which frames to be used as reference
262     uint8_t                 m_numRefFrames  = 0;                     //!< number of current used reference surfaces
263     PMOS_SURFACE            m_currRefPic[av1NumInterRefFrames] = {}; //!< pointer to the current used reference surfaces
264     PMOS_SURFACE            m_firstValidRefPic = nullptr;            //!< pointer to the first valid reference surfaces
265     MOS_MEMCOMP_STATE       m_refMmcState[av1TotalRefsPerFrame] = { MOS_MEMCOMP_DISABLED };
266     uint32_t                m_refCompressionFormat = 0;
267     CODEC_PIC_ID            m_picIdx[CODEC_AV1_NUM_REF_FRAMES] = {}; //!< keep a map of frame index
268     bool                    m_lowDelay = true;                       //!< Low delay flag
269     bool                    m_PFrame   = true;                       //!< P frame flag
270     bool                    m_enable_order_hint = false;
271     uint8_t                 m_orderHintBitsMinus1 = 0;
272     uint8_t                 m_orderHintCount[ENCODE_AV1_ORDER_HINT_SIZE];
273     int32_t                 m_frameOut = 0;                        //!<frame output number
274     int32_t                 m_prevFrameOffset = 0;
275     int32_t                 m_prevFrameDisplayerOrder = 0;
276 
277     bool       m_encUsePostCdefAsRef = false;
278     BufferType m_encRefBufType       = BufferType::postCdefReconSurface;
279     BufferType m_enc4xRefBufType     = BufferType::ds4xSurface;
280     BufferType m_enc8xRefBufType     = BufferType::ds8xSurface;
281     uint32_t   m_refWidth            = 0;
282     uint32_t   m_refHeight           = 0;
283 
284     union
285     {
286         struct
287         {
288             uint8_t LAST_FRAME    : 1;
289             uint8_t LAST2_FRAME   : 1;
290             uint8_t LAST3_FRAME   : 1;
291             uint8_t GOLDEN_FRAME  : 1;
292             uint8_t BWDREF_FRAME  : 1;
293             uint8_t ALTREF_FRAME  : 1;
294             uint8_t ALTREF2_FRAME : 1;
295             uint8_t Reserved1     : 1;
296         } fields;
297         uint8_t value;
298     } m_refFrameBiasFlagsForPak, m_refFrameBiasFlagsForRefManagement;
299 
300 MEDIA_CLASS_DEFINE_END(encode__Av1ReferenceFrames)
301 };
302 
303 }  // namespace encode
304 
305 #endif  // !__ENCODE_AV1_REFERENCE_FRAMES_H__
306