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

Unified Diff: media/filters/audio_renderer_impl.cc

Issue 10918022: Move AudioDecoder initialization into AudioRenderer. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 3 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/audio_renderer_impl.cc
diff --git a/media/filters/audio_renderer_impl.cc b/media/filters/audio_renderer_impl.cc
index 94ee20f7145fb35e5f650eab18461af55c7cc5b7..deed856fa848df32cb175fe476397a009086ae24 100644
--- a/media/filters/audio_renderer_impl.cc
+++ b/media/filters/audio_renderer_impl.cc
@@ -11,6 +11,7 @@
#include "base/callback_helpers.h"
#include "base/logging.h"
#include "media/audio/audio_util.h"
+#include "media/base/demuxer_stream.h"
namespace media {
@@ -22,10 +23,8 @@ AudioRendererImpl::AudioRendererImpl(media::AudioRendererSink* sink)
audio_time_buffered_(kNoTimestamp()),
current_time_(kNoTimestamp()),
bytes_per_frame_(0),
- bytes_per_second_(0),
stopped_(false),
sink_(sink),
- is_initialized_(false),
underflow_disabled_(false) {
}
@@ -49,7 +48,6 @@ void AudioRendererImpl::Play(const base::Closure& callback) {
void AudioRendererImpl::DoPlay() {
earliest_end_time_ = base::Time::Now();
- DCHECK(sink_.get());
Ami GONE FROM CHROMIUM 2012/09/07 14:40:02 this is just random cleanup?
sink_->Play();
}
@@ -73,7 +71,6 @@ void AudioRendererImpl::Pause(const base::Closure& callback) {
}
void AudioRendererImpl::DoPause() {
- DCHECK(sink_.get());
sink_->Pause(false);
}
@@ -83,9 +80,7 @@ void AudioRendererImpl::Flush(const base::Closure& callback) {
void AudioRendererImpl::Stop(const base::Closure& callback) {
if (!stopped_) {
- DCHECK(sink_.get());
sink_->Stop();
-
stopped_ = true;
}
{
@@ -128,36 +123,82 @@ void AudioRendererImpl::Preroll(base::TimeDelta time,
sink_->Pause(true);
}
-void AudioRendererImpl::Initialize(const scoped_refptr<AudioDecoder>& decoder,
+void AudioRendererImpl::Initialize(const scoped_refptr<DemuxerStream>& stream,
+ const AudioDecoderList& decoders,
const PipelineStatusCB& init_cb,
+ const StatisticsCB& statistics_cb,
const base::Closure& underflow_cb,
const TimeCB& time_cb,
const base::Closure& ended_cb,
const base::Closure& disabled_cb,
const PipelineStatusCB& error_cb) {
- DCHECK(decoder);
+ base::AutoLock l(lock_);
Ami GONE FROM CHROMIUM 2012/09/07 14:40:02 "l" is not stylish
+ DCHECK(stream);
+ DCHECK(!decoders.empty());
+ DCHECK_EQ(stream->type(), DemuxerStream::AUDIO);
DCHECK(!init_cb.is_null());
+ DCHECK(!statistics_cb.is_null());
DCHECK(!underflow_cb.is_null());
DCHECK(!time_cb.is_null());
DCHECK(!ended_cb.is_null());
DCHECK(!disabled_cb.is_null());
DCHECK(!error_cb.is_null());
DCHECK_EQ(kUninitialized, state_);
- decoder_ = decoder;
+ init_cb_ = init_cb;
+ statistics_cb_ = statistics_cb;
Ami GONE FROM CHROMIUM 2012/09/07 14:40:02 This is only used during the init dance, right? Wh
underflow_cb_ = underflow_cb;
time_cb_ = time_cb;
ended_cb_ = ended_cb;
disabled_cb_ = disabled_cb;
error_cb_ = error_cb;
- // Create a callback so our algorithm can request more reads.
- base::Closure cb = base::Bind(&AudioRendererImpl::ScheduleRead_Locked, this);
+ scoped_ptr<AudioDecoderList> decoder_list(new AudioDecoderList(decoders));
+ InitializeNextDecoder(stream, decoder_list.Pass());
+}
- // Construct the algorithm.
- algorithm_.reset(new AudioRendererAlgorithm());
+void AudioRendererImpl::InitializeNextDecoder(
+ const scoped_refptr<DemuxerStream>& demuxer_stream,
+ scoped_ptr<AudioDecoderList> decoders) {
+ lock_.AssertAcquired();
Ami GONE FROM CHROMIUM 2012/09/07 14:40:02 this locking is making me very sad. If you dropped
+ DCHECK(!decoders->empty());
+
+ scoped_refptr<AudioDecoder> decoder = decoders->front();
Ami GONE FROM CHROMIUM 2012/09/07 14:40:02 put it straight into decoder_ instead?
+ decoders->pop_front();
+
+ DCHECK(decoder);
+ decoder_ = decoder;
+
+ base::AutoUnlock auto_unlock(lock_);
+ decoder->Initialize(
+ demuxer_stream,
+ base::Bind(&AudioRendererImpl::OnDecoderInitDone, this,
+ demuxer_stream,
+ base::Passed(&decoders)),
+ statistics_cb_);
+}
+
+void AudioRendererImpl::OnDecoderInitDone(
+ const scoped_refptr<DemuxerStream>& demuxer_stream,
+ scoped_ptr<AudioDecoderList> decoders,
+ PipelineStatus status) {
+ base::AutoLock auto_lock(lock_);
+
+ if (stopped_ || state_ == kStopped)
+ return;
+
+ if (!decoders->empty() && status == DECODER_ERROR_NOT_SUPPORTED) {
+ InitializeNextDecoder(demuxer_stream, decoders.Pass());
+ return;
+ }
+
+ if (status != PIPELINE_OK) {
+ base::ResetAndReturn(&init_cb_).Run(status);
+ return;
+ }
+
+ // We're all good! Continue initializing the rest of the audio renderer based
+ // on the decoder format.
- // Initialize our algorithm with media properties, initial playback rate,
- // and a callback to request more reads from the data source.
ChannelLayout channel_layout = decoder_->channel_layout();
int channels = ChannelLayoutToChannelCount(channel_layout);
int bits_per_channel = decoder_->bits_per_channel();
@@ -165,15 +206,15 @@ void AudioRendererImpl::Initialize(const scoped_refptr<AudioDecoder>& decoder,
// TODO(vrk): Add method to AudioDecoder to compute bytes per frame.
bytes_per_frame_ = channels * bits_per_channel / 8;
- bool config_ok = algorithm_->ValidateConfig(channels, sample_rate,
scherkus (not reviewing) 2012/09/07 13:59:54 this was some miscellaneous cleanup
- bits_per_channel);
- if (!config_ok || is_initialized_) {
- init_cb.Run(PIPELINE_ERROR_INITIALIZATION_FAILED);
+ algorithm_.reset(new AudioRendererAlgorithm());
+ if (!algorithm_->ValidateConfig(channels, sample_rate, bits_per_channel)) {
+ base::ResetAndReturn(&init_cb_).Run(PIPELINE_ERROR_INITIALIZATION_FAILED);
return;
}
- if (config_ok)
- algorithm_->Initialize(channels, sample_rate, bits_per_channel, 0.0f, cb);
+ algorithm_->Initialize(
+ channels, sample_rate, bits_per_channel, 0.0f,
+ base::Bind(&AudioRendererImpl::ScheduleRead_Locked, this));
// We use the AUDIO_PCM_LINEAR flag because AUDIO_PCM_LOW_LATENCY
// does not currently support all the sample-rates that we require.
@@ -183,19 +224,11 @@ void AudioRendererImpl::Initialize(const scoped_refptr<AudioDecoder>& decoder,
AudioParameters::AUDIO_PCM_LINEAR, channel_layout, sample_rate,
bits_per_channel, GetHighLatencyOutputBufferSize(sample_rate));
- bytes_per_second_ = audio_parameters_.GetBytesPerSecond();
-
- DCHECK(sink_.get());
- DCHECK(!is_initialized_);
-
sink_->Initialize(audio_parameters_, this);
-
sink_->Start();
- is_initialized_ = true;
- // Finally, execute the start callback.
state_ = kPaused;
- init_cb.Run(PIPELINE_OK);
+ base::ResetAndReturn(&init_cb_).Run(PIPELINE_OK);
}
void AudioRendererImpl::ResumeAfterUnderflow(bool buffer_more_audio) {
@@ -481,11 +514,10 @@ void AudioRendererImpl::UpdateEarliestEndTime(int bytes_filled,
}
base::TimeDelta AudioRendererImpl::ConvertToDuration(int bytes) {
- if (bytes_per_second_) {
- return base::TimeDelta::FromMicroseconds(
- base::Time::kMicrosecondsPerSecond * bytes / bytes_per_second_);
- }
- return base::TimeDelta();
+ int bytes_per_second = audio_parameters_.GetBytesPerSecond();
+ CHECK(bytes_per_second);
scherkus (not reviewing) 2012/09/07 13:59:54 calling algorithm_->ValidateConfig() should preven
+ return base::TimeDelta::FromMicroseconds(
+ base::Time::kMicrosecondsPerSecond * bytes / bytes_per_second);
}
void AudioRendererImpl::OnRenderError() {
@@ -493,7 +525,6 @@ void AudioRendererImpl::OnRenderError() {
}
void AudioRendererImpl::DisableUnderflowForTesting() {
- DCHECK(!is_initialized_);
underflow_disabled_ = true;
}

Powered by Google App Engine
This is Rietveld 408576698