OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "media/mp4/box_definitions.h" | 8 #include "media/mp4/box_definitions.h" |
9 #include "media/mp4/rcheck.h" | 9 #include "media/mp4/rcheck.h" |
10 #include "media/mp4/track_run_iterator.h" | 10 #include "media/mp4/track_run_iterator.h" |
11 #include "testing/gtest/include/gtest/gtest.h" | 11 #include "testing/gtest/include/gtest/gtest.h" |
12 | 12 |
13 // The sum of the elements in a vector initialized with SumAscending, | 13 // The sum of the elements in a vector initialized with SumAscending, |
14 // less the value of the last element. | 14 // less the value of the last element. |
15 static const int kSumAscending1 = 45; | 15 static const int kSumAscending1 = 45; |
16 | 16 |
17 static const int kAudioScale = 48000; | 17 static const int kAudioScale = 48000; |
18 static const int kVideoScale = 25; | 18 static const int kVideoScale = 25; |
19 | 19 |
20 static const uint32 kSampleIsDifferenceSampleFlagMask = 0x10000; | 20 static const uint32 kSampleIsDifferenceSampleFlagMask = 0x10000; |
21 | 21 |
22 static const uint8 kAuxInfo[] = { | |
23 0x41, 0x54, 0x65, 0x73, 0x74, 0x49, 0x76, 0x31, | |
24 0x41, 0x54, 0x65, 0x73, 0x74, 0x49, 0x76, 0x32, | |
25 0x00, 0x02, | |
26 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, | |
27 0x00, 0x03, 0x00, 0x00, 0x00, 0x04 | |
28 }; | |
29 | |
30 static const char kIv1[] = { | |
31 0x41, 0x54, 0x65, 0x73, 0x74, 0x49, 0x76, 0x31, | |
32 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 | |
33 }; | |
34 | |
35 static const uint8 kKeyId[] = { | |
36 0x41, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x54, | |
37 0x65, 0x73, 0x74, 0x4b, 0x65, 0x79, 0x49, 0x44 | |
38 }; | |
39 | |
22 namespace media { | 40 namespace media { |
23 namespace mp4 { | 41 namespace mp4 { |
24 | 42 |
25 class TrackRunIteratorTest : public testing::Test { | 43 class TrackRunIteratorTest : public testing::Test { |
26 public: | 44 public: |
27 TrackRunIteratorTest() { | 45 TrackRunIteratorTest() { |
28 CreateMovie(); | 46 CreateMovie(); |
29 } | 47 } |
30 | 48 |
31 protected: | 49 protected: |
32 Movie moov_; | 50 Movie moov_; |
33 scoped_ptr<TrackRunIterator> iter_; | 51 scoped_ptr<TrackRunIterator> iter_; |
34 | 52 |
35 void CreateMovie() { | 53 void CreateMovie() { |
36 moov_.header.timescale = 1000; | 54 moov_.header.timescale = 1000; |
37 moov_.tracks.resize(3); | 55 moov_.tracks.resize(3); |
38 moov_.extends.tracks.resize(2); | 56 moov_.extends.tracks.resize(2); |
39 moov_.tracks[0].header.track_id = 1; | 57 moov_.tracks[0].header.track_id = 1; |
40 moov_.tracks[0].media.header.timescale = kAudioScale; | 58 moov_.tracks[0].media.header.timescale = kAudioScale; |
41 SampleDescription& desc1 = | 59 SampleDescription& desc1 = |
42 moov_.tracks[0].media.information.sample_table.description; | 60 moov_.tracks[0].media.information.sample_table.description; |
61 AudioSampleEntry aud_desc; | |
62 aud_desc.format = FOURCC_MP4A; | |
63 aud_desc.sinf.info.track_encryption.is_encrypted = false; | |
43 desc1.type = kAudio; | 64 desc1.type = kAudio; |
44 desc1.audio_entries.resize(1); | 65 desc1.audio_entries.push_back(aud_desc); |
45 desc1.audio_entries[0].format = FOURCC_MP4A; | |
46 moov_.extends.tracks[0].track_id = 1; | 66 moov_.extends.tracks[0].track_id = 1; |
67 moov_.extends.tracks[0].default_sample_description_index = 1; | |
47 | 68 |
48 moov_.tracks[1].header.track_id = 2; | 69 moov_.tracks[1].header.track_id = 2; |
49 moov_.tracks[1].media.header.timescale = kVideoScale; | 70 moov_.tracks[1].media.header.timescale = kVideoScale; |
50 SampleDescription& desc2 = | 71 SampleDescription& desc2 = |
51 moov_.tracks[1].media.information.sample_table.description; | 72 moov_.tracks[1].media.information.sample_table.description; |
73 VideoSampleEntry vid_desc; | |
74 vid_desc.format = FOURCC_AVC1; | |
75 vid_desc.sinf.info.track_encryption.is_encrypted = false; | |
52 desc2.type = kVideo; | 76 desc2.type = kVideo; |
53 desc2.video_entries.resize(1); | 77 desc2.video_entries.push_back(vid_desc); |
54 desc2.video_entries[0].sinf.info.track_encryption.is_encrypted = false; | |
55 moov_.extends.tracks[1].track_id = 2; | 78 moov_.extends.tracks[1].track_id = 2; |
79 moov_.extends.tracks[1].default_sample_description_index = 1; | |
56 | 80 |
57 moov_.tracks[2].header.track_id = 3; | 81 moov_.tracks[2].header.track_id = 3; |
58 moov_.tracks[2].media.information.sample_table.description.type = kHint; | 82 moov_.tracks[2].media.information.sample_table.description.type = kHint; |
59 } | 83 } |
60 | 84 |
61 MovieFragment CreateFragment() { | 85 MovieFragment CreateFragment() { |
62 MovieFragment moof; | 86 MovieFragment moof; |
63 moof.tracks.resize(2); | 87 moof.tracks.resize(2); |
64 moof.tracks[0].decode_time.decode_time = 0; | 88 moof.tracks[0].decode_time.decode_time = 0; |
65 moof.tracks[0].header.track_id = 1; | 89 moof.tracks[0].header.track_id = 1; |
(...skipping 18 matching lines...) Expand all Loading... | |
84 SetAscending(&moof.tracks[1].runs[0].sample_durations); | 108 SetAscending(&moof.tracks[1].runs[0].sample_durations); |
85 moof.tracks[1].runs[0].sample_flags.resize(10); | 109 moof.tracks[1].runs[0].sample_flags.resize(10); |
86 for (size_t i = 1; i < moof.tracks[1].runs[0].sample_flags.size(); i++) { | 110 for (size_t i = 1; i < moof.tracks[1].runs[0].sample_flags.size(); i++) { |
87 moof.tracks[1].runs[0].sample_flags[i] = | 111 moof.tracks[1].runs[0].sample_flags[i] = |
88 kSampleIsDifferenceSampleFlagMask; | 112 kSampleIsDifferenceSampleFlagMask; |
89 } | 113 } |
90 | 114 |
91 return moof; | 115 return moof; |
92 } | 116 } |
93 | 117 |
118 // Update the first sample description of a Track to indicate encryption | |
119 void AddEncryption(Track* track) { | |
120 SampleDescription* stsd = | |
121 &track->media.information.sample_table.description; | |
122 ProtectionSchemeInfo* sinf; | |
123 if (!stsd->video_entries.empty()) { | |
124 sinf = &stsd->video_entries[0].sinf; | |
125 } else { | |
126 sinf = &stsd->audio_entries[0].sinf; | |
127 } | |
128 | |
129 sinf->type.type = FOURCC_CENC; | |
130 sinf->info.track_encryption.is_encrypted = true; | |
131 sinf->info.track_encryption.default_iv_size = 8; | |
132 sinf->info.track_encryption.default_kid.insert( | |
133 sinf->info.track_encryption.default_kid.begin(), | |
134 kKeyId, kKeyId + arraysize(kKeyId)); | |
135 } | |
136 | |
137 // Add aux info covering the first track run to a TrackFragment, and update | |
138 // the run to ensure it matches length and subsample information. | |
139 void AddAuxInfoHeaders(int offset, TrackFragment* frag) { | |
140 frag->auxiliary_offset.offsets.push_back(offset); | |
141 frag->auxiliary_size.sample_count = 2; | |
142 frag->auxiliary_size.sample_info_sizes.push_back(8); | |
143 frag->auxiliary_size.sample_info_sizes.push_back(22); | |
144 frag->runs[0].sample_count = 2; | |
145 frag->runs[0].sample_sizes[1] = 10; | |
146 } | |
147 | |
94 void SetAscending(std::vector<uint32>* vec) { | 148 void SetAscending(std::vector<uint32>* vec) { |
95 vec->resize(10); | 149 vec->resize(10); |
96 for (size_t i = 0; i < vec->size(); i++) | 150 for (size_t i = 0; i < vec->size(); i++) |
97 (*vec)[i] = i+1; | 151 (*vec)[i] = i+1; |
98 } | 152 } |
99 }; | 153 }; |
100 | 154 |
101 TEST_F(TrackRunIteratorTest, NoRunsTest) { | 155 TEST_F(TrackRunIteratorTest, NoRunsTest) { |
102 iter_.reset(new TrackRunIterator(&moov_)); | 156 iter_.reset(new TrackRunIterator(&moov_)); |
103 ASSERT_TRUE(iter_->Init(MovieFragment())); | 157 ASSERT_TRUE(iter_->Init(MovieFragment())); |
104 EXPECT_FALSE(iter_->RunIsValid()); | 158 EXPECT_FALSE(iter_->IsRunValid()); |
105 EXPECT_FALSE(iter_->SampleIsValid()); | 159 EXPECT_FALSE(iter_->IsSampleValid()); |
106 } | 160 } |
107 | 161 |
108 TEST_F(TrackRunIteratorTest, BasicOperationTest) { | 162 TEST_F(TrackRunIteratorTest, BasicOperationTest) { |
109 iter_.reset(new TrackRunIterator(&moov_)); | 163 iter_.reset(new TrackRunIterator(&moov_)); |
110 MovieFragment moof = CreateFragment(); | 164 MovieFragment moof = CreateFragment(); |
111 | 165 |
112 // Test that runs are sorted correctly, and that properties of the initial | 166 // Test that runs are sorted correctly, and that properties of the initial |
113 // sample of the first run are correct | 167 // sample of the first run are correct |
114 ASSERT_TRUE(iter_->Init(moof)); | 168 ASSERT_TRUE(iter_->Init(moof)); |
115 EXPECT_TRUE(iter_->RunIsValid()); | 169 EXPECT_TRUE(iter_->IsRunValid()); |
116 EXPECT_FALSE(iter_->is_encrypted()); | 170 EXPECT_FALSE(iter_->is_encrypted()); |
117 EXPECT_EQ(iter_->track_id(), 1u); | 171 EXPECT_EQ(iter_->track_id(), 1u); |
118 EXPECT_EQ(iter_->sample_offset(), 100); | 172 EXPECT_EQ(iter_->sample_offset(), 100); |
119 EXPECT_EQ(iter_->sample_size(), 1); | 173 EXPECT_EQ(iter_->sample_size(), 1); |
120 EXPECT_EQ(iter_->dts(), TimeDeltaFromFrac(0, kAudioScale)); | 174 EXPECT_EQ(iter_->dts(), TimeDeltaFromRational(0, kAudioScale)); |
121 EXPECT_EQ(iter_->cts(), TimeDeltaFromFrac(0, kAudioScale)); | 175 EXPECT_EQ(iter_->cts(), TimeDeltaFromRational(0, kAudioScale)); |
122 EXPECT_EQ(iter_->duration(), TimeDeltaFromFrac(1024, kAudioScale)); | 176 EXPECT_EQ(iter_->duration(), TimeDeltaFromRational(1024, kAudioScale)); |
123 EXPECT_TRUE(iter_->is_keyframe()); | 177 EXPECT_TRUE(iter_->is_keyframe()); |
124 | 178 |
125 // Advance to the last sample in the current run, and test its properties | 179 // Advance to the last sample in the current run, and test its properties |
126 for (int i = 0; i < 9; i++) iter_->AdvanceSample(); | 180 for (int i = 0; i < 9; i++) iter_->AdvanceSample(); |
127 EXPECT_EQ(iter_->track_id(), 1u); | 181 EXPECT_EQ(iter_->track_id(), 1u); |
128 EXPECT_EQ(iter_->sample_offset(), 100 + kSumAscending1); | 182 EXPECT_EQ(iter_->sample_offset(), 100 + kSumAscending1); |
129 EXPECT_EQ(iter_->sample_size(), 10); | 183 EXPECT_EQ(iter_->sample_size(), 10); |
130 EXPECT_EQ(iter_->dts(), TimeDeltaFromFrac(1024 * 9, kAudioScale)); | 184 EXPECT_EQ(iter_->dts(), TimeDeltaFromRational(1024 * 9, kAudioScale)); |
131 EXPECT_EQ(iter_->duration(), TimeDeltaFromFrac(1024, kAudioScale)); | 185 EXPECT_EQ(iter_->duration(), TimeDeltaFromRational(1024, kAudioScale)); |
132 EXPECT_TRUE(iter_->is_keyframe()); | 186 EXPECT_TRUE(iter_->is_keyframe()); |
133 | 187 |
134 // Test end-of-run | 188 // Test end-of-run |
135 iter_->AdvanceSample(); | 189 iter_->AdvanceSample(); |
136 EXPECT_FALSE(iter_->SampleIsValid()); | 190 EXPECT_FALSE(iter_->IsSampleValid()); |
137 | 191 |
138 // Test last sample of next run | 192 // Test last sample of next run |
139 iter_->AdvanceRun(); | 193 iter_->AdvanceRun(); |
140 EXPECT_TRUE(iter_->is_keyframe()); | 194 EXPECT_TRUE(iter_->is_keyframe()); |
141 for (int i = 0; i < 9; i++) iter_->AdvanceSample(); | 195 for (int i = 0; i < 9; i++) iter_->AdvanceSample(); |
142 EXPECT_EQ(iter_->track_id(), 2u); | 196 EXPECT_EQ(iter_->track_id(), 2u); |
143 EXPECT_EQ(iter_->sample_offset(), 200 + kSumAscending1); | 197 EXPECT_EQ(iter_->sample_offset(), 200 + kSumAscending1); |
144 EXPECT_EQ(iter_->sample_size(), 10); | 198 EXPECT_EQ(iter_->sample_size(), 10); |
145 int64 base_dts = kSumAscending1 + moof.tracks[1].decode_time.decode_time; | 199 int64 base_dts = kSumAscending1 + moof.tracks[1].decode_time.decode_time; |
146 EXPECT_EQ(iter_->dts(), TimeDeltaFromFrac(base_dts, kVideoScale)); | 200 EXPECT_EQ(iter_->dts(), TimeDeltaFromRational(base_dts, kVideoScale)); |
147 EXPECT_EQ(iter_->duration(), TimeDeltaFromFrac(10, kVideoScale)); | 201 EXPECT_EQ(iter_->duration(), TimeDeltaFromRational(10, kVideoScale)); |
148 EXPECT_FALSE(iter_->is_keyframe()); | 202 EXPECT_FALSE(iter_->is_keyframe()); |
149 | 203 |
150 // Test final run | 204 // Test final run |
151 iter_->AdvanceRun(); | 205 iter_->AdvanceRun(); |
152 EXPECT_EQ(iter_->track_id(), 1u); | 206 EXPECT_EQ(iter_->track_id(), 1u); |
153 EXPECT_EQ(iter_->dts(), TimeDeltaFromFrac(1024 * 10, kAudioScale)); | 207 EXPECT_EQ(iter_->dts(), TimeDeltaFromRational(1024 * 10, kAudioScale)); |
154 iter_->AdvanceSample(); | 208 iter_->AdvanceSample(); |
155 EXPECT_EQ(moof.tracks[0].runs[1].data_offset + | 209 EXPECT_EQ(moof.tracks[0].runs[1].data_offset + |
156 moof.tracks[0].header.default_sample_size, | 210 moof.tracks[0].header.default_sample_size, |
157 iter_->sample_offset()); | 211 iter_->sample_offset()); |
158 iter_->AdvanceRun(); | 212 iter_->AdvanceRun(); |
159 EXPECT_FALSE(iter_->RunIsValid()); | 213 EXPECT_FALSE(iter_->IsRunValid()); |
160 } | 214 } |
161 | 215 |
162 TEST_F(TrackRunIteratorTest, TrackExtendsDefaultsTest) { | 216 TEST_F(TrackRunIteratorTest, TrackExtendsDefaultsTest) { |
163 moov_.extends.tracks[0].default_sample_duration = 50; | 217 moov_.extends.tracks[0].default_sample_duration = 50; |
164 moov_.extends.tracks[0].default_sample_size = 3; | 218 moov_.extends.tracks[0].default_sample_size = 3; |
165 moov_.extends.tracks[0].default_sample_flags = | 219 moov_.extends.tracks[0].default_sample_flags = |
166 kSampleIsDifferenceSampleFlagMask; | 220 kSampleIsDifferenceSampleFlagMask; |
167 iter_.reset(new TrackRunIterator(&moov_)); | 221 iter_.reset(new TrackRunIterator(&moov_)); |
168 MovieFragment moof = CreateFragment(); | 222 MovieFragment moof = CreateFragment(); |
169 moof.tracks[0].header.has_default_sample_flags = false; | 223 moof.tracks[0].header.has_default_sample_flags = false; |
170 moof.tracks[0].header.default_sample_size = 0; | 224 moof.tracks[0].header.default_sample_size = 0; |
171 moof.tracks[0].header.default_sample_duration = 0; | 225 moof.tracks[0].header.default_sample_duration = 0; |
172 moof.tracks[0].runs[0].sample_sizes.clear(); | 226 moof.tracks[0].runs[0].sample_sizes.clear(); |
173 ASSERT_TRUE(iter_->Init(moof)); | 227 ASSERT_TRUE(iter_->Init(moof)); |
174 iter_->AdvanceSample(); | 228 iter_->AdvanceSample(); |
175 EXPECT_FALSE(iter_->is_keyframe()); | 229 EXPECT_FALSE(iter_->is_keyframe()); |
176 EXPECT_EQ(iter_->sample_size(), 3); | 230 EXPECT_EQ(iter_->sample_size(), 3); |
177 EXPECT_EQ(iter_->sample_offset(), moof.tracks[0].runs[0].data_offset + 3); | 231 EXPECT_EQ(iter_->sample_offset(), moof.tracks[0].runs[0].data_offset + 3); |
178 EXPECT_EQ(iter_->duration(), TimeDeltaFromFrac(50, kAudioScale)); | 232 EXPECT_EQ(iter_->duration(), TimeDeltaFromRational(50, kAudioScale)); |
179 EXPECT_EQ(iter_->dts(), TimeDeltaFromFrac(50, kAudioScale)); | 233 EXPECT_EQ(iter_->dts(), TimeDeltaFromRational(50, kAudioScale)); |
180 } | 234 } |
181 | 235 |
182 TEST_F(TrackRunIteratorTest, FirstSampleFlagTest) { | 236 TEST_F(TrackRunIteratorTest, FirstSampleFlagTest) { |
183 // Ensure that keyframes are flagged correctly in the face of BMFF boxes which | 237 // Ensure that keyframes are flagged correctly in the face of BMFF boxes which |
184 // explicitly specify the flags for the first sample in a run and rely on | 238 // explicitly specify the flags for the first sample in a run and rely on |
185 // defaults for all subsequent samples | 239 // defaults for all subsequent samples |
186 iter_.reset(new TrackRunIterator(&moov_)); | 240 iter_.reset(new TrackRunIterator(&moov_)); |
187 MovieFragment moof = CreateFragment(); | 241 MovieFragment moof = CreateFragment(); |
188 moof.tracks[1].header.has_default_sample_flags = true; | 242 moof.tracks[1].header.has_default_sample_flags = true; |
189 moof.tracks[1].header.default_sample_flags = | 243 moof.tracks[1].header.default_sample_flags = |
190 kSampleIsDifferenceSampleFlagMask; | 244 kSampleIsDifferenceSampleFlagMask; |
191 moof.tracks[1].runs[0].sample_flags.resize(1); | 245 moof.tracks[1].runs[0].sample_flags.resize(1); |
192 ASSERT_TRUE(iter_->Init(moof)); | 246 ASSERT_TRUE(iter_->Init(moof)); |
193 iter_->AdvanceRun(); | 247 iter_->AdvanceRun(); |
194 EXPECT_TRUE(iter_->is_keyframe()); | 248 EXPECT_TRUE(iter_->is_keyframe()); |
195 iter_->AdvanceSample(); | 249 iter_->AdvanceSample(); |
196 EXPECT_FALSE(iter_->is_keyframe()); | 250 EXPECT_FALSE(iter_->is_keyframe()); |
197 } | 251 } |
198 | 252 |
199 TEST_F(TrackRunIteratorTest, MinDecodeTest) { | 253 TEST_F(TrackRunIteratorTest, MinDecodeTest) { |
200 iter_.reset(new TrackRunIterator(&moov_)); | 254 iter_.reset(new TrackRunIterator(&moov_)); |
201 MovieFragment moof = CreateFragment(); | 255 MovieFragment moof = CreateFragment(); |
202 moof.tracks[0].decode_time.decode_time = kAudioScale; | 256 moof.tracks[0].decode_time.decode_time = kAudioScale; |
203 ASSERT_TRUE(iter_->Init(moof)); | 257 ASSERT_TRUE(iter_->Init(moof)); |
204 EXPECT_EQ(TimeDeltaFromFrac(moof.tracks[1].decode_time.decode_time, | 258 EXPECT_EQ(TimeDeltaFromRational(moof.tracks[1].decode_time.decode_time, |
205 kVideoScale), | 259 kVideoScale), |
206 iter_->GetMinDecodeTimestamp()); | 260 iter_->GetMinDecodeTimestamp()); |
207 } | 261 } |
208 | 262 |
209 TEST_F(TrackRunIteratorTest, ReorderingTest) { | 263 TEST_F(TrackRunIteratorTest, ReorderingTest) { |
210 iter_.reset(new TrackRunIterator(&moov_)); | 264 iter_.reset(new TrackRunIterator(&moov_)); |
211 MovieFragment moof = CreateFragment(); | 265 MovieFragment moof = CreateFragment(); |
212 std::vector<int32>& cts_offsets = | 266 std::vector<int32>& cts_offsets = |
213 moof.tracks[1].runs[0].sample_composition_time_offsets; | 267 moof.tracks[1].runs[0].sample_composition_time_offsets; |
214 cts_offsets.resize(10); | 268 cts_offsets.resize(10); |
215 cts_offsets[0] = 2; | 269 cts_offsets[0] = 2; |
216 cts_offsets[1] = -1; | 270 cts_offsets[1] = -1; |
217 moof.tracks[1].decode_time.decode_time = 0; | 271 moof.tracks[1].decode_time.decode_time = 0; |
218 ASSERT_TRUE(iter_->Init(moof)); | 272 ASSERT_TRUE(iter_->Init(moof)); |
219 iter_->AdvanceRun(); | 273 iter_->AdvanceRun(); |
220 EXPECT_EQ(iter_->dts(), TimeDeltaFromFrac(0, kVideoScale)); | 274 EXPECT_EQ(iter_->dts(), TimeDeltaFromRational(0, kVideoScale)); |
221 EXPECT_EQ(iter_->cts(), TimeDeltaFromFrac(2, kVideoScale)); | 275 EXPECT_EQ(iter_->cts(), TimeDeltaFromRational(2, kVideoScale)); |
222 EXPECT_EQ(iter_->duration(), TimeDeltaFromFrac(1, kVideoScale)); | 276 EXPECT_EQ(iter_->duration(), TimeDeltaFromRational(1, kVideoScale)); |
223 iter_->AdvanceSample(); | 277 iter_->AdvanceSample(); |
224 EXPECT_EQ(iter_->dts(), TimeDeltaFromFrac(1, kVideoScale)); | 278 EXPECT_EQ(iter_->dts(), TimeDeltaFromRational(1, kVideoScale)); |
225 EXPECT_EQ(iter_->cts(), TimeDeltaFromFrac(0, kVideoScale)); | 279 EXPECT_EQ(iter_->cts(), TimeDeltaFromRational(0, kVideoScale)); |
226 EXPECT_EQ(iter_->duration(), TimeDeltaFromFrac(2, kVideoScale)); | 280 EXPECT_EQ(iter_->duration(), TimeDeltaFromRational(2, kVideoScale)); |
281 } | |
282 | |
283 TEST_F(TrackRunIteratorTest, IgnoreUnknownAuxInfoTest) { | |
284 iter_.reset(new TrackRunIterator(&moov_)); | |
285 MovieFragment moof = CreateFragment(); | |
286 moof.tracks[1].auxiliary_offset.offsets.push_back(50); | |
287 moof.tracks[1].auxiliary_size.default_sample_info_size = 2; | |
288 moof.tracks[1].auxiliary_size.sample_count = 2; | |
289 moof.tracks[1].runs[0].sample_count = 2; | |
290 ASSERT_TRUE(iter_->Init(moof)); | |
291 iter_->AdvanceRun(); | |
292 EXPECT_FALSE(iter_->AuxInfoNeedsToBeCached()); | |
293 } | |
294 | |
295 TEST_F(TrackRunIteratorTest, DecryptConfigTest) { | |
296 AddEncryption(&moov_.tracks[1]); | |
297 iter_.reset(new TrackRunIterator(&moov_)); | |
298 | |
299 MovieFragment moof = CreateFragment(); | |
300 AddAuxInfoHeaders(50, &moof.tracks[1]); | |
301 | |
302 ASSERT_TRUE(iter_->Init(moof)); | |
303 | |
304 // The run for track 2 will be first, since its aux info offset is the first | |
305 // element in the file. | |
306 EXPECT_EQ(iter_->track_id(), 2u); | |
307 EXPECT_TRUE(iter_->is_encrypted()); | |
308 EXPECT_TRUE(iter_->AuxInfoNeedsToBeCached()); | |
309 EXPECT_EQ(static_cast<uint32>(iter_->aux_info_size()), arraysize(kAuxInfo)); | |
310 EXPECT_EQ(iter_->aux_info_offset(), 50); | |
311 EXPECT_EQ(iter_->GetMaxClearOffset(), 50); | |
312 EXPECT_FALSE(iter_->CacheAuxInfo(NULL, 0)); | |
313 EXPECT_FALSE(iter_->CacheAuxInfo(kAuxInfo, 3)); | |
314 EXPECT_TRUE(iter_->AuxInfoNeedsToBeCached()); | |
315 EXPECT_TRUE(iter_->CacheAuxInfo(kAuxInfo, arraysize(kAuxInfo))); | |
316 EXPECT_FALSE(iter_->AuxInfoNeedsToBeCached()); | |
317 EXPECT_EQ(iter_->sample_offset(), 200); | |
318 EXPECT_EQ(iter_->GetMaxClearOffset(), moof.tracks[0].runs[0].data_offset); | |
319 scoped_ptr<DecryptConfig> config = iter_->GetDecryptConfig(); | |
320 ASSERT_EQ(arraysize(kKeyId), config->key_id().size()); | |
321 EXPECT_TRUE(!memcmp(kKeyId, config->key_id().data(), | |
322 config->key_id().size())); | |
323 ASSERT_EQ(arraysize(kIv1), config->iv().size()); | |
324 EXPECT_TRUE(!memcmp(kIv1, config->iv().data(), config->iv().size())); | |
325 EXPECT_TRUE(config->subsamples().empty()); | |
326 iter_->AdvanceSample(); | |
327 config = iter_->GetDecryptConfig(); | |
328 EXPECT_EQ(config->subsamples().size(), 2u); | |
329 EXPECT_EQ(config->subsamples()[0].clear_bytes, 1u); | |
330 EXPECT_EQ(config->subsamples()[1].cypher_bytes, 4u); | |
331 } | |
332 | |
333 // It is legal for aux info blocks to be shared among multiple formats. | |
334 TEST_F(TrackRunIteratorTest, SharedAuxInfoTest) { | |
335 AddEncryption(&moov_.tracks[0]); | |
336 AddEncryption(&moov_.tracks[1]); | |
337 iter_.reset(new TrackRunIterator(&moov_)); | |
338 | |
339 MovieFragment moof = CreateFragment(); | |
340 moof.tracks[0].runs.resize(1); | |
341 AddAuxInfoHeaders(50, &moof.tracks[0]); | |
342 AddAuxInfoHeaders(50, &moof.tracks[1]); | |
343 moof.tracks[0].auxiliary_size.default_sample_info_size = 8; | |
344 | |
345 ASSERT_TRUE(iter_->Init(moof)); | |
346 EXPECT_EQ(iter_->track_id(), 1u); | |
347 EXPECT_EQ(iter_->aux_info_offset(), 50); | |
348 EXPECT_TRUE(iter_->CacheAuxInfo(kAuxInfo, arraysize(kAuxInfo))); | |
349 scoped_ptr<DecryptConfig> config = iter_->GetDecryptConfig(); | |
350 ASSERT_EQ(arraysize(kIv1), config->iv().size()); | |
351 EXPECT_TRUE(!memcmp(kIv1, config->iv().data(), config->iv().size())); | |
352 iter_->AdvanceSample(); | |
353 EXPECT_EQ(iter_->GetMaxClearOffset(), 50); | |
354 iter_->AdvanceRun(); | |
355 EXPECT_EQ(iter_->GetMaxClearOffset(), 50); | |
356 EXPECT_EQ(iter_->aux_info_offset(), 50); | |
357 EXPECT_TRUE(iter_->CacheAuxInfo(kAuxInfo, arraysize(kAuxInfo))); | |
358 EXPECT_EQ(iter_->GetMaxClearOffset(), 200); | |
359 ASSERT_EQ(arraysize(kIv1), config->iv().size()); | |
360 EXPECT_TRUE(!memcmp(kIv1, config->iv().data(), config->iv().size())); | |
361 iter_->AdvanceSample(); | |
362 EXPECT_EQ(iter_->GetMaxClearOffset(), 201); | |
363 } | |
364 | |
365 | |
366 // Sensible files are expected to place auxiliary information for a run | |
367 // immediately before the main data for that run. Alternative schemes are | |
368 // possible, however, including the somewhat reasonable behavior of placing all | |
369 // aux info at the head of the 'mdat' box together, and the completely | |
370 // unreasonable behavior demonstrated here: | |
371 // byte 50: track 2, run 1 aux info | |
372 // byte 100: track 1, run 1 data | |
373 // byte 200: track 2, run 1 data | |
374 // byte 201: track 1, run 2 aux info (*inside* track 2, run 1 data) | |
375 // byte 10000: track 1, run 2 data | |
376 // byte 20000: track 1, run 1 aux info | |
377 TEST_F(TrackRunIteratorTest, PathologicalOrderingTest) { | |
ddorwin
2012/07/25 07:13:47
Pathological isn't very descriptive of ordering. "
strobe_
2012/07/25 21:12:36
Done.
| |
378 AddEncryption(&moov_.tracks[0]); | |
379 AddEncryption(&moov_.tracks[1]); | |
380 iter_.reset(new TrackRunIterator(&moov_)); | |
381 | |
382 MovieFragment moof = CreateFragment(); | |
383 AddAuxInfoHeaders(20000, &moof.tracks[0]); | |
384 moof.tracks[0].auxiliary_offset.offsets.push_back(201); | |
385 moof.tracks[0].auxiliary_size.sample_count += 2; | |
386 moof.tracks[0].auxiliary_size.default_sample_info_size = 8; | |
387 moof.tracks[0].runs[1].sample_count = 2; | |
388 AddAuxInfoHeaders(50, &moof.tracks[1]); | |
389 moof.tracks[1].runs[0].sample_sizes[0] = 5; | |
390 | |
391 ASSERT_TRUE(iter_->Init(moof)); | |
392 EXPECT_EQ(iter_->track_id(), 2u); | |
393 EXPECT_EQ(iter_->aux_info_offset(), 50); | |
394 EXPECT_EQ(iter_->sample_offset(), 200); | |
395 EXPECT_TRUE(iter_->CacheAuxInfo(kAuxInfo, arraysize(kAuxInfo))); | |
396 EXPECT_EQ(iter_->GetMaxClearOffset(), 100); | |
397 iter_->AdvanceRun(); | |
398 EXPECT_EQ(iter_->track_id(), 1u); | |
399 EXPECT_EQ(iter_->aux_info_offset(), 20000); | |
400 EXPECT_EQ(iter_->sample_offset(), 100); | |
401 EXPECT_TRUE(iter_->CacheAuxInfo(kAuxInfo, arraysize(kAuxInfo))); | |
402 EXPECT_EQ(iter_->GetMaxClearOffset(), 100); | |
403 iter_->AdvanceSample(); | |
404 EXPECT_EQ(iter_->GetMaxClearOffset(), 101); | |
405 iter_->AdvanceRun(); | |
406 EXPECT_EQ(iter_->track_id(), 1u); | |
407 EXPECT_EQ(iter_->aux_info_offset(), 201); | |
408 EXPECT_EQ(iter_->sample_offset(), 10000); | |
409 EXPECT_EQ(iter_->GetMaxClearOffset(), 201); | |
410 EXPECT_TRUE(iter_->CacheAuxInfo(kAuxInfo, arraysize(kAuxInfo))); | |
411 EXPECT_EQ(iter_->GetMaxClearOffset(), 10000); | |
227 } | 412 } |
228 | 413 |
229 } // namespace mp4 | 414 } // namespace mp4 |
230 } // namespace media | 415 } // namespace media |
OLD | NEW |