1 /* 2 * Copyright (c) 2021-2021 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #ifndef HISTREAMER_BIT_READER_H 17 #define HISTREAMER_BIT_READER_H 18 19 #include <algorithm> 20 #include <cstdint> // NOLINT 21 22 namespace OHOS { 23 namespace Media { 24 namespace Plugin { 25 namespace Ffmpeg { 26 class BitReader { 27 public: 28 BitReader(); 29 30 BitReader(const uint8_t* buffer, size_t bufferSize); 31 32 BitReader(const uint8_t* begin, const uint8_t* end); 33 34 template <typename T> BitReader(const T * buffer,size_t bufferSize)35 BitReader(const T* buffer, size_t bufferSize) : BitReader(buffer, buffer + bufferSize) 36 { 37 } 38 39 template <typename T> BitReader(const T * begin,const T * end)40 BitReader(const T* begin, const T* end) 41 : BitReader(reinterpret_cast<const uint8_t*>(begin), reinterpret_cast<const uint8_t*>(end)) // NOLINT: cast 42 { 43 } 44 45 ~BitReader(); 46 47 template <typename T, typename std::enable_if<std::is_unsigned<T>::value, bool>::type = true> ReadBits(uint8_t bits,T & val)48 bool ReadBits(uint8_t bits, T& val) 49 { 50 if (GetAvailableBits() < bits) { 51 return false; 52 } 53 val = 0; 54 uint8_t remainBits = bits; 55 for (uint8_t toRead = 0; remainBits; remainBits -= toRead) { 56 if (availBits_ == 0) { 57 ++cur_; 58 availBits_ = 8; // 8 59 } 60 toRead = std::min(remainBits, availBits_); 61 uint8_t shift = availBits_ - toRead; 62 uint64_t mask = 0xFF >> (0x08 - toRead); 63 val = static_cast<T>((val << toRead) | static_cast<T>(((*cur_) >> shift) & mask)); 64 availBits_ -= toRead; 65 } 66 return true; 67 } 68 69 size_t GetAvailableBits() const; 70 71 const uint8_t* GetCurrentPtr() const; 72 73 void SkipBits(size_t bits); 74 75 bool SeekTo(size_t bitPos); 76 77 template <typename T> PeekBits(uint8_t bits,T & val)78 bool PeekBits(uint8_t bits, T& val) 79 { 80 auto tmp = *this; 81 return tmp.ReadBits<T>(bits, val); 82 } 83 84 template <typename T> Reset(const T * buffer,size_t bufferSize)85 void Reset(const T* buffer, size_t bufferSize) 86 { 87 Reset(buffer, buffer + bufferSize); 88 } 89 90 template <typename T> Reset(const T * begin,const T * end)91 void Reset(const T* begin, const T* end) 92 { 93 Reset(reinterpret_cast<const uint8_t*>(begin), reinterpret_cast<const uint8_t*>(end)); // NOLINT: cast 94 } 95 96 private: 97 void Reset(const uint8_t* begin, const uint8_t* end); 98 99 const uint8_t* begin_; 100 const uint8_t* cur_; 101 const uint8_t* end_; 102 uint8_t availBits_{8}; 103 }; 104 } // namespace Ffmpeg 105 } // namespace Plugin 106 } // namespace Media 107 } // namespace OHOS 108 #endif // HISTREAMER_BIT_READER_H 109