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() |
62 { | |
63 LOG(Media, "MediaSource::~MediaSource %p", this); | |
64 ASSERT(isClosed()); | |
65 } | |
66 | |
67 SourceBufferList* MediaSource::sourceBuffers() | |
adamk
2013/06/10 23:05:40
Not a big deal, but any reason not to inline this
acolwell GONE FROM CHROMIUM
2013/06/10 23:36:15
Done.
| |
59 { | 68 { |
60 return m_sourceBuffers.get(); | 69 return m_sourceBuffers.get(); |
61 } | 70 } |
62 | 71 |
63 WebKitSourceBufferList* WebKitMediaSource::activeSourceBuffers() | 72 SourceBufferList* MediaSource::activeSourceBuffers() |
64 { | 73 { |
65 // FIXME(91649): support track selection | |
66 return m_activeSourceBuffers.get(); | 74 return m_activeSourceBuffers.get(); |
67 } | 75 } |
68 | 76 |
69 WebKitSourceBuffer* WebKitMediaSource::addSourceBuffer(const String& type, Excep tionCode& ec) | 77 SourceBuffer* MediaSource::addSourceBuffer(const String& type, ExceptionCode& ec ) |
70 { | 78 { |
71 // 3.1 http://dvcs.w3.org/hg/html-media/raw-file/tip/media-source/media-sour ce.html#dom-addsourcebuffer | 79 LOG(Media, "MediaSource::addSourceBuffer(%s) %p", type.ascii().data(), this) ; |
80 | |
81 // 2.2 https://dvcs.w3.org/hg/html-media/raw-file/default/media-source/media -source.html#widl-MediaSource-addSourceBuffer-SourceBuffer-DOMString-type | |
72 // 1. If type is null or an empty then throw an INVALID_ACCESS_ERR exception and | 82 // 1. If type is null or an empty then throw an INVALID_ACCESS_ERR exception and |
73 // abort these steps. | 83 // abort these steps. |
74 if (type.isNull() || type.isEmpty()) { | 84 if (type.isNull() || type.isEmpty()) { |
75 ec = INVALID_ACCESS_ERR; | 85 ec = INVALID_ACCESS_ERR; |
76 return 0; | 86 return 0; |
77 } | 87 } |
78 | 88 |
79 // 2. If type contains a MIME type that is not supported ..., then throw a | 89 // 2. If type contains a MIME type that is not supported ..., then throw a |
80 // NOT_SUPPORTED_ERR exception and abort these steps. | 90 // NOT_SUPPORTED_ERR exception and abort these steps. |
81 if (!isTypeSupported(type)) { | 91 if (!isTypeSupported(type)) { |
82 ec = NOT_SUPPORTED_ERR; | 92 ec = NOT_SUPPORTED_ERR; |
83 return 0; | 93 return 0; |
84 } | 94 } |
85 | 95 |
86 // 4. If the readyState attribute is not in the "open" state then throw an | 96 // 4. If the readyState attribute is not in the "open" state then throw an |
87 // INVALID_STATE_ERR exception and abort these steps. | 97 // INVALID_STATE_ERR exception and abort these steps. |
88 if (!isOpen()) { | 98 if (!isOpen()) { |
89 ec = INVALID_STATE_ERR; | 99 ec = INVALID_STATE_ERR; |
90 return 0; | 100 return 0; |
91 } | 101 } |
92 | 102 |
93 // 5. Create a new SourceBuffer object and associated resources. | 103 // 5. Create a new SourceBuffer object and associated resources. |
94 ContentType contentType(type); | 104 ContentType contentType(type); |
95 Vector<String> codecs = contentType.codecs(); | 105 Vector<String> codecs = contentType.codecs(); |
96 OwnPtr<SourceBufferPrivate> sourceBufferPrivate = createSourceBufferPrivate( contentType.type(), codecs, ec); | 106 OwnPtr<SourceBufferPrivate> sourceBufferPrivate = createSourceBufferPrivate( contentType.type(), codecs, ec); |
97 if (!sourceBufferPrivate) | 107 |
108 if (!sourceBufferPrivate) { | |
109 ASSERT(ec == NOT_SUPPORTED_ERR || ec == QUOTA_EXCEEDED_ERR); | |
110 // 2. If type contains a MIME type that is not supported ..., then throw a NOT_SUPPORTED_ERR exception and abort these steps. | |
111 // 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; | 112 return 0; |
113 } | |
99 | 114 |
100 RefPtr<WebKitSourceBuffer> buffer = WebKitSourceBuffer::create(sourceBufferP rivate.release(), this); | 115 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. | 116 // 6. Add the new object to sourceBuffers and fire a addsourcebuffer on that object. |
102 m_sourceBuffers->add(buffer); | 117 m_sourceBuffers->add(buffer); |
103 m_activeSourceBuffers->add(buffer); | 118 m_activeSourceBuffers->add(buffer); |
104 // 7. Return the new object to the caller. | 119 // 7. Return the new object to the caller. |
105 return buffer.get(); | 120 return buffer.get(); |
106 } | 121 } |
107 | 122 |
108 void WebKitMediaSource::removeSourceBuffer(WebKitSourceBuffer* buffer, Exception Code& ec) | 123 void MediaSource::removeSourceBuffer(SourceBuffer* buffer, ExceptionCode& ec) |
109 { | 124 { |
110 // 3.1 http://dvcs.w3.org/hg/html-media/raw-file/tip/media-source/media-sour ce.html#dom-removesourcebuffer | 125 LOG(Media, "MediaSource::removeSourceBuffer() %p", this); |
126 RefPtr<SourceBuffer> protect(buffer); | |
127 | |
128 // 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 | 129 // 1. If sourceBuffer is null then throw an INVALID_ACCESS_ERR exception and |
112 // abort these steps. | 130 // abort these steps. |
113 if (!buffer) { | 131 if (!buffer) { |
114 ec = INVALID_ACCESS_ERR; | 132 ec = INVALID_ACCESS_ERR; |
115 return; | 133 return; |
116 } | 134 } |
117 | 135 |
118 // 2. If sourceBuffers is empty then throw an INVALID_STATE_ERR exception an d | 136 // 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. | 137 // throw a NOT_FOUND_ERR exception and abort these steps. |
127 // 6. Remove sourceBuffer from sourceBuffers and fire a removesourcebuffer e vent | 138 if (!m_sourceBuffers->length() || !m_sourceBuffers->contains(buffer)) { |
128 // on that object. | |
129 if (!m_sourceBuffers->remove(buffer)) { | |
130 ec = NOT_FOUND_ERR; | 139 ec = NOT_FOUND_ERR; |
131 return; | 140 return; |
132 } | 141 } |
133 | 142 |
134 // 7. Destroy all resources for sourceBuffer. | 143 // 3. If the sourceBuffer.updating attribute equals true, then run the follo wing steps: ... |
144 buffer->abortIfUpdating(); | |
145 | |
146 // Steps 4-9 are related to updating audioTracks, videoTracks, and textTrack s which aren't implmented yet. | |
147 // FIXME(91649): support track selection | |
148 | |
149 // 10. If sourceBuffer is in activeSourceBuffers, then remove sourceBuffer f rom activeSourceBuffers ... | |
135 m_activeSourceBuffers->remove(buffer); | 150 m_activeSourceBuffers->remove(buffer); |
136 | 151 |
137 // 4. Remove track information from audioTracks, videoTracks, and textTracks for all tracks | 152 // 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. | 153 // on that object. |
139 // FIXME(91649): support track selection | 154 m_sourceBuffers->remove(buffer); |
adamk
2013/06/10 23:05:40
Won't this fire two events?
acolwell GONE FROM CHROMIUM
2013/06/10 23:36:15
Yes. One for the m_activeSourceBuffers list and on
| |
140 | 155 |
141 // 5. If sourceBuffer is in activeSourceBuffers, then remove it from that li st and fire a | 156 // 12. Destroy all resources for sourceBuffer. |
142 // removesourcebuffer event on that object. | 157 buffer->removedFromMediaSource(); |
143 // FIXME(91649): support track selection | |
144 } | 158 } |
145 | 159 |
146 void WebKitMediaSource::setReadyState(const AtomicString& state) | 160 void MediaSource::setReadyState(const AtomicString& state) |
147 { | 161 { |
148 ASSERT(state == openKeyword() || state == closedKeyword() || state == endedK eyword()); | 162 ASSERT(state == openKeyword() || state == closedKeyword() || state == endedK eyword()); |
149 String oldState = readyState(); | 163 AtomicString oldState = readyState(); |
150 if (oldState == state) | 164 if (oldState == state) |
151 return; | 165 return; |
152 | 166 |
167 LOG(Media, "MediaSource::setReadyState() %p : %s -> %s", this, oldState.stri ng().ascii().data(), state.string().ascii().data()); | |
168 | |
153 MediaSourceBase::setReadyState(state); | 169 MediaSourceBase::setReadyState(state); |
154 | 170 |
155 if (isClosed()) { | 171 if (isOpen()) { |
156 m_sourceBuffers->clear(); | 172 scheduleEvent(eventNames().sourceopenEvent); |
157 m_activeSourceBuffers->clear(); | |
158 scheduleEvent(eventNames().webkitsourcecloseEvent); | |
159 return; | 173 return; |
160 } | 174 } |
161 | 175 |
162 if (oldState == openKeyword() && state == endedKeyword()) { | 176 if (oldState == openKeyword() && state == endedKeyword()) { |
163 scheduleEvent(eventNames().webkitsourceendedEvent); | 177 scheduleEvent(eventNames().sourceendedEvent); |
164 return; | 178 return; |
165 } | 179 } |
166 | 180 |
167 if (isOpen()) { | 181 ASSERT(isClosed()); |
168 scheduleEvent(eventNames().webkitsourceopenEvent); | 182 |
169 return; | 183 m_activeSourceBuffers->clear(); |
170 } | 184 |
185 // Clear SourceBuffer references to this object. | |
186 for (int i = 0; i < m_sourceBuffers->length(); ++i) | |
adamk
2013/06/10 23:05:40
I expect you'll need to make this some sort of uns
acolwell GONE FROM CHROMIUM
2013/06/10 23:36:15
Done. {Shakes fist at clang for not detecting this
| |
187 m_sourceBuffers->item(i)->removedFromMediaSource(); | |
188 m_sourceBuffers->clear(); | |
189 | |
190 scheduleEvent(eventNames().sourcecloseEvent); | |
171 } | 191 } |
172 | 192 |
173 bool WebKitMediaSource::isTypeSupported(const String& type) | 193 bool MediaSource::isTypeSupported(const String& type) |
174 { | 194 { |
175 // Section 2.1 isTypeSupported() method steps. | 195 LOG(Media, "MediaSource::isTypeSupported(%s)", type.ascii().data()); |
196 | |
197 // 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 | 198 // 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. | 199 // 1. If type is an empty string, then return false. |
178 if (type.isNull() || type.isEmpty()) | 200 if (type.isNull() || type.isEmpty()) |
179 return false; | 201 return false; |
180 | 202 |
181 ContentType contentType(type); | 203 ContentType contentType(type); |
182 String codecs = contentType.parameter("codecs"); | 204 String codecs = contentType.parameter("codecs"); |
183 | 205 |
184 // 2. If type does not contain a valid MIME type string, then return false. | 206 // 2. If type does not contain a valid MIME type string, then return false. |
185 if (contentType.type().isEmpty() || codecs.isEmpty()) | 207 if (contentType.type().isEmpty() || codecs.isEmpty()) |
186 return false; | 208 return false; |
187 | 209 |
188 // 3. If type contains a media type or media subtype that the MediaSource do es not support, then return false. | 210 // 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. | 211 // 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. | 212 // 5. If the MediaSource does not support the specified combination of media type, media subtype, and codecs then return false. |
191 // 6. Return true. | 213 // 6. Return true. |
192 return MIMETypeRegistry::isSupportedMediaSourceMIMEType(contentType.type(), codecs); | 214 return MIMETypeRegistry::isSupportedMediaSourceMIMEType(contentType.type(), codecs); |
193 } | 215 } |
194 | 216 |
195 const AtomicString& WebKitMediaSource::interfaceName() const | 217 const AtomicString& MediaSource::interfaceName() const |
196 { | 218 { |
197 return eventNames().interfaceForWebKitMediaSource; | 219 return eventNames().interfaceForMediaSource; |
198 } | 220 } |
199 | 221 |
200 void WebKitMediaSource::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) co nst | 222 void MediaSource::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const |
201 { | 223 { |
202 MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::DOM); | 224 MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::DOM); |
203 ScriptWrappable::reportMemoryUsage(memoryObjectInfo); | 225 ScriptWrappable::reportMemoryUsage(memoryObjectInfo); |
204 MediaSourceBase::reportMemoryUsage(memoryObjectInfo); | 226 MediaSourceBase::reportMemoryUsage(memoryObjectInfo); |
205 info.addMember(m_sourceBuffers, "sourceBuffers"); | 227 info.addMember(m_sourceBuffers, "sourceBuffers"); |
206 info.addMember(m_activeSourceBuffers, "activeSourceBuffers"); | 228 info.addMember(m_activeSourceBuffers, "activeSourceBuffers"); |
207 } | 229 } |
208 | 230 |
209 } // namespace WebCore | 231 } // namespace WebCore |
OLD | NEW |