OLD | NEW |
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 #include "content/browser/renderer_host/media/audio_sync_reader.h" | 5 #include "content/browser/renderer_host/media/audio_sync_reader.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/metrics/histogram.h" | 9 #include "base/metrics/histogram.h" |
10 #include "base/process_util.h" | 10 #include "base/process_util.h" |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
61 // Store unknown length of data into buffer, so we later | 61 // Store unknown length of data into buffer, so we later |
62 // can find out if data became available. | 62 // can find out if data became available. |
63 media::SetUnknownDataSize(shared_memory_, packet_size_); | 63 media::SetUnknownDataSize(shared_memory_, packet_size_); |
64 } | 64 } |
65 | 65 |
66 if (socket_) { | 66 if (socket_) { |
67 socket_->Send(&bytes, sizeof(bytes)); | 67 socket_->Send(&bytes, sizeof(bytes)); |
68 } | 68 } |
69 } | 69 } |
70 | 70 |
71 int AudioSyncReader::Read(AudioBus* source, AudioBus* dest) { | 71 int AudioSyncReader::Read(bool block, const AudioBus* source, AudioBus* dest) { |
72 ++renderer_callback_count_; | 72 ++renderer_callback_count_; |
73 if (!DataReady()) | 73 if (!DataReady()) { |
74 ++renderer_missed_callback_count_; | 74 ++renderer_missed_callback_count_; |
75 | 75 |
| 76 if (block) |
| 77 WaitTillDataReady(); |
| 78 } |
| 79 |
76 // Copy optional synchronized live audio input for consumption by renderer | 80 // Copy optional synchronized live audio input for consumption by renderer |
77 // process. | 81 // process. |
78 if (source && input_bus_) { | 82 if (source && input_bus_) { |
79 DCHECK_EQ(source->channels(), input_bus_->channels()); | 83 DCHECK_EQ(source->channels(), input_bus_->channels()); |
80 // TODO(crogers): In some cases with device and sample-rate changes | 84 // TODO(crogers): In some cases with device and sample-rate changes |
81 // it's possible for an AOR to insert a resampler in the path. | 85 // it's possible for an AOR to insert a resampler in the path. |
82 // Because this is used with the Web Audio API, it'd be better | 86 // Because this is used with the Web Audio API, it'd be better |
83 // to bypass the device change handling in AOR and instead let | 87 // to bypass the device change handling in AOR and instead let |
84 // the renderer-side Web Audio code deal with this. | 88 // the renderer-side Web Audio code deal with this. |
85 if (source->frames() == input_bus_->frames() && | 89 if (source->frames() == input_bus_->frames() && |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
155 base::ProcessHandle process_handle, | 159 base::ProcessHandle process_handle, |
156 base::FileDescriptor* foreign_handle) { | 160 base::FileDescriptor* foreign_handle) { |
157 foreign_handle->fd = foreign_socket_->handle(); | 161 foreign_handle->fd = foreign_socket_->handle(); |
158 foreign_handle->auto_close = false; | 162 foreign_handle->auto_close = false; |
159 if (foreign_handle->fd != -1) | 163 if (foreign_handle->fd != -1) |
160 return true; | 164 return true; |
161 return false; | 165 return false; |
162 } | 166 } |
163 #endif | 167 #endif |
164 | 168 |
| 169 void AudioSyncReader::WaitTillDataReady() { |
| 170 base::TimeTicks start = base::TimeTicks::Now(); |
| 171 const base::TimeDelta kMaxWait = base::TimeDelta::FromMilliseconds(20); |
| 172 #if defined(OS_WIN) |
| 173 // Sleep(0) on Windows lets the other threads run. |
| 174 const base::TimeDelta kSleep = base::TimeDelta::FromMilliseconds(0); |
| 175 #else |
| 176 // We want to sleep for a bit here, as otherwise a backgrounded renderer won't |
| 177 // get enough cpu to send the data and the high priority thread in the browser |
| 178 // will use up a core causing even more skips. |
| 179 const base::TimeDelta kSleep = base::TimeDelta::FromMilliseconds(2); |
| 180 #endif |
| 181 base::TimeDelta time_since_start; |
| 182 do { |
| 183 base::PlatformThread::Sleep(kSleep); |
| 184 time_since_start = base::TimeTicks::Now() - start; |
| 185 } while (!DataReady() && time_since_start < kMaxWait); |
| 186 UMA_HISTOGRAM_CUSTOM_TIMES("Media.AudioOutputControllerDataNotReady", |
| 187 time_since_start, |
| 188 base::TimeDelta::FromMilliseconds(1), |
| 189 base::TimeDelta::FromMilliseconds(1000), |
| 190 50); |
| 191 } |
| 192 |
165 } // namespace content | 193 } // namespace content |
OLD | NEW |