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 10namespace { 11const int kRegWidthInBits = sizeof(uint64) * 8; 12} 13 14namespace media { 15 16BitReaderCore::ByteStreamProvider::ByteStreamProvider() { 17} 18 19BitReaderCore::ByteStreamProvider::~ByteStreamProvider() { 20} 21 22BitReaderCore::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 31BitReaderCore::~BitReaderCore() { 32} 33 34bool 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 45int 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 54bool BitReaderCore::SkipBitsSmall(int num_bits) { 55 DCHECK_GE(num_bits, 0); 56 uint64 dummy; 57 while (num_bits >= kRegWidthInBits) { 58 if (!ReadBitsInternal(kRegWidthInBits, &dummy)) 59 return false; 60 num_bits -= kRegWidthInBits; 61 } 62 return ReadBitsInternal(num_bits, &dummy); 63} 64 65bool BitReaderCore::SkipBits(int num_bits) { 66 DCHECK_GE(num_bits, 0); 67 68 const int remaining_bits = nbits_ + nbits_next_; 69 if (remaining_bits >= num_bits) 70 return SkipBitsSmall(num_bits); 71 72 // Skip first the remaining available bits. 73 num_bits -= remaining_bits; 74 bits_read_ += remaining_bits; 75 nbits_ = 0; 76 reg_ = 0; 77 nbits_next_ = 0; 78 reg_next_ = 0; 79 80 // Next, skip an integer number of bytes. 81 const int nbytes = num_bits / 8; 82 if (nbytes > 0) { 83 const uint8* byte_stream_window; 84 const int window_size = 85 byte_stream_provider_->GetBytes(nbytes, &byte_stream_window); 86 DCHECK_GE(window_size, 0); 87 DCHECK_LE(window_size, nbytes); 88 if (window_size < nbytes) 89 return false; 90 num_bits -= 8 * nbytes; 91 bits_read_ += 8 * nbytes; 92 } 93 94 // Skip the remaining bits. 95 return SkipBitsSmall(num_bits); 96} 97 98int BitReaderCore::bits_read() const { 99 return bits_read_; 100} 101 102bool BitReaderCore::ReadBitsInternal(int num_bits, uint64* out) { 103 DCHECK_GE(num_bits, 0); 104 105 if (num_bits == 0) { 106 *out = 0; 107 return true; 108 } 109 110 if (num_bits > nbits_ && !Refill(num_bits)) { 111 // Any subsequent ReadBits should fail: 112 // empty the current bit register for that purpose. 113 nbits_ = 0; 114 reg_ = 0; 115 return false; 116 } 117 118 bits_read_ += num_bits; 119 120 if (num_bits == kRegWidthInBits) { 121 // Special case needed since for example for a 64 bit integer "a" 122 // "a << 64" is not defined by the C/C++ standard. 123 *out = reg_; 124 reg_ = 0; 125 nbits_ = 0; 126 return true; 127 } 128 129 *out = reg_ >> (kRegWidthInBits - num_bits); 130 reg_ <<= num_bits; 131 nbits_ -= num_bits; 132 return true; 133} 134 135bool BitReaderCore::Refill(int min_nbits) { 136 DCHECK_LE(min_nbits, kRegWidthInBits); 137 138 // Transfer from the next to the current register. 139 RefillCurrentRegister(); 140 if (min_nbits <= nbits_) 141 return true; 142 DCHECK_EQ(nbits_next_, 0); 143 DCHECK_EQ(reg_next_, 0u); 144 145 // Max number of bytes to refill. 146 int max_nbytes = sizeof(reg_next_); 147 148 // Refill. 149 const uint8* byte_stream_window; 150 int window_size = 151 byte_stream_provider_->GetBytes(max_nbytes, &byte_stream_window); 152 DCHECK_GE(window_size, 0); 153 DCHECK_LE(window_size, max_nbytes); 154 if (window_size == 0) 155 return false; 156 157 reg_next_ = 0; 158 memcpy(®_next_, byte_stream_window, window_size); 159 reg_next_ = base::NetToHost64(reg_next_); 160 nbits_next_ = window_size * 8; 161 162 // Transfer from the next to the current register. 163 RefillCurrentRegister(); 164 165 return (nbits_ >= min_nbits); 166} 167 168void BitReaderCore::RefillCurrentRegister() { 169 // No refill possible if the destination register is full 170 // or the source register is empty. 171 if (nbits_ == kRegWidthInBits || nbits_next_ == 0) 172 return; 173 174 reg_ |= (reg_next_ >> nbits_); 175 176 int free_nbits = kRegWidthInBits - nbits_; 177 if (free_nbits >= nbits_next_) { 178 nbits_ += nbits_next_; 179 reg_next_ = 0; 180 nbits_next_ = 0; 181 return; 182 } 183 184 nbits_ += free_nbits; 185 reg_next_ <<= free_nbits; 186 nbits_next_ -= free_nbits; 187} 188 189} // namespace media 190