| 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 "media/base/audio_decoder_config.h" | 6 #include "media/base/audio_decoder_config.h" |
| 7 #include "media/base/mock_callback.h" | 7 #include "media/base/mock_callback.h" |
| 8 #include "media/base/mock_demuxer_host.h" | 8 #include "media/base/mock_demuxer_host.h" |
| 9 #include "media/base/test_data_util.h" | 9 #include "media/base/test_data_util.h" |
| 10 #include "media/filters/chunk_demuxer.h" | 10 #include "media/filters/chunk_demuxer.h" |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 83 protected: | 83 protected: |
| 84 enum CodecsIndex { | 84 enum CodecsIndex { |
| 85 AUDIO, | 85 AUDIO, |
| 86 VIDEO, | 86 VIDEO, |
| 87 MAX_CODECS_INDEX | 87 MAX_CODECS_INDEX |
| 88 }; | 88 }; |
| 89 | 89 |
| 90 ChunkDemuxerTest() | 90 ChunkDemuxerTest() |
| 91 : client_(new MockChunkDemuxerClient()), | 91 : client_(new MockChunkDemuxerClient()), |
| 92 demuxer_(new ChunkDemuxer(client_.get())) { | 92 demuxer_(new ChunkDemuxer(client_.get())) { |
| 93 demuxer_->set_host(&mock_demuxer_host_); | |
| 94 } | 93 } |
| 95 | 94 |
| 96 virtual ~ChunkDemuxerTest() { | 95 virtual ~ChunkDemuxerTest() { |
| 97 ShutdownDemuxer(); | 96 ShutdownDemuxer(); |
| 98 } | 97 } |
| 99 | 98 |
| 100 void CreateInfoTracks(bool has_audio, bool has_video, | 99 void CreateInfoTracks(bool has_audio, bool has_video, |
| 101 bool video_content_encoded, scoped_array<uint8>* buffer, | 100 bool video_content_encoded, scoped_array<uint8>* buffer, |
| 102 int* size) { | 101 int* size) { |
| 103 scoped_array<uint8> info; | 102 scoped_array<uint8> info; |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 154 video_content_encodings_size); | 153 video_content_encodings_size); |
| 155 video_track_entry_size += video_content_encodings_size; | 154 video_track_entry_size += video_content_encodings_size; |
| 156 WriteInt64(buf + kVideoTrackSizeOffset, | 155 WriteInt64(buf + kVideoTrackSizeOffset, |
| 157 video_track_entry_size - kVideoTrackEntryHeaderSize); | 156 video_track_entry_size - kVideoTrackEntryHeaderSize); |
| 158 } | 157 } |
| 159 buf += video_track_entry_size; | 158 buf += video_track_entry_size; |
| 160 } | 159 } |
| 161 } | 160 } |
| 162 | 161 |
| 163 bool AppendData(const uint8* data, size_t length) { | 162 bool AppendData(const uint8* data, size_t length) { |
| 164 EXPECT_CALL(mock_demuxer_host_, SetBufferedBytes(_)).Times(AnyNumber()); | 163 EXPECT_CALL(host_, SetBufferedBytes(_)).Times(AnyNumber()); |
| 165 EXPECT_CALL(mock_demuxer_host_, SetBufferedTime(_)).Times(AnyNumber()); | 164 EXPECT_CALL(host_, SetBufferedTime(_)).Times(AnyNumber()); |
| 166 EXPECT_CALL(mock_demuxer_host_, SetNetworkActivity(true)) | 165 EXPECT_CALL(host_, SetNetworkActivity(true)) |
| 167 .Times(AnyNumber()); | 166 .Times(AnyNumber()); |
| 168 return demuxer_->AppendData(data, length); | 167 return demuxer_->AppendData(data, length); |
| 169 } | 168 } |
| 170 | 169 |
| 171 bool AppendDataInPieces(const uint8* data, size_t length) { | 170 bool AppendDataInPieces(const uint8* data, size_t length) { |
| 172 return AppendDataInPieces(data, length, 7); | 171 return AppendDataInPieces(data, length, 7); |
| 173 } | 172 } |
| 174 | 173 |
| 175 bool AppendDataInPieces(const uint8* data, size_t length, size_t piece_size) { | 174 bool AppendDataInPieces(const uint8* data, size_t length, size_t piece_size) { |
| 176 const uint8* start = data; | 175 const uint8* start = data; |
| (...skipping 18 matching lines...) Expand all Loading... |
| 195 } | 194 } |
| 196 | 195 |
| 197 void InitDoneCalled(PipelineStatus expected_status, | 196 void InitDoneCalled(PipelineStatus expected_status, |
| 198 PipelineStatus status) { | 197 PipelineStatus status) { |
| 199 EXPECT_EQ(status, expected_status); | 198 EXPECT_EQ(status, expected_status); |
| 200 } | 199 } |
| 201 | 200 |
| 202 PipelineStatusCB CreateInitDoneCB(const base::TimeDelta& expected_duration, | 201 PipelineStatusCB CreateInitDoneCB(const base::TimeDelta& expected_duration, |
| 203 PipelineStatus expected_status) { | 202 PipelineStatus expected_status) { |
| 204 if (expected_status == PIPELINE_OK) { | 203 if (expected_status == PIPELINE_OK) { |
| 205 EXPECT_CALL(mock_demuxer_host_, SetDuration(expected_duration)); | 204 EXPECT_CALL(host_, SetDuration(expected_duration)); |
| 206 EXPECT_CALL(mock_demuxer_host_, SetCurrentReadPosition(_)); | 205 EXPECT_CALL(host_, SetCurrentReadPosition(_)); |
| 207 } | 206 } |
| 208 | 207 |
| 209 return base::Bind(&ChunkDemuxerTest::InitDoneCalled, | 208 return base::Bind(&ChunkDemuxerTest::InitDoneCalled, |
| 210 base::Unretained(this), | 209 base::Unretained(this), |
| 211 expected_status); | 210 expected_status); |
| 212 } | 211 } |
| 213 | 212 |
| 214 bool InitDemuxer(bool has_audio, bool has_video, | 213 bool InitDemuxer(bool has_audio, bool has_video, |
| 215 bool video_content_encoded) { | 214 bool video_content_encoded) { |
| 216 PipelineStatus expected_status = | 215 PipelineStatus expected_status = |
| 217 (has_audio || has_video) ? PIPELINE_OK : DEMUXER_ERROR_COULD_NOT_OPEN; | 216 (has_audio || has_video) ? PIPELINE_OK : DEMUXER_ERROR_COULD_NOT_OPEN; |
| 218 | 217 |
| 219 EXPECT_CALL(*client_, DemuxerOpened(_)); | 218 EXPECT_CALL(*client_, DemuxerOpened(_)); |
| 220 demuxer_->Initialize(CreateInitDoneCB( | 219 demuxer_->Initialize( |
| 221 kDefaultDuration(), expected_status)); | 220 &host_, CreateInitDoneCB(kDefaultDuration(), expected_status)); |
| 222 | 221 |
| 223 return AppendInfoTracks(has_audio, has_video, video_content_encoded); | 222 return AppendInfoTracks(has_audio, has_video, video_content_encoded); |
| 224 } | 223 } |
| 225 | 224 |
| 226 void ShutdownDemuxer() { | 225 void ShutdownDemuxer() { |
| 227 if (demuxer_) { | 226 if (demuxer_) { |
| 228 EXPECT_CALL(*client_, DemuxerClosed()); | 227 EXPECT_CALL(*client_, DemuxerClosed()); |
| 229 demuxer_->Shutdown(); | 228 demuxer_->Shutdown(); |
| 230 } | 229 } |
| 231 } | 230 } |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 263 // a timestamp of kSkip indicates that a Read() call for that stream | 262 // a timestamp of kSkip indicates that a Read() call for that stream |
| 264 // shouldn't be made on that iteration of the loop. If both streams have | 263 // shouldn't be made on that iteration of the loop. If both streams have |
| 265 // a kSkip then the loop will terminate. | 264 // a kSkip then the loop will terminate. |
| 266 bool ParseWebMFile(const std::string& filename, | 265 bool ParseWebMFile(const std::string& filename, |
| 267 const BufferTimestamps* timestamps, | 266 const BufferTimestamps* timestamps, |
| 268 const base::TimeDelta& duration) { | 267 const base::TimeDelta& duration) { |
| 269 scoped_array<uint8> buffer; | 268 scoped_array<uint8> buffer; |
| 270 int buffer_size = 0; | 269 int buffer_size = 0; |
| 271 | 270 |
| 272 EXPECT_CALL(*client_, DemuxerOpened(_)); | 271 EXPECT_CALL(*client_, DemuxerOpened(_)); |
| 273 demuxer_->Initialize(CreateInitDoneCB(duration, PIPELINE_OK)); | 272 demuxer_->Initialize( |
| 273 &host_, CreateInitDoneCB(duration, PIPELINE_OK)); |
| 274 | 274 |
| 275 // Read a WebM file into memory and send the data to the demuxer. | 275 // Read a WebM file into memory and send the data to the demuxer. |
| 276 ReadTestDataFile(filename, &buffer, &buffer_size); | 276 ReadTestDataFile(filename, &buffer, &buffer_size); |
| 277 if (!AppendDataInPieces(buffer.get(), buffer_size, 512)) | 277 if (!AppendDataInPieces(buffer.get(), buffer_size, 512)) |
| 278 return false; | 278 return false; |
| 279 | 279 |
| 280 scoped_refptr<DemuxerStream> audio = | 280 scoped_refptr<DemuxerStream> audio = |
| 281 demuxer_->GetStream(DemuxerStream::AUDIO); | 281 demuxer_->GetStream(DemuxerStream::AUDIO); |
| 282 scoped_refptr<DemuxerStream> video = | 282 scoped_refptr<DemuxerStream> video = |
| 283 demuxer_->GetStream(DemuxerStream::VIDEO); | 283 demuxer_->GetStream(DemuxerStream::VIDEO); |
| (...skipping 23 matching lines...) Expand all Loading... |
| 307 timestamps[i].video_time_ms), | 307 timestamps[i].video_time_ms), |
| 308 &video_read_done)); | 308 &video_read_done)); |
| 309 | 309 |
| 310 EXPECT_TRUE(video_read_done); | 310 EXPECT_TRUE(video_read_done); |
| 311 } | 311 } |
| 312 } | 312 } |
| 313 | 313 |
| 314 return true; | 314 return true; |
| 315 } | 315 } |
| 316 | 316 |
| 317 MockDemuxerHost mock_demuxer_host_; | 317 MockDemuxerHost host_; |
| 318 | 318 |
| 319 scoped_ptr<MockChunkDemuxerClient> client_; | 319 scoped_ptr<MockChunkDemuxerClient> client_; |
| 320 scoped_refptr<ChunkDemuxer> demuxer_; | 320 scoped_refptr<ChunkDemuxer> demuxer_; |
| 321 | 321 |
| 322 private: | 322 private: |
| 323 DISALLOW_COPY_AND_ASSIGN(ChunkDemuxerTest); | 323 DISALLOW_COPY_AND_ASSIGN(ChunkDemuxerTest); |
| 324 }; | 324 }; |
| 325 | 325 |
| 326 TEST_F(ChunkDemuxerTest, TestInit) { | 326 TEST_F(ChunkDemuxerTest, TestInit) { |
| 327 // Test no streams, audio-only, video-only, and audio & video scenarios, | 327 // Test no streams, audio-only, video-only, and audio & video scenarios, |
| 328 // with video content encoded or not. | 328 // with video content encoded or not. |
| 329 for (int i = 0; i < 8; i++) { | 329 for (int i = 0; i < 8; i++) { |
| 330 bool has_audio = (i & 0x1) != 0; | 330 bool has_audio = (i & 0x1) != 0; |
| 331 bool has_video = (i & 0x2) != 0; | 331 bool has_video = (i & 0x2) != 0; |
| 332 bool video_content_encoded = (i & 0x4) != 0; | 332 bool video_content_encoded = (i & 0x4) != 0; |
| 333 | 333 |
| 334 // No test on invalid combination. | 334 // No test on invalid combination. |
| 335 if (!has_video && video_content_encoded) | 335 if (!has_video && video_content_encoded) |
| 336 continue; | 336 continue; |
| 337 | 337 |
| 338 client_.reset(new MockChunkDemuxerClient()); | 338 client_.reset(new MockChunkDemuxerClient()); |
| 339 demuxer_ = new ChunkDemuxer(client_.get()); | 339 demuxer_ = new ChunkDemuxer(client_.get()); |
| 340 demuxer_->set_host(&mock_demuxer_host_); | |
| 341 ASSERT_TRUE(InitDemuxer(has_audio, has_video, video_content_encoded)); | 340 ASSERT_TRUE(InitDemuxer(has_audio, has_video, video_content_encoded)); |
| 342 | 341 |
| 343 scoped_refptr<DemuxerStream> audio_stream = | 342 scoped_refptr<DemuxerStream> audio_stream = |
| 344 demuxer_->GetStream(DemuxerStream::AUDIO); | 343 demuxer_->GetStream(DemuxerStream::AUDIO); |
| 345 if (has_audio) { | 344 if (has_audio) { |
| 346 ASSERT_TRUE(audio_stream); | 345 ASSERT_TRUE(audio_stream); |
| 347 | 346 |
| 348 const AudioDecoderConfig& config = audio_stream->audio_decoder_config(); | 347 const AudioDecoderConfig& config = audio_stream->audio_decoder_config(); |
| 349 EXPECT_EQ(kCodecVorbis, config.codec()); | 348 EXPECT_EQ(kCodecVorbis, config.codec()); |
| 350 EXPECT_EQ(16, config.bits_per_channel()); | 349 EXPECT_EQ(16, config.bits_per_channel()); |
| (...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 513 // that overlaps. | 512 // that overlaps. |
| 514 cb.SetClusterTimecode(5); | 513 cb.SetClusterTimecode(5); |
| 515 AddSimpleBlock(&cb, kAudioTrackNum, 5); | 514 AddSimpleBlock(&cb, kAudioTrackNum, 5); |
| 516 AddSimpleBlock(&cb, kVideoTrackNum, 7); | 515 AddSimpleBlock(&cb, kVideoTrackNum, 7); |
| 517 AddSimpleBlock(&cb, kAudioTrackNum, 28); | 516 AddSimpleBlock(&cb, kAudioTrackNum, 28); |
| 518 AddSimpleBlock(&cb, kVideoTrackNum, 40); | 517 AddSimpleBlock(&cb, kVideoTrackNum, 40); |
| 519 scoped_ptr<Cluster> cluster_b(cb.Finish()); | 518 scoped_ptr<Cluster> cluster_b(cb.Finish()); |
| 520 | 519 |
| 521 // Make sure that AppendData() fails because this cluster data | 520 // Make sure that AppendData() fails because this cluster data |
| 522 // is before previous data. | 521 // is before previous data. |
| 523 EXPECT_CALL(mock_demuxer_host_, OnDemuxerError(PIPELINE_ERROR_DECODE)); | 522 EXPECT_CALL(host_, OnDemuxerError(PIPELINE_ERROR_DECODE)); |
| 524 ASSERT_TRUE(AppendData(cluster_b->data(), cluster_b->size())); | 523 ASSERT_TRUE(AppendData(cluster_b->data(), cluster_b->size())); |
| 525 | 524 |
| 526 // Verify that AppendData() doesn't accept more data now. | 525 // Verify that AppendData() doesn't accept more data now. |
| 527 cb.SetClusterTimecode(45); | 526 cb.SetClusterTimecode(45); |
| 528 AddSimpleBlock(&cb, kAudioTrackNum, 45); | 527 AddSimpleBlock(&cb, kAudioTrackNum, 45); |
| 529 AddSimpleBlock(&cb, kVideoTrackNum, 45); | 528 AddSimpleBlock(&cb, kVideoTrackNum, 45); |
| 530 scoped_ptr<Cluster> cluster_c(cb.Finish()); | 529 scoped_ptr<Cluster> cluster_c(cb.Finish()); |
| 531 EXPECT_FALSE(demuxer_->AppendData(cluster_c->data(), cluster_c->size())); | 530 EXPECT_FALSE(demuxer_->AppendData(cluster_c->data(), cluster_c->size())); |
| 532 } | 531 } |
| 533 | 532 |
| 534 TEST_F(ChunkDemuxerTest, TestNonMonotonicButAboveClusterTimecode) { | 533 TEST_F(ChunkDemuxerTest, TestNonMonotonicButAboveClusterTimecode) { |
| 535 ASSERT_TRUE(InitDemuxer(true, true, false)); | 534 ASSERT_TRUE(InitDemuxer(true, true, false)); |
| 536 | 535 |
| 537 ClusterBuilder cb; | 536 ClusterBuilder cb; |
| 538 | 537 |
| 539 // Test the case where block timecodes are not monotonically | 538 // Test the case where block timecodes are not monotonically |
| 540 // increasing but stay above the cluster timecode. | 539 // increasing but stay above the cluster timecode. |
| 541 cb.SetClusterTimecode(5); | 540 cb.SetClusterTimecode(5); |
| 542 AddSimpleBlock(&cb, kAudioTrackNum, 5); | 541 AddSimpleBlock(&cb, kAudioTrackNum, 5); |
| 543 AddSimpleBlock(&cb, kVideoTrackNum, 10); | 542 AddSimpleBlock(&cb, kVideoTrackNum, 10); |
| 544 AddSimpleBlock(&cb, kAudioTrackNum, 7); | 543 AddSimpleBlock(&cb, kAudioTrackNum, 7); |
| 545 AddSimpleBlock(&cb, kVideoTrackNum, 15); | 544 AddSimpleBlock(&cb, kVideoTrackNum, 15); |
| 546 scoped_ptr<Cluster> cluster_a(cb.Finish()); | 545 scoped_ptr<Cluster> cluster_a(cb.Finish()); |
| 547 | 546 |
| 548 EXPECT_CALL(mock_demuxer_host_, OnDemuxerError(PIPELINE_ERROR_DECODE)); | 547 EXPECT_CALL(host_, OnDemuxerError(PIPELINE_ERROR_DECODE)); |
| 549 ASSERT_TRUE(AppendData(cluster_a->data(), cluster_a->size())); | 548 ASSERT_TRUE(AppendData(cluster_a->data(), cluster_a->size())); |
| 550 | 549 |
| 551 // Verify that AppendData() doesn't accept more data now. | 550 // Verify that AppendData() doesn't accept more data now. |
| 552 cb.SetClusterTimecode(20); | 551 cb.SetClusterTimecode(20); |
| 553 AddSimpleBlock(&cb, kAudioTrackNum, 20); | 552 AddSimpleBlock(&cb, kAudioTrackNum, 20); |
| 554 AddSimpleBlock(&cb, kVideoTrackNum, 20); | 553 AddSimpleBlock(&cb, kVideoTrackNum, 20); |
| 555 scoped_ptr<Cluster> cluster_b(cb.Finish()); | 554 scoped_ptr<Cluster> cluster_b(cb.Finish()); |
| 556 EXPECT_FALSE(demuxer_->AppendData(cluster_b->data(), cluster_b->size())); | 555 EXPECT_FALSE(demuxer_->AppendData(cluster_b->data(), cluster_b->size())); |
| 557 } | 556 } |
| 558 | 557 |
| 559 TEST_F(ChunkDemuxerTest, TestBackwardsAndBeforeClusterTimecode) { | 558 TEST_F(ChunkDemuxerTest, TestBackwardsAndBeforeClusterTimecode) { |
| 560 ASSERT_TRUE(InitDemuxer(true, true, false)); | 559 ASSERT_TRUE(InitDemuxer(true, true, false)); |
| 561 | 560 |
| 562 ClusterBuilder cb; | 561 ClusterBuilder cb; |
| 563 | 562 |
| 564 // Test timecodes going backwards and including values less than the cluster | 563 // Test timecodes going backwards and including values less than the cluster |
| 565 // timecode. | 564 // timecode. |
| 566 cb.SetClusterTimecode(5); | 565 cb.SetClusterTimecode(5); |
| 567 AddSimpleBlock(&cb, kAudioTrackNum, 5); | 566 AddSimpleBlock(&cb, kAudioTrackNum, 5); |
| 568 AddSimpleBlock(&cb, kVideoTrackNum, 5); | 567 AddSimpleBlock(&cb, kVideoTrackNum, 5); |
| 569 AddSimpleBlock(&cb, kAudioTrackNum, 3); | 568 AddSimpleBlock(&cb, kAudioTrackNum, 3); |
| 570 AddSimpleBlock(&cb, kVideoTrackNum, 3); | 569 AddSimpleBlock(&cb, kVideoTrackNum, 3); |
| 571 scoped_ptr<Cluster> cluster_a(cb.Finish()); | 570 scoped_ptr<Cluster> cluster_a(cb.Finish()); |
| 572 | 571 |
| 573 EXPECT_CALL(mock_demuxer_host_, OnDemuxerError(PIPELINE_ERROR_DECODE)); | 572 EXPECT_CALL(host_, OnDemuxerError(PIPELINE_ERROR_DECODE)); |
| 574 ASSERT_TRUE(AppendData(cluster_a->data(), cluster_a->size())); | 573 ASSERT_TRUE(AppendData(cluster_a->data(), cluster_a->size())); |
| 575 | 574 |
| 576 // Verify that AppendData() doesn't accept more data now. | 575 // Verify that AppendData() doesn't accept more data now. |
| 577 cb.SetClusterTimecode(6); | 576 cb.SetClusterTimecode(6); |
| 578 AddSimpleBlock(&cb, kAudioTrackNum, 6); | 577 AddSimpleBlock(&cb, kAudioTrackNum, 6); |
| 579 AddSimpleBlock(&cb, kVideoTrackNum, 6); | 578 AddSimpleBlock(&cb, kVideoTrackNum, 6); |
| 580 scoped_ptr<Cluster> cluster_b(cb.Finish()); | 579 scoped_ptr<Cluster> cluster_b(cb.Finish()); |
| 581 EXPECT_FALSE(demuxer_->AppendData(cluster_b->data(), cluster_b->size())); | 580 EXPECT_FALSE(demuxer_->AppendData(cluster_b->data(), cluster_b->size())); |
| 582 } | 581 } |
| 583 | 582 |
| 584 | 583 |
| 585 TEST_F(ChunkDemuxerTest, TestPerStreamMonotonicallyIncreasingTimestamps) { | 584 TEST_F(ChunkDemuxerTest, TestPerStreamMonotonicallyIncreasingTimestamps) { |
| 586 ASSERT_TRUE(InitDemuxer(true, true, false)); | 585 ASSERT_TRUE(InitDemuxer(true, true, false)); |
| 587 | 586 |
| 588 ClusterBuilder cb; | 587 ClusterBuilder cb; |
| 589 | 588 |
| 590 // Test strict monotonic increasing timestamps on a per stream | 589 // Test strict monotonic increasing timestamps on a per stream |
| 591 // basis. | 590 // basis. |
| 592 cb.SetClusterTimecode(5); | 591 cb.SetClusterTimecode(5); |
| 593 AddSimpleBlock(&cb, kAudioTrackNum, 5); | 592 AddSimpleBlock(&cb, kAudioTrackNum, 5); |
| 594 AddSimpleBlock(&cb, kVideoTrackNum, 5); | 593 AddSimpleBlock(&cb, kVideoTrackNum, 5); |
| 595 AddSimpleBlock(&cb, kAudioTrackNum, 5); | 594 AddSimpleBlock(&cb, kAudioTrackNum, 5); |
| 596 AddSimpleBlock(&cb, kVideoTrackNum, 7); | 595 AddSimpleBlock(&cb, kVideoTrackNum, 7); |
| 597 scoped_ptr<Cluster> cluster(cb.Finish()); | 596 scoped_ptr<Cluster> cluster(cb.Finish()); |
| 598 | 597 |
| 599 EXPECT_CALL(mock_demuxer_host_, OnDemuxerError(PIPELINE_ERROR_DECODE)); | 598 EXPECT_CALL(host_, OnDemuxerError(PIPELINE_ERROR_DECODE)); |
| 600 ASSERT_TRUE(AppendData(cluster->data(), cluster->size())); | 599 ASSERT_TRUE(AppendData(cluster->data(), cluster->size())); |
| 601 } | 600 } |
| 602 | 601 |
| 603 TEST_F(ChunkDemuxerTest, TestMonotonicallyIncreasingTimestampsAcrossClusters) { | 602 TEST_F(ChunkDemuxerTest, TestMonotonicallyIncreasingTimestampsAcrossClusters) { |
| 604 ASSERT_TRUE(InitDemuxer(true, true, false)); | 603 ASSERT_TRUE(InitDemuxer(true, true, false)); |
| 605 | 604 |
| 606 ClusterBuilder cb; | 605 ClusterBuilder cb; |
| 607 | 606 |
| 608 // Test strict monotonic increasing timestamps on a per stream | 607 // Test strict monotonic increasing timestamps on a per stream |
| 609 // basis across clusters. | 608 // basis across clusters. |
| 610 cb.SetClusterTimecode(5); | 609 cb.SetClusterTimecode(5); |
| 611 AddSimpleBlock(&cb, kAudioTrackNum, 5); | 610 AddSimpleBlock(&cb, kAudioTrackNum, 5); |
| 612 AddSimpleBlock(&cb, kVideoTrackNum, 5); | 611 AddSimpleBlock(&cb, kVideoTrackNum, 5); |
| 613 scoped_ptr<Cluster> cluster_a(cb.Finish()); | 612 scoped_ptr<Cluster> cluster_a(cb.Finish()); |
| 614 | 613 |
| 615 ASSERT_TRUE(AppendData(cluster_a->data(), cluster_a->size())); | 614 ASSERT_TRUE(AppendData(cluster_a->data(), cluster_a->size())); |
| 616 | 615 |
| 617 cb.SetClusterTimecode(5); | 616 cb.SetClusterTimecode(5); |
| 618 AddSimpleBlock(&cb, kAudioTrackNum, 5); | 617 AddSimpleBlock(&cb, kAudioTrackNum, 5); |
| 619 AddSimpleBlock(&cb, kVideoTrackNum, 7); | 618 AddSimpleBlock(&cb, kVideoTrackNum, 7); |
| 620 scoped_ptr<Cluster> cluster_b(cb.Finish()); | 619 scoped_ptr<Cluster> cluster_b(cb.Finish()); |
| 621 | 620 |
| 622 EXPECT_CALL(mock_demuxer_host_, OnDemuxerError(PIPELINE_ERROR_DECODE)); | 621 EXPECT_CALL(host_, OnDemuxerError(PIPELINE_ERROR_DECODE)); |
| 623 ASSERT_TRUE(AppendData(cluster_b->data(), cluster_b->size())); | 622 ASSERT_TRUE(AppendData(cluster_b->data(), cluster_b->size())); |
| 624 | 623 |
| 625 // Verify that AppendData() doesn't accept more data now. | 624 // Verify that AppendData() doesn't accept more data now. |
| 626 cb.SetClusterTimecode(10); | 625 cb.SetClusterTimecode(10); |
| 627 AddSimpleBlock(&cb, kAudioTrackNum, 10); | 626 AddSimpleBlock(&cb, kAudioTrackNum, 10); |
| 628 AddSimpleBlock(&cb, kVideoTrackNum, 10); | 627 AddSimpleBlock(&cb, kVideoTrackNum, 10); |
| 629 scoped_ptr<Cluster> cluster_c(cb.Finish()); | 628 scoped_ptr<Cluster> cluster_c(cb.Finish()); |
| 630 EXPECT_FALSE(demuxer_->AppendData(cluster_c->data(), cluster_c->size())); | 629 EXPECT_FALSE(demuxer_->AppendData(cluster_c->data(), cluster_c->size())); |
| 631 } | 630 } |
| 632 | 631 |
| 633 // Test the case where a cluster is passed to AppendData() before | 632 // Test the case where a cluster is passed to AppendData() before |
| 634 // INFO & TRACKS data. | 633 // INFO & TRACKS data. |
| 635 TEST_F(ChunkDemuxerTest, TestClusterBeforeInfoTracks) { | 634 TEST_F(ChunkDemuxerTest, TestClusterBeforeInfoTracks) { |
| 636 EXPECT_CALL(*client_, DemuxerOpened(_)); | 635 EXPECT_CALL(*client_, DemuxerOpened(_)); |
| 637 demuxer_->Initialize(NewExpectedStatusCB(DEMUXER_ERROR_COULD_NOT_OPEN)); | 636 demuxer_->Initialize( |
| 637 &host_, NewExpectedStatusCB(DEMUXER_ERROR_COULD_NOT_OPEN)); |
| 638 | 638 |
| 639 ClusterBuilder cb; | 639 ClusterBuilder cb; |
| 640 cb.SetClusterTimecode(0); | 640 cb.SetClusterTimecode(0); |
| 641 AddSimpleBlock(&cb, kVideoTrackNum, 0); | 641 AddSimpleBlock(&cb, kVideoTrackNum, 0); |
| 642 scoped_ptr<Cluster> cluster(cb.Finish()); | 642 scoped_ptr<Cluster> cluster(cb.Finish()); |
| 643 | 643 |
| 644 ASSERT_TRUE(AppendData(cluster->data(), cluster->size())); | 644 ASSERT_TRUE(AppendData(cluster->data(), cluster->size())); |
| 645 } | 645 } |
| 646 | 646 |
| 647 // Test cases where we get an EndOfStream() call during initialization. | 647 // Test cases where we get an EndOfStream() call during initialization. |
| 648 TEST_F(ChunkDemuxerTest, TestEOSDuringInit) { | 648 TEST_F(ChunkDemuxerTest, TestEOSDuringInit) { |
| 649 EXPECT_CALL(*client_, DemuxerOpened(_)); | 649 EXPECT_CALL(*client_, DemuxerOpened(_)); |
| 650 demuxer_->Initialize(NewExpectedStatusCB(DEMUXER_ERROR_COULD_NOT_OPEN)); | 650 demuxer_->Initialize( |
| 651 &host_, NewExpectedStatusCB(DEMUXER_ERROR_COULD_NOT_OPEN)); |
| 651 demuxer_->EndOfStream(PIPELINE_OK); | 652 demuxer_->EndOfStream(PIPELINE_OK); |
| 652 } | 653 } |
| 653 | 654 |
| 654 TEST_F(ChunkDemuxerTest, TestDecodeErrorEndOfStream) { | 655 TEST_F(ChunkDemuxerTest, TestDecodeErrorEndOfStream) { |
| 655 ASSERT_TRUE(InitDemuxer(true, true, false)); | 656 ASSERT_TRUE(InitDemuxer(true, true, false)); |
| 656 | 657 |
| 657 ClusterBuilder cb; | 658 ClusterBuilder cb; |
| 658 cb.SetClusterTimecode(0); | 659 cb.SetClusterTimecode(0); |
| 659 AddSimpleBlock(&cb, kAudioTrackNum, 0); | 660 AddSimpleBlock(&cb, kAudioTrackNum, 0); |
| 660 AddSimpleBlock(&cb, kVideoTrackNum, 0); | 661 AddSimpleBlock(&cb, kVideoTrackNum, 0); |
| 661 AddSimpleBlock(&cb, kAudioTrackNum, 23); | 662 AddSimpleBlock(&cb, kAudioTrackNum, 23); |
| 662 AddSimpleBlock(&cb, kVideoTrackNum, 33); | 663 AddSimpleBlock(&cb, kVideoTrackNum, 33); |
| 663 scoped_ptr<Cluster> cluster(cb.Finish()); | 664 scoped_ptr<Cluster> cluster(cb.Finish()); |
| 664 ASSERT_TRUE(AppendData(cluster->data(), cluster->size())); | 665 ASSERT_TRUE(AppendData(cluster->data(), cluster->size())); |
| 665 | 666 |
| 666 EXPECT_CALL(mock_demuxer_host_, OnDemuxerError(PIPELINE_ERROR_DECODE)); | 667 EXPECT_CALL(host_, OnDemuxerError(PIPELINE_ERROR_DECODE)); |
| 667 demuxer_->EndOfStream(PIPELINE_ERROR_DECODE); | 668 demuxer_->EndOfStream(PIPELINE_ERROR_DECODE); |
| 668 } | 669 } |
| 669 | 670 |
| 670 TEST_F(ChunkDemuxerTest, TestNetworkErrorEndOfStream) { | 671 TEST_F(ChunkDemuxerTest, TestNetworkErrorEndOfStream) { |
| 671 ASSERT_TRUE(InitDemuxer(true, true, false)); | 672 ASSERT_TRUE(InitDemuxer(true, true, false)); |
| 672 | 673 |
| 673 ClusterBuilder cb; | 674 ClusterBuilder cb; |
| 674 cb.SetClusterTimecode(0); | 675 cb.SetClusterTimecode(0); |
| 675 AddSimpleBlock(&cb, kAudioTrackNum, 0); | 676 AddSimpleBlock(&cb, kAudioTrackNum, 0); |
| 676 AddSimpleBlock(&cb, kVideoTrackNum, 0); | 677 AddSimpleBlock(&cb, kVideoTrackNum, 0); |
| 677 AddSimpleBlock(&cb, kAudioTrackNum, 23); | 678 AddSimpleBlock(&cb, kAudioTrackNum, 23); |
| 678 AddSimpleBlock(&cb, kVideoTrackNum, 33); | 679 AddSimpleBlock(&cb, kVideoTrackNum, 33); |
| 679 scoped_ptr<Cluster> cluster(cb.Finish()); | 680 scoped_ptr<Cluster> cluster(cb.Finish()); |
| 680 ASSERT_TRUE(AppendData(cluster->data(), cluster->size())); | 681 ASSERT_TRUE(AppendData(cluster->data(), cluster->size())); |
| 681 | 682 |
| 682 EXPECT_CALL(mock_demuxer_host_, OnDemuxerError(PIPELINE_ERROR_NETWORK)); | 683 EXPECT_CALL(host_, OnDemuxerError(PIPELINE_ERROR_NETWORK)); |
| 683 demuxer_->EndOfStream(PIPELINE_ERROR_NETWORK); | 684 demuxer_->EndOfStream(PIPELINE_ERROR_NETWORK); |
| 684 } | 685 } |
| 685 | 686 |
| 686 // Helper class to reduce duplicate code when testing end of stream | 687 // Helper class to reduce duplicate code when testing end of stream |
| 687 // Read() behavior. | 688 // Read() behavior. |
| 688 class EndOfStreamHelper { | 689 class EndOfStreamHelper { |
| 689 public: | 690 public: |
| 690 EndOfStreamHelper(const scoped_refptr<Demuxer> demuxer) | 691 EndOfStreamHelper(const scoped_refptr<Demuxer> demuxer) |
| 691 : demuxer_(demuxer), | 692 : demuxer_(demuxer), |
| 692 audio_read_done_(false), | 693 audio_read_done_(false), |
| (...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 824 end_of_stream_helper_2.CheckIfReadDonesWereCalled(true); | 825 end_of_stream_helper_2.CheckIfReadDonesWereCalled(true); |
| 825 | 826 |
| 826 end_of_stream_helper_3.RequestReads(); | 827 end_of_stream_helper_3.RequestReads(); |
| 827 end_of_stream_helper_3.CheckIfReadDonesWereCalled(true); | 828 end_of_stream_helper_3.CheckIfReadDonesWereCalled(true); |
| 828 } | 829 } |
| 829 | 830 |
| 830 // Make sure AppendData() will accept elements that span multiple calls. | 831 // Make sure AppendData() will accept elements that span multiple calls. |
| 831 TEST_F(ChunkDemuxerTest, TestAppendingInPieces) { | 832 TEST_F(ChunkDemuxerTest, TestAppendingInPieces) { |
| 832 | 833 |
| 833 EXPECT_CALL(*client_, DemuxerOpened(_)); | 834 EXPECT_CALL(*client_, DemuxerOpened(_)); |
| 834 demuxer_->Initialize(CreateInitDoneCB(kDefaultDuration(), PIPELINE_OK)); | 835 demuxer_->Initialize( |
| 836 &host_, CreateInitDoneCB(kDefaultDuration(), PIPELINE_OK)); |
| 835 | 837 |
| 836 scoped_array<uint8> info_tracks; | 838 scoped_array<uint8> info_tracks; |
| 837 int info_tracks_size = 0; | 839 int info_tracks_size = 0; |
| 838 CreateInfoTracks(true, true, false, &info_tracks, &info_tracks_size); | 840 CreateInfoTracks(true, true, false, &info_tracks, &info_tracks_size); |
| 839 | 841 |
| 840 ClusterBuilder cb; | 842 ClusterBuilder cb; |
| 841 cb.SetClusterTimecode(0); | 843 cb.SetClusterTimecode(0); |
| 842 AddSimpleBlock(&cb, kAudioTrackNum, 32, 512); | 844 AddSimpleBlock(&cb, kAudioTrackNum, 32, 512); |
| 843 AddSimpleBlock(&cb, kVideoTrackNum, 123, 1024); | 845 AddSimpleBlock(&cb, kVideoTrackNum, 123, 1024); |
| 844 scoped_ptr<Cluster> cluster_a(cb.Finish()); | 846 scoped_ptr<Cluster> cluster_a(cb.Finish()); |
| (...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1019 | 1021 |
| 1020 // Append the remaining data. | 1022 // Append the remaining data. |
| 1021 ASSERT_TRUE(AppendData(cluster->data() + i, cluster->size() - i)); | 1023 ASSERT_TRUE(AppendData(cluster->data() + i, cluster->size() - i)); |
| 1022 | 1024 |
| 1023 EXPECT_TRUE(audio_read_done); | 1025 EXPECT_TRUE(audio_read_done); |
| 1024 EXPECT_TRUE(video_read_done); | 1026 EXPECT_TRUE(video_read_done); |
| 1025 } | 1027 } |
| 1026 | 1028 |
| 1027 | 1029 |
| 1028 TEST_F(ChunkDemuxerTest, TestParseErrorDuringInit) { | 1030 TEST_F(ChunkDemuxerTest, TestParseErrorDuringInit) { |
| 1029 EXPECT_CALL(mock_demuxer_host_, OnDemuxerError(PIPELINE_ERROR_DECODE)); | 1031 EXPECT_CALL(host_, OnDemuxerError(PIPELINE_ERROR_DECODE)); |
| 1030 | 1032 |
| 1031 EXPECT_CALL(*client_, DemuxerOpened(_)); | 1033 EXPECT_CALL(*client_, DemuxerOpened(_)); |
| 1032 demuxer_->Initialize(CreateInitDoneCB( | 1034 demuxer_->Initialize( |
| 1033 kDefaultDuration(), PIPELINE_OK)); | 1035 &host_, CreateInitDoneCB(kDefaultDuration(), PIPELINE_OK)); |
| 1034 ASSERT_TRUE(AppendInfoTracks(true, true, false)); | 1036 ASSERT_TRUE(AppendInfoTracks(true, true, false)); |
| 1035 | 1037 |
| 1036 uint8 tmp = 0; | 1038 uint8 tmp = 0; |
| 1037 ASSERT_TRUE(demuxer_->AppendData(&tmp, 1)); | 1039 ASSERT_TRUE(demuxer_->AppendData(&tmp, 1)); |
| 1038 } | 1040 } |
| 1039 | 1041 |
| 1040 } // namespace media | 1042 } // namespace media |
| OLD | NEW |