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.
5 #include "media/base/bit_reader_core.h"
9 #include "base/sys_byteorder.h"
12 const int kRegWidthInBits
= sizeof(uint64
) * 8;
17 BitReaderCore::ByteStreamProvider::ByteStreamProvider() {
20 BitReaderCore::ByteStreamProvider::~ByteStreamProvider() {
23 BitReaderCore::BitReaderCore(ByteStreamProvider
* byte_stream_provider
)
24 : byte_stream_provider_(byte_stream_provider
),
32 BitReaderCore::~BitReaderCore() {
35 bool BitReaderCore::ReadFlag(bool* flag
) {
36 if (nbits_
== 0 && !Refill(1))
39 *flag
= (reg_
& (UINT64_C(1) << (kRegWidthInBits
- 1))) != 0;
46 int BitReaderCore::PeekBitsMsbAligned(int num_bits
, uint64
* out
) {
47 // Try to have at least |num_bits| in the bit register.
48 if (nbits_
< num_bits
)
55 bool BitReaderCore::SkipBitsSmall(int num_bits
) {
56 DCHECK_GE(num_bits
, 0);
58 while (num_bits
>= kRegWidthInBits
) {
59 if (!ReadBitsInternal(kRegWidthInBits
, &dummy
))
61 num_bits
-= kRegWidthInBits
;
63 return ReadBitsInternal(num_bits
, &dummy
);
66 bool BitReaderCore::SkipBits(int num_bits
) {
67 DCHECK_GE(num_bits
, 0);
69 const int remaining_bits
= nbits_
+ nbits_next_
;
70 if (remaining_bits
>= num_bits
)
71 return SkipBitsSmall(num_bits
);
73 // Skip first the remaining available bits.
74 num_bits
-= remaining_bits
;
75 bits_read_
+= remaining_bits
;
81 // Next, skip an integer number of bytes.
82 const int nbytes
= num_bits
/ 8;
84 const uint8
* byte_stream_window
;
85 const int window_size
=
86 byte_stream_provider_
->GetBytes(nbytes
, &byte_stream_window
);
87 DCHECK_GE(window_size
, 0);
88 DCHECK_LE(window_size
, nbytes
);
89 if (window_size
< nbytes
)
91 num_bits
-= 8 * nbytes
;
92 bits_read_
+= 8 * nbytes
;
95 // Skip the remaining bits.
96 return SkipBitsSmall(num_bits
);
99 int BitReaderCore::bits_read() const {
103 bool BitReaderCore::ReadBitsInternal(int num_bits
, uint64
* out
) {
104 DCHECK_GE(num_bits
, 0);
111 if (num_bits
> nbits_
&& !Refill(num_bits
)) {
112 // Any subsequent ReadBits should fail:
113 // empty the current bit register for that purpose.
119 bits_read_
+= num_bits
;
121 if (num_bits
== kRegWidthInBits
) {
122 // Special case needed since for example for a 64 bit integer "a"
123 // "a << 64" is not defined by the C/C++ standard.
130 *out
= reg_
>> (kRegWidthInBits
- num_bits
);
136 bool BitReaderCore::Refill(int min_nbits
) {
137 DCHECK_LE(min_nbits
, kRegWidthInBits
);
139 // Transfer from the next to the current register.
140 RefillCurrentRegister();
141 if (min_nbits
<= nbits_
)
143 DCHECK_EQ(nbits_next_
, 0);
144 DCHECK_EQ(reg_next_
, 0u);
146 // Max number of bytes to refill.
147 int max_nbytes
= sizeof(reg_next_
);
150 const uint8
* byte_stream_window
;
152 byte_stream_provider_
->GetBytes(max_nbytes
, &byte_stream_window
);
153 DCHECK_GE(window_size
, 0);
154 DCHECK_LE(window_size
, max_nbytes
);
155 if (window_size
== 0)
159 memcpy(®_next_
, byte_stream_window
, window_size
);
160 reg_next_
= base::NetToHost64(reg_next_
);
161 nbits_next_
= window_size
* 8;
163 // Transfer from the next to the current register.
164 RefillCurrentRegister();
166 return (nbits_
>= min_nbits
);
169 void BitReaderCore::RefillCurrentRegister() {
170 // No refill possible if the destination register is full
171 // or the source register is empty.
172 if (nbits_
== kRegWidthInBits
|| nbits_next_
== 0)
175 reg_
|= (reg_next_
>> nbits_
);
177 int free_nbits
= kRegWidthInBits
- nbits_
;
178 if (free_nbits
>= nbits_next_
) {
179 nbits_
+= nbits_next_
;
185 nbits_
+= free_nbits
;
186 reg_next_
<<= free_nbits
;
187 nbits_next_
-= free_nbits
;