Chromium Code Reviews| Index: media/formats/mp4/mp4_stream_parser.cc |
| diff --git a/media/formats/mp4/mp4_stream_parser.cc b/media/formats/mp4/mp4_stream_parser.cc |
| index 8e8ec08b3898ab20bd27f4fc79110cbc44d1cd5f..a9f27d7a79823cea65bf3deb830a3968eb177fd7 100644 |
| --- a/media/formats/mp4/mp4_stream_parser.cc |
| +++ b/media/formats/mp4/mp4_stream_parser.cc |
| @@ -17,6 +17,7 @@ |
| #include "base/time/time.h" |
| #include "build/build_config.h" |
| #include "media/base/audio_decoder_config.h" |
| +#include "media/base/encryption_scheme.h" |
| #include "media/base/media_tracks.h" |
| #include "media/base/media_util.h" |
| #include "media/base/stream_parser_buffer.h" |
| @@ -35,6 +36,39 @@ namespace mp4 { |
| namespace { |
| const int kMaxEmptySampleLogs = 20; |
| + |
| +// Caller should be prepared to handle return of Unencrypted() in case of |
| +// unsupported scheme. |
| +EncryptionScheme GetEncryptionScheme(const ProtectionSchemeInfo& sinf) { |
| + if (!sinf.HasSupportedScheme()) |
| + return Unencrypted(); |
| + FourCC fourCC = sinf.type.type; |
|
kqyang
2016/10/12 22:16:52
s/fourCC/fourcc/
variable name should not be capi
dougsteed
2016/10/14 21:24:35
Done.
|
| + EncryptionScheme::CipherMode mode = EncryptionScheme::CIPHER_MODE_UNENCRYPTED; |
| + EncryptionScheme::Pattern pattern; |
| + bool uses_pattern_encryption = false; |
| + switch (fourCC) { |
| + case FOURCC_CENC: |
| + mode = EncryptionScheme::CIPHER_MODE_AES_CTR; |
| + break; |
| +#if BUILDFLAG(ENABLE_CBCS_ENCRYPTION_SCHEME) |
| + case FOURCC_CBCS: |
| + mode = EncryptionScheme::CIPHER_MODE_AES_CBC; |
| + uses_pattern_encryption = true; |
| + break; |
| +#endif |
| + default: |
| + NOTREACHED(); |
| + break; |
| + } |
| +#if BUILDFLAG(ENABLE_CBCS_ENCRYPTION_SCHEME) |
| + if (uses_pattern_encryption) { |
| + uint8_t crypt = sinf.info.track_encryption.default_crypt_byte_block; |
| + uint8_t skip = sinf.info.track_encryption.default_skip_byte_block; |
| + pattern = EncryptionScheme::Pattern(crypt, skip); |
| + } |
| +#endif |
| + return EncryptionScheme(mode, pattern); |
| +} |
| } // namespace |
| MP4StreamParser::MP4StreamParser(const std::set<int>& audio_object_types, |
| @@ -317,10 +351,15 @@ bool MP4StreamParser::ParseMoov(BoxReader* reader) { |
| } |
| bool is_track_encrypted = entry.sinf.info.track_encryption.is_encrypted; |
| is_track_encrypted_[audio_track_id] = is_track_encrypted; |
| - audio_config.Initialize( |
| - codec, sample_format, channel_layout, sample_per_second, extra_data, |
| - is_track_encrypted ? AesCtrEncryptionScheme() : Unencrypted(), |
| - base::TimeDelta(), 0); |
| + EncryptionScheme scheme = Unencrypted(); |
| + if (is_track_encrypted) { |
| + scheme = GetEncryptionScheme(entry.sinf); |
| + if (!scheme.is_encrypted()) |
| + return false; |
| + } |
| + audio_config.Initialize(codec, sample_format, channel_layout, |
| + sample_per_second, extra_data, scheme, |
|
kqyang
2016/10/12 22:16:52
I don't think it is a good idea to pass encryption
dougsteed
2016/10/14 21:24:35
Let's discuss further. I'm not sure I agree that s
|
| + base::TimeDelta(), 0); |
| DVLOG(1) << "audio_track_id=" << audio_track_id |
| << " config=" << audio_config.AsHumanReadableString(); |
| if (!audio_config.IsValidConfig()) { |
| @@ -378,13 +417,18 @@ bool MP4StreamParser::ParseMoov(BoxReader* reader) { |
| } |
| bool is_track_encrypted = entry.sinf.info.track_encryption.is_encrypted; |
| is_track_encrypted_[video_track_id] = is_track_encrypted; |
| - video_config.Initialize( |
| - entry.video_codec, entry.video_codec_profile, PIXEL_FORMAT_YV12, |
| - COLOR_SPACE_HD_REC709, coded_size, visible_rect, natural_size, |
| - // No decoder-specific buffer needed for AVC; |
| - // SPS/PPS are embedded in the video stream |
| - EmptyExtraData(), |
| - is_track_encrypted ? AesCtrEncryptionScheme() : Unencrypted()); |
| + EncryptionScheme scheme = Unencrypted(); |
| + if (is_track_encrypted) { |
| + scheme = GetEncryptionScheme(entry.sinf); |
| + if (!scheme.is_encrypted()) |
| + return false; |
| + } |
| + video_config.Initialize(entry.video_codec, entry.video_codec_profile, |
| + PIXEL_FORMAT_YV12, COLOR_SPACE_HD_REC709, |
| + coded_size, visible_rect, natural_size, |
| + // No decoder-specific buffer needed for AVC; |
| + // SPS/PPS are embedded in the video stream |
| + EmptyExtraData(), scheme); |
| DVLOG(1) << "video_track_id=" << video_track_id |
| << " config=" << video_config.AsHumanReadableString(); |
| if (!video_config.IsValidConfig()) { |
| @@ -622,11 +666,9 @@ bool MP4StreamParser::EnqueueSample(BufferQueueMap* buffers, bool* err) { |
| if (decrypt_config) { |
| if (!subsamples.empty()) { |
| - // Create a new config with the updated subsamples. |
| - decrypt_config.reset(new DecryptConfig( |
| - decrypt_config->key_id(), |
| - decrypt_config->iv(), |
| - subsamples)); |
| + // Create a new config with the updated subsamples. |
| + decrypt_config.reset(new DecryptConfig(decrypt_config->key_id(), |
| + decrypt_config->iv(), subsamples)); |
| } |
| // else, use the existing config. |
| } else if (is_track_encrypted_[runs_->track_id()]) { |