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

Side by Side Diff: content/common/gpu/media/h264_parser.cc

Issue 10834071: Add unittest for H264BitReader. (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Add empty line between common and specific headers. Created 8 years, 4 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
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/common/gpu/media/h264_parser.h" 5 #include "content/common/gpu/media/h264_parser.h"
6 6
7 #include "base/logging.h" 7 #include "base/logging.h"
8 #include "base/memory/scoped_ptr.h" 8 #include "base/memory/scoped_ptr.h"
9 #include "base/stl_util.h" 9 #include "base/stl_util.h"
10 10
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
43 } 43 }
44 44
45 H264SliceHeader::H264SliceHeader() { 45 H264SliceHeader::H264SliceHeader() {
46 memset(this, 0, sizeof(*this)); 46 memset(this, 0, sizeof(*this));
47 } 47 }
48 48
49 H264SEIMessage::H264SEIMessage() { 49 H264SEIMessage::H264SEIMessage() {
50 memset(this, 0, sizeof(*this)); 50 memset(this, 0, sizeof(*this));
51 } 51 }
52 52
53 H264Parser::H264BitReader::H264BitReader()
54 : data_(NULL),
55 bytes_left_(0),
56 curr_byte_(0),
57 num_remaining_bits_in_curr_byte_(0),
58 prev_two_bytes_(0) {
59 }
60
61 H264Parser::H264BitReader::~H264BitReader() {}
62
63 bool H264Parser::H264BitReader::Initialize(const uint8* data, off_t size) {
64 DCHECK(data);
65
66 if (size < 1)
67 return false;
68
69 data_ = data;
70 bytes_left_ = size;
71 num_remaining_bits_in_curr_byte_ = 0;
72 // Initially set to 0xffff to accept all initial two-byte sequences.
73 prev_two_bytes_ = 0xffff;
74
75 return true;
76 }
77
78 bool H264Parser::H264BitReader::UpdateCurrByte() {
79 if (bytes_left_ < 1)
80 return false;
81
82 // Emulation prevention three-byte detection.
83 // If a sequence of 0x000003 is found, skip (ignore) the last byte (0x03).
84 if (*data_ == 0x03 && (prev_two_bytes_ & 0xffff) == 0) {
85 // Detected 0x000003, skip last byte.
86 ++data_;
87 --bytes_left_;
88 // Need another full three bytes before we can detect the sequence again.
89 prev_two_bytes_ = 0xffff;
90
91 if (bytes_left_ < 1)
92 return false;
93 }
94
95 // Load a new byte and advance pointers.
96 curr_byte_ = *data_++ & 0xff;
97 --bytes_left_;
98 num_remaining_bits_in_curr_byte_ = 8;
99
100 prev_two_bytes_ = (prev_two_bytes_ << 8) | curr_byte_;
101
102 return true;
103 }
104
105 // Read |num_bits| (1 to 31 inclusive) from the stream and return them
106 // in |out|, with first bit in the stream as MSB in |out| at position
107 // (|num_bits| - 1).
108 bool H264Parser::H264BitReader::ReadBits(int num_bits, int *out) {
109 int bits_left = num_bits;
110 *out = 0;
111 DCHECK(num_bits <= 31);
112
113 while (num_remaining_bits_in_curr_byte_ < bits_left) {
114 // Take all that's left in current byte, shift to make space for the rest.
115 *out = (curr_byte_ << (bits_left - num_remaining_bits_in_curr_byte_));
116 bits_left -= num_remaining_bits_in_curr_byte_;
117
118 if (!UpdateCurrByte())
119 return false;
120 }
121
122 *out |= (curr_byte_ >> (num_remaining_bits_in_curr_byte_ - bits_left));
123 *out &= ((1 << num_bits) - 1);
124 num_remaining_bits_in_curr_byte_ -= bits_left;
125
126 return true;
127 }
128
129 off_t H264Parser::H264BitReader::NumBitsLeft() {
130 return (num_remaining_bits_in_curr_byte_ + bytes_left_ * 8);
131 }
132
133 bool H264Parser::H264BitReader::HasMoreRBSPData() {
134 // Make sure we have more bits, if we are at 0 bits in current byte
135 // and updating current byte fails, we don't have more data anyway.
136 if (num_remaining_bits_in_curr_byte_ == 0 && !UpdateCurrByte())
137 return false;
138
139 // On last byte?
140 if (bytes_left_)
141 return true;
142
143 // Last byte, look for stop bit;
144 // We have more RBSP data if the last non-zero bit we find is not the
145 // first available bit.
146 return (curr_byte_ &
147 ((1 << (num_remaining_bits_in_curr_byte_ - 1)) - 1)) != 0;
148 }
149
150 #define READ_BITS_OR_RETURN(num_bits, out) \ 53 #define READ_BITS_OR_RETURN(num_bits, out) \
151 do { \ 54 do { \
152 int _out; \ 55 int _out; \
153 if (!br_.ReadBits(num_bits, &_out)) { \ 56 if (!br_.ReadBits(num_bits, &_out)) { \
154 DVLOG(1) << "Error in stream: unexpected EOS while trying to read " #out; \ 57 DVLOG(1) << "Error in stream: unexpected EOS while trying to read " #out; \
155 return kInvalidStream; \ 58 return kInvalidStream; \
156 } \ 59 } \
157 *out = _out; \ 60 *out = _out; \
158 } while (0) 61 } while (0)
159 62
(...skipping 1052 matching lines...) Expand 10 before | Expand all | Expand 10 after
1212 1115
1213 default: 1116 default:
1214 DVLOG(4) << "Unsupported SEI message"; 1117 DVLOG(4) << "Unsupported SEI message";
1215 break; 1118 break;
1216 } 1119 }
1217 1120
1218 return kOk; 1121 return kOk;
1219 } 1122 }
1220 1123
1221 } // namespace content 1124 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698