OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2013 Google Inc. All rights reserved. | 2 * Copyright (C) 2013 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 are | 5 * modification, are permitted provided that the following conditions are |
6 * met: | 6 * met: |
7 * | 7 * |
8 * * Redistributions of source code must retain the above copyright | 8 * * 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 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
(...skipping 13 matching lines...) Expand all Loading... |
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
29 */ | 29 */ |
30 | 30 |
31 #include "config.h" | 31 #include "config.h" |
32 #include "modules/mediasource/MediaSourceBase.h" | 32 #include "modules/mediasource/MediaSourceBase.h" |
33 | 33 |
34 #include "bindings/v8/ExceptionState.h" | |
35 #include "bindings/v8/ExceptionStatePlaceholder.h" | |
36 #include "core/dom/Event.h" | 34 #include "core/dom/Event.h" |
37 #include "core/dom/ExceptionCode.h" | 35 #include "core/dom/ExceptionCode.h" |
| 36 #include "core/dom/ExceptionCodePlaceholder.h" |
38 #include "core/dom/GenericEventQueue.h" | 37 #include "core/dom/GenericEventQueue.h" |
39 #include "core/platform/Logging.h" | 38 #include "core/platform/Logging.h" |
40 #include "core/platform/graphics/SourceBufferPrivate.h" | 39 #include "core/platform/graphics/SourceBufferPrivate.h" |
41 #include "modules/mediasource/MediaSourceRegistry.h" | 40 #include "modules/mediasource/MediaSourceRegistry.h" |
42 #include "wtf/text/WTFString.h" | 41 #include "wtf/text/WTFString.h" |
43 | 42 |
44 namespace WebCore { | 43 namespace WebCore { |
45 | 44 |
46 MediaSourceBase::MediaSourceBase(ScriptExecutionContext* context) | 45 MediaSourceBase::MediaSourceBase(ScriptExecutionContext* context) |
47 : ActiveDOMObject(context) | 46 : ActiveDOMObject(context) |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
106 // 1. If activeSourceBuffers.length equals 0 then return an empty TimeRanges
object and abort these steps. | 105 // 1. If activeSourceBuffers.length equals 0 then return an empty TimeRanges
object and abort these steps. |
107 if (ranges.isEmpty()) | 106 if (ranges.isEmpty()) |
108 return TimeRanges::create(); | 107 return TimeRanges::create(); |
109 | 108 |
110 // 2. Let active ranges be the ranges returned by buffered for each SourceBu
ffer object in activeSourceBuffers. | 109 // 2. Let active ranges be the ranges returned by buffered for each SourceBu
ffer object in activeSourceBuffers. |
111 // 3. Let highest end time be the largest range end time in the active range
s. | 110 // 3. Let highest end time be the largest range end time in the active range
s. |
112 double highestEndTime = -1; | 111 double highestEndTime = -1; |
113 for (size_t i = 0; i < ranges.size(); ++i) { | 112 for (size_t i = 0; i < ranges.size(); ++i) { |
114 unsigned length = ranges[i]->length(); | 113 unsigned length = ranges[i]->length(); |
115 if (length) | 114 if (length) |
116 highestEndTime = std::max(highestEndTime, ranges[i]->end(length - 1,
ASSERT_NO_EXCEPTION_STATE)); | 115 highestEndTime = std::max(highestEndTime, ranges[i]->end(length - 1,
ASSERT_NO_EXCEPTION)); |
117 } | 116 } |
118 | 117 |
119 // Return an empty range if all ranges are empty. | 118 // Return an empty range if all ranges are empty. |
120 if (highestEndTime < 0) | 119 if (highestEndTime < 0) |
121 return TimeRanges::create(); | 120 return TimeRanges::create(); |
122 | 121 |
123 // 4. Let intersection ranges equal a TimeRange object containing a single r
ange from 0 to highest end time. | 122 // 4. Let intersection ranges equal a TimeRange object containing a single r
ange from 0 to highest end time. |
124 RefPtr<TimeRanges> intersectionRanges = TimeRanges::create(0, highestEndTime
); | 123 RefPtr<TimeRanges> intersectionRanges = TimeRanges::create(0, highestEndTime
); |
125 | 124 |
126 // 5. For each SourceBuffer object in activeSourceBuffers run the following
steps: | 125 // 5. For each SourceBuffer object in activeSourceBuffers run the following
steps: |
127 bool ended = readyState() == endedKeyword(); | 126 bool ended = readyState() == endedKeyword(); |
128 for (size_t i = 0; i < ranges.size(); ++i) { | 127 for (size_t i = 0; i < ranges.size(); ++i) { |
129 // 5.1 Let source ranges equal the ranges returned by the buffered attri
bute on the current SourceBuffer. | 128 // 5.1 Let source ranges equal the ranges returned by the buffered attri
bute on the current SourceBuffer. |
130 TimeRanges* sourceRanges = ranges[i].get(); | 129 TimeRanges* sourceRanges = ranges[i].get(); |
131 | 130 |
132 // 5.2 If readyState is "ended", then set the end time on the last range
in source ranges to highest end time. | 131 // 5.2 If readyState is "ended", then set the end time on the last range
in source ranges to highest end time. |
133 if (ended && sourceRanges->length()) | 132 if (ended && sourceRanges->length()) |
134 sourceRanges->add(sourceRanges->start(sourceRanges->length() - 1, AS
SERT_NO_EXCEPTION_STATE), highestEndTime); | 133 sourceRanges->add(sourceRanges->start(sourceRanges->length() - 1, AS
SERT_NO_EXCEPTION), highestEndTime); |
135 | 134 |
136 // 5.3 Let new intersection ranges equal the the intersection between th
e intersection ranges and the source ranges. | 135 // 5.3 Let new intersection ranges equal the the intersection between th
e intersection ranges and the source ranges. |
137 // 5.4 Replace the ranges in intersection ranges with the new intersecti
on ranges. | 136 // 5.4 Replace the ranges in intersection ranges with the new intersecti
on ranges. |
138 intersectionRanges->intersectWith(sourceRanges); | 137 intersectionRanges->intersectWith(sourceRanges); |
139 } | 138 } |
140 | 139 |
141 return intersectionRanges.release(); | 140 return intersectionRanges.release(); |
142 } | 141 } |
143 | 142 |
144 void MediaSourceBase::setDuration(double duration, ExceptionState& es) | 143 void MediaSourceBase::setDuration(double duration, ExceptionCode& ec) |
145 { | 144 { |
146 if (duration < 0.0 || std::isnan(duration)) { | 145 if (duration < 0.0 || std::isnan(duration)) { |
147 es.throwDOMException(InvalidAccessError); | 146 ec = InvalidAccessError; |
148 return; | 147 return; |
149 } | 148 } |
150 if (!isOpen()) { | 149 if (!isOpen()) { |
151 es.throwDOMException(InvalidStateError); | 150 ec = InvalidStateError; |
152 return; | 151 return; |
153 } | 152 } |
154 m_private->setDuration(duration); | 153 m_private->setDuration(duration); |
155 } | 154 } |
156 | 155 |
157 | 156 |
158 void MediaSourceBase::setReadyState(const AtomicString& state) | 157 void MediaSourceBase::setReadyState(const AtomicString& state) |
159 { | 158 { |
160 ASSERT(state == openKeyword() || state == closedKeyword() || state == endedK
eyword()); | 159 ASSERT(state == openKeyword() || state == closedKeyword() || state == endedK
eyword()); |
161 | 160 |
162 AtomicString oldState = readyState(); | 161 AtomicString oldState = readyState(); |
163 LOG(Media, "MediaSourceBase::setReadyState() %p : %s -> %s", this, oldState.
string().ascii().data(), state.string().ascii().data()); | 162 LOG(Media, "MediaSourceBase::setReadyState() %p : %s -> %s", this, oldState.
string().ascii().data(), state.string().ascii().data()); |
164 | 163 |
165 if (state == closedKeyword()) { | 164 if (state == closedKeyword()) { |
166 m_private.clear(); | 165 m_private.clear(); |
167 m_attached = false; | 166 m_attached = false; |
168 } | 167 } |
169 | 168 |
170 if (oldState == state) | 169 if (oldState == state) |
171 return; | 170 return; |
172 | 171 |
173 m_readyState = state; | 172 m_readyState = state; |
174 | 173 |
175 onReadyStateChange(oldState, state); | 174 onReadyStateChange(oldState, state); |
176 } | 175 } |
177 | 176 |
178 void MediaSourceBase::endOfStream(const AtomicString& error, ExceptionState& es) | 177 void MediaSourceBase::endOfStream(const AtomicString& error, ExceptionCode& ec) |
179 { | 178 { |
180 DEFINE_STATIC_LOCAL(const AtomicString, network, ("network", AtomicString::C
onstructFromLiteral)); | 179 DEFINE_STATIC_LOCAL(const AtomicString, network, ("network", AtomicString::C
onstructFromLiteral)); |
181 DEFINE_STATIC_LOCAL(const AtomicString, decode, ("decode", AtomicString::Con
structFromLiteral)); | 180 DEFINE_STATIC_LOCAL(const AtomicString, decode, ("decode", AtomicString::Con
structFromLiteral)); |
182 | 181 |
183 // 3.1 http://dvcs.w3.org/hg/html-media/raw-file/tip/media-source/media-sour
ce.html#dom-endofstream | 182 // 3.1 http://dvcs.w3.org/hg/html-media/raw-file/tip/media-source/media-sour
ce.html#dom-endofstream |
184 // 1. If the readyState attribute is not in the "open" state then throw an | 183 // 1. If the readyState attribute is not in the "open" state then throw an |
185 // InvalidStateError exception and abort these steps. | 184 // InvalidStateError exception and abort these steps. |
186 if (!isOpen()) { | 185 if (!isOpen()) { |
187 es.throwDOMException(InvalidStateError); | 186 ec = InvalidStateError; |
188 return; | 187 return; |
189 } | 188 } |
190 | 189 |
191 MediaSourcePrivate::EndOfStreamStatus eosStatus = MediaSourcePrivate::EosNoE
rror; | 190 MediaSourcePrivate::EndOfStreamStatus eosStatus = MediaSourcePrivate::EosNoE
rror; |
192 | 191 |
193 if (error.isNull() || error.isEmpty()) { | 192 if (error.isNull() || error.isEmpty()) { |
194 eosStatus = MediaSourcePrivate::EosNoError; | 193 eosStatus = MediaSourcePrivate::EosNoError; |
195 } else if (error == network) { | 194 } else if (error == network) { |
196 eosStatus = MediaSourcePrivate::EosNetworkError; | 195 eosStatus = MediaSourcePrivate::EosNetworkError; |
197 } else if (error == decode) { | 196 } else if (error == decode) { |
198 eosStatus = MediaSourcePrivate::EosDecodeError; | 197 eosStatus = MediaSourcePrivate::EosDecodeError; |
199 } else { | 198 } else { |
200 es.throwDOMException(InvalidAccessError); | 199 ec = InvalidAccessError; |
201 return; | 200 return; |
202 } | 201 } |
203 | 202 |
204 // 2. Change the readyState attribute value to "ended". | 203 // 2. Change the readyState attribute value to "ended". |
205 setReadyState(endedKeyword()); | 204 setReadyState(endedKeyword()); |
206 m_private->markEndOfStream(eosStatus); | 205 m_private->markEndOfStream(eosStatus); |
207 } | 206 } |
208 | 207 |
209 bool MediaSourceBase::isOpen() const | 208 bool MediaSourceBase::isOpen() const |
210 { | 209 { |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
248 } | 247 } |
249 | 248 |
250 void MediaSourceBase::stop() | 249 void MediaSourceBase::stop() |
251 { | 250 { |
252 m_asyncEventQueue->close(); | 251 m_asyncEventQueue->close(); |
253 if (!isClosed()) | 252 if (!isClosed()) |
254 setReadyState(closedKeyword()); | 253 setReadyState(closedKeyword()); |
255 m_private.clear(); | 254 m_private.clear(); |
256 } | 255 } |
257 | 256 |
258 PassOwnPtr<SourceBufferPrivate> MediaSourceBase::createSourceBufferPrivate(const
String& type, const MediaSourcePrivate::CodecsArray& codecs, ExceptionState& es
) | 257 PassOwnPtr<SourceBufferPrivate> MediaSourceBase::createSourceBufferPrivate(const
String& type, const MediaSourcePrivate::CodecsArray& codecs, ExceptionCode& ec) |
259 { | 258 { |
260 OwnPtr<SourceBufferPrivate> sourceBufferPrivate; | 259 OwnPtr<SourceBufferPrivate> sourceBufferPrivate; |
261 switch (m_private->addSourceBuffer(type, codecs, &sourceBufferPrivate)) { | 260 switch (m_private->addSourceBuffer(type, codecs, &sourceBufferPrivate)) { |
262 case MediaSourcePrivate::Ok: { | 261 case MediaSourcePrivate::Ok: { |
263 return sourceBufferPrivate.release(); | 262 return sourceBufferPrivate.release(); |
264 } | 263 } |
265 case MediaSourcePrivate::NotSupported: | 264 case MediaSourcePrivate::NotSupported: |
266 // 2.2 https://dvcs.w3.org/hg/html-media/raw-file/default/media-source/m
edia-source.html#widl-MediaSource-addSourceBuffer-SourceBuffer-DOMString-type | 265 // 2.2 https://dvcs.w3.org/hg/html-media/raw-file/default/media-source/m
edia-source.html#widl-MediaSource-addSourceBuffer-SourceBuffer-DOMString-type |
267 // Step 2: If type contains a MIME type ... that is not supported with t
he types | 266 // Step 2: If type contains a MIME type ... that is not supported with t
he types |
268 // specified for the other SourceBuffer objects in sourceBuffers, then t
hrow | 267 // specified for the other SourceBuffer objects in sourceBuffers, then t
hrow |
269 // a NotSupportedError exception and abort these steps. | 268 // a NotSupportedError exception and abort these steps. |
270 es.throwDOMException(NotSupportedError); | 269 ec = NotSupportedError; |
271 return nullptr; | 270 return nullptr; |
272 case MediaSourcePrivate::ReachedIdLimit: | 271 case MediaSourcePrivate::ReachedIdLimit: |
273 // 2.2 https://dvcs.w3.org/hg/html-media/raw-file/default/media-source/m
edia-source.html#widl-MediaSource-addSourceBuffer-SourceBuffer-DOMString-type | 272 // 2.2 https://dvcs.w3.org/hg/html-media/raw-file/default/media-source/m
edia-source.html#widl-MediaSource-addSourceBuffer-SourceBuffer-DOMString-type |
274 // Step 3: If the user agent can't handle any more SourceBuffer objects
then throw | 273 // Step 3: If the user agent can't handle any more SourceBuffer objects
then throw |
275 // a QuotaExceededError exception and abort these steps. | 274 // a QuotaExceededError exception and abort these steps. |
276 es.throwDOMException(QuotaExceededError); | 275 ec = QuotaExceededError; |
277 return nullptr; | 276 return nullptr; |
278 } | 277 } |
279 | 278 |
280 ASSERT_NOT_REACHED(); | 279 ASSERT_NOT_REACHED(); |
281 return nullptr; | 280 return nullptr; |
282 } | 281 } |
283 | 282 |
284 void MediaSourceBase::scheduleEvent(const AtomicString& eventName) | 283 void MediaSourceBase::scheduleEvent(const AtomicString& eventName) |
285 { | 284 { |
286 ASSERT(m_asyncEventQueue); | 285 ASSERT(m_asyncEventQueue); |
(...skipping 18 matching lines...) Expand all Loading... |
305 { | 304 { |
306 return &m_eventTargetData; | 305 return &m_eventTargetData; |
307 } | 306 } |
308 | 307 |
309 URLRegistry& MediaSourceBase::registry() const | 308 URLRegistry& MediaSourceBase::registry() const |
310 { | 309 { |
311 return MediaSourceRegistry::registry(); | 310 return MediaSourceRegistry::registry(); |
312 } | 311 } |
313 | 312 |
314 } | 313 } |
OLD | NEW |