| Index: media/formats/mp4/track_run_iterator_unittest.cc
|
| diff --git a/media/formats/mp4/track_run_iterator_unittest.cc b/media/formats/mp4/track_run_iterator_unittest.cc
|
| index d1b3129d3f426b6e6f295df18f23f854a0d3adc1..7c2043bf3411807e8bf64098217869259ec607f1 100644
|
| --- a/media/formats/mp4/track_run_iterator_unittest.cc
|
| +++ b/media/formats/mp4/track_run_iterator_unittest.cc
|
| @@ -97,6 +97,48 @@ const uint8_t kFragmentCencSampleGroupKeyId[] = {
|
| 0x74, 0x43, 0x65, 0x6e, 0x63, 0x53, 0x61, 0x6d,
|
| };
|
|
|
| +#if BUILDFLAG(ENABLE_CBCS_ENCRYPTION_SCHEME)
|
| +// Sample encryption data for two samples, using constant IV (defined by 'tenc'
|
| +// or sample group entry).
|
| +const uint8_t kSampleEncryptionDataWithSubsamplesAndConstantIv[] = {
|
| + // Sample count.
|
| + 0x00, 0x00, 0x00, 0x05,
|
| + // Sample 1: Subsample count.
|
| + 0x00, 0x01,
|
| + // Sample 1: Subsample 1.
|
| + 0x00, 0x01, 0x00, 0x00, 0x00, 0x02,
|
| + // Sample 2: Subsample count.
|
| + 0x00, 0x02,
|
| + // Sample 2: Subsample 1.
|
| + 0x00, 0x01, 0x00, 0x00, 0x00, 0x02,
|
| + // Sample 2: Subsample 2.
|
| + 0x00, 0x03, 0x00, 0x00, 0x00, 0x04,
|
| + // Sample 3: Subsample count.
|
| + 0x00, 0x01,
|
| + // Sample 3: Subsample 1.
|
| + 0x00, 0x01, 0x00, 0x00, 0x00, 0x02,
|
| + // Sample 4: Subsample count.
|
| + 0x00, 0x01,
|
| + // Sample 4: Subsample 1.
|
| + 0x00, 0x01, 0x00, 0x00, 0x00, 0x02,
|
| + // Sample 5: Subsample count.
|
| + 0x00, 0x01,
|
| + // Sample 5: Subsample 1.
|
| + 0x00, 0x01, 0x00, 0x00, 0x00, 0x02,
|
| +};
|
| +
|
| +// Size of these IVs are 16 bytes.
|
| +const char kIv4[] = {
|
| + 0x41, 0x54, 0x65, 0x73, 0x74, 0x49, 0x76, 0x34,
|
| + 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
|
| +};
|
| +
|
| +const char kIv5[] = {
|
| + 0x41, 0x54, 0x65, 0x73, 0x74, 0x49, 0x76, 0x35,
|
| + 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
|
| +};
|
| +#endif
|
| +
|
| } // namespace
|
|
|
| namespace media {
|
| @@ -258,8 +300,7 @@ class TrackRunIteratorTest : public testing::Test {
|
| return moof;
|
| }
|
|
|
| - // Update the first sample description of a Track to indicate encryption
|
| - void AddEncryption(Track* track) {
|
| + ProtectionSchemeInfo* GetProtectionSchemeInfoForTrack(Track* track) {
|
| SampleDescription* stsd =
|
| &track->media.information.sample_table.description;
|
| ProtectionSchemeInfo* sinf;
|
| @@ -268,7 +309,12 @@ class TrackRunIteratorTest : public testing::Test {
|
| } else {
|
| sinf = &stsd->audio_entries[0].sinf;
|
| }
|
| + return sinf;
|
| + }
|
|
|
| + // Update the first sample description of a Track to indicate CENC encryption
|
| + void AddEncryption(Track* track) {
|
| + ProtectionSchemeInfo* sinf = GetProtectionSchemeInfoForTrack(track);
|
| sinf->type.type = FOURCC_CENC;
|
| sinf->info.track_encryption.is_encrypted = true;
|
| sinf->info.track_encryption.default_iv_size = 8;
|
| @@ -354,6 +400,70 @@ class TrackRunIteratorTest : public testing::Test {
|
| }
|
| }
|
|
|
| +#if BUILDFLAG(ENABLE_CBCS_ENCRYPTION_SCHEME)
|
| + // Update the first sample description of a Track to indicate CBCS encryption
|
| + // with a constant IV and pattern.
|
| + void AddEncryptionCbcs(Track* track) {
|
| + ProtectionSchemeInfo* sinf = GetProtectionSchemeInfoForTrack(track);
|
| + sinf->type.type = FOURCC_CBCS;
|
| + sinf->info.track_encryption.is_encrypted = true;
|
| + sinf->info.track_encryption.default_iv_size = 0;
|
| + sinf->info.track_encryption.default_crypt_byte_block = 1;
|
| + sinf->info.track_encryption.default_skip_byte_block = 9;
|
| + sinf->info.track_encryption.default_constant_iv_size = 16;
|
| + memcpy(sinf->info.track_encryption.default_constant_iv, kIv3, 16);
|
| + sinf->info.track_encryption.default_kid.assign(kKeyId,
|
| + kKeyId + arraysize(kKeyId));
|
| + }
|
| +
|
| + void AddConstantIvsToCencSampleGroup(Track* track, TrackFragment* frag) {
|
| + auto& track_cenc_group =
|
| + track->media.information.sample_table.sample_group_description;
|
| + track_cenc_group.entries[0].iv_size = 0;
|
| + track_cenc_group.entries[0].crypt_byte_block = 1;
|
| + track_cenc_group.entries[0].skip_byte_block = 9;
|
| + track_cenc_group.entries[0].constant_iv_size = 16;
|
| + memcpy(track_cenc_group.entries[0].constant_iv, kIv4, 16);
|
| +
|
| + frag->sample_group_description.entries[1].iv_size = 0;
|
| + frag->sample_group_description.entries[1].crypt_byte_block = 1;
|
| + frag->sample_group_description.entries[1].skip_byte_block = 9;
|
| + frag->sample_group_description.entries[1].constant_iv_size = 16;
|
| + memcpy(frag->sample_group_description.entries[1].constant_iv, kIv5, 16);
|
| + frag->sample_group_description.entries[2].iv_size = 0;
|
| + frag->sample_group_description.entries[2].crypt_byte_block = 1;
|
| + frag->sample_group_description.entries[2].skip_byte_block = 9;
|
| + frag->sample_group_description.entries[2].constant_iv_size = 16;
|
| + memcpy(frag->sample_group_description.entries[2].constant_iv, kIv5, 16);
|
| + }
|
| +
|
| + void AddSampleEncryptionCbcs(TrackFragment* frag) {
|
| + frag->sample_encryption.use_subsample_encryption = true;
|
| + frag->sample_encryption.sample_encryption_data.assign(
|
| + kSampleEncryptionDataWithSubsamplesAndConstantIv,
|
| + kSampleEncryptionDataWithSubsamplesAndConstantIv +
|
| + arraysize(kSampleEncryptionDataWithSubsamplesAndConstantIv));
|
| +
|
| + // Update sample sizes and aux info header.
|
| + frag->runs.resize(1);
|
| + frag->runs[0].sample_count = 5;
|
| + frag->auxiliary_offset.offsets.push_back(0);
|
| + frag->auxiliary_size.sample_count = 5;
|
| + // Update sample sizes to match with subsample entries above.
|
| + frag->runs[0].sample_sizes[0] = 3;
|
| + frag->runs[0].sample_sizes[1] = 10;
|
| + frag->runs[0].sample_sizes[2] = 3;
|
| + frag->runs[0].sample_sizes[3] = 3;
|
| + frag->runs[0].sample_sizes[4] = 3;
|
| + // Set aux info header.
|
| + frag->auxiliary_size.sample_info_sizes.push_back(16);
|
| + frag->auxiliary_size.sample_info_sizes.push_back(30);
|
| + frag->auxiliary_size.sample_info_sizes.push_back(16);
|
| + frag->auxiliary_size.sample_info_sizes.push_back(16);
|
| + frag->auxiliary_size.sample_info_sizes.push_back(16);
|
| + }
|
| +#endif
|
| +
|
| bool InitMoofWithArbitraryAuxInfo(MovieFragment* moof) {
|
| // Add aux info header (equal sized aux info for every sample).
|
| for (uint32_t i = 0; i < moof->tracks.size(); ++i) {
|
| @@ -879,5 +989,97 @@ TEST_F(TrackRunIteratorTest, KeyFrameFlagCombinations) {
|
| EXPECT_EQ("2 K P P P K P", KeyframeAndRAPInfo(iter_.get()));
|
| }
|
|
|
| +#if BUILDFLAG(ENABLE_CBCS_ENCRYPTION_SCHEME)
|
| +TEST_F(TrackRunIteratorTest, DecryptConfigTestWithConstantIvNoAuxInfo) {
|
| + AddEncryptionCbcs(&moov_.tracks[1]);
|
| + iter_.reset(new TrackRunIterator(&moov_, media_log_));
|
| +
|
| + MovieFragment moof = CreateFragment();
|
| +
|
| + ASSERT_TRUE(iter_->Init(moof));
|
| +
|
| + // The run for track 2 will be the second.
|
| + iter_->AdvanceRun();
|
| + EXPECT_EQ(iter_->track_id(), 2u);
|
| + EXPECT_TRUE(iter_->is_encrypted());
|
| + ASSERT_FALSE(iter_->AuxInfoNeedsToBeCached());
|
| + EXPECT_EQ(iter_->sample_offset(), 200);
|
| + std::unique_ptr<DecryptConfig> config = iter_->GetDecryptConfig();
|
| + EXPECT_EQ(
|
| + std::string(reinterpret_cast<const char*>(kKeyId), arraysize(kKeyId)),
|
| + config->key_id());
|
| + EXPECT_EQ(std::string(reinterpret_cast<const char*>(kIv3), arraysize(kIv3)),
|
| + config->iv());
|
| + EXPECT_TRUE(config->subsamples().empty());
|
| + iter_->AdvanceSample();
|
| + config = iter_->GetDecryptConfig();
|
| + EXPECT_EQ(
|
| + std::string(reinterpret_cast<const char*>(kKeyId), arraysize(kKeyId)),
|
| + config->key_id());
|
| + EXPECT_EQ(std::string(reinterpret_cast<const char*>(kIv3), arraysize(kIv3)),
|
| + config->iv());
|
| + EXPECT_TRUE(config->subsamples().empty());
|
| +}
|
| +
|
| +TEST_F(TrackRunIteratorTest, DecryptConfigTestWithSampleGroupsAndConstantIv) {
|
| + // Add TrackEncryption Box.
|
| + AddEncryptionCbcs(&moov_.tracks[1]);
|
| +
|
| + MovieFragment moof = CreateFragment();
|
| + AddSampleEncryptionCbcs(&moof.tracks[1]);
|
| +
|
| + const SampleToGroupEntry kSampleToGroupTable[] = {
|
| + // Associated with the 2nd entry in fragment SampleGroupDescription Box.
|
| + {1, SampleToGroupEntry::kFragmentGroupDescriptionIndexBase + 2},
|
| + // Associated with the default values specified in TrackEncryption Box.
|
| + {1, 0},
|
| + // Associated with the 1st entry in fragment SampleGroupDescription Box.
|
| + {1, SampleToGroupEntry::kFragmentGroupDescriptionIndexBase + 1},
|
| + // Associated with the 1st entry in track SampleGroupDescription Box.
|
| + {1, 1}};
|
| + AddCencSampleGroup(&moov_.tracks[1], &moof.tracks[1], kSampleToGroupTable,
|
| + arraysize(kSampleToGroupTable));
|
| + AddConstantIvsToCencSampleGroup(&moov_.tracks[1], &moof.tracks[1]);
|
| + iter_.reset(new TrackRunIterator(&moov_, media_log_));
|
| + ASSERT_TRUE(iter_->Init(moof));
|
| +
|
| + // The run for track 2 will be the second.
|
| + iter_->AdvanceRun();
|
| +
|
| + std::string track_encryption_iv(kIv3, kIv3 + arraysize(kIv3));
|
| + std::string track_cenc_sample_group_iv(kIv4, kIv4 + arraysize(kIv4));
|
| + std::string fragment_cenc_sample_group_iv(kIv5, kIv5 + arraysize(kIv5));
|
| +
|
| + for (size_t i = 0; i < kSampleToGroupTable[0].sample_count; ++i) {
|
| + EXPECT_TRUE(iter_->is_encrypted());
|
| + EXPECT_EQ(fragment_cenc_sample_group_iv, iter_->GetDecryptConfig()->iv());
|
| + iter_->AdvanceSample();
|
| + }
|
| +
|
| + for (size_t i = 0; i < kSampleToGroupTable[1].sample_count; ++i) {
|
| + EXPECT_TRUE(iter_->is_encrypted());
|
| + EXPECT_EQ(track_encryption_iv, iter_->GetDecryptConfig()->iv());
|
| + iter_->AdvanceSample();
|
| + }
|
| +
|
| + for (size_t i = 0; i < kSampleToGroupTable[2].sample_count; ++i) {
|
| + EXPECT_FALSE(iter_->is_encrypted());
|
| + iter_->AdvanceSample();
|
| + }
|
| +
|
| + for (size_t i = 0; i < kSampleToGroupTable[3].sample_count; ++i) {
|
| + EXPECT_TRUE(iter_->is_encrypted());
|
| + EXPECT_EQ(track_cenc_sample_group_iv, iter_->GetDecryptConfig()->iv());
|
| + iter_->AdvanceSample();
|
| + }
|
| +
|
| + // The remaining samples should be associated with the default values
|
| + // specified in TrackEncryption Box.
|
| + EXPECT_TRUE(iter_->is_encrypted());
|
| + EXPECT_EQ(track_encryption_iv, iter_->GetDecryptConfig()->iv());
|
| +}
|
| +
|
| +#endif
|
| +
|
| } // namespace mp4
|
| } // namespace media
|
|
|