Diff
Modified: trunk/LayoutTests/ChangeLog (126945 => 126946)
--- trunk/LayoutTests/ChangeLog 2012-08-29 01:05:41 UTC (rev 126945)
+++ trunk/LayoutTests/ChangeLog 2012-08-29 01:07:56 UTC (rev 126946)
@@ -1,3 +1,20 @@
+2012-08-28 Aaron Colwell <[email protected]>
+
+ Make MediaSource event dispatch asynchronous.
+ https://bugs.webkit.org/show_bug.cgi?id=95217
+
+ Reviewed by Eric Carlson.
+
+ - Added a test to verify that MediaSource & SourceBufferList events are dispatched asynchronously.
+ - Updated a few existing tests that were relying on the old synchronous dispatch.
+
+ * http/tests/media/media-source/video-media-source-async-events-expected.txt: Added.
+ * http/tests/media/media-source/video-media-source-async-events.html: Added.
+ * http/tests/media/media-source/video-media-source-event-attributes.html:
+ * http/tests/media/media-source/video-media-source-objects.html:
+ * http/tests/media/media-source/video-media-source-seek-expected.txt:
+ * http/tests/media/media-source/video-media-source-state-changes-expected.txt:
+
2012-08-28 Julien Chaffraix <[email protected]>
Unreviewed penultimate rebaseline after r126683.
Added: trunk/LayoutTests/http/tests/media/media-source/video-media-source-async-events-expected.txt (0 => 126946)
--- trunk/LayoutTests/http/tests/media/media-source/video-media-source-async-events-expected.txt (rev 0)
+++ trunk/LayoutTests/http/tests/media/media-source/video-media-source-async-events-expected.txt 2012-08-29 01:07:56 UTC (rev 126946)
@@ -0,0 +1,11 @@
+Verify that all MediaSource & SourceBufferList events are dispatched asynchronously.
+
+onSourceOpen
+onAddSourceBuffer
+onAddSourceBuffer
+onSourceEnded
+onRemoveSourceBuffer
+onRemoveSourceBuffer
+onSourceClose
+END OF TEST
+
Added: trunk/LayoutTests/http/tests/media/media-source/video-media-source-async-events.html (0 => 126946)
--- trunk/LayoutTests/http/tests/media/media-source/video-media-source-async-events.html (rev 0)
+++ trunk/LayoutTests/http/tests/media/media-source/video-media-source-async-events.html 2012-08-29 01:07:56 UTC (rev 126946)
@@ -0,0 +1,87 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <script src=""
+ <script type="text/_javascript_">
+ var eventHandlerDepth = 0;
+
+ function enterHandler(label)
+ {
+ consoleWrite(label);
+
+ if (eventHandlerDepth > 0)
+ failTest("Unexpected eventHandlerDepth " + eventHandlerDepth);
+
+ eventHandlerDepth++;
+ }
+
+ function exitHandler()
+ {
+ if (eventHandlerDepth <= 0)
+ failTest("Unexpected eventHandlerDepth " + eventHandlerDepth);
+
+ eventHandlerDepth--;
+ }
+
+ function onSourceOpen(e)
+ {
+ enterHandler("onSourceOpen");
+
+ e.target.addSourceBuffer('video/webm;codecs="vp8"');
+
+ window.setTimeout(e.target.endOfStream.bind(e.target));
+
+ exitHandler();
+ }
+
+ function onAddSourceBuffer(e) {
+ enterHandler("onAddSourceBuffer");
+ exitHandler();
+ }
+
+ function onSourceEnded(e)
+ {
+ enterHandler("onSourceEnded");
+
+ document.querySelector('#v').src = ""
+
+ exitHandler();
+ }
+
+ function onRemoveSourceBuffer(e) {
+ enterHandler("onRemoveSourceBuffer");
+ exitHandler();
+ }
+
+
+ function onSourceClose(e)
+ {
+ enterHandler("onSourceClose");
+ window.setTimeout(endTest, 0);
+ exitHandler();
+ }
+
+ function main()
+ {
+ var video = document.querySelector('#v');
+ var mediaSource = new MediaSource();
+
+ mediaSource.addEventListener('webkitsourceopen', onSourceOpen);
+ mediaSource.addEventListener('webkitsourceended', onSourceEnded);
+ mediaSource.addEventListener('webkitsourceclose', onSourceClose);
+
+ mediaSource.sourceBuffers.addEventListener('webkitaddsourcebuffer', onAddSourceBuffer);
+ mediaSource.activeSourceBuffers.addEventListener('webkitaddsourcebuffer', onAddSourceBuffer);
+
+ mediaSource.sourceBuffers.addEventListener('webkitremovesourcebuffer', onRemoveSourceBuffer);
+ mediaSource.activeSourceBuffers.addEventListener('webkitremovesourcebuffer', onRemoveSourceBuffer);
+
+ video.src = ""
+ }
+ </script>
+ </head>
+ <body _onload_="main()">
+ <video id="v"></video>
+ <p>Verify that all MediaSource & SourceBufferList events are dispatched asynchronously.</p>
+ </body>
+</html>
Modified: trunk/LayoutTests/http/tests/media/media-source/video-media-source-event-attributes.html (126945 => 126946)
--- trunk/LayoutTests/http/tests/media/media-source/video-media-source-event-attributes.html 2012-08-29 01:05:41 UTC (rev 126945)
+++ trunk/LayoutTests/http/tests/media/media-source/video-media-source-event-attributes.html 2012-08-29 01:07:56 UTC (rev 126946)
@@ -19,7 +19,6 @@
consoleWrite("onSourceEnded()");
consoleWrite("Setting src attribute to \"\" to trigger a webkitsourceclosed event.");
video.src = ""
- endTest();
}
function onSourceClose()
Modified: trunk/LayoutTests/http/tests/media/media-source/video-media-source-objects.html (126945 => 126946)
--- trunk/LayoutTests/http/tests/media/media-source/video-media-source-objects.html 2012-08-29 01:05:41 UTC (rev 126945)
+++ trunk/LayoutTests/http/tests/media/media-source/video-media-source-objects.html 2012-08-29 01:07:56 UTC (rev 126946)
@@ -21,7 +21,10 @@
mediaSource.sourceBuffers.addEventListener('webkitaddsourcebuffer', onSourceBufferAdded);
run("segmentHelper.addSourceBuffer()");
+ }
+ function afterSourceBufferAdded()
+ {
consoleWrite("");
consoleWrite("Test SourceBuffer object type");
testExpected("segmentHelper.sourceBuffer instanceof window.SourceBuffer", true);
@@ -64,7 +67,10 @@
mediaSource.sourceBuffers.addEventListener('webkitremovesourcebuffer', onSourceBufferRemoved);
run("mediaSource.removeSourceBuffer(segmentHelper.sourceBuffer)");
+ }
+ function afterSourceBufferRemoved()
+ {
consoleWrite("Test that addSourceBuffer() throws and error when the MediaSource is not associated with a media element.");
var mediaSource2 = new MediaSource();
video.src = ""
@@ -83,7 +89,7 @@
endTest();
}
-
+
function onSourceBufferAdded(event)
{
testExpected("mediaSource.sourceBuffers.length", 1);
@@ -92,6 +98,8 @@
consoleWrite("Test SourceBufferList object type:");
testExpected("mediaSource.sourceBuffers", event.target);
testExpected("mediaSource.sourceBuffers instanceof window.SourceBufferList", true);
+
+ afterSourceBufferAdded();
}
function onSourceBufferRemoved(event)
@@ -114,6 +122,8 @@
consoleWrite("Got expected exception " + e);
}
testExpected("mediaSource.sourceBuffers.length", 0);
+
+ afterSourceBufferRemoved();
}
function onLoad()
Modified: trunk/LayoutTests/http/tests/media/media-source/video-media-source-seek-expected.txt (126945 => 126946)
--- trunk/LayoutTests/http/tests/media/media-source/video-media-source-seek-expected.txt 2012-08-29 01:05:41 UTC (rev 126945)
+++ trunk/LayoutTests/http/tests/media/media-source/video-media-source-seek-expected.txt 2012-08-29 01:07:56 UTC (rev 126946)
@@ -4,8 +4,8 @@
EVENT(webkitsourceended)
EVENT(playing)
EVENT(timeupdate) : seeking to 2.78
+EVENT(seeking)
EVENT(webkitsourceopen)
-EVENT(seeking)
EVENT(webkitsourceended)
EVENT(playing)
EVENT(ended)
Modified: trunk/LayoutTests/http/tests/media/media-source/video-media-source-state-changes-expected.txt (126945 => 126946)
--- trunk/LayoutTests/http/tests/media/media-source/video-media-source-state-changes-expected.txt 2012-08-29 01:05:41 UTC (rev 126945)
+++ trunk/LayoutTests/http/tests/media/media-source/video-media-source-state-changes-expected.txt 2012-08-29 01:07:56 UTC (rev 126946)
@@ -16,18 +16,18 @@
onSecondSeeking
EVENT(seeked)
onSecondSeeked
+EVENT(emptied)
EVENT(webkitsourceclose) : closed
onFirstSourceClose
-EVENT(emptied)
EVENT(webkitsourceopen) : open
onSecondSourceOpen
EVENT(webkitsourceended) : ended
onSecondSourceEnded
EVENT(playing)
triggerSecondSourceClose
+EVENT(emptied)
EVENT(webkitsourceclose) : closed
onSecondSourceClose
-EVENT(emptied)
EVENT(webkitsourceopen) : open
onThirdSourceOpen
END OF TEST
Modified: trunk/Source/WebCore/ChangeLog (126945 => 126946)
--- trunk/Source/WebCore/ChangeLog 2012-08-29 01:05:41 UTC (rev 126945)
+++ trunk/Source/WebCore/ChangeLog 2012-08-29 01:07:56 UTC (rev 126946)
@@ -1,3 +1,32 @@
+2012-08-28 Aaron Colwell <[email protected]>
+
+ Make MediaSource event dispatch asynchronous.
+ https://bugs.webkit.org/show_bug.cgi?id=95217
+
+ Reviewed by Eric Carlson.
+
+ Update MediaSource & SourceBufferList to use a GenericEventQueue to dispatch events
+ instead of using synchronous dispatch.
+
+ Test: http/tests/media/media-source/video-media-source-async-events.html
+
+ * Modules/mediasource/MediaSource.cpp:
+ (WebCore::MediaSource::MediaSource): Create GenericEventQueue & pass a pointer to SourceBufferList.
+ (WebCore::MediaSource::addSourceBuffer):
+ (WebCore::MediaSource::setReadyState): Updated to use new scheduleEvent() helper method.
+ (WebCore::MediaSource::scheduleEvent): New method for creating events and adding them to the event queue.
+ (WebCore):
+ * Modules/mediasource/MediaSource.h: Added GenericEventQueue member and scheduleEvent() signature.
+ (MediaSource):
+ * Modules/mediasource/SourceBufferList.cpp:
+ (WebCore::SourceBufferList::SourceBufferList):
+ (WebCore::SourceBufferList::remove):
+ (WebCore::SourceBufferList::createAndFireEvent): Updated to queue events instead of synchronously dispatch them.
+ * Modules/mediasource/SourceBufferList.h:
+ (WebCore):
+ (WebCore::SourceBufferList::create):
+ (SourceBufferList):
+
2012-08-28 Leandro Gracia Gil <[email protected]>
Content detection should not disrupt the page behaviour
Modified: trunk/Source/WebCore/Modules/mediasource/MediaSource.cpp (126945 => 126946)
--- trunk/Source/WebCore/Modules/mediasource/MediaSource.cpp 2012-08-29 01:05:41 UTC (rev 126945)
+++ trunk/Source/WebCore/Modules/mediasource/MediaSource.cpp 2012-08-29 01:07:56 UTC (rev 126946)
@@ -49,9 +49,10 @@
: ContextDestructionObserver(context)
, m_readyState(closedKeyword())
, m_player(0)
+ , m_asyncEventQueue(GenericEventQueue::create(this))
{
- m_sourceBuffers = SourceBufferList::create(scriptExecutionContext());
- m_activeSourceBuffers = SourceBufferList::create(scriptExecutionContext());
+ m_sourceBuffers = SourceBufferList::create(scriptExecutionContext(), m_asyncEventQueue.get());
+ m_activeSourceBuffers = SourceBufferList::create(scriptExecutionContext(), m_asyncEventQueue.get());
}
SourceBufferList* MediaSource::sourceBuffers()
@@ -84,7 +85,7 @@
ec = NOT_SUPPORTED_ERR;
return 0;
}
-
+
// 4. If the readyState attribute is not in the "open" state then throw an
// INVALID_STATE_ERR exception and abort these steps.
if (!m_player || m_readyState != openKeyword()) {
@@ -182,17 +183,17 @@
m_sourceBuffers->clear();
m_activeSourceBuffers->clear();
m_player = 0;
- dispatchEvent(Event::create(eventNames().webkitsourcecloseEvent, false, false));
+ scheduleEvent(eventNames().webkitsourcecloseEvent);
return;
}
-
+
if (oldState == openKeyword() && m_readyState == endedKeyword()) {
- dispatchEvent(Event::create(eventNames().webkitsourceendedEvent, false, false));
+ scheduleEvent(eventNames().webkitsourceendedEvent);
return;
}
if (m_readyState == openKeyword()) {
- dispatchEvent(Event::create(eventNames().webkitsourceopenEvent, false, false));
+ scheduleEvent(eventNames().webkitsourceopenEvent);
return;
}
}
@@ -301,6 +302,16 @@
return &m_eventTargetData;
}
+void MediaSource::scheduleEvent(const AtomicString& eventName)
+{
+ ASSERT(m_asyncEventQueue);
+
+ RefPtr<Event> event = Event::create(eventName, false, false);
+ event->setTarget(this);
+
+ m_asyncEventQueue->enqueueEvent(event.release());
+}
+
} // namespace WebCore
#endif
Modified: trunk/Source/WebCore/Modules/mediasource/MediaSource.h (126945 => 126946)
--- trunk/Source/WebCore/Modules/mediasource/MediaSource.h 2012-08-29 01:05:41 UTC (rev 126945)
+++ trunk/Source/WebCore/Modules/mediasource/MediaSource.h 2012-08-29 01:07:56 UTC (rev 126946)
@@ -34,6 +34,7 @@
#if ENABLE(MEDIA_SOURCE)
#include "ContextDestructionObserver.h"
+#include "GenericEventQueue.h"
#include "MediaPlayer.h"
#include "SourceBuffer.h"
#include "SourceBufferList.h"
@@ -76,7 +77,7 @@
void endOfStream(const String& error, ExceptionCode&);
void setMediaPlayer(MediaPlayer* player) { m_player = player; }
-
+
PassRefPtr<TimeRanges> buffered(const String& id, ExceptionCode&) const;
void append(const String& id, PassRefPtr<Uint8Array> data, ExceptionCode&);
void abort(const String& id, ExceptionCode&);
@@ -98,6 +99,8 @@
virtual void refEventTarget() OVERRIDE { ref(); }
virtual void derefEventTarget() OVERRIDE { deref(); }
+ void scheduleEvent(const AtomicString& eventName);
+
EventTargetData m_eventTargetData;
String m_readyState;
@@ -105,6 +108,7 @@
RefPtr<SourceBufferList> m_sourceBuffers;
RefPtr<SourceBufferList> m_activeSourceBuffers;
+ OwnPtr<GenericEventQueue> m_asyncEventQueue;
};
} // namespace WebCore
Modified: trunk/Source/WebCore/Modules/mediasource/SourceBufferList.cpp (126945 => 126946)
--- trunk/Source/WebCore/Modules/mediasource/SourceBufferList.cpp 2012-08-29 01:05:41 UTC (rev 126945)
+++ trunk/Source/WebCore/Modules/mediasource/SourceBufferList.cpp 2012-08-29 01:07:56 UTC (rev 126946)
@@ -38,8 +38,10 @@
namespace WebCore {
-SourceBufferList::SourceBufferList(ScriptExecutionContext* context)
+SourceBufferList::SourceBufferList(ScriptExecutionContext* context,
+ GenericEventQueue* asyncEventQueue)
: m_scriptExecutionContext(context)
+ , m_asyncEventQueue(asyncEventQueue)
, m_lastSourceBufferId(0)
{
}
@@ -63,7 +65,7 @@
}
bool SourceBufferList::remove(SourceBuffer* buffer)
-{
+{
size_t index = m_list.find(buffer);
if (index == notFound)
return false;
@@ -110,10 +112,12 @@
void SourceBufferList::createAndFireEvent(const AtomicString& eventName)
{
+ ASSERT(m_asyncEventQueue);
+
RefPtr<Event> event = Event::create(eventName, false, false);
event->setTarget(this);
- EventTarget::dispatchEvent(event);
+ m_asyncEventQueue->enqueueEvent(event.release());
}
const AtomicString& SourceBufferList::interfaceName() const
Modified: trunk/Source/WebCore/Modules/mediasource/SourceBufferList.h (126945 => 126946)
--- trunk/Source/WebCore/Modules/mediasource/SourceBufferList.h 2012-08-29 01:05:41 UTC (rev 126945)
+++ trunk/Source/WebCore/Modules/mediasource/SourceBufferList.h 2012-08-29 01:07:56 UTC (rev 126946)
@@ -40,12 +40,13 @@
namespace WebCore {
class SourceBuffer;
+class GenericEventQueue;
class SourceBufferList : public RefCounted<SourceBufferList>, public EventTarget {
public:
- static PassRefPtr<SourceBufferList> create(ScriptExecutionContext* context)
+ static PassRefPtr<SourceBufferList> create(ScriptExecutionContext* context, GenericEventQueue* asyncEventQueue)
{
- return adoptRef(new SourceBufferList(context));
+ return adoptRef(new SourceBufferList(context, asyncEventQueue));
}
virtual ~SourceBufferList() { }
@@ -72,7 +73,7 @@
virtual EventTargetData* ensureEventTargetData() OVERRIDE;
private:
- explicit SourceBufferList(ScriptExecutionContext*);
+ SourceBufferList(ScriptExecutionContext*, GenericEventQueue*);
bool contains(size_t id) const;
void createAndFireEvent(const AtomicString&);
@@ -82,6 +83,7 @@
EventTargetData m_eventTargetData;
ScriptExecutionContext* m_scriptExecutionContext;
+ GenericEventQueue* m_asyncEventQueue;
Vector<RefPtr<SourceBuffer> > m_list;
size_t m_lastSourceBufferId;