| 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..97d474579af8d8b6e1728d88e1ba890d49988b18 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,41 @@ 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;
|
| + EncryptionScheme::CipherMode mode = EncryptionScheme::CIPHER_MODE_UNENCRYPTED;
|
| + EncryptionScheme::Pattern pattern;
|
| +#if BUILDFLAG(ENABLE_CBCS_ENCRYPTION_SCHEME)
|
| + bool uses_pattern_encryption = false;
|
| +#endif
|
| + 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 +353,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,
|
| + base::TimeDelta(), 0);
|
| DVLOG(1) << "audio_track_id=" << audio_track_id
|
| << " config=" << audio_config.AsHumanReadableString();
|
| if (!audio_config.IsValidConfig()) {
|
| @@ -378,13 +419,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 +668,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()]) {
|
|
|