<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[160258] trunk/Source/WebCore</title>
</head>
<body>
<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; }
#msg dl a { font-weight: bold}
#msg dl a:link { color:#fc3; }
#msg dl a:active { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/160258">160258</a></dd>
<dt>Author</dt> <dd>jer.noble@apple.com</dd>
<dt>Date</dt> <dd>2013-12-06 16:10:05 -0800 (Fri, 06 Dec 2013)</dd>
</dl>
<h3>Log Message</h3>
<pre>[MSE] Refactor MediaSourceBase back into MediaSource
https://bugs.webkit.org/show_bug.cgi?id=125245
Reviewed by Eric Carlson.
Now that the legacy WebKitMediaSource has been removed, there is no reason to have
a separate MediaSource and MediaSourceBase. Re-integrate the two.
Copy all the methods from MediaSource into MediaSourceBase, and rename the class MediaSource:
* Modules/mediasource/MediaSource.cpp: Copied from MediaSourceBase.cpp.
(WebCore::MediaSource::create): Copied from MediaSource.cpp.
(WebCore::MediaSource::addSourceBuffer): Ditto.
(WebCore::MediaSource::removeSourceBuffer): Ditto.
(WebCore::MediaSource::isTypeSupported): Ditto.
(WebCore::MediaSource::eventTargetInterface): Ditto.
(WebCore::MediaSource::sourceBufferDidChangeAcitveState): Ditto.
* Modules/mediasource/MediaSource.h: Copied from MediaSourceBase.h.
(WebCore::MediaSource::sourceBuffers): Copied from MediaSource.h.
(WebCore::MediaSource::activeSourceBuffers): Copied from MediaSource.h.
* Modules/mediasource/MediaSourceBase.cpp: Removed.
* Modules/mediasource/MediaSourceBase.h: Removed.
Change all references to MediaSourceBase into MediaSource:
* Modules/mediasource/DOMURLMediaSource.cpp:
(WebCore::DOMURLMediaSource::createObjectURL):
* Modules/mediasource/DOMURLMediaSource.h:
* Modules/mediasource/MediaSourceRegistry.cpp:
(WebCore::MediaSourceRegistry::registerURL):
(WebCore::MediaSourceRegistry::unregisterURL):
* Modules/mediasource/MediaSourceRegistry.h:
Remove MediaSourceBase.cpp/h from the project file:
* WebCore.xcodeproj/project.pbxproj:
* GNUmakefile.list.am:</pre>
<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreGNUmakefilelistam">trunk/Source/WebCore/GNUmakefile.list.am</a></li>
<li><a href="#trunkSourceWebCoreModulesmediasourceDOMURLMediaSourcecpp">trunk/Source/WebCore/Modules/mediasource/DOMURLMediaSource.cpp</a></li>
<li><a href="#trunkSourceWebCoreModulesmediasourceDOMURLMediaSourceh">trunk/Source/WebCore/Modules/mediasource/DOMURLMediaSource.h</a></li>
<li><a href="#trunkSourceWebCoreModulesmediasourceMediaSourcecpp">trunk/Source/WebCore/Modules/mediasource/MediaSource.cpp</a></li>
<li><a href="#trunkSourceWebCoreModulesmediasourceMediaSourceh">trunk/Source/WebCore/Modules/mediasource/MediaSource.h</a></li>
<li><a href="#trunkSourceWebCoreModulesmediasourceMediaSourceRegistrycpp">trunk/Source/WebCore/Modules/mediasource/MediaSourceRegistry.cpp</a></li>
<li><a href="#trunkSourceWebCoreModulesmediasourceMediaSourceRegistryh">trunk/Source/WebCore/Modules/mediasource/MediaSourceRegistry.h</a></li>
<li><a href="#trunkSourceWebCoreWebCorexcodeprojprojectpbxproj">trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj</a></li>
</ul>
<h3>Removed Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreModulesmediasourceMediaSourceBasecpp">trunk/Source/WebCore/Modules/mediasource/MediaSourceBase.cpp</a></li>
<li><a href="#trunkSourceWebCoreModulesmediasourceMediaSourceBaseh">trunk/Source/WebCore/Modules/mediasource/MediaSourceBase.h</a></li>
</ul>
</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (160257 => 160258)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2013-12-06 23:20:09 UTC (rev 160257)
+++ trunk/Source/WebCore/ChangeLog        2013-12-07 00:10:05 UTC (rev 160258)
</span><span class="lines">@@ -1,3 +1,40 @@
</span><ins>+2013-12-04 Jer Noble <jer.noble@apple.com>
+
+ [MSE] Refactor MediaSourceBase back into MediaSource
+ https://bugs.webkit.org/show_bug.cgi?id=125245
+
+ Reviewed by Eric Carlson.
+
+ Now that the legacy WebKitMediaSource has been removed, there is no reason to have
+ a separate MediaSource and MediaSourceBase. Re-integrate the two.
+
+ Copy all the methods from MediaSource into MediaSourceBase, and rename the class MediaSource:
+ * Modules/mediasource/MediaSource.cpp: Copied from MediaSourceBase.cpp.
+ (WebCore::MediaSource::create): Copied from MediaSource.cpp.
+ (WebCore::MediaSource::addSourceBuffer): Ditto.
+ (WebCore::MediaSource::removeSourceBuffer): Ditto.
+ (WebCore::MediaSource::isTypeSupported): Ditto.
+ (WebCore::MediaSource::eventTargetInterface): Ditto.
+ (WebCore::MediaSource::sourceBufferDidChangeAcitveState): Ditto.
+ * Modules/mediasource/MediaSource.h: Copied from MediaSourceBase.h.
+ (WebCore::MediaSource::sourceBuffers): Copied from MediaSource.h.
+ (WebCore::MediaSource::activeSourceBuffers): Copied from MediaSource.h.
+ * Modules/mediasource/MediaSourceBase.cpp: Removed.
+ * Modules/mediasource/MediaSourceBase.h: Removed.
+
+ Change all references to MediaSourceBase into MediaSource:
+ * Modules/mediasource/DOMURLMediaSource.cpp:
+ (WebCore::DOMURLMediaSource::createObjectURL):
+ * Modules/mediasource/DOMURLMediaSource.h:
+ * Modules/mediasource/MediaSourceRegistry.cpp:
+ (WebCore::MediaSourceRegistry::registerURL):
+ (WebCore::MediaSourceRegistry::unregisterURL):
+ * Modules/mediasource/MediaSourceRegistry.h:
+
+ Remove MediaSourceBase.cpp/h from the project file:
+ * WebCore.xcodeproj/project.pbxproj:
+ * GNUmakefile.list.am:
+
</ins><span class="cx"> 2013-12-06 Eric Carlson <eric.carlson@apple.com>
</span><span class="cx">
</span><span class="cx"> r159827 broke plug-in snapshotting
</span></span></pre></div>
<a id="trunkSourceWebCoreGNUmakefilelistam"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/GNUmakefile.list.am (160257 => 160258)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/GNUmakefile.list.am        2013-12-06 23:20:09 UTC (rev 160257)
+++ trunk/Source/WebCore/GNUmakefile.list.am        2013-12-07 00:10:05 UTC (rev 160258)
</span><span class="lines">@@ -1874,8 +1874,6 @@
</span><span class="cx">         Source/WebCore/Modules/indexeddb/WorkerGlobalScopeIndexedDatabase.h \
</span><span class="cx">         Source/WebCore/Modules/mediasource/MediaSource.cpp \
</span><span class="cx">         Source/WebCore/Modules/mediasource/MediaSource.h \
</span><del>-        Source/WebCore/Modules/mediasource/MediaSourceBase.cpp \
-        Source/WebCore/Modules/mediasource/MediaSourceBase.h \
</del><span class="cx">         Source/WebCore/Modules/mediasource/MediaSourceRegistry.cpp \
</span><span class="cx">         Source/WebCore/Modules/mediasource/MediaSourceRegistry.h \
</span><span class="cx">         Source/WebCore/Modules/mediasource/SourceBuffer.cpp \
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesmediasourceDOMURLMediaSourcecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/mediasource/DOMURLMediaSource.cpp (160257 => 160258)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/mediasource/DOMURLMediaSource.cpp        2013-12-06 23:20:09 UTC (rev 160257)
+++ trunk/Source/WebCore/Modules/mediasource/DOMURLMediaSource.cpp        2013-12-07 00:10:05 UTC (rev 160258)
</span><span class="lines">@@ -34,12 +34,12 @@
</span><span class="cx"> #if ENABLE(MEDIA_SOURCE)
</span><span class="cx">
</span><span class="cx"> #include "DOMURL.h"
</span><del>-#include "MediaSourceBase.h"
</del><ins>+#include "MediaSource.h"
</ins><span class="cx"> #include <wtf/MainThread.h>
</span><span class="cx">
</span><span class="cx"> namespace WebCore {
</span><span class="cx">
</span><del>-String DOMURLMediaSource::createObjectURL(ScriptExecutionContext* scriptExecutionContext, MediaSourceBase* source)
</del><ins>+String DOMURLMediaSource::createObjectURL(ScriptExecutionContext* scriptExecutionContext, MediaSource* source)
</ins><span class="cx"> {
</span><span class="cx"> // Since WebWorkers cannot obtain MediaSource objects, we should be on the main thread.
</span><span class="cx"> ASSERT(isMainThread());
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesmediasourceDOMURLMediaSourceh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/mediasource/DOMURLMediaSource.h (160257 => 160258)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/mediasource/DOMURLMediaSource.h        2013-12-06 23:20:09 UTC (rev 160257)
+++ trunk/Source/WebCore/Modules/mediasource/DOMURLMediaSource.h        2013-12-07 00:10:05 UTC (rev 160258)
</span><span class="lines">@@ -37,12 +37,12 @@
</span><span class="cx">
</span><span class="cx"> namespace WebCore {
</span><span class="cx">
</span><del>-class MediaSourceBase;
</del><ins>+class MediaSource;
</ins><span class="cx"> class ScriptExecutionContext;
</span><span class="cx">
</span><span class="cx"> class DOMURLMediaSource {
</span><span class="cx"> public:
</span><del>- static String createObjectURL(ScriptExecutionContext*, MediaSourceBase*);
</del><ins>+ static String createObjectURL(ScriptExecutionContext*, MediaSource*);
</ins><span class="cx"> };
</span><span class="cx">
</span><span class="cx"> } // namespace WebCore
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesmediasourceMediaSourcecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/mediasource/MediaSource.cpp (160257 => 160258)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/mediasource/MediaSource.cpp        2013-12-06 23:20:09 UTC (rev 160257)
+++ trunk/Source/WebCore/Modules/mediasource/MediaSource.cpp        2013-12-07 00:10:05 UTC (rev 160258)
</span><span class="lines">@@ -36,6 +36,8 @@
</span><span class="cx"> #include "AudioTrack.h"
</span><span class="cx"> #include "AudioTrackList.h"
</span><span class="cx"> #include "ContentType.h"
</span><ins>+#include "Event.h"
+#include "ExceptionCode.h"
</ins><span class="cx"> #include "ExceptionCodePlaceholder.h"
</span><span class="cx"> #include "GenericEventQueue.h"
</span><span class="cx"> #include "HTMLMediaElement.h"
</span><span class="lines">@@ -51,6 +53,7 @@
</span><span class="cx"> #include "VideoTrackList.h"
</span><span class="cx"> #include <runtime/Uint8Array.h>
</span><span class="cx"> #include <wtf/text/CString.h>
</span><ins>+#include <wtf/text/WTFString.h>
</ins><span class="cx">
</span><span class="cx"> namespace WebCore {
</span><span class="cx">
</span><span class="lines">@@ -62,7 +65,10 @@
</span><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> MediaSource::MediaSource(ScriptExecutionContext& context)
</span><del>- : MediaSourceBase(context)
</del><ins>+ : ActiveDOMObject(&context)
+ , m_mediaElement(0)
+ , m_readyState(closedKeyword())
+ , m_asyncEventQueue(*this)
</ins><span class="cx"> {
</span><span class="cx"> LOG(Media, "MediaSource::MediaSource %p", this);
</span><span class="cx"> m_sourceBuffers = SourceBufferList::create(scriptExecutionContext());
</span><span class="lines">@@ -75,6 +81,259 @@
</span><span class="cx"> ASSERT(isClosed());
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+const AtomicString& MediaSource::openKeyword()
+{
+ DEFINE_STATIC_LOCAL(const AtomicString, open, ("open", AtomicString::ConstructFromLiteral));
+ return open;
+}
+
+const AtomicString& MediaSource::closedKeyword()
+{
+ DEFINE_STATIC_LOCAL(const AtomicString, closed, ("closed", AtomicString::ConstructFromLiteral));
+ return closed;
+}
+
+const AtomicString& MediaSource::endedKeyword()
+{
+ DEFINE_STATIC_LOCAL(const AtomicString, ended, ("ended", AtomicString::ConstructFromLiteral));
+ return ended;
+}
+
+void MediaSource::setPrivateAndOpen(PassRef<MediaSourcePrivate> mediaSourcePrivate)
+{
+ ASSERT(!m_private);
+ ASSERT(m_mediaElement);
+ m_private = std::move(mediaSourcePrivate);
+ setReadyState(openKeyword());
+}
+
+void MediaSource::addedToRegistry()
+{
+ setPendingActivity(this);
+}
+
+void MediaSource::removedFromRegistry()
+{
+ unsetPendingActivity(this);
+}
+
+double MediaSource::duration() const
+{
+ return isClosed() ? std::numeric_limits<float>::quiet_NaN() : m_private->duration();
+}
+
+PassRefPtr<TimeRanges> MediaSource::buffered() const
+{
+ // Implements MediaSource algorithm for HTMLMediaElement.buffered.
+ // https://dvcs.w3.org/hg/html-media/raw-file/default/media-source/media-source.html#htmlmediaelement-extensions
+ Vector<RefPtr<TimeRanges>> ranges = activeRanges();
+
+ // 1. If activeSourceBuffers.length equals 0 then return an empty TimeRanges object and abort these steps.
+ if (ranges.isEmpty())
+ return TimeRanges::create();
+
+ // 2. Let active ranges be the ranges returned by buffered for each SourceBuffer object in activeSourceBuffers.
+ // 3. Let highest end time be the largest range end time in the active ranges.
+ double highestEndTime = -1;
+ for (size_t i = 0; i < ranges.size(); ++i) {
+ unsigned length = ranges[i]->length();
+ if (length)
+ highestEndTime = std::max(highestEndTime, ranges[i]->end(length - 1, ASSERT_NO_EXCEPTION));
+ }
+
+ // Return an empty range if all ranges are empty.
+ if (highestEndTime < 0)
+ return TimeRanges::create();
+
+ // 4. Let intersection ranges equal a TimeRange object containing a single range from 0 to highest end time.
+ RefPtr<TimeRanges> intersectionRanges = TimeRanges::create(0, highestEndTime);
+
+ // 5. For each SourceBuffer object in activeSourceBuffers run the following steps:
+ bool ended = readyState() == endedKeyword();
+ for (size_t i = 0; i < ranges.size(); ++i) {
+ // 5.1 Let source ranges equal the ranges returned by the buffered attribute on the current SourceBuffer.
+ TimeRanges* sourceRanges = ranges[i].get();
+
+ // 5.2 If readyState is "ended", then set the end time on the last range in source ranges to highest end time.
+ if (ended && sourceRanges->length())
+ sourceRanges->add(sourceRanges->start(sourceRanges->length() - 1, ASSERT_NO_EXCEPTION), highestEndTime);
+
+ // 5.3 Let new intersection ranges equal the the intersection between the intersection ranges and the source ranges.
+ // 5.4 Replace the ranges in intersection ranges with the new intersection ranges.
+ intersectionRanges->intersectWith(sourceRanges);
+ }
+
+ return intersectionRanges.release();
+}
+
+class SourceBufferBufferedDoesNotContainTime {
+public:
+ SourceBufferBufferedDoesNotContainTime(double time) : m_time(time) { }
+ bool operator()(RefPtr<SourceBuffer> sourceBuffer)
+ {
+ return !sourceBuffer->buffered()->contain(m_time);
+ }
+
+ double m_time;
+};
+
+class SourceBufferBufferedHasEnough {
+public:
+ SourceBufferBufferedHasEnough(double time, double duration) : m_time(time), m_duration(duration) { }
+ bool operator()(RefPtr<SourceBuffer> sourceBuffer)
+ {
+ size_t rangePos = sourceBuffer->buffered()->find(m_time);
+ if (rangePos == notFound)
+ return false;
+
+ double endTime = sourceBuffer->buffered()->end(rangePos, IGNORE_EXCEPTION);
+ return m_duration - endTime < 1;
+ }
+
+ double m_time;
+ double m_duration;
+};
+
+class SourceBufferBufferedHasFuture {
+public:
+ SourceBufferBufferedHasFuture(double time) : m_time(time) { }
+ bool operator()(RefPtr<SourceBuffer> sourceBuffer)
+ {
+ size_t rangePos = sourceBuffer->buffered()->find(m_time);
+ if (rangePos == notFound)
+ return false;
+
+ double endTime = sourceBuffer->buffered()->end(rangePos, IGNORE_EXCEPTION);
+ return endTime - m_time > 1;
+ }
+
+ double m_time;
+};
+
+void MediaSource::monitorSourceBuffers()
+{
+ double currentTime = mediaElement()->currentTime();
+
+ // 2.4.4 SourceBuffer Monitoring
+ // https://dvcs.w3.org/hg/html-media/raw-file/default/media-source/media-source.html#buffer-monitoring
+ // ↳ If buffered for all objects in activeSourceBuffers do not contain TimeRanges for the current
+ // playback position:
+ auto begin = m_activeSourceBuffers->begin();
+ auto end = m_activeSourceBuffers->end();
+ if (std::all_of(begin, end, SourceBufferBufferedDoesNotContainTime(currentTime))) {
+ // 1. Set the HTMLMediaElement.readyState attribute to HAVE_METADATA.
+ // 2. If this is the first transition to HAVE_METADATA, then queue a task to fire a simple event
+ // named loadedmetadata at the media element.
+ m_private->setReadyState(MediaPlayer::HaveMetadata);
+
+ // 3. Abort these steps.
+ return;
+ }
+
+ // ↳ If buffered for all objects in activeSourceBuffers contain TimeRanges that include the current
+ // playback position and enough data to ensure uninterrupted playback:
+ if (std::all_of(begin, end, SourceBufferBufferedHasEnough(currentTime, mediaElement()->duration()))) {
+ // 1. Set the HTMLMediaElement.readyState attribute to HAVE_ENOUGH_DATA.
+ // 2. Queue a task to fire a simple event named canplaythrough at the media element.
+ // 3. Playback may resume at this point if it was previously suspended by a transition to HAVE_CURRENT_DATA.
+ m_private->setReadyState(MediaPlayer::HaveEnoughData);
+
+ // 4. Abort these steps.
+ return;
+ }
+
+ // ↳ If buffered for at least one object in activeSourceBuffers contains a TimeRange that includes
+ // the current playback position but not enough data to ensure uninterrupted playback:
+ if (std::any_of(begin, end, SourceBufferBufferedHasFuture(currentTime))) {
+ // 1. Set the HTMLMediaElement.readyState attribute to HAVE_FUTURE_DATA.
+ // 2. If the previous value of HTMLMediaElement.readyState was less than HAVE_FUTURE_DATA, then queue a task to fire a simple event named canplay at the media element.
+ // 3. Playback may resume at this point if it was previously suspended by a transition to HAVE_CURRENT_DATA.
+ m_private->setReadyState(MediaPlayer::HaveFutureData);
+
+ // 4. Abort these steps.
+ return;
+ }
+
+ // ↳ If buffered for at least one object in activeSourceBuffers contains a TimeRange that ends
+ // at the current playback position and does not have a range covering the time immediately
+ // after the current position:
+ // NOTE: Logically, !(all objects do not contain currentTime) == (some objects contain current time)
+
+ // 1. Set the HTMLMediaElement.readyState attribute to HAVE_CURRENT_DATA.
+ // 2. If this is the first transition to HAVE_CURRENT_DATA, then queue a task to fire a simple
+ // event named loadeddata at the media element.
+ // 3. Playback is suspended at this point since the media element doesn't have enough data to
+ // advance the media timeline.
+ m_private->setReadyState(MediaPlayer::HaveCurrentData);
+
+ // 4. Abort these steps.
+}
+
+void MediaSource::setDuration(double duration, ExceptionCode& ec)
+{
+ if (duration < 0.0 || std::isnan(duration)) {
+ ec = INVALID_ACCESS_ERR;
+ return;
+ }
+ if (!isOpen()) {
+ ec = INVALID_STATE_ERR;
+ return;
+ }
+ m_private->setDuration(duration);
+}
+
+
+void MediaSource::setReadyState(const AtomicString& state)
+{
+ ASSERT(state == openKeyword() || state == closedKeyword() || state == endedKeyword());
+
+ AtomicString oldState = readyState();
+ LOG(Media, "MediaSource::setReadyState() %p : %s -> %s", this, oldState.string().ascii().data(), state.string().ascii().data());
+
+ if (state == closedKeyword()) {
+ m_private.clear();
+ m_mediaElement = 0;
+ }
+
+ if (oldState == state)
+ return;
+
+ m_readyState = state;
+
+ onReadyStateChange(oldState, state);
+}
+
+void MediaSource::endOfStream(const AtomicString& error, ExceptionCode& ec)
+{
+ DEFINE_STATIC_LOCAL(const AtomicString, network, ("network", AtomicString::ConstructFromLiteral));
+ DEFINE_STATIC_LOCAL(const AtomicString, decode, ("decode", AtomicString::ConstructFromLiteral));
+
+ // 3.1 http://dvcs.w3.org/hg/html-media/raw-file/tip/media-source/media-source.html#dom-endofstream
+ // 1. If the readyState attribute is not in the "open" state then throw an
+ // INVALID_STATE_ERR exception and abort these steps.
+ if (!isOpen()) {
+ ec = INVALID_STATE_ERR;
+ return;
+ }
+
+ MediaSourcePrivate::EndOfStreamStatus eosStatus = MediaSourcePrivate::EosNoError;
+
+ if (error.isNull() || error.isEmpty())
+ eosStatus = MediaSourcePrivate::EosNoError;
+ else if (error == network)
+ eosStatus = MediaSourcePrivate::EosNetworkError;
+ else if (error == decode)
+ eosStatus = MediaSourcePrivate::EosDecodeError;
+ else {
+ ec = INVALID_ACCESS_ERR;
+ return;
+ }
+
+ // 2. Change the readyState attribute value to "ended".
+ setReadyState(endedKeyword());
+ m_private->markEndOfStream(eosStatus);
+}
+
</ins><span class="cx"> SourceBuffer* MediaSource::addSourceBuffer(const String& type, ExceptionCode& ec)
</span><span class="cx"> {
</span><span class="cx"> LOG(Media, "MediaSource::addSourceBuffer(%s) %p", type.ascii().data(), this);
</span><span class="lines">@@ -256,58 +515,25 @@
</span><span class="cx"> // cancelable, and that uses the TrackEvent interface, at the SourceBuffer textTracks list.
</span><span class="cx"> textTracks->remove(track);
</span><span class="cx"> }
</span><del>-
</del><ins>+
</ins><span class="cx"> // 9.4 If the removed enabled text track flag equals true, then queue a task to fire a simple event
</span><span class="cx"> // named change at the HTMLMediaElement textTracks list.
</span><span class="cx"> if (removedEnabledTextTrack)
</span><span class="cx"> mediaElement()->textTracks()->scheduleChangeEvent();
</span><span class="cx"> }
</span><del>-
-
</del><ins>+
+
</ins><span class="cx"> // 10. If sourceBuffer is in activeSourceBuffers, then remove sourceBuffer from activeSourceBuffers ...
</span><span class="cx"> m_activeSourceBuffers->remove(buffer);
</span><del>-
</del><ins>+
</ins><span class="cx"> // 11. Remove sourceBuffer from sourceBuffers and fire a removesourcebuffer event
</span><span class="cx"> // on that object.
</span><span class="cx"> m_sourceBuffers->remove(buffer);
</span><del>-
</del><ins>+
</ins><span class="cx"> // 12. Destroy all resources for sourceBuffer.
</span><span class="cx"> buffer->removedFromMediaSource();
</span><span class="cx"> }
</span><span class="cx">
</span><del>-void MediaSource::onReadyStateChange(const AtomicString& oldState, const AtomicString& newState)
-{
- if (isOpen()) {
- scheduleEvent(eventNames().sourceopenEvent);
- return;
- }
-
- if (oldState == openKeyword() && newState == endedKeyword()) {
- scheduleEvent(eventNames().sourceendedEvent);
- return;
- }
-
- ASSERT(isClosed());
-
- m_activeSourceBuffers->clear();
-
- // Clear SourceBuffer references to this object.
- for (unsigned long i = 0; i < m_sourceBuffers->length(); ++i)
- m_sourceBuffers->item(i)->removedFromMediaSource();
- m_sourceBuffers->clear();
-
- scheduleEvent(eventNames().sourcecloseEvent);
-}
-
-Vector<RefPtr<TimeRanges>> MediaSource::activeRanges() const
-{
- Vector<RefPtr<TimeRanges>> activeRanges(m_activeSourceBuffers->length());
- for (size_t i = 0; i < m_activeSourceBuffers->length(); ++i)
- activeRanges[i] = m_activeSourceBuffers->item(i)->buffered(ASSERT_NO_EXCEPTION);
-
- return activeRanges;
-}
-
</del><span class="cx"> bool MediaSource::isTypeSupported(const String& type)
</span><span class="cx"> {
</span><span class="cx"> LOG(Media, "MediaSource::isTypeSupported(%s)", type.ascii().data());
</span><span class="lines">@@ -336,11 +562,21 @@
</span><span class="cx"> return MediaPlayer::supportsType(parameters, 0) != MediaPlayer::IsNotSupported;
</span><span class="cx"> }
</span><span class="cx">
</span><del>-EventTargetInterface MediaSource::eventTargetInterface() const
</del><ins>+bool MediaSource::isOpen() const
</ins><span class="cx"> {
</span><del>- return MediaSourceEventTargetInterfaceType;
</del><ins>+ return readyState() == openKeyword();
</ins><span class="cx"> }
</span><span class="cx">
</span><ins>+bool MediaSource::isClosed() const
+{
+ return readyState() == closedKeyword();
+}
+
+void MediaSource::close()
+{
+ setReadyState(closedKeyword());
+}
+
</ins><span class="cx"> void MediaSource::sourceBufferDidChangeAcitveState(SourceBuffer* sourceBuffer, bool active)
</span><span class="cx"> {
</span><span class="cx"> if (active && !m_activeSourceBuffers->contains(sourceBuffer))
</span><span class="lines">@@ -349,109 +585,122 @@
</span><span class="cx"> m_activeSourceBuffers->remove(sourceBuffer);
</span><span class="cx"> }
</span><span class="cx">
</span><del>-class SourceBufferBufferedDoesNotContainTime {
-public:
- SourceBufferBufferedDoesNotContainTime(double time) : m_time(time) { }
- bool operator()(RefPtr<SourceBuffer> sourceBuffer)
- {
- return !sourceBuffer->buffered()->contain(m_time);
- }
</del><ins>+bool MediaSource::attachToElement(HTMLMediaElement* element)
+{
+ if (m_mediaElement)
+ return false;
</ins><span class="cx">
</span><del>- double m_time;
-};
</del><ins>+ ASSERT(isClosed());
</ins><span class="cx">
</span><del>-class SourceBufferBufferedHasEnough {
-public:
- SourceBufferBufferedHasEnough(double time, double duration) : m_time(time), m_duration(duration) { }
- bool operator()(RefPtr<SourceBuffer> sourceBuffer)
- {
- size_t rangePos = sourceBuffer->buffered()->find(m_time);
- if (rangePos == notFound)
- return false;
</del><ins>+ m_mediaElement = element;
+ return true;
+}
</ins><span class="cx">
</span><del>- double endTime = sourceBuffer->buffered()->end(rangePos, IGNORE_EXCEPTION);
- return m_duration - endTime < 1;
- }
</del><ins>+void MediaSource::openIfInEndedState()
+{
+ if (m_readyState != endedKeyword())
+ return;
</ins><span class="cx">
</span><del>- double m_time;
- double m_duration;
-};
</del><ins>+ setReadyState(openKeyword());
+ m_private->unmarkEndOfStream();
+}
</ins><span class="cx">
</span><del>-class SourceBufferBufferedHasFuture {
-public:
- SourceBufferBufferedHasFuture(double time) : m_time(time) { }
- bool operator()(RefPtr<SourceBuffer> sourceBuffer)
- {
- size_t rangePos = sourceBuffer->buffered()->find(m_time);
- if (rangePos == notFound)
- return false;
</del><ins>+bool MediaSource::hasPendingActivity() const
+{
+ return m_private || m_asyncEventQueue.hasPendingEvents()
+ || ActiveDOMObject::hasPendingActivity();
+}
</ins><span class="cx">
</span><del>- double endTime = sourceBuffer->buffered()->end(rangePos, IGNORE_EXCEPTION);
- return endTime - m_time > 1;
</del><ins>+void MediaSource::stop()
+{
+ m_asyncEventQueue.close();
+ if (!isClosed())
+ setReadyState(closedKeyword());
+ m_private.clear();
+}
+
+void MediaSource::onReadyStateChange(const AtomicString& oldState, const AtomicString& newState)
+{
+ if (isOpen()) {
+ scheduleEvent(eventNames().sourceopenEvent);
+ return;
</ins><span class="cx"> }
</span><span class="cx">
</span><del>- double m_time;
-};
</del><ins>+ if (oldState == openKeyword() && newState == endedKeyword()) {
+ scheduleEvent(eventNames().sourceendedEvent);
+ return;
+ }
</ins><span class="cx">
</span><del>-void MediaSource::monitorSourceBuffers()
</del><ins>+ ASSERT(isClosed());
+
+ m_activeSourceBuffers->clear();
+
+ // Clear SourceBuffer references to this object.
+ for (unsigned long i = 0, length = m_sourceBuffers->length(); i < length; ++i)
+ m_sourceBuffers->item(i)->removedFromMediaSource();
+ m_sourceBuffers->clear();
+
+ scheduleEvent(eventNames().sourcecloseEvent);
+}
+
+Vector<RefPtr<TimeRanges>> MediaSource::activeRanges() const
</ins><span class="cx"> {
</span><del>- double currentTime = mediaElement()->currentTime();
</del><ins>+ Vector<RefPtr<TimeRanges>> activeRanges(m_activeSourceBuffers->length());
+ for (size_t i = 0, length = m_activeSourceBuffers->length(); i < length; ++i)
+ activeRanges[i] = m_activeSourceBuffers->item(i)->buffered(ASSERT_NO_EXCEPTION);
</ins><span class="cx">
</span><del>- // 2.4.4 SourceBuffer Monitoring
- // https://dvcs.w3.org/hg/html-media/raw-file/default/media-source/media-source.html#buffer-monitoring
- // ↳ If buffered for all objects in activeSourceBuffers do not contain TimeRanges for the current
- // playback position:
- auto begin = m_activeSourceBuffers->begin();
- auto end = m_activeSourceBuffers->end();
- if (std::all_of(begin, end, SourceBufferBufferedDoesNotContainTime(currentTime))) {
- // 1. Set the HTMLMediaElement.readyState attribute to HAVE_METADATA.
- // 2. If this is the first transition to HAVE_METADATA, then queue a task to fire a simple event
- // named loadedmetadata at the media element.
- m_private->setReadyState(MediaPlayer::HaveMetadata);
</del><ins>+ return activeRanges;
+}
</ins><span class="cx">
</span><del>- // 3. Abort these steps.
- return;
</del><ins>+RefPtr<SourceBufferPrivate> MediaSource::createSourceBufferPrivate(const ContentType& type, ExceptionCode& ec)
+{
+ RefPtr<SourceBufferPrivate> sourceBufferPrivate;
+ switch (m_private->addSourceBuffer(type, sourceBufferPrivate)) {
+ case MediaSourcePrivate::Ok: {
+ return sourceBufferPrivate;
</ins><span class="cx"> }
</span><ins>+ case MediaSourcePrivate::NotSupported:
+ // 2.2 https://dvcs.w3.org/hg/html-media/raw-file/default/media-source/media-source.html#widl-MediaSource-addSourceBuffer-SourceBuffer-DOMString-type
+ // Step 2: If type contains a MIME type ... that is not supported with the types
+ // specified for the other SourceBuffer objects in sourceBuffers, then throw
+ // a NOT_SUPPORTED_ERR exception and abort these steps.
+ ec = NOT_SUPPORTED_ERR;
+ return nullptr;
+ case MediaSourcePrivate::ReachedIdLimit:
+ // 2.2 https://dvcs.w3.org/hg/html-media/raw-file/default/media-source/media-source.html#widl-MediaSource-addSourceBuffer-SourceBuffer-DOMString-type
+ // Step 3: If the user agent can't handle any more SourceBuffer objects then throw
+ // a QUOTA_EXCEEDED_ERR exception and abort these steps.
+ ec = QUOTA_EXCEEDED_ERR;
+ return nullptr;
+ }
</ins><span class="cx">
</span><del>- // ↳ If buffered for all objects in activeSourceBuffers contain TimeRanges that include the current
- // playback position and enough data to ensure uninterrupted playback:
- if (std::all_of(begin, end, SourceBufferBufferedHasEnough(currentTime, mediaElement()->duration()))) {
- // 1. Set the HTMLMediaElement.readyState attribute to HAVE_ENOUGH_DATA.
- // 2. Queue a task to fire a simple event named canplaythrough at the media element.
- // 3. Playback may resume at this point if it was previously suspended by a transition to HAVE_CURRENT_DATA.
- m_private->setReadyState(MediaPlayer::HaveEnoughData);
</del><ins>+ ASSERT_NOT_REACHED();
+ return nullptr;
+}
</ins><span class="cx">
</span><del>- // 4. Abort these steps.
- return;
- }
</del><ins>+void MediaSource::scheduleEvent(const AtomicString& eventName)
+{
+ RefPtr<Event> event = Event::create(eventName, false, false);
+ event->setTarget(this);
</ins><span class="cx">
</span><del>- // ↳ If buffered for at least one object in activeSourceBuffers contains a TimeRange that includes
- // the current playback position but not enough data to ensure uninterrupted playback:
- if (std::any_of(begin, end, SourceBufferBufferedHasFuture(currentTime))) {
- // 1. Set the HTMLMediaElement.readyState attribute to HAVE_FUTURE_DATA.
- // 2. If the previous value of HTMLMediaElement.readyState was less than HAVE_FUTURE_DATA, then queue a task to fire a simple event named canplay at the media element.
- // 3. Playback may resume at this point if it was previously suspended by a transition to HAVE_CURRENT_DATA.
- m_private->setReadyState(MediaPlayer::HaveFutureData);
</del><ins>+ m_asyncEventQueue.enqueueEvent(event.release());
+}
</ins><span class="cx">
</span><del>- // 4. Abort these steps.
- return;
- }
</del><ins>+ScriptExecutionContext* MediaSource::scriptExecutionContext() const
+{
+ return ActiveDOMObject::scriptExecutionContext();
+}
</ins><span class="cx">
</span><del>- // ↳ If buffered for at least one object in activeSourceBuffers contains a TimeRange that ends
- // at the current playback position and does not have a range covering the time immediately
- // after the current position:
- // NOTE: Logically, !(all objects do not contain currentTime) == (some objects contain current time)
</del><ins>+EventTargetInterface MediaSource::eventTargetInterface() const
+{
+ return MediaSourceEventTargetInterfaceType;
+}
</ins><span class="cx">
</span><del>- // 1. Set the HTMLMediaElement.readyState attribute to HAVE_CURRENT_DATA.
- // 2. If this is the first transition to HAVE_CURRENT_DATA, then queue a task to fire a simple
- // event named loadeddata at the media element.
- // 3. Playback is suspended at this point since the media element doesn't have enough data to
- // advance the media timeline.
- m_private->setReadyState(MediaPlayer::HaveCurrentData);
</del><ins>+URLRegistry& MediaSource::registry() const
+{
+ return MediaSourceRegistry::registry();
+}
</ins><span class="cx">
</span><del>- // 4. Abort these steps.
</del><span class="cx"> }
</span><span class="cx">
</span><del>-} // namespace WebCore
-
</del><span class="cx"> #endif
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesmediasourceMediaSourceh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/mediasource/MediaSource.h (160257 => 160258)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/mediasource/MediaSource.h        2013-12-06 23:20:09 UTC (rev 160257)
+++ trunk/Source/WebCore/Modules/mediasource/MediaSource.h        2013-12-07 00:10:05 UTC (rev 160258)
</span><span class="lines">@@ -33,19 +33,56 @@
</span><span class="cx">
</span><span class="cx"> #if ENABLE(MEDIA_SOURCE)
</span><span class="cx">
</span><del>-#include "MediaSourceBase.h"
</del><ins>+#include "ActiveDOMObject.h"
+#include "EventTarget.h"
+#include "GenericEventQueue.h"
+#include "HTMLMediaSource.h"
+#include "MediaSourcePrivate.h"
</ins><span class="cx"> #include "ScriptWrappable.h"
</span><span class="cx"> #include "SourceBuffer.h"
</span><span class="cx"> #include "SourceBufferList.h"
</span><ins>+#include "URLRegistry.h"
+#include <wtf/PassOwnPtr.h>
</ins><span class="cx"> #include <wtf/RefCounted.h>
</span><ins>+#include <wtf/Vector.h>
</ins><span class="cx">
</span><span class="cx"> namespace WebCore {
</span><span class="cx">
</span><del>-class MediaSource : public MediaSourceBase, public ScriptWrappable {
</del><ins>+class GenericEventQueue;
+
+class MediaSource : public RefCounted<MediaSource>, public HTMLMediaSource, public ActiveDOMObject, public EventTargetWithInlineData, public ScriptWrappable {
</ins><span class="cx"> public:
</span><ins>+ static const AtomicString& openKeyword();
+ static const AtomicString& closedKeyword();
+ static const AtomicString& endedKeyword();
+
</ins><span class="cx"> static PassRefPtr<MediaSource> create(ScriptExecutionContext&);
</span><span class="cx"> virtual ~MediaSource();
</span><span class="cx">
</span><ins>+ void addedToRegistry();
+ void removedFromRegistry();
+ void openIfInEndedState();
+ bool isOpen() const;
+ void sourceBufferDidChangeAcitveState(SourceBuffer*, bool);
+
+ // HTMLMediaSource
+ virtual bool attachToElement(HTMLMediaElement*) OVERRIDE;
+ virtual void setPrivateAndOpen(PassRef<MediaSourcePrivate>) OVERRIDE;
+ virtual void close() OVERRIDE;
+ virtual bool isClosed() const OVERRIDE;
+ virtual double duration() const OVERRIDE;
+ virtual PassRefPtr<TimeRanges> buffered() const OVERRIDE;
+ virtual void refHTMLMediaSource() OVERRIDE { ref(); }
+ virtual void derefHTMLMediaSource() OVERRIDE { deref(); }
+ virtual void monitorSourceBuffers() OVERRIDE;
+
+ void setDuration(double, ExceptionCode&);
+ const AtomicString& readyState() const { return m_readyState; }
+ void setReadyState(const AtomicString&);
+ void endOfStream(const AtomicString& error, ExceptionCode&);
+
+ HTMLMediaElement* mediaElement() const { return m_mediaElement; }
+
</ins><span class="cx"> // MediaSource.idl methods
</span><span class="cx"> SourceBufferList* sourceBuffers() { return m_sourceBuffers.get(); }
</span><span class="cx"> SourceBufferList* activeSourceBuffers() { return m_activeSourceBuffers.get(); }
</span><span class="lines">@@ -53,28 +90,41 @@
</span><span class="cx"> void removeSourceBuffer(SourceBuffer*, ExceptionCode&);
</span><span class="cx"> static bool isTypeSupported(const String& type);
</span><span class="cx">
</span><ins>+ // ActiveDOMObject interface
+ virtual bool hasPendingActivity() const OVERRIDE;
+ virtual void stop() OVERRIDE;
+
</ins><span class="cx"> // EventTarget interface
</span><ins>+ virtual ScriptExecutionContext* scriptExecutionContext() const OVERRIDE FINAL;
+ virtual void refEventTarget() OVERRIDE FINAL { ref(); }
+ virtual void derefEventTarget() OVERRIDE FINAL { deref(); }
</ins><span class="cx"> virtual EventTargetInterface eventTargetInterface() const OVERRIDE;
</span><span class="cx">
</span><del>- using RefCounted<MediaSourceBase>::ref;
- using RefCounted<MediaSourceBase>::deref;
</del><ins>+ // URLRegistrable interface
+ virtual URLRegistry& registry() const OVERRIDE;
</ins><span class="cx">
</span><del>- void sourceBufferDidChangeAcitveState(SourceBuffer*, bool);
</del><ins>+ using RefCounted<MediaSource>::ref;
+ using RefCounted<MediaSource>::deref;
</ins><span class="cx">
</span><del>- virtual void monitorSourceBuffers() OVERRIDE;
-
-private:
</del><ins>+protected:
</ins><span class="cx"> explicit MediaSource(ScriptExecutionContext&);
</span><span class="cx">
</span><del>- // MediaSourceBase interface
- virtual void onReadyStateChange(const AtomicString&, const AtomicString&) OVERRIDE;
- virtual Vector<RefPtr<TimeRanges>> activeRanges() const OVERRIDE;
</del><ins>+ void onReadyStateChange(const AtomicString& oldState, const AtomicString& newState);
+ Vector<RefPtr<TimeRanges>> activeRanges() const;
</ins><span class="cx">
</span><ins>+ RefPtr<SourceBufferPrivate> createSourceBufferPrivate(const ContentType&, ExceptionCode&);
+ void scheduleEvent(const AtomicString& eventName);
+ GenericEventQueue& asyncEventQueue() { return m_asyncEventQueue; }
+
+ RefPtr<MediaSourcePrivate> m_private;
</ins><span class="cx"> RefPtr<SourceBufferList> m_sourceBuffers;
</span><span class="cx"> RefPtr<SourceBufferList> m_activeSourceBuffers;
</span><ins>+ HTMLMediaElement* m_mediaElement;
+ AtomicString m_readyState;
+ GenericEventQueue m_asyncEventQueue;
</ins><span class="cx"> };
</span><span class="cx">
</span><del>-} // namespace WebCore
</del><ins>+}
</ins><span class="cx">
</span><span class="cx"> #endif
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesmediasourceMediaSourceBasecpp"></a>
<div class="delfile"><h4>Deleted: trunk/Source/WebCore/Modules/mediasource/MediaSourceBase.cpp (160257 => 160258)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/mediasource/MediaSourceBase.cpp        2013-12-06 23:20:09 UTC (rev 160257)
+++ trunk/Source/WebCore/Modules/mediasource/MediaSourceBase.cpp        2013-12-07 00:10:05 UTC (rev 160258)
</span><span class="lines">@@ -1,305 +0,0 @@
</span><del>-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "MediaSourceBase.h"
-
-#if ENABLE(MEDIA_SOURCE)
-
-#include "Event.h"
-#include "ExceptionCode.h"
-#include "ExceptionCodePlaceholder.h"
-#include "GenericEventQueue.h"
-#include "Logging.h"
-#include "MediaSourceRegistry.h"
-#include "SourceBufferPrivate.h"
-#include <wtf/text/CString.h>
-#include <wtf/text/WTFString.h>
-
-namespace WebCore {
-
-MediaSourceBase::MediaSourceBase(ScriptExecutionContext& context)
- : ActiveDOMObject(&context)
- , m_mediaElement(0)
- , m_readyState(closedKeyword())
- , m_asyncEventQueue(*this)
-{
-}
-
-MediaSourceBase::~MediaSourceBase()
-{
-}
-
-const AtomicString& MediaSourceBase::openKeyword()
-{
- DEFINE_STATIC_LOCAL(const AtomicString, open, ("open", AtomicString::ConstructFromLiteral));
- return open;
-}
-
-const AtomicString& MediaSourceBase::closedKeyword()
-{
- DEFINE_STATIC_LOCAL(const AtomicString, closed, ("closed", AtomicString::ConstructFromLiteral));
- return closed;
-}
-
-const AtomicString& MediaSourceBase::endedKeyword()
-{
- DEFINE_STATIC_LOCAL(const AtomicString, ended, ("ended", AtomicString::ConstructFromLiteral));
- return ended;
-}
-
-void MediaSourceBase::setPrivateAndOpen(PassRef<MediaSourcePrivate> mediaSourcePrivate)
-{
- ASSERT(!m_private);
- ASSERT(m_mediaElement);
- m_private = std::move(mediaSourcePrivate);
- setReadyState(openKeyword());
-}
-
-void MediaSourceBase::addedToRegistry()
-{
- setPendingActivity(this);
-}
-
-void MediaSourceBase::removedFromRegistry()
-{
- unsetPendingActivity(this);
-}
-
-double MediaSourceBase::duration() const
-{
- return isClosed() ? std::numeric_limits<float>::quiet_NaN() : m_private->duration();
-}
-
-PassRefPtr<TimeRanges> MediaSourceBase::buffered() const
-{
- // Implements MediaSource algorithm for HTMLMediaElement.buffered.
- // https://dvcs.w3.org/hg/html-media/raw-file/default/media-source/media-source.html#htmlmediaelement-extensions
- Vector<RefPtr<TimeRanges>> ranges = activeRanges();
-
- // 1. If activeSourceBuffers.length equals 0 then return an empty TimeRanges object and abort these steps.
- if (ranges.isEmpty())
- return TimeRanges::create();
-
- // 2. Let active ranges be the ranges returned by buffered for each SourceBuffer object in activeSourceBuffers.
- // 3. Let highest end time be the largest range end time in the active ranges.
- double highestEndTime = -1;
- for (size_t i = 0; i < ranges.size(); ++i) {
- unsigned length = ranges[i]->length();
- if (length)
- highestEndTime = std::max(highestEndTime, ranges[i]->end(length - 1, ASSERT_NO_EXCEPTION));
- }
-
- // Return an empty range if all ranges are empty.
- if (highestEndTime < 0)
- return TimeRanges::create();
-
- // 4. Let intersection ranges equal a TimeRange object containing a single range from 0 to highest end time.
- RefPtr<TimeRanges> intersectionRanges = TimeRanges::create(0, highestEndTime);
-
- // 5. For each SourceBuffer object in activeSourceBuffers run the following steps:
- bool ended = readyState() == endedKeyword();
- for (size_t i = 0; i < ranges.size(); ++i) {
- // 5.1 Let source ranges equal the ranges returned by the buffered attribute on the current SourceBuffer.
- TimeRanges* sourceRanges = ranges[i].get();
-
- // 5.2 If readyState is "ended", then set the end time on the last range in source ranges to highest end time.
- if (ended && sourceRanges->length())
- sourceRanges->add(sourceRanges->start(sourceRanges->length() - 1, ASSERT_NO_EXCEPTION), highestEndTime);
-
- // 5.3 Let new intersection ranges equal the the intersection between the intersection ranges and the source ranges.
- // 5.4 Replace the ranges in intersection ranges with the new intersection ranges.
- intersectionRanges->intersectWith(sourceRanges);
- }
-
- return intersectionRanges.release();
-}
-
-void MediaSourceBase::setDuration(double duration, ExceptionCode& ec)
-{
- if (duration < 0.0 || std::isnan(duration)) {
- ec = INVALID_ACCESS_ERR;
- return;
- }
- if (!isOpen()) {
- ec = INVALID_STATE_ERR;
- return;
- }
- m_private->setDuration(duration);
-}
-
-
-void MediaSourceBase::setReadyState(const AtomicString& state)
-{
- ASSERT(state == openKeyword() || state == closedKeyword() || state == endedKeyword());
-
- AtomicString oldState = readyState();
- LOG(Media, "MediaSourceBase::setReadyState() %p : %s -> %s", this, oldState.string().ascii().data(), state.string().ascii().data());
-
- if (state == closedKeyword()) {
- m_private.clear();
- m_mediaElement = 0;
- }
-
- if (oldState == state)
- return;
-
- m_readyState = state;
-
- onReadyStateChange(oldState, state);
-}
-
-void MediaSourceBase::endOfStream(const AtomicString& error, ExceptionCode& ec)
-{
- DEFINE_STATIC_LOCAL(const AtomicString, network, ("network", AtomicString::ConstructFromLiteral));
- DEFINE_STATIC_LOCAL(const AtomicString, decode, ("decode", AtomicString::ConstructFromLiteral));
-
- // 3.1 http://dvcs.w3.org/hg/html-media/raw-file/tip/media-source/media-source.html#dom-endofstream
- // 1. If the readyState attribute is not in the "open" state then throw an
- // INVALID_STATE_ERR exception and abort these steps.
- if (!isOpen()) {
- ec = INVALID_STATE_ERR;
- return;
- }
-
- MediaSourcePrivate::EndOfStreamStatus eosStatus = MediaSourcePrivate::EosNoError;
-
- if (error.isNull() || error.isEmpty())
- eosStatus = MediaSourcePrivate::EosNoError;
- else if (error == network)
- eosStatus = MediaSourcePrivate::EosNetworkError;
- else if (error == decode)
- eosStatus = MediaSourcePrivate::EosDecodeError;
- else {
- ec = INVALID_ACCESS_ERR;
- return;
- }
-
- // 2. Change the readyState attribute value to "ended".
- setReadyState(endedKeyword());
- m_private->markEndOfStream(eosStatus);
-}
-
-bool MediaSourceBase::isOpen() const
-{
- return readyState() == openKeyword();
-}
-
-bool MediaSourceBase::isClosed() const
-{
- return readyState() == closedKeyword();
-}
-
-void MediaSourceBase::close()
-{
- setReadyState(closedKeyword());
-}
-
-bool MediaSourceBase::attachToElement(HTMLMediaElement* element)
-{
- if (m_mediaElement)
- return false;
-
- ASSERT(isClosed());
-
- m_mediaElement = element;
- return true;
-}
-
-void MediaSourceBase::openIfInEndedState()
-{
- if (m_readyState != endedKeyword())
- return;
-
- setReadyState(openKeyword());
- m_private->unmarkEndOfStream();
-}
-
-bool MediaSourceBase::hasPendingActivity() const
-{
- return m_private || m_asyncEventQueue.hasPendingEvents()
- || ActiveDOMObject::hasPendingActivity();
-}
-
-void MediaSourceBase::stop()
-{
- m_asyncEventQueue.close();
- if (!isClosed())
- setReadyState(closedKeyword());
- m_private.clear();
-}
-
-RefPtr<SourceBufferPrivate> MediaSourceBase::createSourceBufferPrivate(const ContentType& type, ExceptionCode& ec)
-{
- RefPtr<SourceBufferPrivate> sourceBufferPrivate;
- switch (m_private->addSourceBuffer(type, sourceBufferPrivate)) {
- case MediaSourcePrivate::Ok: {
- return sourceBufferPrivate;
- }
- case MediaSourcePrivate::NotSupported:
- // 2.2 https://dvcs.w3.org/hg/html-media/raw-file/default/media-source/media-source.html#widl-MediaSource-addSourceBuffer-SourceBuffer-DOMString-type
- // Step 2: If type contains a MIME type ... that is not supported with the types
- // specified for the other SourceBuffer objects in sourceBuffers, then throw
- // a NOT_SUPPORTED_ERR exception and abort these steps.
- ec = NOT_SUPPORTED_ERR;
- return nullptr;
- case MediaSourcePrivate::ReachedIdLimit:
- // 2.2 https://dvcs.w3.org/hg/html-media/raw-file/default/media-source/media-source.html#widl-MediaSource-addSourceBuffer-SourceBuffer-DOMString-type
- // Step 3: If the user agent can't handle any more SourceBuffer objects then throw
- // a QUOTA_EXCEEDED_ERR exception and abort these steps.
- ec = QUOTA_EXCEEDED_ERR;
- return nullptr;
- }
-
- ASSERT_NOT_REACHED();
- return nullptr;
-}
-
-void MediaSourceBase::scheduleEvent(const AtomicString& eventName)
-{
- RefPtr<Event> event = Event::create(eventName, false, false);
- event->setTarget(this);
-
- m_asyncEventQueue.enqueueEvent(event.release());
-}
-
-ScriptExecutionContext* MediaSourceBase::scriptExecutionContext() const
-{
- return ActiveDOMObject::scriptExecutionContext();
-}
-
-URLRegistry& MediaSourceBase::registry() const
-{
- return MediaSourceRegistry::registry();
-}
-
-}
-
-#endif
</del></span></pre></div>
<a id="trunkSourceWebCoreModulesmediasourceMediaSourceBaseh"></a>
<div class="delfile"><h4>Deleted: trunk/Source/WebCore/Modules/mediasource/MediaSourceBase.h (160257 => 160258)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/mediasource/MediaSourceBase.h        2013-12-06 23:20:09 UTC (rev 160257)
+++ trunk/Source/WebCore/Modules/mediasource/MediaSourceBase.h        2013-12-07 00:10:05 UTC (rev 160258)
</span><span class="lines">@@ -1,115 +0,0 @@
</span><del>-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef MediaSourceBase_h
-#define MediaSourceBase_h
-
-#if ENABLE(MEDIA_SOURCE)
-
-#include "ActiveDOMObject.h"
-#include "EventTarget.h"
-#include "GenericEventQueue.h"
-#include "HTMLMediaSource.h"
-#include "MediaSourcePrivate.h"
-#include "URLRegistry.h"
-#include <wtf/PassOwnPtr.h>
-#include <wtf/RefCounted.h>
-#include <wtf/Vector.h>
-
-namespace WebCore {
-
-class GenericEventQueue;
-
-class MediaSourceBase : public RefCounted<MediaSourceBase>, public HTMLMediaSource, public ActiveDOMObject, public EventTargetWithInlineData {
-public:
- static const AtomicString& openKeyword();
- static const AtomicString& closedKeyword();
- static const AtomicString& endedKeyword();
-
- virtual ~MediaSourceBase();
-
- void addedToRegistry();
- void removedFromRegistry();
- void openIfInEndedState();
- bool isOpen() const;
-
- // HTMLMediaSource
- virtual bool attachToElement(HTMLMediaElement*) OVERRIDE;
- virtual void setPrivateAndOpen(PassRef<MediaSourcePrivate>) OVERRIDE;
- virtual void close() OVERRIDE;
- virtual bool isClosed() const OVERRIDE;
- virtual double duration() const OVERRIDE;
- virtual PassRefPtr<TimeRanges> buffered() const OVERRIDE;
- virtual void refHTMLMediaSource() OVERRIDE { ref(); }
- virtual void derefHTMLMediaSource() OVERRIDE { deref(); }
-
- void setDuration(double, ExceptionCode&);
- const AtomicString& readyState() const { return m_readyState; }
- void setReadyState(const AtomicString&);
- void endOfStream(const AtomicString& error, ExceptionCode&);
-
- HTMLMediaElement* mediaElement() const { return m_mediaElement; }
-
- // ActiveDOMObject interface
- virtual bool hasPendingActivity() const OVERRIDE;
- virtual void stop() OVERRIDE;
-
- // EventTarget interface
- virtual ScriptExecutionContext* scriptExecutionContext() const OVERRIDE FINAL;
- virtual void refEventTarget() OVERRIDE FINAL { ref(); }
- virtual void derefEventTarget() OVERRIDE FINAL { deref(); }
-
- // URLRegistrable interface
- virtual URLRegistry& registry() const OVERRIDE;
-
- using RefCounted<MediaSourceBase>::ref;
- using RefCounted<MediaSourceBase>::deref;
-
-protected:
- explicit MediaSourceBase(ScriptExecutionContext&);
-
- virtual void onReadyStateChange(const AtomicString& oldState, const AtomicString& newState) = 0;
- virtual Vector<RefPtr<TimeRanges>> activeRanges() const = 0;
-
- RefPtr<SourceBufferPrivate> createSourceBufferPrivate(const ContentType&, ExceptionCode&);
- void scheduleEvent(const AtomicString& eventName);
- GenericEventQueue& asyncEventQueue() { return m_asyncEventQueue; }
-
- RefPtr<MediaSourcePrivate> m_private;
- HTMLMediaElement* m_mediaElement;
- AtomicString m_readyState;
- GenericEventQueue m_asyncEventQueue;
-};
-
-}
-
-#endif
-
-#endif
</del></span></pre></div>
<a id="trunkSourceWebCoreModulesmediasourceMediaSourceRegistrycpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/mediasource/MediaSourceRegistry.cpp (160257 => 160258)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/mediasource/MediaSourceRegistry.cpp        2013-12-06 23:20:09 UTC (rev 160257)
+++ trunk/Source/WebCore/Modules/mediasource/MediaSourceRegistry.cpp        2013-12-07 00:10:05 UTC (rev 160258)
</span><span class="lines">@@ -33,8 +33,8 @@
</span><span class="cx">
</span><span class="cx"> #if ENABLE(MEDIA_SOURCE)
</span><span class="cx">
</span><ins>+#include "MediaSource.h"
</ins><span class="cx"> #include "URL.h"
</span><del>-#include "MediaSourceBase.h"
</del><span class="cx"> #include <wtf/MainThread.h>
</span><span class="cx">
</span><span class="cx"> namespace WebCore {
</span><span class="lines">@@ -51,7 +51,7 @@
</span><span class="cx"> ASSERT(&registrable->registry() == this);
</span><span class="cx"> ASSERT(isMainThread());
</span><span class="cx">
</span><del>- MediaSourceBase* source = static_cast<MediaSourceBase*>(registrable);
</del><ins>+ MediaSource* source = static_cast<MediaSource*>(registrable);
</ins><span class="cx"> source->addedToRegistry();
</span><span class="cx"> m_mediaSources.set(url.string(), source);
</span><span class="cx"> }
</span><span class="lines">@@ -59,11 +59,11 @@
</span><span class="cx"> void MediaSourceRegistry::unregisterURL(const URL& url)
</span><span class="cx"> {
</span><span class="cx"> ASSERT(isMainThread());
</span><del>- HashMap<String, RefPtr<MediaSourceBase>>::iterator iter = m_mediaSources.find(url.string());
</del><ins>+ HashMap<String, RefPtr<MediaSource>>::iterator iter = m_mediaSources.find(url.string());
</ins><span class="cx"> if (iter == m_mediaSources.end())
</span><span class="cx"> return;
</span><span class="cx">
</span><del>- RefPtr<MediaSourceBase> source = iter->value;
</del><ins>+ RefPtr<MediaSource> source = iter->value;
</ins><span class="cx"> m_mediaSources.remove(iter);
</span><span class="cx"> source->removedFromRegistry();
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesmediasourceMediaSourceRegistryh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/mediasource/MediaSourceRegistry.h (160257 => 160258)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/mediasource/MediaSourceRegistry.h        2013-12-06 23:20:09 UTC (rev 160257)
+++ trunk/Source/WebCore/Modules/mediasource/MediaSourceRegistry.h        2013-12-07 00:10:05 UTC (rev 160258)
</span><span class="lines">@@ -41,7 +41,7 @@
</span><span class="cx"> namespace WebCore {
</span><span class="cx">
</span><span class="cx"> class URL;
</span><del>-class MediaSourceBase;
</del><ins>+class MediaSource;
</ins><span class="cx">
</span><span class="cx"> class MediaSourceRegistry FINAL : public URLRegistry {
</span><span class="cx"> public:
</span><span class="lines">@@ -55,7 +55,7 @@
</span><span class="cx">
</span><span class="cx"> private:
</span><span class="cx"> MediaSourceRegistry();
</span><del>- HashMap<String, RefPtr<MediaSourceBase>> m_mediaSources;
</del><ins>+ HashMap<String, RefPtr<MediaSource>> m_mediaSources;
</ins><span class="cx"> };
</span><span class="cx">
</span><span class="cx"> } // namespace WebCore
</span></span></pre></div>
<a id="trunkSourceWebCoreWebCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (160257 => 160258)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj        2013-12-06 23:20:09 UTC (rev 160257)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj        2013-12-07 00:10:05 UTC (rev 160258)
</span><span class="lines">@@ -5329,8 +5329,6 @@
</span><span class="cx">                 CD336F6717FA0AC600DDDCD0 /* VideoTrackPrivateAVFObjC.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CD336F6517FA0AC600DDDCD0 /* VideoTrackPrivateAVFObjC.cpp */; };
</span><span class="cx">                 CD336F6817FA0AC600DDDCD0 /* VideoTrackPrivateAVFObjC.h in Headers */ = {isa = PBXBuildFile; fileRef = CD336F6617FA0AC600DDDCD0 /* VideoTrackPrivateAVFObjC.h */; };
</span><span class="cx">                 CD37B39815C1B971006DC898 /* DiagnosticLoggingKeys.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CD37B37415C1A7E1006DC898 /* DiagnosticLoggingKeys.cpp */; };
</span><del>-                CD3A495217A9C8C600274E42 /* MediaSourceBase.h in Headers */ = {isa = PBXBuildFile; fileRef = CD3A495117A9C8B600274E42 /* MediaSourceBase.h */; };
-                CD3A495417A9CC9000274E42 /* MediaSourceBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CD3A495017A9C8B600274E42 /* MediaSourceBase.cpp */; };
</del><span class="cx">                 CD3A495E17A9D01B00274E42 /* MediaSource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CD3A495517A9D01B00274E42 /* MediaSource.cpp */; };
</span><span class="cx">                 CD3A495F17A9D01B00274E42 /* MediaSource.h in Headers */ = {isa = PBXBuildFile; fileRef = CD3A495617A9D01B00274E42 /* MediaSource.h */; };
</span><span class="cx">                 CD3A496117A9D01B00274E42 /* SourceBuffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CD3A495817A9D01B00274E42 /* SourceBuffer.cpp */; };
</span><span class="lines">@@ -7740,8 +7738,8 @@
</span><span class="cx">                 3146FE6518442087001A937C /* OESTextureFloatLinear.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = OESTextureFloatLinear.cpp; path = canvas/OESTextureFloatLinear.cpp; sourceTree = "<group>"; };
</span><span class="cx">                 3146FE6618442087001A937C /* OESTextureFloatLinear.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OESTextureFloatLinear.h; path = canvas/OESTextureFloatLinear.h; sourceTree = "<group>"; };
</span><span class="cx">                 3146FE6718442087001A937C /* OESTextureFloatLinear.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = OESTextureFloatLinear.idl; path = canvas/OESTextureFloatLinear.idl; sourceTree = "<group>"; };
</span><del>-                3146FE7018442367001A937C /* JSOESTextureFloatLinear.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JSOESTextureFloatLinear.cpp; path = JSOESTextureFloatLinear.cpp; sourceTree = "<group>"; };
-                3146FE7118442367001A937C /* JSOESTextureFloatLinear.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JSOESTextureFloatLinear.h; path = JSOESTextureFloatLinear.h; sourceTree = "<group>"; };
</del><ins>+                3146FE7018442367001A937C /* JSOESTextureFloatLinear.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSOESTextureFloatLinear.cpp; sourceTree = "<group>"; };
+                3146FE7118442367001A937C /* JSOESTextureFloatLinear.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSOESTextureFloatLinear.h; sourceTree = "<group>"; };
</ins><span class="cx">                 316023EF1532C40C00D50FF4 /* Dictionary.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Dictionary.h; sourceTree = "<group>"; };
</span><span class="cx">                 31611E540E1C4D4A00F6A579 /* WebKitCSSTransformValue.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = WebKitCSSTransformValue.idl; sourceTree = "<group>"; };
</span><span class="cx">                 31611E580E1C4DE000F6A579 /* JSWebKitCSSTransformValue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSWebKitCSSTransformValue.cpp; sourceTree = "<group>"; };
</span><span class="lines">@@ -12416,8 +12414,6 @@
</span><span class="cx">                 CD336F6617FA0AC600DDDCD0 /* VideoTrackPrivateAVFObjC.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = VideoTrackPrivateAVFObjC.h; path = objc/VideoTrackPrivateAVFObjC.h; sourceTree = "<group>"; };
</span><span class="cx">                 CD37B37415C1A7E1006DC898 /* DiagnosticLoggingKeys.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DiagnosticLoggingKeys.cpp; sourceTree = "<group>"; };
</span><span class="cx">                 CD37B37515C1A7E1006DC898 /* DiagnosticLoggingKeys.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DiagnosticLoggingKeys.h; sourceTree = "<group>"; };
</span><del>-                CD3A495017A9C8B600274E42 /* MediaSourceBase.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = MediaSourceBase.cpp; sourceTree = "<group>"; };
-                CD3A495117A9C8B600274E42 /* MediaSourceBase.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MediaSourceBase.h; sourceTree = "<group>"; };
</del><span class="cx">                 CD3A495517A9D01B00274E42 /* MediaSource.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MediaSource.cpp; sourceTree = "<group>"; };
</span><span class="cx">                 CD3A495617A9D01B00274E42 /* MediaSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MediaSource.h; sourceTree = "<group>"; };
</span><span class="cx">                 CD3A495717A9D01B00274E42 /* MediaSource.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = MediaSource.idl; sourceTree = "<group>"; };
</span><span class="lines">@@ -18568,8 +18564,6 @@
</span><span class="cx">                                 CD3A495517A9D01B00274E42 /* MediaSource.cpp */,
</span><span class="cx">                                 CD3A495617A9D01B00274E42 /* MediaSource.h */,
</span><span class="cx">                                 CD3A495717A9D01B00274E42 /* MediaSource.idl */,
</span><del>-                                CD3A495017A9C8B600274E42 /* MediaSourceBase.cpp */,
-                                CD3A495117A9C8B600274E42 /* MediaSourceBase.h */,
</del><span class="cx">                                 B1A942E115B5CE2200D525D1 /* MediaSourceRegistry.cpp */,
</span><span class="cx">                                 B1A942E215B5CE2200D525D1 /* MediaSourceRegistry.h */,
</span><span class="cx">                                 CD3A495817A9D01B00274E42 /* SourceBuffer.cpp */,
</span><span class="lines">@@ -23962,7 +23956,6 @@
</span><span class="cx">                                 BC2CBF4E140F1ABD003879BE /* JSWebGLContextEvent.h in Headers */,
</span><span class="cx">                                 6E3FAD3914733F4011E42307 /* JSWebGLDebugRendererInfo.h in Headers */,
</span><span class="cx">                                 6E3FAD3914733F4022E42307 /* JSWebGLDebugShaders.h in Headers */,
</span><del>-                                CD3A495217A9C8C600274E42 /* MediaSourceBase.h in Headers */,
</del><span class="cx">                                 6E3FAD3914733F4000E42307 /* JSWebGLDepthTexture.h in Headers */,
</span><span class="cx">                                 49C7B9981042D2D30009D447 /* JSWebGLFramebuffer.h in Headers */,
</span><span class="cx">                                 93F1D5C112D5335600832BEC /* JSWebGLLoseContext.h in Headers */,
</span><span class="lines">@@ -26367,7 +26360,6 @@
</span><span class="cx">                                 5160306C0CC4362300C8AC25 /* FileSystemCF.cpp in Sources */,
</span><span class="cx">                                 0779BF0D18453168000B6AE7 /* HTMLMediaElementMediaStream.cpp in Sources */,
</span><span class="cx">                                 26C17A3F1491D2D400D12BA2 /* FileSystemIOS.mm in Sources */,
</span><del>-                                CD3A495417A9CC9000274E42 /* MediaSourceBase.cpp in Sources */,
</del><span class="cx">                                 514B3F760C722055000530DF /* FileSystemMac.mm in Sources */,
</span><span class="cx">                                 6ED8C379183BFF8C009E53BD /* BoxShape.cpp in Sources */,
</span><span class="cx">                                 5160300B0CC4251200C8AC25 /* FileSystemPOSIX.cpp in Sources */,
</span></span></pre>
</div>
</div>
</body>
</html>