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 "base/logging.h" 6 #include "media/filters/h264_bit_reader.h" 7 8 namespace media { 9 10 H264BitReader::H264BitReader() 11 : data_(NULL), 12 bytes_left_(0), 13 curr_byte_(0), 14 num_remaining_bits_in_curr_byte_(0), 15 prev_two_bytes_(0), 16 emulation_prevention_bytes_(0) {} 17 18 H264BitReader::~H264BitReader() {} 19 20 bool H264BitReader::Initialize(const uint8* data, off_t size) { 21 DCHECK(data); 22 23 if (size < 1) 24 return false; 25 26 data_ = data; 27 bytes_left_ = size; 28 num_remaining_bits_in_curr_byte_ = 0; 29 // Initially set to 0xffff to accept all initial two-byte sequences. 30 prev_two_bytes_ = 0xffff; 31 emulation_prevention_bytes_ = 0; 32 33 return true; 34 } 35 36 bool H264BitReader::UpdateCurrByte() { 37 if (bytes_left_ < 1) 38 return false; 39 40 // Emulation prevention three-byte detection. 41 // If a sequence of 0x000003 is found, skip (ignore) the last byte (0x03). 42 if (*data_ == 0x03 && (prev_two_bytes_ & 0xffff) == 0) { 43 // Detected 0x000003, skip last byte. 44 ++data_; 45 --bytes_left_; 46 ++emulation_prevention_bytes_; 47 // Need another full three bytes before we can detect the sequence again. 48 prev_two_bytes_ = 0xffff; 49 50 if (bytes_left_ < 1) 51 return false; 52 } 53 54 // Load a new byte and advance pointers. 55 curr_byte_ = *data_++ & 0xff; 56 --bytes_left_; 57 num_remaining_bits_in_curr_byte_ = 8; 58 59 prev_two_bytes_ = (prev_two_bytes_ << 8) | curr_byte_; 60 61 return true; 62 } 63 64 // Read |num_bits| (1 to 31 inclusive) from the stream and return them 65 // in |out|, with first bit in the stream as MSB in |out| at position 66 // (|num_bits| - 1). 67 bool H264BitReader::ReadBits(int num_bits, int* out) { 68 int bits_left = num_bits; 69 *out = 0; 70 DCHECK(num_bits <= 31); 71 72 while (num_remaining_bits_in_curr_byte_ < bits_left) { 73 // Take all that's left in current byte, shift to make space for the rest. 74 *out |= (curr_byte_ << (bits_left - num_remaining_bits_in_curr_byte_)); 75 bits_left -= num_remaining_bits_in_curr_byte_; 76 77 if (!UpdateCurrByte()) 78 return false; 79 } 80 81 *out |= (curr_byte_ >> (num_remaining_bits_in_curr_byte_ - bits_left)); 82 *out &= ((1 << num_bits) - 1); 83 num_remaining_bits_in_curr_byte_ -= bits_left; 84 85 return true; 86 } 87 88 off_t H264BitReader::NumBitsLeft() { 89 return (num_remaining_bits_in_curr_byte_ + bytes_left_ * 8); 90 } 91 92 bool H264BitReader::HasMoreRBSPData() { 93 // Make sure we have more bits, if we are at 0 bits in current byte 94 // and updating current byte fails, we don't have more data anyway. 95 if (num_remaining_bits_in_curr_byte_ == 0 && !UpdateCurrByte()) 96 return false; 97 98 // On last byte? 99 if (bytes_left_) 100 return true; 101 102 // Last byte, look for stop bit; 103 // We have more RBSP data if the last non-zero bit we find is not the 104 // first available bit. 105 return (curr_byte_ & 106 ((1 << (num_remaining_bits_in_curr_byte_ - 1)) - 1)) != 0; 107 } 108 109 size_t H264BitReader::NumEmulationPreventionBytesRead() { 110 return emulation_prevention_bytes_; 111 } 112 113 } // namespace media 114