Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1003)

Unified Diff: media/filters/source_buffer_stream.cc

Issue 125543002: Add plumbing and support for crossfading StreamParserBuffers. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: There and back again. Created 6 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: media/filters/source_buffer_stream.cc
diff --git a/media/filters/source_buffer_stream.cc b/media/filters/source_buffer_stream.cc
index 20e9156ad02e207ed8b676deac038553d6cafdeb..3d8a6c21586574c7faa7ee7f2f99c3992a69b968 100644
--- a/media/filters/source_buffer_stream.cc
+++ b/media/filters/source_buffer_stream.cc
@@ -341,7 +341,8 @@ SourceBufferStream::SourceBufferStream(const AudioDecoderConfig& audio_config,
last_output_buffer_timestamp_(kNoTimestamp()),
max_interbuffer_distance_(kNoTimestamp()),
memory_limit_(kDefaultAudioMemoryLimit),
- config_change_pending_(false) {
+ config_change_pending_(false),
+ fade_out_preroll_index_(0) {
DCHECK(audio_config.IsValidConfig());
audio_configs_.push_back(audio_config);
}
@@ -363,7 +364,8 @@ SourceBufferStream::SourceBufferStream(const VideoDecoderConfig& video_config,
last_output_buffer_timestamp_(kNoTimestamp()),
max_interbuffer_distance_(kNoTimestamp()),
memory_limit_(kDefaultVideoMemoryLimit),
- config_change_pending_(false) {
+ config_change_pending_(false),
+ fade_out_preroll_index_(0) {
DCHECK(video_config.IsValidConfig());
video_configs_.push_back(video_config);
}
@@ -386,7 +388,8 @@ SourceBufferStream::SourceBufferStream(const TextTrackConfig& text_config,
last_output_buffer_timestamp_(kNoTimestamp()),
max_interbuffer_distance_(kNoTimestamp()),
memory_limit_(kDefaultAudioMemoryLimit),
- config_change_pending_(false) {
+ config_change_pending_(false),
+ fade_out_preroll_index_(0) {
}
SourceBufferStream::~SourceBufferStream() {
@@ -670,6 +673,8 @@ void SourceBufferStream::ResetSeekState() {
track_buffer_.clear();
config_change_pending_ = false;
last_output_buffer_timestamp_ = kNoTimestamp();
+ fade_out_preroll_index_ = 0;
+ fade_in_buffer_ = NULL;
}
bool SourceBufferStream::ShouldSeekToStartOfBuffered(
@@ -1092,17 +1097,78 @@ void SourceBufferStream::OnSetDuration(base::TimeDelta duration) {
SourceBufferStream::Status SourceBufferStream::GetNextBuffer(
scoped_refptr<StreamParserBuffer>* out_buffer) {
+ if (!fade_in_buffer_) {
+ const SourceBufferStream::Status status = GetNextBufferInternal(out_buffer);
+
+ // Just return if GetNextBufferInternal() failed or there's no fade out
+ // preroll, there's nothing else to do.
+ if (status != SourceBufferStream::kSuccess ||
+ (*out_buffer)->GetFadeOutPreroll().empty()) {
+ return status;
+ }
+
+ // Setup fade in buffer and fall through into splice frame buffer handling.
+ fade_out_preroll_index_ = 0;
+ fade_in_buffer_ = *out_buffer;
+ }
+
+ DCHECK(fade_in_buffer_);
+ const std::vector<scoped_refptr<StreamParserBuffer> >& fade_out_preroll =
+ fade_in_buffer_->GetFadeOutPreroll();
+
+ // Are there any fade out buffers left to hand out?
+ if (fade_out_preroll_index_ < fade_out_preroll.size()) {
+ // Account for config changes which occur between fade out buffers.
+ if (current_config_index_ !=
+ fade_out_preroll.at(fade_out_preroll_index_)->GetConfigId()) {
+ config_change_pending_ = true;
+ DVLOG(1) << "Config change (fade out preroll config ID does not match).";
+ return SourceBufferStream::kConfigChange;
+ }
+
+ *out_buffer = fade_out_preroll.at(fade_out_preroll_index_++);
+ return SourceBufferStream::kSuccess;
+ }
+
+ // Did we hand out the last fade out buffer on the last call?
+ if (fade_out_preroll_index_ == fade_out_preroll.size()) {
+ fade_out_preroll_index_++;
+ config_change_pending_ = true;
+ DVLOG(1) << "Config change (forced for fade in of splice frame).";
+ return SourceBufferStream::kConfigChange;
+ }
+
+ // All fade out buffers have been handed out and a config change completed, so
+ // hand out the final buffer for fade in. Because a config change has already
+ // been issued, we don't need to account for
acolwell GONE FROM CHROMIUM 2014/01/10 22:53:31 nit: Finish the sentence. :)
DaleCurtis 2014/01/10 23:03:49 Haha, awesome, I accidentally a sentence.
+ DCHECK_GT(fade_out_preroll_index_, fade_out_preroll.size());
+ *out_buffer = fade_in_buffer_;
+ fade_in_buffer_ = NULL;
+ fade_out_preroll_index_ = 0;
+ return SourceBufferStream::kSuccess;
+}
+
+SourceBufferStream::Status SourceBufferStream::GetNextBufferInternal(
+ scoped_refptr<StreamParserBuffer>* out_buffer) {
CHECK(!config_change_pending_);
if (!track_buffer_.empty()) {
DCHECK(!selected_range_);
- if (track_buffer_.front()->GetConfigId() != current_config_index_) {
+ scoped_refptr<StreamParserBuffer>& next_buffer = track_buffer_.front();
+
+ // If the next buffer is an audio splice frame, the next effective config id
+ // comes from the first fade out preroll buffer.
+ const int next_config_id = next_buffer->GetFadeOutPreroll().empty() ?
+ next_buffer->GetConfigId() :
+ next_buffer->GetFadeOutPreroll().at(0)->GetConfigId();
acolwell GONE FROM CHROMIUM 2014/01/10 22:53:31 nit: Any reason you can't use the [0] instead of .
DaleCurtis 2014/01/10 23:03:49 I switched to .at() since that seemed to be the st
+
+ if (next_config_id != current_config_index_) {
config_change_pending_ = true;
DVLOG(1) << "Config change (track buffer config ID does not match).";
return kConfigChange;
}
- *out_buffer = track_buffer_.front();
+ *out_buffer = next_buffer;
track_buffer_.pop_front();
last_output_buffer_timestamp_ = (*out_buffer)->GetDecodeTimestamp();
@@ -1338,6 +1404,15 @@ bool SourceBufferStream::UpdateVideoConfig(const VideoDecoderConfig& config) {
void SourceBufferStream::CompleteConfigChange() {
config_change_pending_ = false;
+ if (fade_in_buffer_) {
+ const std::vector<scoped_refptr<StreamParserBuffer> >& fade_out_preroll =
+ fade_in_buffer_->GetFadeOutPreroll();
+ current_config_index_ = fade_out_preroll_index_ < fade_out_preroll.size() ?
+ fade_out_preroll.at(fade_out_preroll_index_)->GetConfigId() :
+ fade_in_buffer_->GetConfigId();
+ return;
+ }
+
if (!track_buffer_.empty()) {
current_config_index_ = track_buffer_.front()->GetConfigId();
return;
@@ -1858,7 +1933,13 @@ bool SourceBufferRange::HasNextBuffer() const {
int SourceBufferRange::GetNextConfigId() const {
DCHECK(HasNextBuffer());
- return buffers_.at(next_buffer_index_)->GetConfigId();
+ const scoped_refptr<StreamParserBuffer>& next_buffer =
+ buffers_.at(next_buffer_index_);
+ // If the next buffer is an audio splice frame, the next effective config id
+ // comes from the first fade out preroll buffer.
+ return next_buffer->GetFadeOutPreroll().empty() ?
+ next_buffer->GetConfigId() :
+ next_buffer->GetFadeOutPreroll().at(0)->GetConfigId();
}
base::TimeDelta SourceBufferRange::GetNextTimestamp() const {
« media/filters/source_buffer_stream.h ('K') | « media/filters/source_buffer_stream.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698