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