Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(708)

Side by Side Diff: media/base/bit_reader_core.cc

Issue 112343011: Split the bit reader functionalities from the byte stream provider. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix compilation warning on windows & Add more unit tests Created 6 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright (c) 2013 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/sys_byteorder.h>
8
9 namespace media {
10
11 BitReaderCore::ByteStreamProvider::ByteStreamProvider() {
12 }
13
14 BitReaderCore::ByteStreamProvider::~ByteStreamProvider() {
15 }
16
17 // static
18 const int BitReaderCore::kRegWidthInBits =
19 sizeof(BitReaderCore::RegType) * CHAR_BIT;
20
21 BitReaderCore::BitReaderCore(ByteStreamProvider* byte_stream_provider)
22 : byte_stream_provider_(byte_stream_provider),
23 bit_count_(0),
24 nbits_(0),
25 reg_(0),
26 nbits_next_(0),
27 reg_next_(0) {
28 }
29
30 BitReaderCore::~BitReaderCore() {
31 }
32
33 bool BitReaderCore::ReadFlag(bool* flag) {
34 if (nbits_ == 0 && !Refill(1))
35 return false;
36
37 *flag = (static_cast<SignedRegType>(reg_) < 0);
acolwell GONE FROM CHROMIUM 2014/01/06 22:44:06 Please don't do this. It obscures what the actual
damienv1 2014/01/07 00:19:40 Will do.
38 reg_ <<= 1;
39 nbits_--;
40 bit_count_++;
41 return true;
42 }
43
44 int BitReaderCore::PeekBitsMsbAligned(int num_bits, uint64* 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::SkipBits(int num_bits) {
54 DCHECK_GE(num_bits, 0);
55 DVLOG_IF(0, num_bits > 100)
56 << "BitReader::SkipBits inefficient for large skips";
57
58 uint64 dummy;
59 while (num_bits >= 64) {
60 if (!ReadBitsInternal(64, &dummy))
61 return false;
62 num_bits -= 64;
63 }
64 return ReadBitsInternal(num_bits, &dummy);
65 }
66
67 int BitReaderCore::GetBitCount() const {
68 return bit_count_;
69 }
70
71 int BitReaderCore::bits_available() const {
72 return (byte_stream_provider_->GetBytesLeft() * CHAR_BIT +
73 nbits_next_ + nbits_);
74 }
75
76 bool BitReaderCore::ReadBitsInternal(int num_bits, uint64* out) {
77 DCHECK_GE(num_bits, 0);
78
79 if (num_bits == 0) {
80 *out = 0;
81 return true;
82 }
83
84 if (num_bits > nbits_ && !Refill(num_bits)) {
85 // Any subsequent ReadBits should fail:
86 // empty the current bit register for that purpose.
87 nbits_ = 0;
88 reg_ = 0;
89 return false;
90 }
91
92 bit_count_ += num_bits;
93
94 if (num_bits == kRegWidthInBits) {
95 // Special case needed since for example for a 64 bit integer "a"
96 // "a << 64" is not defined by the C/C++ standard.
97 *out = reg_;
98 reg_ = 0;
99 nbits_ = 0;
100 return true;
101 }
102
103 *out = reg_ >> (kRegWidthInBits - num_bits);
104 reg_ <<= num_bits;
105 nbits_ -= num_bits;
106 return true;
107 }
108
109 bool BitReaderCore::Refill(int min_nbits) {
110 DCHECK_LE(min_nbits, kRegWidthInBits);
111
112 // Transfer from the next to the current register.
113 RefillCurrentRegister();
114 if (min_nbits <= nbits_)
115 return true;
116 DCHECK_EQ(nbits_next_, 0);
117 DCHECK_EQ(reg_next_, 0u);
118
119 // Max number of bytes to refill.
120 int max_nbytes = sizeof(RegType);
acolwell GONE FROM CHROMIUM 2014/01/06 22:44:06 nit: How about just using sizeof(reg_next_) here s
damienv1 2014/01/07 00:19:40 Will do.
121
122 // Refill.
123 const uint8* byte_stream_window;
124 int window_size =
125 byte_stream_provider_->GetBytes(max_nbytes, &byte_stream_window);
126 if (window_size == 0)
127 return false;
128
129 reg_next_ = 0;
130 memcpy(&reg_next_, byte_stream_window, window_size);
131 reg_next_ = base::NetToHost64(reg_next_);
132 nbits_next_ = window_size * CHAR_BIT;
acolwell GONE FROM CHROMIUM 2014/01/06 22:44:06 Please just use 8 instead of CHAR_BIT everywhere i
damienv1 2014/01/07 00:19:40 I can do it although I think it's good programming
133
134 // Transfer from the next to the current register.
135 RefillCurrentRegister();
136
137 return (nbits_ >= min_nbits);
138 }
139
140 void BitReaderCore::RefillCurrentRegister() {
141 // No refill possible if the destination register is full
142 // or the source register is empty.
143 if (nbits_ == kRegWidthInBits || nbits_next_ == 0)
144 return;
145
146 reg_ |= (reg_next_ >> nbits_);
147
148 int free_nbits = kRegWidthInBits - nbits_;
149 if (free_nbits >= nbits_next_) {
150 nbits_ += nbits_next_;
151 reg_next_ = 0;
152 nbits_next_ = 0;
153 } else {
154 nbits_ += free_nbits;
155 reg_next_ <<= free_nbits;
156 nbits_next_ -= free_nbits;
157 }
158 }
159
160 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698