OLD | NEW |
---|---|
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 "media/formats/mp4/mp4_stream_parser.h" | 5 #include "media/formats/mp4/mp4_stream_parser.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 | 8 |
9 #include <limits> | 9 #include <limits> |
10 #include <memory> | 10 #include <memory> |
11 #include <utility> | 11 #include <utility> |
12 #include <vector> | 12 #include <vector> |
13 | 13 |
14 #include "base/callback_helpers.h" | 14 #include "base/callback_helpers.h" |
15 #include "base/logging.h" | 15 #include "base/logging.h" |
16 #include "base/strings/string_number_conversions.h" | 16 #include "base/strings/string_number_conversions.h" |
17 #include "base/time/time.h" | 17 #include "base/time/time.h" |
18 #include "build/build_config.h" | 18 #include "build/build_config.h" |
19 #include "media/base/audio_decoder_config.h" | 19 #include "media/base/audio_decoder_config.h" |
20 #include "media/base/encryption_scheme.h" | |
20 #include "media/base/media_tracks.h" | 21 #include "media/base/media_tracks.h" |
21 #include "media/base/media_util.h" | 22 #include "media/base/media_util.h" |
22 #include "media/base/stream_parser_buffer.h" | 23 #include "media/base/stream_parser_buffer.h" |
23 #include "media/base/text_track_config.h" | 24 #include "media/base/text_track_config.h" |
24 #include "media/base/timestamp_constants.h" | 25 #include "media/base/timestamp_constants.h" |
25 #include "media/base/video_decoder_config.h" | 26 #include "media/base/video_decoder_config.h" |
26 #include "media/base/video_util.h" | 27 #include "media/base/video_util.h" |
27 #include "media/formats/mp4/box_definitions.h" | 28 #include "media/formats/mp4/box_definitions.h" |
28 #include "media/formats/mp4/box_reader.h" | 29 #include "media/formats/mp4/box_reader.h" |
29 #include "media/formats/mp4/es_descriptor.h" | 30 #include "media/formats/mp4/es_descriptor.h" |
30 #include "media/formats/mp4/rcheck.h" | 31 #include "media/formats/mp4/rcheck.h" |
31 #include "media/formats/mpeg/adts_constants.h" | 32 #include "media/formats/mpeg/adts_constants.h" |
32 | 33 |
33 namespace media { | 34 namespace media { |
34 namespace mp4 { | 35 namespace mp4 { |
35 | 36 |
37 namespace { | |
38 | |
39 EncryptionScheme GetEncryptionScheme(const ProtectionSchemeInfo& sinf) { | |
40 if (!sinf.HasSupportedScheme()) | |
41 return Unencrypted(); | |
ddorwin
2016/06/17 23:32:41
Is that the best way to handle this? We know it is
dougsteed
2016/10/10 18:18:01
Done.
| |
42 FourCC fourCC = sinf.type.type; | |
43 EncryptionScheme::CipherMode mode = EncryptionScheme::CIPHER_MODE_UNENCRYPTED; | |
44 EncryptionScheme::Pattern pattern; | |
45 bool pattern_encryption = false; | |
ddorwin
2016/06/17 23:32:41
nit: is_/uses_...
dougsteed
2016/10/10 18:18:02
Done.
| |
46 switch (fourCC) { | |
47 case FOURCC_CENC: | |
48 mode = EncryptionScheme::CIPHER_MODE_AES_CTR; | |
49 break; | |
50 #if BUILDFLAG(ENABLE_CBCS_ENCRYPTION_SCHEME) | |
51 case FOURCC_CBCS: | |
52 mode = EncryptionScheme::CIPHER_MODE_AES_CBC; | |
53 pattern_encryption = true; | |
54 break; | |
55 #endif | |
56 default: | |
57 DLOG(WARNING) << "Unsupported encryption scheme: " << fourCC; | |
ddorwin
2016/06/17 23:32:40
Should this be a DCHECK based on line 40?
dougsteed
2016/10/10 18:18:02
Done.
| |
58 break; | |
59 } | |
60 #if BUILDFLAG(ENABLE_CBCS_ENCRYPTION_SCHEME) | |
61 if (pattern_encryption) { | |
62 uint8_t crypt = sinf.info.track_encryption.default_crypt_byte_block; | |
ddorwin
2016/06/17 23:32:40
ditto on "crypt"
dougsteed
2016/10/10 18:18:01
as mentioned above, this is the term used in the s
| |
63 uint8_t skip = sinf.info.track_encryption.default_skip_byte_block; | |
64 pattern = EncryptionScheme::Pattern(crypt, skip); | |
65 } | |
66 #endif | |
67 return EncryptionScheme(mode, pattern); | |
68 } | |
69 | |
70 } // namespace | |
71 | |
36 MP4StreamParser::MP4StreamParser(const std::set<int>& audio_object_types, | 72 MP4StreamParser::MP4StreamParser(const std::set<int>& audio_object_types, |
37 bool has_sbr) | 73 bool has_sbr) |
38 : state_(kWaitingForInit), | 74 : state_(kWaitingForInit), |
39 moof_head_(0), | 75 moof_head_(0), |
40 mdat_tail_(0), | 76 mdat_tail_(0), |
41 highest_end_offset_(0), | 77 highest_end_offset_(0), |
42 has_audio_(false), | 78 has_audio_(false), |
43 has_video_(false), | 79 has_video_(false), |
44 audio_track_id_(0), | 80 audio_track_id_(0), |
45 video_track_id_(0), | 81 video_track_id_(0), |
(...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
309 sample_format = kSampleFormatS32; | 345 sample_format = kSampleFormatS32; |
310 } else { | 346 } else { |
311 LOG(ERROR) << "Unsupported sample size."; | 347 LOG(ERROR) << "Unsupported sample size."; |
312 return false; | 348 return false; |
313 } | 349 } |
314 | 350 |
315 is_audio_track_encrypted_ = entry.sinf.info.track_encryption.is_encrypted; | 351 is_audio_track_encrypted_ = entry.sinf.info.track_encryption.is_encrypted; |
316 DVLOG(1) << "is_audio_track_encrypted_: " << is_audio_track_encrypted_; | 352 DVLOG(1) << "is_audio_track_encrypted_: " << is_audio_track_encrypted_; |
317 audio_config.Initialize( | 353 audio_config.Initialize( |
318 codec, sample_format, channel_layout, sample_per_second, extra_data, | 354 codec, sample_format, channel_layout, sample_per_second, extra_data, |
319 is_audio_track_encrypted_ ? AesCtrEncryptionScheme() : Unencrypted(), | 355 is_audio_track_encrypted_ ? GetEncryptionScheme(entry.sinf) |
ddorwin
2016/06/17 23:32:40
Continuing from line 41, we know it's encrypted, b
dougsteed
2016/10/10 18:18:01
Done.
| |
356 : Unencrypted(), | |
320 base::TimeDelta(), 0); | 357 base::TimeDelta(), 0); |
321 has_audio_ = true; | 358 has_audio_ = true; |
322 audio_track_id_ = track->header.track_id; | 359 audio_track_id_ = track->header.track_id; |
323 media_tracks->AddAudioTrack( | 360 media_tracks->AddAudioTrack( |
324 audio_config, base::UintToString(audio_track_id_), "main", | 361 audio_config, base::UintToString(audio_track_id_), "main", |
325 track->media.handler.name, track->media.header.language()); | 362 track->media.handler.name, track->media.header.language()); |
326 continue; | 363 continue; |
327 } | 364 } |
328 | 365 |
329 if (track->media.handler.type == kVideo) { | 366 if (track->media.handler.type == kVideo) { |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
361 } | 398 } |
362 | 399 |
363 is_video_track_encrypted_ = entry.sinf.info.track_encryption.is_encrypted; | 400 is_video_track_encrypted_ = entry.sinf.info.track_encryption.is_encrypted; |
364 DVLOG(1) << "is_video_track_encrypted_: " << is_video_track_encrypted_; | 401 DVLOG(1) << "is_video_track_encrypted_: " << is_video_track_encrypted_; |
365 video_config.Initialize( | 402 video_config.Initialize( |
366 entry.video_codec, entry.video_codec_profile, PIXEL_FORMAT_YV12, | 403 entry.video_codec, entry.video_codec_profile, PIXEL_FORMAT_YV12, |
367 COLOR_SPACE_HD_REC709, coded_size, visible_rect, natural_size, | 404 COLOR_SPACE_HD_REC709, coded_size, visible_rect, natural_size, |
368 // No decoder-specific buffer needed for AVC; | 405 // No decoder-specific buffer needed for AVC; |
369 // SPS/PPS are embedded in the video stream | 406 // SPS/PPS are embedded in the video stream |
370 EmptyExtraData(), | 407 EmptyExtraData(), |
371 is_video_track_encrypted_ ? AesCtrEncryptionScheme() : Unencrypted()); | 408 is_video_track_encrypted_ ? GetEncryptionScheme(entry.sinf) |
409 : Unencrypted()); | |
372 has_video_ = true; | 410 has_video_ = true; |
373 video_track_id_ = track->header.track_id; | 411 video_track_id_ = track->header.track_id; |
374 media_tracks->AddVideoTrack( | 412 media_tracks->AddVideoTrack( |
375 video_config, base::UintToString(video_track_id_), "main", | 413 video_config, base::UintToString(video_track_id_), "main", |
376 track->media.handler.name, track->media.header.language()); | 414 track->media.handler.name, track->media.header.language()); |
377 continue; | 415 continue; |
378 } | 416 } |
379 | 417 |
380 // TODO(wolenetz): Investigate support in MSE and Chrome MSE for CEA 608/708 | 418 // TODO(wolenetz): Investigate support in MSE and Chrome MSE for CEA 608/708 |
381 // embedded caption data in video track. At time of init segment parsing, we | 419 // embedded caption data in video track. At time of init segment parsing, we |
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
567 !PrepareAACBuffer(runs_->audio_description().esds.aac, | 605 !PrepareAACBuffer(runs_->audio_description().esds.aac, |
568 &frame_buf, &subsamples)) { | 606 &frame_buf, &subsamples)) { |
569 MEDIA_LOG(ERROR, media_log_) << "Failed to prepare AAC sample for decode"; | 607 MEDIA_LOG(ERROR, media_log_) << "Failed to prepare AAC sample for decode"; |
570 *err = true; | 608 *err = true; |
571 return false; | 609 return false; |
572 } | 610 } |
573 } | 611 } |
574 | 612 |
575 if (decrypt_config) { | 613 if (decrypt_config) { |
576 if (!subsamples.empty()) { | 614 if (!subsamples.empty()) { |
577 // Create a new config with the updated subsamples. | 615 // Create a new config with the updated subsamples. |
578 decrypt_config.reset(new DecryptConfig( | 616 decrypt_config.reset(new DecryptConfig(decrypt_config->key_id(), |
579 decrypt_config->key_id(), | 617 decrypt_config->iv(), subsamples)); |
580 decrypt_config->iv(), | |
581 subsamples)); | |
582 } | 618 } |
583 // else, use the existing config. | 619 // else, use the existing config. |
584 } else if ((audio && is_audio_track_encrypted_) || | 620 } else if ((audio && is_audio_track_encrypted_) || |
585 (video && is_video_track_encrypted_)) { | 621 (video && is_video_track_encrypted_)) { |
586 // The media pipeline requires a DecryptConfig with an empty |iv|. | 622 // The media pipeline requires a DecryptConfig with an empty |iv|. |
587 // TODO(ddorwin): Refactor so we do not need a fake key ID ("1"); | 623 // TODO(ddorwin): Refactor so we do not need a fake key ID ("1"); |
588 decrypt_config.reset( | 624 decrypt_config.reset( |
589 new DecryptConfig("1", "", std::vector<SubsampleEntry>())); | 625 new DecryptConfig("1", "", std::vector<SubsampleEntry>())); |
590 } | 626 } |
591 | 627 |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
698 runs.AdvanceSample(); | 734 runs.AdvanceSample(); |
699 } | 735 } |
700 runs.AdvanceRun(); | 736 runs.AdvanceRun(); |
701 } | 737 } |
702 | 738 |
703 return true; | 739 return true; |
704 } | 740 } |
705 | 741 |
706 } // namespace mp4 | 742 } // namespace mp4 |
707 } // namespace media | 743 } // namespace media |
OLD | NEW |