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) { ...@@ -928,7 +928,7 @@ void SourceBufferStream::Seek(base::TimeDelta timestamp) {
} }
bool SourceBufferStream::IsSeekPending() const { bool SourceBufferStream::IsSeekPending() const {
return !(end_of_stream_ && IsEndSelected()) && seek_pending_; return seek_pending_ && !IsEndOfStreamReached();
} }
void SourceBufferStream::OnSetDuration(base::TimeDelta duration) { void SourceBufferStream::OnSetDuration(base::TimeDelta duration) {
...@@ -1098,9 +1098,11 @@ SourceBufferStream::Status SourceBufferStream::GetNextBufferInternal( ...@@ -1098,9 +1098,11 @@ SourceBufferStream::Status SourceBufferStream::GetNextBufferInternal(
return kSuccess; return kSuccess;
} }
DCHECK(track_buffer_.empty());
if (!selected_range_ || !selected_range_->HasNextBuffer()) { if (!selected_range_ || !selected_range_->HasNextBuffer()) {
if (end_of_stream_ && IsEndSelected()) if (IsEndOfStreamReached()) {
return kEndOfStream; return kEndOfStream;
}
DVLOG(3) << __FUNCTION__ << " " << GetStreamTypeName() DVLOG(3) << __FUNCTION__ << " " << GetStreamTypeName()
<< ": returning kNeedBuffer " << ": returning kNeedBuffer "
<< (selected_range_ ? "(selected range has no next buffer)" << (selected_range_ ? "(selected range has no next buffer)"
...@@ -1205,7 +1207,10 @@ void SourceBufferStream::UnmarkEndOfStream() { ...@@ -1205,7 +1207,10 @@ void SourceBufferStream::UnmarkEndOfStream() {
end_of_stream_ = false; end_of_stream_ = false;
} }
bool SourceBufferStream::IsEndSelected() const { bool SourceBufferStream::IsEndOfStreamReached() const {
if (!end_of_stream_ || !track_buffer_.empty())
return false;
if (ranges_.empty()) if (ranges_.empty())
return true; return true;
...@@ -1215,6 +1220,9 @@ bool SourceBufferStream::IsEndSelected() const { ...@@ -1215,6 +1220,9 @@ bool SourceBufferStream::IsEndSelected() const {
return seek_buffer_timestamp_ >= last_range_end_time; return seek_buffer_timestamp_ >= last_range_end_time;
} }
if (!selected_range_)
return true;
return selected_range_ == ranges_.back(); return selected_range_ == ranges_.back();
} }
......
...@@ -275,9 +275,12 @@ class MEDIA_EXPORT SourceBufferStream { ...@@ -275,9 +275,12 @@ class MEDIA_EXPORT SourceBufferStream {
// stream, and "TEXT" for a text stream. // stream, and "TEXT" for a text stream.
std::string GetStreamTypeName() const; std::string GetStreamTypeName() const;
// Returns true if we don't have any ranges or the last range is selected // Returns true if end of stream has been reached, i.e. the
// or there is a pending seek beyond any existing ranges. // following conditions are met:
bool IsEndSelected() const; // 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_|. // Deletes the range pointed to by |*itr| and removes it from |ranges_|.
// If |*itr| points to |selected_range_|, then |selected_range_| is set to // If |*itr| points to |selected_range_|, then |selected_range_| is set to
......
...@@ -349,6 +349,12 @@ class SourceBufferStreamTest : public testing::Test { ...@@ -349,6 +349,12 @@ class SourceBufferStreamTest : public testing::Test {
EXPECT_EQ(SourceBufferStream::kNeedBuffer, stream_->GetNextBuffer(&buffer)); 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) { void CheckVideoConfig(const VideoDecoderConfig& config) {
const VideoDecoderConfig& actual = stream_->GetCurrentVideoDecoderConfig(); const VideoDecoderConfig& actual = stream_->GetCurrentVideoDecoderConfig();
EXPECT_TRUE(actual.Matches(config)) EXPECT_TRUE(actual.Matches(config))
...@@ -3239,6 +3245,55 @@ TEST_F(SourceBufferStreamTest, ...@@ -3239,6 +3245,55 @@ TEST_F(SourceBufferStreamTest,
CheckExpectedRangesByTimestamp("{ [0,90) }"); 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 // Test the case were the current playback position is at the end of the
// buffered data and several overlaps occur that causes the selected // buffered data and several overlaps occur that causes the selected
// range to get split and then merged back into a single range. // 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