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

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

Issue 7157001: Implements AudioMessageFilter as member in RenderThread (Closed) Base URL: http://src.chromium.org/svn/trunk/src/
Patch Set: Fixed nits in AudioRenderImpl unit test Created 9 years, 5 months 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 #include "content/renderer/media/audio_renderer_impl.h" 5 #include "content/renderer/media/audio_renderer_impl.h"
6 6
7 #include <math.h> 7 #include <math.h>
8 8
9 #include "content/common/child_process.h"
9 #include "base/command_line.h" 10 #include "base/command_line.h"
10 #include "content/common/content_switches.h" 11 #include "content/common/content_switches.h"
11 #include "content/common/media/audio_messages.h" 12 #include "content/common/media/audio_messages.h"
12 #include "content/renderer/render_thread.h" 13 #include "content/renderer/render_thread.h"
13 #include "content/renderer/render_view.h" 14 #include "content/renderer/render_view.h"
14 #include "media/audio/audio_output_controller.h" 15 #include "media/audio/audio_output_controller.h"
15 #include "media/base/filter_host.h" 16 #include "media/base/filter_host.h"
16 17
17 // Static variable that says what code path we are using -- low or high 18 // Static variable that says what code path we are using -- low or high
18 // latency. Made separate variable so we don't have to go to command line 19 // latency. Made separate variable so we don't have to go to command line
19 // for every DCHECK(). 20 // for every DCHECK().
20 AudioRendererImpl::LatencyType AudioRendererImpl::latency_type_ = 21 AudioRendererImpl::LatencyType AudioRendererImpl::latency_type_ =
21 AudioRendererImpl::kUninitializedLatency; 22 AudioRendererImpl::kUninitializedLatency;
22 23
23 AudioRendererImpl::AudioRendererImpl(AudioMessageFilter* filter) 24 AudioRendererImpl::AudioRendererImpl()
24 : AudioRendererBase(), 25 : AudioRendererBase(),
25 bytes_per_second_(0), 26 bytes_per_second_(0),
26 filter_(filter),
27 stream_id_(0), 27 stream_id_(0),
28 shared_memory_(NULL), 28 shared_memory_(NULL),
29 shared_memory_size_(0), 29 shared_memory_size_(0),
30 io_loop_(filter->message_loop()),
31 stopped_(false), 30 stopped_(false),
32 pending_request_(false), 31 pending_request_(false),
33 prerolling_(false), 32 prerolling_(false),
34 preroll_bytes_(0) { 33 preroll_bytes_(0) {
35 DCHECK(io_loop_); 34 filter_ = RenderThread::current()->audio_message_filter();
36 // Figure out if we are planning to use high or low latency code path. 35 // Figure out if we are planning to use high or low latency code path.
37 // We are initializing only one variable and double initialization is Ok, 36 // We are initializing only one variable and double initialization is Ok,
38 // so there would not be any issues caused by CPU memory model. 37 // so there would not be any issues caused by CPU memory model.
39 if (latency_type_ == kUninitializedLatency) { 38 if (latency_type_ == kUninitializedLatency) {
40 if (CommandLine::ForCurrentProcess()->HasSwitch( 39 if (CommandLine::ForCurrentProcess()->HasSwitch(
41 switches::kLowLatencyAudio)) { 40 switches::kLowLatencyAudio)) {
42 latency_type_ = kLowLatency; 41 latency_type_ = kLowLatency;
43 } else { 42 } else {
44 latency_type_ = kHighLatency; 43 latency_type_ = kHighLatency;
45 } 44 }
(...skipping 16 matching lines...) Expand all
62 } 61 }
63 return base::TimeDelta(); 62 return base::TimeDelta();
64 } 63 }
65 64
66 bool AudioRendererImpl::OnInitialize(const media::AudioDecoderConfig& config) { 65 bool AudioRendererImpl::OnInitialize(const media::AudioDecoderConfig& config) {
67 AudioParameters params(config); 66 AudioParameters params(config);
68 params.format = AudioParameters::AUDIO_PCM_LINEAR; 67 params.format = AudioParameters::AUDIO_PCM_LINEAR;
69 68
70 bytes_per_second_ = params.GetBytesPerSecond(); 69 bytes_per_second_ = params.GetBytesPerSecond();
71 70
72 io_loop_->PostTask(FROM_HERE, 71 ChildProcess::current()->io_message_loop()->PostTask(
72 FROM_HERE,
73 NewRunnableMethod(this, &AudioRendererImpl::CreateStreamTask, params)); 73 NewRunnableMethod(this, &AudioRendererImpl::CreateStreamTask, params));
74 return true; 74 return true;
75 } 75 }
76 76
77 void AudioRendererImpl::OnStop() { 77 void AudioRendererImpl::OnStop() {
78 base::AutoLock auto_lock(lock_); 78 base::AutoLock auto_lock(lock_);
79 if (stopped_) 79 if (stopped_)
80 return; 80 return;
81 stopped_ = true; 81 stopped_ = true;
82 82
83 // We should never touch |io_loop_| after being stopped, so post our final 83 ChildProcess::current()->io_message_loop()->PostTask(
84 // task to clean up. 84 FROM_HERE,
85 io_loop_->PostTask(FROM_HERE,
86 NewRunnableMethod(this, &AudioRendererImpl::DestroyTask)); 85 NewRunnableMethod(this, &AudioRendererImpl::DestroyTask));
87 86
88 if (audio_thread_.get()) { 87 if (audio_thread_.get()) {
89 socket_->Close(); 88 socket_->Close();
90 audio_thread_->Join(); 89 audio_thread_->Join();
91 } 90 }
92 } 91 }
93 92
94 void AudioRendererImpl::NotifyDataAvailableIfNecessary() { 93 void AudioRendererImpl::NotifyDataAvailableIfNecessary() {
95 if (latency_type_ == kHighLatency) { 94 if (latency_type_ == kHighLatency) {
96 // Post a task to render thread to notify a packet reception. 95 // Post a task to render thread to notify a packet reception.
97 io_loop_->PostTask(FROM_HERE, 96 ChildProcess::current()->io_message_loop()->PostTask(
97 FROM_HERE,
98 NewRunnableMethod(this, &AudioRendererImpl::NotifyPacketReadyTask)); 98 NewRunnableMethod(this, &AudioRendererImpl::NotifyPacketReadyTask));
99 } 99 }
100 } 100 }
101 101
102 void AudioRendererImpl::ConsumeAudioSamples( 102 void AudioRendererImpl::ConsumeAudioSamples(
103 scoped_refptr<media::Buffer> buffer_in) { 103 scoped_refptr<media::Buffer> buffer_in) {
104 base::AutoLock auto_lock(lock_); 104 base::AutoLock auto_lock(lock_);
105 if (stopped_) 105 if (stopped_)
106 return; 106 return;
107 107
108 // TODO(hclam): handle end of stream here. 108 // TODO(hclam): handle end of stream here.
109 109
110 // Use the base class to queue the buffer. 110 // Use the base class to queue the buffer.
111 AudioRendererBase::ConsumeAudioSamples(buffer_in); 111 AudioRendererBase::ConsumeAudioSamples(buffer_in);
112 112
113 NotifyDataAvailableIfNecessary(); 113 NotifyDataAvailableIfNecessary();
114 } 114 }
115 115
116 void AudioRendererImpl::SetPlaybackRate(float rate) { 116 void AudioRendererImpl::SetPlaybackRate(float rate) {
117 DCHECK_LE(0.0f, rate); 117 DCHECK_LE(0.0f, rate);
118 118
119 base::AutoLock auto_lock(lock_); 119 base::AutoLock auto_lock(lock_);
120 // Handle the case where we stopped due to |io_loop_| dying. 120 // Handle the case where we stopped due to IO message loop dying.
121 if (stopped_) { 121 if (stopped_) {
122 AudioRendererBase::SetPlaybackRate(rate); 122 AudioRendererBase::SetPlaybackRate(rate);
123 return; 123 return;
124 } 124 }
125 125
126 // We have two cases here: 126 // We have two cases here:
127 // Play: GetPlaybackRate() == 0.0 && rate != 0.0 127 // Play: GetPlaybackRate() == 0.0 && rate != 0.0
128 // Pause: GetPlaybackRate() != 0.0 && rate == 0.0 128 // Pause: GetPlaybackRate() != 0.0 && rate == 0.0
129 if (GetPlaybackRate() == 0.0f && rate != 0.0f) { 129 if (GetPlaybackRate() == 0.0f && rate != 0.0f) {
130 io_loop_->PostTask(FROM_HERE, 130 ChildProcess::current()->io_message_loop()->PostTask(
131 NewRunnableMethod(this, &AudioRendererImpl::PlayTask)); 131 FROM_HERE,
132 NewRunnableMethod(this, &AudioRendererImpl::PlayTask));
132 } else if (GetPlaybackRate() != 0.0f && rate == 0.0f) { 133 } else if (GetPlaybackRate() != 0.0f && rate == 0.0f) {
133 // Pause is easy, we can always pause. 134 // Pause is easy, we can always pause.
134 io_loop_->PostTask(FROM_HERE, 135 ChildProcess::current()->io_message_loop()->PostTask(
135 NewRunnableMethod(this, &AudioRendererImpl::PauseTask)); 136 FROM_HERE,
137 NewRunnableMethod(this, &AudioRendererImpl::PauseTask));
136 } 138 }
137 AudioRendererBase::SetPlaybackRate(rate); 139 AudioRendererBase::SetPlaybackRate(rate);
138 140
139 // If we are playing, give a kick to try fulfilling the packet request as 141 // If we are playing, give a kick to try fulfilling the packet request as
140 // the previous packet request may be stalled by a pause. 142 // the previous packet request may be stalled by a pause.
141 if (rate > 0.0f) { 143 if (rate > 0.0f) {
142 NotifyDataAvailableIfNecessary(); 144 NotifyDataAvailableIfNecessary();
143 } 145 }
144 } 146 }
145 147
146 void AudioRendererImpl::Pause(media::FilterCallback* callback) { 148 void AudioRendererImpl::Pause(media::FilterCallback* callback) {
147 AudioRendererBase::Pause(callback); 149 AudioRendererBase::Pause(callback);
148 base::AutoLock auto_lock(lock_); 150 base::AutoLock auto_lock(lock_);
149 if (stopped_) 151 if (stopped_)
150 return; 152 return;
151 153
152 io_loop_->PostTask(FROM_HERE, 154 ChildProcess::current()->io_message_loop()->PostTask(
155 FROM_HERE,
153 NewRunnableMethod(this, &AudioRendererImpl::PauseTask)); 156 NewRunnableMethod(this, &AudioRendererImpl::PauseTask));
154 } 157 }
155 158
156 void AudioRendererImpl::Seek(base::TimeDelta time, 159 void AudioRendererImpl::Seek(base::TimeDelta time,
157 const media::FilterStatusCB& cb) { 160 const media::FilterStatusCB& cb) {
158 AudioRendererBase::Seek(time, cb); 161 AudioRendererBase::Seek(time, cb);
159 base::AutoLock auto_lock(lock_); 162 base::AutoLock auto_lock(lock_);
160 if (stopped_) 163 if (stopped_)
161 return; 164 return;
162 165
163 io_loop_->PostTask(FROM_HERE, 166 ChildProcess::current()->io_message_loop()->PostTask(
167 FROM_HERE,
164 NewRunnableMethod(this, &AudioRendererImpl::SeekTask)); 168 NewRunnableMethod(this, &AudioRendererImpl::SeekTask));
165 } 169 }
166 170
167 171
168 void AudioRendererImpl::Play(media::FilterCallback* callback) { 172 void AudioRendererImpl::Play(media::FilterCallback* callback) {
169 AudioRendererBase::Play(callback); 173 AudioRendererBase::Play(callback);
170 base::AutoLock auto_lock(lock_); 174 base::AutoLock auto_lock(lock_);
171 if (stopped_) 175 if (stopped_)
172 return; 176 return;
173 177
174 if (GetPlaybackRate() != 0.0f) { 178 if (GetPlaybackRate() != 0.0f) {
175 io_loop_->PostTask(FROM_HERE, 179 ChildProcess::current()->io_message_loop()->PostTask(
176 NewRunnableMethod(this, &AudioRendererImpl::PlayTask)); 180 FROM_HERE,
181 NewRunnableMethod(this, &AudioRendererImpl::PlayTask));
177 } else { 182 } else {
178 io_loop_->PostTask(FROM_HERE, 183 ChildProcess::current()->io_message_loop()->PostTask(
179 NewRunnableMethod(this, &AudioRendererImpl::PauseTask)); 184 FROM_HERE,
185 NewRunnableMethod(this, &AudioRendererImpl::PauseTask));
180 } 186 }
181 } 187 }
182 188
183 void AudioRendererImpl::SetVolume(float volume) { 189 void AudioRendererImpl::SetVolume(float volume) {
184 base::AutoLock auto_lock(lock_); 190 base::AutoLock auto_lock(lock_);
185 if (stopped_) 191 if (stopped_)
186 return; 192 return;
187 io_loop_->PostTask(FROM_HERE, 193 ChildProcess::current()->io_message_loop()->PostTask(
188 NewRunnableMethod( 194 FROM_HERE,
189 this, &AudioRendererImpl::SetVolumeTask, volume)); 195 NewRunnableMethod(this, &AudioRendererImpl::SetVolumeTask, volume));
190 } 196 }
191 197
192 void AudioRendererImpl::OnCreated(base::SharedMemoryHandle handle, 198 void AudioRendererImpl::OnCreated(base::SharedMemoryHandle handle,
193 uint32 length) { 199 uint32 length) {
194 DCHECK(MessageLoop::current() == io_loop_); 200 DCHECK(MessageLoop::current() == ChildProcess::current()->io_message_loop());
195 DCHECK_EQ(kHighLatency, latency_type_); 201 DCHECK_EQ(kHighLatency, latency_type_);
196 202
197 base::AutoLock auto_lock(lock_); 203 base::AutoLock auto_lock(lock_);
198 if (stopped_) 204 if (stopped_)
199 return; 205 return;
200 206
201 shared_memory_.reset(new base::SharedMemory(handle, false)); 207 shared_memory_.reset(new base::SharedMemory(handle, false));
202 shared_memory_->Map(length); 208 shared_memory_->Map(length);
203 shared_memory_size_ = length; 209 shared_memory_size_ = length;
204 } 210 }
(...skipping 12 matching lines...) Expand all
217 DCHECK_EQ(kLowLatency, latency_type_); 223 DCHECK_EQ(kLowLatency, latency_type_);
218 audio_thread_.reset( 224 audio_thread_.reset(
219 new base::DelegateSimpleThread(this, "renderer_audio_thread")); 225 new base::DelegateSimpleThread(this, "renderer_audio_thread"));
220 audio_thread_->Start(); 226 audio_thread_->Start();
221 } 227 }
222 228
223 void AudioRendererImpl::OnLowLatencyCreated( 229 void AudioRendererImpl::OnLowLatencyCreated(
224 base::SharedMemoryHandle handle, 230 base::SharedMemoryHandle handle,
225 base::SyncSocket::Handle socket_handle, 231 base::SyncSocket::Handle socket_handle,
226 uint32 length) { 232 uint32 length) {
227 DCHECK(MessageLoop::current() == io_loop_); 233 DCHECK(MessageLoop::current() == ChildProcess::current()->io_message_loop());
228 DCHECK_EQ(kLowLatency, latency_type_); 234 DCHECK_EQ(kLowLatency, latency_type_);
229 #if defined(OS_WIN) 235 #if defined(OS_WIN)
230 DCHECK(handle); 236 DCHECK(handle);
231 #else 237 #else
232 DCHECK_GE(handle.fd, 0); 238 DCHECK_GE(handle.fd, 0);
233 #endif 239 #endif
234 DCHECK_NE(0u, length); 240 DCHECK_NE(0u, length);
235 241
236 base::AutoLock auto_lock(lock_); 242 base::AutoLock auto_lock(lock_);
237 if (stopped_) 243 if (stopped_)
238 return; 244 return;
239 245
240 shared_memory_.reset(new base::SharedMemory(handle, false)); 246 shared_memory_.reset(new base::SharedMemory(handle, false));
241 shared_memory_->Map(length); 247 shared_memory_->Map(length);
242 shared_memory_size_ = length; 248 shared_memory_size_ = length;
243 249
244 CreateSocket(socket_handle); 250 CreateSocket(socket_handle);
245 CreateAudioThread(); 251 CreateAudioThread();
246 } 252 }
247 253
248 void AudioRendererImpl::OnRequestPacket(AudioBuffersState buffers_state) { 254 void AudioRendererImpl::OnRequestPacket(AudioBuffersState buffers_state) {
249 DCHECK(MessageLoop::current() == io_loop_); 255 DCHECK(MessageLoop::current() == ChildProcess::current()->io_message_loop());
250 DCHECK_EQ(kHighLatency, latency_type_); 256 DCHECK_EQ(kHighLatency, latency_type_);
251 { 257 {
252 base::AutoLock auto_lock(lock_); 258 base::AutoLock auto_lock(lock_);
253 DCHECK(!pending_request_); 259 DCHECK(!pending_request_);
254 pending_request_ = true; 260 pending_request_ = true;
255 request_buffers_state_ = buffers_state; 261 request_buffers_state_ = buffers_state;
256 } 262 }
257 263
258 // Try to fill in the fulfill the packet request. 264 // Try to fill in the fulfill the packet request.
259 NotifyPacketReadyTask(); 265 NotifyPacketReadyTask();
260 } 266 }
261 267
262 void AudioRendererImpl::OnStateChanged(AudioStreamState state) { 268 void AudioRendererImpl::OnStateChanged(AudioStreamState state) {
263 DCHECK(MessageLoop::current() == io_loop_); 269 DCHECK(MessageLoop::current() == ChildProcess::current()->io_message_loop());
264 270
265 base::AutoLock auto_lock(lock_); 271 base::AutoLock auto_lock(lock_);
266 if (stopped_) 272 if (stopped_)
267 return; 273 return;
268 274
269 switch (state) { 275 switch (state) {
270 case kAudioStreamError: 276 case kAudioStreamError:
271 // We receive this error if we counter an hardware error on the browser 277 // We receive this error if we counter an hardware error on the browser
272 // side. We can proceed with ignoring the audio stream. 278 // side. We can proceed with ignoring the audio stream.
273 // TODO(hclam): We need more handling of these kind of error. For example 279 // TODO(hclam): We need more handling of these kind of error. For example
(...skipping 10 matching lines...) Expand all
284 break; 290 break;
285 } 291 }
286 } 292 }
287 293
288 void AudioRendererImpl::OnVolume(double volume) { 294 void AudioRendererImpl::OnVolume(double volume) {
289 // TODO(hclam): decide whether we need to report the current volume to 295 // TODO(hclam): decide whether we need to report the current volume to
290 // pipeline. 296 // pipeline.
291 } 297 }
292 298
293 void AudioRendererImpl::CreateStreamTask(const AudioParameters& audio_params) { 299 void AudioRendererImpl::CreateStreamTask(const AudioParameters& audio_params) {
294 DCHECK(MessageLoop::current() == io_loop_); 300 DCHECK(MessageLoop::current() == ChildProcess::current()->io_message_loop());
295 301
296 base::AutoLock auto_lock(lock_); 302 base::AutoLock auto_lock(lock_);
297 if (stopped_) 303 if (stopped_)
298 return; 304 return;
299 305
300 // Make sure we don't call create more than once. 306 // Make sure we don't call create more than once.
301 DCHECK_EQ(0, stream_id_); 307 DCHECK_EQ(0, stream_id_);
302 stream_id_ = filter_->AddDelegate(this); 308 stream_id_ = filter_->AddDelegate(this);
303 io_loop_->AddDestructionObserver(this); 309 ChildProcess::current()->io_message_loop()->AddDestructionObserver(this);
304 310
305 AudioParameters params_to_send(audio_params); 311 AudioParameters params_to_send(audio_params);
306 // Let the browser choose packet size. 312 // Let the browser choose packet size.
307 params_to_send.samples_per_packet = 0; 313 params_to_send.samples_per_packet = 0;
308 314
309 filter_->Send(new AudioHostMsg_CreateStream(0, 315 Send(new AudioHostMsg_CreateStream(stream_id_,
310 stream_id_, 316 params_to_send,
311 params_to_send, 317 latency_type_ == kLowLatency));
312 latency_type_ == kLowLatency));
313 } 318 }
314 319
315 void AudioRendererImpl::PlayTask() { 320 void AudioRendererImpl::PlayTask() {
316 DCHECK(MessageLoop::current() == io_loop_); 321 DCHECK(MessageLoop::current() == ChildProcess::current()->io_message_loop());
317 322
318 filter_->Send(new AudioHostMsg_PlayStream(0, stream_id_)); 323 Send(new AudioHostMsg_PlayStream(stream_id_));
319 } 324 }
320 325
321 void AudioRendererImpl::PauseTask() { 326 void AudioRendererImpl::PauseTask() {
322 DCHECK(MessageLoop::current() == io_loop_); 327 DCHECK(MessageLoop::current() == ChildProcess::current()->io_message_loop());
323 328
324 filter_->Send(new AudioHostMsg_PauseStream(0, stream_id_)); 329 Send(new AudioHostMsg_PauseStream(stream_id_));
325 } 330 }
326 331
327 void AudioRendererImpl::SeekTask() { 332 void AudioRendererImpl::SeekTask() {
328 DCHECK(MessageLoop::current() == io_loop_); 333 DCHECK(MessageLoop::current() == ChildProcess::current()->io_message_loop());
329 334
330 // We have to pause the audio stream before we can flush. 335 // We have to pause the audio stream before we can flush.
331 filter_->Send(new AudioHostMsg_PauseStream(0, stream_id_)); 336 Send(new AudioHostMsg_PauseStream(stream_id_));
332 filter_->Send(new AudioHostMsg_FlushStream(0, stream_id_)); 337 Send(new AudioHostMsg_FlushStream(stream_id_));
333 } 338 }
334 339
335 void AudioRendererImpl::DestroyTask() { 340 void AudioRendererImpl::DestroyTask() {
336 DCHECK(MessageLoop::current() == io_loop_); 341 DCHECK(MessageLoop::current() == ChildProcess::current()->io_message_loop());
337 342
338 // Make sure we don't call destroy more than once. 343 // Make sure we don't call destroy more than once.
339 DCHECK_NE(0, stream_id_); 344 DCHECK_NE(0, stream_id_);
340 filter_->RemoveDelegate(stream_id_); 345 filter_->RemoveDelegate(stream_id_);
341 filter_->Send(new AudioHostMsg_CloseStream(0, stream_id_)); 346 Send(new AudioHostMsg_CloseStream(stream_id_));
342 io_loop_->RemoveDestructionObserver(this); 347 ChildProcess::current()->io_message_loop()->RemoveDestructionObserver(this);
343 stream_id_ = 0; 348 stream_id_ = 0;
344 } 349 }
345 350
346 void AudioRendererImpl::SetVolumeTask(double volume) { 351 void AudioRendererImpl::SetVolumeTask(double volume) {
347 DCHECK(MessageLoop::current() == io_loop_); 352 DCHECK(MessageLoop::current() == ChildProcess::current()->io_message_loop());
348 353
349 base::AutoLock auto_lock(lock_); 354 base::AutoLock auto_lock(lock_);
350 if (stopped_) 355 if (stopped_)
351 return; 356 return;
352 filter_->Send(new AudioHostMsg_SetVolume(0, stream_id_, volume)); 357 Send(new AudioHostMsg_SetVolume(stream_id_, volume));
353 } 358 }
354 359
355 void AudioRendererImpl::NotifyPacketReadyTask() { 360 void AudioRendererImpl::NotifyPacketReadyTask() {
356 DCHECK(MessageLoop::current() == io_loop_); 361 DCHECK(MessageLoop::current() == ChildProcess::current()->io_message_loop());
357 DCHECK_EQ(kHighLatency, latency_type_); 362 DCHECK_EQ(kHighLatency, latency_type_);
358 363
359 base::AutoLock auto_lock(lock_); 364 base::AutoLock auto_lock(lock_);
360 if (stopped_) 365 if (stopped_)
361 return; 366 return;
362 if (pending_request_ && GetPlaybackRate() > 0.0f) { 367 if (pending_request_ && GetPlaybackRate() > 0.0f) {
363 DCHECK(shared_memory_.get()); 368 DCHECK(shared_memory_.get());
364 369
365 // Adjust the playback delay. 370 // Adjust the playback delay.
366 base::Time current_time = base::Time::Now(); 371 base::Time current_time = base::Time::Now();
(...skipping 19 matching lines...) Expand all
386 request_delay = base::TimeDelta::FromMicroseconds( 391 request_delay = base::TimeDelta::FromMicroseconds(
387 static_cast<int64>(ceil(request_delay.InMicroseconds() * 392 static_cast<int64>(ceil(request_delay.InMicroseconds() *
388 GetPlaybackRate()))); 393 GetPlaybackRate())));
389 } 394 }
390 395
391 uint32 filled = FillBuffer(static_cast<uint8*>(shared_memory_->memory()), 396 uint32 filled = FillBuffer(static_cast<uint8*>(shared_memory_->memory()),
392 shared_memory_size_, request_delay, 397 shared_memory_size_, request_delay,
393 request_buffers_state_.pending_bytes == 0); 398 request_buffers_state_.pending_bytes == 0);
394 pending_request_ = false; 399 pending_request_ = false;
395 // Then tell browser process we are done filling into the buffer. 400 // Then tell browser process we are done filling into the buffer.
396 filter_->Send(new AudioHostMsg_NotifyPacketReady(0, stream_id_, filled)); 401 Send(new AudioHostMsg_NotifyPacketReady(stream_id_, filled));
397 } 402 }
398 } 403 }
399 404
400 void AudioRendererImpl::WillDestroyCurrentMessageLoop() { 405 void AudioRendererImpl::WillDestroyCurrentMessageLoop() {
401 DCHECK(MessageLoop::current() == io_loop_); 406 DCHECK(MessageLoop::current() == ChildProcess::current()->io_message_loop());
402 407
403 // We treat the IO loop going away the same as stopping. 408 // We treat the IO loop going away the same as stopping.
404 base::AutoLock auto_lock(lock_); 409 base::AutoLock auto_lock(lock_);
405 if (stopped_) 410 if (stopped_)
406 return; 411 return;
407 412
408 stopped_ = true; 413 stopped_ = true;
409 DestroyTask(); 414 DestroyTask();
410 } 415 }
411 416
412 // Our audio thread runs here. We receive requests for more data and send it 417 // Our audio thread runs here. We receive requests for more data and send it
413 // on this thread. 418 // on this thread.
414 void AudioRendererImpl::Run() { 419 void AudioRendererImpl::Run() {
415 audio_thread_->SetThreadPriority(base::kThreadPriority_RealtimeAudio); 420 audio_thread_->SetThreadPriority(base::kThreadPriority_RealtimeAudio);
416 421
417 int bytes; 422 int bytes;
418 while (sizeof(bytes) == socket_->Receive(&bytes, sizeof(bytes))) { 423 while (sizeof(bytes) == socket_->Receive(&bytes, sizeof(bytes))) {
419 LOG(ERROR) << "+++ bytes: " << bytes; 424 LOG(ERROR) << "+++ bytes: " << bytes;
420 if (bytes == media::AudioOutputController::kPauseMark) 425 if (bytes == media::AudioOutputController::kPauseMark)
421 continue; 426 continue;
422 else if (bytes < 0) 427 else if (bytes < 0)
423 break; 428 break;
424 base::AutoLock auto_lock(lock_); 429 base::AutoLock auto_lock(lock_);
425 if (stopped_) 430 if (stopped_)
426 break; 431 break;
427 float playback_rate = GetPlaybackRate(); 432 float playback_rate = GetPlaybackRate();
428 if (playback_rate <= 0.0f) 433 if (playback_rate <= 0.0f)
429 continue; 434 continue;
430 DCHECK(shared_memory_.get()); 435 DCHECK(shared_memory_.get());
431 base::TimeDelta request_delay = ConvertToDuration(bytes); 436 base::TimeDelta request_delay = ConvertToDuration(bytes);
432 // We need to adjust the delay according to playback rate. 437 // We need to adjust the delay according to playback rate.
433 if (playback_rate != 1.0f) { 438 if (playback_rate != 1.0f) {
434 request_delay = base::TimeDelta::FromMicroseconds( 439 request_delay = base::TimeDelta::FromMicroseconds(
435 static_cast<int64>(ceil(request_delay.InMicroseconds() * 440 static_cast<int64>(ceil(request_delay.InMicroseconds() *
436 playback_rate))); 441 playback_rate)));
437 } 442 }
438 FillBuffer(static_cast<uint8*>(shared_memory_->memory()), 443 FillBuffer(static_cast<uint8*>(shared_memory_->memory()),
439 shared_memory_size_, 444 shared_memory_size_,
440 request_delay, 445 request_delay,
441 true /* buffers empty */); 446 true /* buffers empty */);
442 } 447 }
443 } 448 }
449
450 void AudioRendererImpl::Send(IPC::Message* message) {
451 filter_->Send(message);
452 }
OLDNEW
« no previous file with comments | « content/renderer/media/audio_renderer_impl.h ('k') | content/renderer/media/audio_renderer_impl_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698