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 #include <string> | |
9 #include <utility> | |
8 | 10 |
9 #include "base/command_line.h" | 11 #include "base/command_line.h" |
10 #include "base/format_macros.h" | 12 #include "base/format_macros.h" |
11 #include "base/memory/shared_memory.h" | 13 #include "base/memory/shared_memory.h" |
12 #include "base/metrics/histogram_macros.h" | 14 #include "base/metrics/histogram_macros.h" |
13 #include "base/strings/stringprintf.h" | 15 #include "base/strings/stringprintf.h" |
14 #include "base/trace_event/trace_event.h" | 16 #include "base/trace_event/trace_event.h" |
15 #include "build/build_config.h" | 17 #include "build/build_config.h" |
16 #include "content/browser/renderer_host/media/media_stream_manager.h" | 18 #include "content/browser/renderer_host/media/media_stream_manager.h" |
17 #include "content/public/common/content_switches.h" | 19 #include "content/public/common/content_switches.h" |
(...skipping 15 matching lines...) Expand all Loading... | |
33 void LogAudioGlitchResult(AudioGlitchResult result) { | 35 void LogAudioGlitchResult(AudioGlitchResult result) { |
34 UMA_HISTOGRAM_ENUMERATION("Media.AudioRendererAudioGlitches", | 36 UMA_HISTOGRAM_ENUMERATION("Media.AudioRendererAudioGlitches", |
35 result, | 37 result, |
36 AUDIO_RENDERER_AUDIO_GLITCHES_MAX + 1); | 38 AUDIO_RENDERER_AUDIO_GLITCHES_MAX + 1); |
37 } | 39 } |
38 | 40 |
39 } // namespace | 41 } // namespace |
40 | 42 |
41 namespace content { | 43 namespace content { |
42 | 44 |
43 AudioSyncReader::AudioSyncReader(base::SharedMemory* shared_memory, | 45 AudioSyncReader::AudioSyncReader( |
44 const media::AudioParameters& params) | 46 const media::AudioParameters& params, |
45 : shared_memory_(shared_memory), | 47 std::unique_ptr<base::SharedMemory> shared_memory, |
48 std::unique_ptr<base::CancelableSyncSocket> socket, | |
49 std::unique_ptr<base::CancelableSyncSocket> foreign_socket) | |
50 : shared_memory_(std::move(shared_memory)), | |
46 mute_audio_(base::CommandLine::ForCurrentProcess()->HasSwitch( | 51 mute_audio_(base::CommandLine::ForCurrentProcess()->HasSwitch( |
47 switches::kMuteAudio)), | 52 switches::kMuteAudio)), |
53 socket_(std::move(socket)), | |
54 foreign_socket_(std::move(foreign_socket)), | |
48 packet_size_(shared_memory_->requested_size()), | 55 packet_size_(shared_memory_->requested_size()), |
49 renderer_callback_count_(0), | 56 renderer_callback_count_(0), |
50 renderer_missed_callback_count_(0), | 57 renderer_missed_callback_count_(0), |
51 trailing_renderer_missed_callback_count_(0), | 58 trailing_renderer_missed_callback_count_(0), |
52 #if defined(OS_MACOSX) | 59 #if defined(OS_MACOSX) |
53 maximum_wait_time_(params.GetBufferDuration() / 2), | 60 maximum_wait_time_(params.GetBufferDuration() / 2), |
54 #else | 61 #else |
55 // TODO(dalecurtis): Investigate if we can reduce this on all platforms. | 62 // TODO(dalecurtis): Investigate if we can reduce this on all platforms. |
56 maximum_wait_time_(base::TimeDelta::FromMilliseconds(20)), | 63 maximum_wait_time_(base::TimeDelta::FromMilliseconds(20)), |
57 #endif | 64 #endif |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
100 renderer_missed_callback_count_ > 0 ? | 107 renderer_missed_callback_count_ > 0 ? |
101 LogAudioGlitchResult(AUDIO_RENDERER_AUDIO_GLITCHES) : | 108 LogAudioGlitchResult(AUDIO_RENDERER_AUDIO_GLITCHES) : |
102 LogAudioGlitchResult(AUDIO_RENDERER_NO_AUDIO_GLITCHES); | 109 LogAudioGlitchResult(AUDIO_RENDERER_NO_AUDIO_GLITCHES); |
103 std::string log_string = base::StringPrintf( | 110 std::string log_string = base::StringPrintf( |
104 "ASR: number of detected audio glitches: %" PRIuS " out of %" PRIuS, | 111 "ASR: number of detected audio glitches: %" PRIuS " out of %" PRIuS, |
105 renderer_missed_callback_count_, renderer_callback_count_); | 112 renderer_missed_callback_count_, renderer_callback_count_); |
106 MediaStreamManager::SendMessageToNativeLog(log_string); | 113 MediaStreamManager::SendMessageToNativeLog(log_string); |
107 DVLOG(1) << log_string; | 114 DVLOG(1) << log_string; |
108 } | 115 } |
109 | 116 |
117 // static | |
118 std::unique_ptr<AudioSyncReader> AudioSyncReader::Create( | |
119 const media::AudioParameters& params) { | |
120 std::unique_ptr<base::SharedMemory> shared_memory(new base::SharedMemory()); | |
121 std::unique_ptr<base::CancelableSyncSocket> socket( | |
122 new base::CancelableSyncSocket()); | |
123 std::unique_ptr<base::CancelableSyncSocket> foreign_socket( | |
124 new base::CancelableSyncSocket()); | |
125 | |
126 size_t memory_size = sizeof(media::AudioOutputBufferParameters) + | |
o1ka
2016/09/16 10:51:59
const
Max Morin
2016/09/16 12:46:15
Done.
| |
127 AudioBus::CalculateMemorySize(params); | |
o1ka
2016/09/16 10:51:59
Since this is the value to be sent over IPC in the
Max Morin
2016/09/16 12:46:15
Yes. Thinking about it, I'm not sure there's anyth
| |
128 | |
129 if (!shared_memory->CreateAndMapAnonymous(memory_size) || | |
130 !base::CancelableSyncSocket::CreatePair(socket.get(), | |
131 foreign_socket.get())) { | |
132 return {}; | |
133 } | |
134 return std::unique_ptr<AudioSyncReader>( | |
135 new AudioSyncReader(params, std::move(shared_memory), std::move(socket), | |
136 std::move(foreign_socket))); | |
137 } | |
138 | |
110 // media::AudioOutputController::SyncReader implementations. | 139 // media::AudioOutputController::SyncReader implementations. |
111 void AudioSyncReader::UpdatePendingBytes(uint32_t bytes, | 140 void AudioSyncReader::UpdatePendingBytes(uint32_t bytes, |
112 uint32_t frames_skipped) { | 141 uint32_t frames_skipped) { |
113 // Increase the number of skipped frames stored in shared memory. We don't | 142 // Increase the number of skipped frames stored in shared memory. We don't |
114 // send it over the socket since sending more than 4 bytes might lead to being | 143 // send it over the socket since sending more than 4 bytes might lead to being |
115 // descheduled. The reading side will zero it when consumed. | 144 // descheduled. The reading side will zero it when consumed. |
116 AudioOutputBuffer* buffer = | 145 AudioOutputBuffer* buffer = |
117 reinterpret_cast<AudioOutputBuffer*>(shared_memory_->memory()); | 146 reinterpret_cast<AudioOutputBuffer*>(shared_memory_->memory()); |
118 buffer->params.frames_skipped += frames_skipped; | 147 buffer->params.frames_skipped += frames_skipped; |
119 | 148 |
(...skipping 25 matching lines...) Expand all Loading... | |
145 if (mute_audio_) | 174 if (mute_audio_) |
146 dest->Zero(); | 175 dest->Zero(); |
147 else | 176 else |
148 output_bus_->CopyTo(dest); | 177 output_bus_->CopyTo(dest); |
149 } | 178 } |
150 | 179 |
151 void AudioSyncReader::Close() { | 180 void AudioSyncReader::Close() { |
152 socket_->Close(); | 181 socket_->Close(); |
153 } | 182 } |
154 | 183 |
155 bool AudioSyncReader::Init() { | |
156 socket_.reset(new base::CancelableSyncSocket()); | |
157 foreign_socket_.reset(new base::CancelableSyncSocket()); | |
158 return base::CancelableSyncSocket::CreatePair(socket_.get(), | |
159 foreign_socket_.get()); | |
160 } | |
161 | |
162 bool AudioSyncReader::PrepareForeignSocket( | |
163 base::ProcessHandle process_handle, | |
164 base::SyncSocket::TransitDescriptor* descriptor) { | |
165 return foreign_socket_->PrepareTransitDescriptor(process_handle, descriptor); | |
166 } | |
167 | |
168 bool AudioSyncReader::WaitUntilDataIsReady() { | 184 bool AudioSyncReader::WaitUntilDataIsReady() { |
169 TRACE_EVENT0("audio", "AudioSyncReader::WaitUntilDataIsReady"); | 185 TRACE_EVENT0("audio", "AudioSyncReader::WaitUntilDataIsReady"); |
170 base::TimeDelta timeout = maximum_wait_time_; | 186 base::TimeDelta timeout = maximum_wait_time_; |
171 const base::TimeTicks start_time = base::TimeTicks::Now(); | 187 const base::TimeTicks start_time = base::TimeTicks::Now(); |
172 const base::TimeTicks finish_time = start_time + timeout; | 188 const base::TimeTicks finish_time = start_time + timeout; |
173 | 189 |
174 // Check if data is ready and if not, wait a reasonable amount of time for it. | 190 // Check if data is ready and if not, wait a reasonable amount of time for it. |
175 // | 191 // |
176 // Data readiness is achieved via parallel counters, one on the renderer side | 192 // Data readiness is achieved via parallel counters, one on the renderer side |
177 // and one here. Every time a buffer is requested via UpdatePendingBytes(), | 193 // and one here. Every time a buffer is requested via UpdatePendingBytes(), |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
213 base::TimeDelta::FromMilliseconds(1), | 229 base::TimeDelta::FromMilliseconds(1), |
214 base::TimeDelta::FromMilliseconds(1000), | 230 base::TimeDelta::FromMilliseconds(1000), |
215 50); | 231 50); |
216 return false; | 232 return false; |
217 } | 233 } |
218 | 234 |
219 return true; | 235 return true; |
220 } | 236 } |
221 | 237 |
222 } // namespace content | 238 } // namespace content |
OLD | NEW |