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_av1_stream_in.h
24 //! \brief    Defines the common interface for encode av1 stream in utility
25 //!
26 #ifndef __ENCODE_AV1_STREAM_IN_H__
27 #define __ENCODE_AV1_STREAM_IN_H__
28 #include "mhw_vdbox.h"
29 #include "encode_allocator.h"
30 #include "codec_def_encode_av1.h"
31 #include "mhw_vdbox_vdenc_itf.h"
32 #include "mhw_vdbox_avp_itf.h"
33 
34 namespace encode
35 {
36 struct VdencStreamInState
37 {
38     // DWORD 0
39     union
40     {
41         struct
42         {
43             uint32_t RoiCtrl : MOS_BITFIELD_RANGE(0, 7);
44             uint32_t MaxTuSize : MOS_BITFIELD_RANGE(8, 9);
45             uint32_t MaxCuSize : MOS_BITFIELD_RANGE(10, 11);
46             uint32_t NumImePredictors : MOS_BITFIELD_RANGE(12, 15);
47             uint32_t Reserved_0 : MOS_BITFIELD_RANGE(16, 20);
48             uint32_t ForceQPDelta : MOS_BITFIELD_BIT(21);
49             uint32_t PaletteDisable : MOS_BITFIELD_BIT(22);
50             uint32_t Reserved_1 : MOS_BITFIELD_BIT(23);
51             uint32_t PuTypeCtrl : MOS_BITFIELD_RANGE(24, 31);
52         };
53         uint32_t Value;
54     } DW0;
55 
56     // DWORD 1-4
57     union
58     {
59         struct
60         {
61             uint32_t ForceMvX : MOS_BITFIELD_RANGE(0, 15);
62             uint32_t ForceMvY : MOS_BITFIELD_RANGE(16, 31);
63         };
64         uint32_t Value;
65     } DW1[4];
66 
67     // DWORD 5
68     union
69     {
70         struct
71         {
72             uint32_t Reserved : MOS_BITFIELD_RANGE(0, 31);
73         };
74         uint32_t Value;
75     } DW5;
76 
77     // DWORD 6
78     union
79     {
80         struct
81         {
82             uint32_t ForceRefIdx : MOS_BITFIELD_RANGE(0, 15);  //4-bits per 16x16 block
83             uint32_t NumMergeCandidateCu8x8 : MOS_BITFIELD_RANGE(16, 19);
84             uint32_t NumMergeCandidateCu16x16 : MOS_BITFIELD_RANGE(20, 23);
85             uint32_t NumMergeCandidateCu32x32 : MOS_BITFIELD_RANGE(24, 27);
86             uint32_t NumMergeCandidateCu64x64 : MOS_BITFIELD_RANGE(28, 31);
87         };
88         uint32_t Value;
89     } DW6;
90 
91     // DWORD 7
92     union
93     {
94         struct
95         {
96             uint32_t SegID : MOS_BITFIELD_RANGE(0, 15);  //4-bits per 16x16 block
97             uint32_t QpEnable : MOS_BITFIELD_RANGE(16, 19);
98             uint32_t SegIDEnable : MOS_BITFIELD_RANGE(20, 20);
99             uint32_t Reserved : MOS_BITFIELD_RANGE(21, 22);
100             uint32_t ForceRefIdEnable : MOS_BITFIELD_RANGE(23, 23);
101             uint32_t ImePredictorSelect : MOS_BITFIELD_RANGE(24, 31);
102         };
103         uint32_t Value;
104     } DW7;
105 
106     // DWORD 8-11
107     union
108     {
109         struct
110         {
111             uint32_t ImePredictorMvX : MOS_BITFIELD_RANGE(0, 15);
112             uint32_t ImePredictorMvY : MOS_BITFIELD_RANGE(16, 31);
113         };
114         uint32_t Value;
115     } DW8[4];
116 
117     // DWORD 12
118     union
119     {
120         struct
121         {
122             uint32_t ImePredictorRefIdx : MOS_BITFIELD_RANGE(0, 15);  //4-bits per 16x16 block
123             uint32_t Reserved : MOS_BITFIELD_RANGE(16, 31);
124         };
125         uint32_t Value;
126     } DW12;
127 
128     // DWORD 13
129     union
130     {
131         struct
132         {
133             uint32_t PanicModeLCUThreshold : MOS_BITFIELD_RANGE(0, 15);
134             uint32_t Reserved : MOS_BITFIELD_RANGE(16, 31);
135         };
136         uint32_t Value;
137     } DW13;
138 
139     // DWORD 14
140     union
141     {
142         struct
143         {
144             uint32_t ForceQp_0 : MOS_BITFIELD_RANGE(0, 7);
145             uint32_t ForceQp_1 : MOS_BITFIELD_RANGE(8, 15);
146             uint32_t ForceQp_2 : MOS_BITFIELD_RANGE(16, 23);
147             uint32_t ForceQp_3 : MOS_BITFIELD_RANGE(24, 31);
148         };
149         uint32_t Value;
150     } DW14;
151 
152     // DWORD 15
153     union
154     {
155         struct
156         {
157             uint32_t Reserved : MOS_BITFIELD_RANGE(0, 31);
158         };
159         uint32_t Value;
160     } DW15;
161 
162     inline bool operator==(const VdencStreamInState& ps) const
163     {
164 
165         if ((this->DW0.Value == ps.DW0.Value) &&
166             (this->DW1[0].Value == ps.DW1[0].Value) &&
167             this->DW1[1].Value == ps.DW1[1].Value &&
168             this->DW1[2].Value == ps.DW1[2].Value &&
169             this->DW1[3].Value == ps.DW1[3].Value &&
170             this->DW5.Value == ps.DW5.Value &&
171             this->DW6.Value == ps.DW6.Value &&
172             this->DW7.Value == ps.DW7.Value &&
173             this->DW8[0].Value == ps.DW8[0].Value &&
174             this->DW8[1].Value == ps.DW8[1].Value &&
175             this->DW8[2].Value == ps.DW8[2].Value &&
176             this->DW8[3].Value == ps.DW8[3].Value &&
177             this->DW12.Value == ps.DW12.Value &&
178             this->DW13.Value == ps.DW13.Value &&
179             this->DW14.Value == ps.DW14.Value &&
180             this->DW15.Value == ps.DW15.Value)
181             return true;
182         return false;
183     }
184 };
185 
186 struct CommonStreamInParams
187 {
188     uint8_t MaxCuSize;
189     uint8_t MaxTuSize;
190     uint8_t NumImePredictors;
191     uint8_t NumMergeCandidateCu8x8;
192     uint8_t NumMergeCandidateCu16x16;
193     uint8_t NumMergeCandidateCu32x32;
194     uint8_t NumMergeCandidateCu64x64;
195 };
196 
AlignRectCoordFloor(uint32_t blockSize,uint32_t coord)197 inline uint32_t AlignRectCoordFloor(uint32_t blockSize, uint32_t coord) { return blockSize * ((coord % 2 != 0) ? coord - 1 : coord); }
AlignRectCoordCeil(uint32_t blockSize,uint32_t coord)198 inline uint32_t AlignRectCoordCeil(uint32_t blockSize, uint32_t coord) { return blockSize * ((coord % 2 != 0) ? coord + 1 : coord); }
199 
200 class Av1BasicFeature;
201 class Av1StreamIn : public mhw::vdbox::vdenc::Itf::ParSetting, public mhw::vdbox::avp::Itf::ParSetting
202 {
203 public:
204     //!
205     //! \brief  Av1StreamIn constructor
206     //!
Av1StreamIn()207     Av1StreamIn() {};
208 
209     //!
210     //! \brief  Av1StreamIn deconstructor
211     //!
212     virtual ~Av1StreamIn();
213 
214     //!
215     //! \brief  Init stream in instance
216     //! \param  [in] basicFeature
217     //!         Pointer to basic feature
218     //! \param  [in] allocator
219     //!         Pointer to allocator
220     //! \return MOS_STATUS
221     //!         MOS_STATUS_SUCCESS if success, else fail reason
222     //!
223     virtual MOS_STATUS Init(Av1BasicFeature *basicFeature, EncodeAllocator *allocator, PMOS_INTERFACE osInterface);
224 
225     //!
226     //! \brief  update stream in buffer for each frame
227     //! \return MOS_STATUS
228     //!         MOS_STATUS_SUCCESS if success, else fail reason
229     //!
230     virtual MOS_STATUS Update();
231 
232     //!
233     //! \brief  Get stream in buffer offset for each CU32x32
234     //! \return uint32_t
235     //!         offset for each cu
236     //!
237     uint32_t GetCuOffset(uint32_t xIdx, uint32_t yIdx) const;
238 
239     //!
240     //! \brief  Get stream in buffer base locked addrress
241     //! \return VdencStreamInState*
242     //!         pointer to stream in buffer locked address
243     //!
244     virtual VdencStreamInState *GetStreamInBuffer();
245 
246     //!
247     //! \brief  Return stream in buffer base locked addrress
248     //! \return MOS_STATUS
249     //!         MOS_STATUS_SUCCESS if success, else fail reason
250     //!
251     virtual MOS_STATUS ReturnStreamInBuffer();
252 
253     MHW_SETPAR_DECL_HDR(VDENC_PIPE_BUF_ADDR_STATE);
254     MHW_SETPAR_DECL_HDR(VDENC_CMD2);
255 
256     //!
257     //! \brief  Reset stream in after frame programming is done
258     //!
259     virtual void Reset();
260 
261     const CommonStreamInParams& GetCommonParams() const;
262 
263     static const uint8_t m_streamInBlockSize = 32;              //!< size of stream in block in one dimension
264 
265 protected:
266     //!
267     //! \brief  Set up LCU map for stream in
268     //! \param  [in] params
269     //!         Pointer to encode parameter
270     //! \return MOS_STATUS
271     //!         MOS_STATUS_SUCCESS if success, else fail reason
272     //!
273     virtual MOS_STATUS SetupLCUMap();
274 
275     //!
276     //! \brief  Get LCU Addr for each (x, y)
277     //! \param  [in] x
278     //!         horizontal coordination for current block
279     //! \param  [in] y
280     //!         vetical coordination for current blockn
281     //! \return uint32_t
282     //!         LCU offset for current block
283     //!
284     uint32_t GetLCUAddr(uint32_t x, uint32_t y) const;
285 
286     //!
287     //! \brief  Initialize all stream in blocks
288     //! \param  [in] streamInBuffer
289     //!         pointer to stream in buffer locked address
290     //!
291     MOS_STATUS StreamInInit(uint8_t *streamInBuffer);
292 
293     Av1BasicFeature *m_basicFeature = nullptr;        //!< AV1 paramter
294     EncodeAllocator *m_allocator = nullptr;           //!< Encode allocator
295     PMOS_INTERFACE   m_osInterface    = nullptr;      //!< Pointer to OS interface
296     PMOS_RESOURCE    m_streamInBuffer = nullptr;      //!< Stream in buffer
297     bool             m_enabled = false;               //!< Indicate stream in enabled or not
298     bool             m_initialized = false;           //!< Indicate stream in buffer initialized or not
299 
300     uint32_t m_widthInLCU = 0;           //!< Frame width in LCU unit
301     uint32_t m_heightInLCU = 0;          //!<  Frame height in LCU unit
302     static const uint8_t m_num32x32BlocksInLCU = 4;             //!< Number of 32x32 blocks in one LCU
303     static const uint8_t m_num32x32BlocksInLCUOnedimension = 2; //!< Number of 32x32 blocks in one LCU in one dimension
304 
305     uint32_t *m_LcuMap = nullptr;
306 
307     CommonStreamInParams m_commonPar = {};
308 
309     uint8_t *m_streamInTemp = nullptr;
310     uint32_t m_streamInSize = 0;
311 
312 MEDIA_CLASS_DEFINE_END(encode__Av1StreamIn)
313 };
314 
315 }  // namespace encode
316 
317 #endif  // !__ENCODE_AV1_STREAM_IN_H__
318