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

Side by Side Diff: third_party/WebKit/Source/platform/audio/AudioDestination.cpp

Issue 2854463002: Fix data race in AudioDestination.cpp (Closed)
Patch Set: SampleRate() fix after l-g-t-m Created 3 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
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2010 Google Inc. All rights reserved. 2 * Copyright (C) 2010 Google Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions 5 * modification, are permitted provided that the following conditions
6 * are met: 6 * are met:
7 * 7 *
8 * 1. Redistributions of source code must retain the above copyright 8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
60 new AudioDestination(callback, number_of_output_channels, latency_hint, 60 new AudioDestination(callback, number_of_output_channels, latency_hint,
61 std::move(security_origin))); 61 std::move(security_origin)));
62 } 62 }
63 63
64 AudioDestination::AudioDestination(AudioIOCallback& callback, 64 AudioDestination::AudioDestination(AudioIOCallback& callback,
65 unsigned number_of_output_channels, 65 unsigned number_of_output_channels,
66 const WebAudioLatencyHint& latency_hint, 66 const WebAudioLatencyHint& latency_hint,
67 PassRefPtr<SecurityOrigin> security_origin) 67 PassRefPtr<SecurityOrigin> security_origin)
68 : number_of_output_channels_(number_of_output_channels), 68 : number_of_output_channels_(number_of_output_channels),
69 is_playing_(false), 69 is_playing_(false),
70 fifo_(WTF::WrapUnique(
nhiroki 2017/05/02 01:42:51 MakeUnique?
71 new PushPullFIFO(number_of_output_channels, kFIFOSize))),
70 rendering_thread_(WTF::WrapUnique( 72 rendering_thread_(WTF::WrapUnique(
71 Platform::Current()->CreateThread("WebAudio Rendering Thread"))), 73 Platform::Current()->CreateThread("WebAudio Rendering Thread"))),
72 fifo_(WTF::WrapUnique(
73 new PushPullFIFO(number_of_output_channels, kFIFOSize))),
74 output_bus_(AudioBus::Create(number_of_output_channels, 74 output_bus_(AudioBus::Create(number_of_output_channels,
75 AudioUtilities::kRenderQuantumFrames, 75 AudioUtilities::kRenderQuantumFrames,
76 false)), 76 false)),
77 render_bus_(AudioBus::Create(number_of_output_channels, 77 render_bus_(AudioBus::Create(number_of_output_channels,
78 AudioUtilities::kRenderQuantumFrames)), 78 AudioUtilities::kRenderQuantumFrames)),
79 callback_(callback), 79 callback_(callback),
80 frames_elapsed_(0) { 80 frames_elapsed_(0) {
81 // Create WebAudioDevice. blink::WebAudioDevice is designed to support the 81 // Create WebAudioDevice. blink::WebAudioDevice is designed to support the
82 // local input (e.g. loopback from OS audio system), but Chromium's media 82 // local input (e.g. loopback from OS audio system), but Chromium's media
83 // renderer does not support it currently. Thus, we use zero for the number 83 // renderer does not support it currently. Thus, we use zero for the number
(...skipping 30 matching lines...) Expand all
114 if (!fifo_ || fifo_->length() < number_of_frames) 114 if (!fifo_ || fifo_->length() < number_of_frames)
115 return; 115 return;
116 116
117 // Associate the destination data array with the output bus then fill the 117 // Associate the destination data array with the output bus then fill the
118 // FIFO. 118 // FIFO.
119 for (unsigned i = 0; i < number_of_output_channels_; ++i) 119 for (unsigned i = 0; i < number_of_output_channels_; ++i)
120 output_bus_->SetChannelMemory(i, destination_data[i], number_of_frames); 120 output_bus_->SetChannelMemory(i, destination_data[i], number_of_frames);
121 121
122 size_t frames_to_render = fifo_->Pull(output_bus_.Get(), number_of_frames); 122 size_t frames_to_render = fifo_->Pull(output_bus_.Get(), number_of_frames);
123 123
124 rendering_thread_->GetWebTaskRunner()->PostTask( 124 // TODO(hongchan): this check might be redundant, so consider removing later.
125 BLINK_FROM_HERE, 125 if (frames_to_render != 0 && rendering_thread_) {
126 CrossThreadBind(&AudioDestination::RequestRenderOnWebThread, 126 rendering_thread_->GetWebTaskRunner()->PostTask(
127 CrossThreadUnretained(this), 127 BLINK_FROM_HERE,
128 number_of_frames, frames_to_render, 128 CrossThreadBind(&AudioDestination::RequestRenderOnWebThread,
129 delay, delay_timestamp, prior_frames_skipped)); 129 CrossThreadUnretained(this), number_of_frames,
130 frames_to_render, delay, delay_timestamp,
131 prior_frames_skipped));
132 }
130 } 133 }
131 134
132 void AudioDestination::RequestRenderOnWebThread(size_t frames_requested, 135 void AudioDestination::RequestRenderOnWebThread(size_t frames_requested,
133 size_t frames_to_render, 136 size_t frames_to_render,
134 double delay, 137 double delay,
135 double delay_timestamp, 138 double delay_timestamp,
136 size_t prior_frames_skipped) { 139 size_t prior_frames_skipped) {
137 // This method is called by WebThread. 140 // This method is called by WebThread.
138 DCHECK(IsRenderingThread()); 141 DCHECK(IsRenderingThread());
139 142
(...skipping 24 matching lines...) Expand all
164 // Process WebAudio graph and push the rendered output to FIFO. 167 // Process WebAudio graph and push the rendered output to FIFO.
165 callback_.Render(nullptr, render_bus_.Get(), 168 callback_.Render(nullptr, render_bus_.Get(),
166 AudioUtilities::kRenderQuantumFrames, output_position); 169 AudioUtilities::kRenderQuantumFrames, output_position);
167 fifo_->Push(render_bus_.Get()); 170 fifo_->Push(render_bus_.Get());
168 } 171 }
169 172
170 frames_elapsed_ += frames_requested; 173 frames_elapsed_ += frames_requested;
171 } 174 }
172 175
173 void AudioDestination::Start() { 176 void AudioDestination::Start() {
177 DCHECK(WTF::IsMainThread());
174 if (web_audio_device_ && !is_playing_) { 178 if (web_audio_device_ && !is_playing_) {
175 web_audio_device_->Start(); 179 web_audio_device_->Start();
176 is_playing_ = true; 180 is_playing_ = true;
177 } 181 }
178 } 182 }
179 183
180 void AudioDestination::Stop() { 184 void AudioDestination::Stop() {
185 DCHECK(WTF::IsMainThread());
181 if (web_audio_device_ && is_playing_) { 186 if (web_audio_device_ && is_playing_) {
187 // This stops the callback from the device thread synchronously.
182 web_audio_device_->Stop(); 188 web_audio_device_->Stop();
189
183 is_playing_ = false; 190 is_playing_ = false;
191
192 // Disable the WebAudio rendering thread. This is safe because the device
193 // thread is stopped at this point and |rendering_thread_| will not be
194 // accessed by it anymore.
195 rendering_thread_.reset();
184 } 196 }
185 } 197 }
186 198
199 size_t AudioDestination::CallbackBufferSize() const {
200 DCHECK(WTF::IsMainThread());
201 return callback_buffer_size_;
202 }
203
204 bool AudioDestination::IsPlaying() {
205 DCHECK(WTF::IsMainThread());
206 return is_playing_;
207 }
208
209 int AudioDestination::FramesPerBuffer() const {
210 DCHECK(WTF::IsMainThread());
211 return web_audio_device_->FramesPerBuffer();
212 }
213
187 size_t AudioDestination::HardwareBufferSize() { 214 size_t AudioDestination::HardwareBufferSize() {
188 return Platform::Current()->AudioHardwareBufferSize(); 215 return Platform::Current()->AudioHardwareBufferSize();
189 } 216 }
190 217
191 float AudioDestination::HardwareSampleRate() { 218 float AudioDestination::HardwareSampleRate() {
192 return static_cast<float>(Platform::Current()->AudioHardwareSampleRate()); 219 return static_cast<float>(Platform::Current()->AudioHardwareSampleRate());
193 } 220 }
194 221
195 unsigned long AudioDestination::MaxChannelCount() { 222 unsigned long AudioDestination::MaxChannelCount() {
196 return static_cast<unsigned long>( 223 return static_cast<unsigned long>(
(...skipping 21 matching lines...) Expand all
218 DCHECK(is_buffer_size_valid); 245 DCHECK(is_buffer_size_valid);
219 return is_buffer_size_valid; 246 return is_buffer_size_valid;
220 } 247 }
221 248
222 bool AudioDestination::IsRenderingThread() { 249 bool AudioDestination::IsRenderingThread() {
223 return static_cast<ThreadIdentifier>(rendering_thread_->ThreadId()) == 250 return static_cast<ThreadIdentifier>(rendering_thread_->ThreadId()) ==
224 CurrentThread(); 251 CurrentThread();
225 } 252 }
226 253
227 } // namespace blink 254 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698