| 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 |