Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(352)

Side by Side Diff: media/formats/mp4/track_run_iterator_unittest.cc

Issue 1319813002: Fix mp4 keyframe parsing, removing unused stss parsing. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Minor typo/fixes. Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 "base/basictypes.h" 5 #include "base/basictypes.h"
6 #include "base/logging.h" 6 #include "base/logging.h"
7 #include "base/memory/scoped_ptr.h" 7 #include "base/memory/scoped_ptr.h"
8 #include "base/strings/string_split.h" 8 #include "base/strings/string_split.h"
9 #include "media/formats/mp4/box_definitions.h" 9 #include "media/formats/mp4/box_definitions.h"
10 #include "media/formats/mp4/rcheck.h" 10 #include "media/formats/mp4/rcheck.h"
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
66 moov_.tracks[0].media.header.timescale = kAudioScale; 66 moov_.tracks[0].media.header.timescale = kAudioScale;
67 SampleDescription& desc1 = 67 SampleDescription& desc1 =
68 moov_.tracks[0].media.information.sample_table.description; 68 moov_.tracks[0].media.information.sample_table.description;
69 AudioSampleEntry aud_desc; 69 AudioSampleEntry aud_desc;
70 aud_desc.format = FOURCC_MP4A; 70 aud_desc.format = FOURCC_MP4A;
71 aud_desc.sinf.info.track_encryption.is_encrypted = false; 71 aud_desc.sinf.info.track_encryption.is_encrypted = false;
72 desc1.type = kAudio; 72 desc1.type = kAudio;
73 desc1.audio_entries.push_back(aud_desc); 73 desc1.audio_entries.push_back(aud_desc);
74 moov_.extends.tracks[0].track_id = 1; 74 moov_.extends.tracks[0].track_id = 1;
75 moov_.extends.tracks[0].default_sample_description_index = 1; 75 moov_.extends.tracks[0].default_sample_description_index = 1;
76 moov_.tracks[0].media.information.sample_table.sync_sample.is_present =
77 false;
78 moov_.tracks[1].header.track_id = 2; 76 moov_.tracks[1].header.track_id = 2;
79 moov_.tracks[1].media.header.timescale = kVideoScale; 77 moov_.tracks[1].media.header.timescale = kVideoScale;
80 SampleDescription& desc2 = 78 SampleDescription& desc2 =
81 moov_.tracks[1].media.information.sample_table.description; 79 moov_.tracks[1].media.information.sample_table.description;
82 VideoSampleEntry vid_desc; 80 VideoSampleEntry vid_desc;
83 vid_desc.format = FOURCC_AVC1; 81 vid_desc.format = FOURCC_AVC1;
84 vid_desc.sinf.info.track_encryption.is_encrypted = false; 82 vid_desc.sinf.info.track_encryption.is_encrypted = false;
85 desc2.type = kVideo; 83 desc2.type = kVideo;
86 desc2.video_entries.push_back(vid_desc); 84 desc2.video_entries.push_back(vid_desc);
87 moov_.extends.tracks[1].track_id = 2; 85 moov_.extends.tracks[1].track_id = 2;
88 moov_.extends.tracks[1].default_sample_description_index = 1; 86 moov_.extends.tracks[1].default_sample_description_index = 1;
89 SyncSample& video_sync_sample =
90 moov_.tracks[1].media.information.sample_table.sync_sample;
91 video_sync_sample.is_present = true;
92 video_sync_sample.entries.resize(1);
93 video_sync_sample.entries[0] = 0;
94 87
95 moov_.tracks[2].header.track_id = 3; 88 moov_.tracks[2].header.track_id = 3;
96 moov_.tracks[2].media.information.sample_table.description.type = kHint; 89 moov_.tracks[2].media.information.sample_table.description.type = kHint;
97 } 90 }
98 91
99 uint32 ToSampleFlags(const std::string& str) { 92 uint32 ToSampleFlags(const std::string& str) {
100 CHECK_EQ(str.length(), 2u); 93 CHECK_EQ(str.length(), 2u);
101 94
102 SampleDependsOn sample_depends_on = kSampleDependsOnReserved; 95 SampleDependsOn sample_depends_on = kSampleDependsOnReserved;
103 bool is_non_sync_sample = false; 96 bool is_non_sync_sample = false;
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
163 trun->sample_flags[i] = ToSampleFlags(flags_data[i]); 156 trun->sample_flags[i] = ToSampleFlags(flags_data[i]);
164 } 157 }
165 158
166 std::string KeyframeAndRAPInfo(TrackRunIterator* iter) { 159 std::string KeyframeAndRAPInfo(TrackRunIterator* iter) {
167 CHECK(iter->IsRunValid()); 160 CHECK(iter->IsRunValid());
168 std::stringstream ss; 161 std::stringstream ss;
169 ss << iter->track_id(); 162 ss << iter->track_id();
170 163
171 while (iter->IsSampleValid()) { 164 while (iter->IsSampleValid()) {
172 ss << " " << (iter->is_keyframe() ? "K" : "P"); 165 ss << " " << (iter->is_keyframe() ? "K" : "P");
173 if (iter->is_random_access_point())
174 ss << "R";
175 iter->AdvanceSample(); 166 iter->AdvanceSample();
176 } 167 }
177 168
178 return ss.str(); 169 return ss.str();
179 } 170 }
180 171
181 MovieFragment CreateFragment() { 172 MovieFragment CreateFragment() {
182 MovieFragment moof; 173 MovieFragment moof;
183 moof.tracks.resize(2); 174 moof.tracks.resize(2);
184 moof.tracks[0].decode_time.decode_time = 0; 175 moof.tracks[0].decode_time.decode_time = 0;
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after
374 // Ensure that keyframes are flagged correctly in the face of BMFF boxes which 365 // Ensure that keyframes are flagged correctly in the face of BMFF boxes which
375 // explicitly specify the flags for the first sample in a run and rely on 366 // explicitly specify the flags for the first sample in a run and rely on
376 // defaults for all subsequent samples 367 // defaults for all subsequent samples
377 iter_.reset(new TrackRunIterator(&moov_, media_log_)); 368 iter_.reset(new TrackRunIterator(&moov_, media_log_));
378 MovieFragment moof = CreateFragment(); 369 MovieFragment moof = CreateFragment();
379 moof.tracks[1].header.has_default_sample_flags = true; 370 moof.tracks[1].header.has_default_sample_flags = true;
380 moof.tracks[1].header.default_sample_flags = ToSampleFlags("UN"); 371 moof.tracks[1].header.default_sample_flags = ToSampleFlags("UN");
381 SetFlagsOnSamples("US", &moof.tracks[1].runs[0]); 372 SetFlagsOnSamples("US", &moof.tracks[1].runs[0]);
382 373
383 ASSERT_TRUE(iter_->Init(moof)); 374 ASSERT_TRUE(iter_->Init(moof));
384 EXPECT_EQ("1 KR KR KR KR KR KR KR KR KR KR", KeyframeAndRAPInfo(iter_.get())); 375 EXPECT_EQ("1 K K K K K K K K K K", KeyframeAndRAPInfo(iter_.get()));
385 376
386 iter_->AdvanceRun(); 377 iter_->AdvanceRun();
387 EXPECT_EQ("2 KR P P P P P P P P P", KeyframeAndRAPInfo(iter_.get())); 378 EXPECT_EQ("2 K P P P P P P P P P", KeyframeAndRAPInfo(iter_.get()));
388 } 379 }
389 380
390 // Verify that parsing fails if a reserved value is in the sample flags. 381 // Verify that parsing fails if a reserved value is in the sample flags.
391 TEST_F(TrackRunIteratorTest, SampleInfoTest_ReservedInSampleFlags) { 382 TEST_F(TrackRunIteratorTest, SampleInfoTest_ReservedInSampleFlags) {
392 iter_.reset(new TrackRunIterator(&moov_, media_log_)); 383 iter_.reset(new TrackRunIterator(&moov_, media_log_));
393 MovieFragment moof = CreateFragment(); 384 MovieFragment moof = CreateFragment();
394 // Change the "depends on" field on one of the samples to a 385 // Change the "depends on" field on one of the samples to a
395 // reserved value. 386 // reserved value.
396 moof.tracks[1].runs[0].sample_flags[0] = ToSampleFlags("RS"); 387 moof.tracks[1].runs[0].sample_flags[0] = ToSampleFlags("RS");
397 ASSERT_FALSE(iter_->Init(moof)); 388 ASSERT_FALSE(iter_->Init(moof));
(...skipping 267 matching lines...) Expand 10 before | Expand all | Expand 10 after
665 EXPECT_EQ(iter_->GetMaxClearOffset(), 101); 656 EXPECT_EQ(iter_->GetMaxClearOffset(), 101);
666 iter_->AdvanceRun(); 657 iter_->AdvanceRun();
667 EXPECT_EQ(iter_->track_id(), 1u); 658 EXPECT_EQ(iter_->track_id(), 1u);
668 EXPECT_EQ(iter_->aux_info_offset(), 201); 659 EXPECT_EQ(iter_->aux_info_offset(), 201);
669 EXPECT_EQ(iter_->sample_offset(), 10000); 660 EXPECT_EQ(iter_->sample_offset(), 10000);
670 EXPECT_EQ(iter_->GetMaxClearOffset(), 201); 661 EXPECT_EQ(iter_->GetMaxClearOffset(), 201);
671 EXPECT_TRUE(iter_->CacheAuxInfo(kAuxInfo, arraysize(kAuxInfo))); 662 EXPECT_TRUE(iter_->CacheAuxInfo(kAuxInfo, arraysize(kAuxInfo)));
672 EXPECT_EQ(iter_->GetMaxClearOffset(), 10000); 663 EXPECT_EQ(iter_->GetMaxClearOffset(), 10000);
673 } 664 }
674 665
675 TEST_F(TrackRunIteratorTest, MissingAndEmptyStss) { 666 TEST_F(TrackRunIteratorTest, KeyFrameFlagCombinations) {
667 // Setup both audio and video tracks to each have 6 samples covering all the
668 // combinations of mp4 "sync sample" and "depends on" relationships.
676 MovieFragment moof = CreateFragment(); 669 MovieFragment moof = CreateFragment();
677
678 // Setup track 0 to not have an stss box, which means that all samples should
679 // be marked as random access points unless the kSampleIsNonSyncSample flag is
680 // set in the sample flags.
681 moov_.tracks[0].media.information.sample_table.sync_sample.is_present = false;
682 moov_.tracks[0].media.information.sample_table.sync_sample.entries.resize(0);
683 moof.tracks[0].runs.resize(1); 670 moof.tracks[0].runs.resize(1);
671 moof.tracks[1].runs.resize(1);
684 moof.tracks[0].runs[0].sample_count = 6; 672 moof.tracks[0].runs[0].sample_count = 6;
685 moof.tracks[0].runs[0].data_offset = 100; 673 moof.tracks[1].runs[0].sample_count = 6;
686 SetFlagsOnSamples("US UN OS ON NS NN", &moof.tracks[0].runs[0]); 674 SetFlagsOnSamples("US UN OS ON NS NN", &moof.tracks[0].runs[0]);
687
688 // Setup track 1 to have an stss box with no entries, which normally means
689 // that none of the samples should be random access points. If the
690 // kSampleIsNonSyncSample flag is NOT set though, the sample should be
691 // considered a random access point.
692 moov_.tracks[1].media.information.sample_table.sync_sample.is_present = true;
693 moov_.tracks[1].media.information.sample_table.sync_sample.entries.resize(0);
694 moof.tracks[1].runs.resize(1);
695 moof.tracks[1].runs[0].sample_count = 6;
696 moof.tracks[1].runs[0].data_offset = 200;
697 SetFlagsOnSamples("US UN OS ON NS NN", &moof.tracks[1].runs[0]); 675 SetFlagsOnSamples("US UN OS ON NS NN", &moof.tracks[1].runs[0]);
698
699 iter_.reset(new TrackRunIterator(&moov_, media_log_)); 676 iter_.reset(new TrackRunIterator(&moov_, media_log_));
700 677
701 ASSERT_TRUE(iter_->Init(moof)); 678 ASSERT_TRUE(iter_->Init(moof));
702 EXPECT_TRUE(iter_->IsRunValid()); 679 EXPECT_TRUE(iter_->IsRunValid());
703 680
704 // Verify that all samples except for the ones that have the 681 // Keyframes should be marked according to downstream's expectations that
705 // kSampleIsNonSyncSample flag set are marked as random access points. 682 // keyframes serve as points of random access for seeking.
706 EXPECT_EQ("1 KR P PR P KR K", KeyframeAndRAPInfo(iter_.get())); 683
684 // For audio, any sync sample should be marked as a key frame. Whether a
685 // sample "depends on" other samples is not considered. Unlike video samples,
686 // audio samples are often marked as depending on other samples but are still
687 // workable for random access. While we allow for parsing of audio samples
688 // that are non-sync samples, we generally expect all audio samples to be sync
689 // samples and downstream will log and discard any non-sync audio samples.
690 EXPECT_EQ("1 K P K P K P", KeyframeAndRAPInfo(iter_.get()));
707 691
708 iter_->AdvanceRun(); 692 iter_->AdvanceRun();
709 693
710 // Verify that nothing is marked as a random access point. 694 // For video, any key frame should be both a sync sample and have no known
711 EXPECT_EQ("2 KR P PR P KR K", KeyframeAndRAPInfo(iter_.get())); 695 // dependents. Ideally, a video sync sample should always be marked as having
696 // no dependents, but we occasionally encounter media where all samples are
697 // marked "sync" and we must rely on combining the two flags to pick out the
698 // true key frames. See http://crbug.com/310712 and http://crbug.com/507916.
699 // Realiably knowing the keyframes for video is also critical to SPS PPS
700 // insertion.
701 EXPECT_EQ("2 K P P P K P", KeyframeAndRAPInfo(iter_.get()));
712 } 702 }
713 703
714
715 } // namespace mp4 704 } // namespace mp4
716 } // namespace media 705 } // namespace media
OLDNEW
« media/formats/mp4/track_run_iterator.cc ('K') | « media/formats/mp4/track_run_iterator.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698