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

Side by Side Diff: content/renderer/media/audio_renderer_impl.h

Issue 8477037: Simplify AudioRendererImpl by using AudioDevice. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 9 years, 1 month 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 // 4 //
5 // Audio rendering unit utilizing audio output stream provided by browser 5 // Audio rendering unit utilizing AudioDevice.
6 // process through IPC.
7 //
8 // Relationship of classes.
9 //
10 // AudioRendererHost AudioRendererImpl
11 // ^ ^
12 // | |
13 // v IPC v
14 // RenderMessageFilter <---------> AudioMessageFilter
15 //
16 // Implementation of interface with audio device is in AudioRendererHost and
17 // it provides services and entry points in RenderMessageFilter, allowing
18 // usage of IPC calls to interact with audio device. AudioMessageFilter acts
19 // as a portal for IPC calls and does no more than delegation.
20 //
21 // Transportation of audio buffer is done by using shared memory, after
22 // OnCreateStream is executed, OnCreated would be called along with a
23 // SharedMemoryHandle upon successful creation of audio output stream in the
24 // browser process. The same piece of shared memory would be used during the
25 // lifetime of this unit.
26 // 6 //
27 // This class lives inside three threads during it's lifetime, namely: 7 // This class lives inside three threads during it's lifetime, namely:
28 // 1. IO thread. 8 // 1. Render thread.
29 // The thread within which this class receives all the IPC messages and 9 // This object is created on the render thread.
30 // IPC communications can only happen in this thread.
31 // 2. Pipeline thread 10 // 2. Pipeline thread
32 // Initialization of filter and proper stopping of filters happens here. 11 // OnInitialize() is called here with the audio format.
33 // Properties of this filter is also set in this thread. 12 // Play/Pause/Seek also happens here.
34 // 3. Audio decoder thread (If there's one.) 13 // 3. Audio thread created by the AudioDevice.
35 // Responsible for decoding audio data and gives raw PCM data to this object. 14 // Render() is called here where audio data is decoded into raw PCM data.
36 15
37 #ifndef CONTENT_RENDERER_MEDIA_AUDIO_RENDERER_IMPL_H_ 16 #ifndef CONTENT_RENDERER_MEDIA_AUDIO_RENDERER_IMPL_H_
38 #define CONTENT_RENDERER_MEDIA_AUDIO_RENDERER_IMPL_H_ 17 #define CONTENT_RENDERER_MEDIA_AUDIO_RENDERER_IMPL_H_
39 #pragma once 18 #pragma once
40 19
20 #include <vector>
21
41 #include "base/gtest_prod_util.h" 22 #include "base/gtest_prod_util.h"
42 #include "base/memory/scoped_ptr.h" 23 #include "base/memory/scoped_ptr.h"
43 #include "base/message_loop.h"
44 #include "base/shared_memory.h"
45 #include "base/synchronization/lock.h" 24 #include "base/synchronization/lock.h"
46 #include "base/threading/simple_thread.h" 25 #include "content/renderer/media/audio_device.h"
47 #include "content/common/content_export.h"
48 #include "content/renderer/media/audio_message_filter.h"
49 #include "media/audio/audio_io.h" 26 #include "media/audio/audio_io.h"
50 #include "media/audio/audio_manager.h" 27 #include "media/audio/audio_parameters.h"
51 #include "media/base/filters.h"
52 #include "media/filters/audio_renderer_base.h" 28 #include "media/filters/audio_renderer_base.h"
53 29
54 class AudioMessageFilter; 30 class AudioMessageFilter;
55 31
56 class CONTENT_EXPORT AudioRendererImpl 32 class CONTENT_EXPORT AudioRendererImpl
57 : public media::AudioRendererBase, 33 : public media::AudioRendererBase,
58 public AudioMessageFilter::Delegate, 34 public AudioDevice::RenderCallback {
59 public base::DelegateSimpleThread::Delegate,
60 public MessageLoop::DestructionObserver {
61 public: 35 public:
62 // Methods called on Render thread ------------------------------------------ 36 // Methods called on Render thread ------------------------------------------
63 AudioRendererImpl(); 37 AudioRendererImpl();
64 virtual ~AudioRendererImpl(); 38 virtual ~AudioRendererImpl();
65 39
66 // Methods called on IO thread ----------------------------------------------
67 // AudioMessageFilter::Delegate methods, called by AudioMessageFilter.
68 virtual void OnRequestPacket(AudioBuffersState buffers_state);
69 virtual void OnStateChanged(AudioStreamState state);
70 virtual void OnCreated(base::SharedMemoryHandle handle, uint32 length);
71 virtual void OnLowLatencyCreated(base::SharedMemoryHandle handle,
72 base::SyncSocket::Handle socket_handle,
73 uint32 length);
74 virtual void OnVolume(double volume);
75
76 // Methods called on pipeline thread ---------------------------------------- 40 // Methods called on pipeline thread ----------------------------------------
77 // media::Filter implementation. 41 // media::Filter implementation.
78 virtual void SetPlaybackRate(float rate); 42 virtual void SetPlaybackRate(float rate);
79 virtual void Pause(const base::Closure& callback); 43 virtual void Pause(const base::Closure& callback);
80 virtual void Seek(base::TimeDelta time, const media::FilterStatusCB& cb); 44 virtual void Seek(base::TimeDelta time, const media::FilterStatusCB& cb);
81 virtual void Play(const base::Closure& callback); 45 virtual void Play(const base::Closure& callback);
82 46
83 // media::AudioRenderer implementation. 47 // media::AudioRenderer implementation.
84 virtual void SetVolume(float volume); 48 virtual void SetVolume(float volume);
85 49
86 protected: 50 protected:
87 // Methods called on audio renderer thread ---------------------------------- 51 // Methods called on pipeline thread ----------------------------------------
88 // These methods are called from AudioRendererBase. 52 // These methods are called from AudioRendererBase.
89 virtual bool OnInitialize(int bits_per_channel, 53 virtual bool OnInitialize(int bits_per_channel,
90 ChannelLayout channel_layout, 54 ChannelLayout channel_layout,
91 int sample_rate); 55 int sample_rate);
92 virtual void OnStop(); 56 virtual void OnStop();
93 57
94 // Called when the decoder completes a Read().
95 virtual void ConsumeAudioSamples(scoped_refptr<media::Buffer> buffer_in);
96
97 private: 58 private:
98 // We are using either low- or high-latency code path.
99 enum LatencyType {
100 kUninitializedLatency = 0,
101 kLowLatency,
102 kHighLatency
103 };
104 static LatencyType latency_type_;
105
106 // For access to constructor and IO thread methods. 59 // For access to constructor and IO thread methods.
107 friend class AudioRendererImplTest; 60 friend class AudioRendererImplTest;
108 friend class DelegateCaller; 61 friend class DelegateCaller;
109 FRIEND_TEST_ALL_PREFIXES(AudioRendererImplTest, Stop); 62 FRIEND_TEST_ALL_PREFIXES(AudioRendererImplTest, Stop);
110 FRIEND_TEST_ALL_PREFIXES(AudioRendererImplTest, 63 FRIEND_TEST_ALL_PREFIXES(AudioRendererImplTest,
111 DestroyedMessageLoop_ConsumeAudioSamples); 64 DestroyedMessageLoop_ConsumeAudioSamples);
112 FRIEND_TEST_ALL_PREFIXES(AudioRendererImplTest, UpdateEarliestEndTime); 65 FRIEND_TEST_ALL_PREFIXES(AudioRendererImplTest, UpdateEarliestEndTime);
113 // Helper methods. 66 // Helper methods.
114 // Convert number of bytes to duration of time using information about the 67 // Convert number of bytes to duration of time using information about the
115 // number of channels, sample rate and sample bits. 68 // number of channels, sample rate and sample bits.
116 base::TimeDelta ConvertToDuration(int bytes); 69 base::TimeDelta ConvertToDuration(int bytes);
117 70
118 // Methods call on IO thread ------------------------------------------------ 71 // Methods called on pipeline thread ----------------------------------------
119 // The following methods are tasks posted on the IO thread that needs to 72 void DoPlay();
120 // be executed on that thread. They interact with AudioMessageFilter and 73 void DoPause();
121 // sends IPC messages on that thread. 74 void DoSeek();
122 void CreateStreamTask(const AudioParameters& params);
123 void PlayTask();
124 void PauseTask();
125 void SeekTask();
126 void SetVolumeTask(double volume);
127 void NotifyPacketReadyTask();
128 void DestroyTask();
129 75
130 // Called on IO thread when message loop is dying. 76 // AudioDevice::RenderCallback implementation.
131 virtual void WillDestroyCurrentMessageLoop(); 77 virtual void Render(const std::vector<float*>& audio_data,
132 78 size_t number_of_frames,
133 // DelegateSimpleThread::Delegate implementation. 79 size_t audio_delay_milliseconds);
134 virtual void Run();
135
136 // (Re-)starts playback.
137 void NotifyDataAvailableIfNecessary();
138
139 // Creates socket. Virtual so tests can override.
140 virtual void CreateSocket(base::SyncSocket::Handle socket_handle);
141
142 // Launching audio thread. Virtual so tests can override.
143 virtual void CreateAudioThread();
144 80
145 // Accessors used by tests. 81 // Accessors used by tests.
146 static LatencyType latency_type() {
147 return latency_type_;
148 }
149
150 base::Time earliest_end_time() const { 82 base::Time earliest_end_time() const {
151 return earliest_end_time_; 83 return earliest_end_time_;
152 } 84 }
153 85
154 void set_earliest_end_time(const base::Time& earliest_end_time) { 86 void set_earliest_end_time(const base::Time& earliest_end_time) {
155 earliest_end_time_ = earliest_end_time; 87 earliest_end_time_ = earliest_end_time;
156 } 88 }
157 89
158 uint32 bytes_per_second() const { 90 uint32 bytes_per_second() const {
159 return bytes_per_second_; 91 return bytes_per_second_;
160 } 92 }
161 93
162 // Should be called before any class instance is created.
163 static void set_latency_type(LatencyType latency_type);
164
165 // Helper method for IPC send calls.
166 void Send(IPC::Message* message);
167
168 // Estimate earliest time when current buffer can stop playing. 94 // Estimate earliest time when current buffer can stop playing.
169 void UpdateEarliestEndTime(int bytes_filled, 95 void UpdateEarliestEndTime(int bytes_filled,
170 base::TimeDelta request_delay, 96 base::TimeDelta request_delay,
171 base::Time time_now); 97 base::Time time_now);
172 98
173 // Used to calculate audio delay given bytes. 99 // Used to calculate audio delay given bytes.
174 uint32 bytes_per_second_; 100 uint32 bytes_per_second_;
175 101
176 // Whether the stream has been created yet.
177 bool stream_created_;
178
179 // ID of the stream created in the browser process.
180 int32 stream_id_;
181
182 // Memory shared by the browser process for audio buffer.
183 scoped_ptr<base::SharedMemory> shared_memory_;
184 uint32 shared_memory_size_;
185
186 // Cached audio message filter (lives on the main render thread).
187 scoped_refptr<AudioMessageFilter> filter_;
188
189 // Low latency IPC stuff.
190 scoped_ptr<base::SyncSocket> socket_;
191
192 // That thread waits for audio input.
193 scoped_ptr<base::DelegateSimpleThread> audio_thread_;
194
195 // Protects:
196 // - |stopped_|
197 // - |pending_request_|
198 // - |request_buffers_state_|
199 base::Lock lock_;
200
201 // A flag that indicates this filter is called to stop. 102 // A flag that indicates this filter is called to stop.
202 bool stopped_; 103 bool stopped_;
203 104
204 // A flag that indicates an outstanding packet request. 105 // audio_device_ is the sink (destination) for rendered audio.
205 bool pending_request_; 106 scoped_refptr<AudioDevice> audio_device_;
206
207 // State of the audio buffers at time of the last request.
208 AudioBuffersState request_buffers_state_;
209 107
210 // We're supposed to know amount of audio data OS or hardware buffered, but 108 // We're supposed to know amount of audio data OS or hardware buffered, but
211 // that is not always so -- on my Linux box 109 // that is not always so -- on my Linux box
212 // AudioBuffersState::hardware_delay_bytes never reaches 0. 110 // AudioBuffersState::hardware_delay_bytes never reaches 0.
213 // 111 //
214 // As a result we cannot use it to find when stream ends. If we just ignore 112 // As a result we cannot use it to find when stream ends. If we just ignore
215 // buffered data we will notify host that stream ended before it is actually 113 // buffered data we will notify host that stream ended before it is actually
216 // did so, I've seen it done ~140ms too early when playing ~150ms file. 114 // did so, I've seen it done ~140ms too early when playing ~150ms file.
217 // 115 //
218 // Instead of trying to invent OS-specific solution for each and every OS we 116 // Instead of trying to invent OS-specific solution for each and every OS we
219 // are supporting, use simple workaround: every time we fill the buffer we 117 // are supporting, use simple workaround: every time we fill the buffer we
220 // remember when it should stop playing, and do not assume that buffer is 118 // remember when it should stop playing, and do not assume that buffer is
221 // empty till that time. Workaround is not bulletproof, as we don't exactly 119 // empty till that time. Workaround is not bulletproof, as we don't exactly
222 // know when that particular data would start playing, but it is much better 120 // know when that particular data would start playing, but it is much better
223 // than nothing. 121 // than nothing.
224 base::Time earliest_end_time_; 122 base::Time earliest_end_time_;
225 123
124 AudioParameters audio_parameters_;
125
226 DISALLOW_COPY_AND_ASSIGN(AudioRendererImpl); 126 DISALLOW_COPY_AND_ASSIGN(AudioRendererImpl);
227 }; 127 };
228 128
229 #endif // CONTENT_RENDERER_MEDIA_AUDIO_RENDERER_IMPL_H_ 129 #endif // CONTENT_RENDERER_MEDIA_AUDIO_RENDERER_IMPL_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698