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

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

Issue 2226443002: Support multiple media tracks in MSE / ChunkDemuxer (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fixed integer overflow Created 4 years, 3 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
« no previous file with comments | « media/filters/chunk_demuxer.cc ('k') | media/filters/frame_processor.h » ('j') | 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 "media/filters/chunk_demuxer.h" 5 #include "media/filters/chunk_demuxer.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 #include <stdint.h> 8 #include <stdint.h>
9 #include <algorithm> 9 #include <algorithm>
10 #include <utility> 10 #include <utility>
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
118 } 118 }
119 } 119 }
120 120
121 MATCHER_P(HasTimestamp, timestamp_in_ms, "") { 121 MATCHER_P(HasTimestamp, timestamp_in_ms, "") {
122 return arg.get() && !arg->end_of_stream() && 122 return arg.get() && !arg->end_of_stream() &&
123 arg->timestamp().InMilliseconds() == timestamp_in_ms; 123 arg->timestamp().InMilliseconds() == timestamp_in_ms;
124 } 124 }
125 125
126 MATCHER(IsEndOfStream, "") { return arg.get() && arg->end_of_stream(); } 126 MATCHER(IsEndOfStream, "") { return arg.get() && arg->end_of_stream(); }
127 127
128 MATCHER_P(SegmentMissingFrames, frame_types_string, "") { 128 MATCHER_P(SegmentMissingFrames, track_id, "") {
129 return CONTAINS_STRING(arg, "Media segment did not contain any " + 129 return CONTAINS_STRING(
130 std::string(frame_types_string) + 130 arg, "Media segment did not contain any coded frames for track " +
131 " coded frames, mismatching initialization " 131 std::string(track_id));
132 "segment. Therefore, MSE coded frame "
133 "processing may not interoperably detect "
134 "discontinuities in appended media.");
135 } 132 }
136 133
137 MATCHER(StreamParsingFailed, "") { 134 MATCHER(StreamParsingFailed, "") {
138 return CONTAINS_STRING(arg, "Append: stream parsing failed."); 135 return CONTAINS_STRING(arg, "Append: stream parsing failed.");
139 } 136 }
140 137
141 MATCHER_P(FoundStream, stream_type_string, "") { 138 MATCHER_P(FoundStream, stream_type_string, "") {
142 return CONTAINS_STRING( 139 return CONTAINS_STRING(
143 arg, "found_" + std::string(stream_type_string) + "_stream") && 140 arg, "found_" + std::string(stream_type_string) + "_stream") &&
144 CONTAINS_STRING(arg, "true"); 141 CONTAINS_STRING(arg, "true");
145 } 142 }
146 143
147 MATCHER_P2(CodecName, stream_type_string, codec_string, "") { 144 MATCHER_P2(CodecName, stream_type_string, codec_string, "") {
148 return CONTAINS_STRING(arg, 145 return CONTAINS_STRING(arg,
149 std::string(stream_type_string) + "_codec_name") && 146 std::string(stream_type_string) + "_codec_name") &&
150 CONTAINS_STRING(arg, std::string(codec_string)); 147 CONTAINS_STRING(arg, std::string(codec_string));
151 } 148 }
152 149
153 MATCHER_P2(InitSegmentMismatchesMimeType, 150 MATCHER_P2(InitSegmentMismatchesMimeType, stream_type, codec_name, "") {
154 track_type_string_with_article, 151 return CONTAINS_STRING(arg, std::string(stream_type) + " stream codec " +
155 mime_missing_track_type_bool, 152 std::string(codec_name) +
156 "") { 153 " doesn't match SourceBuffer codecs.");
157 return CONTAINS_STRING( 154 }
158 arg, "Initialization segment " + 155
159 std::string(mime_missing_track_type_bool ? "has " 156 MATCHER_P(InitSegmentMissesExpectedTrack, missing_codec, "") {
160 : "does not have ") + 157 return CONTAINS_STRING(arg, "Initialization segment misses expected " +
161 std::string(track_type_string_with_article) + 158 std::string(missing_codec) + " track.");
162 " track, but the mimetype " +
163 std::string(mime_missing_track_type_bool ? "does not specify "
164 : "specifies ") +
165 std::string(track_type_string_with_article) + " codec.");
166 } 159 }
167 160
168 MATCHER_P2(GeneratedSplice, duration_microseconds, time_microseconds, "") { 161 MATCHER_P2(GeneratedSplice, duration_microseconds, time_microseconds, "") {
169 return CONTAINS_STRING(arg, "Generated splice of overlap duration " + 162 return CONTAINS_STRING(arg, "Generated splice of overlap duration " +
170 base::IntToString(duration_microseconds) + 163 base::IntToString(duration_microseconds) +
171 "us into new buffer at " + 164 "us into new buffer at " +
172 base::IntToString(time_microseconds) + "us."); 165 base::IntToString(time_microseconds) + "us.");
173 } 166 }
174 167
175 MATCHER_P2(SkippingSpliceAtOrBefore, 168 MATCHER_P2(SkippingSpliceAtOrBefore,
(...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after
381 374
382 memcpy(buf, info->data(), info->data_size()); 375 memcpy(buf, info->data(), info->data_size());
383 buf += info->data_size(); 376 buf += info->data_size();
384 377
385 memcpy(buf, kTracksHeader, kTracksHeaderSize); 378 memcpy(buf, kTracksHeader, kTracksHeaderSize);
386 WriteInt64(buf + kTracksSizeOffset, tracks_element_size); 379 WriteInt64(buf + kTracksSizeOffset, tracks_element_size);
387 buf += kTracksHeaderSize; 380 buf += kTracksHeaderSize;
388 381
389 // TODO(xhwang): Simplify this! Probably have test data files that contain 382 // TODO(xhwang): Simplify this! Probably have test data files that contain
390 // ContentEncodings directly instead of trying to create one at run-time. 383 // ContentEncodings directly instead of trying to create one at run-time.
391 if (has_audio) {
392 memcpy(buf, audio_track_entry->data(),
393 audio_track_entry->data_size());
394 if (is_audio_encrypted) {
395 memcpy(buf + audio_track_entry->data_size(),
396 audio_content_encodings->data(),
397 audio_content_encodings->data_size());
398 WriteInt64(buf + kAudioTrackSizeOffset,
399 audio_track_entry->data_size() +
400 audio_content_encodings->data_size() -
401 kAudioTrackEntryHeaderSize);
402 buf += audio_content_encodings->data_size();
403 }
404 buf += audio_track_entry->data_size();
405 }
406
407 if (has_video) { 384 if (has_video) {
408 memcpy(buf, video_track_entry->data(), 385 memcpy(buf, video_track_entry->data(),
409 video_track_entry->data_size()); 386 video_track_entry->data_size());
410 if (is_video_encrypted) { 387 if (is_video_encrypted) {
411 memcpy(buf + video_track_entry->data_size(), 388 memcpy(buf + video_track_entry->data_size(),
412 video_content_encodings->data(), 389 video_content_encodings->data(),
413 video_content_encodings->data_size()); 390 video_content_encodings->data_size());
414 WriteInt64(buf + kVideoTrackSizeOffset, 391 WriteInt64(buf + kVideoTrackSizeOffset,
415 video_track_entry->data_size() + 392 video_track_entry->data_size() +
416 video_content_encodings->data_size() - 393 video_content_encodings->data_size() -
417 kVideoTrackEntryHeaderSize); 394 kVideoTrackEntryHeaderSize);
418 buf += video_content_encodings->data_size(); 395 buf += video_content_encodings->data_size();
419 } 396 }
420 buf += video_track_entry->data_size(); 397 buf += video_track_entry->data_size();
421 } 398 }
422 399
400 if (has_audio) {
401 memcpy(buf, audio_track_entry->data(), audio_track_entry->data_size());
402 if (is_audio_encrypted) {
403 memcpy(buf + audio_track_entry->data_size(),
404 audio_content_encodings->data(),
405 audio_content_encodings->data_size());
406 WriteInt64(buf + kAudioTrackSizeOffset,
407 audio_track_entry->data_size() +
408 audio_content_encodings->data_size() -
409 kAudioTrackEntryHeaderSize);
410 buf += audio_content_encodings->data_size();
411 }
412 buf += audio_track_entry->data_size();
413 }
414
423 if (has_text) { 415 if (has_text) {
424 memcpy(buf, text_track_entry->data(), 416 memcpy(buf, text_track_entry->data(),
425 text_track_entry->data_size()); 417 text_track_entry->data_size());
426 buf += text_track_entry->data_size(); 418 buf += text_track_entry->data_size();
427 } 419 }
428 } 420 }
429 421
430 ChunkDemuxer::Status AddId() { 422 ChunkDemuxer::Status AddId() {
431 return AddId(kSourceId, HAS_AUDIO | HAS_VIDEO); 423 return AddId(kSourceId, HAS_AUDIO | HAS_VIDEO);
432 } 424 }
433 425
434 ChunkDemuxer::Status AddId(const std::string& source_id, int stream_flags) { 426 ChunkDemuxer::Status AddId(const std::string& source_id, int stream_flags) {
435 bool has_audio = (stream_flags & HAS_AUDIO) != 0; 427 bool has_audio = (stream_flags & HAS_AUDIO) != 0;
436 bool has_video = (stream_flags & HAS_VIDEO) != 0; 428 bool has_video = (stream_flags & HAS_VIDEO) != 0;
437 std::vector<std::string> codecs; 429 std::string codecs;
438 std::string type; 430 std::string type;
439 431
440 if (has_audio) { 432 if (has_audio) {
441 codecs.push_back("vorbis"); 433 codecs += "vorbis";
442 type = "audio/webm"; 434 type = "audio/webm";
443 } 435 }
444 436
445 if (has_video) { 437 if (has_video) {
446 codecs.push_back("vp8"); 438 if (codecs == "")
439 codecs = "vp8";
440 else
441 codecs += ",vp8";
447 type = "video/webm"; 442 type = "video/webm";
448 } 443 }
449 444
450 if (!has_audio && !has_video) { 445 if (!has_audio && !has_video) {
451 return AddId(kSourceId, HAS_AUDIO | HAS_VIDEO); 446 return AddId(kSourceId, HAS_AUDIO | HAS_VIDEO);
452 } 447 }
453 448
454 ChunkDemuxer::Status status = demuxer_->AddId(source_id, type, codecs); 449 return AddId(source_id, type, codecs);
450 }
451
452 ChunkDemuxer::Status AddId(const std::string& source_id,
453 const std::string& mime_type,
454 const std::string& codecs) {
455 ChunkDemuxer::Status status = demuxer_->AddId(source_id, mime_type, codecs);
455 if (status == ChunkDemuxer::kOk) 456 if (status == ChunkDemuxer::kOk)
456 demuxer_->SetTracksWatcher( 457 demuxer_->SetTracksWatcher(
457 source_id, base::Bind(&ChunkDemuxerTest::InitSegmentReceived, 458 source_id, base::Bind(&ChunkDemuxerTest::InitSegmentReceived,
458 base::Unretained(this))); 459 base::Unretained(this)));
459 return status; 460 return status;
460 } 461 }
461 462
462 #if BUILDFLAG(ENABLE_MSE_MPEG2TS_STREAM_PARSER)
463 ChunkDemuxer::Status AddIdForMp2tSource(const std::string& source_id) {
464 std::vector<std::string> codecs;
465 std::string type = "video/mp2t";
466 codecs.push_back("mp4a.40.2");
467 codecs.push_back("avc1.640028");
468 ChunkDemuxer::Status status = demuxer_->AddId(source_id, type, codecs);
469 if (status == ChunkDemuxer::kOk)
470 demuxer_->SetTracksWatcher(
471 source_id, base::Bind(&ChunkDemuxerTest::InitSegmentReceived,
472 base::Unretained(this)));
473 return status;
474 }
475 #endif
476
477 bool AppendData(const uint8_t* data, size_t length) { 463 bool AppendData(const uint8_t* data, size_t length) {
478 return AppendData(kSourceId, data, length); 464 return AppendData(kSourceId, data, length);
479 } 465 }
480 466
481 bool AppendCluster(const std::string& source_id, 467 bool AppendCluster(const std::string& source_id,
482 std::unique_ptr<Cluster> cluster) { 468 std::unique_ptr<Cluster> cluster) {
483 return AppendData(source_id, cluster->data(), cluster->size()); 469 return AppendData(source_id, cluster->data(), cluster->size());
484 } 470 }
485 471
486 bool AppendCluster(std::unique_ptr<Cluster> cluster) { 472 bool AppendCluster(std::unique_ptr<Cluster> cluster) {
(...skipping 324 matching lines...) Expand 10 before | Expand all | Expand 10 after
811 USE_ALTERNATE_AUDIO_TRACK_ID = 1 << 3, 797 USE_ALTERNATE_AUDIO_TRACK_ID = 1 << 3,
812 USE_ALTERNATE_VIDEO_TRACK_ID = 1 << 4, 798 USE_ALTERNATE_VIDEO_TRACK_ID = 1 << 4,
813 USE_ALTERNATE_TEXT_TRACK_ID = 1 << 5, 799 USE_ALTERNATE_TEXT_TRACK_ID = 1 << 5,
814 }; 800 };
815 801
816 bool InitDemuxer(int stream_flags) { 802 bool InitDemuxer(int stream_flags) {
817 return InitDemuxerWithEncryptionInfo(stream_flags, false, false); 803 return InitDemuxerWithEncryptionInfo(stream_flags, false, false);
818 } 804 }
819 805
820 void ExpectInitMediaLogs(int stream_flags) { 806 void ExpectInitMediaLogs(int stream_flags) {
807 if (stream_flags & HAS_VIDEO) {
808 EXPECT_MEDIA_LOG(FoundStream("video"));
809 EXPECT_MEDIA_LOG(CodecName("video", "vp8"));
810 }
821 if (stream_flags & HAS_AUDIO) { 811 if (stream_flags & HAS_AUDIO) {
822 EXPECT_MEDIA_LOG(FoundStream("audio")); 812 EXPECT_MEDIA_LOG(FoundStream("audio"));
823 EXPECT_MEDIA_LOG(CodecName("audio", "vorbis")); 813 EXPECT_MEDIA_LOG(CodecName("audio", "vorbis"));
824 } 814 }
825
826 if (stream_flags & HAS_VIDEO) {
827 EXPECT_MEDIA_LOG(FoundStream("video"));
828 EXPECT_MEDIA_LOG(CodecName("video", "vp8"));
829 }
830 } 815 }
831 816
832 bool InitDemuxerWithEncryptionInfo( 817 bool InitDemuxerWithEncryptionInfo(
833 int stream_flags, bool is_audio_encrypted, bool is_video_encrypted) { 818 int stream_flags, bool is_audio_encrypted, bool is_video_encrypted) {
834 PipelineStatus expected_status = 819 PipelineStatus expected_status =
835 (stream_flags != 0) ? PIPELINE_OK : CHUNK_DEMUXER_ERROR_APPEND_FAILED; 820 (stream_flags != 0) ? PIPELINE_OK : CHUNK_DEMUXER_ERROR_APPEND_FAILED;
836 821
837 base::TimeDelta expected_duration = kNoTimestamp; 822 base::TimeDelta expected_duration = kNoTimestamp;
838 if (expected_status == PIPELINE_OK) 823 if (expected_status == PIPELINE_OK)
839 expected_duration = kDefaultDuration(); 824 expected_duration = kDefaultDuration();
(...skipping 17 matching lines...) Expand all
857 842
858 // Adding expectations prior to CreateInitDoneCB() here because InSequence 843 // Adding expectations prior to CreateInitDoneCB() here because InSequence
859 // tests require init segment received before duration set. Also, only 844 // tests require init segment received before duration set. Also, only
860 // expect an init segment received callback if there is actually a track in 845 // expect an init segment received callback if there is actually a track in
861 // it. 846 // it.
862 if (stream_flags != 0) { 847 if (stream_flags != 0) {
863 ExpectInitMediaLogs(stream_flags); 848 ExpectInitMediaLogs(stream_flags);
864 EXPECT_CALL(*this, InitSegmentReceivedMock(_)); 849 EXPECT_CALL(*this, InitSegmentReceivedMock(_));
865 } else { 850 } else {
866 // OnNewConfigs() requires at least one audio, video, or text track. 851 // OnNewConfigs() requires at least one audio, video, or text track.
852 EXPECT_MEDIA_LOG(InitSegmentMissesExpectedTrack("vorbis"));
853 EXPECT_MEDIA_LOG(InitSegmentMissesExpectedTrack("vp8"));
867 EXPECT_MEDIA_LOG(StreamParsingFailed()); 854 EXPECT_MEDIA_LOG(StreamParsingFailed());
868 } 855 }
869 856
870 demuxer_->Initialize( 857 demuxer_->Initialize(
871 &host_, CreateInitDoneCB(expected_duration, expected_status), true); 858 &host_, CreateInitDoneCB(expected_duration, expected_status), true);
872 859
873 if (AddId(kSourceId, stream_flags) != ChunkDemuxer::kOk) 860 if (AddId(kSourceId, stream_flags) != ChunkDemuxer::kOk)
874 return false; 861 return false;
875 862
876 return AppendInitSegmentWithEncryptedInfo( 863 return AppendInitSegmentWithEncryptedInfo(
(...skipping 1526 matching lines...) Expand 10 before | Expand all | Expand 10 after
2403 kSourceId, &tmp, 1, append_window_start_for_next_append_, 2390 kSourceId, &tmp, 1, append_window_start_for_next_append_,
2404 append_window_end_for_next_append_, &timestamp_offset_map_[kSourceId])); 2391 append_window_end_for_next_append_, &timestamp_offset_map_[kSourceId]));
2405 } 2392 }
2406 2393
2407 TEST_F(ChunkDemuxerTest, AVHeadersWithAudioOnlyType) { 2394 TEST_F(ChunkDemuxerTest, AVHeadersWithAudioOnlyType) {
2408 EXPECT_CALL(*this, DemuxerOpened()); 2395 EXPECT_CALL(*this, DemuxerOpened());
2409 demuxer_->Initialize( 2396 demuxer_->Initialize(
2410 &host_, CreateInitDoneCB(kNoTimestamp, CHUNK_DEMUXER_ERROR_APPEND_FAILED), 2397 &host_, CreateInitDoneCB(kNoTimestamp, CHUNK_DEMUXER_ERROR_APPEND_FAILED),
2411 true); 2398 true);
2412 2399
2413 std::vector<std::string> codecs(1); 2400 ASSERT_EQ(demuxer_->AddId(kSourceId, "audio/webm", "vorbis"),
2414 codecs[0] = "vorbis";
2415 ASSERT_EQ(demuxer_->AddId(kSourceId, "audio/webm", codecs),
2416 ChunkDemuxer::kOk); 2401 ChunkDemuxer::kOk);
2417 demuxer_->SetTracksWatcher(kSourceId, 2402 demuxer_->SetTracksWatcher(kSourceId,
2418 base::Bind(&ChunkDemuxerTest::InitSegmentReceived, 2403 base::Bind(&ChunkDemuxerTest::InitSegmentReceived,
2419 base::Unretained(this))); 2404 base::Unretained(this)));
2420 2405
2421 // Video track is unexpected per mimetype. 2406 // Video track is unexpected per mimetype.
2422 EXPECT_MEDIA_LOG(InitSegmentMismatchesMimeType("a video", true)); 2407 EXPECT_MEDIA_LOG(InitSegmentMismatchesMimeType("Video", "vp8"));
2423 EXPECT_MEDIA_LOG(StreamParsingFailed()); 2408 EXPECT_MEDIA_LOG(StreamParsingFailed());
2424 ASSERT_FALSE(AppendInitSegment(HAS_AUDIO | HAS_VIDEO)); 2409 ASSERT_FALSE(AppendInitSegment(HAS_AUDIO | HAS_VIDEO));
2425 } 2410 }
2426 2411
2427 TEST_F(ChunkDemuxerTest, AVHeadersWithVideoOnlyType) { 2412 TEST_F(ChunkDemuxerTest, AVHeadersWithVideoOnlyType) {
2428 EXPECT_CALL(*this, DemuxerOpened()); 2413 EXPECT_CALL(*this, DemuxerOpened());
2429 demuxer_->Initialize( 2414 demuxer_->Initialize(
2430 &host_, CreateInitDoneCB(kNoTimestamp, CHUNK_DEMUXER_ERROR_APPEND_FAILED), 2415 &host_, CreateInitDoneCB(kNoTimestamp, CHUNK_DEMUXER_ERROR_APPEND_FAILED),
2431 true); 2416 true);
2432 2417
2433 std::vector<std::string> codecs(1); 2418 ASSERT_EQ(demuxer_->AddId(kSourceId, "video/webm", "vp8"), ChunkDemuxer::kOk);
2434 codecs[0] = "vp8";
2435 ASSERT_EQ(demuxer_->AddId(kSourceId, "video/webm", codecs),
2436 ChunkDemuxer::kOk);
2437 demuxer_->SetTracksWatcher(kSourceId, 2419 demuxer_->SetTracksWatcher(kSourceId,
2438 base::Bind(&ChunkDemuxerTest::InitSegmentReceived, 2420 base::Bind(&ChunkDemuxerTest::InitSegmentReceived,
2439 base::Unretained(this))); 2421 base::Unretained(this)));
2440 2422
2441 // Audio track is unexpected per mimetype. 2423 // Audio track is unexpected per mimetype.
2442 EXPECT_MEDIA_LOG(InitSegmentMismatchesMimeType("an audio", true)); 2424 EXPECT_MEDIA_LOG(FoundStream("video"));
2425 EXPECT_MEDIA_LOG(CodecName("video", "vp8"));
2426 EXPECT_MEDIA_LOG(InitSegmentMismatchesMimeType("Audio", "vorbis"));
2443 EXPECT_MEDIA_LOG(StreamParsingFailed()); 2427 EXPECT_MEDIA_LOG(StreamParsingFailed());
2444 ASSERT_FALSE(AppendInitSegment(HAS_AUDIO | HAS_VIDEO)); 2428 ASSERT_FALSE(AppendInitSegment(HAS_AUDIO | HAS_VIDEO));
2445 } 2429 }
2446 2430
2447 TEST_F(ChunkDemuxerTest, AudioOnlyHeaderWithAVType) { 2431 TEST_F(ChunkDemuxerTest, AudioOnlyHeaderWithAVType) {
2448 EXPECT_CALL(*this, DemuxerOpened()); 2432 EXPECT_CALL(*this, DemuxerOpened());
2449 demuxer_->Initialize( 2433 demuxer_->Initialize(
2450 &host_, CreateInitDoneCB(kNoTimestamp, CHUNK_DEMUXER_ERROR_APPEND_FAILED), 2434 &host_, CreateInitDoneCB(kNoTimestamp, CHUNK_DEMUXER_ERROR_APPEND_FAILED),
2451 true); 2435 true);
2452 2436
2453 std::vector<std::string> codecs(2); 2437 ASSERT_EQ(demuxer_->AddId(kSourceId, "video/webm", "vorbis,vp8"),
2454 codecs[0] = "vorbis";
2455 codecs[1] = "vp8";
2456 ASSERT_EQ(demuxer_->AddId(kSourceId, "video/webm", codecs),
2457 ChunkDemuxer::kOk); 2438 ChunkDemuxer::kOk);
2458 demuxer_->SetTracksWatcher(kSourceId, 2439 demuxer_->SetTracksWatcher(kSourceId,
2459 base::Bind(&ChunkDemuxerTest::InitSegmentReceived, 2440 base::Bind(&ChunkDemuxerTest::InitSegmentReceived,
2460 base::Unretained(this))); 2441 base::Unretained(this)));
2461 2442
2462 // Video track is also expected per mimetype. 2443 // Video track is also expected per mimetype.
2463 EXPECT_MEDIA_LOG(InitSegmentMismatchesMimeType("a video", false)); 2444 EXPECT_MEDIA_LOG(FoundStream("audio"));
2445 EXPECT_MEDIA_LOG(CodecName("audio", "vorbis"));
2446 EXPECT_MEDIA_LOG(InitSegmentMissesExpectedTrack("vp8"));
2464 EXPECT_MEDIA_LOG(StreamParsingFailed()); 2447 EXPECT_MEDIA_LOG(StreamParsingFailed());
2465 ASSERT_FALSE(AppendInitSegment(HAS_AUDIO)); 2448 ASSERT_FALSE(AppendInitSegment(HAS_AUDIO));
2466 } 2449 }
2467 2450
2468 TEST_F(ChunkDemuxerTest, VideoOnlyHeaderWithAVType) { 2451 TEST_F(ChunkDemuxerTest, VideoOnlyHeaderWithAVType) {
2469 EXPECT_CALL(*this, DemuxerOpened()); 2452 EXPECT_CALL(*this, DemuxerOpened());
2470 demuxer_->Initialize( 2453 demuxer_->Initialize(
2471 &host_, CreateInitDoneCB(kNoTimestamp, CHUNK_DEMUXER_ERROR_APPEND_FAILED), 2454 &host_, CreateInitDoneCB(kNoTimestamp, CHUNK_DEMUXER_ERROR_APPEND_FAILED),
2472 true); 2455 true);
2473 2456
2474 std::vector<std::string> codecs(2); 2457 ASSERT_EQ(demuxer_->AddId(kSourceId, "video/webm", "vorbis,vp8"),
2475 codecs[0] = "vorbis";
2476 codecs[1] = "vp8";
2477 ASSERT_EQ(demuxer_->AddId(kSourceId, "video/webm", codecs),
2478 ChunkDemuxer::kOk); 2458 ChunkDemuxer::kOk);
2479 demuxer_->SetTracksWatcher(kSourceId, 2459 demuxer_->SetTracksWatcher(kSourceId,
2480 base::Bind(&ChunkDemuxerTest::InitSegmentReceived, 2460 base::Bind(&ChunkDemuxerTest::InitSegmentReceived,
2481 base::Unretained(this))); 2461 base::Unretained(this)));
2482 2462
2483 // Audio track is also expected per mimetype. 2463 // Audio track is also expected per mimetype.
2484 EXPECT_MEDIA_LOG(InitSegmentMismatchesMimeType("an audio", false)); 2464 EXPECT_MEDIA_LOG(FoundStream("video"));
2465 EXPECT_MEDIA_LOG(CodecName("video", "vp8"));
2466 EXPECT_MEDIA_LOG(InitSegmentMissesExpectedTrack("vorbis"));
2485 EXPECT_MEDIA_LOG(StreamParsingFailed()); 2467 EXPECT_MEDIA_LOG(StreamParsingFailed());
2486 ASSERT_FALSE(AppendInitSegment(HAS_VIDEO)); 2468 ASSERT_FALSE(AppendInitSegment(HAS_VIDEO));
2487 } 2469 }
2488 2470
2489 TEST_F(ChunkDemuxerTest, MultipleHeaders) { 2471 TEST_F(ChunkDemuxerTest, MultipleHeaders) {
2490 ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO)); 2472 ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
2491 2473
2492 ASSERT_TRUE(AppendCluster(kDefaultFirstCluster())); 2474 ASSERT_TRUE(AppendCluster(kDefaultFirstCluster()));
2493 2475
2494 // Append another identical initialization segment. 2476 // Append another identical initialization segment.
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
2541 TEST_F(ChunkDemuxerTest, AddIdFailures) { 2523 TEST_F(ChunkDemuxerTest, AddIdFailures) {
2542 EXPECT_CALL(*this, DemuxerOpened()); 2524 EXPECT_CALL(*this, DemuxerOpened());
2543 demuxer_->Initialize( 2525 demuxer_->Initialize(
2544 &host_, CreateInitDoneCB(kDefaultDuration(), PIPELINE_OK), true); 2526 &host_, CreateInitDoneCB(kDefaultDuration(), PIPELINE_OK), true);
2545 2527
2546 std::string audio_id = "audio1"; 2528 std::string audio_id = "audio1";
2547 std::string video_id = "video1"; 2529 std::string video_id = "video1";
2548 2530
2549 ASSERT_EQ(AddId(audio_id, HAS_AUDIO), ChunkDemuxer::kOk); 2531 ASSERT_EQ(AddId(audio_id, HAS_AUDIO), ChunkDemuxer::kOk);
2550 2532
2551 // Adding an id with audio/video should fail because we already added audio.
2552 ASSERT_EQ(AddId(), ChunkDemuxer::kReachedIdLimit);
2553
2554 ExpectInitMediaLogs(HAS_AUDIO); 2533 ExpectInitMediaLogs(HAS_AUDIO);
2555 EXPECT_CALL(*this, InitSegmentReceivedMock(_)); 2534 EXPECT_CALL(*this, InitSegmentReceivedMock(_));
2556 ASSERT_TRUE(AppendInitSegmentWithSourceId(audio_id, HAS_AUDIO)); 2535 ASSERT_TRUE(AppendInitSegmentWithSourceId(audio_id, HAS_AUDIO));
2557 2536
2558 // Adding an id after append should fail. 2537 // Adding an id after append should fail.
2559 ASSERT_EQ(AddId(video_id, HAS_VIDEO), ChunkDemuxer::kReachedIdLimit); 2538 ASSERT_EQ(AddId(video_id, HAS_VIDEO), ChunkDemuxer::kReachedIdLimit);
2560 } 2539 }
2561 2540
2562 // Test that Read() calls after a RemoveId() return "end of stream" buffers. 2541 // Test that Read() calls after a RemoveId() return "end of stream" buffers.
2563 TEST_F(ChunkDemuxerTest, RemoveId) { 2542 TEST_F(ChunkDemuxerTest, RemoveId) {
2564 std::string audio_id = "audio1"; 2543 std::string audio_id = "audio1";
2565 std::string video_id = "video1"; 2544 std::string video_id = "video1";
2566 ASSERT_TRUE(InitDemuxerAudioAndVideoSources(audio_id, video_id)); 2545 ASSERT_TRUE(InitDemuxerAudioAndVideoSources(audio_id, video_id));
2567 2546
2568 // Append audio and video data into separate source ids. 2547 // Append audio and video data into separate source ids.
2569 ASSERT_TRUE(AppendCluster( 2548 ASSERT_TRUE(AppendCluster(
2570 audio_id, 2549 audio_id,
2571 GenerateSingleStreamCluster(0, 92, kAudioTrackNum, kAudioBlockDuration))); 2550 GenerateSingleStreamCluster(0, 92, kAudioTrackNum, kAudioBlockDuration)));
2572 ASSERT_TRUE(AppendCluster(video_id, 2551 ASSERT_TRUE(AppendCluster(video_id,
2573 GenerateSingleStreamCluster(0, 132, kVideoTrackNum, 2552 GenerateSingleStreamCluster(0, 132, kVideoTrackNum,
2574 kVideoBlockDuration))); 2553 kVideoBlockDuration)));
2575 2554
2576 // Read() from audio should return normal buffers. 2555 // Read() from audio should return normal buffers.
2577 GenerateAudioStreamExpectedReads(0, 4); 2556 GenerateAudioStreamExpectedReads(0, 4);
2578 2557
2558 // Audio stream will become inaccessible after |audio_id| is removed, so save
2559 // it here to read from it after RemoveId.
2560 DemuxerStream* audio_stream = demuxer_->GetStream(DemuxerStream::AUDIO);
2561
2579 // Remove the audio id. 2562 // Remove the audio id.
2580 demuxer_->RemoveId(audio_id); 2563 demuxer_->RemoveId(audio_id);
2581 2564
2582 // Read() from audio should return "end of stream" buffers. 2565 // Read() from audio should return "end of stream" buffers.
2583 bool audio_read_done = false; 2566 bool audio_read_done = false;
2584 ReadAudio(base::Bind(&OnReadDone_EOSExpected, &audio_read_done)); 2567 audio_stream->Read(base::Bind(&OnReadDone_EOSExpected, &audio_read_done));
2585 base::RunLoop().RunUntilIdle(); 2568 base::RunLoop().RunUntilIdle();
2586 EXPECT_TRUE(audio_read_done); 2569 EXPECT_TRUE(audio_read_done);
2587 2570
2588 // Read() from video should still return normal buffers. 2571 // Read() from video should still return normal buffers.
2589 GenerateVideoStreamExpectedReads(0, 4); 2572 GenerateVideoStreamExpectedReads(0, 4);
2590 } 2573 }
2591 2574
2592 // Test that removing an ID immediately after adding it does not interfere with 2575 // Test that removing an ID immediately after adding it does not interfere with
2593 // quota for new IDs in the future. 2576 // quota for new IDs in the future.
2594 TEST_F(ChunkDemuxerTest, RemoveAndAddId) { 2577 TEST_F(ChunkDemuxerTest, RemoveAndAddId) {
(...skipping 545 matching lines...) Expand 10 before | Expand all | Expand 10 after
3140 3123
3141 #if defined(USE_PROPRIETARY_CODECS) 3124 #if defined(USE_PROPRIETARY_CODECS)
3142 #if defined(OS_ANDROID) 3125 #if defined(OS_ANDROID)
3143 if (HasPlatformDecoderSupport()) 3126 if (HasPlatformDecoderSupport())
3144 expected = ChunkDemuxer::kOk; 3127 expected = ChunkDemuxer::kOk;
3145 #else 3128 #else
3146 expected = ChunkDemuxer::kOk; 3129 expected = ChunkDemuxer::kOk;
3147 #endif 3130 #endif
3148 #endif 3131 #endif
3149 3132
3150 std::vector<std::string> codecs; 3133 EXPECT_EQ(demuxer_->AddId("source_id", "video/mp4", "avc1.4D4041"), expected);
3151 codecs.push_back("avc1.4D4041");
3152
3153 EXPECT_EQ(demuxer_->AddId("source_id", "video/mp4", codecs), expected);
3154 } 3134 }
3155 3135
3156 // Test codec ID's that are not compliant with RFC6381, but have been 3136 // Test codec ID's that are not compliant with RFC6381, but have been
3157 // seen in the wild. 3137 // seen in the wild.
3158 TEST_F(ChunkDemuxerTest, CodecIDsThatAreNotRFC6381Compliant) { 3138 TEST_F(ChunkDemuxerTest, CodecIDsThatAreNotRFC6381Compliant) {
3159 ChunkDemuxer::Status expected = ChunkDemuxer::kNotSupported; 3139 ChunkDemuxer::Status expected = ChunkDemuxer::kNotSupported;
3160 3140
3161 #if defined(USE_PROPRIETARY_CODECS) 3141 #if defined(USE_PROPRIETARY_CODECS)
3162 expected = ChunkDemuxer::kOk; 3142 expected = ChunkDemuxer::kOk;
3163 #endif 3143 #endif
3164 const char* codec_ids[] = { 3144 const char* codec_ids[] = {
3165 // GPAC places leading zeros on the audio object type. 3145 // GPAC places leading zeros on the audio object type.
3166 "mp4a.40.02", 3146 "mp4a.40.02",
3167 "mp4a.40.05" 3147 "mp4a.40.05"
3168 }; 3148 };
3169 3149
3170 for (size_t i = 0; i < arraysize(codec_ids); ++i) { 3150 for (size_t i = 0; i < arraysize(codec_ids); ++i) {
3171 std::vector<std::string> codecs;
3172 codecs.push_back(codec_ids[i]);
3173
3174 ChunkDemuxer::Status result = 3151 ChunkDemuxer::Status result =
3175 demuxer_->AddId("source_id", "audio/mp4", codecs); 3152 demuxer_->AddId("source_id", "audio/mp4", codec_ids[i]);
3176 3153
3177 EXPECT_EQ(result, expected) 3154 EXPECT_EQ(result, expected)
3178 << "Fail to add codec_id '" << codec_ids[i] << "'"; 3155 << "Fail to add codec_id '" << codec_ids[i] << "'";
3179 3156
3180 if (result == ChunkDemuxer::kOk) 3157 if (result == ChunkDemuxer::kOk)
3181 demuxer_->RemoveId("source_id"); 3158 demuxer_->RemoveId("source_id");
3182 } 3159 }
3183 } 3160 }
3184 3161
3185 TEST_F(ChunkDemuxerTest, EndOfStreamStillSetAfterSeek) { 3162 TEST_F(ChunkDemuxerTest, EndOfStreamStillSetAfterSeek) {
(...skipping 281 matching lines...) Expand 10 before | Expand all | Expand 10 after
3467 append_window_end_for_next_append_, 3444 append_window_end_for_next_append_,
3468 &timestamp_offset_map_[kSourceId]); 3445 &timestamp_offset_map_[kSourceId]);
3469 3446
3470 // After ResetParserState(), parsing should no longer be in the middle of a 3447 // After ResetParserState(), parsing should no longer be in the middle of a
3471 // media segment. 3448 // media segment.
3472 ASSERT_FALSE(demuxer_->IsParsingMediaSegment(kSourceId)); 3449 ASSERT_FALSE(demuxer_->IsParsingMediaSegment(kSourceId));
3473 } 3450 }
3474 3451
3475 #if defined(USE_PROPRIETARY_CODECS) 3452 #if defined(USE_PROPRIETARY_CODECS)
3476 #if BUILDFLAG(ENABLE_MSE_MPEG2TS_STREAM_PARSER) 3453 #if BUILDFLAG(ENABLE_MSE_MPEG2TS_STREAM_PARSER)
3454 namespace {
3455 const char* kMp2tMimeType = "video/mp2t";
3456 const char* kMp2tCodecs = "mp4a.40.2,avc1.640028";
3457 }
3458
3477 TEST_F(ChunkDemuxerTest, EmitBuffersDuringAbort) { 3459 TEST_F(ChunkDemuxerTest, EmitBuffersDuringAbort) {
3478 EXPECT_CALL(*this, DemuxerOpened()); 3460 EXPECT_CALL(*this, DemuxerOpened());
3479 EXPECT_MEDIA_LOG(FoundStream("audio")); 3461 EXPECT_MEDIA_LOG(FoundStream("audio"));
3480 EXPECT_MEDIA_LOG(CodecName("audio", "aac")); 3462 EXPECT_MEDIA_LOG(CodecName("audio", "aac"));
3481 EXPECT_MEDIA_LOG(FoundStream("video")); 3463 EXPECT_MEDIA_LOG(FoundStream("video"));
3482 EXPECT_MEDIA_LOG(CodecName("video", "h264")); 3464 EXPECT_MEDIA_LOG(CodecName("video", "h264"));
3483 demuxer_->Initialize(&host_, CreateInitDoneCB(kInfiniteDuration, PIPELINE_OK), 3465 demuxer_->Initialize(&host_, CreateInitDoneCB(kInfiniteDuration, PIPELINE_OK),
3484 true); 3466 true);
3485 EXPECT_EQ(ChunkDemuxer::kOk, AddIdForMp2tSource(kSourceId)); 3467 EXPECT_EQ(ChunkDemuxer::kOk, AddId(kSourceId, kMp2tMimeType, kMp2tCodecs));
3486 3468
3487 // For info: 3469 // For info:
3488 // DTS/PTS derived using dvbsnoop -s ts -if bear-1280x720.ts -tssubdecode 3470 // DTS/PTS derived using dvbsnoop -s ts -if bear-1280x720.ts -tssubdecode
3489 // Video: first PES: 3471 // Video: first PES:
3490 // PTS: 126912 (0x0001efc0) [= 90 kHz-Timestamp: 0:00:01.4101] 3472 // PTS: 126912 (0x0001efc0) [= 90 kHz-Timestamp: 0:00:01.4101]
3491 // DTS: 123909 (0x0001e405) [= 90 kHz-Timestamp: 0:00:01.3767] 3473 // DTS: 123909 (0x0001e405) [= 90 kHz-Timestamp: 0:00:01.3767]
3492 // Audio: first PES: 3474 // Audio: first PES:
3493 // PTS: 126000 (0x0001ec30) [= 90 kHz-Timestamp: 0:00:01.4000] 3475 // PTS: 126000 (0x0001ec30) [= 90 kHz-Timestamp: 0:00:01.4000]
3494 // DTS: 123910 (0x0001e406) [= 90 kHz-Timestamp: 0:00:01.3767] 3476 // DTS: 123910 (0x0001e406) [= 90 kHz-Timestamp: 0:00:01.3767]
3495 // Video: last PES: 3477 // Video: last PES:
(...skipping 27 matching lines...) Expand all
3523 } 3505 }
3524 3506
3525 TEST_F(ChunkDemuxerTest, SeekCompleteDuringAbort) { 3507 TEST_F(ChunkDemuxerTest, SeekCompleteDuringAbort) {
3526 EXPECT_CALL(*this, DemuxerOpened()); 3508 EXPECT_CALL(*this, DemuxerOpened());
3527 EXPECT_MEDIA_LOG(FoundStream("audio")); 3509 EXPECT_MEDIA_LOG(FoundStream("audio"));
3528 EXPECT_MEDIA_LOG(CodecName("audio", "aac")); 3510 EXPECT_MEDIA_LOG(CodecName("audio", "aac"));
3529 EXPECT_MEDIA_LOG(FoundStream("video")); 3511 EXPECT_MEDIA_LOG(FoundStream("video"));
3530 EXPECT_MEDIA_LOG(CodecName("video", "h264")); 3512 EXPECT_MEDIA_LOG(CodecName("video", "h264"));
3531 demuxer_->Initialize(&host_, CreateInitDoneCB(kInfiniteDuration, PIPELINE_OK), 3513 demuxer_->Initialize(&host_, CreateInitDoneCB(kInfiniteDuration, PIPELINE_OK),
3532 true); 3514 true);
3533 EXPECT_EQ(ChunkDemuxer::kOk, AddIdForMp2tSource(kSourceId)); 3515 EXPECT_EQ(ChunkDemuxer::kOk, AddId(kSourceId, kMp2tMimeType, kMp2tCodecs));
3534 3516
3535 // For info: 3517 // For info:
3536 // DTS/PTS derived using dvbsnoop -s ts -if bear-1280x720.ts -tssubdecode 3518 // DTS/PTS derived using dvbsnoop -s ts -if bear-1280x720.ts -tssubdecode
3537 // Video: first PES: 3519 // Video: first PES:
3538 // PTS: 126912 (0x0001efc0) [= 90 kHz-Timestamp: 0:00:01.4101] 3520 // PTS: 126912 (0x0001efc0) [= 90 kHz-Timestamp: 0:00:01.4101]
3539 // DTS: 123909 (0x0001e405) [= 90 kHz-Timestamp: 0:00:01.3767] 3521 // DTS: 123909 (0x0001e405) [= 90 kHz-Timestamp: 0:00:01.3767]
3540 // Audio: first PES: 3522 // Audio: first PES:
3541 // PTS: 126000 (0x0001ec30) [= 90 kHz-Timestamp: 0:00:01.4000] 3523 // PTS: 126000 (0x0001ec30) [= 90 kHz-Timestamp: 0:00:01.4000]
3542 // DTS: 123910 (0x0001e406) [= 90 kHz-Timestamp: 0:00:01.3767] 3524 // DTS: 123910 (0x0001e406) [= 90 kHz-Timestamp: 0:00:01.3767]
3543 // Video: last PES: 3525 // Video: last PES:
(...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after
3810 Seek(seek_time); 3792 Seek(seek_time);
3811 3793
3812 // Append data to satisfy the seek. 3794 // Append data to satisfy the seek.
3813 ASSERT_TRUE(AppendCluster(seek_time.InMilliseconds(), 10)); 3795 ASSERT_TRUE(AppendCluster(seek_time.InMilliseconds(), 10));
3814 } 3796 }
3815 3797
3816 TEST_F(ChunkDemuxerTest, SetMemoryLimitType) { 3798 TEST_F(ChunkDemuxerTest, SetMemoryLimitType) {
3817 ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO)); 3799 ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
3818 3800
3819 // Set different memory limits for audio and video. 3801 // Set different memory limits for audio and video.
3820 demuxer_->SetMemoryLimits(DemuxerStream::AUDIO, 10 * kBlockSize); 3802 demuxer_->SetMemoryLimitsForTest(DemuxerStream::AUDIO, 10 * kBlockSize);
3821 demuxer_->SetMemoryLimits(DemuxerStream::VIDEO, 5 * kBlockSize + 1); 3803 demuxer_->SetMemoryLimitsForTest(DemuxerStream::VIDEO, 5 * kBlockSize + 1);
3822 3804
3823 base::TimeDelta seek_time = base::TimeDelta::FromMilliseconds(1000); 3805 base::TimeDelta seek_time = base::TimeDelta::FromMilliseconds(1000);
3824 3806
3825 // Append data at the start that can be garbage collected: 3807 // Append data at the start that can be garbage collected:
3826 AppendMuxedCluster( 3808 AppendMuxedCluster(
3827 MuxedStreamInfo(kAudioTrackNum, 3809 MuxedStreamInfo(kAudioTrackNum,
3828 "0K 23K 46K 69K 92K 115K 138K 161K 184K 207K", 23), 3810 "0K 23K 46K 69K 92K 115K 138K 161K 184K 207K", 23),
3829 MuxedStreamInfo(kVideoTrackNum, "0K 33K 66K 99K 132K", 33)); 3811 MuxedStreamInfo(kVideoTrackNum, "0K 33K 66K 99K 132K", 33));
3830 3812
3831 // We should be right at buffer limit, should pass 3813 // We should be right at buffer limit, should pass
(...skipping 16 matching lines...) Expand all
3848 // We should delete first append, and be exactly at buffer limit 3830 // We should delete first append, and be exactly at buffer limit
3849 EXPECT_TRUE(demuxer_->EvictCodedFrames(kSourceId, seek_time, 0)); 3831 EXPECT_TRUE(demuxer_->EvictCodedFrames(kSourceId, seek_time, 0));
3850 3832
3851 // Verify that the old data, and nothing more, has been garbage collected. 3833 // Verify that the old data, and nothing more, has been garbage collected.
3852 CheckExpectedRanges(DemuxerStream::AUDIO, "{ [1000,1230) }"); 3834 CheckExpectedRanges(DemuxerStream::AUDIO, "{ [1000,1230) }");
3853 CheckExpectedRanges(DemuxerStream::VIDEO, "{ [1000,1165) }"); 3835 CheckExpectedRanges(DemuxerStream::VIDEO, "{ [1000,1165) }");
3854 } 3836 }
3855 3837
3856 TEST_F(ChunkDemuxerTest, GCDuringSeek_SingleRange_SeekForward) { 3838 TEST_F(ChunkDemuxerTest, GCDuringSeek_SingleRange_SeekForward) {
3857 ASSERT_TRUE(InitDemuxer(HAS_AUDIO)); 3839 ASSERT_TRUE(InitDemuxer(HAS_AUDIO));
3858 demuxer_->SetMemoryLimits(DemuxerStream::AUDIO, 10 * kBlockSize); 3840 demuxer_->SetMemoryLimitsForTest(DemuxerStream::AUDIO, 10 * kBlockSize);
3859 // Append some data at position 1000ms 3841 // Append some data at position 1000ms
3860 AppendSingleStreamCluster(kSourceId, kAudioTrackNum, 1000, 10); 3842 AppendSingleStreamCluster(kSourceId, kAudioTrackNum, 1000, 10);
3861 CheckExpectedRanges("{ [1000,1230) }"); 3843 CheckExpectedRanges("{ [1000,1230) }");
3862 3844
3863 // GC should be able to evict frames in the currently buffered range, since 3845 // GC should be able to evict frames in the currently buffered range, since
3864 // those frames are earlier than the seek target position. 3846 // those frames are earlier than the seek target position.
3865 base::TimeDelta seek_time = base::TimeDelta::FromMilliseconds(2000); 3847 base::TimeDelta seek_time = base::TimeDelta::FromMilliseconds(2000);
3866 Seek(seek_time); 3848 Seek(seek_time);
3867 EXPECT_TRUE(demuxer_->EvictCodedFrames(kSourceId, seek_time, 5 * kBlockSize)); 3849 EXPECT_TRUE(demuxer_->EvictCodedFrames(kSourceId, seek_time, 5 * kBlockSize));
3868 3850
3869 // Append data to complete seek operation 3851 // Append data to complete seek operation
3870 AppendSingleStreamCluster(kSourceId, kAudioTrackNum, 2000, 5); 3852 AppendSingleStreamCluster(kSourceId, kAudioTrackNum, 2000, 5);
3871 CheckExpectedRanges("{ [1115,1230) [2000,2115) }"); 3853 CheckExpectedRanges("{ [1115,1230) [2000,2115) }");
3872 } 3854 }
3873 3855
3874 TEST_F(ChunkDemuxerTest, GCDuringSeek_SingleRange_SeekBack) { 3856 TEST_F(ChunkDemuxerTest, GCDuringSeek_SingleRange_SeekBack) {
3875 ASSERT_TRUE(InitDemuxer(HAS_AUDIO)); 3857 ASSERT_TRUE(InitDemuxer(HAS_AUDIO));
3876 demuxer_->SetMemoryLimits(DemuxerStream::AUDIO, 10 * kBlockSize); 3858 demuxer_->SetMemoryLimitsForTest(DemuxerStream::AUDIO, 10 * kBlockSize);
3877 // Append some data at position 1000ms 3859 // Append some data at position 1000ms
3878 AppendSingleStreamCluster(kSourceId, kAudioTrackNum, 1000, 10); 3860 AppendSingleStreamCluster(kSourceId, kAudioTrackNum, 1000, 10);
3879 CheckExpectedRanges("{ [1000,1230) }"); 3861 CheckExpectedRanges("{ [1000,1230) }");
3880 3862
3881 // GC should be able to evict frames in the currently buffered range, since 3863 // GC should be able to evict frames in the currently buffered range, since
3882 // seek target position has no data and so we should allow some frames to be 3864 // seek target position has no data and so we should allow some frames to be
3883 // evicted to make space for the upcoming append at seek target position. 3865 // evicted to make space for the upcoming append at seek target position.
3884 base::TimeDelta seek_time = base::TimeDelta(); 3866 base::TimeDelta seek_time = base::TimeDelta();
3885 Seek(seek_time); 3867 Seek(seek_time);
3886 EXPECT_TRUE(demuxer_->EvictCodedFrames(kSourceId, seek_time, 5 * kBlockSize)); 3868 EXPECT_TRUE(demuxer_->EvictCodedFrames(kSourceId, seek_time, 5 * kBlockSize));
3887 3869
3888 // Append data to complete seek operation 3870 // Append data to complete seek operation
3889 AppendSingleStreamCluster(kSourceId, kAudioTrackNum, 0, 5); 3871 AppendSingleStreamCluster(kSourceId, kAudioTrackNum, 0, 5);
3890 CheckExpectedRanges("{ [0,115) [1115,1230) }"); 3872 CheckExpectedRanges("{ [0,115) [1115,1230) }");
3891 } 3873 }
3892 3874
3893 TEST_F(ChunkDemuxerTest, GCDuringSeek_MultipleRanges_SeekForward) { 3875 TEST_F(ChunkDemuxerTest, GCDuringSeek_MultipleRanges_SeekForward) {
3894 ASSERT_TRUE(InitDemuxer(HAS_AUDIO)); 3876 ASSERT_TRUE(InitDemuxer(HAS_AUDIO));
3895 demuxer_->SetMemoryLimits(DemuxerStream::AUDIO, 10 * kBlockSize); 3877 demuxer_->SetMemoryLimitsForTest(DemuxerStream::AUDIO, 10 * kBlockSize);
3896 // Append some data at position 1000ms then at 2000ms 3878 // Append some data at position 1000ms then at 2000ms
3897 AppendSingleStreamCluster(kSourceId, kAudioTrackNum, 1000, 5); 3879 AppendSingleStreamCluster(kSourceId, kAudioTrackNum, 1000, 5);
3898 AppendSingleStreamCluster(kSourceId, kAudioTrackNum, 2000, 5); 3880 AppendSingleStreamCluster(kSourceId, kAudioTrackNum, 2000, 5);
3899 CheckExpectedRanges("{ [1000,1115) [2000,2115) }"); 3881 CheckExpectedRanges("{ [1000,1115) [2000,2115) }");
3900 3882
3901 // GC should be able to evict frames in the currently buffered ranges, since 3883 // GC should be able to evict frames in the currently buffered ranges, since
3902 // those frames are earlier than the seek target position. 3884 // those frames are earlier than the seek target position.
3903 base::TimeDelta seek_time = base::TimeDelta::FromMilliseconds(3000); 3885 base::TimeDelta seek_time = base::TimeDelta::FromMilliseconds(3000);
3904 Seek(seek_time); 3886 Seek(seek_time);
3905 EXPECT_TRUE(demuxer_->EvictCodedFrames(kSourceId, seek_time, 8 * kBlockSize)); 3887 EXPECT_TRUE(demuxer_->EvictCodedFrames(kSourceId, seek_time, 8 * kBlockSize));
3906 3888
3907 // Append data to complete seek operation 3889 // Append data to complete seek operation
3908 AppendSingleStreamCluster(kSourceId, kAudioTrackNum, 3000, 5); 3890 AppendSingleStreamCluster(kSourceId, kAudioTrackNum, 3000, 5);
3909 CheckExpectedRanges("{ [2069,2115) [3000,3115) }"); 3891 CheckExpectedRanges("{ [2069,2115) [3000,3115) }");
3910 } 3892 }
3911 3893
3912 TEST_F(ChunkDemuxerTest, GCDuringSeek_MultipleRanges_SeekInbetween1) { 3894 TEST_F(ChunkDemuxerTest, GCDuringSeek_MultipleRanges_SeekInbetween1) {
3913 ASSERT_TRUE(InitDemuxer(HAS_AUDIO)); 3895 ASSERT_TRUE(InitDemuxer(HAS_AUDIO));
3914 demuxer_->SetMemoryLimits(DemuxerStream::AUDIO, 10 * kBlockSize); 3896 demuxer_->SetMemoryLimitsForTest(DemuxerStream::AUDIO, 10 * kBlockSize);
3915 // Append some data at position 1000ms then at 2000ms 3897 // Append some data at position 1000ms then at 2000ms
3916 AppendSingleStreamCluster(kSourceId, kAudioTrackNum, 1000, 5); 3898 AppendSingleStreamCluster(kSourceId, kAudioTrackNum, 1000, 5);
3917 AppendSingleStreamCluster(kSourceId, kAudioTrackNum, 2000, 5); 3899 AppendSingleStreamCluster(kSourceId, kAudioTrackNum, 2000, 5);
3918 CheckExpectedRanges("{ [1000,1115) [2000,2115) }"); 3900 CheckExpectedRanges("{ [1000,1115) [2000,2115) }");
3919 3901
3920 // GC should be able to evict all frames from the first buffered range, since 3902 // GC should be able to evict all frames from the first buffered range, since
3921 // those frames are earlier than the seek target position. But there's only 5 3903 // those frames are earlier than the seek target position. But there's only 5
3922 // blocks worth of data in the first range and seek target position has no 3904 // blocks worth of data in the first range and seek target position has no
3923 // data, so GC proceeds with trying to delete some frames from the back of 3905 // data, so GC proceeds with trying to delete some frames from the back of
3924 // buffered ranges, that doesn't yield anything, since that's the most 3906 // buffered ranges, that doesn't yield anything, since that's the most
3925 // recently appended data, so then GC starts removing data from the front of 3907 // recently appended data, so then GC starts removing data from the front of
3926 // the remaining buffered range (2000ms) to ensure we free up enough space for 3908 // the remaining buffered range (2000ms) to ensure we free up enough space for
3927 // the upcoming append and allow seek to proceed. 3909 // the upcoming append and allow seek to proceed.
3928 base::TimeDelta seek_time = base::TimeDelta::FromMilliseconds(1500); 3910 base::TimeDelta seek_time = base::TimeDelta::FromMilliseconds(1500);
3929 Seek(seek_time); 3911 Seek(seek_time);
3930 EXPECT_TRUE(demuxer_->EvictCodedFrames(kSourceId, seek_time, 8 * kBlockSize)); 3912 EXPECT_TRUE(demuxer_->EvictCodedFrames(kSourceId, seek_time, 8 * kBlockSize));
3931 3913
3932 // Append data to complete seek operation 3914 // Append data to complete seek operation
3933 AppendSingleStreamCluster(kSourceId, kAudioTrackNum, 1500, 5); 3915 AppendSingleStreamCluster(kSourceId, kAudioTrackNum, 1500, 5);
3934 CheckExpectedRanges("{ [1500,1615) [2069,2115) }"); 3916 CheckExpectedRanges("{ [1500,1615) [2069,2115) }");
3935 } 3917 }
3936 3918
3937 TEST_F(ChunkDemuxerTest, GCDuringSeek_MultipleRanges_SeekInbetween2) { 3919 TEST_F(ChunkDemuxerTest, GCDuringSeek_MultipleRanges_SeekInbetween2) {
3938 ASSERT_TRUE(InitDemuxer(HAS_AUDIO)); 3920 ASSERT_TRUE(InitDemuxer(HAS_AUDIO));
3939 demuxer_->SetMemoryLimits(DemuxerStream::AUDIO, 10 * kBlockSize); 3921 demuxer_->SetMemoryLimitsForTest(DemuxerStream::AUDIO, 10 * kBlockSize);
3940 3922
3941 // Append some data at position 2000ms first, then at 1000ms, so that the last 3923 // Append some data at position 2000ms first, then at 1000ms, so that the last
3942 // appended data position is in the first buffered range (that matters to the 3924 // appended data position is in the first buffered range (that matters to the
3943 // GC algorithm since it tries to preserve more recently appended data). 3925 // GC algorithm since it tries to preserve more recently appended data).
3944 AppendSingleStreamCluster(kSourceId, kAudioTrackNum, 2000, 5); 3926 AppendSingleStreamCluster(kSourceId, kAudioTrackNum, 2000, 5);
3945 AppendSingleStreamCluster(kSourceId, kAudioTrackNum, 1000, 5); 3927 AppendSingleStreamCluster(kSourceId, kAudioTrackNum, 1000, 5);
3946 CheckExpectedRanges("{ [1000,1115) [2000,2115) }"); 3928 CheckExpectedRanges("{ [1000,1115) [2000,2115) }");
3947 3929
3948 // Now try performing garbage collection without announcing seek first, i.e. 3930 // Now try performing garbage collection without announcing seek first, i.e.
3949 // without calling Seek(), the GC algorithm should try to preserve data in the 3931 // without calling Seek(), the GC algorithm should try to preserve data in the
3950 // first range, since that is most recently appended data. 3932 // first range, since that is most recently appended data.
3951 base::TimeDelta seek_time = base::TimeDelta::FromMilliseconds(2030); 3933 base::TimeDelta seek_time = base::TimeDelta::FromMilliseconds(2030);
3952 EXPECT_TRUE(demuxer_->EvictCodedFrames(kSourceId, seek_time, 5 * kBlockSize)); 3934 EXPECT_TRUE(demuxer_->EvictCodedFrames(kSourceId, seek_time, 5 * kBlockSize));
3953 3935
3954 AppendSingleStreamCluster(kSourceId, kAudioTrackNum, 1500, 5); 3936 AppendSingleStreamCluster(kSourceId, kAudioTrackNum, 1500, 5);
3955 CheckExpectedRanges("{ [1000,1115) [1500,1615) }"); 3937 CheckExpectedRanges("{ [1000,1115) [1500,1615) }");
3956 } 3938 }
3957 3939
3958 TEST_F(ChunkDemuxerTest, GCDuringSeek_MultipleRanges_SeekBack) { 3940 TEST_F(ChunkDemuxerTest, GCDuringSeek_MultipleRanges_SeekBack) {
3959 ASSERT_TRUE(InitDemuxer(HAS_AUDIO)); 3941 ASSERT_TRUE(InitDemuxer(HAS_AUDIO));
3960 demuxer_->SetMemoryLimits(DemuxerStream::AUDIO, 10 * kBlockSize); 3942 demuxer_->SetMemoryLimitsForTest(DemuxerStream::AUDIO, 10 * kBlockSize);
3961 // Append some data at position 1000ms then at 2000ms 3943 // Append some data at position 1000ms then at 2000ms
3962 AppendSingleStreamCluster(kSourceId, kAudioTrackNum, 1000, 5); 3944 AppendSingleStreamCluster(kSourceId, kAudioTrackNum, 1000, 5);
3963 AppendSingleStreamCluster(kSourceId, kAudioTrackNum, 2000, 5); 3945 AppendSingleStreamCluster(kSourceId, kAudioTrackNum, 2000, 5);
3964 CheckExpectedRanges("{ [1000,1115) [2000,2115) }"); 3946 CheckExpectedRanges("{ [1000,1115) [2000,2115) }");
3965 3947
3966 // GC should be able to evict frames in the currently buffered ranges, since 3948 // GC should be able to evict frames in the currently buffered ranges, since
3967 // those frames are earlier than the seek target position. 3949 // those frames are earlier than the seek target position.
3968 base::TimeDelta seek_time = base::TimeDelta(); 3950 base::TimeDelta seek_time = base::TimeDelta();
3969 Seek(seek_time); 3951 Seek(seek_time);
3970 EXPECT_TRUE(demuxer_->EvictCodedFrames(kSourceId, seek_time, 8 * kBlockSize)); 3952 EXPECT_TRUE(demuxer_->EvictCodedFrames(kSourceId, seek_time, 8 * kBlockSize));
3971 3953
3972 // Append data to complete seek operation 3954 // Append data to complete seek operation
3973 AppendSingleStreamCluster(kSourceId, kAudioTrackNum, 0, 5); 3955 AppendSingleStreamCluster(kSourceId, kAudioTrackNum, 0, 5);
3974 CheckExpectedRanges("{ [0,115) [2069,2115) }"); 3956 CheckExpectedRanges("{ [0,115) [2069,2115) }");
3975 } 3957 }
3976 3958
3977 TEST_F(ChunkDemuxerTest, GCDuringSeek) { 3959 TEST_F(ChunkDemuxerTest, GCDuringSeek) {
3978 ASSERT_TRUE(InitDemuxer(HAS_AUDIO)); 3960 ASSERT_TRUE(InitDemuxer(HAS_AUDIO));
3979 3961
3980 demuxer_->SetMemoryLimits(DemuxerStream::AUDIO, 5 * kBlockSize); 3962 demuxer_->SetMemoryLimitsForTest(DemuxerStream::AUDIO, 5 * kBlockSize);
3981 3963
3982 base::TimeDelta seek_time1 = base::TimeDelta::FromMilliseconds(1000); 3964 base::TimeDelta seek_time1 = base::TimeDelta::FromMilliseconds(1000);
3983 base::TimeDelta seek_time2 = base::TimeDelta::FromMilliseconds(500); 3965 base::TimeDelta seek_time2 = base::TimeDelta::FromMilliseconds(500);
3984 3966
3985 // Initiate a seek to |seek_time1|. 3967 // Initiate a seek to |seek_time1|.
3986 Seek(seek_time1); 3968 Seek(seek_time1);
3987 3969
3988 // Append data to satisfy the first seek request. 3970 // Append data to satisfy the first seek request.
3989 AppendSingleStreamCluster(kSourceId, kAudioTrackNum, 3971 AppendSingleStreamCluster(kSourceId, kAudioTrackNum,
3990 seek_time1.InMilliseconds(), 5); 3972 seek_time1.InMilliseconds(), 5);
(...skipping 24 matching lines...) Expand all
4015 // around |seek_time2|, because that's the current playback position, 3997 // around |seek_time2|, because that's the current playback position,
4016 // and the newly appended range, since this is the most recent append. 3998 // and the newly appended range, since this is the most recent append.
4017 AppendSingleStreamCluster(kSourceId, kAudioTrackNum, 700, 5); 3999 AppendSingleStreamCluster(kSourceId, kAudioTrackNum, 700, 5);
4018 EXPECT_FALSE(demuxer_->EvictCodedFrames(kSourceId, seek_time2, 0)); 4000 EXPECT_FALSE(demuxer_->EvictCodedFrames(kSourceId, seek_time2, 0));
4019 CheckExpectedRanges("{ [500,615) [700,815) }"); 4001 CheckExpectedRanges("{ [500,615) [700,815) }");
4020 } 4002 }
4021 4003
4022 TEST_F(ChunkDemuxerTest, GCKeepPlayhead) { 4004 TEST_F(ChunkDemuxerTest, GCKeepPlayhead) {
4023 ASSERT_TRUE(InitDemuxer(HAS_AUDIO)); 4005 ASSERT_TRUE(InitDemuxer(HAS_AUDIO));
4024 4006
4025 demuxer_->SetMemoryLimits(DemuxerStream::AUDIO, 5 * kBlockSize); 4007 demuxer_->SetMemoryLimitsForTest(DemuxerStream::AUDIO, 5 * kBlockSize);
4026 4008
4027 // Append data at the start that can be garbage collected: 4009 // Append data at the start that can be garbage collected:
4028 AppendSingleStreamCluster(kSourceId, kAudioTrackNum, 0, 10); 4010 AppendSingleStreamCluster(kSourceId, kAudioTrackNum, 0, 10);
4029 CheckExpectedRanges("{ [0,230) }"); 4011 CheckExpectedRanges("{ [0,230) }");
4030 4012
4031 // We expect garbage collection to fail, as we don't want to spontaneously 4013 // We expect garbage collection to fail, as we don't want to spontaneously
4032 // create gaps in source buffer stream. Gaps could break playback for many 4014 // create gaps in source buffer stream. Gaps could break playback for many
4033 // clients, who don't bother to check ranges after append. 4015 // clients, who don't bother to check ranges after append.
4034 EXPECT_FALSE(demuxer_->EvictCodedFrames( 4016 EXPECT_FALSE(demuxer_->EvictCodedFrames(
4035 kSourceId, base::TimeDelta::FromMilliseconds(0), 0)); 4017 kSourceId, base::TimeDelta::FromMilliseconds(0), 0));
(...skipping 378 matching lines...) Expand 10 before | Expand all | Expand 10 after
4414 ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO)); 4396 ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
4415 4397
4416 ASSERT_TRUE(AppendCluster(GenerateCluster(0, 0, 4))); 4398 ASSERT_TRUE(AppendCluster(GenerateCluster(0, 0, 4)));
4417 ASSERT_TRUE(AppendData(kCuesHeader, sizeof(kCuesHeader))); 4399 ASSERT_TRUE(AppendData(kCuesHeader, sizeof(kCuesHeader)));
4418 ASSERT_TRUE(AppendCluster(GenerateCluster(46, 66, 5))); 4400 ASSERT_TRUE(AppendCluster(GenerateCluster(46, 66, 5)));
4419 CheckExpectedRanges("{ [0,115) }"); 4401 CheckExpectedRanges("{ [0,115) }");
4420 } 4402 }
4421 4403
4422 TEST_F(ChunkDemuxerTest, EvictCodedFramesTest) { 4404 TEST_F(ChunkDemuxerTest, EvictCodedFramesTest) {
4423 ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO)); 4405 ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
4424 demuxer_->SetMemoryLimits(DemuxerStream::AUDIO, 10 * kBlockSize); 4406 demuxer_->SetMemoryLimitsForTest(DemuxerStream::AUDIO, 10 * kBlockSize);
4425 demuxer_->SetMemoryLimits(DemuxerStream::VIDEO, 15 * kBlockSize); 4407 demuxer_->SetMemoryLimitsForTest(DemuxerStream::VIDEO, 15 * kBlockSize);
4426 DemuxerStream* audio_stream = demuxer_->GetStream(DemuxerStream::AUDIO); 4408 DemuxerStream* audio_stream = demuxer_->GetStream(DemuxerStream::AUDIO);
4427 DemuxerStream* video_stream = demuxer_->GetStream(DemuxerStream::VIDEO); 4409 DemuxerStream* video_stream = demuxer_->GetStream(DemuxerStream::VIDEO);
4428 4410
4429 const char* kAudioStreamInfo = "0K 40K 80K 120K 160K 200K 240K 280K"; 4411 const char* kAudioStreamInfo = "0K 40K 80K 120K 160K 200K 240K 280K";
4430 const char* kVideoStreamInfo = "0K 10 20K 30 40K 50 60K 70 80K 90 100K " 4412 const char* kVideoStreamInfo = "0K 10 20K 30 40K 50 60K 70 80K 90 100K "
4431 "110 120K 130 140K"; 4413 "110 120K 130 140K";
4432 // Append 8 blocks (80 bytes) of data to audio stream and 15 blocks (150 4414 // Append 8 blocks (80 bytes) of data to audio stream and 15 blocks (150
4433 // bytes) to video stream. 4415 // bytes) to video stream.
4434 AppendMuxedCluster(MuxedStreamInfo(kAudioTrackNum, kAudioStreamInfo, 40), 4416 AppendMuxedCluster(MuxedStreamInfo(kAudioTrackNum, kAudioStreamInfo, 40),
4435 MuxedStreamInfo(kVideoTrackNum, kVideoStreamInfo, 10)); 4417 MuxedStreamInfo(kVideoTrackNum, kVideoStreamInfo, 10));
(...skipping 28 matching lines...) Expand all
4464 // byte block to stay under 100 bytes memory limit after append 4446 // byte block to stay under 100 bytes memory limit after append
4465 // 80 - 10 + 28 = 98). 4447 // 80 - 10 + 28 = 98).
4466 // For video stream 150 + 52 = 202. Video limit is 150 bytes. We need to 4448 // For video stream 150 + 52 = 202. Video limit is 150 bytes. We need to
4467 // remove at least 6 blocks to stay under limit. 4449 // remove at least 6 blocks to stay under limit.
4468 CheckExpectedBuffers(audio_stream, "40K 80K 120K 160K 200K 240K 280K"); 4450 CheckExpectedBuffers(audio_stream, "40K 80K 120K 160K 200K 240K 280K");
4469 CheckExpectedBuffers(video_stream, "60K 70 80K 90 100K 110 120K 130 140K"); 4451 CheckExpectedBuffers(video_stream, "60K 70 80K 90 100K 110 120K 130 140K");
4470 } 4452 }
4471 4453
4472 TEST_F(ChunkDemuxerTest, SegmentMissingAudioFrame_AudioOnly) { 4454 TEST_F(ChunkDemuxerTest, SegmentMissingAudioFrame_AudioOnly) {
4473 ASSERT_TRUE(InitDemuxer(HAS_AUDIO)); 4455 ASSERT_TRUE(InitDemuxer(HAS_AUDIO));
4474 EXPECT_MEDIA_LOG(SegmentMissingFrames("audio")); 4456 EXPECT_MEDIA_LOG(SegmentMissingFrames("2"));
4475 ASSERT_TRUE(AppendCluster(GenerateEmptyCluster(0))); 4457 ASSERT_TRUE(AppendCluster(GenerateEmptyCluster(0)));
4476 } 4458 }
4477 4459
4478 TEST_F(ChunkDemuxerTest, SegmentMissingVideoFrame_VideoOnly) { 4460 TEST_F(ChunkDemuxerTest, SegmentMissingVideoFrame_VideoOnly) {
4479 ASSERT_TRUE(InitDemuxer(HAS_VIDEO)); 4461 ASSERT_TRUE(InitDemuxer(HAS_VIDEO));
4480 EXPECT_MEDIA_LOG(SegmentMissingFrames("video")); 4462 EXPECT_MEDIA_LOG(SegmentMissingFrames("1"));
4481 ASSERT_TRUE(AppendCluster(GenerateEmptyCluster(0))); 4463 ASSERT_TRUE(AppendCluster(GenerateEmptyCluster(0)));
4482 } 4464 }
4483 4465
4484 TEST_F(ChunkDemuxerTest, SegmentMissingAudioFrame_AudioVideo) { 4466 TEST_F(ChunkDemuxerTest, SegmentMissingAudioFrame_AudioVideo) {
4485 ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO)); 4467 ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
4486 EXPECT_MEDIA_LOG(SegmentMissingFrames("audio")); 4468 EXPECT_MEDIA_LOG(SegmentMissingFrames("2"));
4487 AppendSingleStreamCluster(kSourceId, kVideoTrackNum, 0, 10); 4469 AppendSingleStreamCluster(kSourceId, kVideoTrackNum, 0, 10);
4488 } 4470 }
4489 4471
4490 TEST_F(ChunkDemuxerTest, SegmentMissingVideoFrame_AudioVideo) { 4472 TEST_F(ChunkDemuxerTest, SegmentMissingVideoFrame_AudioVideo) {
4491 ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO)); 4473 ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
4492 EXPECT_MEDIA_LOG(SegmentMissingFrames("video")); 4474 EXPECT_MEDIA_LOG(SegmentMissingFrames("1"));
4493 AppendSingleStreamCluster(kSourceId, kAudioTrackNum, 0, 10); 4475 AppendSingleStreamCluster(kSourceId, kAudioTrackNum, 0, 10);
4494 } 4476 }
4495 4477
4496 TEST_F(ChunkDemuxerTest, SegmentMissingAudioVideoFrames) { 4478 TEST_F(ChunkDemuxerTest, SegmentMissingAudioVideoFrames) {
4497 ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO)); 4479 ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
4498 EXPECT_MEDIA_LOG(SegmentMissingFrames("audio or video")); 4480 EXPECT_MEDIA_LOG(SegmentMissingFrames("1"));
4481 EXPECT_MEDIA_LOG(SegmentMissingFrames("2"));
4499 ASSERT_TRUE(AppendCluster(GenerateEmptyCluster(0))); 4482 ASSERT_TRUE(AppendCluster(GenerateEmptyCluster(0)));
4500 } 4483 }
4501 4484
4502 TEST_F(ChunkDemuxerTest, RelaxedKeyframe_FirstSegmentMissingKeyframe) { 4485 TEST_F(ChunkDemuxerTest, RelaxedKeyframe_FirstSegmentMissingKeyframe) {
4503 // Append V:[n n n][n n K] 4486 // Append V:[n n n][n n K]
4504 // Expect V: [K] 4487 // Expect V: [K]
4505 ASSERT_TRUE(InitDemuxer(HAS_VIDEO)); 4488 ASSERT_TRUE(InitDemuxer(HAS_VIDEO));
4506 DemuxerStream* video_stream = demuxer_->GetStream(DemuxerStream::VIDEO); 4489 DemuxerStream* video_stream = demuxer_->GetStream(DemuxerStream::VIDEO);
4507 4490
4508 EXPECT_MEDIA_LOG(WebMSimpleBlockDurationEstimated(10)).Times(2); 4491 EXPECT_MEDIA_LOG(WebMSimpleBlockDurationEstimated(10)).Times(2);
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
4622 // V: [n n n][n K n] 4605 // V: [n n n][n K n]
4623 // Expect: 4606 // Expect:
4624 // A: [K K K][K K K] 4607 // A: [K K K][K K K]
4625 // V [................K n] (As would occur if there really were a 4608 // V [................K n] (As would occur if there really were a
4626 // jagged cluster start and not badly muxed clusters as used to 4609 // jagged cluster start and not badly muxed clusters as used to
4627 // simulate a jagged start in this test.) 4610 // simulate a jagged start in this test.)
4628 ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO)); 4611 ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
4629 DemuxerStream* audio_stream = demuxer_->GetStream(DemuxerStream::AUDIO); 4612 DemuxerStream* audio_stream = demuxer_->GetStream(DemuxerStream::AUDIO);
4630 DemuxerStream* video_stream = demuxer_->GetStream(DemuxerStream::VIDEO); 4613 DemuxerStream* video_stream = demuxer_->GetStream(DemuxerStream::VIDEO);
4631 4614
4632 EXPECT_MEDIA_LOG(SegmentMissingFrames("video")); 4615 EXPECT_MEDIA_LOG(SegmentMissingFrames("1"));
4633 AppendMuxedCluster(MuxedStreamInfo(kAudioTrackNum, "0K 10K 20D10K"), 4616 AppendMuxedCluster(MuxedStreamInfo(kAudioTrackNum, "0K 10K 20D10K"),
4634 MuxedStreamInfo(kVideoTrackNum, "")); 4617 MuxedStreamInfo(kVideoTrackNum, ""));
4635 demuxer_->Remove(kSourceId, base::TimeDelta(), 4618 demuxer_->Remove(kSourceId, base::TimeDelta(),
4636 base::TimeDelta::FromMilliseconds(30)); 4619 base::TimeDelta::FromMilliseconds(30));
4637 AppendMuxedCluster(MuxedStreamInfo(kAudioTrackNum, "30K 40K 50D10K"), 4620 AppendMuxedCluster(MuxedStreamInfo(kAudioTrackNum, "30K 40K 50D10K"),
4638 MuxedStreamInfo(kVideoTrackNum, "30 40 50", 10)); 4621 MuxedStreamInfo(kVideoTrackNum, "30 40 50", 10));
4639 AppendMuxedCluster(MuxedStreamInfo(kAudioTrackNum, "60K 70K 80D10K"), 4622 AppendMuxedCluster(MuxedStreamInfo(kAudioTrackNum, "60K 70K 80D10K"),
4640 MuxedStreamInfo(kVideoTrackNum, "60 70K 80", 10)); 4623 MuxedStreamInfo(kVideoTrackNum, "60 70K 80", 10));
4641 CheckExpectedRanges(DemuxerStream::AUDIO, "{ [30,90) }"); 4624 CheckExpectedRanges(DemuxerStream::AUDIO, "{ [30,90) }");
4642 CheckExpectedRanges(DemuxerStream::VIDEO, "{ [0,90) }"); 4625 CheckExpectedRanges(DemuxerStream::VIDEO, "{ [0,90) }");
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
4737 TEST_F(ChunkDemuxerTest, StreamStatusNotifications) { 4720 TEST_F(ChunkDemuxerTest, StreamStatusNotifications) {
4738 ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO)); 4721 ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
4739 DemuxerStream* audio_stream = demuxer_->GetStream(DemuxerStream::AUDIO); 4722 DemuxerStream* audio_stream = demuxer_->GetStream(DemuxerStream::AUDIO);
4740 EXPECT_NE(nullptr, audio_stream); 4723 EXPECT_NE(nullptr, audio_stream);
4741 CheckStreamStatusNotifications(audio_stream); 4724 CheckStreamStatusNotifications(audio_stream);
4742 DemuxerStream* video_stream = demuxer_->GetStream(DemuxerStream::VIDEO); 4725 DemuxerStream* video_stream = demuxer_->GetStream(DemuxerStream::VIDEO);
4743 EXPECT_NE(nullptr, video_stream); 4726 EXPECT_NE(nullptr, video_stream);
4744 CheckStreamStatusNotifications(video_stream); 4727 CheckStreamStatusNotifications(video_stream);
4745 } 4728 }
4746 4729
4730 TEST_F(ChunkDemuxerTest, MultipleIds) {
4731 CreateNewDemuxer();
4732 EXPECT_CALL(*this, DemuxerOpened());
4733 EXPECT_CALL(host_, SetDuration(_)).Times(2);
4734 demuxer_->Initialize(&host_, CreateInitDoneCB(kNoTimestamp, PIPELINE_OK),
4735 true);
4736
4737 const char* kId1 = "id1";
4738 const char* kId2 = "id2";
4739 EXPECT_EQ(AddId(kId1, "video/webm", "opus,vp9"), ChunkDemuxer::kOk);
4740 EXPECT_EQ(AddId(kId2, "video/webm", "opus,vp9"), ChunkDemuxer::kOk);
4741 scoped_refptr<DecoderBuffer> data1 = ReadTestDataFile("green-a300hz.webm");
4742 scoped_refptr<DecoderBuffer> data2 = ReadTestDataFile("red-a500hz.webm");
4743
4744 EXPECT_MEDIA_LOG(FoundStream("audio")).Times(2);
4745 EXPECT_MEDIA_LOG(FoundStream("video")).Times(2);
4746 EXPECT_MEDIA_LOG(CodecName("audio", "opus")).Times(2);
4747 EXPECT_MEDIA_LOG(CodecName("video", "vp9")).Times(2);
4748 EXPECT_CALL(*this, InitSegmentReceivedMock(_)).Times(2);
4749 EXPECT_MEDIA_LOG(SegmentMissingFrames("1")).Times(1);
4750
4751 EXPECT_TRUE(AppendData(kId1, data1->data(), data1->data_size()));
4752 EXPECT_TRUE(AppendData(kId2, data2->data(), data2->data_size()));
4753 CheckExpectedRanges(kId1, "{ [0,12007) }");
4754 CheckExpectedRanges(kId2, "{ [0,10007) }");
4755 }
4756
4757 TEST_F(ChunkDemuxerTest, CompleteInitAfterIdRemoved) {
4758 CreateNewDemuxer();
4759 EXPECT_CALL(*this, DemuxerOpened());
4760 demuxer_->Initialize(&host_,
4761 CreateInitDoneCB(kDefaultDuration(), PIPELINE_OK), true);
4762
4763 // Add two ids, then remove one of the ids and verify that adding init segment
4764 // only for the remaining id still triggers the InitDoneCB.
4765 const char* kId1 = "id1";
4766 const char* kId2 = "id2";
4767 EXPECT_EQ(AddId(kId1, "video/webm", "vp8"), ChunkDemuxer::kOk);
4768 EXPECT_EQ(AddId(kId2, "video/webm", "vp9"), ChunkDemuxer::kOk);
4769 demuxer_->RemoveId(kId2);
4770
4771 EXPECT_CALL(*this, InitSegmentReceivedMock(_));
4772 EXPECT_MEDIA_LOG(WebMSimpleBlockDurationEstimated(30));
4773 EXPECT_MEDIA_LOG(FoundStream("video"));
4774 EXPECT_MEDIA_LOG(CodecName("video", "vp8"));
4775
4776 ASSERT_TRUE(AppendInitSegmentWithSourceId(kId1, HAS_VIDEO));
4777 AppendSingleStreamCluster(kId1, kVideoTrackNum, "0K 30 60 90");
4778 }
4779
4780 TEST_F(ChunkDemuxerTest, RemovingIdMustRemoveStreams) {
4781 CreateNewDemuxer();
4782 EXPECT_CALL(*this, DemuxerOpened());
4783 demuxer_->Initialize(&host_,
4784 CreateInitDoneCB(kDefaultDuration(), PIPELINE_OK), true);
4785
4786 const char* kId1 = "id1";
4787 EXPECT_EQ(AddId(kId1, "video/webm", "vorbis,vp8"), ChunkDemuxer::kOk);
4788
4789 EXPECT_CALL(*this, InitSegmentReceivedMock(_));
4790 EXPECT_MEDIA_LOG(FoundStream("video"));
4791 EXPECT_MEDIA_LOG(CodecName("video", "vp8"));
4792 EXPECT_MEDIA_LOG(FoundStream("audio"));
4793 EXPECT_MEDIA_LOG(CodecName("audio", "vorbis"));
4794
4795 // Append init segment to ensure demuxer streams get created.
4796 ASSERT_TRUE(AppendInitSegmentWithSourceId(kId1, HAS_AUDIO | HAS_VIDEO));
4797 EXPECT_NE(nullptr, demuxer_->GetStream(DemuxerStream::AUDIO));
4798 EXPECT_NE(nullptr, demuxer_->GetStream(DemuxerStream::VIDEO));
4799
4800 // Removing the id should remove also the DemuxerStreams.
4801 demuxer_->RemoveId(kId1);
4802 EXPECT_EQ(nullptr, demuxer_->GetStream(DemuxerStream::AUDIO));
4803 EXPECT_EQ(nullptr, demuxer_->GetStream(DemuxerStream::VIDEO));
4804 }
4805
4806 // TODO(servolk): Add a unit test with multiple audio/video tracks using the
4807 // same codec type in a single SourceBuffer/MediaSourceState, when WebM parser
4808 // supports multiple tracks. crbug.com/646900
4809
4747 } // namespace media 4810 } // namespace media
OLDNEW
« no previous file with comments | « media/filters/chunk_demuxer.cc ('k') | media/filters/frame_processor.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698