Index: media/base/bit_reader_h264.cc |
diff --git a/media/base/bit_reader_h264.cc b/media/base/bit_reader_h264.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..14ab2a636d14bc81e469eae1b1c5a7c3b22616bc |
--- /dev/null |
+++ b/media/base/bit_reader_h264.cc |
@@ -0,0 +1,112 @@ |
+// Copyright (c) 2013 The Chromium Authors. All rights reserved. |
acolwell GONE FROM CHROMIUM
2014/01/11 00:24:37
s/2013/2014
damienv1
2014/01/13 22:41:06
Done.
|
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "media/base/bit_reader_h264.h" |
+ |
+namespace media { |
+ |
+// static |
+const int BitReaderH264::kMaxExpGolombCodeSize = 63; |
+ |
+BitReaderH264::BitReaderH264(const uint8* data, int size) |
+ : data_(data), |
+ bytes_left_(size), |
+ prev_two_bytes_(0xffff), |
+ bit_reader_core_(this) { |
+ DCHECK(data_ != NULL); |
+ DCHECK_GE(bytes_left_, 0); |
+} |
+ |
+BitReaderH264::~BitReaderH264() {} |
+ |
+bool BitReaderH264::ReadUE(uint32* out, int* code_size) { |
+ int ue_code_size = ReadUEInternal(out); |
+ |
+ if (code_size) |
+ *code_size = ue_code_size; |
+ |
+ return (ue_code_size >= 0 && ue_code_size <= kMaxExpGolombCodeSize); |
+} |
+ |
+bool BitReaderH264::HasMoreRBSPData() { |
+ uint64 bit_reg; |
+ int nbits = bit_reader_core_.PeekBitsMsbAligned(9, &bit_reg); |
+ |
+ // Not on last byte. |
+ if (nbits > 8) |
+ return true; |
+ |
+ // Last byte, look for stop bit; |
+ // We have more RBSP data if the last non-zero bit we find is not the |
+ // first available bit. |
+ return (bit_reg << 1) != 0; |
+} |
+ |
+int BitReaderH264::GetBytes(int max_nbytes, const uint8** out) { |
+ DCHECK_LE(max_nbytes, static_cast<int>(sizeof(data_window_))); |
+ DCHECK_GE(max_nbytes, 0); |
+ DCHECK(out); |
+ |
+ const uint8* start = data_; |
+ bool emulation_prevention_byte_detected = false; |
+ |
+ int nbytes = 0; |
+ *out = data_; |
+ |
+ while (nbytes < max_nbytes && bytes_left_ > 0) { |
+ // Emulation prevention three-byte detection. |
+ // If a sequence of 0x000003 is found, skip (ignore) the last byte (0x03) |
+ // and starts copying data to |data_window_| which is used as the output. |
+ if (*data_ == 0x3 && (prev_two_bytes_ & 0xffff) == 0) { |
+ if (!emulation_prevention_byte_detected && nbytes > 0) |
+ memcpy(data_window_, start, nbytes); |
+ emulation_prevention_byte_detected = true; |
+ *out = data_window_; |
+ // Need another full three bytes before we can detect the sequence again. |
+ prev_two_bytes_ = 0xffff; |
+ } else { |
+ if (emulation_prevention_byte_detected) |
+ data_window_[nbytes] = *data_; |
+ prev_two_bytes_ = (prev_two_bytes_ << 8) | *data_; |
+ ++nbytes; |
+ } |
+ |
+ ++data_; |
+ --bytes_left_; |
+ } |
+ |
+ return nbytes; |
+} |
+ |
+int BitReaderH264::ReadUEInternal(uint32* out) { |
+ // Get the number of leading zeros. |
+ int zero_count = -1; |
+ bool is_one; |
+ do { |
+ if (!bit_reader_core_.ReadFlag(&is_one)) |
+ return -1; |
+ zero_count++; |
+ } while(!is_one); |
+ |
+ int code_size = 2 * zero_count + 1; |
+ |
+ // If zero_count is greater than 31, the calculated value will overflow, |
acolwell GONE FROM CHROMIUM
2014/01/11 00:24:37
nit: This comment appears to be out of sync w/ the
damienv1
2014/01/13 22:41:06
Updated the comment based on the exp-golomb code s
|
+ // just skip the bits corresponding to the exp-golomb value. |
+ if (code_size > kMaxExpGolombCodeSize) { |
+ if (!bit_reader_core_.SkipBits(zero_count)) |
+ return -1; |
+ return code_size; |
+ } |
+ |
+ // Read the actual value. |
+ uint32 base = (1 << zero_count) - 1; |
acolwell GONE FROM CHROMIUM
2014/01/11 00:24:37
nit: Doesn't this take us into undefined territory
damienv1
2014/01/13 22:41:06
The code size is basically twice longer that the s
|
+ uint32 offset; |
+ if (!ReadBits(zero_count, &offset)) |
+ return -1; |
+ *out = base + offset; |
+ |
+ return code_size; |
+} |
+ |
+} // namespace media |