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 5 #include "media/base/bit_reader_core.h" 6 7 #include <base/port.h> 8 #include <base/sys_byteorder.h> 9 10 namespace { 11 const int kRegWidthInBits = sizeof(uint64) * 8; 12 } 13 14 namespace media { 15 16 BitReaderCore::ByteStreamProvider::ByteStreamProvider() { 17 } 18 19 BitReaderCore::ByteStreamProvider::~ByteStreamProvider() { 20 } 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() { 32 } 33 34 bool BitReaderCore::ReadFlag(bool* flag) { 35 if (nbits_ == 0 && !Refill(1)) 36 return false; 37 38 *flag = (reg_ & (GG_UINT64_C(1) << (kRegWidthInBits - 1))) != 0; 39 reg_ <<= 1; 40 nbits_--; 41 bits_read_++; 42 return true; 43 } 44 45 int BitReaderCore::PeekBitsMsbAligned(int num_bits, uint64* out) { 46 // Try to have at least |num_bits| in the bit register. 47 if (nbits_ < num_bits) 48 Refill(num_bits); 49 50 *out = reg_; 51 return nbits_; 52 } 53 54 bool BitReaderCore::SkipBits(int num_bits) { 55 DCHECK_GE(num_bits, 0); 56 DVLOG_IF(0, num_bits > 100) 57 << "BitReader::SkipBits inefficient for large skips"; 58 59 uint64 dummy; 60 while (num_bits >= kRegWidthInBits) { 61 if (!ReadBitsInternal(kRegWidthInBits, &dummy)) 62 return false; 63 num_bits -= kRegWidthInBits; 64 } 65 return ReadBitsInternal(num_bits, &dummy); 66 } 67 68 int BitReaderCore::bits_read() const { 69 return bits_read_; 70 } 71 72 bool BitReaderCore::ReadBitsInternal(int num_bits, uint64* out) { 73 DCHECK_GE(num_bits, 0); 74 75 if (num_bits == 0) { 76 *out = 0; 77 return true; 78 } 79 80 if (num_bits > nbits_ && !Refill(num_bits)) { 81 // Any subsequent ReadBits should fail: 82 // empty the current bit register for that purpose. 83 nbits_ = 0; 84 reg_ = 0; 85 return false; 86 } 87 88 bits_read_ += num_bits; 89 90 if (num_bits == kRegWidthInBits) { 91 // Special case needed since for example for a 64 bit integer "a" 92 // "a << 64" is not defined by the C/C++ standard. 93 *out = reg_; 94 reg_ = 0; 95 nbits_ = 0; 96 return true; 97 } 98 99 *out = reg_ >> (kRegWidthInBits - num_bits); 100 reg_ <<= num_bits; 101 nbits_ -= num_bits; 102 return true; 103 } 104 105 bool BitReaderCore::Refill(int min_nbits) { 106 DCHECK_LE(min_nbits, kRegWidthInBits); 107 108 // Transfer from the next to the current register. 109 RefillCurrentRegister(); 110 if (min_nbits <= nbits_) 111 return true; 112 DCHECK_EQ(nbits_next_, 0); 113 DCHECK_EQ(reg_next_, 0u); 114 115 // Max number of bytes to refill. 116 int max_nbytes = sizeof(reg_next_); 117 118 // Refill. 119 const uint8* byte_stream_window; 120 int window_size = 121 byte_stream_provider_->GetBytes(max_nbytes, &byte_stream_window); 122 DCHECK_GE(window_size, 0); 123 DCHECK_LE(window_size, max_nbytes); 124 if (window_size == 0) 125 return false; 126 127 reg_next_ = 0; 128 memcpy(®_next_, byte_stream_window, window_size); 129 reg_next_ = base::NetToHost64(reg_next_); 130 nbits_next_ = window_size * 8; 131 132 // Transfer from the next to the current register. 133 RefillCurrentRegister(); 134 135 return (nbits_ >= min_nbits); 136 } 137 138 void BitReaderCore::RefillCurrentRegister() { 139 // No refill possible if the destination register is full 140 // or the source register is empty. 141 if (nbits_ == kRegWidthInBits || nbits_next_ == 0) 142 return; 143 144 reg_ |= (reg_next_ >> nbits_); 145 146 int free_nbits = kRegWidthInBits - nbits_; 147 if (free_nbits >= nbits_next_) { 148 nbits_ += nbits_next_; 149 reg_next_ = 0; 150 nbits_next_ = 0; 151 return; 152 } 153 154 nbits_ += free_nbits; 155 reg_next_ <<= free_nbits; 156 nbits_next_ -= free_nbits; 157 } 158 159 } // namespace media 160