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

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

Issue 155695: Replace the guts of AudioRendererBase with calls to scaling algorithm. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 11 years, 4 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
« no previous file with comments | « chrome/renderer/media/audio_renderer_impl.h ('k') | media/base/buffer_queue.h » ('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) 2009 The Chromium Authors. All rights reserved. Use of this 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. Use of this
2 // source code is governed by a BSD-style license that can be found in the 2 // source code is governed by a BSD-style license that can be found in the
3 // LICENSE file. 3 // LICENSE file.
4 4
5 #include "chrome/common/render_messages.h" 5 #include "chrome/common/render_messages.h"
6 #include "chrome/renderer/audio_message_filter.h" 6 #include "chrome/renderer/audio_message_filter.h"
7 #include "chrome/renderer/media/audio_renderer_impl.h" 7 #include "chrome/renderer/media/audio_renderer_impl.h"
8 #include "chrome/renderer/render_view.h" 8 #include "chrome/renderer/render_view.h"
9 #include "chrome/renderer/render_thread.h" 9 #include "chrome/renderer/render_thread.h"
10 #include "media/base/filter_host.h" 10 #include "media/base/filter_host.h"
11 11
12 namespace { 12 namespace {
13 13
14 // We will try to fill 200 ms worth of audio samples in each packet. A round 14 // We will try to fill 200 ms worth of audio samples in each packet. A round
15 // trip latency for IPC messages are typically 10 ms, this should give us 15 // trip latency for IPC messages are typically 10 ms, this should give us
16 // plenty of time to avoid clicks. 16 // plenty of time to avoid clicks.
17 const int kMillisecondsPerPacket = 200; 17 const int kMillisecondsPerPacket = 200;
18 18
19 // We have at most 3 packets in browser, i.e. 600 ms. This is a reasonable 19 // We have at most 3 packets in browser, i.e. 600 ms. This is a reasonable
20 // amount to avoid clicks. 20 // amount to avoid clicks.
21 const int kPacketsInBuffer = 3; 21 const int kPacketsInBuffer = 3;
22 22
23 // We want to preroll 400 milliseconds before starting to play. Again, 400 ms 23 // We want to preroll 400 milliseconds before starting to play. Again, 400 ms
24 // of audio data should give us enough time to get more from the renderer. 24 // of audio data should give us enough time to get more from the renderer.
25 const int kMillisecondsPreroll = 400; 25 const int kMillisecondsPreroll = 400;
26 26
27 } // namespace 27 } // namespace
28 28
29 AudioRendererImpl::AudioRendererImpl(AudioMessageFilter* filter) 29 AudioRendererImpl::AudioRendererImpl(AudioMessageFilter* filter)
30 : AudioRendererBase(kDefaultMaxQueueSize), 30 : AudioRendererBase(),
31 channels_(0), 31 channels_(0),
32 sample_rate_(0), 32 sample_rate_(0),
33 sample_bits_(0), 33 sample_bits_(0),
34 bytes_per_second_(0), 34 bytes_per_second_(0),
35 filter_(filter), 35 filter_(filter),
36 stream_id_(0), 36 stream_id_(0),
37 shared_memory_(NULL), 37 shared_memory_(NULL),
38 shared_memory_size_(0), 38 shared_memory_size_(0),
39 io_loop_(filter->message_loop()), 39 io_loop_(filter->message_loop()),
40 stopped_(false), 40 stopped_(false),
41 playback_rate_(0.0f),
42 pending_request_(false), 41 pending_request_(false),
43 prerolling_(true), 42 prerolling_(true),
44 preroll_bytes_(0) { 43 preroll_bytes_(0) {
45 DCHECK(io_loop_); 44 DCHECK(io_loop_);
46 } 45 }
47 46
48 AudioRendererImpl::~AudioRendererImpl() { 47 AudioRendererImpl::~AudioRendererImpl() {
49 } 48 }
50 49
51 base::TimeDelta AudioRendererImpl::ConvertToDuration(int bytes) { 50 base::TimeDelta AudioRendererImpl::ConvertToDuration(int bytes) {
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
110 109
111 // Post a task to render thread to notify a packet reception. 110 // Post a task to render thread to notify a packet reception.
112 io_loop_->PostTask(FROM_HERE, 111 io_loop_->PostTask(FROM_HERE,
113 NewRunnableMethod(this, &AudioRendererImpl::OnNotifyPacketReady)); 112 NewRunnableMethod(this, &AudioRendererImpl::OnNotifyPacketReady));
114 } 113 }
115 114
116 void AudioRendererImpl::SetPlaybackRate(float rate) { 115 void AudioRendererImpl::SetPlaybackRate(float rate) {
117 DCHECK(rate >= 0.0f); 116 DCHECK(rate >= 0.0f);
118 117
119 // We have two cases here: 118 // We have two cases here:
120 // Play: playback_rate_ == 0.0 && rate != 0.0 119 // Play: GetPlaybackRate() == 0.0 && rate != 0.0
121 // Pause: playback_rate_ != 0.0 && rate == 0.0 120 // Pause: GetPlaybackRate() != 0.0 && rate == 0.0
122 AutoLock auto_lock(lock_); 121 AutoLock auto_lock(lock_);
123 if (playback_rate_ == 0.0f && rate != 0.0f) { 122 if (GetPlaybackRate() == 0.0f && rate != 0.0f) {
124 // Play is a bit tricky, we can only play if we have done prerolling. 123 // Play is a bit tricky, we can only play if we have done prerolling.
125 // TODO(hclam): I should check for end of streams status here. 124 // TODO(hclam): I should check for end of streams status here.
126 if (!prerolling_) 125 if (!prerolling_)
127 io_loop_->PostTask(FROM_HERE, 126 io_loop_->PostTask(FROM_HERE,
128 NewRunnableMethod(this, &AudioRendererImpl::OnPlay)); 127 NewRunnableMethod(this, &AudioRendererImpl::OnPlay));
129 } else if (playback_rate_ != 0.0f && rate == 0.0f) { 128 } else if (GetPlaybackRate() != 0.0f && rate == 0.0f) {
130 // Pause is easy, we can always pause. 129 // Pause is easy, we can always pause.
131 io_loop_->PostTask(FROM_HERE, 130 io_loop_->PostTask(FROM_HERE,
132 NewRunnableMethod(this, &AudioRendererImpl::OnPause)); 131 NewRunnableMethod(this, &AudioRendererImpl::OnPause));
133 } 132 }
134 playback_rate_ = rate; 133 AudioRendererBase::SetPlaybackRate(rate);
135 134
136 // If we are playing, give a kick to try fulfilling the packet request as 135 // If we are playing, give a kick to try fulfilling the packet request as
137 // the previous packet request may be stalled by a pause. 136 // the previous packet request may be stalled by a pause.
138 if (rate > 0.0f) { 137 if (rate > 0.0f) {
139 io_loop_->PostTask( 138 io_loop_->PostTask(
140 FROM_HERE, 139 FROM_HERE,
141 NewRunnableMethod(this, &AudioRendererImpl::OnNotifyPacketReady)); 140 NewRunnableMethod(this, &AudioRendererImpl::OnNotifyPacketReady));
142 } 141 }
143 } 142 }
144 143
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
266 return; 265 return;
267 filter_->Send(new ViewHostMsg_SetAudioVolume(0, stream_id_, left, right)); 266 filter_->Send(new ViewHostMsg_SetAudioVolume(0, stream_id_, left, right));
268 } 267 }
269 268
270 void AudioRendererImpl::OnNotifyPacketReady() { 269 void AudioRendererImpl::OnNotifyPacketReady() {
271 DCHECK(MessageLoop::current() == io_loop_); 270 DCHECK(MessageLoop::current() == io_loop_);
272 271
273 AutoLock auto_lock(lock_); 272 AutoLock auto_lock(lock_);
274 if (stopped_) 273 if (stopped_)
275 return; 274 return;
276 if (pending_request_ && playback_rate_ > 0.0f) { 275 if (pending_request_ && GetPlaybackRate() > 0.0f) {
277 DCHECK(shared_memory_.get()); 276 DCHECK(shared_memory_.get());
278 277
279 // Adjust the playback delay. 278 // Adjust the playback delay.
280 base::Time current_time = base::Time::Now(); 279 base::Time current_time = base::Time::Now();
281 280
282 // Save a local copy of the request delay. 281 // Save a local copy of the request delay.
283 base::TimeDelta request_delay = request_delay_; 282 base::TimeDelta request_delay = request_delay_;
284 if (current_time > request_timestamp_) { 283 if (current_time > request_timestamp_) {
285 base::TimeDelta receive_latency = current_time - request_timestamp_; 284 base::TimeDelta receive_latency = current_time - request_timestamp_;
286 285
287 // If the receive latency is too much it may offset all the delay. 286 // If the receive latency is too much it may offset all the delay.
288 if (receive_latency >= request_delay) { 287 if (receive_latency >= request_delay) {
289 request_delay = base::TimeDelta(); 288 request_delay = base::TimeDelta();
290 } else { 289 } else {
291 request_delay -= receive_latency; 290 request_delay -= receive_latency;
292 } 291 }
293 } 292 }
294 293
295 size_t filled = FillBuffer(static_cast<uint8*>(shared_memory_->memory()), 294 size_t filled = FillBuffer(static_cast<uint8*>(shared_memory_->memory()),
296 shared_memory_size_, 295 shared_memory_size_,
297 playback_rate_,
298 request_delay); 296 request_delay);
299 // TODO(hclam): we should try to fill in the buffer as much as possible. 297 // TODO(hclam): we should try to fill in the buffer as much as possible.
300 if (filled > 0) { 298 if (filled > 0) {
301 pending_request_ = false; 299 pending_request_ = false;
302 request_delay_ = base::TimeDelta(); 300 request_delay_ = base::TimeDelta();
303 request_timestamp_ = base::Time(); 301 request_timestamp_ = base::Time();
304 // Then tell browser process we are done filling into the buffer. 302 // Then tell browser process we are done filling into the buffer.
305 filter_->Send( 303 filter_->Send(
306 new ViewHostMsg_NotifyAudioPacketReady(0, stream_id_, filled)); 304 new ViewHostMsg_NotifyAudioPacketReady(0, stream_id_, filled));
307 305
308 if (prerolling_) { 306 if (prerolling_) {
309 // We have completed prerolling. 307 // We have completed prerolling.
310 if (filled > preroll_bytes_) { 308 if (filled > preroll_bytes_) {
311 prerolling_ = false; 309 prerolling_ = false;
312 preroll_bytes_ = 0; 310 preroll_bytes_ = 0;
313 filter_->Send(new ViewHostMsg_StartAudioStream(0, stream_id_)); 311 filter_->Send(new ViewHostMsg_StartAudioStream(0, stream_id_));
314 } else { 312 } else {
315 preroll_bytes_ -= filled; 313 preroll_bytes_ -= filled;
316 } 314 }
317 } 315 }
318 } 316 }
319 } 317 }
320 } 318 }
OLDNEW
« no previous file with comments | « chrome/renderer/media/audio_renderer_impl.h ('k') | media/base/buffer_queue.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698