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

Side by Side Diff: media/filters/audio_renderer_impl.h

Issue 11275087: Move OnDecoderInitDone() from decoder to pipeline thread. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix unittest. Created 8 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
« no previous file with comments | « no previous file | media/filters/audio_renderer_impl.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 an AudioRendererSink to output data. 5 // Audio rendering unit utilizing an AudioRendererSink to output data.
6 // 6 //
7 // This class lives inside three threads during it's lifetime, namely: 7 // This class lives inside three threads during it's lifetime, namely:
8 // 1. Render thread. 8 // 1. Render thread.
9 // This object is created on the render thread. 9 // This object is created on the render thread.
10 // 2. Pipeline thread 10 // 2. Pipeline thread
11 // Initialize() is called here with the audio format. 11 // Initialize() is called here with the audio format.
12 // Play/Pause/Preroll() also happens here. 12 // Play/Pause/Preroll() also happens here.
13 // 3. Audio thread created by the AudioRendererSink. 13 // 3. Audio thread created by the AudioRendererSink.
14 // Render() is called here where audio data is decoded into raw PCM data. 14 // Render() is called here where audio data is decoded into raw PCM data.
15 // 15 //
16 // AudioRendererImpl talks to an AudioRendererAlgorithm that takes care of 16 // AudioRendererImpl talks to an AudioRendererAlgorithm that takes care of
17 // queueing audio data and stretching/shrinking audio data when playback rate != 17 // queueing audio data and stretching/shrinking audio data when playback rate !=
18 // 1.0 or 0.0. 18 // 1.0 or 0.0.
19 19
20 #ifndef MEDIA_FILTERS_AUDIO_RENDERER_IMPL_H_ 20 #ifndef MEDIA_FILTERS_AUDIO_RENDERER_IMPL_H_
21 #define MEDIA_FILTERS_AUDIO_RENDERER_IMPL_H_ 21 #define MEDIA_FILTERS_AUDIO_RENDERER_IMPL_H_
22 22
23 #include <deque> 23 #include <deque>
24 24
25 #include "base/synchronization/lock.h" 25 #include "base/synchronization/lock.h"
26 #include "base/threading/thread_checker.h"
26 #include "media/base/audio_decoder.h" 27 #include "media/base/audio_decoder.h"
27 #include "media/base/audio_renderer.h" 28 #include "media/base/audio_renderer.h"
28 #include "media/base/audio_renderer_sink.h" 29 #include "media/base/audio_renderer_sink.h"
29 #include "media/base/buffers.h" 30 #include "media/base/buffers.h"
30 #include "media/filters/audio_renderer_algorithm.h" 31 #include "media/filters/audio_renderer_algorithm.h"
31 32
32 namespace media { 33 namespace media {
33 34
34 class MEDIA_EXPORT AudioRendererImpl 35 class MEDIA_EXPORT AudioRendererImpl
35 : public AudioRenderer, 36 : public AudioRenderer,
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
89 // 90 //
90 // If this method returns fewer frames than |requested_frames|, it could 91 // If this method returns fewer frames than |requested_frames|, it could
91 // be a sign that the pipeline is stalled or unable to stream the data fast 92 // be a sign that the pipeline is stalled or unable to stream the data fast
92 // enough. In such scenarios, the callee should zero out unused portions 93 // enough. In such scenarios, the callee should zero out unused portions
93 // of their buffer to playback silence. 94 // of their buffer to playback silence.
94 // 95 //
95 // FillBuffer() updates the pipeline's playback timestamp. If FillBuffer() is 96 // FillBuffer() updates the pipeline's playback timestamp. If FillBuffer() is
96 // not called at the same rate as audio samples are played, then the reported 97 // not called at the same rate as audio samples are played, then the reported
97 // timestamp in the pipeline will be ahead of the actual audio playback. In 98 // timestamp in the pipeline will be ahead of the actual audio playback. In
98 // this case |playback_delay| should be used to indicate when in the future 99 // this case |playback_delay| should be used to indicate when in the future
99 // should the filled buffer be played. If FillBuffer() is called as the audio 100 // should the filled buffer be played.
100 // hardware plays the buffer, then |playback_delay| should be zero.
101 // 101 //
102 // Safe to call on any thread. 102 // Safe to call on any thread.
103 uint32 FillBuffer(uint8* dest, 103 uint32 FillBuffer(uint8* dest,
104 uint32 requested_frames, 104 uint32 requested_frames,
105 const base::TimeDelta& playback_delay); 105 int audio_delay_milliseconds);
106
107 // Get the playback rate of |algorithm_|.
108 float GetPlaybackRate();
109
110 // Convert number of bytes to duration of time using information about the
111 // number of channels, sample rate and sample bits.
112 base::TimeDelta ConvertToDuration(int bytes);
113 106
114 // Estimate earliest time when current buffer can stop playing. 107 // Estimate earliest time when current buffer can stop playing.
115 void UpdateEarliestEndTime(int bytes_filled, 108 void UpdateEarliestEndTime_Locked(int frames_filled,
116 base::TimeDelta request_delay, 109 float playback_rate,
117 base::Time time_now); 110 base::TimeDelta playback_delay,
111 base::Time time_now);
118 112
119 // Methods called on pipeline thread ---------------------------------------- 113 // Methods called on pipeline thread ----------------------------------------
120 void DoPlay(); 114 void DoPlay();
121 void DoPause(); 115 void DoPause();
122 116
123 // media::AudioRendererSink::RenderCallback implementation. 117 // media::AudioRendererSink::RenderCallback implementation. Called on the
118 // AudioDevice thread.
124 virtual int Render(AudioBus* audio_bus, 119 virtual int Render(AudioBus* audio_bus,
125 int audio_delay_milliseconds) OVERRIDE; 120 int audio_delay_milliseconds) OVERRIDE;
126 virtual void OnRenderError() OVERRIDE; 121 virtual void OnRenderError() OVERRIDE;
127 122
128 // Helper method that schedules an asynchronous read from the decoder and 123 // Helper method that schedules an asynchronous read from the decoder and
129 // increments |pending_reads_|. 124 // increments |pending_reads_|.
130 // 125 //
131 // Safe to call from any thread. 126 // Safe to call from any thread.
132 void ScheduleRead_Locked(); 127 void ScheduleRead_Locked();
133 128
(...skipping 10 matching lines...) Expand all
144 // Called when |decoder_| initialization completes. 139 // Called when |decoder_| initialization completes.
145 // |demuxer_stream| & |decoders| are used if initialization failed and 140 // |demuxer_stream| & |decoders| are used if initialization failed and
146 // InitializeNextDecoder() needs to be called again. 141 // InitializeNextDecoder() needs to be called again.
147 void OnDecoderInitDone(const scoped_refptr<DemuxerStream>& demuxer_stream, 142 void OnDecoderInitDone(const scoped_refptr<DemuxerStream>& demuxer_stream,
148 scoped_ptr<AudioDecoderList> decoders, 143 scoped_ptr<AudioDecoderList> decoders,
149 PipelineStatus status); 144 PipelineStatus status);
150 145
151 // Audio decoder. 146 // Audio decoder.
152 scoped_refptr<AudioDecoder> decoder_; 147 scoped_refptr<AudioDecoder> decoder_;
153 148
149 // The sink (destination) for rendered audio. |sink_| must only be accessed
150 // on the pipeline thread (verify with |pipeline_thread_checker_|). |sink_|
151 // must never be called under |lock_| or the 3-way thread bridge between the
152 // audio, pipeline, and decoder threads may deadlock.
153 scoped_refptr<media::AudioRendererSink> sink_;
154
155 // Ensures certain methods are always called on the pipeline thread.
156 base::ThreadChecker pipeline_thread_checker_;
157
158 // AudioParameters constructed during Initialize() based on |decoder_|.
159 AudioParameters audio_parameters_;
160
161 // Callbacks provided during Initialize().
162 PipelineStatusCB init_cb_;
163 StatisticsCB statistics_cb_;
164 base::Closure underflow_cb_;
165 TimeCB time_cb_;
166 base::Closure ended_cb_;
167 base::Closure disabled_cb_;
168 PipelineStatusCB error_cb_;
169
170 // Callback provided to Pause().
171 base::Closure pause_cb_;
172
173 // Callback provided to Preroll().
174 PipelineStatusCB preroll_cb_;
175
176 // After Initialize() has completed, all variables below must be accessed
177 // under |lock_|. ------------------------------------------------------------
178 base::Lock lock_;
179
154 // Algorithm for scaling audio. 180 // Algorithm for scaling audio.
155 scoped_ptr<AudioRendererAlgorithm> algorithm_; 181 scoped_ptr<AudioRendererAlgorithm> algorithm_;
156 182
157 base::Lock lock_;
158
159 // Simple state tracking variable. 183 // Simple state tracking variable.
160 enum State { 184 enum State {
161 kUninitialized, 185 kUninitialized,
162 kPaused, 186 kPaused,
163 kPrerolling, 187 kPrerolling,
164 kPlaying, 188 kPlaying,
165 kStopped, 189 kStopped,
166 kUnderflow, 190 kUnderflow,
167 kRebuffering, 191 kRebuffering,
168 }; 192 };
169 State state_; 193 State state_;
170 194
171 // Keep track of our outstanding read to |decoder_|. 195 // Keep track of our outstanding read to |decoder_|.
172 bool pending_read_; 196 bool pending_read_;
173 197
174 // Keeps track of whether we received and rendered the end of stream buffer. 198 // Keeps track of whether we received and rendered the end of stream buffer.
175 bool received_end_of_stream_; 199 bool received_end_of_stream_;
176 bool rendered_end_of_stream_; 200 bool rendered_end_of_stream_;
177 201
178 // The timestamp of the last frame (i.e. furthest in the future) buffered as 202 // The timestamp of the last frame (i.e. furthest in the future) buffered as
179 // well as the current time that takes current playback delay into account. 203 // well as the current time that takes current playback delay into account.
180 base::TimeDelta audio_time_buffered_; 204 base::TimeDelta audio_time_buffered_;
181 base::TimeDelta current_time_; 205 base::TimeDelta current_time_;
182 206
183 PipelineStatusCB init_cb_;
184 StatisticsCB statistics_cb_;
185
186 // Filter callbacks.
187 base::Closure pause_cb_;
188 PipelineStatusCB preroll_cb_;
189
190 base::Closure underflow_cb_;
191 TimeCB time_cb_;
192 base::Closure ended_cb_;
193 base::Closure disabled_cb_;
194 PipelineStatusCB error_cb_;
195
196 base::TimeDelta preroll_timestamp_; 207 base::TimeDelta preroll_timestamp_;
197 208
198 uint32 bytes_per_frame_;
199
200 // A flag that indicates this filter is called to stop.
201 bool stopped_;
202
203 // The sink (destination) for rendered audio.
204 scoped_refptr<media::AudioRendererSink> sink_;
205
206 // We're supposed to know amount of audio data OS or hardware buffered, but 209 // We're supposed to know amount of audio data OS or hardware buffered, but
207 // that is not always so -- on my Linux box 210 // that is not always so -- on my Linux box
208 // AudioBuffersState::hardware_delay_bytes never reaches 0. 211 // AudioBuffersState::hardware_delay_bytes never reaches 0.
209 // 212 //
210 // As a result we cannot use it to find when stream ends. If we just ignore 213 // As a result we cannot use it to find when stream ends. If we just ignore
211 // buffered data we will notify host that stream ended before it is actually 214 // buffered data we will notify host that stream ended before it is actually
212 // did so, I've seen it done ~140ms too early when playing ~150ms file. 215 // did so, I've seen it done ~140ms too early when playing ~150ms file.
213 // 216 //
214 // Instead of trying to invent OS-specific solution for each and every OS we 217 // Instead of trying to invent OS-specific solution for each and every OS we
215 // are supporting, use simple workaround: every time we fill the buffer we 218 // are supporting, use simple workaround: every time we fill the buffer we
216 // remember when it should stop playing, and do not assume that buffer is 219 // remember when it should stop playing, and do not assume that buffer is
217 // empty till that time. Workaround is not bulletproof, as we don't exactly 220 // empty till that time. Workaround is not bulletproof, as we don't exactly
218 // know when that particular data would start playing, but it is much better 221 // know when that particular data would start playing, but it is much better
219 // than nothing. 222 // than nothing.
220 base::Time earliest_end_time_; 223 base::Time earliest_end_time_;
221 224
222 AudioParameters audio_parameters_;
223
224 bool underflow_disabled_; 225 bool underflow_disabled_;
225 226
226 // True if the renderer receives a buffer with kAborted status during preroll, 227 // True if the renderer receives a buffer with kAborted status during preroll,
227 // false otherwise. This flag is cleared on the next Preroll() call. 228 // false otherwise. This flag is cleared on the next Preroll() call.
228 bool preroll_aborted_; 229 bool preroll_aborted_;
229 230
231 // End variables which must be accessed under |lock_|. ----------------------
232
233 // Variables used only on the audio thread. ---------------------------------
234 int actual_frames_per_buffer_;
235 scoped_array<uint8> audio_buffer_;
236
230 DISALLOW_COPY_AND_ASSIGN(AudioRendererImpl); 237 DISALLOW_COPY_AND_ASSIGN(AudioRendererImpl);
231 }; 238 };
232 239
233 } // namespace media 240 } // namespace media
234 241
235 #endif // MEDIA_FILTERS_AUDIO_RENDERER_IMPL_H_ 242 #endif // MEDIA_FILTERS_AUDIO_RENDERER_IMPL_H_
OLDNEW
« no previous file with comments | « no previous file | media/filters/audio_renderer_impl.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698