| 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 |