From d08f6ae0cce0b36b9ed3b91b6752e8d448b796af Mon Sep 17 00:00:00 2001 From: Kongqun Yang Date: Thu, 26 May 2016 15:44:37 -0700 Subject: [PATCH] Fix cbcs/cens behavior when applied to non video tracks - Tracks other than video are protected using whole-block full-sample encryption as specified in ISO/IEC 23001-7:2016(E) 9.7, which is equivalent to a pattern of 1:0. This is different to the non pattern encryption counterparts. - Also updated the code to allow the existence of other protection schemes in the original content, which will simply be ignored. - The internal cryptor used by AesPatternCryptor should not use constant iv, add a DCHECK for that. - Optimize AesPatternCryptor handling on the special pattern 1:0. Change-Id: Idc704e7bc6b347741336f38c6d3620fc19392960 --- packager/app/test/packager_test.py | 4 +- .../testdata/bear-640x360-a-cbcs-golden.mp4 | Bin 0 -> 43935 bytes .../testdata/bear-640x360-a-cens-golden.mp4 | Bin 0 -> 44600 bytes .../testdata/bear-640x360-av-cbcs-golden.mpd | 8 +- .../testdata/bear-640x360-av-cens-golden.mpd | 2 +- packager/app/widevine_encryption_flags.cc | 6 +- packager/media/base/aes_cryptor.h | 3 + packager/media/base/aes_pattern_cryptor.cc | 17 ++++ packager/media/base/aes_pattern_cryptor.h | 3 +- .../base/aes_pattern_cryptor_unittest.cc | 30 ++++++ packager/media/formats/mp4/box_definitions.cc | 49 ++++++--- .../formats/mp4/encrypting_fragmenter.cc | 17 +++- packager/media/formats/mp4/segmenter.cc | 96 ++++++++++-------- 13 files changed, 163 insertions(+), 72 deletions(-) create mode 100644 packager/app/test/testdata/bear-640x360-a-cbcs-golden.mp4 create mode 100644 packager/app/test/testdata/bear-640x360-a-cens-golden.mp4 diff --git a/packager/app/test/packager_test.py b/packager/app/test/packager_test.py index 08e4754c90..1f1cae2546 100755 --- a/packager/app/test/packager_test.py +++ b/packager/app/test/packager_test.py @@ -171,7 +171,7 @@ class PackagerAppTest(unittest.TestCase): self._GetStreams(['audio', 'video']), self._GetFlags(encryption=True, protection_scheme='cens')) - self._DiffGold(self.output[0], 'bear-640x360-a-cenc-golden.mp4') + self._DiffGold(self.output[0], 'bear-640x360-a-cens-golden.mp4') self._DiffGold(self.output[1], 'bear-640x360-v-cens-golden.mp4') self._DiffGold(self.mpd_output, 'bear-640x360-av-cens-golden.mpd') self._VerifyDecryption(self.output[0], 'bear-640x360-a-golden.mp4') @@ -182,7 +182,7 @@ class PackagerAppTest(unittest.TestCase): self._GetStreams(['audio', 'video']), self._GetFlags(encryption=True, protection_scheme='cbcs')) - self._DiffGold(self.output[0], 'bear-640x360-a-cbc1-golden.mp4') + self._DiffGold(self.output[0], 'bear-640x360-a-cbcs-golden.mp4') self._DiffGold(self.output[1], 'bear-640x360-v-cbcs-golden.mp4') self._DiffGold(self.mpd_output, 'bear-640x360-av-cbcs-golden.mpd') self._VerifyDecryption(self.output[0], 'bear-640x360-a-golden.mp4') diff --git a/packager/app/test/testdata/bear-640x360-a-cbcs-golden.mp4 b/packager/app/test/testdata/bear-640x360-a-cbcs-golden.mp4 new file mode 100644 index 0000000000000000000000000000000000000000..313271ea5800be682d8139eb84fee77a452a83f5 GIT binary patch literal 43935 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

