1 // Copyright (c) 2017-2019 Intel Corporation
2 //
3 // Permission is hereby granted, free of charge, to any person obtaining a copy
4 // of this software and associated documentation files (the "Software"), to deal
5 // in the Software without restriction, including without limitation the rights
6 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 // copies of the Software, and to permit persons to whom the Software is
8 // furnished to do so, subject to the following conditions:
9 //
10 // The above copyright notice and this permission notice shall be included in all
11 // copies or substantial portions of the Software.
12 //
13 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19 // SOFTWARE.
20 
21 #ifndef _MFX_VP8_DECODE_HW_H_
22 #define _MFX_VP8_DECODE_HW_H_
23 
24 #include "mfx_common.h"
25 
26 #if defined(MFX_ENABLE_VP8_VIDEO_DECODE_HW)
27 
28 #include "mfx_common_int.h"
29 #include "mfx_umc_alloc_wrapper.h"
30 #include "mfx_critical_error_handler.h"
31 #include "umc_frame_data.h"
32 #include "umc_media_data.h"
33 #include "umc_va_base.h"
34 
35 #include "mfx_task.h"
36 
37 #include "umc_mutex.h"
38 
39 #include "mfx_vp8_dec_decode_vp8_defs.h"
40 #include "mfx_vp8_dec_decode_common.h"
41 
42 class MFX_VP8_BoolDecoder
43 {
44 private:
45     uint32_t m_range;
46     uint32_t m_value;
47     int32_t m_bitcount;
48     uint32_t m_pos;
49     uint8_t *m_input;
50     int32_t m_input_size;
51 
52     static const int range_normalization_shift[64];
53 
decode_bit(int probability)54     int decode_bit(int probability)
55     {
56 
57         uint32_t bit = 0;
58         uint32_t split;
59         uint32_t bigsplit;
60         uint32_t count = this->m_bitcount;
61         uint32_t range = this->m_range;
62         uint32_t value = this->m_value;
63 
64         split = 1 +  (((range - 1) * probability) >> 8);
65         bigsplit = (split << 24);
66 
67         range = split;
68         if(value >= bigsplit)
69         {
70            range = this->m_range - split;
71            value = value - bigsplit;
72            bit = 1;
73         }
74 
75         if(range >= 0x80)
76         {
77             this->m_value = value;
78             this->m_range = range;
79             return bit;
80         }
81         else
82         {
83             do
84             {
85                 range += range;
86                 value += value;
87 
88                 if (!--count)
89                 {
90                     count = 8;
91                     value |= static_cast<uint32_t>(this->m_input[this->m_pos]);
92                     this->m_pos++;
93                 }
94              }
95              while(range < 0x80);
96         }
97         this->m_bitcount = count;
98         this->m_value = value;
99         this->m_range = range;
100         return bit;
101 
102     }
103 
104 public:
MFX_VP8_BoolDecoder()105     MFX_VP8_BoolDecoder() :
106         m_range(0),
107         m_value(0),
108         m_bitcount(0),
109         m_pos(0),
110         m_input(0),
111         m_input_size(0)
112     {}
113 
MFX_VP8_BoolDecoder(uint8_t * pBitStream,int32_t dataSize)114     MFX_VP8_BoolDecoder(uint8_t *pBitStream, int32_t dataSize)
115     {
116         init(pBitStream, dataSize);
117     }
118 
init(uint8_t * pBitStream,int32_t dataSize)119     void init(uint8_t *pBitStream, int32_t dataSize)
120     {
121         dataSize = std::min(dataSize, 2);
122         m_range = 255;
123         m_bitcount = 8;
124         m_pos = 0;
125         m_value = (pBitStream[0] << 24) + (pBitStream[1] << 16) +
126                   (pBitStream[2] << 8) + pBitStream[3];
127         m_pos += 4;
128         m_input     = pBitStream;
129         m_input_size = dataSize;
130     }
131 
132     uint32_t decode(int bits = 1, int prob = 128)
133     {
134         uint32_t z = 0;
135         int bit;
136         for (bit = bits - 1; bit >= 0;bit--)
137         {
138             z |= (decode_bit(prob) << bit);
139         }
140         return z;
141     }
142 
input()143     uint8_t * input()
144     {
145         return &m_input[m_pos];
146     }
147 
pos()148     uint32_t pos() const
149     {
150         return m_pos;
151     }
152 
bitcount()153     int32_t bitcount() const
154     {
155         return m_bitcount;
156     }
157 
range()158     uint32_t range() const
159     {
160         return m_range;
161     }
162 
value()163     uint32_t value() const
164     {
165         return m_value;
166     }
167 };
168 
169 class VideoDECODEVP8_HW : public VideoDECODE, public MfxCriticalErrorHandler
170 {
171 public:
172 
173     VideoDECODEVP8_HW(VideoCORE *pCore, mfxStatus *sts);
174     ~VideoDECODEVP8_HW();
175 
176     static mfxStatus Query(VideoCORE *pCore, mfxVideoParam *pIn, mfxVideoParam *pOut);
177     static mfxStatus QueryIOSurf(VideoCORE *pCore, mfxVideoParam *pPar, mfxFrameAllocRequest *pRequest);
178 
179     virtual mfxStatus Init(mfxVideoParam *pPar);
180     virtual mfxStatus Reset(mfxVideoParam *pPar);
181     virtual mfxStatus Close();
182 
183     virtual mfxTaskThreadingPolicy GetThreadingPolicy();
184     virtual mfxStatus GetVideoParam(mfxVideoParam *pPar);
185     virtual mfxStatus GetDecodeStat(mfxDecodeStat *pStat);
186 
187     virtual mfxStatus DecodeFrameCheck(mfxBitstream *bs, mfxFrameSurface1 *surface_work, mfxFrameSurface1 **surface_out);
188     virtual mfxStatus DecodeFrameCheck(mfxBitstream *pBs, mfxFrameSurface1 *pSurfaceWork, mfxFrameSurface1 **ppSurfaceOut, MFX_ENTRY_POINT *pEntryPoint);
189     virtual mfxStatus DecodeFrame(mfxBitstream *pBs, mfxFrameSurface1 *pSurfaceWork, mfxFrameSurface1 *pSurfaceOut);
190 
191     virtual mfxStatus GetUserData(mfxU8 *pUserData, mfxU32 *pSize, mfxU64 *pTimeStamp);
192     virtual mfxStatus GetPayload(mfxU64 *pTimeStamp, mfxPayload *pPayload);
193     virtual mfxStatus SetSkipMode(mfxSkipMode mode);
194 
195 private:
196 
197     mfxFrameSurface1 * GetOriginalSurface(mfxFrameSurface1 *);
198     mfxStatus GetOutputSurface(mfxFrameSurface1 **, mfxFrameSurface1 *, UMC::FrameMemID);
199 
200     mfxStatus ConstructFrame(mfxBitstream *, mfxBitstream *, VP8DecodeCommon::IVF_FRAME&);
201     mfxStatus PreDecodeFrame(mfxBitstream *, mfxFrameSurface1 *);
202 
203     mfxStatus DecodeFrameHeader(mfxBitstream *p_bistream);
204     void UpdateSegmentation(MFX_VP8_BoolDecoder &);
205     void UpdateLoopFilterDeltas(MFX_VP8_BoolDecoder &);
206     void DecodeInitDequantization(MFX_VP8_BoolDecoder &);
207     mfxStatus PackHeaders(mfxBitstream *p_bistream);
208 
209     static bool CheckHardwareSupport(VideoCORE *p_core, mfxVideoParam *p_par);
210 
211     UMC::FrameMemID GetMemIdToUnlock();
212 
213     mfxStatus GetFrame(UMC::MediaData* in, UMC::FrameData** out);
214 
215     friend mfxStatus MFX_CDECL VP8DECODERoutine(void *p_state, void *pp_param, mfxU32 thread_number, mfxU32);
216 
217     struct VP8DECODERoutineData
218     {
219         VideoDECODEVP8_HW* decoder;
220         mfxFrameSurface1* surface_work;
221         UMC::FrameMemID memId;
222     };
223 
224     struct sFrameInfo
225     {
226         UMC::FrameType frameType;
227         mfxU16 currIndex;
228         mfxU16 goldIndex;
229         mfxU16 altrefIndex;
230         mfxU16 lastrefIndex;
231         UMC::FrameMemID memId;
232     };
233 
234     bool                    m_is_initialized;
235     bool                    m_is_opaque_memory;
236     VideoCORE*              m_p_core;
237     eMFXPlatform            m_platform;
238 
239     mfxVideoParamWrapper    m_on_init_video_params,
240                             m_video_params;
241     mfxU32                  m_init_w,
242                             m_init_h;
243     mfxF64                  m_in_framerate;
244     mfxU16                  m_frameOrder;
245 
246     mfxBitstream            m_bs;
247     VP8Defs::vp8_FrameInfo  m_frame_info;
248     unsigned                m_CodedCoeffTokenPartition;
249     bool                    m_firstFrame;
250 
251     VP8Defs::vp8_RefreshInfo         m_refresh_info;
252     VP8Defs::vp8_FrameProbabilities  m_frameProbs;
253     VP8Defs::vp8_FrameProbabilities  m_frameProbs_saved;
254     VP8Defs::vp8_QuantInfo           m_quantInfo;
255     MFX_VP8_BoolDecoder     m_boolDecoder[VP8Defs::VP8_MAX_NUMBER_OF_PARTITIONS];
256 
257     mfxU16 gold_indx;
258     mfxU16 altref_indx;
259     mfxU16 lastrefIndex;
260 
261     std::vector<sFrameInfo>      m_frames;
262     std::vector<UMC::FrameMemID> m_memIdReadyToFree;
263 
264     mfxFrameAllocResponse   m_response;
265     mfxDecodeStat           m_stat;
266     mfxFrameAllocRequest    m_request;
267 
268     std::unique_ptr<mfx_UMC_FrameAllocator> m_p_frame_allocator;
269     UMC::VideoAccelerator *m_p_video_accelerator;
270 
271     UMC::Mutex              m_mGuard;
272 };
273 
274 #endif // _MFX_VP8_DECODE_HW_H_
275 #endif // MFX_ENABLE_VP8_VIDEO_DECODE_HW && MFX_VA
276 /* EOF */
277