1 // Copyright 2014 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 // Note: ported from Chromium commit head: 2de6929 5 6 #include "bit_reader_core.h" 7 8 #include <stdint.h> 9 10 #include "base/sys_byteorder.h" 11 12 namespace { 13 const int kRegWidthInBits = sizeof(uint64_t) * 8; 14 } 15 16 namespace media { 17 18 BitReaderCore::ByteStreamProvider::ByteStreamProvider() = default; 19 20 BitReaderCore::ByteStreamProvider::~ByteStreamProvider() = default; 21 22 BitReaderCore::BitReaderCore(ByteStreamProvider* byte_stream_provider) 23 : byte_stream_provider_(byte_stream_provider), 24 bits_read_(0), 25 nbits_(0), 26 reg_(0), 27 nbits_next_(0), 28 reg_next_(0) { 29 } 30 31 BitReaderCore::~BitReaderCore() = default; 32 33 bool BitReaderCore::ReadFlag(bool* flag) { 34 if (nbits_ == 0 && !Refill(1)) 35 return false; 36 37 *flag = (reg_ & (UINT64_C(1) << (kRegWidthInBits - 1))) != 0; 38 reg_ <<= 1; 39 nbits_--; 40 bits_read_++; 41 return true; 42 } 43 44 int BitReaderCore::PeekBitsMsbAligned(int num_bits, uint64_t* out) { 45 // Try to have at least |num_bits| in the bit register. 46 if (nbits_ < num_bits) 47 Refill(num_bits); 48 49 *out = reg_; 50 return nbits_; 51 } 52 53 bool BitReaderCore::SkipBitsSmall(int num_bits) { 54 DCHECK_GE(num_bits, 0); 55 uint64_t dummy; 56 while (num_bits >= kRegWidthInBits) { 57 if (!ReadBitsInternal(kRegWidthInBits, &dummy)) 58 return false; 59 num_bits -= kRegWidthInBits; 60 } 61 return ReadBitsInternal(num_bits, &dummy); 62 } 63 64 bool BitReaderCore::SkipBits(int num_bits) { 65 DCHECK_GE(num_bits, 0); 66 67 const int remaining_bits = nbits_ + nbits_next_; 68 if (remaining_bits >= num_bits) 69 return SkipBitsSmall(num_bits); 70 71 // Skip first the remaining available bits. 72 num_bits -= remaining_bits; 73 bits_read_ += remaining_bits; 74 nbits_ = 0; 75 reg_ = 0; 76 nbits_next_ = 0; 77 reg_next_ = 0; 78 79 // Next, skip an integer number of bytes. 80 const int nbytes = num_bits / 8; 81 if (nbytes > 0) { 82 const uint8_t* byte_stream_window; 83 const int window_size = 84 byte_stream_provider_->GetBytes(nbytes, &byte_stream_window); 85 DCHECK_GE(window_size, 0); 86 DCHECK_LE(window_size, nbytes); 87 if (window_size < nbytes) { 88 // Note that some bytes were consumed. 89 bits_read_ += 8 * window_size; 90 return false; 91 } 92 num_bits -= 8 * nbytes; 93 bits_read_ += 8 * nbytes; 94 } 95 96 // Skip the remaining bits. 97 return SkipBitsSmall(num_bits); 98 } 99 100 int BitReaderCore::bits_read() const { 101 return bits_read_; 102 } 103 104 bool BitReaderCore::ReadBitsInternal(int num_bits, uint64_t* out) { 105 DCHECK_GE(num_bits, 0); 106 107 if (num_bits == 0) { 108 *out = 0; 109 return true; 110 } 111 112 if (num_bits > nbits_ && !Refill(num_bits)) { 113 // Any subsequent ReadBits should fail: 114 // empty the current bit register for that purpose. 115 nbits_ = 0; 116 reg_ = 0; 117 return false; 118 } 119 120 bits_read_ += num_bits; 121 122 if (num_bits == kRegWidthInBits) { 123 // Special case needed since for example for a 64 bit integer "a" 124 // "a << 64" is not defined by the C/C++ standard. 125 *out = reg_; 126 reg_ = 0; 127 nbits_ = 0; 128 return true; 129 } 130 131 *out = reg_ >> (kRegWidthInBits - num_bits); 132 reg_ <<= num_bits; 133 nbits_ -= num_bits; 134 return true; 135 } 136 137 bool BitReaderCore::Refill(int min_nbits) { 138 DCHECK_LE(min_nbits, kRegWidthInBits); 139 140 // Transfer from the next to the current register. 141 RefillCurrentRegister(); 142 if (min_nbits <= nbits_) 143 return true; 144 DCHECK_EQ(nbits_next_, 0); 145 DCHECK_EQ(reg_next_, 0u); 146 147 // Max number of bytes to refill. 148 int max_nbytes = sizeof(reg_next_); 149 150 // Refill. 151 const uint8_t* byte_stream_window; 152 int window_size = 153 byte_stream_provider_->GetBytes(max_nbytes, &byte_stream_window); 154 DCHECK_GE(window_size, 0); 155 DCHECK_LE(window_size, max_nbytes); 156 if (window_size == 0) 157 return false; 158 159 reg_next_ = 0; 160 memcpy(®_next_, byte_stream_window, window_size); 161 reg_next_ = base::NetToHost64(reg_next_); 162 nbits_next_ = window_size * 8; 163 164 // Transfer from the next to the current register. 165 RefillCurrentRegister(); 166 167 return (nbits_ >= min_nbits); 168 } 169 170 void BitReaderCore::RefillCurrentRegister() { 171 // No refill possible if the destination register is full 172 // or the source register is empty. 173 if (nbits_ == kRegWidthInBits || nbits_next_ == 0) 174 return; 175 176 reg_ |= (reg_next_ >> nbits_); 177 178 int free_nbits = kRegWidthInBits - nbits_; 179 if (free_nbits >= nbits_next_) { 180 nbits_ += nbits_next_; 181 reg_next_ = 0; 182 nbits_next_ = 0; 183 return; 184 } 185 186 nbits_ += free_nbits; 187 reg_next_ <<= free_nbits; 188 nbits_next_ -= free_nbits; 189 } 190 191 } // namespace media 192