MOQ{uJ*vcS9V@G_Nj}L>OOMB^IV)i2HdQ1rah1W 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 literal 0 HcmV?d00001 diff --git a/packager/app/test/testdata/bear-640x360-a-cens-golden.mp4 b/packager/app/test/testdata/bear-640x360-a-cens-golden.mp4 new file mode 100644 index 0000000000000000000000000000000000000000..fe06b5ac9d8be9b6b46157bb79ec38f7a9744663 GIT binary patch literal 44600 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 output_audio.mp4 - - + + diff --git a/packager/app/test/testdata/bear-640x360-av-cens-golden.mpd b/packager/app/test/testdata/bear-640x360-av-cens-golden.mpd index 627ef222cb..cbd0e46067 100644 --- a/packager/app/test/testdata/bear-640x360-av-cens-golden.mpd +++ b/packager/app/test/testdata/bear-640x360-av-cens-golden.mpd @@ -17,7 +17,7 @@ - + AAAAMHBzc2gAAAAA7e+LqXnWSs6jyCfc1R0h7QAAABAxMjM0NTY3ODkwMTIzNDU2 diff --git a/packager/app/widevine_encryption_flags.cc b/packager/app/widevine_encryption_flags.cc index 7c34a62baf..09ef9f0955 100644 --- a/packager/app/widevine_encryption_flags.cc +++ b/packager/app/widevine_encryption_flags.cc @@ -58,11 +58,7 @@ DEFINE_int32(crypto_period_duration, DEFINE_string(protection_scheme, "cenc", "Choose protection scheme, 'cenc' or 'cbc1' or pattern-based " - "protection schemes 'cens' or 'cbcs'. Note that if a " - "pattern-based protection scheme only applies to video stream; " - "audio stream will be encrypted using the corresponding " - "non-pattern-based protection schemes, i.e. 'cenc' for 'cens', " - "'cbc1' for 'cbcs'."); + "protection schemes 'cens' or 'cbcs'."); namespace shaka { diff --git a/packager/media/base/aes_cryptor.h b/packager/media/base/aes_cryptor.h index 2c4997f232..1ca85c1369 100644 --- a/packager/media/base/aes_cryptor.h +++ b/packager/media/base/aes_cryptor.h @@ -80,6 +80,9 @@ class AesCryptor { /// @return The current iv. const std::vector& iv() const { return iv_; } + /// @return true if constant iv is used, false otherwise. + bool use_constant_iv() const { return constant_iv_flag_ == kUseConstantIv; } + /// @param protection_scheme specifies the protection scheme: 'cenc', 'cens', /// 'cbc1', 'cbcs', which is useful to determine the random iv size. /// @param iv points to generated initialization vector. diff --git a/packager/media/base/aes_pattern_cryptor.cc b/packager/media/base/aes_pattern_cryptor.cc index 8de98ede90..55a3be6b81 100644 --- a/packager/media/base/aes_pattern_cryptor.cc +++ b/packager/media/base/aes_pattern_cryptor.cc @@ -23,7 +23,13 @@ AesPatternCryptor::AesPatternCryptor(uint8_t crypt_byte_block, skip_byte_block_(skip_byte_block), encryption_mode_(encryption_mode), cryptor_(cryptor.Pass()) { + // |crypt_byte_block_| should never be 0. |skip_byte_block_| can be 0 to allow + // a special pattern of 1:0, which is the pattern for the case of pattern + // encryption when applied to non video tracks. + DCHECK_NE(crypt_byte_block_, 0u); + DCHECK(skip_byte_block_ != 0 || crypt_byte_block_ == 1); DCHECK(cryptor_); + DCHECK(!cryptor_->use_constant_iv()); } AesPatternCryptor::~AesPatternCryptor() {} @@ -45,6 +51,17 @@ bool AesPatternCryptor::CryptInternal(const uint8_t* text, } *crypt_text_size = text_size; + // Handle the special pattern 1:0. + if (skip_byte_block_ == 0) { + DCHECK_EQ(crypt_byte_block_, 1u); + const size_t crypt_byte_size = text_size / AES_BLOCK_SIZE * AES_BLOCK_SIZE; + if (!cryptor_->Crypt(text, crypt_byte_size, crypt_text)) + return false; + memcpy(crypt_text + crypt_byte_size, text + crypt_byte_size, + text_size - crypt_byte_size); + return true; + } + while (text_size > 0) { const size_t crypt_byte_size = crypt_byte_block_ * AES_BLOCK_SIZE; if (NeedEncrypt(text_size, crypt_byte_size)) { diff --git a/packager/media/base/aes_pattern_cryptor.h b/packager/media/base/aes_pattern_cryptor.h index 7c4d364a38..ba351304a6 100644 --- a/packager/media/base/aes_pattern_cryptor.h +++ b/packager/media/base/aes_pattern_cryptor.h @@ -47,7 +47,8 @@ class AesPatternCryptor : public AesCryptor { /// internally inside Crypt call, i.e. iv will be updated across Crypt /// calls. /// @param cryptor points to an AesCryptor instance which performs the actual - /// encryption/decryption. + /// encryption/decryption. Note that @a cryptor shall not use constant + /// iv. AesPatternCryptor(uint8_t crypt_byte_block, uint8_t skip_byte_block, PatternEncryptionMode encryption_mode, diff --git a/packager/media/base/aes_pattern_cryptor_unittest.cc b/packager/media/base/aes_pattern_cryptor_unittest.cc index dc6dbfb423..f7f311be04 100644 --- a/packager/media/base/aes_pattern_cryptor_unittest.cc +++ b/packager/media/base/aes_pattern_cryptor_unittest.cc @@ -219,5 +219,35 @@ TEST(SampleAesPatternCryptor, MoreThan16Bytes) { ASSERT_TRUE(pattern_cryptor.Crypt("0123456789abcdef012", &crypt_text)); } +TEST(FullSampleSpecialPatternTest, Test) { + MockAesCryptor* mock_cryptor = new MockAesCryptor(); + EXPECT_CALL(*mock_cryptor, CryptInternal(_, 96u, _, _)) + .WillOnce(Invoke([](const uint8_t* text, size_t text_size, + uint8_t* crypt_text, size_t* crypt_text_size) { + *crypt_text_size = text_size; + for (size_t i = 0; i < text_size; ++i) + *crypt_text++ = 'e'; + return true; + })); + + const uint8_t kFulLSampleCryptBlock = 1; + const uint8_t kFullSampleSkipBlock = 0; + AesPatternCryptor pattern_cryptor( + kFulLSampleCryptBlock, kFullSampleSkipBlock, + AesPatternCryptor::kSkipIfCryptByteBlockRemaining, + AesPatternCryptor::kUseConstantIv, + scoped_ptr(mock_cryptor)); + + std::vector iv(8, 'i'); + // SetIv will be called only once by AesPatternCryptor::SetIv. + EXPECT_TRUE(pattern_cryptor.SetIv(iv)); + + std::string input_text(100, 'c'); + std::string crypt_text; + // More than 16 bytes so mock's CryptInternal should be called. + ASSERT_TRUE(pattern_cryptor.Crypt(input_text, &crypt_text)); + EXPECT_EQ(std::string(96, 'e') + std::string(4, 'c'), crypt_text); +} + } // namespace media } // namespace shaka diff --git a/packager/media/formats/mp4/box_definitions.cc b/packager/media/formats/mp4/box_definitions.cc index 253820c922..55b45cc226 100644 --- a/packager/media/formats/mp4/box_definitions.cc +++ b/packager/media/formats/mp4/box_definitions.cc @@ -126,6 +126,11 @@ FourCC TrackTypeToFourCC(TrackType track_type) { } } +bool IsProtectionSchemeSupported(FourCC scheme) { + return scheme == FOURCC_cenc || scheme == FOURCC_cens || + scheme == FOURCC_cbc1 || scheme == FOURCC_cbcs; +} + } // namespace FileType::FileType() : major_brand(FOURCC_NULL), minor_version(0) {} @@ -483,9 +488,12 @@ bool ProtectionSchemeInfo::ReadWriteInternal(BoxBuffer* buffer) { buffer->PrepareChildren() && buffer->ReadWriteChild(&format) && buffer->ReadWriteChild(&type)); - RCHECK(type.type == FOURCC_cenc || type.type == FOURCC_cbc1 || - type.type == FOURCC_cens || type.type == FOURCC_cbcs); - RCHECK(buffer->ReadWriteChild(&info)); + if (IsProtectionSchemeSupported(type.type)) { + RCHECK(buffer->ReadWriteChild(&info)); + } else { + DLOG(WARNING) << "Ignore unsupported protection scheme: " + << FourCCToString(type.type); + } // Other protection schemes are silently ignored. Since the protection scheme // type can't be determined until this box is opened, we return 'true' for // non-CENC protection scheme types. It is the parent box's responsibility to @@ -1001,8 +1009,8 @@ bool SampleGroupDescription::ReadWriteInternal(BoxBuffer* buffer) { return ReadWriteEntries(buffer, &audio_roll_recovery_entries); default: DCHECK(buffer->Reading()); - DLOG(WARNING) << "Sample group '" << grouping_type - << "' is not supported."; + DLOG(WARNING) << "Ignore unsupported sample group: " + << FourCCToString(static_cast(grouping_type)); return true; } } @@ -1077,9 +1085,8 @@ bool SampleToGroup::ReadWriteInternal(BoxBuffer* buffer) { if (grouping_type != FOURCC_seig && grouping_type != FOURCC_roll) { DCHECK(buffer->Reading()); - DLOG(WARNING) << "Sample group " - << FourCCToString(static_cast(grouping_type)) - << " is not supported."; + DLOG(WARNING) << "Ignore unsupported sample group: " + << FourCCToString(static_cast(grouping_type)); return true; } @@ -1538,8 +1545,17 @@ bool VideoSampleEntry::ReadWriteInternal(BoxBuffer* buffer) { RCHECK(buffer->PrepareChildren()); - if (format == FOURCC_encv) - RCHECK(buffer->ReadWriteChild(&sinf)); + if (format == FOURCC_encv) { + if (buffer->Reading()) { + // Continue scanning until a supported protection scheme is found, or + // until we run out of protection schemes. + while (!IsProtectionSchemeSupported(sinf.type.type)) + RCHECK(buffer->ReadWriteChild(&sinf)); + } else { + DCHECK(IsProtectionSchemeSupported(sinf.type.type)); + RCHECK(buffer->ReadWriteChild(&sinf)); + } + } const FourCC actual_format = GetActualFormat(); if (buffer->Reading()) { @@ -1777,8 +1793,17 @@ bool AudioSampleEntry::ReadWriteInternal(BoxBuffer* buffer) { samplerate >>= 16; RCHECK(buffer->PrepareChildren()); - if (format == FOURCC_enca) - RCHECK(buffer->ReadWriteChild(&sinf)); + if (format == FOURCC_enca) { + if (buffer->Reading()) { + // Continue scanning until a supported protection scheme is found, or + // until we run out of protection schemes. + while (!IsProtectionSchemeSupported(sinf.type.type)) + RCHECK(buffer->ReadWriteChild(&sinf)); + } else { + DCHECK(IsProtectionSchemeSupported(sinf.type.type)); + RCHECK(buffer->ReadWriteChild(&sinf)); + } + } RCHECK(buffer->TryReadWriteChild(&esds)); RCHECK(buffer->TryReadWriteChild(&ddts)); diff --git a/packager/media/formats/mp4/encrypting_fragmenter.cc b/packager/media/formats/mp4/encrypting_fragmenter.cc index 8e69aac10c..d54dcced06 100644 --- a/packager/media/formats/mp4/encrypting_fragmenter.cc +++ b/packager/media/formats/mp4/encrypting_fragmenter.cc @@ -186,9 +186,18 @@ void EncryptingFragmenter::FinalizeFragmentForEncryption() { DCHECK(!IsSubsampleEncryptionRequired()); saiz.default_sample_info_size = per_sample_iv_size; } - // It should only happen with full sample encryption + constant iv, which is - // not a legal combination. - CHECK(!saiz.sample_info_sizes.empty() || saiz.default_sample_info_size != 0); + + // It should only happen with full sample encryption + constant iv, i.e. + // 'cbcs' applying to audio. + if (saiz.default_sample_info_size == 0 && saiz.sample_info_sizes.empty()) { + DCHECK_EQ(protection_scheme_, FOURCC_cbcs); + DCHECK(!IsSubsampleEncryptionRequired()); + // ISO/IEC 23001-7:2016(E) The sample auxiliary information would then be + // empty and should be emitted. Clear saiz and saio boxes so they are not + // written. + saiz.sample_count = 0; + traf()->auxiliary_offset.offsets.clear(); + } } Status EncryptingFragmenter::CreateEncryptor() { @@ -337,6 +346,8 @@ Status EncryptingFragmenter::EncryptSample(scoped_refptr sample) { traf()->auxiliary_size.sample_info_sizes.push_back( sample_encryption_entry.ComputeSize()); } else { + DCHECK_LE(crypt_byte_block(), 1u); + DCHECK_EQ(skip_byte_block(), 0u); EncryptBytes(data, sample->data_size()); } diff --git a/packager/media/formats/mp4/segmenter.cc b/packager/media/formats/mp4/segmenter.cc index fbb7a32516..5b35794e00 100644 --- a/packager/media/formats/mp4/segmenter.cc +++ b/packager/media/formats/mp4/segmenter.cc @@ -28,10 +28,6 @@ namespace media { namespace mp4 { namespace { -// For pattern-based encryption. -const uint8_t kCryptByteBlock = 1u; -const uint8_t kSkipByteBlock = 9u; - const size_t kCencKeyIdSize = 16u; // The version of cenc implemented here. CENC 4. @@ -43,6 +39,12 @@ const uint8_t kKeyRotationDefaultKeyId[] = { 0, 0, 0, 0, 0, 0, 0, 0 }; +// Defines protection pattern for pattern-based encryption. +struct ProtectionPattern { + uint8_t crypt_byte_block; + uint8_t skip_byte_block; +}; + COMPILE_ASSERT(arraysize(kKeyRotationDefaultKeyId) == kCencKeyIdSize, cenc_key_id_must_be_size_16); @@ -52,21 +54,37 @@ uint64_t Rescale(uint64_t time_in_old_scale, return static_cast(time_in_old_scale) / old_scale * new_scale; } -uint8_t GetCryptByteBlock(FourCC protection_scheme) { - return (protection_scheme == FOURCC_cbcs || protection_scheme == FOURCC_cens) - ? kCryptByteBlock - : 0; -} - -uint8_t GetSkipByteBlock(FourCC protection_scheme) { - return (protection_scheme == FOURCC_cbcs || protection_scheme == FOURCC_cens) - ? kSkipByteBlock - : 0; +ProtectionPattern GetProtectionPattern(FourCC protection_scheme, + TrackType track_type) { + ProtectionPattern pattern; + if (protection_scheme != FOURCC_cbcs && protection_scheme != FOURCC_cens) { + // Not using pattern encryption. + pattern.crypt_byte_block = 0u; + pattern.skip_byte_block = 0u; + } else if (track_type != kVideo) { + // Tracks other than video are protected using whole-block full-sample + // encryption, which is essentially a pattern of 1:0. Note that this may not + // be the same as the non-pattern based encryption counterparts, e.g. in + // 'cens' for full sample encryption, the whole sample is encrypted up to + // the last 16-byte boundary, see 23001-7:2016(E) 9.7; while in 'cenc' for + // full sample encryption, the last partial 16-byte block is also encrypted, + // see 23001-7:2016(E) 9.4.2. Another difference is the use of constant iv. + pattern.crypt_byte_block = 1u; + pattern.skip_byte_block = 0u; + } else { + // Use 1:9 pattern for video. + const uint8_t kCryptByteBlock = 1u; + const uint8_t kSkipByteBlock = 9u; + pattern.crypt_byte_block = kCryptByteBlock; + pattern.skip_byte_block = kSkipByteBlock; + } + return pattern; } void GenerateSinf(const EncryptionKey& encryption_key, FourCC old_type, FourCC protection_scheme, + ProtectionPattern pattern, ProtectionSchemeInfo* sinf) { sinf->format.format = old_type; @@ -85,16 +103,15 @@ void GenerateSinf(const EncryptionKey& encryption_key, } else { track_encryption.default_per_sample_iv_size = encryption_key.iv.size(); } - track_encryption.default_crypt_byte_block = - GetCryptByteBlock(protection_scheme); - track_encryption.default_skip_byte_block = - GetSkipByteBlock(protection_scheme); + track_encryption.default_crypt_byte_block = pattern.crypt_byte_block; + track_encryption.default_skip_byte_block = pattern.skip_byte_block; track_encryption.default_kid = encryption_key.key_id; } void GenerateEncryptedSampleEntry(const EncryptionKey& encryption_key, double clear_lead_in_seconds, FourCC protection_scheme, + ProtectionPattern pattern, SampleDescription* description) { DCHECK(description); if (description->type == kVideo) { @@ -106,7 +123,8 @@ void GenerateEncryptedSampleEntry(const EncryptionKey& encryption_key, // Convert the first entry to an encrypted entry. VideoSampleEntry& entry = description->video_entries[0]; - GenerateSinf(encryption_key, entry.format, protection_scheme, &entry.sinf); + GenerateSinf(encryption_key, entry.format, protection_scheme, pattern, + &entry.sinf); entry.format = FOURCC_encv; } else { DCHECK_EQ(kAudio, description->type); @@ -118,7 +136,8 @@ void GenerateEncryptedSampleEntry(const EncryptionKey& encryption_key, // Convert the first entry to an encrypted entry. AudioSampleEntry& entry = description->audio_entries[0]; - GenerateSinf(encryption_key, entry.format, protection_scheme, &entry.sinf); + GenerateSinf(encryption_key, entry.format, protection_scheme, pattern, + &entry.sinf); entry.format = FOURCC_enca; } } @@ -174,20 +193,12 @@ Status Segmenter::Initialize(const std::vector& streams, continue; } - FourCC local_protection_scheme = protection_scheme; - if (streams[i]->info()->stream_type() != kStreamVideo) { - // Pattern encryption should only be used with video. Replaces with the - // corresponding non-pattern encryption scheme. - if (protection_scheme == FOURCC_cbcs) - local_protection_scheme = FOURCC_cbc1; - else if (protection_scheme == FOURCC_cens) - local_protection_scheme = FOURCC_cenc; - } - KeySource::TrackType track_type = GetTrackTypeForEncryption(*streams[i]->info(), max_sd_pixels); SampleDescription& description = moov_->tracks[i].media.information.sample_table.description; + ProtectionPattern pattern = + GetProtectionPattern(protection_scheme, description.type); if (key_rotation_enabled) { // Fill encrypted sample entry with default key. @@ -195,17 +206,16 @@ Status Segmenter::Initialize(const std::vector& streams, encryption_key.key_id.assign( kKeyRotationDefaultKeyId, kKeyRotationDefaultKeyId + arraysize(kKeyRotationDefaultKeyId)); - if (!AesCryptor::GenerateRandomIv(local_protection_scheme, + if (!AesCryptor::GenerateRandomIv(protection_scheme, &encryption_key.iv)) { return Status(error::INTERNAL_ERROR, "Failed to generate random iv."); } GenerateEncryptedSampleEntry(encryption_key, clear_lead_in_seconds, - local_protection_scheme, &description); + protection_scheme, pattern, &description); if (muxer_listener_) { muxer_listener_->OnEncryptionInfoReady( - kInitialEncryptionInfo, local_protection_scheme, - encryption_key.key_id, encryption_key.iv, - encryption_key.key_system_info); + kInitialEncryptionInfo, protection_scheme, encryption_key.key_id, + encryption_key.iv, encryption_key.key_system_info); } fragmenters_[i] = new KeyRotationFragmenter( @@ -213,8 +223,8 @@ Status Segmenter::Initialize(const std::vector& streams, encryption_key_source, track_type, crypto_period_duration_in_seconds * streams[i]->info()->time_scale(), clear_lead_in_seconds * streams[i]->info()->time_scale(), - local_protection_scheme, GetCryptByteBlock(local_protection_scheme), - GetSkipByteBlock(local_protection_scheme), muxer_listener_); + protection_scheme, pattern.crypt_byte_block, pattern.skip_byte_block, + muxer_listener_); continue; } @@ -224,14 +234,14 @@ Status Segmenter::Initialize(const std::vector& streams, if (!status.ok()) return status; if (encryption_key->iv.empty()) { - if (!AesCryptor::GenerateRandomIv(local_protection_scheme, + if (!AesCryptor::GenerateRandomIv(protection_scheme, &encryption_key->iv)) { return Status(error::INTERNAL_ERROR, "Failed to generate random iv."); } } GenerateEncryptedSampleEntry(*encryption_key, clear_lead_in_seconds, - local_protection_scheme, &description); + protection_scheme, pattern, &description); if (moov_->pssh.empty()) { moov_->pssh.resize(encryption_key->key_system_info.size()); @@ -241,17 +251,15 @@ Status Segmenter::Initialize(const std::vector& streams, if (muxer_listener_) { muxer_listener_->OnEncryptionInfoReady( - kInitialEncryptionInfo, local_protection_scheme, - encryption_key->key_id, encryption_key->iv, - encryption_key->key_system_info); + kInitialEncryptionInfo, protection_scheme, encryption_key->key_id, + encryption_key->iv, encryption_key->key_system_info); } } fragmenters_[i] = new EncryptingFragmenter( streams[i]->info(), &moof_->tracks[i], encryption_key.Pass(), clear_lead_in_seconds * streams[i]->info()->time_scale(), - local_protection_scheme, GetCryptByteBlock(local_protection_scheme), - GetSkipByteBlock(local_protection_scheme)); + protection_scheme, pattern.crypt_byte_block, pattern.skip_byte_block); } // Choose the first stream if there is no VIDEO.