| 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 |