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

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" 24 #include "base/message_loop.h"
44 #include "base/shared_memory.h"
45 #include "base/synchronization/lock.h" 25 #include "base/synchronization/lock.h"
46 #include "base/threading/simple_thread.h" 26 #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" 27 #include "media/audio/audio_io.h"
50 #include "media/audio/audio_manager.h" 28 #include "media/audio/audio_parameters.h"
51 #include "media/base/filters.h"
52 #include "media/filters/audio_renderer_base.h" 29 #include "media/filters/audio_renderer_base.h"
53 30
54 class AudioMessageFilter; 31 class AudioMessageFilter;
55 32
56 class CONTENT_EXPORT AudioRendererImpl 33 class CONTENT_EXPORT AudioRendererImpl
57 : public media::AudioRendererBase, 34 : public media::AudioRendererBase,
58 public AudioMessageFilter::Delegate, 35 public AudioDevice::RenderCallback,
59 public base::DelegateSimpleThread::Delegate,
60 public MessageLoop::DestructionObserver { 36 public MessageLoop::DestructionObserver {
61 public: 37 public:
62 // Methods called on Render thread ------------------------------------------ 38 // Methods called on Render thread ------------------------------------------
63 AudioRendererImpl(); 39 AudioRendererImpl();
64 virtual ~AudioRendererImpl(); 40 virtual ~AudioRendererImpl();
65 41
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 ---------------------------------------- 42 // Methods called on pipeline thread ----------------------------------------
77 // media::Filter implementation. 43 // media::Filter implementation.
78 virtual void SetPlaybackRate(float rate); 44 virtual void SetPlaybackRate(float rate);
79 virtual void Pause(const base::Closure& callback); 45 virtual void Pause(const base::Closure& callback);
80 virtual void Seek(base::TimeDelta time, const media::FilterStatusCB& cb); 46 virtual void Seek(base::TimeDelta time, const media::FilterStatusCB& cb);
81 virtual void Play(const base::Closure& callback); 47 virtual void Play(const base::Closure& callback);
82 48
83 // media::AudioRenderer implementation. 49 // media::AudioRenderer implementation.
84 virtual void SetVolume(float volume); 50 virtual void SetVolume(float volume);
85 51
86 protected: 52 protected:
87 // Methods called on audio renderer thread ---------------------------------- 53 // Methods called on pipeline thread ----------------------------------------
88 // These methods are called from AudioRendererBase. 54 // These methods are called from AudioRendererBase.
89 virtual bool OnInitialize(int bits_per_channel, 55 virtual bool OnInitialize(int bits_per_channel,
90 ChannelLayout channel_layout, 56 ChannelLayout channel_layout,
91 int sample_rate); 57 int sample_rate);
92 virtual void OnStop(); 58 virtual void OnStop();
93 59
94 // Called when the decoder completes a Read(). 60 // Called when the decoder completes a Read().
95 virtual void ConsumeAudioSamples(scoped_refptr<media::Buffer> buffer_in); 61 virtual void ConsumeAudioSamples(scoped_refptr<media::Buffer> buffer_in);
96 62
97 private: 63 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. 64 // For access to constructor and IO thread methods.
107 friend class AudioRendererImplTest; 65 friend class AudioRendererImplTest;
108 friend class DelegateCaller; 66 friend class DelegateCaller;
109 FRIEND_TEST_ALL_PREFIXES(AudioRendererImplTest, Stop); 67 FRIEND_TEST_ALL_PREFIXES(AudioRendererImplTest, Stop);
110 FRIEND_TEST_ALL_PREFIXES(AudioRendererImplTest, 68 FRIEND_TEST_ALL_PREFIXES(AudioRendererImplTest,
111 DestroyedMessageLoop_ConsumeAudioSamples); 69 DestroyedMessageLoop_ConsumeAudioSamples);
112 FRIEND_TEST_ALL_PREFIXES(AudioRendererImplTest, UpdateEarliestEndTime); 70 FRIEND_TEST_ALL_PREFIXES(AudioRendererImplTest, UpdateEarliestEndTime);
113 // Helper methods. 71 // Helper methods.
114 // Convert number of bytes to duration of time using information about the 72 // Convert number of bytes to duration of time using information about the
115 // number of channels, sample rate and sample bits. 73 // number of channels, sample rate and sample bits.
116 base::TimeDelta ConvertToDuration(int bytes); 74 base::TimeDelta ConvertToDuration(int bytes);
117 75
118 // Methods call on IO thread ------------------------------------------------ 76 // Methods called on pipeline thread ----------------------------------------
119 // The following methods are tasks posted on the IO thread that needs to 77 void DoPlay();
120 // be executed on that thread. They interact with AudioMessageFilter and 78 void DoPause();
121 // sends IPC messages on that thread. 79 void DoSeek();
122 void CreateStreamTask(const AudioParameters& params); 80
123 void PlayTask(); 81 // AudioDevice::RenderCallback implementation.
124 void PauseTask(); 82 virtual void Render(const std::vector<float*>& audio_data,
125 void SeekTask(); 83 size_t number_of_frames,
126 void SetVolumeTask(double volume); 84 size_t audio_delay_milliseconds);
127 void NotifyPacketReadyTask();
128 void DestroyTask();
129 85
130 // Called on IO thread when message loop is dying. 86 // Called on IO thread when message loop is dying.
131 virtual void WillDestroyCurrentMessageLoop(); 87 virtual void WillDestroyCurrentMessageLoop();
132 88
133 // DelegateSimpleThread::Delegate implementation.
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
145 // Accessors used by tests. 89 // Accessors used by tests.
146 static LatencyType latency_type() {
147 return latency_type_;
148 }
149
150 base::Time earliest_end_time() const { 90 base::Time earliest_end_time() const {
151 return earliest_end_time_; 91 return earliest_end_time_;
152 } 92 }
153 93
154 void set_earliest_end_time(const base::Time& earliest_end_time) { 94 void set_earliest_end_time(const base::Time& earliest_end_time) {
155 earliest_end_time_ = earliest_end_time; 95 earliest_end_time_ = earliest_end_time;
156 } 96 }
157 97
158 uint32 bytes_per_second() const { 98 uint32 bytes_per_second() const {
159 return bytes_per_second_; 99 return bytes_per_second_;
160 } 100 }
161 101
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. 102 // Estimate earliest time when current buffer can stop playing.
169 void UpdateEarliestEndTime(int bytes_filled, 103 void UpdateEarliestEndTime(int bytes_filled,
170 base::TimeDelta request_delay, 104 base::TimeDelta request_delay,
171 base::Time time_now); 105 base::Time time_now);
172 106
173 // Used to calculate audio delay given bytes. 107 // Used to calculate audio delay given bytes.
174 uint32 bytes_per_second_; 108 uint32 bytes_per_second_;
175 109
176 // ID of the stream created in the browser process.
177 int32 stream_id_;
178
179 // Memory shared by the browser process for audio buffer.
180 scoped_ptr<base::SharedMemory> shared_memory_;
181 uint32 shared_memory_size_;
182
183 // Cached audio message filter (lives on the main render thread).
184 scoped_refptr<AudioMessageFilter> filter_;
185
186 // Low latency IPC stuff.
187 scoped_ptr<base::SyncSocket> socket_;
188
189 // That thread waits for audio input.
190 scoped_ptr<base::DelegateSimpleThread> audio_thread_;
191
192 // Protects: 110 // Protects:
193 // - |stopped_| 111 // - |stopped_|
194 // - |pending_request_| 112 // - |pending_request_|
195 // - |request_buffers_state_| 113 // - |request_buffers_state_|
196 base::Lock lock_; 114 base::Lock lock_;
197 115
198 // A flag that indicates this filter is called to stop. 116 // A flag that indicates this filter is called to stop.
199 bool stopped_; 117 bool stopped_;
200 118
201 // A flag that indicates an outstanding packet request.
202 bool pending_request_;
203
204 // State of the audio buffers at time of the last request. 119 // State of the audio buffers at time of the last request.
205 AudioBuffersState request_buffers_state_; 120 AudioBuffersState request_buffers_state_;
206 121
122 // audio_device_ is the sink (destination) for rendered audio.
123 scoped_refptr<AudioDevice> audio_device_;
124
207 // We're supposed to know amount of audio data OS or hardware buffered, but 125 // We're supposed to know amount of audio data OS or hardware buffered, but
208 // that is not always so -- on my Linux box 126 // that is not always so -- on my Linux box
209 // AudioBuffersState::hardware_delay_bytes never reaches 0. 127 // AudioBuffersState::hardware_delay_bytes never reaches 0.
210 // 128 //
211 // As a result we cannot use it to find when stream ends. If we just ignore 129 // As a result we cannot use it to find when stream ends. If we just ignore
212 // buffered data we will notify host that stream ended before it is actually 130 // buffered data we will notify host that stream ended before it is actually
213 // did so, I've seen it done ~140ms too early when playing ~150ms file. 131 // did so, I've seen it done ~140ms too early when playing ~150ms file.
214 // 132 //
215 // Instead of trying to invent OS-specific solution for each and every OS we 133 // Instead of trying to invent OS-specific solution for each and every OS we
216 // are supporting, use simple workaround: every time we fill the buffer we 134 // are supporting, use simple workaround: every time we fill the buffer we
217 // remember when it should stop playing, and do not assume that buffer is 135 // remember when it should stop playing, and do not assume that buffer is
218 // empty till that time. Workaround is not bulletproof, as we don't exactly 136 // empty till that time. Workaround is not bulletproof, as we don't exactly
219 // know when that particular data would start playing, but it is much better 137 // know when that particular data would start playing, but it is much better
220 // than nothing. 138 // than nothing.
221 base::Time earliest_end_time_; 139 base::Time earliest_end_time_;
222 140
141 AudioParameters audio_parameters_;
142
223 DISALLOW_COPY_AND_ASSIGN(AudioRendererImpl); 143 DISALLOW_COPY_AND_ASSIGN(AudioRendererImpl);
224 }; 144 };
225 145
226 #endif // CONTENT_RENDERER_MEDIA_AUDIO_RENDERER_IMPL_H_ 146 #endif // CONTENT_RENDERER_MEDIA_AUDIO_RENDERER_IMPL_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698