Chromium Code Reviews| Index: media/filters/chunk_demuxer.cc |
| diff --git a/media/filters/chunk_demuxer.cc b/media/filters/chunk_demuxer.cc |
| index 203c91407ab700c8f5c46b894f21077b0f48e3cb..f9f0573872e0ede6e52ecab8b7ce7d40b22e9841 100644 |
| --- a/media/filters/chunk_demuxer.cc |
| +++ b/media/filters/chunk_demuxer.cc |
| @@ -192,6 +192,7 @@ class ChunkDemuxerStream : public DemuxerStream { |
| enum State { |
| RETURNING_DATA_FOR_READS, |
| WAITING_FOR_SEEK, |
| + CONFIG_CHANGE, |
| SHUTDOWN, |
| }; |
| @@ -206,6 +207,11 @@ class ChunkDemuxerStream : public DemuxerStream { |
| // |buffers_| and pops the callbacks & buffers from the respecive queues. |
| void CreateReadDoneClosures_Locked(ClosureQueue* closures); |
| + // Called when audio_decoder_config() or video_decoder_config() is called. |
| + // This method handles transitioning from |
| + // CONFIG_CHANGE to RETURNING_DATA_FOR_READS if necessary. |
| + void OnConfigRequest(); |
| + |
| // Specifies the type of the stream (must be AUDIO or VIDEO for now). |
| Type type_; |
| @@ -294,46 +300,13 @@ Ranges<TimeDelta> ChunkDemuxerStream::GetBufferedRanges() { |
| bool ChunkDemuxerStream::UpdateAudioConfig(const AudioDecoderConfig& config) { |
| DCHECK(config.IsValidConfig()); |
| DCHECK_EQ(type_, AUDIO); |
| - |
| - const AudioDecoderConfig& current_config = |
| - stream_->GetCurrentAudioDecoderConfig(); |
| - |
| - bool success = (current_config.codec() == config.codec()) && |
| - (current_config.bits_per_channel() == config.bits_per_channel()) && |
| - (current_config.channel_layout() == config.channel_layout()) && |
| - (current_config.samples_per_second() == config.samples_per_second()) && |
| - (current_config.extra_data_size() == config.extra_data_size()) && |
| - (!current_config.extra_data() || |
| - !memcmp(current_config.extra_data(), config.extra_data(), |
| - current_config.extra_data_size())); |
| - |
| - if (!success) |
| - DVLOG(1) << "UpdateAudioConfig() : Failed to update audio config."; |
| - |
| - return success; |
| + return stream_->UpdateAudioConfig(config); |
| } |
| bool ChunkDemuxerStream::UpdateVideoConfig(const VideoDecoderConfig& config) { |
| DCHECK(config.IsValidConfig()); |
| DCHECK_EQ(type_, VIDEO); |
| - const VideoDecoderConfig& current_config = |
| - stream_->GetCurrentVideoDecoderConfig(); |
| - |
| - bool success = (current_config.codec() == config.codec()) && |
| - (current_config.format() == config.format()) && |
| - (current_config.profile() == config.profile()) && |
| - (current_config.coded_size() == config.coded_size()) && |
| - (current_config.visible_rect() == config.visible_rect()) && |
| - (current_config.natural_size() == config.natural_size()) && |
| - (current_config.extra_data_size() == config.extra_data_size()) && |
| - (!current_config.extra_data() || |
| - !memcmp(current_config.extra_data(), config.extra_data(), |
| - current_config.extra_data_size())); |
| - |
| - if (!success) |
| - DVLOG(1) << "UpdateVideoConfig() : Failed to update video config."; |
| - |
| - return success; |
| + return stream_->UpdateVideoConfig(config); |
| } |
| void ChunkDemuxerStream::EndOfStream() { |
| @@ -392,10 +365,23 @@ void ChunkDemuxerStream::Read(const ReadCB& read_cb) { |
| case RETURNING_DATA_FOR_READS: |
| // If we already have pending reads or we don't have any buffers ready, |
| // then defer this read. |
| - if (!read_cbs_.empty() || !stream_->GetNextBuffer(&buffer)) { |
| + if (!read_cbs_.empty()) { |
| DeferRead_Locked(read_cb); |
| return; |
| } |
| + |
| + switch (stream_->GetNextBuffer(&buffer)) { |
| + case SourceBufferStream::kSuccess: |
| + // Do nothing and continue |
|
vrk (LEFT CHROMIUM)
2012/07/12 19:37:55
nit: period at end
acolwell GONE FROM CHROMIUM
2012/07/12 23:07:58
Done.
|
| + break; |
| + case SourceBufferStream::kNeedBuffer: |
| + DeferRead_Locked(read_cb); |
| + return; |
| + case SourceBufferStream::kConfigChange: |
| + ChangeState_Locked(CONFIG_CHANGE); |
| + status = kConfigChanged; |
| + break; |
| + } |
| break; |
| case WAITING_FOR_SEEK: |
| // Null buffers should be returned in this state since we are waiting |
| @@ -404,6 +390,10 @@ void ChunkDemuxerStream::Read(const ReadCB& read_cb) { |
| DCHECK(read_cbs_.empty()); |
| status = kAborted; |
| break; |
| + case CONFIG_CHANGE: |
| + DCHECK(read_cbs_.empty()); |
| + status = kConfigChanged; |
| + break; |
| case SHUTDOWN: |
| DCHECK(read_cbs_.empty()); |
| buffer = StreamParserBuffer::CreateEOSBuffer(); |
| @@ -420,17 +410,30 @@ void ChunkDemuxerStream::EnableBitstreamConverter() {} |
| const AudioDecoderConfig& ChunkDemuxerStream::audio_decoder_config() { |
|
vrk (LEFT CHROMIUM)
2012/07/12 19:37:55
nit: {audio,video}_decoder_config() does more than
|
| CHECK_EQ(type_, AUDIO); |
| base::AutoLock auto_lock(lock_); |
| + OnConfigRequest(); |
| return stream_->GetCurrentAudioDecoderConfig(); |
| } |
| const VideoDecoderConfig& ChunkDemuxerStream::video_decoder_config() { |
| CHECK_EQ(type_, VIDEO); |
| base::AutoLock auto_lock(lock_); |
| + OnConfigRequest(); |
| return stream_->GetCurrentVideoDecoderConfig(); |
| } |
| +void ChunkDemuxerStream::OnConfigRequest() { |
| + lock_.AssertAcquired(); |
| + if (state_ == CONFIG_CHANGE) { |
| + stream_->UpdateCurrentConfigIndex(); |
|
vrk (LEFT CHROMIUM)
2012/07/12 19:37:55
Change method name to something like "CompleteConf
acolwell GONE FROM CHROMIUM
2012/07/12 23:07:58
Done.
|
| + ChangeState_Locked(RETURNING_DATA_FOR_READS); |
| + } |
| +} |
| + |
| void ChunkDemuxerStream::ChangeState_Locked(State state) { |
| lock_.AssertAcquired(); |
| + DVLOG(1) << "ChunkDemuxerStream::ChangeState_Locked() : " |
| + << "type " << type_ |
| + << " - " << state_ << " -> " << state; |
| state_ = state; |
| } |
| @@ -450,14 +453,27 @@ void ChunkDemuxerStream::CreateReadDoneClosures_Locked(ClosureQueue* closures) { |
| if (state_ != RETURNING_DATA_FOR_READS) |
| return; |
| - scoped_refptr<StreamParserBuffer> buffer; |
| + bool configChange = false; |
| while (!read_cbs_.empty()) { |
| - if (!stream_->GetNextBuffer(&buffer)) |
| - return; |
| - closures->push_back(base::Bind(read_cbs_.front(), |
| - DemuxerStream::kOk, buffer)); |
| - read_cbs_.pop_front(); |
| + scoped_refptr<StreamParserBuffer> buffer; |
| + switch (stream_->GetNextBuffer(&buffer)) { |
| + case SourceBufferStream::kSuccess: |
| + closures->push_back(base::Bind(read_cbs_.front(), |
| + DemuxerStream::kOk, buffer)); |
| + read_cbs_.pop_front(); |
| + break; |
| + case SourceBufferStream::kNeedBuffer: |
| + return; |
| + case SourceBufferStream::kConfigChange: |
| + configChange = true; |
| + closures->push_back(base::Bind(read_cbs_.front(), |
| + DemuxerStream::kConfigChanged, |
| + scoped_refptr<DecoderBuffer>())); |
| + read_cbs_.pop_front(); |
| + } |
| } |
| + if (configChange) |
| + ChangeState_Locked(CONFIG_CHANGE); |
| } |
| ChunkDemuxer::ChunkDemuxer(ChunkDemuxerClient* client) |