diff options
author | xians@chromium.org <xians@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-03-14 14:07:39 +0000 |
---|---|---|
committer | xians@chromium.org <xians@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-03-14 14:07:39 +0000 |
commit | d6a5d747415a472f8755af23de94cd42fb20799a (patch) | |
tree | c069dd45c4bac1858abb5fc716cab13a808058e2 /media/audio/audio_manager_base.cc | |
parent | 49ee2828a9fb5c9502768c2ba932aef9ed00a604 (diff) | |
download | chromium_src-d6a5d747415a472f8755af23de94cd42fb20799a.zip chromium_src-d6a5d747415a472f8755af23de94cd42fb20799a.tar.gz chromium_src-d6a5d747415a472f8755af23de94cd42fb20799a.tar.bz2 |
Stopping the audio thread before destroying the AudioManager<Platform>.
The destruction of the AudioManager family happens in order of: AudioManager<Platform>, AudioManagerBase, AudioManager.
So before getting into the destruction of AudioManagerBase, we have make sure the audio thread has been stopped before AudioManager<Platform> is gone, otherwise it will end up into unexpected behavior, for example, crash because of pure virtual function.
BUG=117470
TEST=media_unittests, Address Sanitizer
Review URL: http://codereview.chromium.org/9692038
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@126635 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'media/audio/audio_manager_base.cc')
-rw-r--r-- | media/audio/audio_manager_base.cc | 45 |
1 files changed, 36 insertions, 9 deletions
diff --git a/media/audio/audio_manager_base.cc b/media/audio/audio_manager_base.cc index 05ed044..abe31dc 100644 --- a/media/audio/audio_manager_base.cc +++ b/media/audio/audio_manager_base.cc @@ -16,7 +16,11 @@ static const int kStreamCloseDelaySeconds = 5; // Default maximum number of output streams that can be open simultaneously // for all platforms. -static const int kDefaultMaxOutputStreams = 15; +static const int kDefaultMaxOutputStreams = 16; + +// Default maximum number of input streams that can be open simultaneously +// for all platforms. +static const int kDefaultMaxInputStreams = 16; static const int kMaxInputChannels = 2; @@ -26,13 +30,22 @@ const char AudioManagerBase::kDefaultDeviceId[] = "default"; AudioManagerBase::AudioManagerBase() : num_active_input_streams_(0), max_num_output_streams_(kDefaultMaxOutputStreams), - num_output_streams_(0) { + max_num_input_streams_(kDefaultMaxInputStreams), + num_output_streams_(0), + num_input_streams_(0) { } AudioManagerBase::~AudioManagerBase() { - Shutdown(); + // The platform specific AudioManager implementation must have already + // stopped the audio thread. Otherwise, we may destroy audio streams before + // stopping the thread, resulting an unexpected behavior. + // This way we make sure activities of the audio streams are all stopped + // before we destroy them. + CHECK(!audio_thread_.get()); // All the output streams should have been deleted. DCHECK_EQ(0, num_output_streams_); + // All the input streams should have been deleted. + DCHECK_EQ(0, num_input_streams_); } void AudioManagerBase::Init() { @@ -63,22 +76,25 @@ AudioOutputStream* AudioManagerBase::MakeAudioOutputStream( // importantly it prevents instability on certain systems. // See bug: http://crbug.com/30242. if (num_output_streams_ >= max_num_output_streams_) { - DLOG(ERROR) << "Number of opened audio streams " << num_output_streams_ - << " exceed the max allowed number " << max_num_output_streams_; + DLOG(ERROR) << "Number of opened output audio streams " + << num_output_streams_ + << " exceed the max allowed number " + << max_num_output_streams_; return NULL; } AudioOutputStream* stream = NULL; if (params.format == AudioParameters::AUDIO_MOCK) { - stream = FakeAudioOutputStream::MakeFakeStream(params); + stream = FakeAudioOutputStream::MakeFakeStream(this, params); } else if (params.format == AudioParameters::AUDIO_PCM_LINEAR) { - num_output_streams_++; stream = MakeLinearOutputStream(params); } else if (params.format == AudioParameters::AUDIO_PCM_LOW_LATENCY) { - num_output_streams_++; stream = MakeLowLatencyOutputStream(params); } + if (stream) + ++num_output_streams_; + return stream; } @@ -90,15 +106,25 @@ AudioInputStream* AudioManagerBase::MakeAudioInputStream( return NULL; } + if (num_input_streams_ >= max_num_input_streams_) { + DLOG(ERROR) << "Number of opened input audio streams " + << num_input_streams_ + << " exceed the max allowed number " << max_num_input_streams_; + return NULL; + } + AudioInputStream* stream = NULL; if (params.format == AudioParameters::AUDIO_MOCK) { - stream = FakeAudioInputStream::MakeFakeStream(params); + stream = FakeAudioInputStream::MakeFakeStream(this, params); } else if (params.format == AudioParameters::AUDIO_PCM_LINEAR) { stream = MakeLinearInputStream(params, device_id); } else if (params.format == AudioParameters::AUDIO_PCM_LOW_LATENCY) { stream = MakeLowLatencyInputStream(params, device_id); } + if (stream) + ++num_input_streams_; + return stream; } @@ -137,6 +163,7 @@ void AudioManagerBase::ReleaseOutputStream(AudioOutputStream* stream) { void AudioManagerBase::ReleaseInputStream(AudioInputStream* stream) { DCHECK(stream); // TODO(xians) : Have a clearer destruction path for the AudioInputStream. + num_input_streams_--; delete stream; } |