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