1 /*
2 * Copyright (c) 2019-2022, Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included
12 * in all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 */
22 //!
23 //! \file     encode_vp9_reference_frames.h
24 //! \brief    Defines reference list related logic for encode vp9
25 //!
26 #ifndef __ENCODE_VP9_REFERENCE_FRAMES_H__
27 #define __ENCODE_VP9_REFERENCE_FRAMES_H__
28 
29 #include "codec_def_common.h"
30 #include "codec_def_common_vp9.h"
31 #include "codec_def_encode_vp9.h"
32 #include "mhw_vdbox.h"
33 #include "encode_utils.h"
34 #include "mhw_vdbox_hcp_itf.h"
35 #include "mhw_vdbox_vdenc_itf.h"
36 
37 namespace encode
38 {
39 
40 class Vp9VdencPipeline;
41 
42 //!
43 //! \enum     DYS_REF_FLAGS
44 //! \brief    DYS reference flags
45 //!
46 enum DYS_REF_FLAGS
47 {
48     DYS_REF_NONE   = 0,
49     DYS_REF_LAST   = (1 << 0),
50     DYS_REF_GOLDEN = (1 << 1),
51     DYS_REF_ALT    = (1 << 2),
52 };
53 
54 class Vp9BasicFeature;
55 
56 class Vp9ReferenceFrames : public mhw::vdbox::hcp::Itf::ParSetting, public mhw::vdbox::vdenc::Itf::ParSetting
57 {
58 public:
59     //!
60     //! \brief  Vp9ReferenceFrames constructor
61     //!
Vp9ReferenceFrames()62     Vp9ReferenceFrames(){};
63 
64     //!
65     //! \brief  Vp9ReferenceFrames destructor
66     //!
67     ~Vp9ReferenceFrames();
68 
69     //!
70     //! \brief  Initialize reference frame
71     //! \param  [in] params
72     //!         Pointer to Vp9BasicFeature
73     //! \return MOS_STATUS
74     //!         MOS_STATUS_SUCCESS if success, else fail reason
75     //!
76     MOS_STATUS Init(Vp9BasicFeature *basicFeature);
77 
78     //!
79     //! \brief  Update reference frame
80     //! \return MOS_STATUS
81     //!         MOS_STATUS_SUCCESS if success, else fail reason
82     //!
83     MOS_STATUS Update();
84 
85     //!
86     //! \brief  Get picture index
87     //! \param  [in] idx
88     //!         Index of pic index
89     //! \return CODEC_PIC_ID
90     //!         CODEC_PIC_ID refer to the picture index
91     //!
GetPicIndex(uint8_t idx)92     CODEC_PIC_ID GetPicIndex(uint8_t idx) { return m_picIdx[idx]; };
93 
94     //!
95     //! \brief  Get reference list index
96     //! \param  [in] idx
97     //!         Index of pic index
98     //! \return uint8_t
99     //!         reference list index
100     //!
GetRefListIndex(uint8_t idx)101     uint8_t GetRefListIndex(uint8_t idx) { return m_picIdx[idx].ucPicIdx; };
102 
103     //!
104     //! \brief  Get current reference list
105     //! \return PCODEC_REF_LIST
106     //!         Pointer of current reference list
107     //!
GetCurrRefList()108     PCODEC_REF_LIST GetCurrRefList() { return m_currRefList; };
109 
110     //!
111     //! \brief  Get reference list
112     //! \return PCODEC_REF_LIST*
113     //!         Pointer of reference list
114     //!
GetRefList()115     PCODEC_REF_LIST* GetRefList() { return m_refList; };
116 
117     //!
118     //! \brief  Set Hcp surface parameters
119     //! \param  [in] surfaceParams
120     //!         Pointer to MHW_VDBOX_SURFACE_PARAMS
121     //! \return MOS_STATUS
122     //!         MOS_STATUS_SUCCESS if success, else fail reason
123     MOS_STATUS SetHcpSurfaceParams(MHW_VDBOX_SURFACE_PARAMS *surfaceParams);
124 
125     //!
126     //! \brief  Set Hcp surface parameters (DYS)
127     //! \param  [in] surfaceParams
128     //!         Pointer to MHW_VDBOX_SURFACE_PARAMS
129     //! \return MOS_STATUS
130     //!         MOS_STATUS_SUCCESS if success, else fail reason
131     MOS_STATUS SetDysHcpSurfaceParams(MHW_VDBOX_SURFACE_PARAMS *surfaceParams);
132 
133     //!
134     //! \brief  Set Hcp pipe buffer address parameter (DYS)
135     //! \param  [in] pipeBufAddrParams
136     //!         Pointer to MHW_VDBOX_PIPE_BUF_ADDR_PARAMS
137     //! \return MOS_STATUS
138     //!         MOS_STATUS_SUCCESS if success, else fail reason
139     MOS_STATUS SetDysHcpPipeBufAddrParams(MHW_VDBOX_PIPE_BUF_ADDR_PARAMS *pipeBufAddrParams);
140 
141     //!
142     //! \brief  Set Vdenc surface parameters
143     //! \param  [in] surfaceParams
144     //!         Pointer to MHW_VDBOX_SURFACE_PARAMS
145     //! \return MOS_STATUS
146     //!         MOS_STATUS_SUCCESS if success, else fail reason
147     MOS_STATUS SetVdencSurfaceParams(MHW_VDBOX_SURFACE_PARAMS *surfaceParams);
148 
149     //!
150     //! \brief  Set VDEnc pipe buffer address parameter
151     //! \param  [in] pipeBufAddrParams
152     //!         Pointer to MHW_VDBOX_PIPE_BUF_ADDR_PARAMS
153     //! \return MOS_STATUS
154     //!         MOS_STATUS_SUCCESS if success, else fail reason
155     //!
156     MOS_STATUS SetVdencPipeBufAddrParams(MHW_VDBOX_PIPE_BUF_ADDR_PARAMS *pipeBufAddrParams);
157 
158     //!
159     //! \brief  Reference frame flags
160     //! \return Refefence frame flags
161     //!
RefFrameFlags()162     uint8_t RefFrameFlags() { return m_refFrameFlags; }
163 
164     //!
165     //! \brief  Number of reference frames
166     //! \return Number of reference frames
167     //!
NumRefFrames()168     uint8_t NumRefFrames() const { return m_numRefFrames; }
169 
170     //!
171     //! \brief  Dynamic scaling reference frame flags
172     //! \return Dynamic scaling Refefence frame flags
173     //!
DysRefFrameFlags()174     uint8_t DysRefFrameFlags() const { return m_dysRefFrameFlags; }
175 
176     //!
177     //! \brief  Set dynamic scaling reference frame flags
178     //! \param  [in] dysRefFrameFlags
179     //!         Dynamic scaling reference frame flags
180     //!
SetDysRefFrameFlags(uint8_t dysRefFrameFlags)181     void SetDysRefFrameFlags(uint8_t dysRefFrameFlags) { m_dysRefFrameFlags = dysRefFrameFlags; }
182 
183     //!
184     //! \brief  Get current dynamic scaling reference list
185     //! \return PCODEC_REF_LIST
186     //!         Pointer of current dynamic scaling reference list
187     //!
GetCurrDysRefList()188     PCODEC_REF_LIST GetCurrDysRefList() { return m_currDysRefList; };
189 
190     //!
191     //! \brief  Get dynamic scaling reference index.
192     //!         For CU_DATA use, 0=intra, 1=Last, 2=Golden, 3=Alt
193     //! \return uint8_t
194     //!         Dynamic scaling reference list index
195     //!
GetDysRefIndex()196     uint8_t GetDysRefIndex() { return m_dysRefIndex; };
197 
198     //!
199     //! \brief  Dump input resources or infomation before submit
200     //! \return MOS_STATUS
201     //!         MOS_STATUS_SUCCESS if success, else fail reason
202     //!
203     MOS_STATUS DumpInput(Vp9VdencPipeline *pipeline);
204 
205     //!
206     //! \brief  Set DynamicScaling flag
207     //! \param  [in] bool
208     //!         Dynamic Scaling value
209     //! \return MOS_STATUS
210     //!         MOS_STATUS_SUCCESS if success, else fail reason
211     //!
212     MOS_STATUS SetDysValue(bool value);
213 
214     //!
215     //! \brief MHW parameters declaration
216     //!
217     MHW_SETPAR_DECL_HDR(HCP_VP9_PIC_STATE);
218     MHW_SETPAR_DECL_HDR(HCP_PIPE_BUF_ADDR_STATE);
219     MHW_SETPAR_DECL_HDR(VDENC_PIPE_BUF_ADDR_STATE);
220 
221 protected:
222 
223     //!
224     //! \brief   Set up internal reference frame flags
225     //! \return  MOS_STATUS
226     //!          MOS_STATUS_SUCCESS if success, else fail reason
227     //!
228     MOS_STATUS SetupRefFlags();
229 
230     //!
231     //! \brief   Set up internal reference picture
232     //! \return  MOS_STATUS
233     //!          MOS_STATUS_SUCCESS if success, else fail reason
234     //!
235     MOS_STATUS SetupRefPic();
236 
237     //!
238     //! \brief   Set up internal dynamic scaling reference picture
239     //! \return  MOS_STATUS
240     //!          MOS_STATUS_SUCCESS if success, else fail reason
241     //!
242     MOS_STATUS SetupDysRefPic();
243 
244     //!
245     //! \brief   Set up reference picture index array
246     //! \return  MOS_STATUS
247     //!          MOS_STATUS_SUCCESS if success, else fail reason
248     //!
249     MOS_STATUS SetupRefIndex();
250 
251     uint32_t usePrevInFindMvRef() const;
252 
253     //!
254     //! \enum     Vp9ReferenceId
255     //! \brief    VP9 referebce frame identify
256     //!
257     enum Vp9ReferenceId
258     {
259         lastFrame = 0,
260         goldenFrame,
261         altFrame,
262         maxReferenceIds
263     };
264 
265     Vp9BasicFeature *m_basicFeature                                   = nullptr;  //!< VP9 parameter
266     CODEC_PIC_ID     m_picIdx[CODEC_VP9_NUM_REF_FRAMES]               = {};       //!< Reference picture index array
267     PCODEC_REF_LIST  m_refList[CODECHAL_NUM_UNCOMPRESSED_SURFACE_VP9] = {};       //!< Pointer to reference pictures
268     PCODEC_REF_LIST  m_currRefList                                    = nullptr;  //!< Current reference list
269     PCODEC_REF_LIST  m_currDysRefList                                 = nullptr;  //!< Current dynamic scaling reference list
270 
271     // m_refFrameFlags is to indicate which frames to be used as reference
272     // m_refFrameFlags & 0x01 != 0: Last ref frames used as reference
273     // m_refFrameFlags & 0x02 != 0: Golden ref frames used as reference
274     // m_refFrameFlags & 0x04 != 0: Alternate ref frames used as reference
275     uint8_t m_refFrameFlags    = 0;  //!< m_refFrameFlags is to indicate which frames to be used as reference
276     uint8_t m_numRefFrames     = 0;  //!< number of current used reference surfaces
277     uint8_t m_dysRefFrameFlags = 0;  //!< Dynamic scaling reference frame flags
278     uint8_t m_dysCurrFrameFlag = 0;  //!< Current dynamic scaling current reference frame flags
279     uint8_t m_dysRefIndex      = 0;  //!< Dynamic reference index (for CU_DATA use, 0=intra, 1=Last, 2=Golden, 3=Alt)
280 
281     // pointer to the reference surfaces
282     PMOS_SURFACE m_lastRefPic   = nullptr;
283     PMOS_SURFACE m_goldenRefPic = nullptr;
284     PMOS_SURFACE m_altRefPic    = nullptr;
285 
286     PMOS_SURFACE m_refSurface[maxReferenceIds]          = {};
287     PMOS_SURFACE m_refSurfaceNonScaled[maxReferenceIds] = {};
288     PMOS_SURFACE m_dsRefSurface4x[maxReferenceIds]      = {};
289     PMOS_SURFACE m_dsRefSurface8x[maxReferenceIds]      = {};
290 
291     // Dynamic scaling reference surfaces
292     PMOS_SURFACE m_dysRefSurface[maxReferenceIds] = {};
293 
294     mutable bool m_dysEnabled = false;
295 MEDIA_CLASS_DEFINE_END(encode__Vp9ReferenceFrames)
296 };
297 
298 }  // namespace
299 
300 #endif
301