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

Side by Side Diff: media/filters/h264_parser.cc

Issue 379983002: Fix AnnexB validation logic to work with encrypted content. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 5 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 2014 The Chromium Authors. All rights reserved. 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 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 "base/logging.h" 5 #include "base/logging.h"
6 #include "base/memory/scoped_ptr.h" 6 #include "base/memory/scoped_ptr.h"
7 #include "base/stl_util.h" 7 #include "base/stl_util.h"
8 8
9 #include "media/base/decrypt_config.h"
9 #include "media/filters/h264_parser.h" 10 #include "media/filters/h264_parser.h"
10 11
11 namespace media { 12 namespace media {
12 13
13 bool H264SliceHeader::IsPSlice() const { 14 bool H264SliceHeader::IsPSlice() const {
14 return (slice_type % 5 == kPSlice); 15 return (slice_type % 5 == kPSlice);
15 } 16 }
16 17
17 bool H264SliceHeader::IsBSlice() const { 18 bool H264SliceHeader::IsBSlice() const {
18 return (slice_type % 5 == kBSlice); 19 return (slice_type % 5 == kBSlice);
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
122 } 123 }
123 124
124 H264Parser::~H264Parser() { 125 H264Parser::~H264Parser() {
125 STLDeleteValues(&active_SPSes_); 126 STLDeleteValues(&active_SPSes_);
126 STLDeleteValues(&active_PPSes_); 127 STLDeleteValues(&active_PPSes_);
127 } 128 }
128 129
129 void H264Parser::Reset() { 130 void H264Parser::Reset() {
130 stream_ = NULL; 131 stream_ = NULL;
131 bytes_left_ = 0; 132 bytes_left_ = 0;
133 encrypted_ranges_.clear();
132 } 134 }
133 135
134 void H264Parser::SetStream(const uint8* stream, off_t stream_size) { 136 void H264Parser::SetStream(const uint8* stream, off_t stream_size) {
137 std::vector<SubsampleEntry> subsamples;
138 SetStream(stream, stream_size, subsamples);
139 }
140
141 void H264Parser::SetStream(const uint8* stream, off_t stream_size,
142 const std::vector<SubsampleEntry>& subsamples) {
135 DCHECK(stream); 143 DCHECK(stream);
136 DCHECK_GT(stream_size, 0); 144 DCHECK_GT(stream_size, 0);
137 145
138 stream_ = stream; 146 stream_ = stream;
139 bytes_left_ = stream_size; 147 bytes_left_ = stream_size;
148
149 encrypted_ranges_.clear();
150 const uint8* offset = stream;
151 for (size_t i = 0; i < subsamples.size(); ++i) {
152 offset += subsamples[i].clear_bytes;
153
154 encrypted_ranges_.Add(offset, offset + subsamples[i].cypher_bytes);
155
156 offset += subsamples[i].cypher_bytes;
157 }
140 } 158 }
141 159
142 const H264PPS* H264Parser::GetPPS(int pps_id) { 160 const H264PPS* H264Parser::GetPPS(int pps_id) {
143 return active_PPSes_[pps_id]; 161 return active_PPSes_[pps_id];
144 } 162 }
145 163
146 const H264SPS* H264Parser::GetSPS(int sps_id) { 164 const H264SPS* H264Parser::GetSPS(int sps_id) {
147 return active_SPSes_[sps_id]; 165 return active_SPSes_[sps_id];
148 } 166 }
149 167
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
184 // |*offset| is equal to 0 (valid offset). 202 // |*offset| is equal to 0 (valid offset).
185 *offset = data_size - bytes_left; 203 *offset = data_size - bytes_left;
186 *start_code_size = 0; 204 *start_code_size = 0;
187 return false; 205 return false;
188 } 206 }
189 207
190 bool H264Parser::LocateNALU(off_t* nalu_size, off_t* start_code_size) { 208 bool H264Parser::LocateNALU(off_t* nalu_size, off_t* start_code_size) {
191 // Find the start code of next NALU. 209 // Find the start code of next NALU.
192 off_t nalu_start_off = 0; 210 off_t nalu_start_off = 0;
193 off_t annexb_start_code_size = 0; 211 off_t annexb_start_code_size = 0;
194 if (!FindStartCode(stream_, bytes_left_, 212
195 &nalu_start_off, &annexb_start_code_size)) { 213 if (!FindNextStartCode(stream_, bytes_left_,
214 &nalu_start_off, &annexb_start_code_size)) {
196 DVLOG(4) << "Could not find start code, end of stream?"; 215 DVLOG(4) << "Could not find start code, end of stream?";
197 return false; 216 return false;
198 } 217 }
199 218
200 // Move the stream to the beginning of the NALU (pointing at the start code). 219 // Move the stream to the beginning of the NALU (pointing at the start code).
201 stream_ += nalu_start_off; 220 stream_ += nalu_start_off;
202 bytes_left_ -= nalu_start_off; 221 bytes_left_ -= nalu_start_off;
203 222
204 const uint8* nalu_data = stream_ + annexb_start_code_size; 223 const uint8* nalu_data = stream_ + annexb_start_code_size;
205 off_t max_nalu_data_size = bytes_left_ - annexb_start_code_size; 224 off_t max_nalu_data_size = bytes_left_ - annexb_start_code_size;
206 if (max_nalu_data_size <= 0) { 225 if (max_nalu_data_size <= 0) {
207 DVLOG(3) << "End of stream"; 226 DVLOG(3) << "End of stream";
208 return false; 227 return false;
209 } 228 }
210 229
211 // Find the start code of next NALU; 230 // Find the start code of next NALU;
212 // if successful, |nalu_size_without_start_code| is the number of bytes from 231 // if successful, |nalu_size_without_start_code| is the number of bytes from
213 // after previous start code to before this one; 232 // after previous start code to before this one;
214 // if next start code is not found, it is still a valid NALU since there 233 // if next start code is not found, it is still a valid NALU since there
215 // are some bytes left after the first start code: all the remaining bytes 234 // are some bytes left after the first start code: all the remaining bytes
216 // belong to the current NALU. 235 // belong to the current NALU.
217 off_t next_start_code_size = 0; 236 off_t next_start_code_size = 0;
218 off_t nalu_size_without_start_code = 0; 237 off_t nalu_size_without_start_code = 0;
219 if (!FindStartCode(nalu_data, max_nalu_data_size, 238 if (!FindNextStartCode(nalu_data, max_nalu_data_size,
220 &nalu_size_without_start_code, &next_start_code_size)) { 239 &nalu_size_without_start_code,
240 &next_start_code_size)) {
221 nalu_size_without_start_code = max_nalu_data_size; 241 nalu_size_without_start_code = max_nalu_data_size;
222 } 242 }
223 *nalu_size = nalu_size_without_start_code + annexb_start_code_size; 243 *nalu_size = nalu_size_without_start_code + annexb_start_code_size;
224 *start_code_size = annexb_start_code_size; 244 *start_code_size = annexb_start_code_size;
225 return true; 245 return true;
226 } 246 }
227 247
248 bool H264Parser::FindNextStartCode(const uint8* data, off_t data_size,
249 off_t* offset, off_t* start_code_size) {
250 if (encrypted_ranges_.size() == 0)
251 return FindStartCode(data, data_size, offset, start_code_size);
252
253 DCHECK_GE(data_size, 0);
254 const uint8* start = data;
255 do {
256 off_t bytes_left = data_size - (start - data);
257
258 if (!FindStartCode(start, bytes_left, offset, start_code_size))
259 return false;
260
261 const uint8* start_code = start + *offset;
262 const uint8* start_code_end = start_code + *start_code_size;
263 Ranges<const uint8*> start_code_range;
264 start_code_range.Add(start_code, start_code_end);
265
266 if (encrypted_ranges_.IntersectionWith(start_code_range).size() > 0) {
267 // The start code is inside an encrypted section so we need to scan
268 // for another start code.
269 *start_code_size = 0;
270 start += std::min(*offset + 1, bytes_left);
271 }
272 } while (*start_code_size == 0);
xhwang 2014/07/10 06:23:01 Will it be simpler and more efficient if you just
acolwell GONE FROM CHROMIUM 2014/07/15 22:10:44 I've changed the code around to search clear range
273
274 // Update |*offset| to include the data we skipped over.
275 *offset += start - data;
276 return true;
277 }
278
228 H264Parser::Result H264Parser::ReadUE(int* val) { 279 H264Parser::Result H264Parser::ReadUE(int* val) {
229 int num_bits = -1; 280 int num_bits = -1;
230 int bit; 281 int bit;
231 int rest; 282 int rest;
232 283
233 // Count the number of contiguous zero bits. 284 // Count the number of contiguous zero bits.
234 do { 285 do {
235 READ_BITS_OR_RETURN(1, &bit); 286 READ_BITS_OR_RETURN(1, &bit);
236 num_bits++; 287 num_bits++;
237 } while (bit == 0); 288 } while (bit == 0);
(...skipping 1013 matching lines...) Expand 10 before | Expand all | Expand 10 after
1251 1302
1252 default: 1303 default:
1253 DVLOG(4) << "Unsupported SEI message"; 1304 DVLOG(4) << "Unsupported SEI message";
1254 break; 1305 break;
1255 } 1306 }
1256 1307
1257 return kOk; 1308 return kOk;
1258 } 1309 }
1259 1310
1260 } // namespace media 1311 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698