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

Side by Side Diff: chrome/browser/renderer_host/audio_renderer_host.cc

Issue 99213: Measure IPC latency for audio... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Created 11 years, 7 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 | « no previous file | chrome/renderer/audio_message_filter.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) 2006-2009 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2006-2009 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 "base/histogram.h" 5 #include "base/histogram.h"
6 #include "base/lock.h" 6 #include "base/lock.h"
7 #include "base/message_loop.h" 7 #include "base/message_loop.h"
8 #include "base/process.h" 8 #include "base/process.h"
9 #include "base/shared_memory.h" 9 #include "base/shared_memory.h"
10 #include "base/waitable_event.h" 10 #include "base/waitable_event.h"
11 #include "chrome/browser/renderer_host/audio_renderer_host.h" 11 #include "chrome/browser/renderer_host/audio_renderer_host.h"
12 #include "chrome/common/ipc_logging.h"
12 #include "chrome/common/render_messages.h" 13 #include "chrome/common/render_messages.h"
13 14
14 namespace { 15 namespace {
15 16
16 void RecordIPCAudioLatency(base::TimeDelta latency) { 17 void RecordRoundTripLatency(base::TimeDelta latency) {
17 // Create a histogram of minimum 1ms and maximum 1000ms with 100 buckets. 18 static ThreadSafeHistogram histogram("Audio.IPC_RoundTripLatency",
18 static ThreadSafeHistogram histogram("Audio.IPCTransportLatency",
19 1, 1000, 100); 19 1, 1000, 100);
20 histogram.AddTime(latency); 20 histogram.AddTime(latency);
21 } 21 }
22 22
23 void RecordReceiveLatency(base::TimeDelta latency) {
24 static ThreadSafeHistogram histogram("Audio.IPC_Browser_ReceiveLatency",
25 1, 500, 100);
26 histogram.AddTime(latency);
27 }
28
29 void RecordProcessTime(base::TimeDelta latency) {
30 static ThreadSafeHistogram histogram("Audio.IPC_Browser_ProcessTime",
31 1, 100, 100);
32 histogram.AddTime(latency);
33 }
34
23 } // namespace 35 } // namespace
24 36
25 //----------------------------------------------------------------------------- 37 //-----------------------------------------------------------------------------
26 // AudioRendererHost::IPCAudioSource implementations. 38 // AudioRendererHost::IPCAudioSource implementations.
27 39
28 AudioRendererHost::IPCAudioSource::IPCAudioSource( 40 AudioRendererHost::IPCAudioSource::IPCAudioSource(
29 AudioRendererHost* host, 41 AudioRendererHost* host,
30 int process_id, 42 int process_id,
31 int route_id, 43 int route_id,
32 int stream_id, 44 int stream_id,
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
145 return; 157 return;
146 double left_channel, right_channel; 158 double left_channel, right_channel;
147 stream_->GetVolume(&left_channel, &right_channel); 159 stream_->GetVolume(&left_channel, &right_channel);
148 host_->Send(new ViewMsg_NotifyAudioStreamVolume(route_id_, stream_id_, 160 host_->Send(new ViewMsg_NotifyAudioStreamVolume(route_id_, stream_id_,
149 left_channel, right_channel)); 161 left_channel, right_channel));
150 } 162 }
151 163
152 size_t AudioRendererHost::IPCAudioSource::OnMoreData(AudioOutputStream* stream, 164 size_t AudioRendererHost::IPCAudioSource::OnMoreData(AudioOutputStream* stream,
153 void* dest, 165 void* dest,
154 size_t max_size) { 166 size_t max_size) {
155 base::TimeTicks tick_start = base::TimeTicks::HighResNow(); 167 #ifdef IPC_MESSAGE_LOG_ENABLED
scherkus (not reviewing) 2009/04/30 02:15:10 do you know how we get this defined?
168 base::Time tick_start = base::Time::Now();
scherkus (not reviewing) 2009/04/30 02:15:10 curious... why not HighResNow?
169 #endif
156 { 170 {
157 AutoLock auto_lock(lock_); 171 AutoLock auto_lock(lock_);
158 // If we are ever stopped, don't ask for more audio packet from the 172 // If we are ever stopped, don't ask for more audio packet from the
159 // renderer. 173 // renderer.
160 if (stop_providing_packets_) 174 if (stop_providing_packets_)
161 return 0; 175 return 0;
162 } 176 }
163 177
164 // If we have an initial packet, use it immediately only in IO thread. 178 // If we have an initial packet, use it immediately only in IO thread.
165 // There's a case when IO thread is blocked and audio hardware thread can 179 // There's a case when IO thread is blocked and audio hardware thread can
(...skipping 22 matching lines...) Expand all
188 packet_read_event_.Wait(); 202 packet_read_event_.Wait();
189 203
190 size_t last_packet_size = 0; 204 size_t last_packet_size = 0;
191 { 205 {
192 AutoLock auto_lock(lock_); 206 AutoLock auto_lock(lock_);
193 last_packet_size = last_packet_size_; 207 last_packet_size = last_packet_size_;
194 } 208 }
195 209
196 size_t copied = SafeCopyBuffer(dest, max_size, 210 size_t copied = SafeCopyBuffer(dest, max_size,
197 shared_memory_.memory(), last_packet_size); 211 shared_memory_.memory(), last_packet_size);
198 RecordIPCAudioLatency(base::TimeTicks::HighResNow() - tick_start); 212 #ifdef IPC_MESSAGE_LOG_ENABLED
213 // The logging to round trip latency doesn't have dependency on IPC logging.
214 // But it's good we use IPC logging to trigger logging of total latency.
215 if (IPC::Logging::current()->Enabled())
216 RecordRoundTripLatency(base::Time::Now() - tick_start);
217 #endif
199 return copied; 218 return copied;
200 } 219 }
201 220
202 void AudioRendererHost::IPCAudioSource::OnClose(AudioOutputStream* stream) { 221 void AudioRendererHost::IPCAudioSource::OnClose(AudioOutputStream* stream) {
203 StopWaitingForPacket(); 222 StopWaitingForPacket();
204 } 223 }
205 224
206 void AudioRendererHost::IPCAudioSource::OnError(AudioOutputStream* stream, 225 void AudioRendererHost::IPCAudioSource::OnError(AudioOutputStream* stream,
207 int code) { 226 int code) {
208 host_->SendErrorMessage(route_id_, stream_id_, code); 227 host_->SendErrorMessage(route_id_, stream_id_, code);
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after
406 425
407 void AudioRendererHost::OnNotifyPacketReady(const IPC::Message& msg, 426 void AudioRendererHost::OnNotifyPacketReady(const IPC::Message& msg,
408 int stream_id, size_t packet_size) { 427 int stream_id, size_t packet_size) {
409 DCHECK(MessageLoop::current() == io_loop_); 428 DCHECK(MessageLoop::current() == io_loop_);
410 IPCAudioSource* source = Lookup(msg.routing_id(), stream_id); 429 IPCAudioSource* source = Lookup(msg.routing_id(), stream_id);
411 if (source) { 430 if (source) {
412 source->NotifyPacketReady(packet_size); 431 source->NotifyPacketReady(packet_size);
413 } else { 432 } else {
414 SendErrorMessage(msg.routing_id(), stream_id, 0); 433 SendErrorMessage(msg.routing_id(), stream_id, 0);
415 } 434 }
435 #ifdef IPC_MESSAGE_LOG_ENABLED
436 if (IPC::Logging::current()->Enabled()) {
437 RecordReceiveLatency(base::Time::FromInternalValue(msg.received_time()) -
438 base::Time::FromInternalValue(msg.sent_time()));
439 RecordProcessTime(base::Time::Now() -
440 base::Time::FromInternalValue(msg.received_time()));
441 }
442 #endif
416 } 443 }
417 444
418 void AudioRendererHost::OnInitialized() { 445 void AudioRendererHost::OnInitialized() {
419 DCHECK(MessageLoop::current() == io_loop_); 446 DCHECK(MessageLoop::current() == io_loop_);
420 // Increase the ref count of this object so it is active until we do 447 // Increase the ref count of this object so it is active until we do
421 // Release(). 448 // Release().
422 AddRef(); 449 AddRef();
423 } 450 }
424 451
425 void AudioRendererHost::OnDestroyed() { 452 void AudioRendererHost::OnDestroyed() {
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
491 if (MessageLoop::current() == io_loop_) { 518 if (MessageLoop::current() == io_loop_) {
492 OnDestroySource(source); 519 OnDestroySource(source);
493 } else { 520 } else {
494 // TODO(hclam): make sure it's always safe to post a task to IO loop. 521 // TODO(hclam): make sure it's always safe to post a task to IO loop.
495 // It is possible that IO message loop is destroyed but there's still some 522 // It is possible that IO message loop is destroyed but there's still some
496 // dangling audio hardware threads that try to call this method. 523 // dangling audio hardware threads that try to call this method.
497 io_loop_->PostTask(FROM_HERE, 524 io_loop_->PostTask(FROM_HERE,
498 NewRunnableMethod(this, &AudioRendererHost::OnDestroySource, source)); 525 NewRunnableMethod(this, &AudioRendererHost::OnDestroySource, source));
499 } 526 }
500 } 527 }
OLDNEW
« no previous file with comments | « no previous file | chrome/renderer/audio_message_filter.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698