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