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/webm/webm_cluster_parser.h" | 5 #include "media/formats/webm/webm_cluster_parser.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 #include <stdint.h> | 8 #include <stdint.h> |
9 | 9 |
10 #include <algorithm> | 10 #include <algorithm> |
(...skipping 300 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
311 parser_(CreateDefaultParser()) {} | 311 parser_(CreateDefaultParser()) {} |
312 | 312 |
313 protected: | 313 protected: |
314 void ResetParserToHaveDefaultDurations() { | 314 void ResetParserToHaveDefaultDurations() { |
315 base::TimeDelta default_audio_duration = base::TimeDelta::FromMilliseconds( | 315 base::TimeDelta default_audio_duration = base::TimeDelta::FromMilliseconds( |
316 kTestAudioFrameDefaultDurationInMs); | 316 kTestAudioFrameDefaultDurationInMs); |
317 base::TimeDelta default_video_duration = base::TimeDelta::FromMilliseconds( | 317 base::TimeDelta default_video_duration = base::TimeDelta::FromMilliseconds( |
318 kTestVideoFrameDefaultDurationInMs); | 318 kTestVideoFrameDefaultDurationInMs); |
319 ASSERT_GE(default_audio_duration, base::TimeDelta()); | 319 ASSERT_GE(default_audio_duration, base::TimeDelta()); |
320 ASSERT_GE(default_video_duration, base::TimeDelta()); | 320 ASSERT_GE(default_video_duration, base::TimeDelta()); |
321 ASSERT_NE(kNoTimestamp(), default_audio_duration); | 321 ASSERT_NE(kNoTimestamp, default_audio_duration); |
322 ASSERT_NE(kNoTimestamp(), default_video_duration); | 322 ASSERT_NE(kNoTimestamp, default_video_duration); |
323 | 323 |
324 parser_.reset(CreateParserWithDefaultDurationsAndOptionalTextTracks( | 324 parser_.reset(CreateParserWithDefaultDurationsAndOptionalTextTracks( |
325 default_audio_duration, default_video_duration)); | 325 default_audio_duration, default_video_duration)); |
326 } | 326 } |
327 | 327 |
328 // Helper that hard-codes some non-varying constructor parameters. | 328 // Helper that hard-codes some non-varying constructor parameters. |
329 WebMClusterParser* CreateParserHelper( | 329 WebMClusterParser* CreateParserHelper( |
330 base::TimeDelta audio_default_duration, | 330 base::TimeDelta audio_default_duration, |
331 base::TimeDelta video_default_duration, | 331 base::TimeDelta video_default_duration, |
332 const WebMTracksParser::TextTracks& text_tracks, | 332 const WebMTracksParser::TextTracks& text_tracks, |
333 const std::set<int64_t>& ignored_tracks, | 333 const std::set<int64_t>& ignored_tracks, |
334 const std::string& audio_encryption_key_id, | 334 const std::string& audio_encryption_key_id, |
335 const std::string& video_encryption_key_id, | 335 const std::string& video_encryption_key_id, |
336 const AudioCodec audio_codec) { | 336 const AudioCodec audio_codec) { |
337 return new WebMClusterParser( | 337 return new WebMClusterParser( |
338 kTimecodeScale, kAudioTrackNum, audio_default_duration, kVideoTrackNum, | 338 kTimecodeScale, kAudioTrackNum, audio_default_duration, kVideoTrackNum, |
339 video_default_duration, text_tracks, ignored_tracks, | 339 video_default_duration, text_tracks, ignored_tracks, |
340 audio_encryption_key_id, video_encryption_key_id, audio_codec, | 340 audio_encryption_key_id, video_encryption_key_id, audio_codec, |
341 media_log_); | 341 media_log_); |
342 } | 342 } |
343 | 343 |
344 // Create a default version of the parser for test. | 344 // Create a default version of the parser for test. |
345 WebMClusterParser* CreateDefaultParser() { | 345 WebMClusterParser* CreateDefaultParser() { |
346 return CreateParserHelper(kNoTimestamp(), kNoTimestamp(), TextTracks(), | 346 return CreateParserHelper(kNoTimestamp, kNoTimestamp, TextTracks(), |
347 std::set<int64_t>(), std::string(), std::string(), | 347 std::set<int64_t>(), std::string(), std::string(), |
348 kUnknownAudioCodec); | 348 kUnknownAudioCodec); |
349 } | 349 } |
350 | 350 |
351 // Create a parser for test with custom audio and video default durations, and | 351 // Create a parser for test with custom audio and video default durations, and |
352 // optionally custom text tracks. | 352 // optionally custom text tracks. |
353 WebMClusterParser* CreateParserWithDefaultDurationsAndOptionalTextTracks( | 353 WebMClusterParser* CreateParserWithDefaultDurationsAndOptionalTextTracks( |
354 base::TimeDelta audio_default_duration, | 354 base::TimeDelta audio_default_duration, |
355 base::TimeDelta video_default_duration, | 355 base::TimeDelta video_default_duration, |
356 const WebMTracksParser::TextTracks& text_tracks = TextTracks()) { | 356 const WebMTracksParser::TextTracks& text_tracks = TextTracks()) { |
357 return CreateParserHelper(audio_default_duration, video_default_duration, | 357 return CreateParserHelper(audio_default_duration, video_default_duration, |
358 text_tracks, std::set<int64_t>(), std::string(), | 358 text_tracks, std::set<int64_t>(), std::string(), |
359 std::string(), kUnknownAudioCodec); | 359 std::string(), kUnknownAudioCodec); |
360 } | 360 } |
361 | 361 |
362 // Create a parser for test with custom ignored tracks. | 362 // Create a parser for test with custom ignored tracks. |
363 WebMClusterParser* CreateParserWithIgnoredTracks( | 363 WebMClusterParser* CreateParserWithIgnoredTracks( |
364 std::set<int64_t>& ignored_tracks) { | 364 std::set<int64_t>& ignored_tracks) { |
365 return CreateParserHelper(kNoTimestamp(), kNoTimestamp(), TextTracks(), | 365 return CreateParserHelper(kNoTimestamp, kNoTimestamp, TextTracks(), |
366 ignored_tracks, std::string(), std::string(), | 366 ignored_tracks, std::string(), std::string(), |
367 kUnknownAudioCodec); | 367 kUnknownAudioCodec); |
368 } | 368 } |
369 | 369 |
370 // Create a parser for test with custom encryption key ids and audio codec. | 370 // Create a parser for test with custom encryption key ids and audio codec. |
371 WebMClusterParser* CreateParserWithKeyIdsAndAudioCodec( | 371 WebMClusterParser* CreateParserWithKeyIdsAndAudioCodec( |
372 const std::string& audio_encryption_key_id, | 372 const std::string& audio_encryption_key_id, |
373 const std::string& video_encryption_key_id, | 373 const std::string& video_encryption_key_id, |
374 const AudioCodec audio_codec) { | 374 const AudioCodec audio_codec) { |
375 return CreateParserHelper(kNoTimestamp(), kNoTimestamp(), TextTracks(), | 375 return CreateParserHelper(kNoTimestamp, kNoTimestamp, TextTracks(), |
376 std::set<int64_t>(), audio_encryption_key_id, | 376 std::set<int64_t>(), audio_encryption_key_id, |
377 video_encryption_key_id, audio_codec); | 377 video_encryption_key_id, audio_codec); |
378 } | 378 } |
379 | 379 |
380 scoped_refptr<StrictMock<MockMediaLog>> media_log_; | 380 scoped_refptr<StrictMock<MockMediaLog>> media_log_; |
381 std::unique_ptr<WebMClusterParser> parser_; | 381 std::unique_ptr<WebMClusterParser> parser_; |
382 | 382 |
383 private: | 383 private: |
384 DISALLOW_COPY_AND_ASSIGN(WebMClusterParserTest); | 384 DISALLOW_COPY_AND_ASSIGN(WebMClusterParserTest); |
385 }; | 385 }; |
386 | 386 |
387 TEST_F(WebMClusterParserTest, HeldBackBufferHoldsBackAllTracks) { | 387 TEST_F(WebMClusterParserTest, HeldBackBufferHoldsBackAllTracks) { |
388 // If a buffer is missing duration and is being held back, then all other | 388 // If a buffer is missing duration and is being held back, then all other |
389 // tracks' buffers that have same or higher (decode) timestamp should be held | 389 // tracks' buffers that have same or higher (decode) timestamp should be held |
390 // back too to keep the timestamps emitted for a cluster monotonically | 390 // back too to keep the timestamps emitted for a cluster monotonically |
391 // non-decreasing and in same order as parsed. | 391 // non-decreasing and in same order as parsed. |
392 InSequence s; | 392 InSequence s; |
393 | 393 |
394 // Reset the parser to have 3 tracks: text, video (no default frame duration), | 394 // Reset the parser to have 3 tracks: text, video (no default frame duration), |
395 // and audio (with a default frame duration). | 395 // and audio (with a default frame duration). |
396 TextTracks text_tracks; | 396 TextTracks text_tracks; |
397 text_tracks.insert(std::make_pair(TextTracks::key_type(kTextTrackNum), | 397 text_tracks.insert(std::make_pair(TextTracks::key_type(kTextTrackNum), |
398 TextTrackConfig(kTextSubtitles, "", "", | 398 TextTrackConfig(kTextSubtitles, "", "", |
399 ""))); | 399 ""))); |
400 base::TimeDelta default_audio_duration = | 400 base::TimeDelta default_audio_duration = |
401 base::TimeDelta::FromMilliseconds(kTestAudioFrameDefaultDurationInMs); | 401 base::TimeDelta::FromMilliseconds(kTestAudioFrameDefaultDurationInMs); |
402 ASSERT_GE(default_audio_duration, base::TimeDelta()); | 402 ASSERT_GE(default_audio_duration, base::TimeDelta()); |
403 ASSERT_NE(kNoTimestamp(), default_audio_duration); | 403 ASSERT_NE(kNoTimestamp, default_audio_duration); |
404 parser_.reset(CreateParserWithDefaultDurationsAndOptionalTextTracks( | 404 parser_.reset(CreateParserWithDefaultDurationsAndOptionalTextTracks( |
405 default_audio_duration, kNoTimestamp(), text_tracks)); | 405 default_audio_duration, kNoTimestamp, text_tracks)); |
406 | 406 |
407 const int kExpectedVideoEstimationInMs = 33; | 407 const int kExpectedVideoEstimationInMs = 33; |
408 | 408 |
409 const BlockInfo kBlockInfo[] = { | 409 const BlockInfo kBlockInfo[] = { |
410 {kVideoTrackNum, 0, 33, true, NULL, 0, false}, | 410 {kVideoTrackNum, 0, 33, true, NULL, 0, false}, |
411 {kAudioTrackNum, 0, 23, false, NULL, 0, false}, | 411 {kAudioTrackNum, 0, 23, false, NULL, 0, false}, |
412 {kTextTrackNum, 10, 42, false, NULL, 0, true}, | 412 {kTextTrackNum, 10, 42, false, NULL, 0, true}, |
413 {kAudioTrackNum, 23, kTestAudioFrameDefaultDurationInMs, true, NULL, 0, | 413 {kAudioTrackNum, 23, kTestAudioFrameDefaultDurationInMs, true, NULL, 0, |
414 false}, | 414 false}, |
415 {kVideoTrackNum, 33, 33, true, NULL, 0, false}, | 415 {kVideoTrackNum, 33, 33, true, NULL, 0, false}, |
(...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
632 } | 632 } |
633 | 633 |
634 TEST_F(WebMClusterParserTest, ParseTextTracks) { | 634 TEST_F(WebMClusterParserTest, ParseTextTracks) { |
635 TextTracks text_tracks; | 635 TextTracks text_tracks; |
636 | 636 |
637 text_tracks.insert(std::make_pair(TextTracks::key_type(kTextTrackNum), | 637 text_tracks.insert(std::make_pair(TextTracks::key_type(kTextTrackNum), |
638 TextTrackConfig(kTextSubtitles, "", "", | 638 TextTrackConfig(kTextSubtitles, "", "", |
639 ""))); | 639 ""))); |
640 | 640 |
641 parser_.reset(CreateParserWithDefaultDurationsAndOptionalTextTracks( | 641 parser_.reset(CreateParserWithDefaultDurationsAndOptionalTextTracks( |
642 kNoTimestamp(), kNoTimestamp(), text_tracks)); | 642 kNoTimestamp, kNoTimestamp, text_tracks)); |
643 | 643 |
644 const BlockInfo kInputBlockInfo[] = { | 644 const BlockInfo kInputBlockInfo[] = { |
645 {kAudioTrackNum, 0, 23, true, NULL, 0, false}, | 645 {kAudioTrackNum, 0, 23, true, NULL, 0, false}, |
646 {kAudioTrackNum, 23, 23, true, NULL, 0, false}, | 646 {kAudioTrackNum, 23, 23, true, NULL, 0, false}, |
647 {kVideoTrackNum, 33, 34, true, NULL, 0, false}, | 647 {kVideoTrackNum, 33, 34, true, NULL, 0, false}, |
648 {kTextTrackNum, 33, 42, false, NULL, 0, true}, | 648 {kTextTrackNum, 33, 42, false, NULL, 0, true}, |
649 {kAudioTrackNum, 46, 23, true, NULL, 0, false}, | 649 {kAudioTrackNum, 46, 23, true, NULL, 0, false}, |
650 {kTextTrackNum, 55, 44, false, NULL, 0, true}, | 650 {kTextTrackNum, 55, 44, false, NULL, 0, true}, |
651 {kVideoTrackNum, 67, 34, true, NULL, 0, false}, | 651 {kVideoTrackNum, 67, 34, true, NULL, 0, false}, |
652 }; | 652 }; |
(...skipping 10 matching lines...) Expand all Loading... |
663 } | 663 } |
664 | 664 |
665 TEST_F(WebMClusterParserTest, TextTracksSimpleBlock) { | 665 TEST_F(WebMClusterParserTest, TextTracksSimpleBlock) { |
666 TextTracks text_tracks; | 666 TextTracks text_tracks; |
667 | 667 |
668 text_tracks.insert(std::make_pair(TextTracks::key_type(kTextTrackNum), | 668 text_tracks.insert(std::make_pair(TextTracks::key_type(kTextTrackNum), |
669 TextTrackConfig(kTextSubtitles, "", "", | 669 TextTrackConfig(kTextSubtitles, "", "", |
670 ""))); | 670 ""))); |
671 | 671 |
672 parser_.reset(CreateParserWithDefaultDurationsAndOptionalTextTracks( | 672 parser_.reset(CreateParserWithDefaultDurationsAndOptionalTextTracks( |
673 kNoTimestamp(), kNoTimestamp(), text_tracks)); | 673 kNoTimestamp, kNoTimestamp, text_tracks)); |
674 | 674 |
675 const BlockInfo kInputBlockInfo[] = { | 675 const BlockInfo kInputBlockInfo[] = { |
676 { kTextTrackNum, 33, 42, true }, | 676 { kTextTrackNum, 33, 42, true }, |
677 }; | 677 }; |
678 int input_block_count = arraysize(kInputBlockInfo); | 678 int input_block_count = arraysize(kInputBlockInfo); |
679 | 679 |
680 std::unique_ptr<Cluster> cluster( | 680 std::unique_ptr<Cluster> cluster( |
681 CreateCluster(0, kInputBlockInfo, input_block_count)); | 681 CreateCluster(0, kInputBlockInfo, input_block_count)); |
682 | 682 |
683 int result = parser_->Parse(cluster->data(), cluster->size()); | 683 int result = parser_->Parse(cluster->data(), cluster->size()); |
684 EXPECT_LT(result, 0); | 684 EXPECT_LT(result, 0); |
685 } | 685 } |
686 | 686 |
687 TEST_F(WebMClusterParserTest, ParseMultipleTextTracks) { | 687 TEST_F(WebMClusterParserTest, ParseMultipleTextTracks) { |
688 TextTracks text_tracks; | 688 TextTracks text_tracks; |
689 | 689 |
690 const int kSubtitleTextTrackNum = kTextTrackNum; | 690 const int kSubtitleTextTrackNum = kTextTrackNum; |
691 const int kCaptionTextTrackNum = kTextTrackNum + 1; | 691 const int kCaptionTextTrackNum = kTextTrackNum + 1; |
692 | 692 |
693 text_tracks.insert(std::make_pair(TextTracks::key_type(kSubtitleTextTrackNum), | 693 text_tracks.insert(std::make_pair(TextTracks::key_type(kSubtitleTextTrackNum), |
694 TextTrackConfig(kTextSubtitles, "", "", | 694 TextTrackConfig(kTextSubtitles, "", "", |
695 ""))); | 695 ""))); |
696 | 696 |
697 text_tracks.insert(std::make_pair(TextTracks::key_type(kCaptionTextTrackNum), | 697 text_tracks.insert(std::make_pair(TextTracks::key_type(kCaptionTextTrackNum), |
698 TextTrackConfig(kTextCaptions, "", "", | 698 TextTrackConfig(kTextCaptions, "", "", |
699 ""))); | 699 ""))); |
700 | 700 |
701 parser_.reset(CreateParserWithDefaultDurationsAndOptionalTextTracks( | 701 parser_.reset(CreateParserWithDefaultDurationsAndOptionalTextTracks( |
702 kNoTimestamp(), kNoTimestamp(), text_tracks)); | 702 kNoTimestamp, kNoTimestamp, text_tracks)); |
703 | 703 |
704 const BlockInfo kInputBlockInfo[] = { | 704 const BlockInfo kInputBlockInfo[] = { |
705 {kAudioTrackNum, 0, 23, true, NULL, 0, false}, | 705 {kAudioTrackNum, 0, 23, true, NULL, 0, false}, |
706 {kAudioTrackNum, 23, 23, true, NULL, 0, false}, | 706 {kAudioTrackNum, 23, 23, true, NULL, 0, false}, |
707 {kVideoTrackNum, 33, 34, true, NULL, 0, false}, | 707 {kVideoTrackNum, 33, 34, true, NULL, 0, false}, |
708 {kSubtitleTextTrackNum, 33, 42, false, NULL, 0, false}, | 708 {kSubtitleTextTrackNum, 33, 42, false, NULL, 0, false}, |
709 {kAudioTrackNum, 46, 23, true, NULL, 0, false}, | 709 {kAudioTrackNum, 46, 23, true, NULL, 0, false}, |
710 {kCaptionTextTrackNum, 55, 44, false, NULL, 0, false}, | 710 {kCaptionTextTrackNum, 55, 44, false, NULL, 0, false}, |
711 {kVideoTrackNum, 67, 34, true, NULL, 0, false}, | 711 {kVideoTrackNum, 67, 34, true, NULL, 0, false}, |
712 {kSubtitleTextTrackNum, 67, 33, false, NULL, 0, false}, | 712 {kSubtitleTextTrackNum, 67, 33, false, NULL, 0, false}, |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
782 | 782 |
783 TEST_F(WebMClusterParserTest, ParseInvalidTextBlockGroupWithoutDuration) { | 783 TEST_F(WebMClusterParserTest, ParseInvalidTextBlockGroupWithoutDuration) { |
784 // Text track frames must have explicitly specified BlockGroup BlockDurations. | 784 // Text track frames must have explicitly specified BlockGroup BlockDurations. |
785 TextTracks text_tracks; | 785 TextTracks text_tracks; |
786 | 786 |
787 text_tracks.insert(std::make_pair(TextTracks::key_type(kTextTrackNum), | 787 text_tracks.insert(std::make_pair(TextTracks::key_type(kTextTrackNum), |
788 TextTrackConfig(kTextSubtitles, "", "", | 788 TextTrackConfig(kTextSubtitles, "", "", |
789 ""))); | 789 ""))); |
790 | 790 |
791 parser_.reset(CreateParserWithDefaultDurationsAndOptionalTextTracks( | 791 parser_.reset(CreateParserWithDefaultDurationsAndOptionalTextTracks( |
792 kNoTimestamp(), kNoTimestamp(), text_tracks)); | 792 kNoTimestamp, kNoTimestamp, text_tracks)); |
793 | 793 |
794 const BlockInfo kBlockInfo[] = { | 794 const BlockInfo kBlockInfo[] = { |
795 {kTextTrackNum, 33, -42, false, NULL, 0, false}, | 795 {kTextTrackNum, 33, -42, false, NULL, 0, false}, |
796 }; | 796 }; |
797 int block_count = arraysize(kBlockInfo); | 797 int block_count = arraysize(kBlockInfo); |
798 std::unique_ptr<Cluster> cluster(CreateCluster(0, kBlockInfo, block_count)); | 798 std::unique_ptr<Cluster> cluster(CreateCluster(0, kBlockInfo, block_count)); |
799 int result = parser_->Parse(cluster->data(), cluster->size()); | 799 int result = parser_->Parse(cluster->data(), cluster->size()); |
800 EXPECT_LT(result, 0); | 800 EXPECT_LT(result, 0); |
801 } | 801 } |
802 | 802 |
(...skipping 377 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1180 int block_count = arraysize(kBlockInfo); | 1180 int block_count = arraysize(kBlockInfo); |
1181 std::unique_ptr<Cluster> cluster(CreateCluster(0, kBlockInfo, block_count)); | 1181 std::unique_ptr<Cluster> cluster(CreateCluster(0, kBlockInfo, block_count)); |
1182 int result = parser_->Parse(cluster->data(), cluster->size()); | 1182 int result = parser_->Parse(cluster->data(), cluster->size()); |
1183 EXPECT_EQ(cluster->size(), result); | 1183 EXPECT_EQ(cluster->size(), result); |
1184 | 1184 |
1185 // Will verify that duration of buffer matches that of BlockDuration. | 1185 // Will verify that duration of buffer matches that of BlockDuration. |
1186 ASSERT_TRUE(VerifyBuffers(parser_, kBlockInfo, block_count)); | 1186 ASSERT_TRUE(VerifyBuffers(parser_, kBlockInfo, block_count)); |
1187 } | 1187 } |
1188 | 1188 |
1189 } // namespace media | 1189 } // namespace media |
OLD | NEW |