Chromium Code Reviews| 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_) { |
|
Ami GONE FROM CHROMIUM
2012/09/12 18:45:34
braces unnecessary
acolwell GONE FROM CHROMIUM
2012/09/12 22:03:53
Done.
| |
| 423 EXPECT_CALL(*client_, DemuxerClosed()); | |
| 424 demuxer_->Shutdown(); | 409 demuxer_->Shutdown(); |
| 425 } | 410 } |
| 426 } | 411 } |
| 427 | 412 |
| 428 void AddSimpleBlock(ClusterBuilder* cb, int track_num, int64 timecode) { | 413 void AddSimpleBlock(ClusterBuilder* cb, int track_num, int64 timecode) { |
| 429 uint8 data[] = { 0x00 }; | 414 uint8 data[] = { 0x00 }; |
| 430 cb->AddSimpleBlock(track_num, timecode, 0, data, sizeof(data)); | 415 cb->AddSimpleBlock(track_num, timecode, 0, data, sizeof(data)); |
| 431 } | 416 } |
| 432 | 417 |
| 433 scoped_ptr<Cluster> GenerateCluster(int timecode, int block_count) { | 418 scoped_ptr<Cluster> GenerateCluster(int timecode, int block_count) { |
| (...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 622 bool ParseWebMFile(const std::string& filename, | 607 bool ParseWebMFile(const std::string& filename, |
| 623 const BufferTimestamps* timestamps, | 608 const BufferTimestamps* timestamps, |
| 624 const base::TimeDelta& duration) { | 609 const base::TimeDelta& duration) { |
| 625 return ParseWebMFile(filename, timestamps, duration, true, true); | 610 return ParseWebMFile(filename, timestamps, duration, true, true); |
| 626 } | 611 } |
| 627 | 612 |
| 628 bool ParseWebMFile(const std::string& filename, | 613 bool ParseWebMFile(const std::string& filename, |
| 629 const BufferTimestamps* timestamps, | 614 const BufferTimestamps* timestamps, |
| 630 const base::TimeDelta& duration, | 615 const base::TimeDelta& duration, |
| 631 bool has_audio, bool has_video) { | 616 bool has_audio, bool has_video) { |
| 632 EXPECT_CALL(*client_, DemuxerOpened(_)); | 617 EXPECT_CALL(*this, DemuxerOpened()); |
| 633 demuxer_->Initialize( | 618 demuxer_->Initialize( |
| 634 &host_, CreateInitDoneCB(duration, PIPELINE_OK)); | 619 &host_, CreateInitDoneCB(duration, PIPELINE_OK)); |
| 635 | 620 |
| 636 if (AddId(kSourceId, has_audio, has_video) != ChunkDemuxer::kOk) | 621 if (AddId(kSourceId, has_audio, has_video) != ChunkDemuxer::kOk) |
| 637 return false; | 622 return false; |
| 638 | 623 |
| 639 // Read a WebM file into memory and send the data to the demuxer. | 624 // Read a WebM file into memory and send the data to the demuxer. |
| 640 scoped_refptr<DecoderBuffer> buffer = ReadTestDataFile(filename); | 625 scoped_refptr<DecoderBuffer> buffer = ReadTestDataFile(filename); |
| 641 if (!AppendDataInPieces(buffer->GetData(), buffer->GetDataSize(), 512)) | 626 if (!AppendDataInPieces(buffer->GetData(), buffer->GetDataSize(), 512)) |
| 642 return false; | 627 return false; |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 671 timestamps[i].video_time_ms), | 656 timestamps[i].video_time_ms), |
| 672 &video_read_done)); | 657 &video_read_done)); |
| 673 | 658 |
| 674 EXPECT_TRUE(video_read_done); | 659 EXPECT_TRUE(video_read_done); |
| 675 } | 660 } |
| 676 } | 661 } |
| 677 | 662 |
| 678 return true; | 663 return true; |
| 679 } | 664 } |
| 680 | 665 |
| 666 MOCK_METHOD0(DemuxerOpened, void()); | |
| 667 // TODO(xhwang): This is a workaround of the issue that move-only parameters | |
| 668 // are not supported in mocked methods. Remove this when the issue is fixed | |
| 669 // (http://code.google.com/p/googletest/issues/detail?id=395) or when we use | |
| 670 // std::string instead of scoped_array<uint8> (http://crbug.com/130689). | |
| 671 MOCK_METHOD2(NeedKeyMock, void(const uint8* init_data, int init_data_size)); | |
| 672 void DemuxerNeedKey(scoped_array<uint8> init_data, int init_data_size) { | |
| 673 NeedKeyMock(init_data.get(), init_data_size); | |
| 674 } | |
| 675 | |
| 681 MessageLoop message_loop_; | 676 MessageLoop message_loop_; |
| 682 MockDemuxerHost host_; | 677 MockDemuxerHost host_; |
| 683 | 678 |
| 684 scoped_ptr<MockChunkDemuxerClient> client_; | |
| 685 scoped_refptr<ChunkDemuxer> demuxer_; | 679 scoped_refptr<ChunkDemuxer> demuxer_; |
| 686 | 680 |
| 687 private: | 681 private: |
| 688 DISALLOW_COPY_AND_ASSIGN(ChunkDemuxerTest); | 682 DISALLOW_COPY_AND_ASSIGN(ChunkDemuxerTest); |
| 689 }; | 683 }; |
| 690 | 684 |
| 691 TEST_F(ChunkDemuxerTest, TestInit) { | 685 TEST_F(ChunkDemuxerTest, TestInit) { |
| 692 // Test no streams, audio-only, video-only, and audio & video scenarios, | 686 // Test no streams, audio-only, video-only, and audio & video scenarios, |
| 693 // with video content encoded or not. | 687 // with video content encoded or not. |
| 694 for (int i = 0; i < 8; i++) { | 688 for (int i = 0; i < 8; i++) { |
| 695 bool has_audio = (i & 0x1) != 0; | 689 bool has_audio = (i & 0x1) != 0; |
| 696 bool has_video = (i & 0x2) != 0; | 690 bool has_video = (i & 0x2) != 0; |
| 697 bool video_content_encoded = (i & 0x4) != 0; | 691 bool video_content_encoded = (i & 0x4) != 0; |
| 698 | 692 |
| 699 // No test on invalid combination. | 693 // No test on invalid combination. |
| 700 if (!has_video && video_content_encoded) | 694 if (!has_video && video_content_encoded) |
| 701 continue; | 695 continue; |
| 702 | 696 |
| 703 client_.reset(new MockChunkDemuxerClient()); | 697 CreateNewDemuxer(); |
| 704 demuxer_ = new ChunkDemuxer(client_.get()); | |
| 705 if (has_video && video_content_encoded) | 698 if (has_video && video_content_encoded) |
| 706 EXPECT_CALL(*client_, NeedKeyMock(NotNull(), 16)); | 699 EXPECT_CALL(*this, NeedKeyMock(NotNull(), 16)); |
| 707 | 700 |
| 708 ASSERT_TRUE(InitDemuxer(has_audio, has_video, video_content_encoded)); | 701 ASSERT_TRUE(InitDemuxer(has_audio, has_video, video_content_encoded)); |
| 709 | 702 |
| 710 scoped_refptr<DemuxerStream> audio_stream = | 703 scoped_refptr<DemuxerStream> audio_stream = |
| 711 demuxer_->GetStream(DemuxerStream::AUDIO); | 704 demuxer_->GetStream(DemuxerStream::AUDIO); |
| 712 if (has_audio) { | 705 if (has_audio) { |
| 713 ASSERT_TRUE(audio_stream); | 706 ASSERT_TRUE(audio_stream); |
| 714 | 707 |
| 715 const AudioDecoderConfig& config = audio_stream->audio_decoder_config(); | 708 const AudioDecoderConfig& config = audio_stream->audio_decoder_config(); |
| 716 EXPECT_EQ(kCodecVorbis, config.codec()); | 709 EXPECT_EQ(kCodecVorbis, config.codec()); |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 732 } | 725 } |
| 733 | 726 |
| 734 ShutdownDemuxer(); | 727 ShutdownDemuxer(); |
| 735 demuxer_ = NULL; | 728 demuxer_ = NULL; |
| 736 } | 729 } |
| 737 } | 730 } |
| 738 | 731 |
| 739 // Make sure that the demuxer reports an error if Shutdown() | 732 // Make sure that the demuxer reports an error if Shutdown() |
| 740 // is called before all the initialization segments are appended. | 733 // is called before all the initialization segments are appended. |
| 741 TEST_F(ChunkDemuxerTest, TestShutdownBeforeAllInitSegmentsAppended) { | 734 TEST_F(ChunkDemuxerTest, TestShutdownBeforeAllInitSegmentsAppended) { |
| 742 EXPECT_CALL(*client_, DemuxerOpened(_)); | 735 EXPECT_CALL(*this, DemuxerOpened()); |
| 743 demuxer_->Initialize( | 736 demuxer_->Initialize( |
| 744 &host_, CreateInitDoneCB( | 737 &host_, CreateInitDoneCB( |
| 745 kDefaultDuration(), DEMUXER_ERROR_COULD_NOT_OPEN)); | 738 kDefaultDuration(), DEMUXER_ERROR_COULD_NOT_OPEN)); |
| 746 | 739 |
| 747 EXPECT_EQ(AddId("audio", true, false), ChunkDemuxer::kOk); | 740 EXPECT_EQ(AddId("audio", true, false), ChunkDemuxer::kOk); |
| 748 EXPECT_EQ(AddId("video", false, true), ChunkDemuxer::kOk); | 741 EXPECT_EQ(AddId("video", false, true), ChunkDemuxer::kOk); |
| 749 | 742 |
| 750 EXPECT_TRUE(AppendInitSegment("audio", true, false, false)); | 743 EXPECT_TRUE(AppendInitSegment("audio", true, false, false)); |
| 751 } | 744 } |
| 752 | 745 |
| (...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 953 AddSimpleBlock(&cb, kVideoTrackNum, 7); | 946 AddSimpleBlock(&cb, kVideoTrackNum, 7); |
| 954 scoped_ptr<Cluster> cluster(cb.Finish()); | 947 scoped_ptr<Cluster> cluster(cb.Finish()); |
| 955 | 948 |
| 956 EXPECT_CALL(host_, OnDemuxerError(PIPELINE_ERROR_DECODE)); | 949 EXPECT_CALL(host_, OnDemuxerError(PIPELINE_ERROR_DECODE)); |
| 957 ASSERT_TRUE(AppendData(cluster->data(), cluster->size())); | 950 ASSERT_TRUE(AppendData(cluster->data(), cluster->size())); |
| 958 } | 951 } |
| 959 | 952 |
| 960 // Test the case where a cluster is passed to AppendData() before | 953 // Test the case where a cluster is passed to AppendData() before |
| 961 // INFO & TRACKS data. | 954 // INFO & TRACKS data. |
| 962 TEST_F(ChunkDemuxerTest, TestClusterBeforeInitSegment) { | 955 TEST_F(ChunkDemuxerTest, TestClusterBeforeInitSegment) { |
| 963 EXPECT_CALL(*client_, DemuxerOpened(_)); | 956 EXPECT_CALL(*this, DemuxerOpened()); |
| 964 demuxer_->Initialize( | 957 demuxer_->Initialize( |
| 965 &host_, NewExpectedStatusCB(DEMUXER_ERROR_COULD_NOT_OPEN)); | 958 &host_, NewExpectedStatusCB(DEMUXER_ERROR_COULD_NOT_OPEN)); |
| 966 | 959 |
| 967 ASSERT_EQ(AddId(), ChunkDemuxer::kOk); | 960 ASSERT_EQ(AddId(), ChunkDemuxer::kOk); |
| 968 | 961 |
| 969 scoped_ptr<Cluster> cluster(GenerateCluster(0, 1)); | 962 scoped_ptr<Cluster> cluster(GenerateCluster(0, 1)); |
| 970 | 963 |
| 971 ASSERT_TRUE(AppendData(cluster->data(), cluster->size())); | 964 ASSERT_TRUE(AppendData(cluster->data(), cluster->size())); |
| 972 } | 965 } |
| 973 | 966 |
| 974 // Test cases where we get an EndOfStream() call during initialization. | 967 // Test cases where we get an EndOfStream() call during initialization. |
| 975 TEST_F(ChunkDemuxerTest, TestEOSDuringInit) { | 968 TEST_F(ChunkDemuxerTest, TestEOSDuringInit) { |
| 976 EXPECT_CALL(*client_, DemuxerOpened(_)); | 969 EXPECT_CALL(*this, DemuxerOpened()); |
| 977 demuxer_->Initialize( | 970 demuxer_->Initialize( |
| 978 &host_, NewExpectedStatusCB(DEMUXER_ERROR_COULD_NOT_OPEN)); | 971 &host_, NewExpectedStatusCB(DEMUXER_ERROR_COULD_NOT_OPEN)); |
| 979 demuxer_->EndOfStream(PIPELINE_OK); | 972 demuxer_->EndOfStream(PIPELINE_OK); |
| 980 } | 973 } |
| 981 | 974 |
| 982 TEST_F(ChunkDemuxerTest, TestEndOfStreamWithNoAppend) { | 975 TEST_F(ChunkDemuxerTest, TestEndOfStreamWithNoAppend) { |
| 983 EXPECT_CALL(*client_, DemuxerOpened(_)); | 976 EXPECT_CALL(*this, DemuxerOpened()); |
| 984 demuxer_->Initialize( | 977 demuxer_->Initialize( |
| 985 &host_, NewExpectedStatusCB(DEMUXER_ERROR_COULD_NOT_OPEN)); | 978 &host_, NewExpectedStatusCB(DEMUXER_ERROR_COULD_NOT_OPEN)); |
| 986 | 979 |
| 987 ASSERT_EQ(AddId(), ChunkDemuxer::kOk); | 980 ASSERT_EQ(AddId(), ChunkDemuxer::kOk); |
| 988 | 981 |
| 989 CheckExpectedRanges("{ }"); | 982 CheckExpectedRanges("{ }"); |
| 990 demuxer_->EndOfStream(PIPELINE_OK); | 983 demuxer_->EndOfStream(PIPELINE_OK); |
| 991 ShutdownDemuxer(); | 984 ShutdownDemuxer(); |
| 992 CheckExpectedRanges("{ }"); | 985 CheckExpectedRanges("{ }"); |
| 993 demuxer_->RemoveId(kSourceId); | 986 demuxer_->RemoveId(kSourceId); |
| (...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1162 end_of_stream_helper_2.RequestReads(); | 1155 end_of_stream_helper_2.RequestReads(); |
| 1163 end_of_stream_helper_2.CheckIfReadDonesWereCalled(true); | 1156 end_of_stream_helper_2.CheckIfReadDonesWereCalled(true); |
| 1164 | 1157 |
| 1165 end_of_stream_helper_3.RequestReads(); | 1158 end_of_stream_helper_3.RequestReads(); |
| 1166 end_of_stream_helper_3.CheckIfReadDonesWereCalled(true); | 1159 end_of_stream_helper_3.CheckIfReadDonesWereCalled(true); |
| 1167 } | 1160 } |
| 1168 | 1161 |
| 1169 // Make sure AppendData() will accept elements that span multiple calls. | 1162 // Make sure AppendData() will accept elements that span multiple calls. |
| 1170 TEST_F(ChunkDemuxerTest, TestAppendingInPieces) { | 1163 TEST_F(ChunkDemuxerTest, TestAppendingInPieces) { |
| 1171 | 1164 |
| 1172 EXPECT_CALL(*client_, DemuxerOpened(_)); | 1165 EXPECT_CALL(*this, DemuxerOpened()); |
| 1173 demuxer_->Initialize( | 1166 demuxer_->Initialize( |
| 1174 &host_, CreateInitDoneCB(kDefaultDuration(), PIPELINE_OK)); | 1167 &host_, CreateInitDoneCB(kDefaultDuration(), PIPELINE_OK)); |
| 1175 | 1168 |
| 1176 ASSERT_EQ(AddId(), ChunkDemuxer::kOk); | 1169 ASSERT_EQ(AddId(), ChunkDemuxer::kOk); |
| 1177 | 1170 |
| 1178 scoped_array<uint8> info_tracks; | 1171 scoped_array<uint8> info_tracks; |
| 1179 int info_tracks_size = 0; | 1172 int info_tracks_size = 0; |
| 1180 CreateInitSegment(true, true, false, &info_tracks, &info_tracks_size); | 1173 CreateInitSegment(true, true, false, &info_tracks, &info_tracks_size); |
| 1181 | 1174 |
| 1182 scoped_ptr<Cluster> cluster_a(kDefaultFirstCluster()); | 1175 scoped_ptr<Cluster> cluster_a(kDefaultFirstCluster()); |
| (...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1339 | 1332 |
| 1340 // Append the remaining data. | 1333 // Append the remaining data. |
| 1341 ASSERT_LT(i, cluster->size()); | 1334 ASSERT_LT(i, cluster->size()); |
| 1342 ASSERT_TRUE(AppendData(cluster->data() + i, cluster->size() - i)); | 1335 ASSERT_TRUE(AppendData(cluster->data() + i, cluster->size() - i)); |
| 1343 | 1336 |
| 1344 EXPECT_TRUE(audio_read_done); | 1337 EXPECT_TRUE(audio_read_done); |
| 1345 EXPECT_TRUE(video_read_done); | 1338 EXPECT_TRUE(video_read_done); |
| 1346 } | 1339 } |
| 1347 | 1340 |
| 1348 TEST_F(ChunkDemuxerTest, TestParseErrorDuringInit) { | 1341 TEST_F(ChunkDemuxerTest, TestParseErrorDuringInit) { |
| 1349 EXPECT_CALL(*client_, DemuxerOpened(_)); | 1342 EXPECT_CALL(*this, DemuxerOpened()); |
| 1350 demuxer_->Initialize( | 1343 demuxer_->Initialize( |
| 1351 &host_, CreateInitDoneCB( | 1344 &host_, CreateInitDoneCB( |
| 1352 kNoTimestamp(), DEMUXER_ERROR_COULD_NOT_OPEN)); | 1345 kNoTimestamp(), DEMUXER_ERROR_COULD_NOT_OPEN)); |
| 1353 | 1346 |
| 1354 ASSERT_EQ(AddId(), ChunkDemuxer::kOk); | 1347 ASSERT_EQ(AddId(), ChunkDemuxer::kOk); |
| 1355 | 1348 |
| 1356 uint8 tmp = 0; | 1349 uint8 tmp = 0; |
| 1357 ASSERT_TRUE(demuxer_->AppendData(kSourceId, &tmp, 1)); | 1350 ASSERT_TRUE(demuxer_->AppendData(kSourceId, &tmp, 1)); |
| 1358 } | 1351 } |
| 1359 | 1352 |
| 1360 TEST_F(ChunkDemuxerTest, TestAVHeadersWithAudioOnlyType) { | 1353 TEST_F(ChunkDemuxerTest, TestAVHeadersWithAudioOnlyType) { |
| 1361 EXPECT_CALL(*client_, DemuxerOpened(_)); | 1354 EXPECT_CALL(*this, DemuxerOpened()); |
| 1362 demuxer_->Initialize( | 1355 demuxer_->Initialize( |
| 1363 &host_, CreateInitDoneCB(kNoTimestamp(), | 1356 &host_, CreateInitDoneCB(kNoTimestamp(), |
| 1364 DEMUXER_ERROR_COULD_NOT_OPEN)); | 1357 DEMUXER_ERROR_COULD_NOT_OPEN)); |
| 1365 | 1358 |
| 1366 std::vector<std::string> codecs(1); | 1359 std::vector<std::string> codecs(1); |
| 1367 codecs[0] = "vorbis"; | 1360 codecs[0] = "vorbis"; |
| 1368 ASSERT_EQ(demuxer_->AddId(kSourceId, "audio/webm", codecs), | 1361 ASSERT_EQ(demuxer_->AddId(kSourceId, "audio/webm", codecs), |
| 1369 ChunkDemuxer::kOk); | 1362 ChunkDemuxer::kOk); |
| 1370 | 1363 |
| 1371 ASSERT_TRUE(AppendInitSegment(true, true, false)); | 1364 ASSERT_TRUE(AppendInitSegment(true, true, false)); |
| 1372 } | 1365 } |
| 1373 | 1366 |
| 1374 TEST_F(ChunkDemuxerTest, TestAVHeadersWithVideoOnlyType) { | 1367 TEST_F(ChunkDemuxerTest, TestAVHeadersWithVideoOnlyType) { |
| 1375 EXPECT_CALL(*client_, DemuxerOpened(_)); | 1368 EXPECT_CALL(*this, DemuxerOpened()); |
| 1376 demuxer_->Initialize( | 1369 demuxer_->Initialize( |
| 1377 &host_, CreateInitDoneCB(kNoTimestamp(), | 1370 &host_, CreateInitDoneCB(kNoTimestamp(), |
| 1378 DEMUXER_ERROR_COULD_NOT_OPEN)); | 1371 DEMUXER_ERROR_COULD_NOT_OPEN)); |
| 1379 | 1372 |
| 1380 std::vector<std::string> codecs(1); | 1373 std::vector<std::string> codecs(1); |
| 1381 codecs[0] = "vp8"; | 1374 codecs[0] = "vp8"; |
| 1382 ASSERT_EQ(demuxer_->AddId(kSourceId, "video/webm", codecs), | 1375 ASSERT_EQ(demuxer_->AddId(kSourceId, "video/webm", codecs), |
| 1383 ChunkDemuxer::kOk); | 1376 ChunkDemuxer::kOk); |
| 1384 | 1377 |
| 1385 ASSERT_TRUE(AppendInitSegment(true, true, false)); | 1378 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)); | 1415 GenerateSingleStreamCluster(0, 132, kVideoTrackNum, kVideoBlockDuration)); |
| 1423 | 1416 |
| 1424 // Append audio and video data into separate source ids. | 1417 // Append audio and video data into separate source ids. |
| 1425 ASSERT_TRUE(AppendData(audio_id, cluster_a->data(), cluster_a->size())); | 1418 ASSERT_TRUE(AppendData(audio_id, cluster_a->data(), cluster_a->size())); |
| 1426 GenerateSingleStreamExpectedReads(0, 4, audio, kAudioBlockDuration); | 1419 GenerateSingleStreamExpectedReads(0, 4, audio, kAudioBlockDuration); |
| 1427 ASSERT_TRUE(AppendData(video_id, cluster_v->data(), cluster_v->size())); | 1420 ASSERT_TRUE(AppendData(video_id, cluster_v->data(), cluster_v->size())); |
| 1428 GenerateSingleStreamExpectedReads(0, 4, video, kVideoBlockDuration); | 1421 GenerateSingleStreamExpectedReads(0, 4, video, kVideoBlockDuration); |
| 1429 } | 1422 } |
| 1430 | 1423 |
| 1431 TEST_F(ChunkDemuxerTest, TestAddIdFailures) { | 1424 TEST_F(ChunkDemuxerTest, TestAddIdFailures) { |
| 1432 EXPECT_CALL(*client_, DemuxerOpened(_)); | 1425 EXPECT_CALL(*this, DemuxerOpened()); |
| 1433 demuxer_->Initialize( | 1426 demuxer_->Initialize( |
| 1434 &host_, CreateInitDoneCB(kDefaultDuration(), PIPELINE_OK)); | 1427 &host_, CreateInitDoneCB(kDefaultDuration(), PIPELINE_OK)); |
| 1435 | 1428 |
| 1436 std::string audio_id = "audio1"; | 1429 std::string audio_id = "audio1"; |
| 1437 std::string video_id = "video1"; | 1430 std::string video_id = "video1"; |
| 1438 | 1431 |
| 1439 ASSERT_EQ(AddId(audio_id, true, false), ChunkDemuxer::kOk); | 1432 ASSERT_EQ(AddId(audio_id, true, false), ChunkDemuxer::kOk); |
| 1440 | 1433 |
| 1441 // Adding an id with audio/video should fail because we already added audio. | 1434 // Adding an id with audio/video should fail because we already added audio. |
| 1442 ASSERT_EQ(AddId(), ChunkDemuxer::kReachedIdLimit); | 1435 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())); | 1610 ASSERT_TRUE(AppendData(audio_id, cluster_a2->data(), cluster_a2->size())); |
| 1618 ASSERT_TRUE(AppendData(video_id, cluster_v2->data(), cluster_v2->size())); | 1611 ASSERT_TRUE(AppendData(video_id, cluster_v2->data(), cluster_v2->size())); |
| 1619 | 1612 |
| 1620 // Read() should return buffers at 3. | 1613 // Read() should return buffers at 3. |
| 1621 EXPECT_TRUE(audio_read_done); | 1614 EXPECT_TRUE(audio_read_done); |
| 1622 EXPECT_TRUE(video_read_done); | 1615 EXPECT_TRUE(video_read_done); |
| 1623 } | 1616 } |
| 1624 | 1617 |
| 1625 // Test ranges in an audio-only stream. | 1618 // Test ranges in an audio-only stream. |
| 1626 TEST_F(ChunkDemuxerTest, GetBufferedRanges_AudioIdOnly) { | 1619 TEST_F(ChunkDemuxerTest, GetBufferedRanges_AudioIdOnly) { |
| 1627 EXPECT_CALL(*client_, DemuxerOpened(_)); | 1620 EXPECT_CALL(*this, DemuxerOpened()); |
| 1628 demuxer_->Initialize( | 1621 demuxer_->Initialize( |
| 1629 &host_, CreateInitDoneCB(kDefaultDuration(), PIPELINE_OK)); | 1622 &host_, CreateInitDoneCB(kDefaultDuration(), PIPELINE_OK)); |
| 1630 | 1623 |
| 1631 ASSERT_EQ(AddId(kSourceId, true, false), ChunkDemuxer::kOk); | 1624 ASSERT_EQ(AddId(kSourceId, true, false), ChunkDemuxer::kOk); |
| 1632 ASSERT_TRUE(AppendInitSegment(true, false, false)); | 1625 ASSERT_TRUE(AppendInitSegment(true, false, false)); |
| 1633 | 1626 |
| 1634 // Test a simple cluster. | 1627 // Test a simple cluster. |
| 1635 scoped_ptr<Cluster> cluster_1(GenerateSingleStreamCluster(0, 92, | 1628 scoped_ptr<Cluster> cluster_1(GenerateSingleStreamCluster(0, 92, |
| 1636 kAudioTrackNum, kAudioBlockDuration)); | 1629 kAudioTrackNum, kAudioBlockDuration)); |
| 1637 ASSERT_TRUE(AppendData(cluster_1->data(), cluster_1->size())); | 1630 ASSERT_TRUE(AppendData(cluster_1->data(), cluster_1->size())); |
| 1638 | 1631 |
| 1639 CheckExpectedRanges("{ [0,92) }"); | 1632 CheckExpectedRanges("{ [0,92) }"); |
| 1640 | 1633 |
| 1641 // Append a disjoint cluster to check for two separate ranges. | 1634 // Append a disjoint cluster to check for two separate ranges. |
| 1642 scoped_ptr<Cluster> cluster_2(GenerateSingleStreamCluster(150, 219, | 1635 scoped_ptr<Cluster> cluster_2(GenerateSingleStreamCluster(150, 219, |
| 1643 kAudioTrackNum, kAudioBlockDuration)); | 1636 kAudioTrackNum, kAudioBlockDuration)); |
| 1644 | 1637 |
| 1645 ASSERT_TRUE(AppendData(cluster_2->data(), cluster_2->size())); | 1638 ASSERT_TRUE(AppendData(cluster_2->data(), cluster_2->size())); |
| 1646 | 1639 |
| 1647 CheckExpectedRanges("{ [0,92) [150,219) }"); | 1640 CheckExpectedRanges("{ [0,92) [150,219) }"); |
| 1648 } | 1641 } |
| 1649 | 1642 |
| 1650 // Test ranges in a video-only stream. | 1643 // Test ranges in a video-only stream. |
| 1651 TEST_F(ChunkDemuxerTest, GetBufferedRanges_VideoIdOnly) { | 1644 TEST_F(ChunkDemuxerTest, GetBufferedRanges_VideoIdOnly) { |
| 1652 EXPECT_CALL(*client_, DemuxerOpened(_)); | 1645 EXPECT_CALL(*this, DemuxerOpened()); |
| 1653 demuxer_->Initialize( | 1646 demuxer_->Initialize( |
| 1654 &host_, CreateInitDoneCB(kDefaultDuration(), PIPELINE_OK)); | 1647 &host_, CreateInitDoneCB(kDefaultDuration(), PIPELINE_OK)); |
| 1655 | 1648 |
| 1656 ASSERT_EQ(AddId(kSourceId, false, true), ChunkDemuxer::kOk); | 1649 ASSERT_EQ(AddId(kSourceId, false, true), ChunkDemuxer::kOk); |
| 1657 ASSERT_TRUE(AppendInitSegment(false, true, false)); | 1650 ASSERT_TRUE(AppendInitSegment(false, true, false)); |
| 1658 | 1651 |
| 1659 // Test a simple cluster. | 1652 // Test a simple cluster. |
| 1660 scoped_ptr<Cluster> cluster_1(GenerateSingleStreamCluster(0, 132, | 1653 scoped_ptr<Cluster> cluster_1(GenerateSingleStreamCluster(0, 132, |
| 1661 kVideoTrackNum, kVideoBlockDuration)); | 1654 kVideoTrackNum, kVideoBlockDuration)); |
| 1662 | 1655 |
| (...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1946 // Append the missing range and verify that EndOfStream() succeeds now. | 1939 // Append the missing range and verify that EndOfStream() succeeds now. |
| 1947 ASSERT_TRUE(AppendData(video_id, cluster_v2->data(), cluster_v2->size())); | 1940 ASSERT_TRUE(AppendData(video_id, cluster_v2->data(), cluster_v2->size())); |
| 1948 | 1941 |
| 1949 CheckExpectedRanges(audio_id, "{ [0,35) }"); | 1942 CheckExpectedRanges(audio_id, "{ [0,35) }"); |
| 1950 CheckExpectedRanges(video_id, "{ [0,50) }"); | 1943 CheckExpectedRanges(video_id, "{ [0,50) }"); |
| 1951 | 1944 |
| 1952 ASSERT_TRUE(demuxer_->EndOfStream(PIPELINE_OK)); | 1945 ASSERT_TRUE(demuxer_->EndOfStream(PIPELINE_OK)); |
| 1953 } | 1946 } |
| 1954 | 1947 |
| 1955 TEST_F(ChunkDemuxerTest, TestGetBufferedRangesBeforeInitSegment) { | 1948 TEST_F(ChunkDemuxerTest, TestGetBufferedRangesBeforeInitSegment) { |
| 1956 EXPECT_CALL(*client_, DemuxerOpened(_)); | 1949 EXPECT_CALL(*this, DemuxerOpened()); |
| 1957 demuxer_->Initialize(&host_, CreateInitDoneCB(PIPELINE_OK)); | 1950 demuxer_->Initialize(&host_, CreateInitDoneCB(PIPELINE_OK)); |
| 1958 ASSERT_EQ(AddId("audio", true, false), ChunkDemuxer::kOk); | 1951 ASSERT_EQ(AddId("audio", true, false), ChunkDemuxer::kOk); |
| 1959 ASSERT_EQ(AddId("video", false, true), ChunkDemuxer::kOk); | 1952 ASSERT_EQ(AddId("video", false, true), ChunkDemuxer::kOk); |
| 1960 | 1953 |
| 1961 CheckExpectedRanges("audio", "{ }"); | 1954 CheckExpectedRanges("audio", "{ }"); |
| 1962 CheckExpectedRanges("video", "{ }"); | 1955 CheckExpectedRanges("video", "{ }"); |
| 1963 } | 1956 } |
| 1964 | 1957 |
| 1965 // Test that Seek() completes successfully when the first cluster | 1958 // Test that Seek() completes successfully when the first cluster |
| 1966 // arrives. | 1959 // arrives. |
| (...skipping 352 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2319 | 2312 |
| 2320 scoped_ptr<Cluster> cluster_a(kDefaultFirstCluster()); | 2313 scoped_ptr<Cluster> cluster_a(kDefaultFirstCluster()); |
| 2321 ASSERT_TRUE(AppendData(cluster_a->data(), cluster_a->size())); | 2314 ASSERT_TRUE(AppendData(cluster_a->data(), cluster_a->size())); |
| 2322 | 2315 |
| 2323 EXPECT_CALL(host_, SetDuration( | 2316 EXPECT_CALL(host_, SetDuration( |
| 2324 base::TimeDelta::FromMilliseconds(kDefaultFirstClusterEndTimestamp))); | 2317 base::TimeDelta::FromMilliseconds(kDefaultFirstClusterEndTimestamp))); |
| 2325 demuxer_->EndOfStream(PIPELINE_OK); | 2318 demuxer_->EndOfStream(PIPELINE_OK); |
| 2326 } | 2319 } |
| 2327 | 2320 |
| 2328 } // namespace media | 2321 } // namespace media |
| OLD | NEW |