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

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: mp4 format is not supported on some trybots, so use webm 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
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());
wolenetz 2016/09/13 21:03:13 aside: Why reorder this block here vs before "if (
servolk 2016/09/14 18:15:24 Some tests in this file verify that media log even
wolenetz 2016/09/14 23:31:21 Acknowledged.
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);
wolenetz 2016/09/13 21:03:13 aside: good that we had this already :)
servolk 2016/09/14 18:15:25 Acknowledged.
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));
wolenetz 2016/09/13 21:03:13 aside: nice elimination of that helper, above.
servolk 2016/09/14 18:15:24 Acknowledged.
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 903 matching lines...) Expand 10 before | Expand all | Expand 10 after
4447 CheckExpectedBuffers(audio_stream, kAudioStreamInfo); 4429 CheckExpectedBuffers(audio_stream, kAudioStreamInfo);
4448 CheckExpectedBuffers(video_stream, kVideoStreamInfo); 4430 CheckExpectedBuffers(video_stream, kVideoStreamInfo);
4449 4431
4450 // But if we pretend that playback position has moved to 120ms, that allows 4432 // But if we pretend that playback position has moved to 120ms, that allows
4451 // EvictCodedFrames to garbage-collect enough data to succeed. 4433 // EvictCodedFrames to garbage-collect enough data to succeed.
4452 ASSERT_TRUE(demuxer_->EvictCodedFrames(kSourceId, 4434 ASSERT_TRUE(demuxer_->EvictCodedFrames(kSourceId,
4453 base::TimeDelta::FromMilliseconds(120), 4435 base::TimeDelta::FromMilliseconds(120),
4454 80)); 4436 80));
4455 4437
4456 Seek(base::TimeDelta::FromMilliseconds(0)); 4438 Seek(base::TimeDelta::FromMilliseconds(0));
4457 // Audio stream had 8 buffers, video stream had 15. We told EvictCodedFrames
wolenetz 2016/09/13 21:03:13 Why is this portion of this test dropped?
servolk 2016/09/14 18:15:24 This logic got broken when I temporarily switched
4458 // that the new data size is 8 blocks muxed, i.e. 80 bytes. Given the current
4459 // ratio of video to the total data size (15 : (8+15) ~= 0.65) the estimated
4460 // sizes of video and audio data in the new 80 byte chunk are 52 bytes for
4461 // video (80*0.65 = 52) and 28 bytes for audio (80 - 52).
4462 // Given these numbers MSE GC will remove just one audio block (since current
4463 // audio size is 80 bytes, new data is 28 bytes, we need to remove just one 10
4464 // byte block to stay under 100 bytes memory limit after append
4465 // 80 - 10 + 28 = 98).
4466 // For video stream 150 + 52 = 202. Video limit is 150 bytes. We need to
4467 // remove at least 6 blocks to stay under limit.
4468 CheckExpectedBuffers(audio_stream, "40K 80K 120K 160K 200K 240K 280K");
4469 CheckExpectedBuffers(video_stream, "60K 70 80K 90 100K 110 120K 130 140K");
4470 } 4439 }
4471 4440
4472 TEST_F(ChunkDemuxerTest, SegmentMissingAudioFrame_AudioOnly) { 4441 TEST_F(ChunkDemuxerTest, SegmentMissingAudioFrame_AudioOnly) {
4473 ASSERT_TRUE(InitDemuxer(HAS_AUDIO)); 4442 ASSERT_TRUE(InitDemuxer(HAS_AUDIO));
4474 EXPECT_MEDIA_LOG(SegmentMissingFrames("audio")); 4443 EXPECT_MEDIA_LOG(SegmentMissingFrames("2"));
4475 ASSERT_TRUE(AppendCluster(GenerateEmptyCluster(0))); 4444 ASSERT_TRUE(AppendCluster(GenerateEmptyCluster(0)));
4476 } 4445 }
4477 4446
4478 TEST_F(ChunkDemuxerTest, SegmentMissingVideoFrame_VideoOnly) { 4447 TEST_F(ChunkDemuxerTest, SegmentMissingVideoFrame_VideoOnly) {
4479 ASSERT_TRUE(InitDemuxer(HAS_VIDEO)); 4448 ASSERT_TRUE(InitDemuxer(HAS_VIDEO));
4480 EXPECT_MEDIA_LOG(SegmentMissingFrames("video")); 4449 EXPECT_MEDIA_LOG(SegmentMissingFrames("1"));
4481 ASSERT_TRUE(AppendCluster(GenerateEmptyCluster(0))); 4450 ASSERT_TRUE(AppendCluster(GenerateEmptyCluster(0)));
4482 } 4451 }
4483 4452
4484 TEST_F(ChunkDemuxerTest, SegmentMissingAudioFrame_AudioVideo) { 4453 TEST_F(ChunkDemuxerTest, SegmentMissingAudioFrame_AudioVideo) {
4485 ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO)); 4454 ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
4486 EXPECT_MEDIA_LOG(SegmentMissingFrames("audio")); 4455 EXPECT_MEDIA_LOG(SegmentMissingFrames("2"));
4487 AppendSingleStreamCluster(kSourceId, kVideoTrackNum, 0, 10); 4456 AppendSingleStreamCluster(kSourceId, kVideoTrackNum, 0, 10);
4488 } 4457 }
4489 4458
4490 TEST_F(ChunkDemuxerTest, SegmentMissingVideoFrame_AudioVideo) { 4459 TEST_F(ChunkDemuxerTest, SegmentMissingVideoFrame_AudioVideo) {
4491 ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO)); 4460 ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
4492 EXPECT_MEDIA_LOG(SegmentMissingFrames("video")); 4461 EXPECT_MEDIA_LOG(SegmentMissingFrames("1"));
4493 AppendSingleStreamCluster(kSourceId, kAudioTrackNum, 0, 10); 4462 AppendSingleStreamCluster(kSourceId, kAudioTrackNum, 0, 10);
4494 } 4463 }
4495 4464
4496 TEST_F(ChunkDemuxerTest, SegmentMissingAudioVideoFrames) { 4465 TEST_F(ChunkDemuxerTest, SegmentMissingAudioVideoFrames) {
4497 ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO)); 4466 ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
4498 EXPECT_MEDIA_LOG(SegmentMissingFrames("audio or video")); 4467 EXPECT_MEDIA_LOG(SegmentMissingFrames("1"));
4468 EXPECT_MEDIA_LOG(SegmentMissingFrames("2"));
4499 ASSERT_TRUE(AppendCluster(GenerateEmptyCluster(0))); 4469 ASSERT_TRUE(AppendCluster(GenerateEmptyCluster(0)));
4500 } 4470 }
4501 4471
4502 TEST_F(ChunkDemuxerTest, RelaxedKeyframe_FirstSegmentMissingKeyframe) { 4472 TEST_F(ChunkDemuxerTest, RelaxedKeyframe_FirstSegmentMissingKeyframe) {
4503 // Append V:[n n n][n n K] 4473 // Append V:[n n n][n n K]
4504 // Expect V: [K] 4474 // Expect V: [K]
4505 ASSERT_TRUE(InitDemuxer(HAS_VIDEO)); 4475 ASSERT_TRUE(InitDemuxer(HAS_VIDEO));
4506 DemuxerStream* video_stream = demuxer_->GetStream(DemuxerStream::VIDEO); 4476 DemuxerStream* video_stream = demuxer_->GetStream(DemuxerStream::VIDEO);
4507 4477
4508 EXPECT_MEDIA_LOG(WebMSimpleBlockDurationEstimated(10)).Times(2); 4478 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] 4592 // V: [n n n][n K n]
4623 // Expect: 4593 // Expect:
4624 // A: [K K K][K K K] 4594 // A: [K K K][K K K]
4625 // V [................K n] (As would occur if there really were a 4595 // V [................K n] (As would occur if there really were a
4626 // jagged cluster start and not badly muxed clusters as used to 4596 // jagged cluster start and not badly muxed clusters as used to
4627 // simulate a jagged start in this test.) 4597 // simulate a jagged start in this test.)
4628 ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO)); 4598 ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
4629 DemuxerStream* audio_stream = demuxer_->GetStream(DemuxerStream::AUDIO); 4599 DemuxerStream* audio_stream = demuxer_->GetStream(DemuxerStream::AUDIO);
4630 DemuxerStream* video_stream = demuxer_->GetStream(DemuxerStream::VIDEO); 4600 DemuxerStream* video_stream = demuxer_->GetStream(DemuxerStream::VIDEO);
4631 4601
4632 EXPECT_MEDIA_LOG(SegmentMissingFrames("video")); 4602 EXPECT_MEDIA_LOG(SegmentMissingFrames("1"));
4633 AppendMuxedCluster(MuxedStreamInfo(kAudioTrackNum, "0K 10K 20D10K"), 4603 AppendMuxedCluster(MuxedStreamInfo(kAudioTrackNum, "0K 10K 20D10K"),
4634 MuxedStreamInfo(kVideoTrackNum, "")); 4604 MuxedStreamInfo(kVideoTrackNum, ""));
4635 demuxer_->Remove(kSourceId, base::TimeDelta(), 4605 demuxer_->Remove(kSourceId, base::TimeDelta(),
4636 base::TimeDelta::FromMilliseconds(30)); 4606 base::TimeDelta::FromMilliseconds(30));
4637 AppendMuxedCluster(MuxedStreamInfo(kAudioTrackNum, "30K 40K 50D10K"), 4607 AppendMuxedCluster(MuxedStreamInfo(kAudioTrackNum, "30K 40K 50D10K"),
4638 MuxedStreamInfo(kVideoTrackNum, "30 40 50", 10)); 4608 MuxedStreamInfo(kVideoTrackNum, "30 40 50", 10));
4639 AppendMuxedCluster(MuxedStreamInfo(kAudioTrackNum, "60K 70K 80D10K"), 4609 AppendMuxedCluster(MuxedStreamInfo(kAudioTrackNum, "60K 70K 80D10K"),
4640 MuxedStreamInfo(kVideoTrackNum, "60 70K 80", 10)); 4610 MuxedStreamInfo(kVideoTrackNum, "60 70K 80", 10));
4641 CheckExpectedRanges(DemuxerStream::AUDIO, "{ [30,90) }"); 4611 CheckExpectedRanges(DemuxerStream::AUDIO, "{ [30,90) }");
4642 CheckExpectedRanges(DemuxerStream::VIDEO, "{ [0,90) }"); 4612 CheckExpectedRanges(DemuxerStream::VIDEO, "{ [0,90) }");
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
4737 TEST_F(ChunkDemuxerTest, StreamStatusNotifications) { 4707 TEST_F(ChunkDemuxerTest, StreamStatusNotifications) {
4738 ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO)); 4708 ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
4739 DemuxerStream* audio_stream = demuxer_->GetStream(DemuxerStream::AUDIO); 4709 DemuxerStream* audio_stream = demuxer_->GetStream(DemuxerStream::AUDIO);
4740 EXPECT_NE(nullptr, audio_stream); 4710 EXPECT_NE(nullptr, audio_stream);
4741 CheckStreamStatusNotifications(audio_stream); 4711 CheckStreamStatusNotifications(audio_stream);
4742 DemuxerStream* video_stream = demuxer_->GetStream(DemuxerStream::VIDEO); 4712 DemuxerStream* video_stream = demuxer_->GetStream(DemuxerStream::VIDEO);
4743 EXPECT_NE(nullptr, video_stream); 4713 EXPECT_NE(nullptr, video_stream);
4744 CheckStreamStatusNotifications(video_stream); 4714 CheckStreamStatusNotifications(video_stream);
4745 } 4715 }
4746 4716
4717 TEST_F(ChunkDemuxerTest, MultipleIds) {
4718 CreateNewDemuxer();
4719 EXPECT_CALL(*this, DemuxerOpened());
4720 EXPECT_CALL(host_, SetDuration(_)).Times(2);
4721 demuxer_->Initialize(&host_, CreateInitDoneCB(kNoTimestamp, PIPELINE_OK),
4722 true);
4723
4724 const char* kId1 = "id1";
4725 const char* kId2 = "id2";
4726 EXPECT_EQ(AddId(kId1, "video/webm", "opus,vp9"), ChunkDemuxer::kOk);
4727 EXPECT_EQ(AddId(kId2, "video/webm", "opus,vp9"), ChunkDemuxer::kOk);
4728 scoped_refptr<DecoderBuffer> data1 = ReadTestDataFile("green-a300hz.webm");
4729 scoped_refptr<DecoderBuffer> data2 = ReadTestDataFile("red-a500hz.webm");
4730
4731 EXPECT_MEDIA_LOG(FoundStream("audio")).Times(2);
4732 EXPECT_MEDIA_LOG(FoundStream("video")).Times(2);
4733 EXPECT_MEDIA_LOG(CodecName("audio", "opus")).Times(2);
4734 EXPECT_MEDIA_LOG(CodecName("video", "vp9")).Times(2);
4735 EXPECT_CALL(*this, InitSegmentReceivedMock(_)).Times(2);
4736 EXPECT_MEDIA_LOG(SegmentMissingFrames("1")).Times(AnyNumber());
wolenetz 2016/09/13 21:03:13 Is this because the test media indeed has muxed se
servolk 2016/09/14 18:15:25 Yes, if I remove this then the test fails due to u
wolenetz 2016/09/14 23:31:21 The binary files used by this test don't apply whe
servolk 2016/09/15 00:18:32 Done.
wolenetz 2016/09/15 01:00:08 Thank you. The files look ok. Specifically, "red-a
servolk 2016/09/15 02:13:07 Done.
4737
4738 EXPECT_TRUE(AppendData(kId1, data1->data(), data1->data_size()));
4739 EXPECT_TRUE(AppendData(kId2, data2->data(), data2->data_size()));
4740 CheckExpectedRanges(kId1, "{ [0,10007) }");
4741 CheckExpectedRanges(kId2, "{ [0,10007) }");
wolenetz 2016/09/13 21:03:13 nit: might be a slightly better test if the two so
servolk 2016/09/14 18:15:24 Done.
4742 }
4743
4744 TEST_F(ChunkDemuxerTest, CompleteInitAfterIdRemoved) {
4745 CreateNewDemuxer();
4746 EXPECT_CALL(*this, DemuxerOpened());
4747 demuxer_->Initialize(&host_,
4748 CreateInitDoneCB(kDefaultDuration(), PIPELINE_OK), true);
4749
4750 // Add two ids, then remove one of the ids and verify that adding data only
wolenetz 2016/09/13 21:03:13 nit: s/data/init segment/
servolk 2016/09/14 18:15:24 Done.
4751 // for the remaining id still triggers the InitDoneCB.
4752 const char* kId1 = "id1";
4753 const char* kId2 = "id2";
4754 EXPECT_EQ(AddId(kId1, "video/webm", "vp8"), ChunkDemuxer::kOk);
4755 EXPECT_EQ(AddId(kId2, "video/webm", "vp9"), ChunkDemuxer::kOk);
4756 demuxer_->RemoveId(kId2);
4757
4758 EXPECT_CALL(*this, InitSegmentReceivedMock(_));
4759 EXPECT_MEDIA_LOG(WebMSimpleBlockDurationEstimated(30));
wolenetz 2016/09/13 21:03:13 nit ditto of below.
servolk 2016/09/14 18:15:25 Acknowledged.
4760 EXPECT_MEDIA_LOG(FoundStream("video"));
4761 EXPECT_MEDIA_LOG(CodecName("video", "vp8"));
4762
4763 ASSERT_TRUE(AppendInitSegmentWithSourceId(kId1, HAS_VIDEO));
4764 AppendSingleStreamCluster(kId1, kVideoTrackNum, "0K 30 60 90");
wolenetz 2016/09/13 21:03:13 nit: this line should not be necessary to trigger
servolk 2016/09/14 18:15:25 I agree this is not strictly necessary, so I can r
wolenetz 2016/09/14 23:31:21 I'm fine with keeping it.
servolk 2016/09/15 00:18:32 Acknowledged.
4765 }
4766
4767 TEST_F(ChunkDemuxerTest, RemovingIdMustRemoveStreams) {
4768 CreateNewDemuxer();
4769 EXPECT_CALL(*this, DemuxerOpened());
4770 demuxer_->Initialize(&host_,
4771 CreateInitDoneCB(kDefaultDuration(), PIPELINE_OK), true);
4772
4773 const char* kId1 = "id1";
4774 EXPECT_EQ(AddId(kId1, "video/webm", "vorbis,vp8"), ChunkDemuxer::kOk);
4775
4776 EXPECT_CALL(*this, InitSegmentReceivedMock(_));
4777 EXPECT_MEDIA_LOG(FoundStream("video"));
4778 EXPECT_MEDIA_LOG(CodecName("video", "vp8"));
4779 EXPECT_MEDIA_LOG(FoundStream("audio"));
4780 EXPECT_MEDIA_LOG(CodecName("audio", "vorbis"));
4781
4782 // Append init segment to ensure demuxer streams get created.
4783 ASSERT_TRUE(AppendInitSegmentWithSourceId(kId1, HAS_AUDIO | HAS_VIDEO));
4784 EXPECT_NE(nullptr, demuxer_->GetStream(DemuxerStream::AUDIO));
4785 EXPECT_NE(nullptr, demuxer_->GetStream(DemuxerStream::VIDEO));
4786
4787 // Removing the id should remove also the DemuxerStreams.
4788 demuxer_->RemoveId(kId1);
4789 EXPECT_EQ(nullptr, demuxer_->GetStream(DemuxerStream::AUDIO));
4790 EXPECT_EQ(nullptr, demuxer_->GetStream(DemuxerStream::VIDEO));
4791 }
4792
4747 } // namespace media 4793 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698