| 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 87509c29cc16cde66daf2da70ec2c90b8f6a84d4..610e78d75866dcca5ada51b9333b61fdbf80f040 100644
|
| --- a/media/filters/source_buffer_stream_unittest.cc
|
| +++ b/media/filters/source_buffer_stream_unittest.cc
|
| @@ -293,6 +293,17 @@ class SourceBufferStreamTest : public testing::Test {
|
| ss << "|" << buffer->GetDecodeTimestamp().InMilliseconds();
|
| }
|
|
|
| + // Check duration if expected timestamp contains it.
|
| + if (timestamps[i].find('D') != std::string::npos) {
|
| + ss << "D" << buffer->duration().InMilliseconds();
|
| + }
|
| +
|
| + // Check duration estimation if expected timestamp contains it.
|
| + if (timestamps[i].find('E') != std::string::npos &&
|
| + buffer->is_duration_estimated()) {
|
| + ss << "E";
|
| + }
|
| +
|
| // Handle preroll buffers.
|
| if (EndsWith(timestamps[i], "P", true)) {
|
| ASSERT_TRUE(buffer->is_key_frame());
|
| @@ -427,9 +438,12 @@ class SourceBufferStreamTest : public testing::Test {
|
| }
|
|
|
| // StringToBufferQueue() allows for the generation of StreamParserBuffers from
|
| - // coded strings of timestamps separated by spaces. Supported syntax:
|
| + // coded strings of timestamps separated by spaces.
|
| //
|
| - // xx:
|
| + // Supported syntax (options must be in this order):
|
| + // pp[|dd][Dzz][E][P][K]
|
| + //
|
| + // pp:
|
| // Generates a StreamParserBuffer with decode and presentation timestamp xx.
|
| // E.g., "0 1 2 3".
|
| //
|
| @@ -437,19 +451,26 @@ class SourceBufferStreamTest : public testing::Test {
|
| // Generates a StreamParserBuffer with presentation timestamp pp and decode
|
| // timestamp dd. E.g., "0|0 3|1 1|2 2|3".
|
| //
|
| - // ##Dzz
|
| - // Specifies the duration for a buffer. ## represents one of the 2 timestamp
|
| - // formats above. zz specifies the duration of the buffer in milliseconds.
|
| - // If the duration isn't specified with this syntax then the buffer duration
|
| - // is determined by the difference between the decode timestamp in ## and
|
| - // the decode timestamp of the previous buffer in the string. If the string
|
| - // only contains 1 buffer then the duration must be explicitly specified with
|
| - // this format.
|
| + // Dzz
|
| + // Explicitly describe the duration of the buffer. zz specifies the duration
|
| + // in milliseconds. If the duration isn't specified with this syntax, the
|
| + // duration is derived using the timestamp delta between this buffer and the
|
| + // next buffer. If not specified, the final buffer will simply copy the
|
| + // duration of the previous buffer. If the queue only contains 1 buffer then
|
| + // the duration must be explicitly specified with this format.
|
| + // E.g. "0D10 10D20"
|
| + //
|
| + // E:
|
| + // Indicates that the buffer should be marked as containing an *estimated*
|
| + // duration. E.g., "0D20E 20 25E 30"
|
| //
|
| - // ##K:
|
| - // Indicates the buffer with timestamp ## reflects a keyframe. ##
|
| - // can be any of the 3 timestamp formats above.
|
| - // E.g., "0K 1|2K 2|4D2K".
|
| + // P:
|
| + // Indicates the buffer with will also have a preroll buffer
|
| + // associated with it. The preroll buffer will just be dummy data.
|
| + // E.g. "0P 5 10"
|
| + //
|
| + // K:
|
| + // Indicates the buffer is a keyframe. E.g., "0K 1|2K 2|4D2K 6 8".
|
| //
|
| // S(a# ... y# z#)
|
| // Indicates a splice frame buffer should be created with timestamp z#. The
|
| @@ -471,6 +492,8 @@ class SourceBufferStreamTest : public testing::Test {
|
| bool is_keyframe = false;
|
| bool has_preroll = false;
|
| bool last_splice_frame = false;
|
| + bool is_duration_estimated = false;
|
| +
|
| // Handle splice frame starts.
|
| if (StartsWithASCII(timestamps[i], "S(", true)) {
|
| CHECK(!splice_frame);
|
| @@ -505,6 +528,12 @@ class SourceBufferStreamTest : public testing::Test {
|
| timestamps[i] = timestamps[i].substr(0, timestamps[i].length() - 1);
|
| }
|
|
|
| + if (EndsWith(timestamps[i], "E", true)) {
|
| + is_duration_estimated = true;
|
| + // Remove the "E" off of the token.
|
| + timestamps[i] = timestamps[i].substr(0, timestamps[i].length() - 1);
|
| + }
|
| +
|
| int duration_in_ms = 0;
|
| size_t duration_pos = timestamps[i].find('D');
|
| if (duration_pos != std::string::npos) {
|
| @@ -531,6 +560,7 @@ class SourceBufferStreamTest : public testing::Test {
|
| StreamParserBuffer::CopyFrom(&kDataA, kDataSize, is_keyframe,
|
| DemuxerStream::AUDIO, 0);
|
| buffer->set_timestamp(base::TimeDelta::FromMilliseconds(pts_in_ms));
|
| + buffer->set_is_duration_estimated(is_duration_estimated);
|
|
|
| if (dts_in_ms != pts_in_ms) {
|
| buffer->SetDecodeTimestamp(
|
| @@ -3959,6 +3989,58 @@ TEST_F(SourceBufferStreamTest, RemoveShouldAlwaysExcludeEnd) {
|
| CheckNoNextBuffer();
|
| }
|
|
|
| +TEST_F(SourceBufferStreamTest, RefinedDurationEstimates_BackOverlap) {
|
| + // Append a few buffers, the last one having estimated duration.
|
| + NewSegmentAppend("0K 5 10 20D10E");
|
| + CheckExpectedRangesByTimestamp("{ [0,30) }");
|
| + Seek(0);
|
| + CheckExpectedBuffers("0K 5 10 20D10E");
|
| + CheckNoNextBuffer();
|
| +
|
| + // Append a buffer to the end that overlaps the *back* of the existing range.
|
| + // This should trigger the estimated duration to be recomputed as a timestamp
|
| + // delta.
|
| + AppendBuffers("25D10");
|
| + CheckExpectedRangesByTimestamp("{ [0,35) }");
|
| + Seek(0);
|
| + // The duration of the buffer at time 20 has changed from 10ms to 5ms.
|
| + CheckExpectedBuffers("0K 5 10 20D5E 25");
|
| + CheckNoNextBuffer();
|
| +
|
| + // If the last buffer is removed, the adjusted duration should remain at 5ms.
|
| + RemoveInMs(25, 35, 35);
|
| + CheckExpectedRangesByTimestamp("{ [0,25) }");
|
| + Seek(0);
|
| + CheckExpectedBuffers("0K 5 10 20D5E");
|
| + CheckNoNextBuffer();
|
| +}
|
| +
|
| +TEST_F(SourceBufferStreamTest, RefinedDurationEstimates_FrontOverlap) {
|
| + // Append a few buffers.
|
| + NewSegmentAppend("10K 15 20D5");
|
| + CheckExpectedRangesByTimestamp("{ [10,25) }");
|
| + SeekToTimestamp(base::TimeDelta::FromMilliseconds(10));
|
| + CheckExpectedBuffers("10K 15 20");
|
| + CheckNoNextBuffer();
|
| +
|
| + // Append new buffers, where the last has estimated duration that overlaps the
|
| + // *front* of the existing range. The overlap should trigger refinement of the
|
| + // estimated duration from 7ms to 5ms.
|
| + NewSegmentAppend("0K 5D7E");
|
| + CheckExpectedRangesByTimestamp("{ [0,25) }");
|
| + Seek(0);
|
| + CheckExpectedBuffers("0K 5D5E 10K 15 20");
|
| + CheckNoNextBuffer();
|
| +
|
| + // If the overlapped buffer at timestamp 10 is removed, the adjusted duration
|
| + // should remain adjusted.
|
| + RemoveInMs(10, 20, 25);
|
| + CheckExpectedRangesByTimestamp("{ [0,10) }");
|
| + Seek(0);
|
| + CheckExpectedBuffers("0K 5D5E");
|
| + CheckNoNextBuffer();
|
| +}
|
| +
|
| // TODO(vrk): Add unit tests where keyframes are unaligned between streams.
|
| // (crbug.com/133557)
|
|
|
|
|