Commit 0fcb1283 authored by landell's avatar landell Committed by Commit bot

Return EOS when selected_range_ is NULL in SourceBufferStream

Fixes the issue where an OnSetDuration call truncates the selected_range_ and resets the
next_buffer_position. kEndOfStream is now returned instead of kNeedBuffer from
GetNextBufferInternal when selected_ranges_ is NULL.

BUG=484992

Review URL: https://codereview.chromium.org/1119163005

Cr-Commit-Position: refs/heads/master@{#329753}
parent 5a6bcfe5
......@@ -928,7 +928,7 @@ void SourceBufferStream::Seek(base::TimeDelta timestamp) {
}
bool SourceBufferStream::IsSeekPending() const {
return !(end_of_stream_ && IsEndSelected()) && seek_pending_;
return seek_pending_ && !IsEndOfStreamReached();
}
void SourceBufferStream::OnSetDuration(base::TimeDelta duration) {
......@@ -1098,9 +1098,11 @@ SourceBufferStream::Status SourceBufferStream::GetNextBufferInternal(
return kSuccess;
}
DCHECK(track_buffer_.empty());
if (!selected_range_ || !selected_range_->HasNextBuffer()) {
if (end_of_stream_ && IsEndSelected())
if (IsEndOfStreamReached()) {
return kEndOfStream;
}
DVLOG(3) << __FUNCTION__ << " " << GetStreamTypeName()
<< ": returning kNeedBuffer "
<< (selected_range_ ? "(selected range has no next buffer)"
......@@ -1205,7 +1207,10 @@ void SourceBufferStream::UnmarkEndOfStream() {
end_of_stream_ = false;
}
bool SourceBufferStream::IsEndSelected() const {
bool SourceBufferStream::IsEndOfStreamReached() const {
if (!end_of_stream_ || !track_buffer_.empty())
return false;
if (ranges_.empty())
return true;
......@@ -1215,6 +1220,9 @@ bool SourceBufferStream::IsEndSelected() const {
return seek_buffer_timestamp_ >= last_range_end_time;
}
if (!selected_range_)
return true;
return selected_range_ == ranges_.back();
}
......
......@@ -275,9 +275,12 @@ class MEDIA_EXPORT SourceBufferStream {
// stream, and "TEXT" for a text stream.
std::string GetStreamTypeName() const;
// Returns true if we don't have any ranges or the last range is selected
// or there is a pending seek beyond any existing ranges.
bool IsEndSelected() const;
// Returns true if end of stream has been reached, i.e. the
// following conditions are met:
// 1. end of stream is marked and there is nothing in the track_buffer.
// 2. We don't have any ranges, or the last or no range is selected,
// or there is a pending seek beyond any existing ranges.
bool IsEndOfStreamReached() const;
// Deletes the range pointed to by |*itr| and removes it from |ranges_|.
// If |*itr| points to |selected_range_|, then |selected_range_| is set to
......
......@@ -349,6 +349,12 @@ class SourceBufferStreamTest : public testing::Test {
EXPECT_EQ(SourceBufferStream::kNeedBuffer, stream_->GetNextBuffer(&buffer));
}
void CheckEOSReached() {
scoped_refptr<StreamParserBuffer> buffer;
EXPECT_EQ(SourceBufferStream::kEndOfStream,
stream_->GetNextBuffer(&buffer));
}
void CheckVideoConfig(const VideoDecoderConfig& config) {
const VideoDecoderConfig& actual = stream_->GetCurrentVideoDecoderConfig();
EXPECT_TRUE(actual.Matches(config))
......@@ -3239,6 +3245,55 @@ TEST_F(SourceBufferStreamTest,
CheckExpectedRangesByTimestamp("{ [0,90) }");
}
TEST_F(SourceBufferStreamTest, SetExplicitDuration_MarkEOS) {
// Append 1 buffer at positions 0 through 8.
NewSegmentAppend(0, 9);
// Check expected ranges.
CheckExpectedRanges("{ [0,8) }");
// Seek to 5.
Seek(5);
// Set duration to be before the seeked to position.
// This will result in truncation of the selected range and a reset
// of NextBufferPosition.
stream_->OnSetDuration(frame_duration() * 4);
// Check the expected ranges.
CheckExpectedRanges("{ [0,3) }");
// Mark EOS reached.
stream_->MarkEndOfStream();
// Expect EOS to be reached.
CheckEOSReached();
}
TEST_F(SourceBufferStreamTest, SetExplicitDuration_MarkEOS_IsSeekPending) {
// Append 1 buffer at positions 0 through 8.
NewSegmentAppend(0, 9);
// Check expected ranges.
CheckExpectedRanges("{ [0,8) }");
// Seek to 9 which will result in a pending seek.
Seek(9);
// Set duration to be before the seeked to position.
// This will result in truncation of the selected range and a reset
// of NextBufferPosition.
stream_->OnSetDuration(frame_duration() * 4);
// Check the expected ranges.
CheckExpectedRanges("{ [0,3) }");
EXPECT_TRUE(stream_->IsSeekPending());
// Mark EOS reached.
stream_->MarkEndOfStream();
EXPECT_FALSE(stream_->IsSeekPending());
}
// Test the case were the current playback position is at the end of the
// buffered data and several overlaps occur that causes the selected
// range to get split and then merged back into a single range.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment