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

Side by Side Diff: Source/modules/webaudio/AudioScheduledSourceNode.cpp

Issue 1256053006: Protect AudioScheduledSoureNode::m_startTime and m_endTime. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Add static_assert Created 5 years, 4 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) 2012, Google Inc. All rights reserved. 2 * Copyright (C) 2012, 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 * 1. Redistributions of source code must retain the above copyright 7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer. 8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright 9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the 10 * notice, this list of conditions and the following disclaimer in the
(...skipping 23 matching lines...) Expand all
34 #include "platform/audio/AudioUtilities.h" 34 #include "platform/audio/AudioUtilities.h"
35 #include "wtf/MathExtras.h" 35 #include "wtf/MathExtras.h"
36 #include <algorithm> 36 #include <algorithm>
37 37
38 namespace blink { 38 namespace blink {
39 39
40 const double AudioScheduledSourceHandler::UnknownTime = -1; 40 const double AudioScheduledSourceHandler::UnknownTime = -1;
41 41
42 AudioScheduledSourceHandler::AudioScheduledSourceHandler(NodeType nodeType, Audi oNode& node, float sampleRate) 42 AudioScheduledSourceHandler::AudioScheduledSourceHandler(NodeType nodeType, Audi oNode& node, float sampleRate)
43 : AudioHandler(nodeType, node, sampleRate) 43 : AudioHandler(nodeType, node, sampleRate)
44 , m_hasEndedListener(false)
44 , m_startTime(0) 45 , m_startTime(0)
45 , m_endTime(UnknownTime) 46 , m_endTime(UnknownTime)
46 , m_hasEndedListener(false)
47 , m_playbackState(UNSCHEDULED_STATE) 47 , m_playbackState(UNSCHEDULED_STATE)
48 { 48 {
49 } 49 }
50 50
51 void AudioScheduledSourceHandler::updateSchedulingInfo( 51 void AudioScheduledSourceHandler::updateSchedulingInfo(
52 size_t quantumFrameSize, AudioBus* outputBus, size_t& quantumFrameOffset, si ze_t& nonSilentFramesToProcess) 52 size_t quantumFrameSize, AudioBus* outputBus, size_t& quantumFrameOffset, si ze_t& nonSilentFramesToProcess)
53 { 53 {
54 ASSERT(outputBus); 54 ASSERT(outputBus);
55 if (!outputBus) 55 if (!outputBus)
56 return; 56 return;
57 57
58 ASSERT(quantumFrameSize == ProcessingSizeInFrames); 58 ASSERT(quantumFrameSize == ProcessingSizeInFrames);
59 if (quantumFrameSize != ProcessingSizeInFrames) 59 if (quantumFrameSize != ProcessingSizeInFrames)
60 return; 60 return;
61 61
62 double sampleRate = this->sampleRate(); 62 double sampleRate = this->sampleRate();
63 63
64 // quantumStartFrame : Start frame of the current time quantum. 64 // quantumStartFrame : Start frame of the current time quantum.
65 // quantumEndFrame : End frame of the current time quantum. 65 // quantumEndFrame : End frame of the current time quantum.
66 // startFrame : Start frame for this source. 66 // startFrame : Start frame for this source.
67 // endFrame : End frame for this source. 67 // endFrame : End frame for this source.
68 size_t quantumStartFrame = context()->currentSampleFrame(); 68 size_t quantumStartFrame = context()->currentSampleFrame();
69 size_t quantumEndFrame = quantumStartFrame + quantumFrameSize; 69 size_t quantumEndFrame = quantumStartFrame + quantumFrameSize;
70 size_t startFrame = AudioUtilities::timeToSampleFrame(m_startTime, sampleRat e); 70 size_t startFrame = AudioUtilities::timeToSampleFrame(startTime(), sampleRat e);
71 size_t endFrame = m_endTime == UnknownTime ? 0 : AudioUtilities::timeToSampl eFrame(m_endTime, sampleRate); 71 double currentEndTime = endTime();
72 size_t endFrame = currentEndTime == UnknownTime ? 0 : AudioUtilities::timeTo SampleFrame(currentEndTime, sampleRate);
72 73
73 // If we know the end time and it's already passed, then don't bother doing any more rendering this cycle. 74 // If we know the end time and it's already passed, then don't bother doing any more rendering this cycle.
74 if (m_endTime != UnknownTime && endFrame <= quantumStartFrame) 75 if (currentEndTime != UnknownTime && endFrame <= quantumStartFrame)
75 finish(); 76 finish();
76 77
77 PlaybackState state = playbackState(); 78 PlaybackState state = playbackState();
78 79
79 if (state == UNSCHEDULED_STATE || state == FINISHED_STATE || startFrame >= q uantumEndFrame) { 80 if (state == UNSCHEDULED_STATE || state == FINISHED_STATE || startFrame >= q uantumEndFrame) {
80 // Output silence. 81 // Output silence.
81 outputBus->zero(); 82 outputBus->zero();
82 nonSilentFramesToProcess = 0; 83 nonSilentFramesToProcess = 0;
83 return; 84 return;
84 } 85 }
(...skipping 17 matching lines...) Expand all
102 // Handle silence before we start playing. 103 // Handle silence before we start playing.
103 // Zero any initial frames representing silence leading up to a rendering st art time in the middle of the quantum. 104 // Zero any initial frames representing silence leading up to a rendering st art time in the middle of the quantum.
104 if (quantumFrameOffset) { 105 if (quantumFrameOffset) {
105 for (unsigned i = 0; i < outputBus->numberOfChannels(); ++i) 106 for (unsigned i = 0; i < outputBus->numberOfChannels(); ++i)
106 memset(outputBus->channel(i)->mutableData(), 0, sizeof(float) * quan tumFrameOffset); 107 memset(outputBus->channel(i)->mutableData(), 0, sizeof(float) * quan tumFrameOffset);
107 } 108 }
108 109
109 // Handle silence after we're done playing. 110 // Handle silence after we're done playing.
110 // If the end time is somewhere in the middle of this time quantum, then zer o out the 111 // If the end time is somewhere in the middle of this time quantum, then zer o out the
111 // frames from the end time to the very end of the quantum. 112 // frames from the end time to the very end of the quantum.
112 if (m_endTime != UnknownTime && endFrame >= quantumStartFrame && endFrame < quantumEndFrame) { 113 if (currentEndTime != UnknownTime && endFrame >= quantumStartFrame && endFra me < quantumEndFrame) {
113 size_t zeroStartFrame = endFrame - quantumStartFrame; 114 size_t zeroStartFrame = endFrame - quantumStartFrame;
114 size_t framesToZero = quantumFrameSize - zeroStartFrame; 115 size_t framesToZero = quantumFrameSize - zeroStartFrame;
115 116
116 bool isSafe = zeroStartFrame < quantumFrameSize && framesToZero <= quant umFrameSize && zeroStartFrame + framesToZero <= quantumFrameSize; 117 bool isSafe = zeroStartFrame < quantumFrameSize && framesToZero <= quant umFrameSize && zeroStartFrame + framesToZero <= quantumFrameSize;
117 ASSERT(isSafe); 118 ASSERT(isSafe);
118 119
119 if (isSafe) { 120 if (isSafe) {
120 if (framesToZero > nonSilentFramesToProcess) 121 if (framesToZero > nonSilentFramesToProcess)
121 nonSilentFramesToProcess = 0; 122 nonSilentFramesToProcess = 0;
122 else 123 else
(...skipping 30 matching lines...) Expand all
153 return; 154 return;
154 } 155 }
155 156
156 // The node is started. Add a reference to keep us alive so that audio will eventually get 157 // The node is started. Add a reference to keep us alive so that audio will eventually get
157 // played even if Javascript should drop all references to this node. The re ference will get 158 // played even if Javascript should drop all references to this node. The re ference will get
158 // dropped when the source has finished playing. 159 // dropped when the source has finished playing.
159 context()->notifySourceNodeStartedProcessing(node()); 160 context()->notifySourceNodeStartedProcessing(node());
160 161
161 // If |when| < currentTime, the source must start now according to the spec. 162 // If |when| < currentTime, the source must start now according to the spec.
162 // So just set startTime to currentTime in this case to start the source now . 163 // So just set startTime to currentTime in this case to start the source now .
163 m_startTime = std::max(when, context()->currentTime()); 164 setStartTime(std::max(when, context()->currentTime()));
164 165
165 setPlaybackState(SCHEDULED_STATE); 166 setPlaybackState(SCHEDULED_STATE);
166 } 167 }
167 168
168 void AudioScheduledSourceHandler::stop(double when, ExceptionState& exceptionSta te) 169 void AudioScheduledSourceHandler::stop(double when, ExceptionState& exceptionSta te)
169 { 170 {
170 ASSERT(isMainThread()); 171 ASSERT(isMainThread());
171 172
172 if (playbackState() == UNSCHEDULED_STATE) { 173 if (playbackState() == UNSCHEDULED_STATE) {
173 exceptionState.throwDOMException( 174 exceptionState.throwDOMException(
174 InvalidStateError, 175 InvalidStateError,
175 "cannot call stop without calling start first."); 176 "cannot call stop without calling start first.");
176 return; 177 return;
177 } 178 }
178 179
179 if (when < 0) { 180 if (when < 0) {
180 exceptionState.throwDOMException( 181 exceptionState.throwDOMException(
181 InvalidAccessError, 182 InvalidAccessError,
182 ExceptionMessages::indexExceedsMinimumBound( 183 ExceptionMessages::indexExceedsMinimumBound(
183 "stop time", 184 "stop time",
184 when, 185 when,
185 0.0)); 186 0.0));
186 return; 187 return;
187 } 188 }
188 189
189 // stop() can be called more than once, with the last call to stop taking ef fect, unless the 190 // stop() can be called more than once, with the last call to stop taking ef fect, unless the
190 // source has already stopped due to earlier calls to stop. No exceptions ar e thrown in any 191 // source has already stopped due to earlier calls to stop. No exceptions ar e thrown in any
191 // case. 192 // case.
192 when = std::max(0.0, when); 193 when = std::max(0.0, when);
193 m_endTime = when; 194 setEndTime(when);
194 } 195 }
195 196
196 void AudioScheduledSourceHandler::finishWithoutOnEnded() 197 void AudioScheduledSourceHandler::finishWithoutOnEnded()
197 { 198 {
198 if (playbackState() != FINISHED_STATE) { 199 if (playbackState() != FINISHED_STATE) {
199 // Let the context dereference this AudioNode. 200 // Let the context dereference this AudioNode.
200 context()->notifySourceNodeFinishedProcessing(this); 201 context()->notifySourceNodeFinishedProcessing(this);
201 setPlaybackState(FINISHED_STATE); 202 setPlaybackState(FINISHED_STATE);
202 } 203 }
203 } 204 }
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
256 257
257 void AudioScheduledSourceNode::setOnended(PassRefPtrWillBeRawPtr<EventListener> listener) 258 void AudioScheduledSourceNode::setOnended(PassRefPtrWillBeRawPtr<EventListener> listener)
258 { 259 {
259 audioScheduledSourceHandler().setHasEndedListener(); 260 audioScheduledSourceHandler().setHasEndedListener();
260 setAttributeEventListener(EventTypeNames::ended, listener); 261 setAttributeEventListener(EventTypeNames::ended, listener);
261 } 262 }
262 263
263 } // namespace blink 264 } // namespace blink
264 265
265 #endif // ENABLE(WEB_AUDIO) 266 #endif // ENABLE(WEB_AUDIO)
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698