Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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( | |
| 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"))), |
|
Raymond Toy
2017/04/28 19:53:56
Why change the order?
hongchan
2017/04/28 20:24:54
I rearranged the class member by the thread type.
| |
| 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 Loading... | |
| 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. |
|
Raymond Toy
2017/04/28 19:53:56
Which checks are redundant? Both? Is it possible
hongchan
2017/04/28 20:24:54
Yes, theoretically it's possible when there is eno
nhiroki
2017/05/01 01:56:39
If |rendering_thread_| is nullptr here, DCHECK at
hongchan
2017/05/01 16:43:08
True, but it cannot be caught in the release build
nhiroki
2017/05/02 01:42:51
If it's valid to call Render() when |render_thread
| |
| 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 23 matching lines...) Expand all Loading... | |
| 163 | 166 |
| 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() { |
|
nhiroki
2017/05/01 01:56:39
Can we have DCHECK(WTF::IsMainThread()) here becau
hongchan
2017/05/01 16:43:08
Done.
| |
| 174 if (web_audio_device_ && !is_playing_) { | 177 if (web_audio_device_ && !is_playing_) { |
| 175 web_audio_device_->Start(); | 178 web_audio_device_->Start(); |
| 176 is_playing_ = true; | 179 is_playing_ = true; |
| 177 } | 180 } |
| 178 } | 181 } |
| 179 | 182 |
| 180 void AudioDestination::Stop() { | 183 void AudioDestination::Stop() { |
|
nhiroki
2017/05/01 01:56:39
ditto.
hongchan
2017/05/01 16:43:08
Done.
| |
| 181 if (web_audio_device_ && is_playing_) { | 184 if (web_audio_device_ && is_playing_) { |
| 185 // This stops the callback from the device thread synchronously. | |
| 182 web_audio_device_->Stop(); | 186 web_audio_device_->Stop(); |
| 187 | |
| 183 is_playing_ = false; | 188 is_playing_ = false; |
| 189 | |
| 190 // Disable the WebAudio rendering thread. This is safe because the device | |
| 191 // thread is stopped at this point and |rendering_thread_| will not be | |
| 192 // accessed by it anymore. | |
| 193 rendering_thread_.reset(); | |
|
Raymond Toy
2017/04/28 19:53:56
Is this synchronous? Are we guaranteed the thread
hongchan
2017/04/28 20:24:54
I believe so. FWIW, this is c++ unique_ptr's metho
nhiroki
2017/05/01 01:56:39
I'm not 100% sure but I think this is safe. Worker
hongchan
2017/05/01 16:43:07
Yes, that's my reference for this fix.
| |
| 184 } | 194 } |
| 185 } | 195 } |
| 186 | 196 |
| 187 size_t AudioDestination::HardwareBufferSize() { | 197 size_t AudioDestination::HardwareBufferSize() { |
| 188 return Platform::Current()->AudioHardwareBufferSize(); | 198 return Platform::Current()->AudioHardwareBufferSize(); |
| 189 } | 199 } |
| 190 | 200 |
| 191 float AudioDestination::HardwareSampleRate() { | 201 float AudioDestination::HardwareSampleRate() { |
| 192 return static_cast<float>(Platform::Current()->AudioHardwareSampleRate()); | 202 return static_cast<float>(Platform::Current()->AudioHardwareSampleRate()); |
| 193 } | 203 } |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 218 DCHECK(is_buffer_size_valid); | 228 DCHECK(is_buffer_size_valid); |
| 219 return is_buffer_size_valid; | 229 return is_buffer_size_valid; |
| 220 } | 230 } |
| 221 | 231 |
| 222 bool AudioDestination::IsRenderingThread() { | 232 bool AudioDestination::IsRenderingThread() { |
| 223 return static_cast<ThreadIdentifier>(rendering_thread_->ThreadId()) == | 233 return static_cast<ThreadIdentifier>(rendering_thread_->ThreadId()) == |
| 224 CurrentThread(); | 234 CurrentThread(); |
| 225 } | 235 } |
| 226 | 236 |
| 227 } // namespace blink | 237 } // namespace blink |
| OLD | NEW |