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

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

Issue 2343543002: MSE: Replace crossfade splicing overlap trimming. (Closed)
Patch Set: fix compile error 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/source_buffer_stream.h" 5 #include "media/filters/source_buffer_stream.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 #include <stdint.h> 8 #include <stdint.h>
9 #include <string> 9 #include <string>
10 #include <vector> 10 #include <vector>
11 11
12 #include "base/bind.h" 12 #include "base/bind.h"
13 #include "base/bind_helpers.h" 13 #include "base/bind_helpers.h"
14 #include "base/logging.h" 14 #include "base/logging.h"
15 #include "base/macros.h" 15 #include "base/macros.h"
16 #include "base/strings/string_number_conversions.h" 16 #include "base/strings/string_number_conversions.h"
17 #include "base/strings/string_split.h" 17 #include "base/strings/string_split.h"
18 #include "base/strings/string_util.h" 18 #include "base/strings/string_util.h"
19 #include "media/base/data_buffer.h" 19 #include "media/base/data_buffer.h"
20 #include "media/base/decoder_buffer.h"
20 #include "media/base/media_log.h" 21 #include "media/base/media_log.h"
21 #include "media/base/media_util.h" 22 #include "media/base/media_util.h"
22 #include "media/base/mock_media_log.h" 23 #include "media/base/mock_media_log.h"
23 #include "media/base/test_helpers.h" 24 #include "media/base/test_helpers.h"
24 #include "media/base/text_track_config.h" 25 #include "media/base/text_track_config.h"
25 #include "media/base/timestamp_constants.h" 26 #include "media/base/timestamp_constants.h"
26 #include "media/filters/webvtt_util.h" 27 #include "media/filters/webvtt_util.h"
27 #include "testing/gtest/include/gtest/gtest.h" 28 #include "testing/gtest/include/gtest/gtest.h"
28 29
29 using ::testing::HasSubstr; 30 using ::testing::HasSubstr;
(...skipping 21 matching lines...) Expand all
51 MATCHER_P(ContainsTrackBufferExhaustionSkipLog, skip_milliseconds, "") { 52 MATCHER_P(ContainsTrackBufferExhaustionSkipLog, skip_milliseconds, "") {
52 return CONTAINS_STRING(arg, 53 return CONTAINS_STRING(arg,
53 "Media append that overlapped current playback " 54 "Media append that overlapped current playback "
54 "position caused time gap in playing VIDEO stream " 55 "position caused time gap in playing VIDEO stream "
55 "because the next keyframe is " + 56 "because the next keyframe is " +
56 base::IntToString(skip_milliseconds) + 57 base::IntToString(skip_milliseconds) +
57 "ms beyond last overlapped frame. Media may " 58 "ms beyond last overlapped frame. Media may "
58 "appear temporarily frozen."); 59 "appear temporarily frozen.");
59 } 60 }
60 61
61 MATCHER_P2(ContainsGeneratedSpliceLog, 62 MATCHER_P3(TrimmedSpliceOverlap,
62 duration_microseconds, 63 splice_time_us,
63 time_microseconds, 64 overlapped_start_us,
65 trim_duration_us,
64 "") { 66 "") {
65 return CONTAINS_STRING(arg, "Generated splice of overlap duration " + 67 return CONTAINS_STRING(
66 base::IntToString(duration_microseconds) + 68 arg, "Audio buffer splice at PTS=" + base::IntToString(splice_time_us) +
67 "us into new buffer at " + 69 "us. Trimmed tail of overlapped buffer (PTS=" +
68 base::IntToString(time_microseconds) + "us."); 70 base::IntToString(overlapped_start_us) + "us) by " +
71 base::IntToString(trim_duration_us));
69 } 72 }
70 73
71 class SourceBufferStreamTest : public testing::Test { 74 class SourceBufferStreamTest : public testing::Test {
72 protected: 75 protected:
73 SourceBufferStreamTest() : media_log_(new StrictMock<MockMediaLog>()) { 76 SourceBufferStreamTest() : media_log_(new StrictMock<MockMediaLog>()) {
74 video_config_ = TestVideoConfig::Normal(); 77 video_config_ = TestVideoConfig::Normal();
75 SetStreamInfo(kDefaultFramesPerSecond, kDefaultKeyframesPerSecond); 78 SetStreamInfo(kDefaultFramesPerSecond, kDefaultKeyframesPerSecond);
76 stream_.reset(new SourceBufferStream(video_config_, media_log_, true)); 79 stream_.reset(new SourceBufferStream(video_config_, media_log_));
77 } 80 }
78 81
79 void SetMemoryLimit(size_t buffers_of_data) { 82 void SetMemoryLimit(size_t buffers_of_data) {
80 stream_->set_memory_limit(buffers_of_data * kDataSize); 83 stream_->set_memory_limit(buffers_of_data * kDataSize);
81 } 84 }
82 85
83 void SetStreamInfo(int frames_per_second, int keyframes_per_second) { 86 void SetStreamInfo(int frames_per_second, int keyframes_per_second) {
84 frames_per_second_ = frames_per_second; 87 frames_per_second_ = frames_per_second;
85 keyframes_per_second_ = keyframes_per_second; 88 keyframes_per_second_ = keyframes_per_second;
86 frame_duration_ = ConvertToFrameDuration(frames_per_second); 89 frame_duration_ = ConvertToFrameDuration(frames_per_second);
87 } 90 }
88 91
89 void SetTextStream() { 92 void SetTextStream() {
90 video_config_ = TestVideoConfig::Invalid(); 93 video_config_ = TestVideoConfig::Invalid();
91 TextTrackConfig config(kTextSubtitles, "", "", ""); 94 TextTrackConfig config(kTextSubtitles, "", "", "");
92 stream_.reset(new SourceBufferStream(config, media_log_, true)); 95 stream_.reset(new SourceBufferStream(config, media_log_));
93 SetStreamInfo(2, 2); 96 SetStreamInfo(2, 2);
94 } 97 }
95 98
96 void SetAudioStream() { 99 void SetAudioStream() {
97 video_config_ = TestVideoConfig::Invalid(); 100 video_config_ = TestVideoConfig::Invalid();
98 audio_config_.Initialize(kCodecVorbis, kSampleFormatPlanarF32, 101 audio_config_.Initialize(kCodecVorbis, kSampleFormatPlanarF32,
99 CHANNEL_LAYOUT_STEREO, 1000, EmptyExtraData(), 102 CHANNEL_LAYOUT_STEREO, 1000, EmptyExtraData(),
100 Unencrypted(), base::TimeDelta(), 0); 103 Unencrypted(), base::TimeDelta(), 0);
101 stream_.reset(new SourceBufferStream(audio_config_, media_log_, true)); 104 stream_.reset(new SourceBufferStream(audio_config_, media_log_));
102 105
103 // Equivalent to 2ms per frame. 106 // Equivalent to 2ms per frame.
104 SetStreamInfo(500, 500); 107 SetStreamInfo(500, 500);
105 } 108 }
106 109
107 void NewCodedFrameGroupAppend(int starting_position, int number_of_buffers) { 110 void NewCodedFrameGroupAppend(int starting_position, int number_of_buffers) {
108 AppendBuffers(starting_position, number_of_buffers, true, 111 AppendBuffers(starting_position, number_of_buffers, true,
109 base::TimeDelta(), true, &kDataA, kDataSize); 112 base::TimeDelta(), true, &kDataA, kDataSize);
110 } 113 }
111 114
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after
299 } 302 }
300 303
301 EXPECT_EQ(ending_position + 1, current_position); 304 EXPECT_EQ(ending_position + 1, current_position);
302 } 305 }
303 306
304 void CheckExpectedBuffers(const std::string& expected) { 307 void CheckExpectedBuffers(const std::string& expected) {
305 std::vector<std::string> timestamps = base::SplitString( 308 std::vector<std::string> timestamps = base::SplitString(
306 expected, " ", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL); 309 expected, " ", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
307 std::stringstream ss; 310 std::stringstream ss;
308 const SourceBufferStream::Type type = stream_->GetType(); 311 const SourceBufferStream::Type type = stream_->GetType();
309 base::TimeDelta active_splice_timestamp = kNoTimestamp;
310 for (size_t i = 0; i < timestamps.size(); i++) { 312 for (size_t i = 0; i < timestamps.size(); i++) {
311 scoped_refptr<StreamParserBuffer> buffer; 313 scoped_refptr<StreamParserBuffer> buffer;
312 SourceBufferStream::Status status = stream_->GetNextBuffer(&buffer); 314 SourceBufferStream::Status status = stream_->GetNextBuffer(&buffer);
313 315
314 if (i > 0) 316 if (i > 0)
315 ss << " "; 317 ss << " ";
316 318
317 if (status == SourceBufferStream::kConfigChange) { 319 if (status == SourceBufferStream::kConfigChange) {
318 switch (type) { 320 switch (type) {
319 case SourceBufferStream::kVideo: 321 case SourceBufferStream::kVideo:
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
373 ASSERT_EQ(buffer->GetDecodeTimestamp(), 375 ASSERT_EQ(buffer->GetDecodeTimestamp(),
374 preroll_buffer->GetDecodeTimestamp()); 376 preroll_buffer->GetDecodeTimestamp());
375 ASSERT_EQ(kInfiniteDuration, preroll_buffer->discard_padding().first); 377 ASSERT_EQ(kInfiniteDuration, preroll_buffer->discard_padding().first);
376 ASSERT_EQ(base::TimeDelta(), preroll_buffer->discard_padding().second); 378 ASSERT_EQ(base::TimeDelta(), preroll_buffer->discard_padding().second);
377 ASSERT_TRUE(buffer->is_key_frame()); 379 ASSERT_TRUE(buffer->is_key_frame());
378 380
379 ss << "P"; 381 ss << "P";
380 } else if (buffer->is_key_frame()) { 382 } else if (buffer->is_key_frame()) {
381 ss << "K"; 383 ss << "K";
382 } 384 }
383
384 // Until the last splice frame is seen, indicated by a matching timestamp,
385 // all buffers must have the same splice_timestamp().
386 if (buffer->timestamp() == active_splice_timestamp) {
387 ASSERT_EQ(buffer->splice_timestamp(), kNoTimestamp);
388 } else {
389 ASSERT_TRUE(active_splice_timestamp == kNoTimestamp ||
390 active_splice_timestamp == buffer->splice_timestamp());
391 }
392
393 active_splice_timestamp = buffer->splice_timestamp();
394 } 385 }
395 EXPECT_EQ(expected, ss.str()); 386 EXPECT_EQ(expected, ss.str());
396 } 387 }
397 388
398 void CheckNoNextBuffer() { 389 void CheckNoNextBuffer() {
399 scoped_refptr<StreamParserBuffer> buffer; 390 scoped_refptr<StreamParserBuffer> buffer;
400 EXPECT_EQ(SourceBufferStream::kNeedBuffer, stream_->GetNextBuffer(&buffer)); 391 EXPECT_EQ(SourceBufferStream::kNeedBuffer, stream_->GetNextBuffer(&buffer));
401 } 392 }
402 393
403 void CheckEOSReached() { 394 void CheckEOSReached() {
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
520 // Indicates that the buffer should be marked as containing an *estimated* 511 // Indicates that the buffer should be marked as containing an *estimated*
521 // duration. E.g., "0D20E 20 25E 30" 512 // duration. E.g., "0D20E 20 25E 30"
522 // 513 //
523 // P: 514 // P:
524 // Indicates the buffer with will also have a preroll buffer 515 // Indicates the buffer with will also have a preroll buffer
525 // associated with it. The preroll buffer will just be dummy data. 516 // associated with it. The preroll buffer will just be dummy data.
526 // E.g. "0P 5 10" 517 // E.g. "0P 5 10"
527 // 518 //
528 // K: 519 // K:
529 // Indicates the buffer is a keyframe. E.g., "0K 1|2K 2|4D2K 6 8". 520 // Indicates the buffer is a keyframe. E.g., "0K 1|2K 2|4D2K 6 8".
530 //
531 // S(a# ... y# z#)
532 // Indicates a splice frame buffer should be created with timestamp z#. The
533 // preceding timestamps a# ... y# will be treated as the fade out preroll for
534 // the splice frame. If a timestamp within the preroll ends with C the config
wolenetz 2016/09/26 23:52:37 I think we still need some configchange testing (s
chcunningham 2016/10/27 23:36:06 See new test, SourceBufferStreamTest.Audio_ConfigC
wolenetz 2016/10/28 23:08:19 Acknowledged.
535 // id to use for that and subsequent preroll appends is incremented by one.
536 // The config id for non-splice frame appends will not be affected.
537 BufferQueue StringToBufferQueue(const std::string& buffers_to_append) { 521 BufferQueue StringToBufferQueue(const std::string& buffers_to_append) {
538 std::vector<std::string> timestamps = base::SplitString( 522 std::vector<std::string> timestamps = base::SplitString(
539 buffers_to_append, " ", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL); 523 buffers_to_append, " ", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
540 524
541 CHECK_GT(timestamps.size(), 0u); 525 CHECK_GT(timestamps.size(), 0u);
542 526
543 bool splice_frame = false;
544 size_t splice_config_id = stream_->append_config_index_;
545 BufferQueue pre_splice_buffers;
546 BufferQueue buffers; 527 BufferQueue buffers;
547 for (size_t i = 0; i < timestamps.size(); i++) { 528 for (size_t i = 0; i < timestamps.size(); i++) {
548 bool is_keyframe = false; 529 bool is_keyframe = false;
549 bool has_preroll = false; 530 bool has_preroll = false;
550 bool last_splice_frame = false;
551 bool is_duration_estimated = false; 531 bool is_duration_estimated = false;
552 532
553 // Handle splice frame starts.
554 if (base::StartsWith(timestamps[i], "S(", base::CompareCase::SENSITIVE)) {
555 CHECK(!splice_frame);
556 splice_frame = true;
557 // Remove the "S(" off of the token.
558 timestamps[i] = timestamps[i].substr(2, timestamps[i].length());
559 }
560 if (splice_frame &&
561 base::EndsWith(timestamps[i], ")", base::CompareCase::SENSITIVE)) {
562 splice_frame = false;
563 last_splice_frame = true;
564 // Remove the ")" off of the token.
565 timestamps[i] = timestamps[i].substr(0, timestamps[i].length() - 1);
566 }
567 // Handle config changes within the splice frame.
568 if (splice_frame &&
569 base::EndsWith(timestamps[i], "C", base::CompareCase::SENSITIVE)) {
570 splice_config_id++;
571 CHECK(splice_config_id < stream_->audio_configs_.size() ||
572 splice_config_id < stream_->video_configs_.size());
573 // Remove the "C" off of the token.
574 timestamps[i] = timestamps[i].substr(0, timestamps[i].length() - 1);
575 }
576 if (base::EndsWith(timestamps[i], "K", base::CompareCase::SENSITIVE)) { 533 if (base::EndsWith(timestamps[i], "K", base::CompareCase::SENSITIVE)) {
577 is_keyframe = true; 534 is_keyframe = true;
578 // Remove the "K" off of the token. 535 // Remove the "K" off of the token.
579 timestamps[i] = timestamps[i].substr(0, timestamps[i].length() - 1); 536 timestamps[i] = timestamps[i].substr(0, timestamps[i].length() - 1);
580 } 537 }
581 // Handle preroll buffers. 538 // Handle preroll buffers.
582 if (base::EndsWith(timestamps[i], "P", base::CompareCase::SENSITIVE)) { 539 if (base::EndsWith(timestamps[i], "P", base::CompareCase::SENSITIVE)) {
583 is_keyframe = true; 540 is_keyframe = true;
584 has_preroll = true; 541 has_preroll = true;
585 // Remove the "P" off of the token. 542 // Remove the "P" off of the token.
586 timestamps[i] = timestamps[i].substr(0, timestamps[i].length() - 1); 543 timestamps[i] = timestamps[i].substr(0, timestamps[i].length() - 1);
587 } 544 }
588 545
589 if (base::EndsWith(timestamps[i], "E", base::CompareCase::SENSITIVE)) { 546 if (base::EndsWith(timestamps[i], "E", base::CompareCase::SENSITIVE)) {
590 is_duration_estimated = true; 547 is_duration_estimated = true;
591 // Remove the "E" off of the token. 548 // Remove the "E" off of the token.
592 timestamps[i] = timestamps[i].substr(0, timestamps[i].length() - 1); 549 timestamps[i] = timestamps[i].substr(0, timestamps[i].length() - 1);
593 } 550 }
594 551
595 int duration_in_ms = 0; 552 int duration_in_ms = -1;
596 size_t duration_pos = timestamps[i].find('D'); 553 size_t duration_pos = timestamps[i].find('D');
597 if (duration_pos != std::string::npos) { 554 if (duration_pos != std::string::npos) {
598 CHECK(base::StringToInt(timestamps[i].substr(duration_pos + 1), 555 CHECK(base::StringToInt(timestamps[i].substr(duration_pos + 1),
599 &duration_in_ms)); 556 &duration_in_ms));
600 timestamps[i] = timestamps[i].substr(0, duration_pos); 557 timestamps[i] = timestamps[i].substr(0, duration_pos);
601 } 558 }
602 559
603 std::vector<std::string> buffer_timestamps = base::SplitString( 560 std::vector<std::string> buffer_timestamps = base::SplitString(
604 timestamps[i], "|", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL); 561 timestamps[i], "|", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
605 562
(...skipping 12 matching lines...) Expand all
618 StreamParserBuffer::CopyFrom(&kDataA, kDataSize, is_keyframe, 575 StreamParserBuffer::CopyFrom(&kDataA, kDataSize, is_keyframe,
619 DemuxerStream::AUDIO, 0); 576 DemuxerStream::AUDIO, 0);
620 buffer->set_timestamp(base::TimeDelta::FromMilliseconds(pts_in_ms)); 577 buffer->set_timestamp(base::TimeDelta::FromMilliseconds(pts_in_ms));
621 buffer->set_is_duration_estimated(is_duration_estimated); 578 buffer->set_is_duration_estimated(is_duration_estimated);
622 579
623 if (dts_in_ms != pts_in_ms) { 580 if (dts_in_ms != pts_in_ms) {
624 buffer->SetDecodeTimestamp( 581 buffer->SetDecodeTimestamp(
625 DecodeTimestamp::FromMilliseconds(dts_in_ms)); 582 DecodeTimestamp::FromMilliseconds(dts_in_ms));
626 } 583 }
627 584
628 if (duration_in_ms) 585 if (duration_in_ms >= 0)
629 buffer->set_duration(base::TimeDelta::FromMilliseconds(duration_in_ms)); 586 buffer->set_duration(base::TimeDelta::FromMilliseconds(duration_in_ms));
630 587
631 // Simulate preroll buffers by just generating another buffer and sticking 588 // Simulate preroll buffers by just generating another buffer and sticking
632 // it as the preroll. 589 // it as the preroll.
633 if (has_preroll) { 590 if (has_preroll) {
634 scoped_refptr<StreamParserBuffer> preroll_buffer = 591 scoped_refptr<StreamParserBuffer> preroll_buffer =
635 StreamParserBuffer::CopyFrom( 592 StreamParserBuffer::CopyFrom(
636 &kDataA, kDataSize, is_keyframe, DemuxerStream::AUDIO, 0); 593 &kDataA, kDataSize, is_keyframe, DemuxerStream::AUDIO, 0);
637 preroll_buffer->set_duration(frame_duration_); 594 preroll_buffer->set_duration(frame_duration_);
638 buffer->SetPrerollBuffer(preroll_buffer); 595 buffer->SetPrerollBuffer(preroll_buffer);
639 } 596 }
640 597
641 if (splice_frame) {
642 // Make sure that splice frames aren't used with content where decode
643 // and presentation timestamps can differ. (i.e., B-frames)
644 CHECK_EQ(buffer->GetDecodeTimestamp().InMicroseconds(),
645 buffer->timestamp().InMicroseconds());
646 if (!pre_splice_buffers.empty()) {
647 // Enforce strictly monotonically increasing timestamps.
648 CHECK_GT(
649 buffer->timestamp().InMicroseconds(),
650 pre_splice_buffers.back()->timestamp().InMicroseconds());
651 CHECK_GT(
652 buffer->GetDecodeTimestamp().InMicroseconds(),
653 pre_splice_buffers.back()->GetDecodeTimestamp().InMicroseconds());
654 }
655 buffer->SetConfigId(splice_config_id);
656 UpdateLastBufferDuration(buffer->GetDecodeTimestamp(),
657 &pre_splice_buffers);
658 pre_splice_buffers.push_back(buffer);
659 continue;
660 }
661
662 if (last_splice_frame) {
663 // Require at least one additional buffer for a splice.
664 CHECK(!pre_splice_buffers.empty());
665 buffer->SetConfigId(splice_config_id);
666 buffer->ConvertToSpliceBuffer(pre_splice_buffers);
667 pre_splice_buffers.clear();
668 }
669
670 UpdateLastBufferDuration(buffer->GetDecodeTimestamp(), &buffers); 598 UpdateLastBufferDuration(buffer->GetDecodeTimestamp(), &buffers);
671 buffers.push_back(buffer); 599 buffers.push_back(buffer);
672 } 600 }
673 601
674 // If the last buffer doesn't have a duration, assume it is the 602 // If the last buffer doesn't have a duration, assume it is the
675 // same as the second to last buffer. 603 // same as the second to last buffer.
676 if (buffers.size() >= 2 && 604 if (buffers.size() >= 2 && buffers.back()->duration() == kNoTimestamp) {
677 buffers.back()->duration() <= base::TimeDelta()) {
678 buffers.back()->set_duration( 605 buffers.back()->set_duration(
679 buffers[buffers.size() - 2]->duration()); 606 buffers[buffers.size() - 2]->duration());
680 } 607 }
681 608
682 return buffers; 609 return buffers;
683 } 610 }
684 611
685 void AppendBuffers(const std::string& buffers_to_append, 612 void AppendBuffers(const std::string& buffers_to_append,
686 bool start_new_coded_frame_group, 613 bool start_new_coded_frame_group,
687 base::TimeDelta coded_frame_group_start_timestamp, 614 base::TimeDelta coded_frame_group_start_timestamp,
(...skipping 2921 matching lines...) Expand 10 before | Expand all | Expand 10 after
3609 TEST_F(SourceBufferStreamTest, SameTimestamp_Video_SingleAppend) { 3536 TEST_F(SourceBufferStreamTest, SameTimestamp_Video_SingleAppend) {
3610 Seek(0); 3537 Seek(0);
3611 NewCodedFrameGroupAppend("0K 30 30 60 90 120K 150"); 3538 NewCodedFrameGroupAppend("0K 30 30 60 90 120K 150");
3612 CheckExpectedBuffers("0K 30 30 60 90 120K 150"); 3539 CheckExpectedBuffers("0K 30 30 60 90 120K 150");
3613 } 3540 }
3614 3541
3615 // Verify that non-keyframes with the same timestamp can occur 3542 // Verify that non-keyframes with the same timestamp can occur
3616 // in different appends. 3543 // in different appends.
3617 TEST_F(SourceBufferStreamTest, SameTimestamp_Video_TwoAppends) { 3544 TEST_F(SourceBufferStreamTest, SameTimestamp_Video_TwoAppends) {
3618 Seek(0); 3545 Seek(0);
3619 NewCodedFrameGroupAppend("0K 30"); 3546 NewCodedFrameGroupAppend("0K 30D0");
3620 AppendBuffers("30 60 90 120K 150"); 3547 AppendBuffers("30 60 90 120K 150");
3621 CheckExpectedBuffers("0K 30 30 60 90 120K 150"); 3548 CheckExpectedBuffers("0K 30 30 60 90 120K 150");
3622 } 3549 }
3623 3550
3624 // Verify that a non-keyframe followed by a keyframe with the same timestamp 3551 // Verify that a non-keyframe followed by a keyframe with the same timestamp
3625 // is allowed, but also results in a MediaLog. 3552 // is allowed, but also results in a MediaLog.
3626 TEST_F(SourceBufferStreamTest, SameTimestamp_Video_SingleAppend_Warning) { 3553 TEST_F(SourceBufferStreamTest, SameTimestamp_Video_SingleAppend_Warning) {
3627 EXPECT_MEDIA_LOG(ContainsSameTimestampAt30MillisecondsLog()); 3554 EXPECT_MEDIA_LOG(ContainsSameTimestampAt30MillisecondsLog());
3628 3555
3629 Seek(0); 3556 Seek(0);
3630 NewCodedFrameGroupAppend("0K 30 30K 60"); 3557 NewCodedFrameGroupAppend("0K 30 30K 60");
3631 CheckExpectedBuffers("0K 30 30K 60"); 3558 CheckExpectedBuffers("0K 30 30K 60");
3632 } 3559 }
3633 3560
3634 TEST_F(SourceBufferStreamTest, SameTimestamp_Video_TwoAppends_Warning) { 3561 TEST_F(SourceBufferStreamTest, SameTimestamp_Video_TwoAppends_Warning) {
3635 EXPECT_MEDIA_LOG(ContainsSameTimestampAt30MillisecondsLog()); 3562 EXPECT_MEDIA_LOG(ContainsSameTimestampAt30MillisecondsLog());
3636 3563
3637 Seek(0); 3564 Seek(0);
3638 NewCodedFrameGroupAppend("0K 30"); 3565 NewCodedFrameGroupAppend("0K 30D0");
3639 AppendBuffers("30K 60"); 3566 AppendBuffers("30K 60");
3640 CheckExpectedBuffers("0K 30 30K 60"); 3567 CheckExpectedBuffers("0K 30 30K 60");
3641 } 3568 }
3642 3569
3643 // Verify that a keyframe followed by a non-keyframe with the same timestamp 3570 // Verify that a keyframe followed by a non-keyframe with the same timestamp
3644 // is allowed. 3571 // is allowed.
3645 TEST_F(SourceBufferStreamTest, SameTimestamp_VideoKeyFrame_TwoAppends) { 3572 TEST_F(SourceBufferStreamTest, SameTimestamp_VideoKeyFrame_TwoAppends) {
3646 Seek(0); 3573 Seek(0);
3647 NewCodedFrameGroupAppend("0K 30K"); 3574 NewCodedFrameGroupAppend("0K 30D0K");
3648 AppendBuffers("30 60"); 3575 AppendBuffers("30 60");
3649 CheckExpectedBuffers("0K 30K 30 60"); 3576 CheckExpectedBuffers("0K 30K 30 60");
3650 } 3577 }
3651 3578
3652 TEST_F(SourceBufferStreamTest, SameTimestamp_VideoKeyFrame_SingleAppend) { 3579 TEST_F(SourceBufferStreamTest, SameTimestamp_VideoKeyFrame_SingleAppend) {
3653 Seek(0); 3580 Seek(0);
3654 NewCodedFrameGroupAppend("0K 30K 30 60"); 3581 NewCodedFrameGroupAppend("0K 30K 30 60");
3655 CheckExpectedBuffers("0K 30K 30 60"); 3582 CheckExpectedBuffers("0K 30K 30 60");
3656 } 3583 }
3657 3584
3658 TEST_F(SourceBufferStreamTest, SameTimestamp_Video_Overlap_1) { 3585 TEST_F(SourceBufferStreamTest, SameTimestamp_Video_Overlap_1) {
3659 Seek(0); 3586 Seek(0);
3660 NewCodedFrameGroupAppend("0K 30 60 60 90 120K 150"); 3587 NewCodedFrameGroupAppend("0K 30 60 60 90 120K 150");
3661 3588
3662 NewCodedFrameGroupAppend("60K 91 121K 151"); 3589 NewCodedFrameGroupAppend("60K 91 121K 151");
3663 CheckExpectedBuffers("0K 30 60K 91 121K 151"); 3590 CheckExpectedBuffers("0K 30 60K 91 121K 151");
3664 } 3591 }
3665 3592
3666 TEST_F(SourceBufferStreamTest, SameTimestamp_Video_Overlap_2) { 3593 TEST_F(SourceBufferStreamTest, SameTimestamp_Video_Overlap_2) {
3667 Seek(0); 3594 Seek(0);
3668 NewCodedFrameGroupAppend("0K 30 60 60 90 120K 150"); 3595 NewCodedFrameGroupAppend("0K 30 60 60 90 120K 150");
3669 NewCodedFrameGroupAppend("0K 30 61"); 3596 NewCodedFrameGroupAppend("0K 30 61");
3670 CheckExpectedBuffers("0K 30 61 120K 150"); 3597 CheckExpectedBuffers("0K 30 61 120K 150");
3671 } 3598 }
3672 3599
3673 TEST_F(SourceBufferStreamTest, SameTimestamp_Video_Overlap_3) { 3600 TEST_F(SourceBufferStreamTest, SameTimestamp_Video_Overlap_3) {
3674 Seek(0); 3601 Seek(0);
3675 NewCodedFrameGroupAppend("0K 20 40 60 80 100K 101 102 103K"); 3602 NewCodedFrameGroupAppend("0K 20 40 60 80 100K 101 102 103K");
3676 NewCodedFrameGroupAppend("0K 20 40 60 80 90"); 3603 NewCodedFrameGroupAppend("0K 20 40 60 80 90D0");
3677 CheckExpectedBuffers("0K 20 40 60 80 90 100K 101 102 103K"); 3604 CheckExpectedBuffers("0K 20 40 60 80 90 100K 101 102 103K");
3678 AppendBuffers("90 110K 150"); 3605 AppendBuffers("90 110K 150");
3679 Seek(0); 3606 Seek(0);
3680 CheckExpectedBuffers("0K 20 40 60 80 90 90 110K 150"); 3607 CheckExpectedBuffers("0K 20 40 60 80 90 90 110K 150");
3681 CheckNoNextBuffer(); 3608 CheckNoNextBuffer();
3682 CheckExpectedRangesByTimestamp("{ [0,190) }"); 3609 CheckExpectedRangesByTimestamp("{ [0,190) }");
3683 } 3610 }
3684 3611
3685 // Test all the valid same timestamp cases for audio. 3612 // Test all the valid same timestamp cases for audio.
3686 TEST_F(SourceBufferStreamTest, SameTimestamp_Audio) { 3613 TEST_F(SourceBufferStreamTest, SameTimestamp_Audio) {
3687 AudioDecoderConfig config(kCodecMP3, kSampleFormatF32, CHANNEL_LAYOUT_STEREO, 3614 AudioDecoderConfig config(kCodecMP3, kSampleFormatF32, CHANNEL_LAYOUT_STEREO,
3688 44100, EmptyExtraData(), Unencrypted()); 3615 44100, EmptyExtraData(), Unencrypted());
3689 stream_.reset(new SourceBufferStream(config, media_log_, true)); 3616 stream_.reset(new SourceBufferStream(config, media_log_));
3690 Seek(0); 3617 Seek(0);
3691 NewCodedFrameGroupAppend("0K 0K 30K 30 60 60"); 3618 NewCodedFrameGroupAppend("0K 0K 30K 30 60 60");
3692 CheckExpectedBuffers("0K 0K 30K 30 60 60"); 3619 CheckExpectedBuffers("0K 0K 30K 30 60 60");
3693 } 3620 }
3694 3621
3695 TEST_F(SourceBufferStreamTest, SameTimestamp_Audio_SingleAppend_Warning) { 3622 TEST_F(SourceBufferStreamTest, SameTimestamp_Audio_SingleAppend_Warning) {
3696 EXPECT_MEDIA_LOG(ContainsSameTimestampAt30MillisecondsLog()); 3623 EXPECT_MEDIA_LOG(ContainsSameTimestampAt30MillisecondsLog());
3697 3624
3698 AudioDecoderConfig config(kCodecMP3, kSampleFormatF32, CHANNEL_LAYOUT_STEREO, 3625 AudioDecoderConfig config(kCodecMP3, kSampleFormatF32, CHANNEL_LAYOUT_STEREO,
3699 44100, EmptyExtraData(), Unencrypted()); 3626 44100, EmptyExtraData(), Unencrypted());
3700 stream_.reset(new SourceBufferStream(config, media_log_, true)); 3627 stream_.reset(new SourceBufferStream(config, media_log_));
3701 Seek(0); 3628 Seek(0);
3702 3629
3703 // Note, in reality, a non-keyframe audio frame is rare or perhaps not 3630 // Note, in reality, a non-keyframe audio frame is rare or perhaps not
3704 // possible. 3631 // possible.
3705 NewCodedFrameGroupAppend("0K 30 30K 60"); 3632 NewCodedFrameGroupAppend("0K 30 30K 60");
3706 CheckExpectedBuffers("0K 30 30K 60"); 3633 CheckExpectedBuffers("0K 30 30K 60");
3707 } 3634 }
3708 3635
3709 // If seeking past any existing range and the seek is pending 3636 // If seeking past any existing range and the seek is pending
3710 // because no data has been provided for that position, 3637 // because no data has been provided for that position,
(...skipping 371 matching lines...) Expand 10 before | Expand all | Expand 10 after
4082 SetTextStream(); 4009 SetTextStream();
4083 NewCodedFrameGroupAppend("1500K 2000K 2500K 3000K 3500K"); 4010 NewCodedFrameGroupAppend("1500K 2000K 2500K 3000K 3500K");
4084 CheckExpectedRangesByTimestamp("{ [1500,4000) }"); 4011 CheckExpectedRangesByTimestamp("{ [1500,4000) }");
4085 NewCodedFrameGroupAppend("0K 501K 1001K 1501K 2001K"); 4012 NewCodedFrameGroupAppend("0K 501K 1001K 1501K 2001K");
4086 CheckExpectedRangesByTimestamp("{ [0,4000) }"); 4013 CheckExpectedRangesByTimestamp("{ [0,4000) }");
4087 4014
4088 Seek(0); 4015 Seek(0);
4089 CheckExpectedBuffers("0K 501K 1001K 1501K 2001K 3000K 3500K"); 4016 CheckExpectedBuffers("0K 501K 1001K 1501K 2001K 3000K 3500K");
4090 } 4017 }
4091 4018
4092 TEST_F(SourceBufferStreamTest, SpliceFrame_Basic) { 4019 TEST_F(SourceBufferStreamTest, Audio_SpliceTrimmingForOverlap) {
4093 Seek(0);
4094 NewCodedFrameGroupAppend("0K S(3K 6 9D3 10D5) 15 20 S(25K 30D5 35D5) 40");
4095 CheckExpectedBuffers("0K 3K 6 9 C 10 15 20 25K 30 C 35 40");
4096 CheckNoNextBuffer();
4097 }
4098
4099 TEST_F(SourceBufferStreamTest, SpliceFrame_SeekClearsSplice) {
4100 Seek(0);
4101 NewCodedFrameGroupAppend("0K S(3K 6 9D3 10D5) 15K 20");
4102 CheckExpectedBuffers("0K 3K 6");
4103
4104 SeekToTimestampMs(15);
4105 CheckExpectedBuffers("15K 20");
4106 CheckNoNextBuffer();
4107 }
4108
4109 TEST_F(SourceBufferStreamTest, SpliceFrame_SeekClearsSpliceFromTrackBuffer) {
4110 Seek(0);
4111 NewCodedFrameGroupAppend("0K 2K S(3K 6 9D3 10D5) 15K 20");
4112 CheckExpectedBuffers("0K 2K");
4113
4114 // Overlap the existing coded frame group.
4115 NewCodedFrameGroupAppend("5K 15K 20");
4116 CheckExpectedBuffers("3K 6");
4117
4118 SeekToTimestampMs(15);
4119 CheckExpectedBuffers("15K 20");
4120 CheckNoNextBuffer();
4121 }
4122
4123 TEST_F(SourceBufferStreamTest, SpliceFrame_ConfigChangeWithinSplice) {
4124 VideoDecoderConfig new_config = TestVideoConfig::Large();
4125 ASSERT_FALSE(new_config.Matches(video_config_));
4126
4127 // Add a new video config, then reset the config index back to the original.
4128 stream_->UpdateVideoConfig(new_config);
4129 stream_->UpdateVideoConfig(video_config_);
4130
4131 Seek(0);
4132 CheckVideoConfig(video_config_);
4133 NewCodedFrameGroupAppend("0K S(3K 6C 9D3 10D5) 15");
4134
4135 CheckExpectedBuffers("0K 3K C");
4136 CheckVideoConfig(new_config);
4137 CheckExpectedBuffers("6 9 C");
4138 CheckExpectedBuffers("10 C");
4139 CheckVideoConfig(video_config_);
4140 CheckExpectedBuffers("15");
4141 CheckNoNextBuffer();
4142 }
4143
4144 TEST_F(SourceBufferStreamTest, SpliceFrame_BasicFromTrackBuffer) {
4145 Seek(0);
4146 NewCodedFrameGroupAppend("0K 5K S(8K 9D1 10D10) 20");
4147 CheckExpectedBuffers("0K 5K");
4148
4149 // Overlap the existing coded frame group.
4150 NewCodedFrameGroupAppend("5K 20");
4151 CheckExpectedBuffers("8K 9 C 10 20");
4152 CheckNoNextBuffer();
4153 }
4154
4155 TEST_F(SourceBufferStreamTest,
4156 SpliceFrame_ConfigChangeWithinSpliceFromTrackBuffer) {
4157 VideoDecoderConfig new_config = TestVideoConfig::Large();
4158 ASSERT_FALSE(new_config.Matches(video_config_));
4159
4160 // Add a new video config, then reset the config index back to the original.
4161 stream_->UpdateVideoConfig(new_config);
4162 stream_->UpdateVideoConfig(video_config_);
4163
4164 Seek(0);
4165 CheckVideoConfig(video_config_);
4166 NewCodedFrameGroupAppend("0K 5K S(7K 8C 9D1 10D10) 20");
4167 CheckExpectedBuffers("0K 5K");
4168
4169 // Overlap the existing coded frame group.
4170 NewCodedFrameGroupAppend("5K 20");
4171 CheckExpectedBuffers("7K C");
4172 CheckVideoConfig(new_config);
4173 CheckExpectedBuffers("8 9 C");
4174 CheckExpectedBuffers("10 C");
4175 CheckVideoConfig(video_config_);
4176 CheckExpectedBuffers("20");
4177 CheckNoNextBuffer();
4178 }
4179
4180 TEST_F(SourceBufferStreamTest, Audio_SpliceFrame_Basic) {
4181 EXPECT_MEDIA_LOG(ContainsGeneratedSpliceLog(3000, 11000));
4182
4183 SetAudioStream(); 4020 SetAudioStream();
4184 Seek(0); 4021 Seek(0);
4185 NewCodedFrameGroupAppend("0K 2K 4K 6K 8K 10K 12K"); 4022 NewCodedFrameGroupAppend("0K 2K 4K 6K 8K 10K 12K");
4186 NewCodedFrameGroupAppend("11K 13K 15K 17K"); 4023 CheckExpectedRangesByTimestamp("{ [0,14) }");
4187 CheckExpectedBuffers("0K 2K 4K 6K 8K 10K 12K C 11K 13K 15K 17K"); 4024 // Note that duration of frame at time 10 is verified to be 2 ms.
4025 CheckExpectedBuffers("0K 2K 4K 6K 8K 10D2K 12K");
4188 CheckNoNextBuffer(); 4026 CheckNoNextBuffer();
4189 }
4190 4027
4191 TEST_F(SourceBufferStreamTest, Audio_SpliceFrame_NoExactSplices) { 4028 // Append new group with front slightly overlapping existing buffer at 10ms.
4192 EXPECT_MEDIA_LOG( 4029 EXPECT_MEDIA_LOG(TrimmedSpliceOverlap(11000, 10000, 1000));
4193 HasSubstr("Skipping splice frame generation: first new buffer at 10000us "
4194 "begins at or before existing buffer at 10000us."));
4195
4196 SetAudioStream();
4197 Seek(0);
4198 NewCodedFrameGroupAppend("0K 2K 4K 6K 8K 10K 12K");
4199 NewCodedFrameGroupAppend("10K 14K");
4200 CheckExpectedBuffers("0K 2K 4K 6K 8K 10K 14K");
4201 CheckNoNextBuffer();
4202 }
4203
4204 // Do not allow splices on top of splices.
4205 TEST_F(SourceBufferStreamTest, Audio_SpliceFrame_NoDoubleSplice) {
4206 InSequence s;
4207 EXPECT_MEDIA_LOG(ContainsGeneratedSpliceLog(3000, 11000));
4208 EXPECT_MEDIA_LOG(
4209 HasSubstr("Skipping splice frame generation: overlapped buffers at "
4210 "10000us are in a previously buffered splice."));
4211
4212 SetAudioStream();
4213 Seek(0);
4214 NewCodedFrameGroupAppend("0K 2K 4K 6K 8K 10K 12K");
4215 NewCodedFrameGroupAppend("11K 13K 15K 17K"); 4030 NewCodedFrameGroupAppend("11K 13K 15K 17K");
4216 4031
4217 // Verify the splice was created. 4032 // Cross-fade splicing is no longer implemented. Instead we should expect
4218 CheckExpectedBuffers("0K 2K 4K 6K 8K 10K 12K C 11K 13K 15K 17K"); 4033 // wholly overlapped buffers to be removed (12K). If a buffer is partially
4219 CheckNoNextBuffer(); 4034 // overlapped (e.g. last millisecond of 10K), the existing buffer should be
4035 // trimmed to perfectly abut the newly appended buffers.
4220 Seek(0); 4036 Seek(0);
4221 4037
4222 // Create a splice before the first splice which would include it. 4038 CheckExpectedRangesByTimestamp("{ [0,19) }");
4223 NewCodedFrameGroupAppend("9D2K"); 4039 CheckExpectedBuffers("0K 2K 4K 6K 8K 10D1K 11D2K 13K 15K 17K");
4224
4225 // A splice on top of a splice should result in a discard of the original
4226 // splice and no new splice frame being generated.
4227 CheckExpectedBuffers("0K 2K 4K 6K 8K 9K 13K 15K 17K");
4228 CheckNoNextBuffer(); 4040 CheckNoNextBuffer();
4229 } 4041 }
4230 4042
4231 // Test that a splice is not created if an end timestamp and start timestamp 4043 // Test that a splice is not created if an end timestamp and start timestamp
4232 // overlap. 4044 // perfectly overlap.
4233 TEST_F(SourceBufferStreamTest, Audio_SpliceFrame_NoSplice) { 4045 TEST_F(SourceBufferStreamTest, Audio_SpliceFrame_NoSplice) {
4234 SetAudioStream(); 4046 SetAudioStream();
4235 Seek(0); 4047 Seek(0);
4048
4049 // Add 10 frames across 2 *non-overlapping* appends.
4236 NewCodedFrameGroupAppend("0K 2K 4K 6K 8K 10K"); 4050 NewCodedFrameGroupAppend("0K 2K 4K 6K 8K 10K");
4237 NewCodedFrameGroupAppend("12K 14K 16K 18K"); 4051 NewCodedFrameGroupAppend("12K 14K 16K 18K");
4238 CheckExpectedBuffers("0K 2K 4K 6K 8K 10K 12K 14K 16K 18K"); 4052
4053 // Manually inspect the buffers at the no-splice boundary to verify duration
4054 // and lack of discard padding (set when splicing).
4055 scoped_refptr<StreamParserBuffer> buffer;
4056 const DecoderBuffer::DiscardPadding kEmptyDiscardPadding;
4057 for (int i = 0; i < 10; i++) {
4058 // Verify buffer timestamps and durations are preserved and no buffers have
4059 // discard padding (indicating no splice trimming).
4060 EXPECT_EQ(SourceBufferStream::kSuccess, stream_->GetNextBuffer(&buffer));
4061 EXPECT_EQ(base::TimeDelta::FromMilliseconds(i * 2), buffer->timestamp());
4062 EXPECT_EQ(base::TimeDelta::FromMilliseconds(2), buffer->duration());
4063 EXPECT_EQ(kEmptyDiscardPadding, buffer->discard_padding());
4064 }
4065
4239 CheckNoNextBuffer(); 4066 CheckNoNextBuffer();
4240 } 4067 }
4241 4068
4242 TEST_F(SourceBufferStreamTest, Audio_SpliceFrame_CorrectGroupStartTime) { 4069 TEST_F(SourceBufferStreamTest, Audio_SpliceTrimming_ExistingTrimming) {
4243 EXPECT_MEDIA_LOG(ContainsGeneratedSpliceLog(5000, 1000)); 4070 const base::TimeDelta kDuration = base::TimeDelta::FromMilliseconds(4);
4244 4071 const base::TimeDelta kNoDiscard = base::TimeDelta();
4245 SetAudioStream(); 4072 const bool is_keyframe = true;
4246 Seek(0);
4247 NewCodedFrameGroupAppend("0K 2K 4K");
4248 CheckExpectedRangesByTimestamp("{ [0,6) }");
4249 NewCodedFrameGroupAppend("6K 8K 10K");
4250 CheckExpectedRangesByTimestamp("{ [0,12) }");
4251 NewCodedFrameGroupAppend("1K 4D2K");
4252 CheckExpectedRangesByTimestamp("{ [0,12) }");
4253 CheckExpectedBuffers("0K 2K 4K C 1K 4K 6K 8K 10K");
4254 CheckNoNextBuffer();
4255 }
4256
4257 TEST_F(SourceBufferStreamTest, Audio_SpliceFrame_ConfigChange) {
4258 EXPECT_MEDIA_LOG(ContainsGeneratedSpliceLog(3000, 5000));
4259
4260 SetAudioStream();
4261
4262 AudioDecoderConfig new_config(kCodecVorbis, kSampleFormatPlanarF32,
4263 CHANNEL_LAYOUT_MONO, 1000, EmptyExtraData(),
4264 Unencrypted());
4265 ASSERT_NE(new_config.channel_layout(), audio_config_.channel_layout());
4266
4267 Seek(0);
4268 CheckAudioConfig(audio_config_);
4269 NewCodedFrameGroupAppend("0K 2K 4K 6K");
4270 stream_->UpdateAudioConfig(new_config);
4271 NewCodedFrameGroupAppend("5K 8K 12K");
4272 CheckExpectedBuffers("0K 2K 4K 6K C 5K 8K 12K");
4273 CheckAudioConfig(new_config);
4274 CheckNoNextBuffer();
4275 }
4276
4277 // Ensure splices are not created if there are not enough frames to crossfade.
4278 TEST_F(SourceBufferStreamTest, Audio_SpliceFrame_NoTinySplices) {
4279 EXPECT_MEDIA_LOG(HasSubstr(
4280 "Skipping splice frame generation: not enough samples for splicing new "
4281 "buffer at 1000us. Have 1000us, but need 2000us."));
4282 4073
4283 SetAudioStream(); 4074 SetAudioStream();
4284 Seek(0); 4075 Seek(0);
4285 4076
4286 // Overlap the range [0, 2) with [1, 3). Since each frame has a duration of 4077 // Make a 2 BufferQueues with a mix of buffers containing of start/end
wolenetz 2016/09/26 23:52:37 nit: Make a 2? containing of?
chcunningham 2016/10/27 23:36:06 Done.
4287 // 2ms this results in an overlap of 1ms between the ranges. A splice frame 4078 // discard. Buffer PTS and duration have been adjusted to reflect discard.
4288 // should not be generated since it requires at least 2 frames, or 2ms in this 4079 // Buffers A will be appended first, then B. The start of B will overlap A
4289 // case, of data to crossfade. 4080 // to generate a splice.
4290 NewCodedFrameGroupAppend("0D2K"); 4081 BufferQueue A_buffers;
4291 CheckExpectedRangesByTimestamp("{ [0,2) }"); 4082 BufferQueue B_buffers;
4292 NewCodedFrameGroupAppend("1D2K"); 4083
4293 CheckExpectedRangesByTimestamp("{ [0,3) }"); 4084 // Buffer A1: PTS = 0, front discard = 2ms, duration = 2ms.
4294 CheckExpectedBuffers("0K 1K"); 4085 scoped_refptr<StreamParserBuffer> bufferA1 = StreamParserBuffer::CopyFrom(
4086 &kDataA, kDataSize, is_keyframe, DemuxerStream::AUDIO, 0);
4087 bufferA1->set_timestamp(base::TimeDelta::FromMilliseconds(0));
4088 bufferA1->set_duration(kDuration / 2);
4089 const DecoderBuffer::DiscardPadding discardA1 =
4090 std::make_pair(kDuration / 2, kNoDiscard);
4091 bufferA1->set_discard_padding(discardA1);
4092 A_buffers.push_back(bufferA1);
4093
4094 // Buffer A2: PTS = 2, end discard = 2ms, duration = 2ms.
4095 scoped_refptr<StreamParserBuffer> bufferA2 = StreamParserBuffer::CopyFrom(
4096 &kDataA, kDataSize, is_keyframe, DemuxerStream::AUDIO, 0);
4097 bufferA2->set_timestamp(base::TimeDelta::FromMilliseconds(2));
4098 bufferA2->set_duration(kDuration / 2);
4099 const DecoderBuffer::DiscardPadding discardA2 =
4100 std::make_pair(kNoDiscard, kDuration / 2);
4101 bufferA2->set_discard_padding(discardA2);
4102 A_buffers.push_back(bufferA2);
4103
4104 // Buffer B1: PTS = 3, front discard = 2ms, duration = 2ms.
4105 scoped_refptr<StreamParserBuffer> bufferB1 = StreamParserBuffer::CopyFrom(
4106 &kDataA, kDataSize, is_keyframe, DemuxerStream::AUDIO, 0);
4107 bufferB1->set_timestamp(base::TimeDelta::FromMilliseconds(3));
4108 bufferB1->set_duration(kDuration / 2);
4109 const DecoderBuffer::DiscardPadding discardB1 =
4110 std::make_pair(kDuration / 2, kNoDiscard);
4111 bufferB1->set_discard_padding(discardB1);
4112 B_buffers.push_back(bufferB1);
4113
4114 // Buffer B2: PTS = 5, no discard padding, duration = 4ms.
4115 scoped_refptr<StreamParserBuffer> bufferB2 = StreamParserBuffer::CopyFrom(
4116 &kDataA, kDataSize, is_keyframe, DemuxerStream::AUDIO, 0);
4117 bufferB2->set_timestamp(base::TimeDelta::FromMilliseconds(5));
4118 bufferB2->set_duration(kDuration);
4119 B_buffers.push_back(bufferB2);
4120
4121 // Append buffers, trigger splice trimming.
4122 stream_->OnStartOfCodedFrameGroup(bufferA1->GetDecodeTimestamp());
4123 stream_->Append(A_buffers);
4124 EXPECT_MEDIA_LOG(TrimmedSpliceOverlap(3000, 2000, 1000));
4125 stream_->Append(B_buffers);
4126
4127 // Verify buffers.
4128 scoped_refptr<StreamParserBuffer> read_buffer;
4129
4130 // Buffer A1 was not spliced, should be unchanged.
4131 EXPECT_EQ(SourceBufferStream::kSuccess, stream_->GetNextBuffer(&read_buffer));
4132 EXPECT_EQ(base::TimeDelta::FromMilliseconds(0), read_buffer->timestamp());
4133 EXPECT_EQ(kDuration / 2, read_buffer->duration());
4134 EXPECT_EQ(discardA1, read_buffer->discard_padding());
4135
4136 // Buffer A2 was overlapped by buffer B1 1ms. Splice trimming should trim A2's
4137 // duration and increase its discard padding by 1ms.
4138 const base::TimeDelta overlap = base::TimeDelta::FromMilliseconds(1);
4139 EXPECT_EQ(SourceBufferStream::kSuccess, stream_->GetNextBuffer(&read_buffer));
4140 EXPECT_EQ(base::TimeDelta::FromMilliseconds(2), read_buffer->timestamp());
4141 EXPECT_EQ((kDuration / 2) - overlap, read_buffer->duration());
4142 const DecoderBuffer::DiscardPadding overlap_discard =
4143 std::make_pair(discardA2.first, discardA2.second + overlap);
4144 EXPECT_EQ(overlap_discard, read_buffer->discard_padding());
4145
4146 // Buffer B1 is overlapping A2, but B1 should be unchanged - splice trimming
4147 // only modifies the earlier buffer (A1).
4148 EXPECT_EQ(SourceBufferStream::kSuccess, stream_->GetNextBuffer(&read_buffer));
4149 EXPECT_EQ(base::TimeDelta::FromMilliseconds(3), read_buffer->timestamp());
4150 EXPECT_EQ(kDuration / 2, read_buffer->duration());
4151 EXPECT_EQ(discardA1, read_buffer->discard_padding());
wolenetz 2016/09/26 23:52:38 nit: s/discardA1/discardB1/
chcunningham 2016/10/27 23:36:06 Done.
4152
4153 // Buffer B2 is not spliced, should be unchanged.
4154 EXPECT_EQ(SourceBufferStream::kSuccess, stream_->GetNextBuffer(&read_buffer));
4155 EXPECT_EQ(base::TimeDelta::FromMilliseconds(5), read_buffer->timestamp());
4156 EXPECT_EQ(kDuration, read_buffer->duration());
4157 EXPECT_EQ(std::make_pair(kNoDiscard, kNoDiscard),
4158 read_buffer->discard_padding());
4159
4295 CheckNoNextBuffer(); 4160 CheckNoNextBuffer();
4296 } 4161 }
4297 4162
4298 TEST_F(SourceBufferStreamTest, Audio_SpliceFrame_NoMillisecondSplices) { 4163 TEST_F(SourceBufferStreamTest, Audio_SpliceFrame_NoMillisecondSplices) {
4299 EXPECT_MEDIA_LOG( 4164 EXPECT_MEDIA_LOG(
4300 HasSubstr("Skipping splice frame generation: not enough samples for " 4165 HasSubstr("Skipping audio splice trimming at PTS=1250us. Found only 250us"
4301 "splicing new buffer at 1250us. Have 750us, but need 1000us.")); 4166 " of overlap, need at least 1000us."));
4302 4167
4303 video_config_ = TestVideoConfig::Invalid(); 4168 video_config_ = TestVideoConfig::Invalid();
4304 audio_config_.Initialize(kCodecVorbis, kSampleFormatPlanarF32, 4169 audio_config_.Initialize(kCodecVorbis, kSampleFormatPlanarF32,
4305 CHANNEL_LAYOUT_STEREO, 4000, EmptyExtraData(), 4170 CHANNEL_LAYOUT_STEREO, 4000, EmptyExtraData(),
4306 Unencrypted(), base::TimeDelta(), 0); 4171 Unencrypted(), base::TimeDelta(), 0);
4307 stream_.reset(new SourceBufferStream(audio_config_, media_log_, true)); 4172 stream_.reset(new SourceBufferStream(audio_config_, media_log_));
4308 // Equivalent to 0.5ms per frame. 4173 // Equivalent to 0.5ms per frame.
4309 SetStreamInfo(2000, 2000); 4174 SetStreamInfo(2000, 2000);
4310 Seek(0); 4175 Seek(0);
4311 4176
4312 // Append four buffers with a 0.5ms duration each. 4177 // Append four buffers with a 0.5ms duration each.
4313 NewCodedFrameGroupAppend(0, 4); 4178 NewCodedFrameGroupAppend(0, 4);
4314 CheckExpectedRangesByTimestamp("{ [0,2) }"); 4179 CheckExpectedRangesByTimestamp("{ [0,2) }");
4315 4180
4316 // Overlap the range [0, 2) with [1.25, 2); this results in an overlap of 4181 // Overlap the range [0, 2) with [1.25, 2); this results in an overlap of
4317 // 0.75ms between the ranges. 4182 // 0.75ms between the ranges.
wolenetz 2016/09/26 23:52:38 nit: s/ranges./ranges, but only 0.25ms end-overlap
chcunningham 2016/10/27 23:36:06 Done, but a little different wording.
4318 NewCodedFrameGroupAppend_OffsetFirstBuffer( 4183 NewCodedFrameGroupAppend_OffsetFirstBuffer(
4319 2, 2, base::TimeDelta::FromMillisecondsD(0.25)); 4184 2, 2, base::TimeDelta::FromMillisecondsD(0.25));
4320 CheckExpectedRangesByTimestamp("{ [0,2) }"); 4185 CheckExpectedRangesByTimestamp("{ [0,2) }");
4321 4186
4322 // A splice frame should not be generated (indicated by the lack of a config 4187 // A splice frame should not be generated (indicated by the lack of a config
wolenetz 2016/09/26 23:52:38 nit: this "lack of config change" would occur even
chcunningham 2016/10/27 23:36:06 Done.
4323 // change in the expected buffer string) since it requires at least 1ms of 4188 // change in the expected buffer string) since it requires at least 1ms of
4324 // data to crossfade. 4189 // data to crossfade.
4325 CheckExpectedBuffers("0K 0K 1K 1K"); 4190 CheckExpectedBuffers("0K 0K 1K 1K");
4326 CheckNoNextBuffer(); 4191 CheckNoNextBuffer();
4327 } 4192 }
4328 4193
4329 TEST_F(SourceBufferStreamTest, Audio_SpliceFrame_Preroll) {
4330 EXPECT_MEDIA_LOG(ContainsGeneratedSpliceLog(3000, 11000));
4331
4332 SetAudioStream();
4333 Seek(0);
4334 NewCodedFrameGroupAppend("0K 2K 4K 6K 8K 10K 12K");
4335 NewCodedFrameGroupAppend("11P 13K 15K 17K");
4336 CheckExpectedBuffers("0K 2K 4K 6K 8K 10K 12K C 11P 13K 15K 17K");
wolenetz 2016/09/26 23:52:37 We should still test that config change across dif
chcunningham 2016/10/27 23:36:06 Done.
4337 CheckNoNextBuffer();
4338 }
4339
4340 TEST_F(SourceBufferStreamTest, Audio_PrerollFrame) { 4194 TEST_F(SourceBufferStreamTest, Audio_PrerollFrame) {
4341 Seek(0); 4195 Seek(0);
4342 NewCodedFrameGroupAppend("0K 3P 6K"); 4196 NewCodedFrameGroupAppend("0K 3P 6K");
4343 CheckExpectedBuffers("0K 3P 6K"); 4197 CheckExpectedBuffers("0K 3P 6K");
4344 CheckNoNextBuffer(); 4198 CheckNoNextBuffer();
4345 } 4199 }
4346 4200
4347 TEST_F(SourceBufferStreamTest, BFrames) { 4201 TEST_F(SourceBufferStreamTest, BFrames) {
4348 Seek(0); 4202 Seek(0);
4349 NewCodedFrameGroupAppend("0K 120|30 30|60 60|90 90|120"); 4203 NewCodedFrameGroupAppend("0K 120|30 30|60 60|90 90|120");
4350 CheckExpectedRangesByTimestamp("{ [0,150) }"); 4204 CheckExpectedRangesByTimestamp("{ [0,150) }");
4351 4205
4352 CheckExpectedBuffers("0K 120|30 30|60 60|90 90|120"); 4206 CheckExpectedBuffers("0K 120|30 30|60 60|90 90|120");
4353 CheckNoNextBuffer(); 4207 CheckNoNextBuffer();
4354 } 4208 }
4355 4209
4356 TEST_F(SourceBufferStreamTest, RemoveShouldAlwaysExcludeEnd) {
4357 NewCodedFrameGroupAppend("10D2K 12D2 14D2");
4358 CheckExpectedRangesByTimestamp("{ [10,16) }");
4359
4360 // Start new coded frame group, appending KF to abut the start of previous
4361 // group.
4362 NewCodedFrameGroupAppend("0D10K");
4363 Seek(0);
4364 CheckExpectedRangesByTimestamp("{ [0,16) }");
4365 CheckExpectedBuffers("0K 10K 12 14");
4366 CheckNoNextBuffer();
wolenetz 2016/09/26 23:52:37 Why remove this?
chcunningham 2016/10/27 23:36:07 See explanation in earlier patch set: https://code
wolenetz 2016/10/28 23:08:19 I see. I commented now on that https://codereview.
4367
4368 // Append another buffer with the same timestamp as the last KF. This triggers
4369 // special logic that allows two buffers to have the same timestamp. When
4370 // preparing for this new append, there is no reason to remove the later GOP
4371 // starting at timestamp 10. This verifies the fix for http://crbug.com/469325
4372 // where the decision *not* to remove the start of the overlapped range was
4373 // erroneously triggering buffers with a timestamp matching the end
4374 // of the append (and any later dependent frames) to be removed.
4375 AppendBuffers("0D10");
4376 Seek(0);
4377 CheckExpectedRangesByTimestamp("{ [0,16) }");
4378 CheckExpectedBuffers("0K 0 10K 12 14");
4379 CheckNoNextBuffer();
4380 }
4381
4382 TEST_F(SourceBufferStreamTest, RefinedDurationEstimates_BackOverlap) { 4210 TEST_F(SourceBufferStreamTest, RefinedDurationEstimates_BackOverlap) {
4383 // Append a few buffers, the last one having estimated duration. 4211 // Append a few buffers, the last one having estimated duration.
4384 NewCodedFrameGroupAppend("0K 5 10 20D10E"); 4212 NewCodedFrameGroupAppend("0K 5 10 20D10E");
4385 CheckExpectedRangesByTimestamp("{ [0,30) }"); 4213 CheckExpectedRangesByTimestamp("{ [0,30) }");
4386 Seek(0); 4214 Seek(0);
4387 CheckExpectedBuffers("0K 5 10 20D10E"); 4215 CheckExpectedBuffers("0K 5 10 20D10E");
4388 CheckNoNextBuffer(); 4216 CheckNoNextBuffer();
4389 4217
4390 // Append a buffer to the end that overlaps the *back* of the existing range. 4218 // Append a buffer to the end that overlaps the *back* of the existing range.
4391 // This should trigger the estimated duration to be recomputed as a timestamp 4219 // This should trigger the estimated duration to be recomputed as a timestamp
(...skipping 428 matching lines...) Expand 10 before | Expand all | Expand 10 after
4820 EXPECT_EQ(base::TimeDelta(), stream_->GetHighestPresentationTimestamp()); 4648 EXPECT_EQ(base::TimeDelta(), stream_->GetHighestPresentationTimestamp());
4821 } 4649 }
4822 4650
4823 // TODO(vrk): Add unit tests where keyframes are unaligned between streams. 4651 // TODO(vrk): Add unit tests where keyframes are unaligned between streams.
4824 // (crbug.com/133557) 4652 // (crbug.com/133557)
4825 4653
4826 // TODO(vrk): Add unit tests with end of stream being called at interesting 4654 // TODO(vrk): Add unit tests with end of stream being called at interesting
4827 // times. 4655 // times.
4828 4656
4829 } // namespace media 4657 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698