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

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

Issue 2777903005: Add WebThread in AudioDestination to support AudioWorkletThread (Closed)
Patch Set: Addressing feedback Created 3 years, 8 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 11 matching lines...) Expand all
22 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */ 27 */
28 28
29 #include "platform/audio/AudioDestination.h" 29 #include "platform/audio/AudioDestination.h"
30 30
31 #include <memory> 31 #include <memory>
32 #include "platform/CrossThreadFunctional.h"
32 #include "platform/Histogram.h" 33 #include "platform/Histogram.h"
34 #include "platform/WebTaskRunner.h"
33 #include "platform/audio/AudioUtilities.h" 35 #include "platform/audio/AudioUtilities.h"
34 #include "platform/audio/PushPullFIFO.h" 36 #include "platform/audio/PushPullFIFO.h"
35 #include "platform/weborigin/SecurityOrigin.h" 37 #include "platform/weborigin/SecurityOrigin.h"
36 #include "public/platform/Platform.h" 38 #include "public/platform/Platform.h"
37 #include "public/platform/WebAudioLatencyHint.h" 39 #include "public/platform/WebAudioLatencyHint.h"
38 #include "public/platform/WebSecurityOrigin.h" 40 #include "public/platform/WebSecurityOrigin.h"
41 #include "public/platform/WebThread.h"
39 #include "wtf/PtrUtil.h" 42 #include "wtf/PtrUtil.h"
40 43
41 namespace blink { 44 namespace blink {
42 45
43 // FIFO Size. 46 // FIFO Size.
44 // 47 //
45 // TODO(hongchan): This was estimated based on the largest callback buffer size 48 // TODO(hongchan): This was estimated based on the largest callback buffer size
46 // that we would ever need. The current UMA stats indicates that this is, in 49 // that we would ever need. The current UMA stats indicates that this is, in
47 // fact, probably too small. There are Android devices out there with a size of 50 // fact, probably too small. There are Android devices out there with a size of
48 // 8000 or so. We might need to make this larger. See: crbug.com/670747 51 // 8000 or so. We might need to make this larger. See: crbug.com/670747
(...skipping 17 matching lines...) Expand all
66 m_isPlaying(false), 69 m_isPlaying(false),
67 m_callback(callback), 70 m_callback(callback),
68 m_outputBus(AudioBus::create(numberOfOutputChannels, 71 m_outputBus(AudioBus::create(numberOfOutputChannels,
69 AudioUtilities::kRenderQuantumFrames, 72 AudioUtilities::kRenderQuantumFrames,
70 false)), 73 false)),
71 m_renderBus(AudioBus::create(numberOfOutputChannels, 74 m_renderBus(AudioBus::create(numberOfOutputChannels,
72 AudioUtilities::kRenderQuantumFrames)), 75 AudioUtilities::kRenderQuantumFrames)),
73 m_fifo( 76 m_fifo(
74 WTF::wrapUnique(new PushPullFIFO(numberOfOutputChannels, kFIFOSize))), 77 WTF::wrapUnique(new PushPullFIFO(numberOfOutputChannels, kFIFOSize))),
75 m_framesElapsed(0) { 78 m_framesElapsed(0) {
79 // Create a thread |WebThread| for WebAudio graph rendering.
80 m_renderingThread = WTF::wrapUnique(
81 Platform::current()->createThread("WebAudio Rendering Thread"));
82
76 // Create WebAudioDevice. blink::WebAudioDevice is designed to support the 83 // Create WebAudioDevice. blink::WebAudioDevice is designed to support the
77 // local input (e.g. loopback from OS audio system), but Chromium's media 84 // local input (e.g. loopback from OS audio system), but Chromium's media
78 // renderer does not support it currently. Thus, we use zero for the number 85 // renderer does not support it currently. Thus, we use zero for the number
79 // of input channels. 86 // of input channels.
80 m_webAudioDevice = WTF::wrapUnique(Platform::current()->createAudioDevice( 87 m_webAudioDevice = WTF::wrapUnique(Platform::current()->createAudioDevice(
81 0, numberOfOutputChannels, latencyHint, this, String(), 88 0, numberOfOutputChannels, latencyHint, this, String(),
82 std::move(securityOrigin))); 89 std::move(securityOrigin)));
83 DCHECK(m_webAudioDevice); 90 DCHECK(m_webAudioDevice);
84 91
85 m_callbackBufferSize = m_webAudioDevice->framesPerBuffer(); 92 m_callbackBufferSize = m_webAudioDevice->framesPerBuffer();
(...skipping 13 matching lines...) Expand all
99 size_t priorFramesSkipped) { 106 size_t priorFramesSkipped) {
100 CHECK_EQ(destinationData.size(), m_numberOfOutputChannels); 107 CHECK_EQ(destinationData.size(), m_numberOfOutputChannels);
101 CHECK_EQ(numberOfFrames, m_callbackBufferSize); 108 CHECK_EQ(numberOfFrames, m_callbackBufferSize);
102 109
103 // Note that this method is called by AudioDeviceThread. If FIFO is not ready, 110 // Note that this method is called by AudioDeviceThread. If FIFO is not ready,
104 // or the requested render size is greater than FIFO size return here. 111 // or the requested render size is greater than FIFO size return here.
105 // (crbug.com/692423) 112 // (crbug.com/692423)
106 if (!m_fifo || m_fifo->length() < numberOfFrames) 113 if (!m_fifo || m_fifo->length() < numberOfFrames)
107 return; 114 return;
108 115
116 // Associate the destination data array with the output bus then fill the
117 // FIFO.
118 for (unsigned i = 0; i < m_numberOfOutputChannels; ++i)
119 m_outputBus->setChannelMemory(i, destinationData[i], numberOfFrames);
120
121 m_renderingThread->getWebTaskRunner()->postTask(
122 BLINK_FROM_HERE,
123 crossThreadBind(&AudioDestination::requestRenderOnWebThread,
124 crossThreadUnretained(this), numberOfFrames, delay,
125 delayTimestamp, priorFramesSkipped));
126
127 m_fifo->pull(m_outputBus.get(), numberOfFrames);
128 }
129
130 void AudioDestination::requestRenderOnWebThread(size_t numberOfFrames,
131 double delay,
132 double delayTimestamp,
133 size_t priorFramesSkipped) {
109 m_framesElapsed -= std::min(m_framesElapsed, priorFramesSkipped); 134 m_framesElapsed -= std::min(m_framesElapsed, priorFramesSkipped);
110 double outputPosition = 135 double outputPosition =
111 m_framesElapsed / static_cast<double>(m_webAudioDevice->sampleRate()) - 136 m_framesElapsed / static_cast<double>(m_webAudioDevice->sampleRate()) -
112 delay; 137 delay;
113 m_outputPosition.position = outputPosition; 138 m_outputPosition.position = outputPosition;
114 m_outputPosition.timestamp = delayTimestamp; 139 m_outputPosition.timestamp = delayTimestamp;
115 m_outputPositionReceivedTimestamp = base::TimeTicks::Now(); 140 m_outputPositionReceivedTimestamp = base::TimeTicks::Now();
116 141
117 // Associate the destination data array with the output bus then fill the
118 // FIFO.
119 for (unsigned i = 0; i < m_numberOfOutputChannels; ++i)
120 m_outputBus->setChannelMemory(i, destinationData[i], numberOfFrames);
121
122 // Number of frames to render via WebAudio graph. |framesToRender > 0| means 142 // Number of frames to render via WebAudio graph. |framesToRender > 0| means
123 // the frames in FIFO is not enough to fulfill the requested frames from the 143 // the frames in FIFO is not enough to fulfill the requested frames from the
124 // audio device. 144 // audio device.
125 size_t framesToRender = numberOfFrames > m_fifo->framesAvailable() 145 size_t framesToRender = numberOfFrames > m_fifo->framesAvailable()
126 ? numberOfFrames - m_fifo->framesAvailable() 146 ? numberOfFrames - m_fifo->framesAvailable()
127 : 0; 147 : 0;
128 148
129 for (size_t pushedFrames = 0; pushedFrames < framesToRender; 149 for (size_t pushedFrames = 0; pushedFrames < framesToRender;
130 pushedFrames += AudioUtilities::kRenderQuantumFrames) { 150 pushedFrames += AudioUtilities::kRenderQuantumFrames) {
131 // If platform buffer is more than two times longer than |framesToProcess| 151 // If platform buffer is more than two times longer than |framesToProcess|
(...skipping 11 matching lines...) Expand all
143 // we might have negative estimation |outputPosition| value. 163 // we might have negative estimation |outputPosition| value.
144 if (m_outputPosition.position < 0.0) 164 if (m_outputPosition.position < 0.0)
145 m_outputPosition.position = 0.0; 165 m_outputPosition.position = 0.0;
146 166
147 // Process WebAudio graph and push the rendered output to FIFO. 167 // Process WebAudio graph and push the rendered output to FIFO.
148 m_callback.render(nullptr, m_renderBus.get(), 168 m_callback.render(nullptr, m_renderBus.get(),
149 AudioUtilities::kRenderQuantumFrames, m_outputPosition); 169 AudioUtilities::kRenderQuantumFrames, m_outputPosition);
150 m_fifo->push(m_renderBus.get()); 170 m_fifo->push(m_renderBus.get());
151 } 171 }
152 172
153 m_fifo->pull(m_outputBus.get(), numberOfFrames);
154
155 m_framesElapsed += numberOfFrames; 173 m_framesElapsed += numberOfFrames;
156 } 174 }
157 175
158 void AudioDestination::start() { 176 void AudioDestination::start() {
159 if (m_webAudioDevice && !m_isPlaying) { 177 if (m_webAudioDevice && !m_isPlaying) {
160 m_webAudioDevice->start(); 178 m_webAudioDevice->start();
161 m_isPlaying = true; 179 m_isPlaying = true;
162 } 180 }
163 } 181 }
164 182
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
198 callbackBufferSizeHistogram.sample(m_callbackBufferSize); 216 callbackBufferSizeHistogram.sample(m_callbackBufferSize);
199 217
200 // Check if the requested buffer size is too large. 218 // Check if the requested buffer size is too large.
201 bool isBufferSizeValid = 219 bool isBufferSizeValid =
202 m_callbackBufferSize + AudioUtilities::kRenderQuantumFrames <= kFIFOSize; 220 m_callbackBufferSize + AudioUtilities::kRenderQuantumFrames <= kFIFOSize;
203 DCHECK(isBufferSizeValid); 221 DCHECK(isBufferSizeValid);
204 return isBufferSizeValid; 222 return isBufferSizeValid;
205 } 223 }
206 224
207 } // namespace blink 225 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698