| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2012 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 |
| 11 * copyright notice, this list of conditions and the following disclaimer | 11 * copyright notice, this list of conditions and the following disclaimer |
| 12 * in the documentation and/or other materials provided with the | 12 * in the documentation and/or other materials provided with the |
| 13 * distribution. | 13 * distribution. |
| 14 * * Neither the name of Google Inc. nor the names of its | 14 * * Neither the name of Google Inc. nor the names of its |
| 15 * contributors may be used to endorse or promote products derived from | 15 * contributors may be used to endorse or promote products derived from |
| 16 * this software without specific prior written permission. | 16 * this software without specific prior written permission. |
| 17 * | 17 * |
| 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| 19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | 19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| 20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | 20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| 21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | 21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| 22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | 22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| 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/WebKitMediaSource.h" | 32 #include "modules/mediasource/MediaSource.h" |
| 33 | 33 |
| 34 #include "core/dom/GenericEventQueue.h" |
| 34 #include "core/html/TimeRanges.h" | 35 #include "core/html/TimeRanges.h" |
| 35 #include "core/platform/ContentType.h" | 36 #include "core/platform/ContentType.h" |
| 37 #include "core/platform/Logging.h" |
| 36 #include "core/platform/MIMETypeRegistry.h" | 38 #include "core/platform/MIMETypeRegistry.h" |
| 37 #include "core/platform/graphics/SourceBufferPrivate.h" | 39 #include "core/platform/graphics/SourceBufferPrivate.h" |
| 38 #include "modules/mediasource/MediaSourceRegistry.h" | 40 #include "modules/mediasource/MediaSourceRegistry.h" |
| 39 #include "wtf/Uint8Array.h" | 41 #include "wtf/Uint8Array.h" |
| 40 | 42 |
| 41 namespace WebCore { | 43 namespace WebCore { |
| 42 | 44 |
| 43 PassRefPtr<WebKitMediaSource> WebKitMediaSource::create(ScriptExecutionContext*
context) | 45 PassRefPtr<MediaSource> MediaSource::create(ScriptExecutionContext* context) |
| 44 { | 46 { |
| 45 RefPtr<WebKitMediaSource> mediaSource(adoptRef(new WebKitMediaSource(context
))); | 47 RefPtr<MediaSource> mediaSource(adoptRef(new MediaSource(context))); |
| 46 mediaSource->suspendIfNeeded(); | 48 mediaSource->suspendIfNeeded(); |
| 47 return mediaSource.release(); | 49 return mediaSource.release(); |
| 48 } | 50 } |
| 49 | 51 |
| 50 WebKitMediaSource::WebKitMediaSource(ScriptExecutionContext* context) | 52 MediaSource::MediaSource(ScriptExecutionContext* context) |
| 51 : MediaSourceBase(context) | 53 : MediaSourceBase(context) |
| 52 { | 54 { |
| 55 LOG(Media, "MediaSource::MediaSource %p", this); |
| 53 ScriptWrappable::init(this); | 56 ScriptWrappable::init(this); |
| 54 m_sourceBuffers = WebKitSourceBufferList::create(scriptExecutionContext(), a
syncEventQueue()); | 57 m_sourceBuffers = SourceBufferList::create(scriptExecutionContext(), asyncEv
entQueue()); |
| 55 m_activeSourceBuffers = WebKitSourceBufferList::create(scriptExecutionContex
t(), asyncEventQueue()); | 58 m_activeSourceBuffers = SourceBufferList::create(scriptExecutionContext(), a
syncEventQueue()); |
| 56 } | 59 } |
| 57 | 60 |
| 58 WebKitSourceBufferList* WebKitMediaSource::sourceBuffers() | 61 MediaSource::~MediaSource() |
| 59 { | 62 { |
| 60 return m_sourceBuffers.get(); | 63 LOG(Media, "MediaSource::~MediaSource %p", this); |
| 64 ASSERT(isClosed()); |
| 61 } | 65 } |
| 62 | 66 |
| 63 WebKitSourceBufferList* WebKitMediaSource::activeSourceBuffers() | 67 SourceBuffer* MediaSource::addSourceBuffer(const String& type, ExceptionCode& ec
) |
| 64 { | 68 { |
| 65 // FIXME(91649): support track selection | 69 LOG(Media, "MediaSource::addSourceBuffer(%s) %p", type.ascii().data(), this)
; |
| 66 return m_activeSourceBuffers.get(); | |
| 67 } | |
| 68 | 70 |
| 69 WebKitSourceBuffer* WebKitMediaSource::addSourceBuffer(const String& type, Excep
tionCode& ec) | 71 // 2.2 https://dvcs.w3.org/hg/html-media/raw-file/default/media-source/media
-source.html#widl-MediaSource-addSourceBuffer-SourceBuffer-DOMString-type |
| 70 { | |
| 71 // 3.1 http://dvcs.w3.org/hg/html-media/raw-file/tip/media-source/media-sour
ce.html#dom-addsourcebuffer | |
| 72 // 1. If type is null or an empty then throw an INVALID_ACCESS_ERR exception
and | 72 // 1. If type is null or an empty then throw an INVALID_ACCESS_ERR exception
and |
| 73 // abort these steps. | 73 // abort these steps. |
| 74 if (type.isNull() || type.isEmpty()) { | 74 if (type.isNull() || type.isEmpty()) { |
| 75 ec = INVALID_ACCESS_ERR; | 75 ec = INVALID_ACCESS_ERR; |
| 76 return 0; | 76 return 0; |
| 77 } | 77 } |
| 78 | 78 |
| 79 // 2. If type contains a MIME type that is not supported ..., then throw a | 79 // 2. If type contains a MIME type that is not supported ..., then throw a |
| 80 // NOT_SUPPORTED_ERR exception and abort these steps. | 80 // NOT_SUPPORTED_ERR exception and abort these steps. |
| 81 if (!isTypeSupported(type)) { | 81 if (!isTypeSupported(type)) { |
| 82 ec = NOT_SUPPORTED_ERR; | 82 ec = NOT_SUPPORTED_ERR; |
| 83 return 0; | 83 return 0; |
| 84 } | 84 } |
| 85 | 85 |
| 86 // 4. If the readyState attribute is not in the "open" state then throw an | 86 // 4. If the readyState attribute is not in the "open" state then throw an |
| 87 // INVALID_STATE_ERR exception and abort these steps. | 87 // INVALID_STATE_ERR exception and abort these steps. |
| 88 if (!isOpen()) { | 88 if (!isOpen()) { |
| 89 ec = INVALID_STATE_ERR; | 89 ec = INVALID_STATE_ERR; |
| 90 return 0; | 90 return 0; |
| 91 } | 91 } |
| 92 | 92 |
| 93 // 5. Create a new SourceBuffer object and associated resources. | 93 // 5. Create a new SourceBuffer object and associated resources. |
| 94 ContentType contentType(type); | 94 ContentType contentType(type); |
| 95 Vector<String> codecs = contentType.codecs(); | 95 Vector<String> codecs = contentType.codecs(); |
| 96 OwnPtr<SourceBufferPrivate> sourceBufferPrivate = createSourceBufferPrivate(
contentType.type(), codecs, ec); | 96 OwnPtr<SourceBufferPrivate> sourceBufferPrivate = createSourceBufferPrivate(
contentType.type(), codecs, ec); |
| 97 if (!sourceBufferPrivate) | 97 |
| 98 if (!sourceBufferPrivate) { |
| 99 ASSERT(ec == NOT_SUPPORTED_ERR || ec == QUOTA_EXCEEDED_ERR); |
| 100 // 2. If type contains a MIME type that is not supported ..., then throw
a NOT_SUPPORTED_ERR exception and abort these steps. |
| 101 // 3. If the user agent can't handle any more SourceBuffer objects then
throw a QUOTA_EXCEEDED_ERR exception and abort these steps |
| 98 return 0; | 102 return 0; |
| 103 } |
| 99 | 104 |
| 100 RefPtr<WebKitSourceBuffer> buffer = WebKitSourceBuffer::create(sourceBufferP
rivate.release(), this); | 105 RefPtr<SourceBuffer> buffer = SourceBuffer::create(sourceBufferPrivate.relea
se(), this, asyncEventQueue()); |
| 101 // 6. Add the new object to sourceBuffers and fire a addsourcebuffer on that
object. | 106 // 6. Add the new object to sourceBuffers and fire a addsourcebuffer on that
object. |
| 102 m_sourceBuffers->add(buffer); | 107 m_sourceBuffers->add(buffer); |
| 103 m_activeSourceBuffers->add(buffer); | 108 m_activeSourceBuffers->add(buffer); |
| 104 // 7. Return the new object to the caller. | 109 // 7. Return the new object to the caller. |
| 105 return buffer.get(); | 110 return buffer.get(); |
| 106 } | 111 } |
| 107 | 112 |
| 108 void WebKitMediaSource::removeSourceBuffer(WebKitSourceBuffer* buffer, Exception
Code& ec) | 113 void MediaSource::removeSourceBuffer(SourceBuffer* buffer, ExceptionCode& ec) |
| 109 { | 114 { |
| 110 // 3.1 http://dvcs.w3.org/hg/html-media/raw-file/tip/media-source/media-sour
ce.html#dom-removesourcebuffer | 115 LOG(Media, "MediaSource::removeSourceBuffer() %p", this); |
| 116 RefPtr<SourceBuffer> protect(buffer); |
| 117 |
| 118 // 2.2 https://dvcs.w3.org/hg/html-media/raw-file/default/media-source/media
-source.html#widl-MediaSource-removeSourceBuffer-void-SourceBuffer-sourceBuffer |
| 111 // 1. If sourceBuffer is null then throw an INVALID_ACCESS_ERR exception and | 119 // 1. If sourceBuffer is null then throw an INVALID_ACCESS_ERR exception and |
| 112 // abort these steps. | 120 // abort these steps. |
| 113 if (!buffer) { | 121 if (!buffer) { |
| 114 ec = INVALID_ACCESS_ERR; | 122 ec = INVALID_ACCESS_ERR; |
| 115 return; | 123 return; |
| 116 } | 124 } |
| 117 | 125 |
| 118 // 2. If sourceBuffers is empty then throw an INVALID_STATE_ERR exception an
d | 126 // 2. If sourceBuffer specifies an object that is not in sourceBuffers then |
| 119 // abort these steps. | |
| 120 if (isClosed() || !m_sourceBuffers->length()) { | |
| 121 ec = INVALID_STATE_ERR; | |
| 122 return; | |
| 123 } | |
| 124 | |
| 125 // 3. If sourceBuffer specifies an object that is not in sourceBuffers then | |
| 126 // throw a NOT_FOUND_ERR exception and abort these steps. | 127 // throw a NOT_FOUND_ERR exception and abort these steps. |
| 127 // 6. Remove sourceBuffer from sourceBuffers and fire a removesourcebuffer e
vent | 128 if (!m_sourceBuffers->length() || !m_sourceBuffers->contains(buffer)) { |
| 128 // on that object. | |
| 129 if (!m_sourceBuffers->remove(buffer)) { | |
| 130 ec = NOT_FOUND_ERR; | 129 ec = NOT_FOUND_ERR; |
| 131 return; | 130 return; |
| 132 } | 131 } |
| 133 | 132 |
| 134 // 7. Destroy all resources for sourceBuffer. | 133 // 3. If the sourceBuffer.updating attribute equals true, then run the follo
wing steps: ... |
| 134 buffer->abortIfUpdating(); |
| 135 |
| 136 // Steps 4-9 are related to updating audioTracks, videoTracks, and textTrack
s which aren't implmented yet. |
| 137 // FIXME(91649): support track selection |
| 138 |
| 139 // 10. If sourceBuffer is in activeSourceBuffers, then remove sourceBuffer f
rom activeSourceBuffers ... |
| 135 m_activeSourceBuffers->remove(buffer); | 140 m_activeSourceBuffers->remove(buffer); |
| 136 | 141 |
| 137 // 4. Remove track information from audioTracks, videoTracks, and textTracks
for all tracks | 142 // 11. Remove sourceBuffer from sourceBuffers and fire a removesourcebuffer
event |
| 138 // associated with sourceBuffer and fire a simple event named change on the
modified lists. | 143 // on that object. |
| 139 // FIXME(91649): support track selection | 144 m_sourceBuffers->remove(buffer); |
| 140 | 145 |
| 141 // 5. If sourceBuffer is in activeSourceBuffers, then remove it from that li
st and fire a | 146 // 12. Destroy all resources for sourceBuffer. |
| 142 // removesourcebuffer event on that object. | 147 buffer->removedFromMediaSource(); |
| 143 // FIXME(91649): support track selection | |
| 144 } | 148 } |
| 145 | 149 |
| 146 void WebKitMediaSource::setReadyState(const AtomicString& state) | 150 void MediaSource::setReadyState(const AtomicString& state) |
| 147 { | 151 { |
| 148 ASSERT(state == openKeyword() || state == closedKeyword() || state == endedK
eyword()); | 152 ASSERT(state == openKeyword() || state == closedKeyword() || state == endedK
eyword()); |
| 149 String oldState = readyState(); | 153 AtomicString oldState = readyState(); |
| 150 if (oldState == state) | 154 if (oldState == state) |
| 151 return; | 155 return; |
| 152 | 156 |
| 157 LOG(Media, "MediaSource::setReadyState() %p : %s -> %s", this, oldState.stri
ng().ascii().data(), state.string().ascii().data()); |
| 158 |
| 153 MediaSourceBase::setReadyState(state); | 159 MediaSourceBase::setReadyState(state); |
| 154 | 160 |
| 155 if (isClosed()) { | 161 if (isOpen()) { |
| 156 m_sourceBuffers->clear(); | 162 scheduleEvent(eventNames().sourceopenEvent); |
| 157 m_activeSourceBuffers->clear(); | |
| 158 scheduleEvent(eventNames().webkitsourcecloseEvent); | |
| 159 return; | 163 return; |
| 160 } | 164 } |
| 161 | 165 |
| 162 if (oldState == openKeyword() && state == endedKeyword()) { | 166 if (oldState == openKeyword() && state == endedKeyword()) { |
| 163 scheduleEvent(eventNames().webkitsourceendedEvent); | 167 scheduleEvent(eventNames().sourceendedEvent); |
| 164 return; | 168 return; |
| 165 } | 169 } |
| 166 | 170 |
| 167 if (isOpen()) { | 171 ASSERT(isClosed()); |
| 168 scheduleEvent(eventNames().webkitsourceopenEvent); | 172 |
| 169 return; | 173 m_activeSourceBuffers->clear(); |
| 170 } | 174 |
| 175 // Clear SourceBuffer references to this object. |
| 176 for (unsigned long i = 0; i < m_sourceBuffers->length(); ++i) |
| 177 m_sourceBuffers->item(i)->removedFromMediaSource(); |
| 178 m_sourceBuffers->clear(); |
| 179 |
| 180 scheduleEvent(eventNames().sourcecloseEvent); |
| 171 } | 181 } |
| 172 | 182 |
| 173 bool WebKitMediaSource::isTypeSupported(const String& type) | 183 bool MediaSource::isTypeSupported(const String& type) |
| 174 { | 184 { |
| 175 // Section 2.1 isTypeSupported() method steps. | 185 LOG(Media, "MediaSource::isTypeSupported(%s)", type.ascii().data()); |
| 186 |
| 187 // Section 2.2 isTypeSupported() method steps. |
| 176 // https://dvcs.w3.org/hg/html-media/raw-file/tip/media-source/media-source.
html#widl-MediaSource-isTypeSupported-boolean-DOMString-type | 188 // https://dvcs.w3.org/hg/html-media/raw-file/tip/media-source/media-source.
html#widl-MediaSource-isTypeSupported-boolean-DOMString-type |
| 177 // 1. If type is an empty string, then return false. | 189 // 1. If type is an empty string, then return false. |
| 178 if (type.isNull() || type.isEmpty()) | 190 if (type.isNull() || type.isEmpty()) |
| 179 return false; | 191 return false; |
| 180 | 192 |
| 181 ContentType contentType(type); | 193 ContentType contentType(type); |
| 182 String codecs = contentType.parameter("codecs"); | 194 String codecs = contentType.parameter("codecs"); |
| 183 | 195 |
| 184 // 2. If type does not contain a valid MIME type string, then return false. | 196 // 2. If type does not contain a valid MIME type string, then return false. |
| 185 if (contentType.type().isEmpty() || codecs.isEmpty()) | 197 if (contentType.type().isEmpty() || codecs.isEmpty()) |
| 186 return false; | 198 return false; |
| 187 | 199 |
| 188 // 3. If type contains a media type or media subtype that the MediaSource do
es not support, then return false. | 200 // 3. If type contains a media type or media subtype that the MediaSource do
es not support, then return false. |
| 189 // 4. If type contains at a codec that the MediaSource does not support, the
n return false. | 201 // 4. If type contains at a codec that the MediaSource does not support, the
n return false. |
| 190 // 5. If the MediaSource does not support the specified combination of media
type, media subtype, and codecs then return false. | 202 // 5. If the MediaSource does not support the specified combination of media
type, media subtype, and codecs then return false. |
| 191 // 6. Return true. | 203 // 6. Return true. |
| 192 return MIMETypeRegistry::isSupportedMediaSourceMIMEType(contentType.type(),
codecs); | 204 return MIMETypeRegistry::isSupportedMediaSourceMIMEType(contentType.type(),
codecs); |
| 193 } | 205 } |
| 194 | 206 |
| 195 const AtomicString& WebKitMediaSource::interfaceName() const | 207 const AtomicString& MediaSource::interfaceName() const |
| 196 { | 208 { |
| 197 return eventNames().interfaceForWebKitMediaSource; | 209 return eventNames().interfaceForMediaSource; |
| 198 } | 210 } |
| 199 | 211 |
| 200 void WebKitMediaSource::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) co
nst | 212 void MediaSource::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const |
| 201 { | 213 { |
| 202 MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::DOM); | 214 MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::DOM); |
| 203 ScriptWrappable::reportMemoryUsage(memoryObjectInfo); | 215 ScriptWrappable::reportMemoryUsage(memoryObjectInfo); |
| 204 MediaSourceBase::reportMemoryUsage(memoryObjectInfo); | 216 MediaSourceBase::reportMemoryUsage(memoryObjectInfo); |
| 205 info.addMember(m_sourceBuffers, "sourceBuffers"); | 217 info.addMember(m_sourceBuffers, "sourceBuffers"); |
| 206 info.addMember(m_activeSourceBuffers, "activeSourceBuffers"); | 218 info.addMember(m_activeSourceBuffers, "activeSourceBuffers"); |
| 207 } | 219 } |
| 208 | 220 |
| 209 } // namespace WebCore | 221 } // namespace WebCore |
| OLD | NEW |