Chromium Code Reviews| 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 |