Chromium Code Reviews| Index: media/filters/source_buffer_stream_unittest.cc |
| diff --git a/media/filters/source_buffer_stream_unittest.cc b/media/filters/source_buffer_stream_unittest.cc |
| index 96b1826bfbaadfcb89c0d96d999e5e7995515e81..edbda87460acbdd030f56934b36c677b0024a6ef 100644 |
| --- a/media/filters/source_buffer_stream_unittest.cc |
| +++ b/media/filters/source_buffer_stream_unittest.cc |
| @@ -7,6 +7,9 @@ |
| #include <string> |
| #include "base/logging.h" |
| +#include "base/string_number_conversions.h" |
| +#include "base/string_split.h" |
| +#include "base/string_util.h" |
| #include "media/base/data_buffer.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| @@ -74,10 +77,22 @@ class SourceBufferStreamTest : public testing::Test { |
| base::TimeDelta(), true, data, kDataSize); |
| } |
| + void NewSegmentAppendOneByOne(const std::string& buffers_to_append) { |
| + AppendBuffersOneByOne(buffers_to_append, true); |
| + } |
| + |
| + void AppendBuffersOneByOne(const std::string& buffers_to_append) { |
| + AppendBuffersOneByOne(buffers_to_append, false); |
| + } |
| + |
| void Seek(int position) { |
| stream_->Seek(position * frame_duration_); |
| } |
| + void SeekToTimestamp(base::TimeDelta timestamp) { |
| + stream_->Seek(timestamp); |
| + } |
| + |
| void CheckExpectedRanges(const std::string& expected) { |
| Ranges<base::TimeDelta> r = stream_->GetBufferedTime(); |
| @@ -92,6 +107,20 @@ class SourceBufferStreamTest : public testing::Test { |
| EXPECT_EQ(ss.str(), expected); |
|
acolwell GONE FROM CHROMIUM
2012/09/19 23:15:51
nit: flip
vrk (LEFT CHROMIUM)
2012/09/20 00:00:59
Done.
|
| } |
| + void CheckExpectedRangesByTimestamp(const std::string& expected) { |
| + Ranges<base::TimeDelta> r = stream_->GetBufferedTime(); |
| + |
| + std::stringstream ss; |
| + ss << "{ "; |
| + for (size_t i = 0; i < r.size(); ++i) { |
| + int64 start = r.start(i).InMilliseconds(); |
| + int64 end = r.end(i).InMilliseconds(); |
| + ss << "[" << start << "," << end << ") "; |
| + } |
| + ss << "}"; |
| + EXPECT_EQ(ss.str(), expected); |
|
acolwell GONE FROM CHROMIUM
2012/09/19 23:15:51
nit: flip
vrk (LEFT CHROMIUM)
2012/09/20 00:00:59
Done.
|
| + } |
| + |
| void CheckExpectedBuffers( |
| int starting_position, int ending_position) { |
| CheckExpectedBuffers(starting_position, ending_position, false, NULL, 0); |
| @@ -147,6 +176,25 @@ class SourceBufferStreamTest : public testing::Test { |
| EXPECT_EQ(ending_position + 1, current_position); |
| } |
| + void CheckExpectedBuffers(const std::string& expected) { |
| + std::vector<std::string> timestamps; |
| + base::SplitString(expected, ' ', ×tamps); |
| + for (size_t i = 0; i < timestamps.size(); i++) { |
| + scoped_refptr<StreamParserBuffer> buffer; |
| + SourceBufferStream::Status status = stream_->GetNextBuffer(&buffer); |
| + |
| + EXPECT_EQ(status, SourceBufferStream::kSuccess); |
|
acolwell GONE FROM CHROMIUM
2012/09/19 23:15:51
nit:flip order.
vrk (LEFT CHROMIUM)
2012/09/20 00:00:59
Done.
|
| + if (status != SourceBufferStream::kSuccess) |
| + break; |
| + |
| + std::stringstream ss; |
| + ss << buffer->GetDecodeTimestamp().InMilliseconds(); |
| + if (buffer->IsKeyframe()) |
| + ss << "K"; |
| + EXPECT_EQ(ss.str(), timestamps[i]); |
|
acolwell GONE FROM CHROMIUM
2012/09/19 23:15:51
nit:ditto
vrk (LEFT CHROMIUM)
2012/09/20 00:00:59
Done.
|
| + } |
| + } |
| + |
| void CheckNoNextBuffer() { |
| scoped_refptr<StreamParserBuffer> buffer; |
| EXPECT_EQ(stream_->GetNextBuffer(&buffer), SourceBufferStream::kNeedBuffer); |
| @@ -215,6 +263,39 @@ class SourceBufferStreamTest : public testing::Test { |
| EXPECT_EQ(expect_success, stream_->Append(queue)); |
| } |
| + void AppendBuffersOneByOne(const std::string& buffers_to_append, |
| + bool start_new_segment) { |
| + std::vector<std::string> timestamps; |
| + base::SplitString(buffers_to_append, ' ', ×tamps); |
| + |
| + CHECK_GT(timestamps.size(), 0u); |
| + |
| + for (size_t i = 0; i < timestamps.size(); i++) { |
| + bool is_keyframe = false; |
| + if (EndsWith(timestamps[i], "K", true)) { |
| + is_keyframe = true; |
| + // Remove the "K" off of the token. |
| + timestamps[i] = timestamps[i].substr(0, timestamps[i].length() - 1); |
| + } |
| + int time_in_ms; |
| + CHECK(base::StringToInt(timestamps[i], &time_in_ms)); |
| + |
| + // Create buffer. |
| + scoped_refptr<StreamParserBuffer> buffer = |
| + StreamParserBuffer::CopyFrom(NULL, 0, is_keyframe); |
|
acolwell GONE FROM CHROMIUM
2012/09/19 23:15:51
nit: use kDataA & sizeof(kDataA) instead of NULL,0
vrk (LEFT CHROMIUM)
2012/09/20 00:00:59
Done.
|
| + base::TimeDelta timestamp = |
| + base::TimeDelta::FromMilliseconds(time_in_ms); |
| + buffer->SetDecodeTimestamp(timestamp); |
| + |
| + if (i == 0u && start_new_segment) |
| + stream_->OnNewMediaSegment(timestamp); |
| + |
| + SourceBufferStream::BufferQueue queue; |
| + queue.push_back(buffer); |
| + EXPECT_TRUE(stream_->Append(queue)); |
| + } |
| + } |
| + |
| int frames_per_second_; |
| int keyframes_per_second_; |
| base::TimeDelta frame_duration_; |
| @@ -1084,6 +1165,82 @@ TEST_F(SourceBufferStreamTest, Middle_Overlap_Selected_4) { |
| CheckExpectedBuffers(10, 14, &kDataA); |
| } |
| +TEST_F(SourceBufferStreamTest, Overlap_OneByOne) { |
| + // Append 5 buffers starting at 10ms, 30ms apart. |
| + NewSegmentAppendOneByOne("10K 40 70 100 130"); |
| + |
| + // The range ends at 160, accounting for the last buffer's duration. |
| + CheckExpectedRangesByTimestamp("{ [10,160) }"); |
| + |
| + // Overlap with 10 buffers starting at the beginning, appended one at a |
| + // time. |
| + NewSegmentAppend(0, 1, &kDataB); |
| + for (int i = 1; i < 10; i++) |
| + AppendBuffers(i, 1, &kDataB); |
| + |
| + // All data should be replaced. |
| + Seek(0); |
| + CheckExpectedRanges("{ [0,9) }"); |
| + CheckExpectedBuffers(0, 9, &kDataB); |
| +} |
| + |
| +TEST_F(SourceBufferStreamTest, Overlap_OneByOne_DeleteGroup) { |
| + NewSegmentAppendOneByOne("10K 40 70 100 130K"); |
| + CheckExpectedRangesByTimestamp("{ [10,160) }"); |
| + |
| + // Seek to 130ms. |
| + SeekToTimestamp(base::TimeDelta::FromMilliseconds(130)); |
| + |
| + // Overlap with a new segment from 0 to 120ms. |
| + NewSegmentAppendOneByOne("0K 120"); |
| + |
| + // Next buffer should still be 130ms. |
| + CheckExpectedBuffers("130K"); |
| + |
| + // Check the final buffers is correct. |
| + SeekToTimestamp(base::TimeDelta::FromMilliseconds(0)); |
| + CheckExpectedBuffers("0K 120 130K"); |
| +} |
| + |
| +TEST_F(SourceBufferStreamTest, Overlap_OneByOne_BetweenMediaSegments) { |
| + // Append 5 buffers starting at 110ms, 30ms apart. |
| + NewSegmentAppendOneByOne("110K 140 170 200 230"); |
| + CheckExpectedRangesByTimestamp("{ [110,260) }"); |
| + |
| + // Now append 2 media segments from 0ms to 210ms, 30ms apart. Note that the |
| + // old keyframe 110ms falls in between these two segments. |
| + NewSegmentAppendOneByOne("0K 30 60 90"); |
| + NewSegmentAppendOneByOne("120K 150 180 210"); |
| + CheckExpectedRangesByTimestamp("{ [0,240) }"); |
| + |
| + // Check the final buffers is correct; the keyframe at 110ms should be |
| + // deleted. |
| + SeekToTimestamp(base::TimeDelta::FromMilliseconds(0)); |
| + CheckExpectedBuffers("0K 30 60 90 120K 150 180 210"); |
| +} |
| + |
| +TEST_F(SourceBufferStreamTest, Overlap_OneByOne_TrackBuffer) { |
| + NewSegmentAppendOneByOne("10K 40 70 100K 125 130K"); |
| + CheckExpectedRangesByTimestamp("{ [10,160) }"); |
| + |
| + // Seek to 70ms. |
| + SeekToTimestamp(base::TimeDelta::FromMilliseconds(10)); |
| + CheckExpectedBuffers("10K 40"); |
| + |
| + // Overlap with a new segment from 0 to 120ms. |
| + NewSegmentAppendOneByOne("0K 30 60 90 120K"); |
| + CheckExpectedRangesByTimestamp("{ [0,160) }"); |
| + |
| + // Should return frames 70ms and 100ms from the track buffer, then switch |
| + // to the new data at 120K, then switch back to the old data at 130K. The |
| + // frame at 125ms that depended on keyframe 100ms should have been deleted. |
| + CheckExpectedBuffers("70 100K 120K 130K"); |
| + |
| + // Check the final result: should not include data from the track buffer. |
| + SeekToTimestamp(base::TimeDelta::FromMilliseconds(0)); |
| + CheckExpectedBuffers("0K 30 60 90 120K 130K"); |
| +} |
| + |
| TEST_F(SourceBufferStreamTest, Seek_Keyframe) { |
| // Append 6 buffers at positions 0 through 5. |
| NewSegmentAppend(0, 6); |