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/track_run_iterator.h" | 5 #include "media/formats/mp4/track_run_iterator.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 #include <stdint.h> | 8 #include <stdint.h> |
9 | 9 |
10 #include <memory> | 10 #include <memory> |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
90 const uint8_t kTrackCencSampleGroupKeyId[] = { | 90 const uint8_t kTrackCencSampleGroupKeyId[] = { |
91 0x46, 0x72, 0x61, 0x67, 0x53, 0x61, 0x6d, 0x70, | 91 0x46, 0x72, 0x61, 0x67, 0x53, 0x61, 0x6d, 0x70, |
92 0x6c, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x4b, | 92 0x6c, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x4b, |
93 }; | 93 }; |
94 | 94 |
95 const uint8_t kFragmentCencSampleGroupKeyId[] = { | 95 const uint8_t kFragmentCencSampleGroupKeyId[] = { |
96 0x6b, 0x46, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, | 96 0x6b, 0x46, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, |
97 0x74, 0x43, 0x65, 0x6e, 0x63, 0x53, 0x61, 0x6d, | 97 0x74, 0x43, 0x65, 0x6e, 0x63, 0x53, 0x61, 0x6d, |
98 }; | 98 }; |
99 | 99 |
| 100 #if BUILDFLAG(ENABLE_CBCS_ENCRYPTION_SCHEME) |
| 101 // Sample encryption data for two samples, using constant IV (defined by 'tenc' |
| 102 // or sample group entry). |
| 103 const uint8_t kSampleEncryptionDataWithSubsamplesAndConstantIv[] = { |
| 104 // Sample count. |
| 105 0x00, 0x00, 0x00, 0x05, |
| 106 // Sample 1: Subsample count. |
| 107 0x00, 0x01, |
| 108 // Sample 1: Subsample 1. |
| 109 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, |
| 110 // Sample 2: Subsample count. |
| 111 0x00, 0x02, |
| 112 // Sample 2: Subsample 1. |
| 113 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, |
| 114 // Sample 2: Subsample 2. |
| 115 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, |
| 116 // Sample 3: Subsample count. |
| 117 0x00, 0x01, |
| 118 // Sample 3: Subsample 1. |
| 119 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, |
| 120 // Sample 4: Subsample count. |
| 121 0x00, 0x01, |
| 122 // Sample 4: Subsample 1. |
| 123 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, |
| 124 // Sample 5: Subsample count. |
| 125 0x00, 0x01, |
| 126 // Sample 5: Subsample 1. |
| 127 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, |
| 128 }; |
| 129 |
| 130 // Size of these IVs are 16 bytes. |
| 131 const char kIv4[] = { |
| 132 0x41, 0x54, 0x65, 0x73, 0x74, 0x49, 0x76, 0x34, |
| 133 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, |
| 134 }; |
| 135 |
| 136 const char kIv5[] = { |
| 137 0x41, 0x54, 0x65, 0x73, 0x74, 0x49, 0x76, 0x35, |
| 138 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, |
| 139 }; |
| 140 #endif |
| 141 |
100 } // namespace | 142 } // namespace |
101 | 143 |
102 namespace media { | 144 namespace media { |
103 namespace mp4 { | 145 namespace mp4 { |
104 | 146 |
105 MATCHER(ReservedValueInSampleDependencyInfo, "") { | 147 MATCHER(ReservedValueInSampleDependencyInfo, "") { |
106 return CONTAINS_STRING(arg, "Reserved value used in sample dependency info."); | 148 return CONTAINS_STRING(arg, "Reserved value used in sample dependency info."); |
107 } | 149 } |
108 | 150 |
109 class TrackRunIteratorTest : public testing::Test { | 151 class TrackRunIteratorTest : public testing::Test { |
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
251 moof.tracks[1].runs.resize(1); | 293 moof.tracks[1].runs.resize(1); |
252 moof.tracks[1].runs[0].sample_count = 10; | 294 moof.tracks[1].runs[0].sample_count = 10; |
253 moof.tracks[1].runs[0].data_offset = 200; | 295 moof.tracks[1].runs[0].data_offset = 200; |
254 SetAscending(&moof.tracks[1].runs[0].sample_sizes); | 296 SetAscending(&moof.tracks[1].runs[0].sample_sizes); |
255 SetAscending(&moof.tracks[1].runs[0].sample_durations); | 297 SetAscending(&moof.tracks[1].runs[0].sample_durations); |
256 SetFlagsOnSamples("US UN UN UN UN UN UN UN UN UN", &moof.tracks[1].runs[0]); | 298 SetFlagsOnSamples("US UN UN UN UN UN UN UN UN UN", &moof.tracks[1].runs[0]); |
257 | 299 |
258 return moof; | 300 return moof; |
259 } | 301 } |
260 | 302 |
261 // Update the first sample description of a Track to indicate encryption | 303 ProtectionSchemeInfo* GetProtectionSchemeInfoForTrack(Track* track) { |
262 void AddEncryption(Track* track) { | |
263 SampleDescription* stsd = | 304 SampleDescription* stsd = |
264 &track->media.information.sample_table.description; | 305 &track->media.information.sample_table.description; |
265 ProtectionSchemeInfo* sinf; | 306 ProtectionSchemeInfo* sinf; |
266 if (!stsd->video_entries.empty()) { | 307 if (!stsd->video_entries.empty()) { |
267 sinf = &stsd->video_entries[0].sinf; | 308 sinf = &stsd->video_entries[0].sinf; |
268 } else { | 309 } else { |
269 sinf = &stsd->audio_entries[0].sinf; | 310 sinf = &stsd->audio_entries[0].sinf; |
270 } | 311 } |
| 312 return sinf; |
| 313 } |
271 | 314 |
| 315 // Update the first sample description of a Track to indicate CENC encryption |
| 316 void AddEncryption(Track* track) { |
| 317 ProtectionSchemeInfo* sinf = GetProtectionSchemeInfoForTrack(track); |
272 sinf->type.type = FOURCC_CENC; | 318 sinf->type.type = FOURCC_CENC; |
273 sinf->info.track_encryption.is_encrypted = true; | 319 sinf->info.track_encryption.is_encrypted = true; |
274 sinf->info.track_encryption.default_iv_size = 8; | 320 sinf->info.track_encryption.default_iv_size = 8; |
275 sinf->info.track_encryption.default_kid.assign(kKeyId, | 321 sinf->info.track_encryption.default_kid.assign(kKeyId, |
276 kKeyId + arraysize(kKeyId)); | 322 kKeyId + arraysize(kKeyId)); |
277 } | 323 } |
278 | 324 |
279 // Add SampleGroupDescription Box to track level sample table and to | 325 // Add SampleGroupDescription Box to track level sample table and to |
280 // fragment. Populate SampleToGroup Box from input array. | 326 // fragment. Populate SampleToGroup Box from input array. |
281 void AddCencSampleGroup(Track* track, | 327 void AddCencSampleGroup(Track* track, |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
347 frag->runs[0].sample_sizes[0] = 3; | 393 frag->runs[0].sample_sizes[0] = 3; |
348 frag->runs[0].sample_sizes[1] = 10; | 394 frag->runs[0].sample_sizes[1] = 10; |
349 // Set aux info header. | 395 // Set aux info header. |
350 frag->auxiliary_size.sample_info_sizes.push_back(16); | 396 frag->auxiliary_size.sample_info_sizes.push_back(16); |
351 frag->auxiliary_size.sample_info_sizes.push_back(30); | 397 frag->auxiliary_size.sample_info_sizes.push_back(30); |
352 } else { | 398 } else { |
353 frag->auxiliary_size.default_sample_info_size = 8; | 399 frag->auxiliary_size.default_sample_info_size = 8; |
354 } | 400 } |
355 } | 401 } |
356 | 402 |
| 403 #if BUILDFLAG(ENABLE_CBCS_ENCRYPTION_SCHEME) |
| 404 // Update the first sample description of a Track to indicate CBCS encryption |
| 405 // with a constant IV and pattern. |
| 406 void AddEncryptionCbcs(Track* track) { |
| 407 ProtectionSchemeInfo* sinf = GetProtectionSchemeInfoForTrack(track); |
| 408 sinf->type.type = FOURCC_CBCS; |
| 409 sinf->info.track_encryption.is_encrypted = true; |
| 410 sinf->info.track_encryption.default_iv_size = 0; |
| 411 sinf->info.track_encryption.default_crypt_byte_block = 1; |
| 412 sinf->info.track_encryption.default_skip_byte_block = 9; |
| 413 sinf->info.track_encryption.default_constant_iv_size = 16; |
| 414 memcpy(sinf->info.track_encryption.default_constant_iv, kIv3, 16); |
| 415 sinf->info.track_encryption.default_kid.assign(kKeyId, |
| 416 kKeyId + arraysize(kKeyId)); |
| 417 } |
| 418 |
| 419 void AddConstantIvsToCencSampleGroup(Track* track, TrackFragment* frag) { |
| 420 auto& track_cenc_group = |
| 421 track->media.information.sample_table.sample_group_description; |
| 422 track_cenc_group.entries[0].iv_size = 0; |
| 423 track_cenc_group.entries[0].crypt_byte_block = 1; |
| 424 track_cenc_group.entries[0].skip_byte_block = 9; |
| 425 track_cenc_group.entries[0].constant_iv_size = 16; |
| 426 memcpy(track_cenc_group.entries[0].constant_iv, kIv4, 16); |
| 427 |
| 428 frag->sample_group_description.entries[1].iv_size = 0; |
| 429 frag->sample_group_description.entries[1].crypt_byte_block = 1; |
| 430 frag->sample_group_description.entries[1].skip_byte_block = 9; |
| 431 frag->sample_group_description.entries[1].constant_iv_size = 16; |
| 432 memcpy(frag->sample_group_description.entries[1].constant_iv, kIv5, 16); |
| 433 frag->sample_group_description.entries[2].iv_size = 0; |
| 434 frag->sample_group_description.entries[2].crypt_byte_block = 1; |
| 435 frag->sample_group_description.entries[2].skip_byte_block = 9; |
| 436 frag->sample_group_description.entries[2].constant_iv_size = 16; |
| 437 memcpy(frag->sample_group_description.entries[2].constant_iv, kIv5, 16); |
| 438 } |
| 439 |
| 440 void AddSampleEncryptionCbcs(TrackFragment* frag) { |
| 441 frag->sample_encryption.use_subsample_encryption = true; |
| 442 frag->sample_encryption.sample_encryption_data.assign( |
| 443 kSampleEncryptionDataWithSubsamplesAndConstantIv, |
| 444 kSampleEncryptionDataWithSubsamplesAndConstantIv + |
| 445 arraysize(kSampleEncryptionDataWithSubsamplesAndConstantIv)); |
| 446 |
| 447 // Update sample sizes and aux info header. |
| 448 frag->runs.resize(1); |
| 449 frag->runs[0].sample_count = 5; |
| 450 frag->auxiliary_offset.offsets.push_back(0); |
| 451 frag->auxiliary_size.sample_count = 5; |
| 452 // Update sample sizes to match with subsample entries above. |
| 453 frag->runs[0].sample_sizes[0] = 3; |
| 454 frag->runs[0].sample_sizes[1] = 10; |
| 455 frag->runs[0].sample_sizes[2] = 3; |
| 456 frag->runs[0].sample_sizes[3] = 3; |
| 457 frag->runs[0].sample_sizes[4] = 3; |
| 458 // Set aux info header. |
| 459 frag->auxiliary_size.sample_info_sizes.push_back(16); |
| 460 frag->auxiliary_size.sample_info_sizes.push_back(30); |
| 461 frag->auxiliary_size.sample_info_sizes.push_back(16); |
| 462 frag->auxiliary_size.sample_info_sizes.push_back(16); |
| 463 frag->auxiliary_size.sample_info_sizes.push_back(16); |
| 464 } |
| 465 #endif |
| 466 |
357 bool InitMoofWithArbitraryAuxInfo(MovieFragment* moof) { | 467 bool InitMoofWithArbitraryAuxInfo(MovieFragment* moof) { |
358 // Add aux info header (equal sized aux info for every sample). | 468 // Add aux info header (equal sized aux info for every sample). |
359 for (uint32_t i = 0; i < moof->tracks.size(); ++i) { | 469 for (uint32_t i = 0; i < moof->tracks.size(); ++i) { |
360 moof->tracks[i].auxiliary_offset.offsets.push_back(50); | 470 moof->tracks[i].auxiliary_offset.offsets.push_back(50); |
361 moof->tracks[i].auxiliary_size.sample_count = 10; | 471 moof->tracks[i].auxiliary_size.sample_count = 10; |
362 moof->tracks[i].auxiliary_size.default_sample_info_size = 8; | 472 moof->tracks[i].auxiliary_size.default_sample_info_size = 8; |
363 } | 473 } |
364 | 474 |
365 // We don't care about the actual data in aux. | 475 // We don't care about the actual data in aux. |
366 std::vector<uint8_t> aux_info(1000); | 476 std::vector<uint8_t> aux_info(1000); |
(...skipping 505 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
872 // For video, any key frame should be both a sync sample and have no known | 982 // For video, any key frame should be both a sync sample and have no known |
873 // dependents. Ideally, a video sync sample should always be marked as having | 983 // dependents. Ideally, a video sync sample should always be marked as having |
874 // no dependents, but we occasionally encounter media where all samples are | 984 // no dependents, but we occasionally encounter media where all samples are |
875 // marked "sync" and we must rely on combining the two flags to pick out the | 985 // marked "sync" and we must rely on combining the two flags to pick out the |
876 // true key frames. See http://crbug.com/310712 and http://crbug.com/507916. | 986 // true key frames. See http://crbug.com/310712 and http://crbug.com/507916. |
877 // Realiably knowing the keyframes for video is also critical to SPS PPS | 987 // Realiably knowing the keyframes for video is also critical to SPS PPS |
878 // insertion. | 988 // insertion. |
879 EXPECT_EQ("2 K P P P K P", KeyframeAndRAPInfo(iter_.get())); | 989 EXPECT_EQ("2 K P P P K P", KeyframeAndRAPInfo(iter_.get())); |
880 } | 990 } |
881 | 991 |
| 992 #if BUILDFLAG(ENABLE_CBCS_ENCRYPTION_SCHEME) |
| 993 TEST_F(TrackRunIteratorTest, DecryptConfigTestWithConstantIvNoAuxInfo) { |
| 994 AddEncryptionCbcs(&moov_.tracks[1]); |
| 995 iter_.reset(new TrackRunIterator(&moov_, media_log_)); |
| 996 |
| 997 MovieFragment moof = CreateFragment(); |
| 998 |
| 999 ASSERT_TRUE(iter_->Init(moof)); |
| 1000 |
| 1001 // The run for track 2 will be the second. |
| 1002 iter_->AdvanceRun(); |
| 1003 EXPECT_EQ(iter_->track_id(), 2u); |
| 1004 EXPECT_TRUE(iter_->is_encrypted()); |
| 1005 ASSERT_FALSE(iter_->AuxInfoNeedsToBeCached()); |
| 1006 EXPECT_EQ(iter_->sample_offset(), 200); |
| 1007 std::unique_ptr<DecryptConfig> config = iter_->GetDecryptConfig(); |
| 1008 EXPECT_EQ( |
| 1009 std::string(reinterpret_cast<const char*>(kKeyId), arraysize(kKeyId)), |
| 1010 config->key_id()); |
| 1011 EXPECT_EQ(std::string(reinterpret_cast<const char*>(kIv3), arraysize(kIv3)), |
| 1012 config->iv()); |
| 1013 EXPECT_TRUE(config->subsamples().empty()); |
| 1014 iter_->AdvanceSample(); |
| 1015 config = iter_->GetDecryptConfig(); |
| 1016 EXPECT_EQ( |
| 1017 std::string(reinterpret_cast<const char*>(kKeyId), arraysize(kKeyId)), |
| 1018 config->key_id()); |
| 1019 EXPECT_EQ(std::string(reinterpret_cast<const char*>(kIv3), arraysize(kIv3)), |
| 1020 config->iv()); |
| 1021 EXPECT_TRUE(config->subsamples().empty()); |
| 1022 } |
| 1023 |
| 1024 TEST_F(TrackRunIteratorTest, DecryptConfigTestWithSampleGroupsAndConstantIv) { |
| 1025 // Add TrackEncryption Box. |
| 1026 AddEncryptionCbcs(&moov_.tracks[1]); |
| 1027 |
| 1028 MovieFragment moof = CreateFragment(); |
| 1029 AddSampleEncryptionCbcs(&moof.tracks[1]); |
| 1030 |
| 1031 const SampleToGroupEntry kSampleToGroupTable[] = { |
| 1032 // Associated with the 2nd entry in fragment SampleGroupDescription Box. |
| 1033 {1, SampleToGroupEntry::kFragmentGroupDescriptionIndexBase + 2}, |
| 1034 // Associated with the default values specified in TrackEncryption Box. |
| 1035 {1, 0}, |
| 1036 // Associated with the 1st entry in fragment SampleGroupDescription Box. |
| 1037 {1, SampleToGroupEntry::kFragmentGroupDescriptionIndexBase + 1}, |
| 1038 // Associated with the 1st entry in track SampleGroupDescription Box. |
| 1039 {1, 1}}; |
| 1040 AddCencSampleGroup(&moov_.tracks[1], &moof.tracks[1], kSampleToGroupTable, |
| 1041 arraysize(kSampleToGroupTable)); |
| 1042 AddConstantIvsToCencSampleGroup(&moov_.tracks[1], &moof.tracks[1]); |
| 1043 iter_.reset(new TrackRunIterator(&moov_, media_log_)); |
| 1044 ASSERT_TRUE(iter_->Init(moof)); |
| 1045 |
| 1046 // The run for track 2 will be the second. |
| 1047 iter_->AdvanceRun(); |
| 1048 |
| 1049 std::string track_encryption_iv(kIv3, kIv3 + arraysize(kIv3)); |
| 1050 std::string track_cenc_sample_group_iv(kIv4, kIv4 + arraysize(kIv4)); |
| 1051 std::string fragment_cenc_sample_group_iv(kIv5, kIv5 + arraysize(kIv5)); |
| 1052 |
| 1053 for (size_t i = 0; i < kSampleToGroupTable[0].sample_count; ++i) { |
| 1054 EXPECT_TRUE(iter_->is_encrypted()); |
| 1055 EXPECT_EQ(fragment_cenc_sample_group_iv, iter_->GetDecryptConfig()->iv()); |
| 1056 iter_->AdvanceSample(); |
| 1057 } |
| 1058 |
| 1059 for (size_t i = 0; i < kSampleToGroupTable[1].sample_count; ++i) { |
| 1060 EXPECT_TRUE(iter_->is_encrypted()); |
| 1061 EXPECT_EQ(track_encryption_iv, iter_->GetDecryptConfig()->iv()); |
| 1062 iter_->AdvanceSample(); |
| 1063 } |
| 1064 |
| 1065 for (size_t i = 0; i < kSampleToGroupTable[2].sample_count; ++i) { |
| 1066 EXPECT_FALSE(iter_->is_encrypted()); |
| 1067 iter_->AdvanceSample(); |
| 1068 } |
| 1069 |
| 1070 for (size_t i = 0; i < kSampleToGroupTable[3].sample_count; ++i) { |
| 1071 EXPECT_TRUE(iter_->is_encrypted()); |
| 1072 EXPECT_EQ(track_cenc_sample_group_iv, iter_->GetDecryptConfig()->iv()); |
| 1073 iter_->AdvanceSample(); |
| 1074 } |
| 1075 |
| 1076 // The remaining samples should be associated with the default values |
| 1077 // specified in TrackEncryption Box. |
| 1078 EXPECT_TRUE(iter_->is_encrypted()); |
| 1079 EXPECT_EQ(track_encryption_iv, iter_->GetDecryptConfig()->iv()); |
| 1080 } |
| 1081 |
| 1082 #endif |
| 1083 |
882 } // namespace mp4 | 1084 } // namespace mp4 |
883 } // namespace media | 1085 } // namespace media |
OLD | NEW |