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 <algorithm> | 5 #include <algorithm> |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/message_loop/message_loop.h" | 8 #include "base/message_loop/message_loop.h" |
9 #include "base/strings/string_number_conversions.h" | 9 #include "base/strings/string_number_conversions.h" |
10 #include "base/strings/string_split.h" | 10 #include "base/strings/string_split.h" |
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
164 Demuxer::NeedKeyCB need_key_cb = | 164 Demuxer::NeedKeyCB need_key_cb = |
165 base::Bind(&ChunkDemuxerTest::DemuxerNeedKey, base::Unretained(this)); | 165 base::Bind(&ChunkDemuxerTest::DemuxerNeedKey, base::Unretained(this)); |
166 demuxer_.reset(new ChunkDemuxer(open_cb, need_key_cb, | 166 demuxer_.reset(new ChunkDemuxer(open_cb, need_key_cb, |
167 base::Bind(&LogFunc))); | 167 base::Bind(&LogFunc))); |
168 } | 168 } |
169 | 169 |
170 virtual ~ChunkDemuxerTest() { | 170 virtual ~ChunkDemuxerTest() { |
171 ShutdownDemuxer(); | 171 ShutdownDemuxer(); |
172 } | 172 } |
173 | 173 |
174 void CreateInitSegment(bool has_audio, bool has_video, bool has_text, | 174 void CreateInitSegment(int stream_flags, |
175 bool is_audio_encrypted, bool is_video_encrypted, | 175 bool is_audio_encrypted, bool is_video_encrypted, |
176 scoped_ptr<uint8[]>* buffer, | 176 scoped_ptr<uint8[]>* buffer, |
177 int* size) { | 177 int* size) { |
| 178 bool has_audio = (stream_flags & HAS_AUDIO) != 0; |
| 179 bool has_video = (stream_flags & HAS_VIDEO) != 0; |
| 180 bool has_text = (stream_flags & HAS_TEXT) != 0; |
178 scoped_refptr<DecoderBuffer> ebml_header; | 181 scoped_refptr<DecoderBuffer> ebml_header; |
179 scoped_refptr<DecoderBuffer> info; | 182 scoped_refptr<DecoderBuffer> info; |
180 scoped_refptr<DecoderBuffer> audio_track_entry; | 183 scoped_refptr<DecoderBuffer> audio_track_entry; |
181 scoped_refptr<DecoderBuffer> video_track_entry; | 184 scoped_refptr<DecoderBuffer> video_track_entry; |
182 scoped_refptr<DecoderBuffer> audio_content_encodings; | 185 scoped_refptr<DecoderBuffer> audio_content_encodings; |
183 scoped_refptr<DecoderBuffer> video_content_encodings; | 186 scoped_refptr<DecoderBuffer> video_content_encodings; |
184 scoped_refptr<DecoderBuffer> text_track_entry; | 187 scoped_refptr<DecoderBuffer> text_track_entry; |
185 | 188 |
186 ebml_header = ReadTestDataFile("webm_ebml_element"); | 189 ebml_header = ReadTestDataFile("webm_ebml_element"); |
187 | 190 |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
279 } | 282 } |
280 | 283 |
281 if (has_text) { | 284 if (has_text) { |
282 memcpy(buf, text_track_entry->data(), | 285 memcpy(buf, text_track_entry->data(), |
283 text_track_entry->data_size()); | 286 text_track_entry->data_size()); |
284 buf += text_track_entry->data_size(); | 287 buf += text_track_entry->data_size(); |
285 } | 288 } |
286 } | 289 } |
287 | 290 |
288 ChunkDemuxer::Status AddId() { | 291 ChunkDemuxer::Status AddId() { |
289 return AddId(kSourceId, true, true); | 292 return AddId(kSourceId, HAS_AUDIO | HAS_VIDEO); |
290 } | 293 } |
291 | 294 |
292 ChunkDemuxer::Status AddId(const std::string& source_id, | 295 ChunkDemuxer::Status AddId(const std::string& source_id, int stream_flags) { |
293 bool has_audio, bool has_video) { | 296 bool has_audio = (stream_flags & HAS_AUDIO) != 0; |
| 297 bool has_video = (stream_flags & HAS_VIDEO) != 0; |
294 std::vector<std::string> codecs; | 298 std::vector<std::string> codecs; |
295 std::string type; | 299 std::string type; |
296 | 300 |
297 if (has_audio) { | 301 if (has_audio) { |
298 codecs.push_back("vorbis"); | 302 codecs.push_back("vorbis"); |
299 type = "audio/webm"; | 303 type = "audio/webm"; |
300 } | 304 } |
301 | 305 |
302 if (has_video) { | 306 if (has_video) { |
303 codecs.push_back("vp8"); | 307 codecs.push_back("vp8"); |
304 type = "video/webm"; | 308 type = "video/webm"; |
305 } | 309 } |
306 | 310 |
307 if (!has_audio && !has_video) { | 311 if (!has_audio && !has_video) { |
308 return AddId(kSourceId, true, true); | 312 return AddId(kSourceId, HAS_AUDIO | HAS_VIDEO); |
309 } | 313 } |
310 | 314 |
311 return demuxer_->AddId(source_id, type, codecs); | 315 return demuxer_->AddId(source_id, type, codecs); |
312 } | 316 } |
313 | 317 |
314 void AppendData(const uint8* data, size_t length) { | 318 void AppendData(const uint8* data, size_t length) { |
315 AppendData(kSourceId, data, length); | 319 AppendData(kSourceId, data, length); |
316 } | 320 } |
317 | 321 |
318 void AppendCluster(const std::string& source_id, | 322 void AppendCluster(const std::string& source_id, |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
401 const uint8* start = data; | 405 const uint8* start = data; |
402 const uint8* end = data + length; | 406 const uint8* end = data + length; |
403 while (start < end) { | 407 while (start < end) { |
404 size_t append_size = std::min(piece_size, | 408 size_t append_size = std::min(piece_size, |
405 static_cast<size_t>(end - start)); | 409 static_cast<size_t>(end - start)); |
406 AppendData(start, append_size); | 410 AppendData(start, append_size); |
407 start += append_size; | 411 start += append_size; |
408 } | 412 } |
409 } | 413 } |
410 | 414 |
411 void AppendInitSegment(bool has_audio, bool has_video) { | 415 void AppendInitSegment(int stream_flags) { |
412 AppendInitSegmentWithSourceId(kSourceId, has_audio, has_video, false); | 416 AppendInitSegmentWithSourceId(kSourceId, stream_flags); |
413 } | 417 } |
414 | 418 |
415 void AppendInitSegmentWithSourceId(const std::string& source_id, | 419 void AppendInitSegmentWithSourceId(const std::string& source_id, |
416 bool has_audio, bool has_video, | 420 int stream_flags) { |
417 bool has_text) { | 421 AppendInitSegmentWithEncryptedInfo(source_id, stream_flags, false, false); |
418 AppendInitSegmentWithEncryptedInfo( | |
419 source_id, has_audio, has_video, has_text, false, false); | |
420 } | 422 } |
421 | 423 |
422 void AppendInitSegmentWithEncryptedInfo(const std::string& source_id, | 424 void AppendInitSegmentWithEncryptedInfo(const std::string& source_id, |
423 bool has_audio, bool has_video, | 425 int stream_flags, |
424 bool has_text, | |
425 bool is_audio_encrypted, | 426 bool is_audio_encrypted, |
426 bool is_video_encrypted) { | 427 bool is_video_encrypted) { |
427 scoped_ptr<uint8[]> info_tracks; | 428 scoped_ptr<uint8[]> info_tracks; |
428 int info_tracks_size = 0; | 429 int info_tracks_size = 0; |
429 CreateInitSegment(has_audio, has_video, has_text, | 430 CreateInitSegment(stream_flags, |
430 is_audio_encrypted, is_video_encrypted, | 431 is_audio_encrypted, is_video_encrypted, |
431 &info_tracks, &info_tracks_size); | 432 &info_tracks, &info_tracks_size); |
432 AppendData(source_id, info_tracks.get(), info_tracks_size); | 433 AppendData(source_id, info_tracks.get(), info_tracks_size); |
433 } | 434 } |
434 | 435 |
435 void AppendGarbage() { | 436 void AppendGarbage() { |
436 // Fill up an array with gibberish. | 437 // Fill up an array with gibberish. |
437 int garbage_cluster_size = 10; | 438 int garbage_cluster_size = 10; |
438 scoped_ptr<uint8[]> garbage_cluster(new uint8[garbage_cluster_size]); | 439 scoped_ptr<uint8[]> garbage_cluster(new uint8[garbage_cluster_size]); |
439 for (int i = 0; i < garbage_cluster_size; ++i) | 440 for (int i = 0; i < garbage_cluster_size; ++i) |
(...skipping 23 matching lines...) Expand all Loading... |
463 expected_status); | 464 expected_status); |
464 } | 465 } |
465 | 466 |
466 enum StreamFlags { | 467 enum StreamFlags { |
467 HAS_AUDIO = 1 << 0, | 468 HAS_AUDIO = 1 << 0, |
468 HAS_VIDEO = 1 << 1, | 469 HAS_VIDEO = 1 << 1, |
469 HAS_TEXT = 1 << 2 | 470 HAS_TEXT = 1 << 2 |
470 }; | 471 }; |
471 | 472 |
472 bool InitDemuxer(int stream_flags) { | 473 bool InitDemuxer(int stream_flags) { |
473 return InitDemuxerWithEncryptionInfo( | 474 return InitDemuxerWithEncryptionInfo(stream_flags, false, false); |
474 (stream_flags & HAS_AUDIO) != 0, | |
475 (stream_flags & HAS_VIDEO) != 0, | |
476 (stream_flags & HAS_TEXT) != 0, | |
477 false, false); | |
478 } | 475 } |
479 | 476 |
480 bool InitDemuxerWithEncryptionInfo( | 477 bool InitDemuxerWithEncryptionInfo( |
481 bool has_audio, bool has_video, bool has_text, | 478 int stream_flags, bool is_audio_encrypted, bool is_video_encrypted) { |
482 bool is_audio_encrypted, bool is_video_encrypted) { | 479 |
483 PipelineStatus expected_status = | 480 PipelineStatus expected_status = |
484 (has_audio || has_video) ? PIPELINE_OK : DEMUXER_ERROR_COULD_NOT_OPEN; | 481 (stream_flags != 0) ? PIPELINE_OK : DEMUXER_ERROR_COULD_NOT_OPEN; |
485 | 482 |
486 base::TimeDelta expected_duration = kNoTimestamp(); | 483 base::TimeDelta expected_duration = kNoTimestamp(); |
487 if (expected_status == PIPELINE_OK) | 484 if (expected_status == PIPELINE_OK) |
488 expected_duration = kDefaultDuration(); | 485 expected_duration = kDefaultDuration(); |
489 | 486 |
490 EXPECT_CALL(*this, DemuxerOpened()); | 487 EXPECT_CALL(*this, DemuxerOpened()); |
491 demuxer_->Initialize( | 488 demuxer_->Initialize( |
492 &host_, CreateInitDoneCB(expected_duration, expected_status), true); | 489 &host_, CreateInitDoneCB(expected_duration, expected_status), true); |
493 | 490 |
494 if (AddId(kSourceId, has_audio, has_video) != ChunkDemuxer::kOk) | 491 if (AddId(kSourceId, stream_flags) != ChunkDemuxer::kOk) |
495 return false; | 492 return false; |
496 | 493 |
497 AppendInitSegmentWithEncryptedInfo( | 494 AppendInitSegmentWithEncryptedInfo( |
498 kSourceId, has_audio, has_video, has_text, | 495 kSourceId, stream_flags, |
499 is_audio_encrypted, is_video_encrypted); | 496 is_audio_encrypted, is_video_encrypted); |
500 return true; | 497 return true; |
501 } | 498 } |
502 | 499 |
503 bool InitDemuxerAudioAndVideoSourcesText(const std::string& audio_id, | 500 bool InitDemuxerAudioAndVideoSourcesText(const std::string& audio_id, |
504 const std::string& video_id, | 501 const std::string& video_id, |
505 bool has_text) { | 502 bool has_text) { |
506 EXPECT_CALL(*this, DemuxerOpened()); | 503 EXPECT_CALL(*this, DemuxerOpened()); |
507 demuxer_->Initialize( | 504 demuxer_->Initialize( |
508 &host_, CreateInitDoneCB(kDefaultDuration(), PIPELINE_OK), true); | 505 &host_, CreateInitDoneCB(kDefaultDuration(), PIPELINE_OK), true); |
509 | 506 |
510 if (AddId(audio_id, true, false) != ChunkDemuxer::kOk) | 507 if (AddId(audio_id, HAS_AUDIO) != ChunkDemuxer::kOk) |
511 return false; | 508 return false; |
512 if (AddId(video_id, false, true) != ChunkDemuxer::kOk) | 509 if (AddId(video_id, HAS_VIDEO) != ChunkDemuxer::kOk) |
513 return false; | 510 return false; |
514 | 511 |
515 AppendInitSegmentWithSourceId(audio_id, true, false, has_text); | 512 int audio_flags = HAS_AUDIO; |
516 AppendInitSegmentWithSourceId(video_id, false, true, has_text); | 513 int video_flags = HAS_VIDEO; |
| 514 |
| 515 if (has_text) { |
| 516 audio_flags |= HAS_TEXT; |
| 517 video_flags |= HAS_TEXT; |
| 518 } |
| 519 |
| 520 AppendInitSegmentWithSourceId(audio_id, audio_flags); |
| 521 AppendInitSegmentWithSourceId(video_id, video_flags); |
517 return true; | 522 return true; |
518 } | 523 } |
519 | 524 |
520 bool InitDemuxerAudioAndVideoSources(const std::string& audio_id, | 525 bool InitDemuxerAudioAndVideoSources(const std::string& audio_id, |
521 const std::string& video_id) { | 526 const std::string& video_id) { |
522 return InitDemuxerAudioAndVideoSourcesText(audio_id, video_id, false); | 527 return InitDemuxerAudioAndVideoSourcesText(audio_id, video_id, false); |
523 } | 528 } |
524 | 529 |
525 // Initializes the demuxer with data from 2 files with different | 530 // Initializes the demuxer with data from 2 files with different |
526 // decoder configurations. This is used to test the decoder config change | 531 // decoder configurations. This is used to test the decoder config change |
(...skipping 14 matching lines...) Expand all Loading... |
541 // bear-640x360.webm : [527-759) | 546 // bear-640x360.webm : [527-759) |
542 bool InitDemuxerWithConfigChangeData() { | 547 bool InitDemuxerWithConfigChangeData() { |
543 scoped_refptr<DecoderBuffer> bear1 = ReadTestDataFile("bear-320x240.webm"); | 548 scoped_refptr<DecoderBuffer> bear1 = ReadTestDataFile("bear-320x240.webm"); |
544 scoped_refptr<DecoderBuffer> bear2 = ReadTestDataFile("bear-640x360.webm"); | 549 scoped_refptr<DecoderBuffer> bear2 = ReadTestDataFile("bear-640x360.webm"); |
545 | 550 |
546 EXPECT_CALL(*this, DemuxerOpened()); | 551 EXPECT_CALL(*this, DemuxerOpened()); |
547 demuxer_->Initialize( | 552 demuxer_->Initialize( |
548 &host_, CreateInitDoneCB(base::TimeDelta::FromMilliseconds(2744), | 553 &host_, CreateInitDoneCB(base::TimeDelta::FromMilliseconds(2744), |
549 PIPELINE_OK), true); | 554 PIPELINE_OK), true); |
550 | 555 |
551 if (AddId(kSourceId, true, true) != ChunkDemuxer::kOk) | 556 if (AddId(kSourceId, HAS_AUDIO | HAS_VIDEO) != ChunkDemuxer::kOk) |
552 return false; | 557 return false; |
553 | 558 |
554 // Append the whole bear1 file. | 559 // Append the whole bear1 file. |
555 AppendData(bear1->data(), bear1->data_size()); | 560 AppendData(bear1->data(), bear1->data_size()); |
556 CheckExpectedRanges(kSourceId, "{ [0,2737) }"); | 561 CheckExpectedRanges(kSourceId, "{ [0,2737) }"); |
557 | 562 |
558 // Append initialization segment for bear2. | 563 // Append initialization segment for bear2. |
559 // Note: Offsets here and below are derived from | 564 // Note: Offsets here and below are derived from |
560 // media/test/data/bear-640x360-manifest.js and | 565 // media/test/data/bear-640x360-manifest.js and |
561 // media/test/data/bear-320x240-manifest.js which were | 566 // media/test/data/bear-320x240-manifest.js which were |
(...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
856 | 861 |
857 // Test parsing a WebM file. | 862 // Test parsing a WebM file. |
858 // |filename| - The name of the file in media/test/data to parse. | 863 // |filename| - The name of the file in media/test/data to parse. |
859 // |timestamps| - The expected timestamps on the parsed buffers. | 864 // |timestamps| - The expected timestamps on the parsed buffers. |
860 // a timestamp of kSkip indicates that a Read() call for that stream | 865 // a timestamp of kSkip indicates that a Read() call for that stream |
861 // shouldn't be made on that iteration of the loop. If both streams have | 866 // shouldn't be made on that iteration of the loop. If both streams have |
862 // a kSkip then the loop will terminate. | 867 // a kSkip then the loop will terminate. |
863 bool ParseWebMFile(const std::string& filename, | 868 bool ParseWebMFile(const std::string& filename, |
864 const BufferTimestamps* timestamps, | 869 const BufferTimestamps* timestamps, |
865 const base::TimeDelta& duration) { | 870 const base::TimeDelta& duration) { |
866 return ParseWebMFile(filename, timestamps, duration, true, true); | 871 return ParseWebMFile(filename, timestamps, duration, HAS_AUDIO | HAS_VIDEO); |
867 } | 872 } |
868 | 873 |
869 bool ParseWebMFile(const std::string& filename, | 874 bool ParseWebMFile(const std::string& filename, |
870 const BufferTimestamps* timestamps, | 875 const BufferTimestamps* timestamps, |
871 const base::TimeDelta& duration, | 876 const base::TimeDelta& duration, |
872 bool has_audio, bool has_video) { | 877 int stream_flags) { |
873 EXPECT_CALL(*this, DemuxerOpened()); | 878 EXPECT_CALL(*this, DemuxerOpened()); |
874 demuxer_->Initialize( | 879 demuxer_->Initialize( |
875 &host_, CreateInitDoneCB(duration, PIPELINE_OK), true); | 880 &host_, CreateInitDoneCB(duration, PIPELINE_OK), true); |
876 | 881 |
877 if (AddId(kSourceId, has_audio, has_video) != ChunkDemuxer::kOk) | 882 if (AddId(kSourceId, stream_flags) != ChunkDemuxer::kOk) |
878 return false; | 883 return false; |
879 | 884 |
880 // Read a WebM file into memory and send the data to the demuxer. | 885 // Read a WebM file into memory and send the data to the demuxer. |
881 scoped_refptr<DecoderBuffer> buffer = ReadTestDataFile(filename); | 886 scoped_refptr<DecoderBuffer> buffer = ReadTestDataFile(filename); |
882 AppendDataInPieces(buffer->data(), buffer->data_size(), 512); | 887 AppendDataInPieces(buffer->data(), buffer->data_size(), 512); |
883 | 888 |
884 // Verify that the timestamps on the first few packets match what we | 889 // Verify that the timestamps on the first few packets match what we |
885 // expect. | 890 // expect. |
886 for (size_t i = 0; | 891 for (size_t i = 0; |
887 (timestamps[i].audio_time_ms != kSkip || | 892 (timestamps[i].audio_time_ms != kSkip || |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
961 CreateNewDemuxer(); | 966 CreateNewDemuxer(); |
962 | 967 |
963 if (is_audio_encrypted || is_video_encrypted) { | 968 if (is_audio_encrypted || is_video_encrypted) { |
964 int need_key_count = (is_audio_encrypted ? 1 : 0) + | 969 int need_key_count = (is_audio_encrypted ? 1 : 0) + |
965 (is_video_encrypted ? 1 : 0); | 970 (is_video_encrypted ? 1 : 0); |
966 EXPECT_CALL(*this, NeedKeyMock(kWebMEncryptInitDataType, NotNull(), | 971 EXPECT_CALL(*this, NeedKeyMock(kWebMEncryptInitDataType, NotNull(), |
967 DecryptConfig::kDecryptionKeySize)) | 972 DecryptConfig::kDecryptionKeySize)) |
968 .Times(Exactly(need_key_count)); | 973 .Times(Exactly(need_key_count)); |
969 } | 974 } |
970 | 975 |
| 976 int stream_flags = 0; |
| 977 if (has_audio) |
| 978 stream_flags |= HAS_AUDIO; |
| 979 |
| 980 if (has_video) |
| 981 stream_flags |= HAS_VIDEO; |
| 982 |
971 ASSERT_TRUE(InitDemuxerWithEncryptionInfo( | 983 ASSERT_TRUE(InitDemuxerWithEncryptionInfo( |
972 has_audio, has_video, false, is_audio_encrypted, is_video_encrypted)); | 984 stream_flags, is_audio_encrypted, is_video_encrypted)); |
973 | 985 |
974 DemuxerStream* audio_stream = demuxer_->GetStream(DemuxerStream::AUDIO); | 986 DemuxerStream* audio_stream = demuxer_->GetStream(DemuxerStream::AUDIO); |
975 if (has_audio) { | 987 if (has_audio) { |
976 ASSERT_TRUE(audio_stream); | 988 ASSERT_TRUE(audio_stream); |
977 | 989 |
978 const AudioDecoderConfig& config = audio_stream->audio_decoder_config(); | 990 const AudioDecoderConfig& config = audio_stream->audio_decoder_config(); |
979 EXPECT_EQ(kCodecVorbis, config.codec()); | 991 EXPECT_EQ(kCodecVorbis, config.codec()); |
980 EXPECT_EQ(32, config.bits_per_channel()); | 992 EXPECT_EQ(32, config.bits_per_channel()); |
981 EXPECT_EQ(CHANNEL_LAYOUT_STEREO, config.channel_layout()); | 993 EXPECT_EQ(CHANNEL_LAYOUT_STEREO, config.channel_layout()); |
982 EXPECT_EQ(44100, config.samples_per_second()); | 994 EXPECT_EQ(44100, config.samples_per_second()); |
(...skipping 13 matching lines...) Expand all Loading... |
996 video_stream->video_decoder_config().is_encrypted()); | 1008 video_stream->video_decoder_config().is_encrypted()); |
997 } else { | 1009 } else { |
998 EXPECT_FALSE(video_stream); | 1010 EXPECT_FALSE(video_stream); |
999 } | 1011 } |
1000 | 1012 |
1001 ShutdownDemuxer(); | 1013 ShutdownDemuxer(); |
1002 demuxer_.reset(); | 1014 demuxer_.reset(); |
1003 } | 1015 } |
1004 } | 1016 } |
1005 | 1017 |
| 1018 // TODO(acolwell): Fold this test into Init tests since the tests are |
| 1019 // almost identical. |
1006 TEST_F(ChunkDemuxerTest, InitText) { | 1020 TEST_F(ChunkDemuxerTest, InitText) { |
1007 // Test with 1 video stream and 1 text streams, and 0 or 1 audio streams. | 1021 // Test with 1 video stream and 1 text streams, and 0 or 1 audio streams. |
1008 // No encryption cases handled here. | 1022 // No encryption cases handled here. |
1009 bool has_video = true; | 1023 bool has_video = true; |
1010 bool is_audio_encrypted = false; | 1024 bool is_audio_encrypted = false; |
1011 bool is_video_encrypted = false; | 1025 bool is_video_encrypted = false; |
1012 for (int i = 0; i < 2; i++) { | 1026 for (int i = 0; i < 2; i++) { |
1013 bool has_audio = (i & 0x1) != 0; | 1027 bool has_audio = (i & 0x1) != 0; |
1014 | 1028 |
1015 CreateNewDemuxer(); | 1029 CreateNewDemuxer(); |
1016 | 1030 |
1017 DemuxerStream* text_stream = NULL; | 1031 DemuxerStream* text_stream = NULL; |
1018 TextTrackConfig text_config; | 1032 TextTrackConfig text_config; |
1019 EXPECT_CALL(host_, AddTextStream(_, _)) | 1033 EXPECT_CALL(host_, AddTextStream(_, _)) |
1020 .WillOnce(DoAll(SaveArg<0>(&text_stream), | 1034 .WillOnce(DoAll(SaveArg<0>(&text_stream), |
1021 SaveArg<1>(&text_config))); | 1035 SaveArg<1>(&text_config))); |
1022 | 1036 |
| 1037 int stream_flags = HAS_TEXT; |
| 1038 if (has_audio) |
| 1039 stream_flags |= HAS_AUDIO; |
| 1040 |
| 1041 if (has_video) |
| 1042 stream_flags |= HAS_VIDEO; |
| 1043 |
1023 ASSERT_TRUE(InitDemuxerWithEncryptionInfo( | 1044 ASSERT_TRUE(InitDemuxerWithEncryptionInfo( |
1024 has_audio, has_video, true, is_audio_encrypted, is_video_encrypted)); | 1045 stream_flags, is_audio_encrypted, is_video_encrypted)); |
1025 ASSERT_TRUE(text_stream); | 1046 ASSERT_TRUE(text_stream); |
1026 EXPECT_EQ(DemuxerStream::TEXT, text_stream->type()); | 1047 EXPECT_EQ(DemuxerStream::TEXT, text_stream->type()); |
1027 EXPECT_EQ(kTextSubtitles, text_config.kind()); | 1048 EXPECT_EQ(kTextSubtitles, text_config.kind()); |
1028 | 1049 |
1029 DemuxerStream* audio_stream = demuxer_->GetStream(DemuxerStream::AUDIO); | 1050 DemuxerStream* audio_stream = demuxer_->GetStream(DemuxerStream::AUDIO); |
1030 if (has_audio) { | 1051 if (has_audio) { |
1031 ASSERT_TRUE(audio_stream); | 1052 ASSERT_TRUE(audio_stream); |
1032 | 1053 |
1033 const AudioDecoderConfig& config = audio_stream->audio_decoder_config(); | 1054 const AudioDecoderConfig& config = audio_stream->audio_decoder_config(); |
1034 EXPECT_EQ(kCodecVorbis, config.codec()); | 1055 EXPECT_EQ(kCodecVorbis, config.codec()); |
(...skipping 18 matching lines...) Expand all Loading... |
1053 EXPECT_FALSE(video_stream); | 1074 EXPECT_FALSE(video_stream); |
1054 } | 1075 } |
1055 | 1076 |
1056 ShutdownDemuxer(); | 1077 ShutdownDemuxer(); |
1057 demuxer_.reset(); | 1078 demuxer_.reset(); |
1058 } | 1079 } |
1059 } | 1080 } |
1060 | 1081 |
1061 // Make sure that the demuxer reports an error if Shutdown() | 1082 // Make sure that the demuxer reports an error if Shutdown() |
1062 // is called before all the initialization segments are appended. | 1083 // is called before all the initialization segments are appended. |
1063 TEST_F(ChunkDemuxerTest, ShutdownBeforeAllInitSegmentsAppended) { | 1084 TEST_F(ChunkDemuxerTest, Shutdown_BeforeAllInitSegmentsAppended) { |
1064 EXPECT_CALL(*this, DemuxerOpened()); | 1085 EXPECT_CALL(*this, DemuxerOpened()); |
1065 demuxer_->Initialize( | 1086 demuxer_->Initialize( |
1066 &host_, CreateInitDoneCB( | 1087 &host_, CreateInitDoneCB( |
1067 kDefaultDuration(), DEMUXER_ERROR_COULD_NOT_OPEN), true); | 1088 kDefaultDuration(), DEMUXER_ERROR_COULD_NOT_OPEN), true); |
1068 | 1089 |
1069 EXPECT_EQ(AddId("audio", true, false), ChunkDemuxer::kOk); | 1090 EXPECT_EQ(AddId("audio", HAS_AUDIO), ChunkDemuxer::kOk); |
1070 EXPECT_EQ(AddId("video", false, true), ChunkDemuxer::kOk); | 1091 EXPECT_EQ(AddId("video", HAS_VIDEO), ChunkDemuxer::kOk); |
1071 | 1092 |
1072 AppendInitSegmentWithSourceId("audio", true, false, false); | 1093 AppendInitSegmentWithSourceId("audio", HAS_AUDIO); |
| 1094 |
| 1095 ShutdownDemuxer(); |
1073 } | 1096 } |
1074 | 1097 |
1075 TEST_F(ChunkDemuxerTest, ShutdownBeforeAllInitSegmentsAppendedText) { | 1098 TEST_F(ChunkDemuxerTest, Shutdown_BeforeAllInitSegmentsAppendedText) { |
1076 EXPECT_CALL(*this, DemuxerOpened()); | 1099 EXPECT_CALL(*this, DemuxerOpened()); |
1077 demuxer_->Initialize( | 1100 demuxer_->Initialize( |
1078 &host_, CreateInitDoneCB( | 1101 &host_, CreateInitDoneCB( |
1079 kDefaultDuration(), DEMUXER_ERROR_COULD_NOT_OPEN), true); | 1102 kDefaultDuration(), DEMUXER_ERROR_COULD_NOT_OPEN), true); |
1080 | 1103 |
1081 EXPECT_EQ(AddId("audio", true, false), ChunkDemuxer::kOk); | 1104 EXPECT_EQ(AddId("audio", HAS_AUDIO), ChunkDemuxer::kOk); |
1082 EXPECT_EQ(AddId("video", false, true), ChunkDemuxer::kOk); | 1105 EXPECT_EQ(AddId("video_and_text", HAS_VIDEO), ChunkDemuxer::kOk); |
1083 | 1106 |
1084 EXPECT_CALL(host_, AddTextStream(_, _)) | 1107 EXPECT_CALL(host_, AddTextStream(_, _)) |
1085 .Times(Exactly(1)); | 1108 .Times(Exactly(1)); |
1086 | 1109 |
1087 AppendInitSegmentWithSourceId("video", false, true, true); | 1110 AppendInitSegmentWithSourceId("video_and_text", HAS_VIDEO | HAS_TEXT); |
| 1111 |
| 1112 ShutdownDemuxer(); |
| 1113 } |
| 1114 |
| 1115 // Verifies that all streams waiting for data receive an end of stream |
| 1116 // buffer when Shutdown() is called. |
| 1117 TEST_F(ChunkDemuxerTest, Shutdown_EndOfStreamWhileWaitingForData) { |
| 1118 DemuxerStream* text_stream = NULL; |
| 1119 EXPECT_CALL(host_, AddTextStream(_, _)) |
| 1120 .WillOnce(SaveArg<0>(&text_stream)); |
| 1121 ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO | HAS_TEXT)); |
| 1122 |
| 1123 DemuxerStream* audio_stream = demuxer_->GetStream(DemuxerStream::AUDIO); |
| 1124 DemuxerStream* video_stream = demuxer_->GetStream(DemuxerStream::VIDEO); |
| 1125 |
| 1126 bool audio_read_done = false; |
| 1127 bool video_read_done = false; |
| 1128 bool text_read_done = false; |
| 1129 audio_stream->Read(base::Bind(&OnReadDone_EOSExpected, &audio_read_done)); |
| 1130 video_stream->Read(base::Bind(&OnReadDone_EOSExpected, &video_read_done)); |
| 1131 text_stream->Read(base::Bind(&OnReadDone_EOSExpected, &text_read_done)); |
| 1132 message_loop_.RunUntilIdle(); |
| 1133 |
| 1134 EXPECT_FALSE(audio_read_done); |
| 1135 EXPECT_FALSE(video_read_done); |
| 1136 EXPECT_FALSE(text_read_done); |
| 1137 |
| 1138 ShutdownDemuxer(); |
| 1139 |
| 1140 EXPECT_TRUE(audio_read_done); |
| 1141 EXPECT_TRUE(video_read_done); |
| 1142 EXPECT_TRUE(text_read_done); |
1088 } | 1143 } |
1089 | 1144 |
1090 // Test that Seek() completes successfully when the first cluster | 1145 // Test that Seek() completes successfully when the first cluster |
1091 // arrives. | 1146 // arrives. |
1092 TEST_F(ChunkDemuxerTest, AppendDataAfterSeek) { | 1147 TEST_F(ChunkDemuxerTest, AppendDataAfterSeek) { |
1093 ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO)); | 1148 ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO)); |
1094 AppendCluster(kDefaultFirstCluster()); | 1149 AppendCluster(kDefaultFirstCluster()); |
1095 | 1150 |
1096 InSequence s; | 1151 InSequence s; |
1097 | 1152 |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1152 // Append the new cluster and verify that only the blocks | 1207 // Append the new cluster and verify that only the blocks |
1153 // in the new cluster are returned. | 1208 // in the new cluster are returned. |
1154 AppendCluster(GenerateCluster(5000, 6)); | 1209 AppendCluster(GenerateCluster(5000, 6)); |
1155 GenerateExpectedReads(5000, 6); | 1210 GenerateExpectedReads(5000, 6); |
1156 } | 1211 } |
1157 | 1212 |
1158 // Test the case where AppendData() is called before Init(). | 1213 // Test the case where AppendData() is called before Init(). |
1159 TEST_F(ChunkDemuxerTest, AppendDataBeforeInit) { | 1214 TEST_F(ChunkDemuxerTest, AppendDataBeforeInit) { |
1160 scoped_ptr<uint8[]> info_tracks; | 1215 scoped_ptr<uint8[]> info_tracks; |
1161 int info_tracks_size = 0; | 1216 int info_tracks_size = 0; |
1162 CreateInitSegment(true, true, false, | 1217 CreateInitSegment(HAS_AUDIO | HAS_VIDEO, |
1163 false, false, &info_tracks, &info_tracks_size); | 1218 false, false, &info_tracks, &info_tracks_size); |
1164 | 1219 |
1165 demuxer_->AppendData(kSourceId, info_tracks.get(), info_tracks_size); | 1220 demuxer_->AppendData(kSourceId, info_tracks.get(), info_tracks_size); |
1166 } | 1221 } |
1167 | 1222 |
1168 // Make sure Read() callbacks are dispatched with the proper data. | 1223 // Make sure Read() callbacks are dispatched with the proper data. |
1169 TEST_F(ChunkDemuxerTest, Read) { | 1224 TEST_F(ChunkDemuxerTest, Read) { |
1170 ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO)); | 1225 ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO)); |
1171 | 1226 |
1172 AppendCluster(kDefaultFirstCluster()); | 1227 AppendCluster(kDefaultFirstCluster()); |
(...skipping 348 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1521 // Make sure AppendData() will accept elements that span multiple calls. | 1576 // Make sure AppendData() will accept elements that span multiple calls. |
1522 TEST_F(ChunkDemuxerTest, AppendingInPieces) { | 1577 TEST_F(ChunkDemuxerTest, AppendingInPieces) { |
1523 EXPECT_CALL(*this, DemuxerOpened()); | 1578 EXPECT_CALL(*this, DemuxerOpened()); |
1524 demuxer_->Initialize( | 1579 demuxer_->Initialize( |
1525 &host_, CreateInitDoneCB(kDefaultDuration(), PIPELINE_OK), true); | 1580 &host_, CreateInitDoneCB(kDefaultDuration(), PIPELINE_OK), true); |
1526 | 1581 |
1527 ASSERT_EQ(AddId(), ChunkDemuxer::kOk); | 1582 ASSERT_EQ(AddId(), ChunkDemuxer::kOk); |
1528 | 1583 |
1529 scoped_ptr<uint8[]> info_tracks; | 1584 scoped_ptr<uint8[]> info_tracks; |
1530 int info_tracks_size = 0; | 1585 int info_tracks_size = 0; |
1531 CreateInitSegment(true, true, false, | 1586 CreateInitSegment(HAS_AUDIO | HAS_VIDEO, |
1532 false, false, &info_tracks, &info_tracks_size); | 1587 false, false, &info_tracks, &info_tracks_size); |
1533 | 1588 |
1534 scoped_ptr<Cluster> cluster_a(kDefaultFirstCluster()); | 1589 scoped_ptr<Cluster> cluster_a(kDefaultFirstCluster()); |
1535 scoped_ptr<Cluster> cluster_b(kDefaultSecondCluster()); | 1590 scoped_ptr<Cluster> cluster_b(kDefaultSecondCluster()); |
1536 | 1591 |
1537 size_t buffer_size = info_tracks_size + cluster_a->size() + cluster_b->size(); | 1592 size_t buffer_size = info_tracks_size + cluster_a->size() + cluster_b->size(); |
1538 scoped_ptr<uint8[]> buffer(new uint8[buffer_size]); | 1593 scoped_ptr<uint8[]> buffer(new uint8[buffer_size]); |
1539 uint8* dst = buffer.get(); | 1594 uint8* dst = buffer.get(); |
1540 memcpy(dst, info_tracks.get(), info_tracks_size); | 1595 memcpy(dst, info_tracks.get(), info_tracks_size); |
1541 dst += info_tracks_size; | 1596 dst += info_tracks_size; |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1584 {kSkip, 0}, | 1639 {kSkip, 0}, |
1585 {kSkip, 3}, | 1640 {kSkip, 3}, |
1586 {kSkip, 6}, | 1641 {kSkip, 6}, |
1587 {kSkip, 9}, | 1642 {kSkip, 9}, |
1588 {kSkip, 12}, | 1643 {kSkip, 12}, |
1589 {kSkip, kSkip}, | 1644 {kSkip, kSkip}, |
1590 }; | 1645 }; |
1591 | 1646 |
1592 ASSERT_TRUE(ParseWebMFile("bear-320x240-audio-only.webm", buffer_timestamps, | 1647 ASSERT_TRUE(ParseWebMFile("bear-320x240-audio-only.webm", buffer_timestamps, |
1593 base::TimeDelta::FromMilliseconds(2744), | 1648 base::TimeDelta::FromMilliseconds(2744), |
1594 true, false)); | 1649 HAS_AUDIO)); |
1595 } | 1650 } |
1596 | 1651 |
1597 TEST_F(ChunkDemuxerTest, WebMFile_VideoOnly) { | 1652 TEST_F(ChunkDemuxerTest, WebMFile_VideoOnly) { |
1598 struct BufferTimestamps buffer_timestamps[] = { | 1653 struct BufferTimestamps buffer_timestamps[] = { |
1599 {0, kSkip}, | 1654 {0, kSkip}, |
1600 {33, kSkip}, | 1655 {33, kSkip}, |
1601 {67, kSkip}, | 1656 {67, kSkip}, |
1602 {100, kSkip}, | 1657 {100, kSkip}, |
1603 {133, kSkip}, | 1658 {133, kSkip}, |
1604 {kSkip, kSkip}, | 1659 {kSkip, kSkip}, |
1605 }; | 1660 }; |
1606 | 1661 |
1607 ASSERT_TRUE(ParseWebMFile("bear-320x240-video-only.webm", buffer_timestamps, | 1662 ASSERT_TRUE(ParseWebMFile("bear-320x240-video-only.webm", buffer_timestamps, |
1608 base::TimeDelta::FromMilliseconds(2703), | 1663 base::TimeDelta::FromMilliseconds(2703), |
1609 false, true)); | 1664 HAS_VIDEO)); |
1610 } | 1665 } |
1611 | 1666 |
1612 TEST_F(ChunkDemuxerTest, WebMFile_AltRefFrames) { | 1667 TEST_F(ChunkDemuxerTest, WebMFile_AltRefFrames) { |
1613 struct BufferTimestamps buffer_timestamps[] = { | 1668 struct BufferTimestamps buffer_timestamps[] = { |
1614 {0, 0}, | 1669 {0, 0}, |
1615 {33, 3}, | 1670 {33, 3}, |
1616 {33, 6}, | 1671 {33, 6}, |
1617 {67, 9}, | 1672 {67, 9}, |
1618 {100, 12}, | 1673 {100, 12}, |
1619 {kSkip, kSkip}, | 1674 {kSkip, kSkip}, |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1703 EXPECT_CALL(*this, DemuxerOpened()); | 1758 EXPECT_CALL(*this, DemuxerOpened()); |
1704 demuxer_->Initialize( | 1759 demuxer_->Initialize( |
1705 &host_, CreateInitDoneCB(kNoTimestamp(), | 1760 &host_, CreateInitDoneCB(kNoTimestamp(), |
1706 DEMUXER_ERROR_COULD_NOT_OPEN), true); | 1761 DEMUXER_ERROR_COULD_NOT_OPEN), true); |
1707 | 1762 |
1708 std::vector<std::string> codecs(1); | 1763 std::vector<std::string> codecs(1); |
1709 codecs[0] = "vorbis"; | 1764 codecs[0] = "vorbis"; |
1710 ASSERT_EQ(demuxer_->AddId(kSourceId, "audio/webm", codecs), | 1765 ASSERT_EQ(demuxer_->AddId(kSourceId, "audio/webm", codecs), |
1711 ChunkDemuxer::kOk); | 1766 ChunkDemuxer::kOk); |
1712 | 1767 |
1713 AppendInitSegment(true, true); | 1768 AppendInitSegment(HAS_AUDIO | HAS_VIDEO); |
1714 } | 1769 } |
1715 | 1770 |
1716 TEST_F(ChunkDemuxerTest, AVHeadersWithVideoOnlyType) { | 1771 TEST_F(ChunkDemuxerTest, AVHeadersWithVideoOnlyType) { |
1717 EXPECT_CALL(*this, DemuxerOpened()); | 1772 EXPECT_CALL(*this, DemuxerOpened()); |
1718 demuxer_->Initialize( | 1773 demuxer_->Initialize( |
1719 &host_, CreateInitDoneCB(kNoTimestamp(), | 1774 &host_, CreateInitDoneCB(kNoTimestamp(), |
1720 DEMUXER_ERROR_COULD_NOT_OPEN), true); | 1775 DEMUXER_ERROR_COULD_NOT_OPEN), true); |
1721 | 1776 |
1722 std::vector<std::string> codecs(1); | 1777 std::vector<std::string> codecs(1); |
1723 codecs[0] = "vp8"; | 1778 codecs[0] = "vp8"; |
1724 ASSERT_EQ(demuxer_->AddId(kSourceId, "video/webm", codecs), | 1779 ASSERT_EQ(demuxer_->AddId(kSourceId, "video/webm", codecs), |
1725 ChunkDemuxer::kOk); | 1780 ChunkDemuxer::kOk); |
1726 | 1781 |
1727 AppendInitSegment(true, true); | 1782 AppendInitSegment(HAS_AUDIO | HAS_VIDEO); |
1728 } | 1783 } |
1729 | 1784 |
1730 TEST_F(ChunkDemuxerTest, MultipleHeaders) { | 1785 TEST_F(ChunkDemuxerTest, MultipleHeaders) { |
1731 ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO)); | 1786 ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO)); |
1732 | 1787 |
1733 AppendCluster(kDefaultFirstCluster()); | 1788 AppendCluster(kDefaultFirstCluster()); |
1734 | 1789 |
1735 // Append another identical initialization segment. | 1790 // Append another identical initialization segment. |
1736 AppendInitSegment(true, true); | 1791 AppendInitSegment(HAS_AUDIO | HAS_VIDEO); |
1737 | 1792 |
1738 AppendCluster(kDefaultSecondCluster()); | 1793 AppendCluster(kDefaultSecondCluster()); |
1739 | 1794 |
1740 GenerateExpectedReads(0, 9); | 1795 GenerateExpectedReads(0, 9); |
1741 } | 1796 } |
1742 | 1797 |
1743 TEST_F(ChunkDemuxerTest, AddSeparateSourcesForAudioAndVideo) { | 1798 TEST_F(ChunkDemuxerTest, AddSeparateSourcesForAudioAndVideo) { |
1744 std::string audio_id = "audio1"; | 1799 std::string audio_id = "audio1"; |
1745 std::string video_id = "video1"; | 1800 std::string video_id = "video1"; |
1746 ASSERT_TRUE(InitDemuxerAudioAndVideoSources(audio_id, video_id)); | 1801 ASSERT_TRUE(InitDemuxerAudioAndVideoSources(audio_id, video_id)); |
(...skipping 28 matching lines...) Expand all Loading... |
1775 } | 1830 } |
1776 | 1831 |
1777 TEST_F(ChunkDemuxerTest, AddIdFailures) { | 1832 TEST_F(ChunkDemuxerTest, AddIdFailures) { |
1778 EXPECT_CALL(*this, DemuxerOpened()); | 1833 EXPECT_CALL(*this, DemuxerOpened()); |
1779 demuxer_->Initialize( | 1834 demuxer_->Initialize( |
1780 &host_, CreateInitDoneCB(kDefaultDuration(), PIPELINE_OK), true); | 1835 &host_, CreateInitDoneCB(kDefaultDuration(), PIPELINE_OK), true); |
1781 | 1836 |
1782 std::string audio_id = "audio1"; | 1837 std::string audio_id = "audio1"; |
1783 std::string video_id = "video1"; | 1838 std::string video_id = "video1"; |
1784 | 1839 |
1785 ASSERT_EQ(AddId(audio_id, true, false), ChunkDemuxer::kOk); | 1840 ASSERT_EQ(AddId(audio_id, HAS_AUDIO), ChunkDemuxer::kOk); |
1786 | 1841 |
1787 // Adding an id with audio/video should fail because we already added audio. | 1842 // Adding an id with audio/video should fail because we already added audio. |
1788 ASSERT_EQ(AddId(), ChunkDemuxer::kReachedIdLimit); | 1843 ASSERT_EQ(AddId(), ChunkDemuxer::kReachedIdLimit); |
1789 | 1844 |
1790 AppendInitSegmentWithSourceId(audio_id, true, false, false); | 1845 AppendInitSegmentWithSourceId(audio_id, HAS_AUDIO); |
1791 | 1846 |
1792 // Adding an id after append should fail. | 1847 // Adding an id after append should fail. |
1793 ASSERT_EQ(AddId(video_id, false, true), ChunkDemuxer::kReachedIdLimit); | 1848 ASSERT_EQ(AddId(video_id, HAS_VIDEO), ChunkDemuxer::kReachedIdLimit); |
1794 } | 1849 } |
1795 | 1850 |
1796 // Test that Read() calls after a RemoveId() return "end of stream" buffers. | 1851 // Test that Read() calls after a RemoveId() return "end of stream" buffers. |
1797 TEST_F(ChunkDemuxerTest, RemoveId) { | 1852 TEST_F(ChunkDemuxerTest, RemoveId) { |
1798 std::string audio_id = "audio1"; | 1853 std::string audio_id = "audio1"; |
1799 std::string video_id = "video1"; | 1854 std::string video_id = "video1"; |
1800 ASSERT_TRUE(InitDemuxerAudioAndVideoSources(audio_id, video_id)); | 1855 ASSERT_TRUE(InitDemuxerAudioAndVideoSources(audio_id, video_id)); |
1801 | 1856 |
1802 // Append audio and video data into separate source ids. | 1857 // Append audio and video data into separate source ids. |
1803 AppendCluster(audio_id, | 1858 AppendCluster(audio_id, |
(...skipping 14 matching lines...) Expand all Loading... |
1818 EXPECT_TRUE(audio_read_done); | 1873 EXPECT_TRUE(audio_read_done); |
1819 | 1874 |
1820 // Read() from video should still return normal buffers. | 1875 // Read() from video should still return normal buffers. |
1821 GenerateVideoStreamExpectedReads(0, 4); | 1876 GenerateVideoStreamExpectedReads(0, 4); |
1822 } | 1877 } |
1823 | 1878 |
1824 // Test that removing an ID immediately after adding it does not interfere with | 1879 // Test that removing an ID immediately after adding it does not interfere with |
1825 // quota for new IDs in the future. | 1880 // quota for new IDs in the future. |
1826 TEST_F(ChunkDemuxerTest, RemoveAndAddId) { | 1881 TEST_F(ChunkDemuxerTest, RemoveAndAddId) { |
1827 std::string audio_id_1 = "audio1"; | 1882 std::string audio_id_1 = "audio1"; |
1828 ASSERT_TRUE(AddId(audio_id_1, true, false) == ChunkDemuxer::kOk); | 1883 ASSERT_TRUE(AddId(audio_id_1, HAS_AUDIO) == ChunkDemuxer::kOk); |
1829 demuxer_->RemoveId(audio_id_1); | 1884 demuxer_->RemoveId(audio_id_1); |
1830 | 1885 |
1831 std::string audio_id_2 = "audio2"; | 1886 std::string audio_id_2 = "audio2"; |
1832 ASSERT_TRUE(AddId(audio_id_2, true, false) == ChunkDemuxer::kOk); | 1887 ASSERT_TRUE(AddId(audio_id_2, HAS_AUDIO) == ChunkDemuxer::kOk); |
1833 } | 1888 } |
1834 | 1889 |
1835 TEST_F(ChunkDemuxerTest, SeekCanceled) { | 1890 TEST_F(ChunkDemuxerTest, SeekCanceled) { |
1836 ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO)); | 1891 ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO)); |
1837 | 1892 |
1838 // Append cluster at the beginning of the stream. | 1893 // Append cluster at the beginning of the stream. |
1839 AppendCluster(GenerateCluster(0, 4)); | 1894 AppendCluster(GenerateCluster(0, 4)); |
1840 | 1895 |
1841 // Seek to an unbuffered region. | 1896 // Seek to an unbuffered region. |
1842 Seek(base::TimeDelta::FromSeconds(50)); | 1897 Seek(base::TimeDelta::FromSeconds(50)); |
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2011 | 2066 |
2012 ShutdownDemuxer(); | 2067 ShutdownDemuxer(); |
2013 } | 2068 } |
2014 | 2069 |
2015 // Test ranges in an audio-only stream. | 2070 // Test ranges in an audio-only stream. |
2016 TEST_F(ChunkDemuxerTest, GetBufferedRanges_AudioIdOnly) { | 2071 TEST_F(ChunkDemuxerTest, GetBufferedRanges_AudioIdOnly) { |
2017 EXPECT_CALL(*this, DemuxerOpened()); | 2072 EXPECT_CALL(*this, DemuxerOpened()); |
2018 demuxer_->Initialize( | 2073 demuxer_->Initialize( |
2019 &host_, CreateInitDoneCB(kDefaultDuration(), PIPELINE_OK), true); | 2074 &host_, CreateInitDoneCB(kDefaultDuration(), PIPELINE_OK), true); |
2020 | 2075 |
2021 ASSERT_EQ(AddId(kSourceId, true, false), ChunkDemuxer::kOk); | 2076 ASSERT_EQ(AddId(kSourceId, HAS_AUDIO), ChunkDemuxer::kOk); |
2022 AppendInitSegment(true, false); | 2077 AppendInitSegment(HAS_AUDIO); |
2023 | 2078 |
2024 // Test a simple cluster. | 2079 // Test a simple cluster. |
2025 AppendCluster( | 2080 AppendCluster( |
2026 GenerateSingleStreamCluster(0, 92, kAudioTrackNum, kAudioBlockDuration)); | 2081 GenerateSingleStreamCluster(0, 92, kAudioTrackNum, kAudioBlockDuration)); |
2027 | 2082 |
2028 CheckExpectedRanges("{ [0,92) }"); | 2083 CheckExpectedRanges("{ [0,92) }"); |
2029 | 2084 |
2030 // Append a disjoint cluster to check for two separate ranges. | 2085 // Append a disjoint cluster to check for two separate ranges. |
2031 AppendCluster(GenerateSingleStreamCluster( | 2086 AppendCluster(GenerateSingleStreamCluster( |
2032 150, 219, kAudioTrackNum, kAudioBlockDuration)); | 2087 150, 219, kAudioTrackNum, kAudioBlockDuration)); |
2033 | 2088 |
2034 CheckExpectedRanges("{ [0,92) [150,219) }"); | 2089 CheckExpectedRanges("{ [0,92) [150,219) }"); |
2035 } | 2090 } |
2036 | 2091 |
2037 // Test ranges in a video-only stream. | 2092 // Test ranges in a video-only stream. |
2038 TEST_F(ChunkDemuxerTest, GetBufferedRanges_VideoIdOnly) { | 2093 TEST_F(ChunkDemuxerTest, GetBufferedRanges_VideoIdOnly) { |
2039 EXPECT_CALL(*this, DemuxerOpened()); | 2094 EXPECT_CALL(*this, DemuxerOpened()); |
2040 demuxer_->Initialize( | 2095 demuxer_->Initialize( |
2041 &host_, CreateInitDoneCB(kDefaultDuration(), PIPELINE_OK), true); | 2096 &host_, CreateInitDoneCB(kDefaultDuration(), PIPELINE_OK), true); |
2042 | 2097 |
2043 ASSERT_EQ(AddId(kSourceId, false, true), ChunkDemuxer::kOk); | 2098 ASSERT_EQ(AddId(kSourceId, HAS_VIDEO), ChunkDemuxer::kOk); |
2044 AppendInitSegment(false, true); | 2099 AppendInitSegment(HAS_VIDEO); |
2045 | 2100 |
2046 // Test a simple cluster. | 2101 // Test a simple cluster. |
2047 AppendCluster( | 2102 AppendCluster( |
2048 GenerateSingleStreamCluster(0, 132, kVideoTrackNum, kVideoBlockDuration)); | 2103 GenerateSingleStreamCluster(0, 132, kVideoTrackNum, kVideoBlockDuration)); |
2049 | 2104 |
2050 CheckExpectedRanges("{ [0,132) }"); | 2105 CheckExpectedRanges("{ [0,132) }"); |
2051 | 2106 |
2052 // Append a disjoint cluster to check for two separate ranges. | 2107 // Append a disjoint cluster to check for two separate ranges. |
2053 AppendCluster(GenerateSingleStreamCluster( | 2108 AppendCluster(GenerateSingleStreamCluster( |
2054 200, 299, kVideoTrackNum, kVideoBlockDuration)); | 2109 200, 299, kVideoTrackNum, kVideoBlockDuration)); |
(...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2342 EXPECT_EQ(kLastAudioTimestamp, last_timestamp); | 2397 EXPECT_EQ(kLastAudioTimestamp, last_timestamp); |
2343 | 2398 |
2344 ReadUntilNotOkOrEndOfStream(DemuxerStream::VIDEO, &status, &last_timestamp); | 2399 ReadUntilNotOkOrEndOfStream(DemuxerStream::VIDEO, &status, &last_timestamp); |
2345 EXPECT_EQ(DemuxerStream::kOk, status); | 2400 EXPECT_EQ(DemuxerStream::kOk, status); |
2346 EXPECT_EQ(kLastVideoTimestamp, last_timestamp); | 2401 EXPECT_EQ(kLastVideoTimestamp, last_timestamp); |
2347 } | 2402 } |
2348 | 2403 |
2349 TEST_F(ChunkDemuxerTest, GetBufferedRangesBeforeInitSegment) { | 2404 TEST_F(ChunkDemuxerTest, GetBufferedRangesBeforeInitSegment) { |
2350 EXPECT_CALL(*this, DemuxerOpened()); | 2405 EXPECT_CALL(*this, DemuxerOpened()); |
2351 demuxer_->Initialize(&host_, CreateInitDoneCB(PIPELINE_OK), true); | 2406 demuxer_->Initialize(&host_, CreateInitDoneCB(PIPELINE_OK), true); |
2352 ASSERT_EQ(AddId("audio", true, false), ChunkDemuxer::kOk); | 2407 ASSERT_EQ(AddId("audio", HAS_AUDIO), ChunkDemuxer::kOk); |
2353 ASSERT_EQ(AddId("video", false, true), ChunkDemuxer::kOk); | 2408 ASSERT_EQ(AddId("video", HAS_VIDEO), ChunkDemuxer::kOk); |
2354 | 2409 |
2355 CheckExpectedRanges("audio", "{ }"); | 2410 CheckExpectedRanges("audio", "{ }"); |
2356 CheckExpectedRanges("video", "{ }"); | 2411 CheckExpectedRanges("video", "{ }"); |
2357 } | 2412 } |
2358 | 2413 |
2359 // Test that Seek() completes successfully when the first cluster | 2414 // Test that Seek() completes successfully when the first cluster |
2360 // arrives. | 2415 // arrives. |
2361 TEST_F(ChunkDemuxerTest, EndOfStreamDuringSeek) { | 2416 TEST_F(ChunkDemuxerTest, EndOfStreamDuringSeek) { |
2362 InSequence s; | 2417 InSequence s; |
2363 | 2418 |
(...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2661 | 2716 |
2662 demuxer_->UnmarkEndOfStream(); | 2717 demuxer_->UnmarkEndOfStream(); |
2663 | 2718 |
2664 AppendCluster(kDefaultSecondCluster()); | 2719 AppendCluster(kDefaultSecondCluster()); |
2665 MarkEndOfStream(PIPELINE_OK); | 2720 MarkEndOfStream(PIPELINE_OK); |
2666 } | 2721 } |
2667 | 2722 |
2668 // Test receiving a Shutdown() call before we get an Initialize() | 2723 // Test receiving a Shutdown() call before we get an Initialize() |
2669 // call. This can happen if video element gets destroyed before | 2724 // call. This can happen if video element gets destroyed before |
2670 // the pipeline has a chance to initialize the demuxer. | 2725 // the pipeline has a chance to initialize the demuxer. |
2671 TEST_F(ChunkDemuxerTest, ShutdownBeforeInitialize) { | 2726 TEST_F(ChunkDemuxerTest, Shutdown_BeforeInitialize) { |
2672 demuxer_->Shutdown(); | 2727 demuxer_->Shutdown(); |
2673 demuxer_->Initialize( | 2728 demuxer_->Initialize( |
2674 &host_, CreateInitDoneCB(DEMUXER_ERROR_COULD_NOT_OPEN), true); | 2729 &host_, CreateInitDoneCB(DEMUXER_ERROR_COULD_NOT_OPEN), true); |
2675 message_loop_.RunUntilIdle(); | 2730 message_loop_.RunUntilIdle(); |
2676 } | 2731 } |
2677 | 2732 |
2678 TEST_F(ChunkDemuxerTest, ReadAfterAudioDisabled) { | 2733 TEST_F(ChunkDemuxerTest, ReadAfterAudioDisabled) { |
2679 ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO)); | 2734 ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO)); |
2680 AppendCluster(kDefaultFirstCluster()); | 2735 AppendCluster(kDefaultFirstCluster()); |
2681 | 2736 |
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2815 // why there are 2 ranges in the expectations. | 2870 // why there are 2 ranges in the expectations. |
2816 AppendSingleStreamCluster(kSourceId, kAudioTrackNum, 700, 5); | 2871 AppendSingleStreamCluster(kSourceId, kAudioTrackNum, 700, 5); |
2817 CheckExpectedRanges(kSourceId, "{ [500,592) [792,815) }"); | 2872 CheckExpectedRanges(kSourceId, "{ [500,592) [792,815) }"); |
2818 } | 2873 } |
2819 | 2874 |
2820 TEST_F(ChunkDemuxerTest, RemoveBeforeInitSegment) { | 2875 TEST_F(ChunkDemuxerTest, RemoveBeforeInitSegment) { |
2821 EXPECT_CALL(*this, DemuxerOpened()); | 2876 EXPECT_CALL(*this, DemuxerOpened()); |
2822 demuxer_->Initialize( | 2877 demuxer_->Initialize( |
2823 &host_, CreateInitDoneCB(kNoTimestamp(), PIPELINE_OK), true); | 2878 &host_, CreateInitDoneCB(kNoTimestamp(), PIPELINE_OK), true); |
2824 | 2879 |
2825 EXPECT_EQ(ChunkDemuxer::kOk, AddId(kSourceId, true, true)); | 2880 EXPECT_EQ(ChunkDemuxer::kOk, AddId(kSourceId, HAS_AUDIO | HAS_VIDEO)); |
2826 | 2881 |
2827 demuxer_->Remove(kSourceId, base::TimeDelta::FromMilliseconds(0), | 2882 demuxer_->Remove(kSourceId, base::TimeDelta::FromMilliseconds(0), |
2828 base::TimeDelta::FromMilliseconds(1)); | 2883 base::TimeDelta::FromMilliseconds(1)); |
2829 } | 2884 } |
2830 | 2885 |
2831 TEST_F(ChunkDemuxerTest, AppendWindow_Video) { | 2886 TEST_F(ChunkDemuxerTest, AppendWindow_Video) { |
2832 ASSERT_TRUE(InitDemuxer(HAS_VIDEO)); | 2887 ASSERT_TRUE(InitDemuxer(HAS_VIDEO)); |
2833 DemuxerStream* stream = demuxer_->GetStream(DemuxerStream::VIDEO); | 2888 DemuxerStream* stream = demuxer_->GetStream(DemuxerStream::VIDEO); |
2834 | 2889 |
2835 // Set the append window to [20,280). | 2890 // Set the append window to [20,280). |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2934 } | 2989 } |
2935 | 2990 |
2936 TEST_F(ChunkDemuxerTest, StartWaitingForSeekAfterParseError) { | 2991 TEST_F(ChunkDemuxerTest, StartWaitingForSeekAfterParseError) { |
2937 ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO)); | 2992 ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO)); |
2938 EXPECT_CALL(host_, OnDemuxerError(PIPELINE_ERROR_DECODE)); | 2993 EXPECT_CALL(host_, OnDemuxerError(PIPELINE_ERROR_DECODE)); |
2939 AppendGarbage(); | 2994 AppendGarbage(); |
2940 base::TimeDelta seek_time = base::TimeDelta::FromSeconds(50); | 2995 base::TimeDelta seek_time = base::TimeDelta::FromSeconds(50); |
2941 demuxer_->StartWaitingForSeek(seek_time); | 2996 demuxer_->StartWaitingForSeek(seek_time); |
2942 } | 2997 } |
2943 | 2998 |
| 2999 TEST_F(ChunkDemuxerTest, Remove_AudioVideoText) { |
| 3000 DemuxerStream* text_stream = NULL; |
| 3001 EXPECT_CALL(host_, AddTextStream(_, _)) |
| 3002 .WillOnce(SaveArg<0>(&text_stream)); |
| 3003 ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO | HAS_TEXT)); |
| 3004 |
| 3005 DemuxerStream* audio_stream = demuxer_->GetStream(DemuxerStream::AUDIO); |
| 3006 DemuxerStream* video_stream = demuxer_->GetStream(DemuxerStream::VIDEO); |
| 3007 |
| 3008 AppendSingleStreamCluster(kSourceId, kAudioTrackNum, |
| 3009 "0K 20K 40K 60K 80K 100K 120K 140K"); |
| 3010 AppendSingleStreamCluster(kSourceId, kVideoTrackNum, |
| 3011 "0K 30 60 90 120K 150 180"); |
| 3012 AppendSingleStreamCluster(kSourceId, kTextTrackNum, "0K 100K 200K"); |
| 3013 |
| 3014 CheckExpectedBuffers(audio_stream, "0 20 40 60 80 100 120 140"); |
| 3015 CheckExpectedBuffers(video_stream, "0 30 60 90 120 150 180"); |
| 3016 CheckExpectedBuffers(text_stream, "0 100 200"); |
| 3017 |
| 3018 // Remove the buffers that were added. |
| 3019 demuxer_->Remove(kSourceId, base::TimeDelta(), |
| 3020 base::TimeDelta::FromMilliseconds(300)); |
| 3021 |
| 3022 // Verify that all the appended data has been removed. |
| 3023 CheckExpectedRanges(kSourceId, "{ }"); |
| 3024 |
| 3025 // Append new buffers that are clearly different than the original |
| 3026 // ones and verify that only the new buffers are returned. |
| 3027 AppendSingleStreamCluster(kSourceId, kAudioTrackNum, |
| 3028 "1K 21K 41K 61K 81K 101K 121K 141K"); |
| 3029 AppendSingleStreamCluster(kSourceId, kVideoTrackNum, |
| 3030 "1K 31 61 91 121K 151 181"); |
| 3031 AppendSingleStreamCluster(kSourceId, kTextTrackNum, "1K 101K 201K"); |
| 3032 |
| 3033 Seek(base::TimeDelta()); |
| 3034 CheckExpectedBuffers(audio_stream, "1 21 41 61 81 101 121 141"); |
| 3035 CheckExpectedBuffers(video_stream, "1 31 61 91 121 151 181"); |
| 3036 CheckExpectedBuffers(text_stream, "1 101 201"); |
| 3037 } |
| 3038 |
| 3039 // Verifies that a Seek() will complete without text cues for |
| 3040 // the seek point and will return cues after the seek position |
| 3041 // when they are eventually appended. |
| 3042 TEST_F(ChunkDemuxerTest, SeekCompletesWithoutTextCues) { |
| 3043 DemuxerStream* text_stream = NULL; |
| 3044 EXPECT_CALL(host_, AddTextStream(_, _)) |
| 3045 .WillOnce(SaveArg<0>(&text_stream)); |
| 3046 ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO | HAS_TEXT)); |
| 3047 |
| 3048 DemuxerStream* audio_stream = demuxer_->GetStream(DemuxerStream::AUDIO); |
| 3049 DemuxerStream* video_stream = demuxer_->GetStream(DemuxerStream::VIDEO); |
| 3050 |
| 3051 base::TimeDelta seek_time = base::TimeDelta::FromMilliseconds(120); |
| 3052 bool seek_cb_was_called = false; |
| 3053 demuxer_->StartWaitingForSeek(seek_time); |
| 3054 demuxer_->Seek(seek_time, |
| 3055 base::Bind(OnSeekDone_OKExpected, &seek_cb_was_called)); |
| 3056 message_loop_.RunUntilIdle(); |
| 3057 |
| 3058 EXPECT_FALSE(seek_cb_was_called); |
| 3059 |
| 3060 bool text_read_done = false; |
| 3061 text_stream->Read(base::Bind(&OnReadDone, |
| 3062 base::TimeDelta::FromMilliseconds(125), |
| 3063 &text_read_done)); |
| 3064 |
| 3065 // Append audio & video data so the seek completes. |
| 3066 AppendSingleStreamCluster(kSourceId, kAudioTrackNum, |
| 3067 "0K 20K 40K 60K 80K 100K 120K 140K 160K 180K"); |
| 3068 AppendSingleStreamCluster(kSourceId, kVideoTrackNum, |
| 3069 "0K 30 60 90 120K 150 180 210"); |
| 3070 |
| 3071 message_loop_.RunUntilIdle(); |
| 3072 EXPECT_TRUE(seek_cb_was_called); |
| 3073 EXPECT_FALSE(text_read_done); |
| 3074 |
| 3075 // Read some audio & video buffers to further verify seek completion. |
| 3076 CheckExpectedBuffers(audio_stream, "120 140"); |
| 3077 CheckExpectedBuffers(video_stream, "120 150"); |
| 3078 |
| 3079 EXPECT_FALSE(text_read_done); |
| 3080 |
| 3081 // Append text cues that start after the seek point and verify that |
| 3082 // they are returned by Read() calls. |
| 3083 AppendSingleStreamCluster(kSourceId, kTextTrackNum, "125K 175K 225K"); |
| 3084 |
| 3085 message_loop_.RunUntilIdle(); |
| 3086 EXPECT_TRUE(text_read_done); |
| 3087 |
| 3088 // NOTE: we start at 175 here because the buffer at 125 was returned |
| 3089 // to the pending read initiated above. |
| 3090 CheckExpectedBuffers(text_stream, "175 225"); |
| 3091 |
| 3092 // Verify that audio & video streams contiue to return expected values. |
| 3093 CheckExpectedBuffers(audio_stream, "160 180"); |
| 3094 CheckExpectedBuffers(video_stream, "180 210"); |
| 3095 } |
| 3096 |
2944 } // namespace media | 3097 } // namespace media |
OLD | NEW |