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 <algorithm> | 5 #include <algorithm> |
6 #include <string> | 6 #include <string> |
7 | 7 |
8 #include "base/bind.h" | 8 #include "base/bind.h" |
9 #include "base/bind_helpers.h" | 9 #include "base/bind_helpers.h" |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
11 #include "base/memory/ref_counted.h" | 11 #include "base/memory/ref_counted.h" |
12 #include "base/time/time.h" | 12 #include "base/time/time.h" |
13 #include "media/base/audio_decoder_config.h" | 13 #include "media/base/audio_decoder_config.h" |
14 #include "media/base/decoder_buffer.h" | 14 #include "media/base/decoder_buffer.h" |
15 #include "media/base/mock_media_log.h" | |
16 #include "media/base/stream_parser_buffer.h" | 15 #include "media/base/stream_parser_buffer.h" |
17 #include "media/base/test_data_util.h" | 16 #include "media/base/test_data_util.h" |
18 #include "media/base/text_track_config.h" | 17 #include "media/base/text_track_config.h" |
19 #include "media/base/video_decoder_config.h" | 18 #include "media/base/video_decoder_config.h" |
20 #include "media/formats/mp4/es_descriptor.h" | 19 #include "media/formats/mp4/es_descriptor.h" |
21 #include "media/formats/mp4/mp4_stream_parser.h" | 20 #include "media/formats/mp4/mp4_stream_parser.h" |
22 #include "testing/gmock/include/gmock/gmock.h" | |
23 #include "testing/gtest/include/gtest/gtest.h" | 21 #include "testing/gtest/include/gtest/gtest.h" |
24 | 22 |
25 using ::testing::InSequence; | |
26 using ::testing::StrictMock; | |
27 using base::TimeDelta; | 23 using base::TimeDelta; |
28 | 24 |
29 namespace media { | 25 namespace media { |
30 namespace mp4 { | 26 namespace mp4 { |
31 | 27 |
32 // Matchers for verifying common media log entry strings. | |
33 MATCHER_P(VideoCodecLog, codec_string, "") { | |
34 return CONTAINS_STRING(arg, "Video codec: " + std::string(codec_string)); | |
35 } | |
36 | |
37 MATCHER_P(AudioCodecLog, codec_string, "") { | |
38 return CONTAINS_STRING(arg, "Audio codec: " + std::string(codec_string)); | |
39 } | |
40 | |
41 MATCHER(AuxInfoUnavailableLog, "") { | |
42 return CONTAINS_STRING(arg, "Aux Info is not available."); | |
43 } | |
44 | |
45 class MP4StreamParserTest : public testing::Test { | 28 class MP4StreamParserTest : public testing::Test { |
46 public: | 29 public: |
47 MP4StreamParserTest() | 30 MP4StreamParserTest() |
48 : media_log_(new StrictMock<MockMediaLog>()), | 31 : configs_received_(false), |
49 configs_received_(false), | |
50 lower_bound_( | 32 lower_bound_( |
51 DecodeTimestamp::FromPresentationTime(base::TimeDelta::Max())) { | 33 DecodeTimestamp::FromPresentationTime(base::TimeDelta::Max())) { |
52 std::set<int> audio_object_types; | 34 std::set<int> audio_object_types; |
53 audio_object_types.insert(kISO_14496_3); | 35 audio_object_types.insert(kISO_14496_3); |
54 parser_.reset(new MP4StreamParser(audio_object_types, false)); | 36 parser_.reset(new MP4StreamParser(audio_object_types, false)); |
55 } | 37 } |
56 | 38 |
57 protected: | 39 protected: |
58 scoped_refptr<StrictMock<MockMediaLog>> media_log_; | |
59 scoped_ptr<MP4StreamParser> parser_; | 40 scoped_ptr<MP4StreamParser> parser_; |
60 bool configs_received_; | 41 bool configs_received_; |
61 AudioDecoderConfig audio_decoder_config_; | 42 AudioDecoderConfig audio_decoder_config_; |
62 VideoDecoderConfig video_decoder_config_; | 43 VideoDecoderConfig video_decoder_config_; |
63 DecodeTimestamp lower_bound_; | 44 DecodeTimestamp lower_bound_; |
64 | 45 |
65 bool AppendData(const uint8* data, size_t length) { | 46 bool AppendData(const uint8* data, size_t length) { |
66 return parser_->Parse(data, length); | 47 return parser_->Parse(data, length); |
67 } | 48 } |
68 | 49 |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
161 DemuxerStream::Liveness expected_liveness) { | 142 DemuxerStream::Liveness expected_liveness) { |
162 parser_->Init( | 143 parser_->Init( |
163 base::Bind(&MP4StreamParserTest::InitF, base::Unretained(this), | 144 base::Bind(&MP4StreamParserTest::InitF, base::Unretained(this), |
164 expected_liveness), | 145 expected_liveness), |
165 base::Bind(&MP4StreamParserTest::NewConfigF, base::Unretained(this)), | 146 base::Bind(&MP4StreamParserTest::NewConfigF, base::Unretained(this)), |
166 base::Bind(&MP4StreamParserTest::NewBuffersF, base::Unretained(this)), | 147 base::Bind(&MP4StreamParserTest::NewBuffersF, base::Unretained(this)), |
167 true, | 148 true, |
168 base::Bind(&MP4StreamParserTest::KeyNeededF, base::Unretained(this)), | 149 base::Bind(&MP4StreamParserTest::KeyNeededF, base::Unretained(this)), |
169 base::Bind(&MP4StreamParserTest::NewSegmentF, base::Unretained(this)), | 150 base::Bind(&MP4StreamParserTest::NewSegmentF, base::Unretained(this)), |
170 base::Bind(&MP4StreamParserTest::EndOfSegmentF, base::Unretained(this)), | 151 base::Bind(&MP4StreamParserTest::EndOfSegmentF, base::Unretained(this)), |
171 media_log_); | 152 new MediaLog()); |
172 } | 153 } |
173 | 154 |
174 void InitializeParser() { | 155 void InitializeParser() { |
175 // Most unencrypted test mp4 files have zero duration and are treated as | 156 // Most unencrypted test mp4 files have zero duration and are treated as |
176 // live streams. | 157 // live streams. |
177 InitializeParserAndExpectLiveness(DemuxerStream::LIVENESS_LIVE); | 158 InitializeParserAndExpectLiveness(DemuxerStream::LIVENESS_LIVE); |
178 } | 159 } |
179 | 160 |
180 bool ParseMP4File(const std::string& filename, int append_bytes) { | 161 bool ParseMP4File(const std::string& filename, int append_bytes) { |
181 InitializeParser(); | 162 InitializeParser(); |
182 | 163 |
183 scoped_refptr<DecoderBuffer> buffer = ReadTestDataFile(filename); | 164 scoped_refptr<DecoderBuffer> buffer = ReadTestDataFile(filename); |
184 EXPECT_TRUE(AppendDataInPieces(buffer->data(), | 165 EXPECT_TRUE(AppendDataInPieces(buffer->data(), |
185 buffer->data_size(), | 166 buffer->data_size(), |
186 append_bytes)); | 167 append_bytes)); |
187 return true; | 168 return true; |
188 } | 169 } |
189 }; | 170 }; |
190 | 171 |
191 TEST_F(MP4StreamParserTest, UnalignedAppend) { | 172 TEST_F(MP4StreamParserTest, UnalignedAppend) { |
192 // Test small, non-segment-aligned appends (small enough to exercise | 173 // Test small, non-segment-aligned appends (small enough to exercise |
193 // incremental append system) | 174 // incremental append system) |
194 EXPECT_MEDIA_LOG(VideoCodecLog("avc1.6401f")); | |
195 EXPECT_MEDIA_LOG(AudioCodecLog("mp4a.40.2")); | |
196 ParseMP4File("bear-1280x720-av_frag.mp4", 512); | 175 ParseMP4File("bear-1280x720-av_frag.mp4", 512); |
197 } | 176 } |
198 | 177 |
199 TEST_F(MP4StreamParserTest, BytewiseAppend) { | 178 TEST_F(MP4StreamParserTest, BytewiseAppend) { |
200 // Ensure no incremental errors occur when parsing | 179 // Ensure no incremental errors occur when parsing |
201 EXPECT_MEDIA_LOG(VideoCodecLog("avc1.6401f")); | |
202 EXPECT_MEDIA_LOG(AudioCodecLog("mp4a.40.2")); | |
203 ParseMP4File("bear-1280x720-av_frag.mp4", 1); | 180 ParseMP4File("bear-1280x720-av_frag.mp4", 1); |
204 } | 181 } |
205 | 182 |
206 TEST_F(MP4StreamParserTest, MultiFragmentAppend) { | 183 TEST_F(MP4StreamParserTest, MultiFragmentAppend) { |
207 // Large size ensures multiple fragments are appended in one call (size is | 184 // Large size ensures multiple fragments are appended in one call (size is |
208 // larger than this particular test file) | 185 // larger than this particular test file) |
209 EXPECT_MEDIA_LOG(VideoCodecLog("avc1.6401f")); | |
210 EXPECT_MEDIA_LOG(AudioCodecLog("mp4a.40.2")); | |
211 ParseMP4File("bear-1280x720-av_frag.mp4", 768432); | 186 ParseMP4File("bear-1280x720-av_frag.mp4", 768432); |
212 } | 187 } |
213 | 188 |
214 TEST_F(MP4StreamParserTest, Flush) { | 189 TEST_F(MP4StreamParserTest, Flush) { |
215 // Flush while reading sample data, then start a new stream. | 190 // Flush while reading sample data, then start a new stream. |
216 EXPECT_MEDIA_LOG(VideoCodecLog("avc1.6401f")).Times(2); | |
217 EXPECT_MEDIA_LOG(AudioCodecLog("mp4a.40.2")).Times(2); | |
218 InitializeParser(); | 191 InitializeParser(); |
219 | 192 |
220 scoped_refptr<DecoderBuffer> buffer = | 193 scoped_refptr<DecoderBuffer> buffer = |
221 ReadTestDataFile("bear-1280x720-av_frag.mp4"); | 194 ReadTestDataFile("bear-1280x720-av_frag.mp4"); |
222 EXPECT_TRUE(AppendDataInPieces(buffer->data(), 65536, 512)); | 195 EXPECT_TRUE(AppendDataInPieces(buffer->data(), 65536, 512)); |
223 parser_->Flush(); | 196 parser_->Flush(); |
224 EXPECT_TRUE(AppendDataInPieces(buffer->data(), | 197 EXPECT_TRUE(AppendDataInPieces(buffer->data(), |
225 buffer->data_size(), | 198 buffer->data_size(), |
226 512)); | 199 512)); |
227 } | 200 } |
228 | 201 |
229 TEST_F(MP4StreamParserTest, Reinitialization) { | 202 TEST_F(MP4StreamParserTest, Reinitialization) { |
230 EXPECT_MEDIA_LOG(VideoCodecLog("avc1.6401f")).Times(2); | |
231 EXPECT_MEDIA_LOG(AudioCodecLog("mp4a.40.2")).Times(2); | |
232 InitializeParser(); | 203 InitializeParser(); |
233 | 204 |
234 scoped_refptr<DecoderBuffer> buffer = | 205 scoped_refptr<DecoderBuffer> buffer = |
235 ReadTestDataFile("bear-1280x720-av_frag.mp4"); | 206 ReadTestDataFile("bear-1280x720-av_frag.mp4"); |
236 EXPECT_TRUE(AppendDataInPieces(buffer->data(), | 207 EXPECT_TRUE(AppendDataInPieces(buffer->data(), |
237 buffer->data_size(), | 208 buffer->data_size(), |
238 512)); | 209 512)); |
239 EXPECT_TRUE(AppendDataInPieces(buffer->data(), | 210 EXPECT_TRUE(AppendDataInPieces(buffer->data(), |
240 buffer->data_size(), | 211 buffer->data_size(), |
241 512)); | 212 512)); |
242 } | 213 } |
243 | 214 |
244 TEST_F(MP4StreamParserTest, MPEG2_AAC_LC) { | 215 TEST_F(MP4StreamParserTest, MPEG2_AAC_LC) { |
245 InSequence s; | |
246 std::set<int> audio_object_types; | 216 std::set<int> audio_object_types; |
247 audio_object_types.insert(kISO_13818_7_AAC_LC); | 217 audio_object_types.insert(kISO_13818_7_AAC_LC); |
248 parser_.reset(new MP4StreamParser(audio_object_types, false)); | 218 parser_.reset(new MP4StreamParser(audio_object_types, false)); |
249 EXPECT_MEDIA_LOG(AudioCodecLog("mp4a.67")); | |
250 EXPECT_MEDIA_LOG(AudioCodecLog("mp4a.40.2")); | |
251 ParseMP4File("bear-mpeg2-aac-only_frag.mp4", 512); | 219 ParseMP4File("bear-mpeg2-aac-only_frag.mp4", 512); |
252 } | 220 } |
253 | 221 |
254 // Test that a moov box is not always required after Flush() is called. | 222 // Test that a moov box is not always required after Flush() is called. |
255 TEST_F(MP4StreamParserTest, NoMoovAfterFlush) { | 223 TEST_F(MP4StreamParserTest, NoMoovAfterFlush) { |
256 EXPECT_MEDIA_LOG(VideoCodecLog("avc1.6401f")); | |
257 EXPECT_MEDIA_LOG(AudioCodecLog("mp4a.40.2")); | |
258 InitializeParser(); | 224 InitializeParser(); |
259 | 225 |
260 scoped_refptr<DecoderBuffer> buffer = | 226 scoped_refptr<DecoderBuffer> buffer = |
261 ReadTestDataFile("bear-1280x720-av_frag.mp4"); | 227 ReadTestDataFile("bear-1280x720-av_frag.mp4"); |
262 EXPECT_TRUE(AppendDataInPieces(buffer->data(), | 228 EXPECT_TRUE(AppendDataInPieces(buffer->data(), |
263 buffer->data_size(), | 229 buffer->data_size(), |
264 512)); | 230 512)); |
265 parser_->Flush(); | 231 parser_->Flush(); |
266 | 232 |
267 const int kFirstMoofOffset = 1307; | 233 const int kFirstMoofOffset = 1307; |
268 EXPECT_TRUE(AppendDataInPieces(buffer->data() + kFirstMoofOffset, | 234 EXPECT_TRUE(AppendDataInPieces(buffer->data() + kFirstMoofOffset, |
269 buffer->data_size() - kFirstMoofOffset, | 235 buffer->data_size() - kFirstMoofOffset, |
270 512)); | 236 512)); |
271 } | 237 } |
272 | 238 |
273 // Test an invalid file where there are encrypted samples, but | 239 // Test an invalid file where there are encrypted samples, but |
274 // SampleAuxiliaryInformation{Sizes|Offsets}Box (saiz|saio) are missing. | 240 // SampleAuxiliaryInformation{Sizes|Offsets}Box (saiz|saio) are missing. |
275 // The parser should fail instead of crash. See http://crbug.com/361347 | 241 // The parser should fail instead of crash. See http://crbug.com/361347 |
276 TEST_F(MP4StreamParserTest, MissingSampleAuxInfo) { | 242 TEST_F(MP4StreamParserTest, MissingSampleAuxInfo) { |
277 InSequence s; | |
278 | |
279 // Encrypted test mp4 files have non-zero duration and are treated as | 243 // Encrypted test mp4 files have non-zero duration and are treated as |
280 // recorded streams. | 244 // recorded streams. |
281 InitializeParserAndExpectLiveness(DemuxerStream::LIVENESS_RECORDED); | 245 InitializeParserAndExpectLiveness(DemuxerStream::LIVENESS_RECORDED); |
282 | 246 |
283 scoped_refptr<DecoderBuffer> buffer = | 247 scoped_refptr<DecoderBuffer> buffer = |
284 ReadTestDataFile("bear-1280x720-a_frag-cenc_missing-saiz-saio.mp4"); | 248 ReadTestDataFile("bear-1280x720-a_frag-cenc_missing-saiz-saio.mp4"); |
285 EXPECT_MEDIA_LOG(AudioCodecLog("mp4a.40.2")).Times(2); | |
286 EXPECT_MEDIA_LOG(AuxInfoUnavailableLog()); | |
287 EXPECT_FALSE(AppendDataInPieces(buffer->data(), buffer->data_size(), 512)); | 249 EXPECT_FALSE(AppendDataInPieces(buffer->data(), buffer->data_size(), 512)); |
288 } | 250 } |
289 | 251 |
290 // Test a file where all video samples start with an Access Unit | 252 // Test a file where all video samples start with an Access Unit |
291 // Delimiter (AUD) NALU. | 253 // Delimiter (AUD) NALU. |
292 TEST_F(MP4StreamParserTest, VideoSamplesStartWithAUDs) { | 254 TEST_F(MP4StreamParserTest, VideoSamplesStartWithAUDs) { |
293 EXPECT_MEDIA_LOG(VideoCodecLog("avc1.4d4028")); | |
294 ParseMP4File("bear-1280x720-av_with-aud-nalus_frag.mp4", 512); | 255 ParseMP4File("bear-1280x720-av_with-aud-nalus_frag.mp4", 512); |
295 } | 256 } |
296 | 257 |
297 TEST_F(MP4StreamParserTest, CENC) { | 258 TEST_F(MP4StreamParserTest, CENC) { |
298 // Encrypted test mp4 files have non-zero duration and are treated as | 259 // Encrypted test mp4 files have non-zero duration and are treated as |
299 // recorded streams. | 260 // recorded streams. |
300 InitializeParserAndExpectLiveness(DemuxerStream::LIVENESS_RECORDED); | 261 InitializeParserAndExpectLiveness(DemuxerStream::LIVENESS_RECORDED); |
301 | 262 |
302 scoped_refptr<DecoderBuffer> buffer = | 263 scoped_refptr<DecoderBuffer> buffer = |
303 ReadTestDataFile("bear-1280x720-v_frag-cenc.mp4"); | 264 ReadTestDataFile("bear-1280x720-v_frag-cenc.mp4"); |
304 EXPECT_MEDIA_LOG(VideoCodecLog("avc1.6401f")); | |
305 EXPECT_TRUE(AppendDataInPieces(buffer->data(), buffer->data_size(), 512)); | 265 EXPECT_TRUE(AppendDataInPieces(buffer->data(), buffer->data_size(), 512)); |
306 } | 266 } |
307 | 267 |
308 TEST_F(MP4StreamParserTest, NaturalSizeWithoutPASP) { | 268 TEST_F(MP4StreamParserTest, NaturalSizeWithoutPASP) { |
309 InitializeParserAndExpectLiveness(DemuxerStream::LIVENESS_RECORDED); | 269 InitializeParserAndExpectLiveness(DemuxerStream::LIVENESS_RECORDED); |
310 | 270 |
311 scoped_refptr<DecoderBuffer> buffer = | 271 scoped_refptr<DecoderBuffer> buffer = |
312 ReadTestDataFile("bear-640x360-non_square_pixel-without_pasp.mp4"); | 272 ReadTestDataFile("bear-640x360-non_square_pixel-without_pasp.mp4"); |
313 | 273 |
314 EXPECT_MEDIA_LOG(VideoCodecLog("avc1.6401e")); | |
315 EXPECT_TRUE(AppendDataInPieces(buffer->data(), buffer->data_size(), 512)); | 274 EXPECT_TRUE(AppendDataInPieces(buffer->data(), buffer->data_size(), 512)); |
316 EXPECT_EQ(gfx::Size(639, 360), video_decoder_config_.natural_size()); | 275 EXPECT_EQ(gfx::Size(639, 360), video_decoder_config_.natural_size()); |
317 } | 276 } |
318 | 277 |
319 TEST_F(MP4StreamParserTest, NaturalSizeWithPASP) { | 278 TEST_F(MP4StreamParserTest, NaturalSizeWithPASP) { |
320 InitializeParserAndExpectLiveness(DemuxerStream::LIVENESS_RECORDED); | 279 InitializeParserAndExpectLiveness(DemuxerStream::LIVENESS_RECORDED); |
321 | 280 |
322 scoped_refptr<DecoderBuffer> buffer = | 281 scoped_refptr<DecoderBuffer> buffer = |
323 ReadTestDataFile("bear-640x360-non_square_pixel-with_pasp.mp4"); | 282 ReadTestDataFile("bear-640x360-non_square_pixel-with_pasp.mp4"); |
324 | 283 |
325 EXPECT_MEDIA_LOG(VideoCodecLog("avc1.6401e")); | |
326 EXPECT_TRUE(AppendDataInPieces(buffer->data(), buffer->data_size(), 512)); | 284 EXPECT_TRUE(AppendDataInPieces(buffer->data(), buffer->data_size(), 512)); |
327 EXPECT_EQ(gfx::Size(639, 360), video_decoder_config_.natural_size()); | 285 EXPECT_EQ(gfx::Size(639, 360), video_decoder_config_.natural_size()); |
328 } | 286 } |
329 | 287 |
330 } // namespace mp4 | 288 } // namespace mp4 |
331 } // namespace media | 289 } // namespace media |
OLD | NEW |