summaryrefslogtreecommitdiffstats
path: root/media/audio
diff options
context:
space:
mode:
authorhclam@chromium.org <hclam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-04-07 21:32:31 +0000
committerhclam@chromium.org <hclam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-04-07 21:32:31 +0000
commit8cf0758dc5b5863bf1fef28e0ca748aabe074c17 (patch)
treeab61d069f29a508c41ac90a8326b1d7a8be66bc4 /media/audio
parent110f48f0a6c0cc8af1d449119be2f540d81f75f5 (diff)
downloadchromium_src-8cf0758dc5b5863bf1fef28e0ca748aabe074c17.zip
chromium_src-8cf0758dc5b5863bf1fef28e0ca748aabe074c17.tar.gz
chromium_src-8cf0758dc5b5863bf1fef28e0ca748aabe074c17.tar.bz2
Fix some threading issues and some refactoring in AudioRendererHost
1. AudioRendererHost should not wait on IO thread. Calling AudioOutputStream::Start requests some audio packets by calling IPCAudioSource::OnMoreData, resulting in a deadlock. I implemented a prefetching logic to solve this problem, source has to know how many internal buffers the implementation of AudioOutputStream is using and prepare the same amount of packets before calling AudioOutputStream::Start. 2. When IPCAudioSource::OnMoreData is waiting for packet to arrive, calling AudioOutputStream::Stop will result in a deadlock since it expects OnMoreData to return. Should wake up all waiting threads before calling AudioOutputStream::Stop. 3. Did some refactoring and move the message handlers completely into AudioRendererHost, it was clumsy to call to AudioRendererHost from ResourceMessageFilter. Also moved all logics of using shared memory for packet passing, prefetching to IPCAudioSource. AudioRendererHost is now merely a container that manages and delegates calls to IPCAudioSource. This refactoring is helpful because the next step is to implement standalone IPC channel for audio. Review URL: http://codereview.chromium.org/57023 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@13288 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'media/audio')
-rw-r--r--media/audio/audio_output.h14
-rw-r--r--media/audio/mac/audio_output_mac.cc8
-rw-r--r--media/audio/mac/audio_output_mac.h11
-rw-r--r--media/audio/win/audio_output_win.cc4
-rw-r--r--media/audio/win/waveout_output_win.cc4
-rw-r--r--media/audio/win/waveout_output_win.h1
6 files changed, 34 insertions, 8 deletions
diff --git a/media/audio/audio_output.h b/media/audio/audio_output.h
index 0cfca08..289b2af 100644
--- a/media/audio/audio_output.h
+++ b/media/audio/audio_output.h
@@ -42,8 +42,11 @@
class AudioOutputStream {
public:
enum State {
- STATE_STARTED = 0, // The output stream is started.
+ STATE_CREATED = 0, // The output stream is created.
+ STATE_STARTED, // The output stream is started.
STATE_PAUSED, // The output stream is paused.
+ STATE_STOPPED, // The output stream is stopped.
+ STATE_CLOSED, // The output stream is closed.
STATE_ERROR, // The output stream is in error state.
};
@@ -82,6 +85,10 @@ class AudioOutputStream {
virtual bool Open(size_t packet_size) = 0;
// Starts playing audio and generating AudioSourceCallback::OnMoreData().
+ // Since implementor of AudioOutputStream may have internal buffers, right
+ // after calling this method initial buffers are fetched. User of this
+ // object should prepare |AudioOutputStream::GetNumBuffers()| before calling
+ // AudioOutputStream::Start().
virtual void Start(AudioSourceCallback* callback) = 0;
// Stops playing audio. Effect might no be instantaneous as the hardware
@@ -100,6 +107,11 @@ class AudioOutputStream {
// After calling this method, the object should not be used anymore.
virtual void Close() = 0;
+ // Gets the number of internal buffers used in this output stream. This
+ // method is useful for providing information about how user of this object
+ // should prepare initial buffers before calling AudioOutputStream::Start().
+ virtual size_t GetNumBuffers() = 0;
+
protected:
virtual ~AudioOutputStream() {}
};
diff --git a/media/audio/mac/audio_output_mac.cc b/media/audio/mac/audio_output_mac.cc
index 3866a56..da6772f 100644
--- a/media/audio/mac/audio_output_mac.cc
+++ b/media/audio/mac/audio_output_mac.cc
@@ -9,7 +9,7 @@
PCMQueueOutAudioOutputStream::PCMQueueOutAudioOutputStream(
AudioManagerMac* manager, int channels, int sampling_rate,
- char bits_per_sample)
+ char bits_per_sample)
: format_(),
audio_queue_(NULL),
buffer_(),
@@ -91,7 +91,7 @@ void PCMQueueOutAudioOutputStream::Close() {
}
void PCMQueueOutAudioOutputStream::Stop() {
- // TODO(cpu): Implement.
+ // TODO(cpu): Implement.
}
void PCMQueueOutAudioOutputStream::SetVolume(double left_level,
@@ -104,6 +104,10 @@ void PCMQueueOutAudioOutputStream::GetVolume(double* left_level,
// TODO(cpu): Implement.
}
+size_t PCMQueueOutAudioOutputStream::GetNumBuffers() {
+ return kNumBuffers;
+}
+
void PCMQueueOutAudioOutputStream::RenderCallback(void* p_this,
AudioQueueRef queue,
AudioQueueBufferRef buffer) {
diff --git a/media/audio/mac/audio_output_mac.h b/media/audio/mac/audio_output_mac.h
index eb3c091..d1129b3 100644
--- a/media/audio/mac/audio_output_mac.h
+++ b/media/audio/mac/audio_output_mac.h
@@ -25,9 +25,9 @@ class PCMQueueOutAudioOutputStream : public AudioOutputStream {
int channels, int sampling_rate,
char bits_per_sample);
// The dtor is typically called by the AudioManager only and it is usually
- // triggered by calling AudioOutputStream::Close().
+ // triggered by calling AudioOutputStream::Close().
virtual ~PCMQueueOutAudioOutputStream();
-
+
// Implementation of AudioOutputStream.
virtual bool Open(size_t packet_size);
virtual void Close();
@@ -35,11 +35,12 @@ class PCMQueueOutAudioOutputStream : public AudioOutputStream {
virtual void Stop();
virtual void SetVolume(double left_level, double right_level);
virtual void GetVolume(double* left_level, double* right_level);
-
+ virtual size_t GetNumBuffers();
+
private:
// The audio is double buffered.
static const size_t kNumBuffers = 2;
-
+
// The OS calls back here when an audio buffer has been processed.
static void RenderCallback(void* p_this, AudioQueueRef queue,
AudioQueueBufferRef buffer);
@@ -56,7 +57,7 @@ class PCMQueueOutAudioOutputStream : public AudioOutputStream {
AudioSourceCallback* source_;
// Our creator, the audio manager needs to be notified when we close.
AudioManagerMac* manager_;
-
+
DISALLOW_COPY_AND_ASSIGN(PCMQueueOutAudioOutputStream);
};
diff --git a/media/audio/win/audio_output_win.cc b/media/audio/win/audio_output_win.cc
index 880555b..5990e27 100644
--- a/media/audio/win/audio_output_win.cc
+++ b/media/audio/win/audio_output_win.cc
@@ -61,6 +61,10 @@ class AudioOutputStreamMockWin : public AudioOutputStream {
*right_level = right_volume_;
}
+ virtual size_t GetNumBuffers() {
+ return 1;
+ }
+
virtual void Close() {
callback_->OnClose(this);
callback_ = NULL;
diff --git a/media/audio/win/waveout_output_win.cc b/media/audio/win/waveout_output_win.cc
index 95f70ab..59efa4e 100644
--- a/media/audio/win/waveout_output_win.cc
+++ b/media/audio/win/waveout_output_win.cc
@@ -193,6 +193,10 @@ void PCMWaveOutAudioOutputStream::GetVolume(double* left_level,
return;
}
+size_t PCMWaveOutAudioOutputStream::GetNumBuffers() {
+ return kNumBuffers;
+}
+
void PCMWaveOutAudioOutputStream::HandleError(MMRESULT error) {
DLOG(WARNING) << "PCMWaveOutAudio error " << error;
callback_->OnError(this, error);
diff --git a/media/audio/win/waveout_output_win.h b/media/audio/win/waveout_output_win.h
index 1c8ffa6..8b90e69 100644
--- a/media/audio/win/waveout_output_win.h
+++ b/media/audio/win/waveout_output_win.h
@@ -40,6 +40,7 @@ class PCMWaveOutAudioOutputStream : public AudioOutputStream {
virtual void Stop();
virtual void SetVolume(double left_level, double right_level);
virtual void GetVolume(double* left_level, double* right_level);
+ virtual size_t GetNumBuffers();
// Sends a buffer to the audio driver for playback.
void QueueNextPacket(WAVEHDR* buffer);