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) |