Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(414)

Side by Side Diff: media/filters/chunk_demuxer_unittest.cc

Issue 110693007: Fix various operations in ChunkDemuxer that were not being applied to text tracks. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Address CR comments Created 6 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « media/filters/chunk_demuxer.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « media/filters/chunk_demuxer.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698