OLD | NEW |
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 "media/webm/webm_cluster_parser.h" | 5 #include "media/webm/webm_cluster_parser.h" |
6 | 6 |
7 #include <vector> | 7 #include <vector> |
8 | 8 |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "media/base/buffers.h" | 10 #include "media/base/buffers.h" |
11 #include "media/base/decrypt_config.h" | 11 #include "media/base/decrypt_config.h" |
12 #include "media/webm/webm_constants.h" | 12 #include "media/webm/webm_constants.h" |
| 13 #include "media/webm/webm_crypto_helpers.h" |
13 | 14 |
14 namespace media { | 15 namespace media { |
15 | 16 |
16 // Generates a 16 byte CTR counter block. The CTR counter block format is a | |
17 // CTR IV appended with a CTR block counter. |iv| is an 8 byte CTR IV. | |
18 // |iv_size| is the size of |iv| in btyes. Returns a string of | |
19 // kDecryptionKeySize bytes. | |
20 static std::string GenerateCounterBlock(const uint8* iv, int iv_size) { | |
21 std::string counter_block(reinterpret_cast<const char*>(iv), iv_size); | |
22 counter_block.append(DecryptConfig::kDecryptionKeySize - iv_size, 0); | |
23 return counter_block; | |
24 } | |
25 | |
26 WebMClusterParser::TextTrackIterator::TextTrackIterator( | 17 WebMClusterParser::TextTrackIterator::TextTrackIterator( |
27 const TextTrackMap& text_track_map) : | 18 const TextTrackMap& text_track_map) : |
28 iterator_(text_track_map.begin()), | 19 iterator_(text_track_map.begin()), |
29 iterator_end_(text_track_map.end()) { | 20 iterator_end_(text_track_map.end()) { |
30 } | 21 } |
31 | 22 |
32 WebMClusterParser::TextTrackIterator::TextTrackIterator( | 23 WebMClusterParser::TextTrackIterator::TextTrackIterator( |
33 const TextTrackIterator& rhs) : | 24 const TextTrackIterator& rhs) : |
34 iterator_(rhs.iterator_), | 25 iterator_(rhs.iterator_), |
35 iterator_end_(rhs.iterator_end_) { | 26 iterator_end_(rhs.iterator_end_) { |
(...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
287 bool is_keyframe = | 278 bool is_keyframe = |
288 is_simple_block ? (flags & 0x80) != 0 : track->IsKeyframe(data, size); | 279 is_simple_block ? (flags & 0x80) != 0 : track->IsKeyframe(data, size); |
289 | 280 |
290 scoped_refptr<StreamParserBuffer> buffer = | 281 scoped_refptr<StreamParserBuffer> buffer = |
291 StreamParserBuffer::CopyFrom(data, size, is_keyframe); | 282 StreamParserBuffer::CopyFrom(data, size, is_keyframe); |
292 | 283 |
293 // Every encrypted Block has a signal byte and IV prepended to it. Current | 284 // Every encrypted Block has a signal byte and IV prepended to it. Current |
294 // encrypted WebM request for comments specification is here | 285 // encrypted WebM request for comments specification is here |
295 // http://wiki.webmproject.org/encryption/webm-encryption-rfc | 286 // http://wiki.webmproject.org/encryption/webm-encryption-rfc |
296 if (!encryption_key_id.empty()) { | 287 if (!encryption_key_id.empty()) { |
297 DCHECK_EQ(kWebMSignalByteSize, 1); | 288 scoped_ptr<DecryptConfig> config(WebMCreateDecryptConfig( |
298 if (size < kWebMSignalByteSize) { | 289 data, size, |
299 MEDIA_LOG(log_cb_) | 290 reinterpret_cast<const uint8*>(encryption_key_id.data()), |
300 << "Got a block from an encrypted stream with no data."; | 291 encryption_key_id.size())); |
| 292 if (!config) |
301 return false; | 293 return false; |
302 } | 294 buffer->SetDecryptConfig(config.Pass()); |
303 uint8 signal_byte = data[0]; | |
304 int data_offset = sizeof(signal_byte); | |
305 | |
306 // Setting the DecryptConfig object of the buffer while leaving the | |
307 // initialization vector empty will tell the decryptor that the frame is | |
308 // unencrypted. | |
309 std::string counter_block; | |
310 | |
311 if (signal_byte & kWebMFlagEncryptedFrame) { | |
312 if (size < kWebMSignalByteSize + kWebMIvSize) { | |
313 MEDIA_LOG(log_cb_) << "Got an encrypted block with not enough data " | |
314 << size; | |
315 return false; | |
316 } | |
317 counter_block = GenerateCounterBlock(data + data_offset, kWebMIvSize); | |
318 data_offset += kWebMIvSize; | |
319 } | |
320 | |
321 // TODO(fgalligan): Revisit if DecryptConfig needs to be set on unencrypted | |
322 // frames after the CDM API is finalized. | |
323 // Unencrypted frames of potentially encrypted streams currently set | |
324 // DecryptConfig. | |
325 buffer->SetDecryptConfig(scoped_ptr<DecryptConfig>(new DecryptConfig( | |
326 encryption_key_id, | |
327 counter_block, | |
328 data_offset, | |
329 std::vector<SubsampleEntry>()))); | |
330 } | 295 } |
331 | 296 |
332 buffer->SetTimestamp(timestamp); | 297 buffer->SetTimestamp(timestamp); |
333 if (cluster_start_time_ == kNoTimestamp()) | 298 if (cluster_start_time_ == kNoTimestamp()) |
334 cluster_start_time_ = timestamp; | 299 cluster_start_time_ = timestamp; |
335 | 300 |
336 if (block_duration >= 0) { | 301 if (block_duration >= 0) { |
337 buffer->SetDuration(base::TimeDelta::FromMicroseconds( | 302 buffer->SetDuration(base::TimeDelta::FromMicroseconds( |
338 block_duration * timecode_multiplier_)); | 303 block_duration * timecode_multiplier_)); |
339 } | 304 } |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
399 WebMClusterParser::FindTextTrack(int track_num) { | 364 WebMClusterParser::FindTextTrack(int track_num) { |
400 const TextTrackMap::iterator it = text_track_map_.find(track_num); | 365 const TextTrackMap::iterator it = text_track_map_.find(track_num); |
401 | 366 |
402 if (it == text_track_map_.end()) | 367 if (it == text_track_map_.end()) |
403 return NULL; | 368 return NULL; |
404 | 369 |
405 return &it->second; | 370 return &it->second; |
406 } | 371 } |
407 | 372 |
408 } // namespace media | 373 } // namespace media |
OLD | NEW |