| 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/bind.h" | 5 #include "base/bind.h" |
| 6 #include "base/message_loop.h" | 6 #include "base/message_loop.h" |
| 7 #include "media/base/audio_decoder_config.h" | 7 #include "media/base/audio_decoder_config.h" |
| 8 #include "media/base/decoder_buffer.h" | 8 #include "media/base/decoder_buffer.h" |
| 9 #include "media/base/mock_callback.h" | 9 #include "media/base/mock_callback.h" |
| 10 #include "media/base/mock_demuxer_host.h" | 10 #include "media/base/mock_demuxer_host.h" |
| 11 #include "media/base/test_data_util.h" | 11 #include "media/base/test_data_util.h" |
| 12 #include "media/filters/chunk_demuxer.h" | 12 #include "media/filters/chunk_demuxer.h" |
| 13 #include "media/filters/chunk_demuxer_client.h" | |
| 14 #include "media/webm/cluster_builder.h" | 13 #include "media/webm/cluster_builder.h" |
| 15 #include "media/webm/webm_constants.h" | 14 #include "media/webm/webm_constants.h" |
| 16 #include "testing/gtest/include/gtest/gtest.h" | 15 #include "testing/gtest/include/gtest/gtest.h" |
| 17 | 16 |
| 18 using ::testing::AnyNumber; | 17 using ::testing::AnyNumber; |
| 19 using ::testing::InSequence; | 18 using ::testing::InSequence; |
| 20 using ::testing::NotNull; | 19 using ::testing::NotNull; |
| 21 using ::testing::Return; | 20 using ::testing::Return; |
| 22 using ::testing::SaveArg; | 21 using ::testing::SaveArg; |
| 23 using ::testing::SetArgumentPointee; | 22 using ::testing::SetArgumentPointee; |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 95 } | 94 } |
| 96 | 95 |
| 97 static void OnReadDone_EOSExpected(bool* called, | 96 static void OnReadDone_EOSExpected(bool* called, |
| 98 DemuxerStream::Status status, | 97 DemuxerStream::Status status, |
| 99 const scoped_refptr<DecoderBuffer>& buffer) { | 98 const scoped_refptr<DecoderBuffer>& buffer) { |
| 100 EXPECT_EQ(status, DemuxerStream::kOk); | 99 EXPECT_EQ(status, DemuxerStream::kOk); |
| 101 EXPECT_TRUE(buffer->IsEndOfStream()); | 100 EXPECT_TRUE(buffer->IsEndOfStream()); |
| 102 *called = true; | 101 *called = true; |
| 103 } | 102 } |
| 104 | 103 |
| 105 class MockChunkDemuxerClient : public ChunkDemuxerClient { | |
| 106 public: | |
| 107 MockChunkDemuxerClient() {} | |
| 108 virtual ~MockChunkDemuxerClient() {} | |
| 109 | |
| 110 MOCK_METHOD1(DemuxerOpened, void(ChunkDemuxer* demuxer)); | |
| 111 MOCK_METHOD0(DemuxerClosed, void()); | |
| 112 // TODO(xhwang): This is a workaround of the issue that move-only parameters | |
| 113 // are not supported in mocked methods. Remove this when the issue is fixed | |
| 114 // (http://code.google.com/p/googletest/issues/detail?id=395) or when we use | |
| 115 // std::string instead of scoped_array<uint8> (http://crbug.com/130689). | |
| 116 MOCK_METHOD2(NeedKeyMock, void(const uint8* init_data, int init_data_size)); | |
| 117 void DemuxerNeedKey(scoped_array<uint8> init_data, int init_data_size) { | |
| 118 NeedKeyMock(init_data.get(), init_data_size); | |
| 119 } | |
| 120 | |
| 121 private: | |
| 122 DISALLOW_COPY_AND_ASSIGN(MockChunkDemuxerClient); | |
| 123 }; | |
| 124 | |
| 125 class ChunkDemuxerTest : public testing::Test { | 104 class ChunkDemuxerTest : public testing::Test { |
| 126 protected: | 105 protected: |
| 127 enum CodecsIndex { | 106 enum CodecsIndex { |
| 128 AUDIO, | 107 AUDIO, |
| 129 VIDEO, | 108 VIDEO, |
| 130 MAX_CODECS_INDEX | 109 MAX_CODECS_INDEX |
| 131 }; | 110 }; |
| 132 | 111 |
| 133 // Default cluster to append first for simple tests. | 112 // Default cluster to append first for simple tests. |
| 134 scoped_ptr<Cluster> kDefaultFirstCluster() { | 113 scoped_ptr<Cluster> kDefaultFirstCluster() { |
| 135 return GenerateCluster(0, 4); | 114 return GenerateCluster(0, 4); |
| 136 } | 115 } |
| 137 | 116 |
| 138 // Default cluster to append after kDefaultFirstCluster() | 117 // Default cluster to append after kDefaultFirstCluster() |
| 139 // has been appended. This cluster starts with blocks that | 118 // has been appended. This cluster starts with blocks that |
| 140 // have timestamps consistent with the end times of the blocks | 119 // have timestamps consistent with the end times of the blocks |
| 141 // in kDefaultFirstCluster() so that these two clusters represent | 120 // in kDefaultFirstCluster() so that these two clusters represent |
| 142 // a continuous region. | 121 // a continuous region. |
| 143 scoped_ptr<Cluster> kDefaultSecondCluster() { | 122 scoped_ptr<Cluster> kDefaultSecondCluster() { |
| 144 return GenerateCluster(46, 66, 5); | 123 return GenerateCluster(46, 66, 5); |
| 145 } | 124 } |
| 146 | 125 |
| 147 ChunkDemuxerTest() | 126 ChunkDemuxerTest() { |
| 148 : client_(new MockChunkDemuxerClient()), | 127 CreateNewDemuxer(); |
| 149 demuxer_(new ChunkDemuxer(client_.get())) { | 128 } |
| 129 |
| 130 void CreateNewDemuxer() { |
| 131 base::Closure open_cb = |
| 132 base::Bind(&ChunkDemuxerTest::DemuxerOpened, base::Unretained(this)); |
| 133 ChunkDemuxer::NeedKeyCB need_key_cb = |
| 134 base::Bind(&ChunkDemuxerTest::DemuxerNeedKey, base::Unretained(this)); |
| 135 demuxer_ = new ChunkDemuxer(open_cb, need_key_cb); |
| 150 } | 136 } |
| 151 | 137 |
| 152 virtual ~ChunkDemuxerTest() { | 138 virtual ~ChunkDemuxerTest() { |
| 153 ShutdownDemuxer(); | 139 ShutdownDemuxer(); |
| 154 } | 140 } |
| 155 | 141 |
| 156 void CreateInitSegment(bool has_audio, bool has_video, | 142 void CreateInitSegment(bool has_audio, bool has_video, |
| 157 bool video_content_encoded, | 143 bool video_content_encoded, |
| 158 scoped_array<uint8>* buffer, | 144 scoped_array<uint8>* buffer, |
| 159 int* size) { | 145 int* size) { |
| (...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 326 | 312 |
| 327 bool InitDemuxer(bool has_audio, bool has_video, | 313 bool InitDemuxer(bool has_audio, bool has_video, |
| 328 bool video_content_encoded) { | 314 bool video_content_encoded) { |
| 329 PipelineStatus expected_status = | 315 PipelineStatus expected_status = |
| 330 (has_audio || has_video) ? PIPELINE_OK : DEMUXER_ERROR_COULD_NOT_OPEN; | 316 (has_audio || has_video) ? PIPELINE_OK : DEMUXER_ERROR_COULD_NOT_OPEN; |
| 331 | 317 |
| 332 base::TimeDelta expected_duration = kNoTimestamp(); | 318 base::TimeDelta expected_duration = kNoTimestamp(); |
| 333 if (expected_status == PIPELINE_OK) | 319 if (expected_status == PIPELINE_OK) |
| 334 expected_duration = kDefaultDuration(); | 320 expected_duration = kDefaultDuration(); |
| 335 | 321 |
| 336 EXPECT_CALL(*client_, DemuxerOpened(_)); | 322 EXPECT_CALL(*this, DemuxerOpened()); |
| 337 demuxer_->Initialize( | 323 demuxer_->Initialize( |
| 338 &host_, CreateInitDoneCB(expected_duration, expected_status)); | 324 &host_, CreateInitDoneCB(expected_duration, expected_status)); |
| 339 | 325 |
| 340 if (AddId(kSourceId, has_audio, has_video) != ChunkDemuxer::kOk) | 326 if (AddId(kSourceId, has_audio, has_video) != ChunkDemuxer::kOk) |
| 341 return false; | 327 return false; |
| 342 | 328 |
| 343 return AppendInitSegment(has_audio, has_video, video_content_encoded); | 329 return AppendInitSegment(has_audio, has_video, video_content_encoded); |
| 344 } | 330 } |
| 345 | 331 |
| 346 bool InitDemuxerAudioAndVideoSources(const std::string& audio_id, | 332 bool InitDemuxerAudioAndVideoSources(const std::string& audio_id, |
| 347 const std::string& video_id) { | 333 const std::string& video_id) { |
| 348 EXPECT_CALL(*client_, DemuxerOpened(_)); | 334 EXPECT_CALL(*this, DemuxerOpened()); |
| 349 demuxer_->Initialize( | 335 demuxer_->Initialize( |
| 350 &host_, CreateInitDoneCB(kDefaultDuration(), PIPELINE_OK)); | 336 &host_, CreateInitDoneCB(kDefaultDuration(), PIPELINE_OK)); |
| 351 | 337 |
| 352 if (AddId(audio_id, true, false) != ChunkDemuxer::kOk) | 338 if (AddId(audio_id, true, false) != ChunkDemuxer::kOk) |
| 353 return false; | 339 return false; |
| 354 if (AddId(video_id, false, true) != ChunkDemuxer::kOk) | 340 if (AddId(video_id, false, true) != ChunkDemuxer::kOk) |
| 355 return false; | 341 return false; |
| 356 | 342 |
| 357 bool success = AppendInitSegment(audio_id, true, false, false); | 343 bool success = AppendInitSegment(audio_id, true, false, false); |
| 358 success &= AppendInitSegment(video_id, false, true, false); | 344 success &= AppendInitSegment(video_id, false, true, false); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 373 // bear-320x240.webm AudioDecoderConfig returns 3863 for its extra_data_size() | 359 // bear-320x240.webm AudioDecoderConfig returns 3863 for its extra_data_size() |
| 374 // bear-640x360.webm AudioDecoderConfig returns 3935 for its extra_data_size() | 360 // bear-640x360.webm AudioDecoderConfig returns 3935 for its extra_data_size() |
| 375 // The resulting audio stream returns data from each file for the following | 361 // The resulting audio stream returns data from each file for the following |
| 376 // time ranges. | 362 // time ranges. |
| 377 // bear-320x240.webm : [0-524) [779-2737) | 363 // bear-320x240.webm : [0-524) [779-2737) |
| 378 // bear-640x360.webm : [527-759) | 364 // bear-640x360.webm : [527-759) |
| 379 bool InitDemuxerWithConfigChangeData() { | 365 bool InitDemuxerWithConfigChangeData() { |
| 380 scoped_refptr<DecoderBuffer> bear1 = ReadTestDataFile("bear-320x240.webm"); | 366 scoped_refptr<DecoderBuffer> bear1 = ReadTestDataFile("bear-320x240.webm"); |
| 381 scoped_refptr<DecoderBuffer> bear2 = ReadTestDataFile("bear-640x360.webm"); | 367 scoped_refptr<DecoderBuffer> bear2 = ReadTestDataFile("bear-640x360.webm"); |
| 382 | 368 |
| 383 EXPECT_CALL(*client_, DemuxerOpened(_)); | 369 EXPECT_CALL(*this, DemuxerOpened()); |
| 384 demuxer_->Initialize( | 370 demuxer_->Initialize( |
| 385 &host_, CreateInitDoneCB(base::TimeDelta::FromMilliseconds(2744), | 371 &host_, CreateInitDoneCB(base::TimeDelta::FromMilliseconds(2744), |
| 386 PIPELINE_OK)); | 372 PIPELINE_OK)); |
| 387 | 373 |
| 388 if (AddId(kSourceId, true, true) != ChunkDemuxer::kOk) | 374 if (AddId(kSourceId, true, true) != ChunkDemuxer::kOk) |
| 389 return false; | 375 return false; |
| 390 | 376 |
| 391 // Append the whole bear1 file. | 377 // Append the whole bear1 file. |
| 392 if (!AppendData(bear1->GetData(), bear1->GetDataSize())) | 378 if (!AppendData(bear1->GetData(), bear1->GetDataSize())) |
| 393 return false; | 379 return false; |
| (...skipping 18 matching lines...) Expand all Loading... |
| 412 if (!AppendData(bear1->GetData(), 4370) || | 398 if (!AppendData(bear1->GetData(), 4370) || |
| 413 !AppendData(bear1->GetData() + 72737, 28183)) { | 399 !AppendData(bear1->GetData() + 72737, 28183)) { |
| 414 return false; | 400 return false; |
| 415 } | 401 } |
| 416 CheckExpectedRanges(kSourceId, "{ [0,2737) }"); | 402 CheckExpectedRanges(kSourceId, "{ [0,2737) }"); |
| 417 | 403 |
| 418 return demuxer_->EndOfStream(PIPELINE_OK); | 404 return demuxer_->EndOfStream(PIPELINE_OK); |
| 419 } | 405 } |
| 420 | 406 |
| 421 void ShutdownDemuxer() { | 407 void ShutdownDemuxer() { |
| 422 if (demuxer_) { | 408 if (demuxer_) |
| 423 EXPECT_CALL(*client_, DemuxerClosed()); | |
| 424 demuxer_->Shutdown(); | 409 demuxer_->Shutdown(); |
| 425 } | |
| 426 } | 410 } |
| 427 | 411 |
| 428 void AddSimpleBlock(ClusterBuilder* cb, int track_num, int64 timecode) { | 412 void AddSimpleBlock(ClusterBuilder* cb, int track_num, int64 timecode) { |
| 429 uint8 data[] = { 0x00 }; | 413 uint8 data[] = { 0x00 }; |
| 430 cb->AddSimpleBlock(track_num, timecode, 0, data, sizeof(data)); | 414 cb->AddSimpleBlock(track_num, timecode, 0, data, sizeof(data)); |
| 431 } | 415 } |
| 432 | 416 |
| 433 scoped_ptr<Cluster> GenerateCluster(int timecode, int block_count) { | 417 scoped_ptr<Cluster> GenerateCluster(int timecode, int block_count) { |
| 434 return GenerateCluster(timecode, timecode, block_count); | 418 return GenerateCluster(timecode, timecode, block_count); |
| 435 } | 419 } |
| (...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 622 bool ParseWebMFile(const std::string& filename, | 606 bool ParseWebMFile(const std::string& filename, |
| 623 const BufferTimestamps* timestamps, | 607 const BufferTimestamps* timestamps, |
| 624 const base::TimeDelta& duration) { | 608 const base::TimeDelta& duration) { |
| 625 return ParseWebMFile(filename, timestamps, duration, true, true); | 609 return ParseWebMFile(filename, timestamps, duration, true, true); |
| 626 } | 610 } |
| 627 | 611 |
| 628 bool ParseWebMFile(const std::string& filename, | 612 bool ParseWebMFile(const std::string& filename, |
| 629 const BufferTimestamps* timestamps, | 613 const BufferTimestamps* timestamps, |
| 630 const base::TimeDelta& duration, | 614 const base::TimeDelta& duration, |
| 631 bool has_audio, bool has_video) { | 615 bool has_audio, bool has_video) { |
| 632 EXPECT_CALL(*client_, DemuxerOpened(_)); | 616 EXPECT_CALL(*this, DemuxerOpened()); |
| 633 demuxer_->Initialize( | 617 demuxer_->Initialize( |
| 634 &host_, CreateInitDoneCB(duration, PIPELINE_OK)); | 618 &host_, CreateInitDoneCB(duration, PIPELINE_OK)); |
| 635 | 619 |
| 636 if (AddId(kSourceId, has_audio, has_video) != ChunkDemuxer::kOk) | 620 if (AddId(kSourceId, has_audio, has_video) != ChunkDemuxer::kOk) |
| 637 return false; | 621 return false; |
| 638 | 622 |
| 639 // Read a WebM file into memory and send the data to the demuxer. | 623 // Read a WebM file into memory and send the data to the demuxer. |
| 640 scoped_refptr<DecoderBuffer> buffer = ReadTestDataFile(filename); | 624 scoped_refptr<DecoderBuffer> buffer = ReadTestDataFile(filename); |
| 641 if (!AppendDataInPieces(buffer->GetData(), buffer->GetDataSize(), 512)) | 625 if (!AppendDataInPieces(buffer->GetData(), buffer->GetDataSize(), 512)) |
| 642 return false; | 626 return false; |
| (...skipping 28 matching lines...) Expand all Loading... |
| 671 timestamps[i].video_time_ms), | 655 timestamps[i].video_time_ms), |
| 672 &video_read_done)); | 656 &video_read_done)); |
| 673 | 657 |
| 674 EXPECT_TRUE(video_read_done); | 658 EXPECT_TRUE(video_read_done); |
| 675 } | 659 } |
| 676 } | 660 } |
| 677 | 661 |
| 678 return true; | 662 return true; |
| 679 } | 663 } |
| 680 | 664 |
| 665 MOCK_METHOD0(DemuxerOpened, void()); |
| 666 // TODO(xhwang): This is a workaround of the issue that move-only parameters |
| 667 // are not supported in mocked methods. Remove this when the issue is fixed |
| 668 // (http://code.google.com/p/googletest/issues/detail?id=395) or when we use |
| 669 // std::string instead of scoped_array<uint8> (http://crbug.com/130689). |
| 670 MOCK_METHOD2(NeedKeyMock, void(const uint8* init_data, int init_data_size)); |
| 671 void DemuxerNeedKey(scoped_array<uint8> init_data, int init_data_size) { |
| 672 NeedKeyMock(init_data.get(), init_data_size); |
| 673 } |
| 674 |
| 681 MessageLoop message_loop_; | 675 MessageLoop message_loop_; |
| 682 MockDemuxerHost host_; | 676 MockDemuxerHost host_; |
| 683 | 677 |
| 684 scoped_ptr<MockChunkDemuxerClient> client_; | |
| 685 scoped_refptr<ChunkDemuxer> demuxer_; | 678 scoped_refptr<ChunkDemuxer> demuxer_; |
| 686 | 679 |
| 687 private: | 680 private: |
| 688 DISALLOW_COPY_AND_ASSIGN(ChunkDemuxerTest); | 681 DISALLOW_COPY_AND_ASSIGN(ChunkDemuxerTest); |
| 689 }; | 682 }; |
| 690 | 683 |
| 691 TEST_F(ChunkDemuxerTest, TestInit) { | 684 TEST_F(ChunkDemuxerTest, TestInit) { |
| 692 // Test no streams, audio-only, video-only, and audio & video scenarios, | 685 // Test no streams, audio-only, video-only, and audio & video scenarios, |
| 693 // with video content encoded or not. | 686 // with video content encoded or not. |
| 694 for (int i = 0; i < 8; i++) { | 687 for (int i = 0; i < 8; i++) { |
| 695 bool has_audio = (i & 0x1) != 0; | 688 bool has_audio = (i & 0x1) != 0; |
| 696 bool has_video = (i & 0x2) != 0; | 689 bool has_video = (i & 0x2) != 0; |
| 697 bool video_content_encoded = (i & 0x4) != 0; | 690 bool video_content_encoded = (i & 0x4) != 0; |
| 698 | 691 |
| 699 // No test on invalid combination. | 692 // No test on invalid combination. |
| 700 if (!has_video && video_content_encoded) | 693 if (!has_video && video_content_encoded) |
| 701 continue; | 694 continue; |
| 702 | 695 |
| 703 client_.reset(new MockChunkDemuxerClient()); | 696 CreateNewDemuxer(); |
| 704 demuxer_ = new ChunkDemuxer(client_.get()); | |
| 705 if (has_video && video_content_encoded) | 697 if (has_video && video_content_encoded) |
| 706 EXPECT_CALL(*client_, NeedKeyMock(NotNull(), 16)); | 698 EXPECT_CALL(*this, NeedKeyMock(NotNull(), 16)); |
| 707 | 699 |
| 708 ASSERT_TRUE(InitDemuxer(has_audio, has_video, video_content_encoded)); | 700 ASSERT_TRUE(InitDemuxer(has_audio, has_video, video_content_encoded)); |
| 709 | 701 |
| 710 scoped_refptr<DemuxerStream> audio_stream = | 702 scoped_refptr<DemuxerStream> audio_stream = |
| 711 demuxer_->GetStream(DemuxerStream::AUDIO); | 703 demuxer_->GetStream(DemuxerStream::AUDIO); |
| 712 if (has_audio) { | 704 if (has_audio) { |
| 713 ASSERT_TRUE(audio_stream); | 705 ASSERT_TRUE(audio_stream); |
| 714 | 706 |
| 715 const AudioDecoderConfig& config = audio_stream->audio_decoder_config(); | 707 const AudioDecoderConfig& config = audio_stream->audio_decoder_config(); |
| 716 EXPECT_EQ(kCodecVorbis, config.codec()); | 708 EXPECT_EQ(kCodecVorbis, config.codec()); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 732 } | 724 } |
| 733 | 725 |
| 734 ShutdownDemuxer(); | 726 ShutdownDemuxer(); |
| 735 demuxer_ = NULL; | 727 demuxer_ = NULL; |
| 736 } | 728 } |
| 737 } | 729 } |
| 738 | 730 |
| 739 // Make sure that the demuxer reports an error if Shutdown() | 731 // Make sure that the demuxer reports an error if Shutdown() |
| 740 // is called before all the initialization segments are appended. | 732 // is called before all the initialization segments are appended. |
| 741 TEST_F(ChunkDemuxerTest, TestShutdownBeforeAllInitSegmentsAppended) { | 733 TEST_F(ChunkDemuxerTest, TestShutdownBeforeAllInitSegmentsAppended) { |
| 742 EXPECT_CALL(*client_, DemuxerOpened(_)); | 734 EXPECT_CALL(*this, DemuxerOpened()); |
| 743 demuxer_->Initialize( | 735 demuxer_->Initialize( |
| 744 &host_, CreateInitDoneCB( | 736 &host_, CreateInitDoneCB( |
| 745 kDefaultDuration(), DEMUXER_ERROR_COULD_NOT_OPEN)); | 737 kDefaultDuration(), DEMUXER_ERROR_COULD_NOT_OPEN)); |
| 746 | 738 |
| 747 EXPECT_EQ(AddId("audio", true, false), ChunkDemuxer::kOk); | 739 EXPECT_EQ(AddId("audio", true, false), ChunkDemuxer::kOk); |
| 748 EXPECT_EQ(AddId("video", false, true), ChunkDemuxer::kOk); | 740 EXPECT_EQ(AddId("video", false, true), ChunkDemuxer::kOk); |
| 749 | 741 |
| 750 EXPECT_TRUE(AppendInitSegment("audio", true, false, false)); | 742 EXPECT_TRUE(AppendInitSegment("audio", true, false, false)); |
| 751 } | 743 } |
| 752 | 744 |
| (...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 953 AddSimpleBlock(&cb, kVideoTrackNum, 7); | 945 AddSimpleBlock(&cb, kVideoTrackNum, 7); |
| 954 scoped_ptr<Cluster> cluster(cb.Finish()); | 946 scoped_ptr<Cluster> cluster(cb.Finish()); |
| 955 | 947 |
| 956 EXPECT_CALL(host_, OnDemuxerError(PIPELINE_ERROR_DECODE)); | 948 EXPECT_CALL(host_, OnDemuxerError(PIPELINE_ERROR_DECODE)); |
| 957 ASSERT_TRUE(AppendData(cluster->data(), cluster->size())); | 949 ASSERT_TRUE(AppendData(cluster->data(), cluster->size())); |
| 958 } | 950 } |
| 959 | 951 |
| 960 // Test the case where a cluster is passed to AppendData() before | 952 // Test the case where a cluster is passed to AppendData() before |
| 961 // INFO & TRACKS data. | 953 // INFO & TRACKS data. |
| 962 TEST_F(ChunkDemuxerTest, TestClusterBeforeInitSegment) { | 954 TEST_F(ChunkDemuxerTest, TestClusterBeforeInitSegment) { |
| 963 EXPECT_CALL(*client_, DemuxerOpened(_)); | 955 EXPECT_CALL(*this, DemuxerOpened()); |
| 964 demuxer_->Initialize( | 956 demuxer_->Initialize( |
| 965 &host_, NewExpectedStatusCB(DEMUXER_ERROR_COULD_NOT_OPEN)); | 957 &host_, NewExpectedStatusCB(DEMUXER_ERROR_COULD_NOT_OPEN)); |
| 966 | 958 |
| 967 ASSERT_EQ(AddId(), ChunkDemuxer::kOk); | 959 ASSERT_EQ(AddId(), ChunkDemuxer::kOk); |
| 968 | 960 |
| 969 scoped_ptr<Cluster> cluster(GenerateCluster(0, 1)); | 961 scoped_ptr<Cluster> cluster(GenerateCluster(0, 1)); |
| 970 | 962 |
| 971 ASSERT_TRUE(AppendData(cluster->data(), cluster->size())); | 963 ASSERT_TRUE(AppendData(cluster->data(), cluster->size())); |
| 972 } | 964 } |
| 973 | 965 |
| 974 // Test cases where we get an EndOfStream() call during initialization. | 966 // Test cases where we get an EndOfStream() call during initialization. |
| 975 TEST_F(ChunkDemuxerTest, TestEOSDuringInit) { | 967 TEST_F(ChunkDemuxerTest, TestEOSDuringInit) { |
| 976 EXPECT_CALL(*client_, DemuxerOpened(_)); | 968 EXPECT_CALL(*this, DemuxerOpened()); |
| 977 demuxer_->Initialize( | 969 demuxer_->Initialize( |
| 978 &host_, NewExpectedStatusCB(DEMUXER_ERROR_COULD_NOT_OPEN)); | 970 &host_, NewExpectedStatusCB(DEMUXER_ERROR_COULD_NOT_OPEN)); |
| 979 demuxer_->EndOfStream(PIPELINE_OK); | 971 demuxer_->EndOfStream(PIPELINE_OK); |
| 980 } | 972 } |
| 981 | 973 |
| 982 TEST_F(ChunkDemuxerTest, TestEndOfStreamWithNoAppend) { | 974 TEST_F(ChunkDemuxerTest, TestEndOfStreamWithNoAppend) { |
| 983 EXPECT_CALL(*client_, DemuxerOpened(_)); | 975 EXPECT_CALL(*this, DemuxerOpened()); |
| 984 demuxer_->Initialize( | 976 demuxer_->Initialize( |
| 985 &host_, NewExpectedStatusCB(DEMUXER_ERROR_COULD_NOT_OPEN)); | 977 &host_, NewExpectedStatusCB(DEMUXER_ERROR_COULD_NOT_OPEN)); |
| 986 | 978 |
| 987 ASSERT_EQ(AddId(), ChunkDemuxer::kOk); | 979 ASSERT_EQ(AddId(), ChunkDemuxer::kOk); |
| 988 | 980 |
| 989 CheckExpectedRanges("{ }"); | 981 CheckExpectedRanges("{ }"); |
| 990 demuxer_->EndOfStream(PIPELINE_OK); | 982 demuxer_->EndOfStream(PIPELINE_OK); |
| 991 ShutdownDemuxer(); | 983 ShutdownDemuxer(); |
| 992 CheckExpectedRanges("{ }"); | 984 CheckExpectedRanges("{ }"); |
| 993 demuxer_->RemoveId(kSourceId); | 985 demuxer_->RemoveId(kSourceId); |
| (...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1162 end_of_stream_helper_2.RequestReads(); | 1154 end_of_stream_helper_2.RequestReads(); |
| 1163 end_of_stream_helper_2.CheckIfReadDonesWereCalled(true); | 1155 end_of_stream_helper_2.CheckIfReadDonesWereCalled(true); |
| 1164 | 1156 |
| 1165 end_of_stream_helper_3.RequestReads(); | 1157 end_of_stream_helper_3.RequestReads(); |
| 1166 end_of_stream_helper_3.CheckIfReadDonesWereCalled(true); | 1158 end_of_stream_helper_3.CheckIfReadDonesWereCalled(true); |
| 1167 } | 1159 } |
| 1168 | 1160 |
| 1169 // Make sure AppendData() will accept elements that span multiple calls. | 1161 // Make sure AppendData() will accept elements that span multiple calls. |
| 1170 TEST_F(ChunkDemuxerTest, TestAppendingInPieces) { | 1162 TEST_F(ChunkDemuxerTest, TestAppendingInPieces) { |
| 1171 | 1163 |
| 1172 EXPECT_CALL(*client_, DemuxerOpened(_)); | 1164 EXPECT_CALL(*this, DemuxerOpened()); |
| 1173 demuxer_->Initialize( | 1165 demuxer_->Initialize( |
| 1174 &host_, CreateInitDoneCB(kDefaultDuration(), PIPELINE_OK)); | 1166 &host_, CreateInitDoneCB(kDefaultDuration(), PIPELINE_OK)); |
| 1175 | 1167 |
| 1176 ASSERT_EQ(AddId(), ChunkDemuxer::kOk); | 1168 ASSERT_EQ(AddId(), ChunkDemuxer::kOk); |
| 1177 | 1169 |
| 1178 scoped_array<uint8> info_tracks; | 1170 scoped_array<uint8> info_tracks; |
| 1179 int info_tracks_size = 0; | 1171 int info_tracks_size = 0; |
| 1180 CreateInitSegment(true, true, false, &info_tracks, &info_tracks_size); | 1172 CreateInitSegment(true, true, false, &info_tracks, &info_tracks_size); |
| 1181 | 1173 |
| 1182 scoped_ptr<Cluster> cluster_a(kDefaultFirstCluster()); | 1174 scoped_ptr<Cluster> cluster_a(kDefaultFirstCluster()); |
| (...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1339 | 1331 |
| 1340 // Append the remaining data. | 1332 // Append the remaining data. |
| 1341 ASSERT_LT(i, cluster->size()); | 1333 ASSERT_LT(i, cluster->size()); |
| 1342 ASSERT_TRUE(AppendData(cluster->data() + i, cluster->size() - i)); | 1334 ASSERT_TRUE(AppendData(cluster->data() + i, cluster->size() - i)); |
| 1343 | 1335 |
| 1344 EXPECT_TRUE(audio_read_done); | 1336 EXPECT_TRUE(audio_read_done); |
| 1345 EXPECT_TRUE(video_read_done); | 1337 EXPECT_TRUE(video_read_done); |
| 1346 } | 1338 } |
| 1347 | 1339 |
| 1348 TEST_F(ChunkDemuxerTest, TestParseErrorDuringInit) { | 1340 TEST_F(ChunkDemuxerTest, TestParseErrorDuringInit) { |
| 1349 EXPECT_CALL(*client_, DemuxerOpened(_)); | 1341 EXPECT_CALL(*this, DemuxerOpened()); |
| 1350 demuxer_->Initialize( | 1342 demuxer_->Initialize( |
| 1351 &host_, CreateInitDoneCB( | 1343 &host_, CreateInitDoneCB( |
| 1352 kNoTimestamp(), DEMUXER_ERROR_COULD_NOT_OPEN)); | 1344 kNoTimestamp(), DEMUXER_ERROR_COULD_NOT_OPEN)); |
| 1353 | 1345 |
| 1354 ASSERT_EQ(AddId(), ChunkDemuxer::kOk); | 1346 ASSERT_EQ(AddId(), ChunkDemuxer::kOk); |
| 1355 | 1347 |
| 1356 uint8 tmp = 0; | 1348 uint8 tmp = 0; |
| 1357 ASSERT_TRUE(demuxer_->AppendData(kSourceId, &tmp, 1)); | 1349 ASSERT_TRUE(demuxer_->AppendData(kSourceId, &tmp, 1)); |
| 1358 } | 1350 } |
| 1359 | 1351 |
| 1360 TEST_F(ChunkDemuxerTest, TestAVHeadersWithAudioOnlyType) { | 1352 TEST_F(ChunkDemuxerTest, TestAVHeadersWithAudioOnlyType) { |
| 1361 EXPECT_CALL(*client_, DemuxerOpened(_)); | 1353 EXPECT_CALL(*this, DemuxerOpened()); |
| 1362 demuxer_->Initialize( | 1354 demuxer_->Initialize( |
| 1363 &host_, CreateInitDoneCB(kNoTimestamp(), | 1355 &host_, CreateInitDoneCB(kNoTimestamp(), |
| 1364 DEMUXER_ERROR_COULD_NOT_OPEN)); | 1356 DEMUXER_ERROR_COULD_NOT_OPEN)); |
| 1365 | 1357 |
| 1366 std::vector<std::string> codecs(1); | 1358 std::vector<std::string> codecs(1); |
| 1367 codecs[0] = "vorbis"; | 1359 codecs[0] = "vorbis"; |
| 1368 ASSERT_EQ(demuxer_->AddId(kSourceId, "audio/webm", codecs), | 1360 ASSERT_EQ(demuxer_->AddId(kSourceId, "audio/webm", codecs), |
| 1369 ChunkDemuxer::kOk); | 1361 ChunkDemuxer::kOk); |
| 1370 | 1362 |
| 1371 ASSERT_TRUE(AppendInitSegment(true, true, false)); | 1363 ASSERT_TRUE(AppendInitSegment(true, true, false)); |
| 1372 } | 1364 } |
| 1373 | 1365 |
| 1374 TEST_F(ChunkDemuxerTest, TestAVHeadersWithVideoOnlyType) { | 1366 TEST_F(ChunkDemuxerTest, TestAVHeadersWithVideoOnlyType) { |
| 1375 EXPECT_CALL(*client_, DemuxerOpened(_)); | 1367 EXPECT_CALL(*this, DemuxerOpened()); |
| 1376 demuxer_->Initialize( | 1368 demuxer_->Initialize( |
| 1377 &host_, CreateInitDoneCB(kNoTimestamp(), | 1369 &host_, CreateInitDoneCB(kNoTimestamp(), |
| 1378 DEMUXER_ERROR_COULD_NOT_OPEN)); | 1370 DEMUXER_ERROR_COULD_NOT_OPEN)); |
| 1379 | 1371 |
| 1380 std::vector<std::string> codecs(1); | 1372 std::vector<std::string> codecs(1); |
| 1381 codecs[0] = "vp8"; | 1373 codecs[0] = "vp8"; |
| 1382 ASSERT_EQ(demuxer_->AddId(kSourceId, "video/webm", codecs), | 1374 ASSERT_EQ(demuxer_->AddId(kSourceId, "video/webm", codecs), |
| 1383 ChunkDemuxer::kOk); | 1375 ChunkDemuxer::kOk); |
| 1384 | 1376 |
| 1385 ASSERT_TRUE(AppendInitSegment(true, true, false)); | 1377 ASSERT_TRUE(AppendInitSegment(true, true, false)); |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1422 GenerateSingleStreamCluster(0, 132, kVideoTrackNum, kVideoBlockDuration)); | 1414 GenerateSingleStreamCluster(0, 132, kVideoTrackNum, kVideoBlockDuration)); |
| 1423 | 1415 |
| 1424 // Append audio and video data into separate source ids. | 1416 // Append audio and video data into separate source ids. |
| 1425 ASSERT_TRUE(AppendData(audio_id, cluster_a->data(), cluster_a->size())); | 1417 ASSERT_TRUE(AppendData(audio_id, cluster_a->data(), cluster_a->size())); |
| 1426 GenerateSingleStreamExpectedReads(0, 4, audio, kAudioBlockDuration); | 1418 GenerateSingleStreamExpectedReads(0, 4, audio, kAudioBlockDuration); |
| 1427 ASSERT_TRUE(AppendData(video_id, cluster_v->data(), cluster_v->size())); | 1419 ASSERT_TRUE(AppendData(video_id, cluster_v->data(), cluster_v->size())); |
| 1428 GenerateSingleStreamExpectedReads(0, 4, video, kVideoBlockDuration); | 1420 GenerateSingleStreamExpectedReads(0, 4, video, kVideoBlockDuration); |
| 1429 } | 1421 } |
| 1430 | 1422 |
| 1431 TEST_F(ChunkDemuxerTest, TestAddIdFailures) { | 1423 TEST_F(ChunkDemuxerTest, TestAddIdFailures) { |
| 1432 EXPECT_CALL(*client_, DemuxerOpened(_)); | 1424 EXPECT_CALL(*this, DemuxerOpened()); |
| 1433 demuxer_->Initialize( | 1425 demuxer_->Initialize( |
| 1434 &host_, CreateInitDoneCB(kDefaultDuration(), PIPELINE_OK)); | 1426 &host_, CreateInitDoneCB(kDefaultDuration(), PIPELINE_OK)); |
| 1435 | 1427 |
| 1436 std::string audio_id = "audio1"; | 1428 std::string audio_id = "audio1"; |
| 1437 std::string video_id = "video1"; | 1429 std::string video_id = "video1"; |
| 1438 | 1430 |
| 1439 ASSERT_EQ(AddId(audio_id, true, false), ChunkDemuxer::kOk); | 1431 ASSERT_EQ(AddId(audio_id, true, false), ChunkDemuxer::kOk); |
| 1440 | 1432 |
| 1441 // Adding an id with audio/video should fail because we already added audio. | 1433 // Adding an id with audio/video should fail because we already added audio. |
| 1442 ASSERT_EQ(AddId(), ChunkDemuxer::kReachedIdLimit); | 1434 ASSERT_EQ(AddId(), ChunkDemuxer::kReachedIdLimit); |
| (...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1617 ASSERT_TRUE(AppendData(audio_id, cluster_a2->data(), cluster_a2->size())); | 1609 ASSERT_TRUE(AppendData(audio_id, cluster_a2->data(), cluster_a2->size())); |
| 1618 ASSERT_TRUE(AppendData(video_id, cluster_v2->data(), cluster_v2->size())); | 1610 ASSERT_TRUE(AppendData(video_id, cluster_v2->data(), cluster_v2->size())); |
| 1619 | 1611 |
| 1620 // Read() should return buffers at 3. | 1612 // Read() should return buffers at 3. |
| 1621 EXPECT_TRUE(audio_read_done); | 1613 EXPECT_TRUE(audio_read_done); |
| 1622 EXPECT_TRUE(video_read_done); | 1614 EXPECT_TRUE(video_read_done); |
| 1623 } | 1615 } |
| 1624 | 1616 |
| 1625 // Test ranges in an audio-only stream. | 1617 // Test ranges in an audio-only stream. |
| 1626 TEST_F(ChunkDemuxerTest, GetBufferedRanges_AudioIdOnly) { | 1618 TEST_F(ChunkDemuxerTest, GetBufferedRanges_AudioIdOnly) { |
| 1627 EXPECT_CALL(*client_, DemuxerOpened(_)); | 1619 EXPECT_CALL(*this, DemuxerOpened()); |
| 1628 demuxer_->Initialize( | 1620 demuxer_->Initialize( |
| 1629 &host_, CreateInitDoneCB(kDefaultDuration(), PIPELINE_OK)); | 1621 &host_, CreateInitDoneCB(kDefaultDuration(), PIPELINE_OK)); |
| 1630 | 1622 |
| 1631 ASSERT_EQ(AddId(kSourceId, true, false), ChunkDemuxer::kOk); | 1623 ASSERT_EQ(AddId(kSourceId, true, false), ChunkDemuxer::kOk); |
| 1632 ASSERT_TRUE(AppendInitSegment(true, false, false)); | 1624 ASSERT_TRUE(AppendInitSegment(true, false, false)); |
| 1633 | 1625 |
| 1634 // Test a simple cluster. | 1626 // Test a simple cluster. |
| 1635 scoped_ptr<Cluster> cluster_1(GenerateSingleStreamCluster(0, 92, | 1627 scoped_ptr<Cluster> cluster_1(GenerateSingleStreamCluster(0, 92, |
| 1636 kAudioTrackNum, kAudioBlockDuration)); | 1628 kAudioTrackNum, kAudioBlockDuration)); |
| 1637 ASSERT_TRUE(AppendData(cluster_1->data(), cluster_1->size())); | 1629 ASSERT_TRUE(AppendData(cluster_1->data(), cluster_1->size())); |
| 1638 | 1630 |
| 1639 CheckExpectedRanges("{ [0,92) }"); | 1631 CheckExpectedRanges("{ [0,92) }"); |
| 1640 | 1632 |
| 1641 // Append a disjoint cluster to check for two separate ranges. | 1633 // Append a disjoint cluster to check for two separate ranges. |
| 1642 scoped_ptr<Cluster> cluster_2(GenerateSingleStreamCluster(150, 219, | 1634 scoped_ptr<Cluster> cluster_2(GenerateSingleStreamCluster(150, 219, |
| 1643 kAudioTrackNum, kAudioBlockDuration)); | 1635 kAudioTrackNum, kAudioBlockDuration)); |
| 1644 | 1636 |
| 1645 ASSERT_TRUE(AppendData(cluster_2->data(), cluster_2->size())); | 1637 ASSERT_TRUE(AppendData(cluster_2->data(), cluster_2->size())); |
| 1646 | 1638 |
| 1647 CheckExpectedRanges("{ [0,92) [150,219) }"); | 1639 CheckExpectedRanges("{ [0,92) [150,219) }"); |
| 1648 } | 1640 } |
| 1649 | 1641 |
| 1650 // Test ranges in a video-only stream. | 1642 // Test ranges in a video-only stream. |
| 1651 TEST_F(ChunkDemuxerTest, GetBufferedRanges_VideoIdOnly) { | 1643 TEST_F(ChunkDemuxerTest, GetBufferedRanges_VideoIdOnly) { |
| 1652 EXPECT_CALL(*client_, DemuxerOpened(_)); | 1644 EXPECT_CALL(*this, DemuxerOpened()); |
| 1653 demuxer_->Initialize( | 1645 demuxer_->Initialize( |
| 1654 &host_, CreateInitDoneCB(kDefaultDuration(), PIPELINE_OK)); | 1646 &host_, CreateInitDoneCB(kDefaultDuration(), PIPELINE_OK)); |
| 1655 | 1647 |
| 1656 ASSERT_EQ(AddId(kSourceId, false, true), ChunkDemuxer::kOk); | 1648 ASSERT_EQ(AddId(kSourceId, false, true), ChunkDemuxer::kOk); |
| 1657 ASSERT_TRUE(AppendInitSegment(false, true, false)); | 1649 ASSERT_TRUE(AppendInitSegment(false, true, false)); |
| 1658 | 1650 |
| 1659 // Test a simple cluster. | 1651 // Test a simple cluster. |
| 1660 scoped_ptr<Cluster> cluster_1(GenerateSingleStreamCluster(0, 132, | 1652 scoped_ptr<Cluster> cluster_1(GenerateSingleStreamCluster(0, 132, |
| 1661 kVideoTrackNum, kVideoBlockDuration)); | 1653 kVideoTrackNum, kVideoBlockDuration)); |
| 1662 | 1654 |
| (...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1946 // Append the missing range and verify that EndOfStream() succeeds now. | 1938 // Append the missing range and verify that EndOfStream() succeeds now. |
| 1947 ASSERT_TRUE(AppendData(video_id, cluster_v2->data(), cluster_v2->size())); | 1939 ASSERT_TRUE(AppendData(video_id, cluster_v2->data(), cluster_v2->size())); |
| 1948 | 1940 |
| 1949 CheckExpectedRanges(audio_id, "{ [0,35) }"); | 1941 CheckExpectedRanges(audio_id, "{ [0,35) }"); |
| 1950 CheckExpectedRanges(video_id, "{ [0,50) }"); | 1942 CheckExpectedRanges(video_id, "{ [0,50) }"); |
| 1951 | 1943 |
| 1952 ASSERT_TRUE(demuxer_->EndOfStream(PIPELINE_OK)); | 1944 ASSERT_TRUE(demuxer_->EndOfStream(PIPELINE_OK)); |
| 1953 } | 1945 } |
| 1954 | 1946 |
| 1955 TEST_F(ChunkDemuxerTest, TestGetBufferedRangesBeforeInitSegment) { | 1947 TEST_F(ChunkDemuxerTest, TestGetBufferedRangesBeforeInitSegment) { |
| 1956 EXPECT_CALL(*client_, DemuxerOpened(_)); | 1948 EXPECT_CALL(*this, DemuxerOpened()); |
| 1957 demuxer_->Initialize(&host_, CreateInitDoneCB(PIPELINE_OK)); | 1949 demuxer_->Initialize(&host_, CreateInitDoneCB(PIPELINE_OK)); |
| 1958 ASSERT_EQ(AddId("audio", true, false), ChunkDemuxer::kOk); | 1950 ASSERT_EQ(AddId("audio", true, false), ChunkDemuxer::kOk); |
| 1959 ASSERT_EQ(AddId("video", false, true), ChunkDemuxer::kOk); | 1951 ASSERT_EQ(AddId("video", false, true), ChunkDemuxer::kOk); |
| 1960 | 1952 |
| 1961 CheckExpectedRanges("audio", "{ }"); | 1953 CheckExpectedRanges("audio", "{ }"); |
| 1962 CheckExpectedRanges("video", "{ }"); | 1954 CheckExpectedRanges("video", "{ }"); |
| 1963 } | 1955 } |
| 1964 | 1956 |
| 1965 // Test that Seek() completes successfully when the first cluster | 1957 // Test that Seek() completes successfully when the first cluster |
| 1966 // arrives. | 1958 // arrives. |
| (...skipping 352 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2319 | 2311 |
| 2320 scoped_ptr<Cluster> cluster_a(kDefaultFirstCluster()); | 2312 scoped_ptr<Cluster> cluster_a(kDefaultFirstCluster()); |
| 2321 ASSERT_TRUE(AppendData(cluster_a->data(), cluster_a->size())); | 2313 ASSERT_TRUE(AppendData(cluster_a->data(), cluster_a->size())); |
| 2322 | 2314 |
| 2323 EXPECT_CALL(host_, SetDuration( | 2315 EXPECT_CALL(host_, SetDuration( |
| 2324 base::TimeDelta::FromMilliseconds(kDefaultFirstClusterEndTimestamp))); | 2316 base::TimeDelta::FromMilliseconds(kDefaultFirstClusterEndTimestamp))); |
| 2325 demuxer_->EndOfStream(PIPELINE_OK); | 2317 demuxer_->EndOfStream(PIPELINE_OK); |
| 2326 } | 2318 } |
| 2327 | 2319 |
| 2328 } // namespace media | 2320 } // namespace media |
| OLD | NEW |