Title: [158928] trunk
Revision
158928
Author
[email protected]
Date
2013-11-08 10:30:29 -0800 (Fri, 08 Nov 2013)

Log Message

[MSE] Bring SourceBuffer.append up to the most recent spec.
https://bugs.webkit.org/show_bug.cgi?id=123377

Reviewed by Eric Carlson.

Source/WebCore:

Test: media/media-source/media-source-append-failed.html

Bring the MediaSource append() implementation up to the current spec.

* Modules/mediasource/SourceBuffer.cpp:
(WebCore::SourceBuffer::appendBufferInternal):
(WebCore::SourceBuffer::appendBufferTimerFired):
* platform/graphics/SourceBufferPrivate.h:
* platform/mock/mediasource/MockSourceBufferPrivate.cpp:
(WebCore::MockSourceBufferPrivate::append):
(WebCore::MockSourceBufferPrivate::evictCodedFrames):
(WebCore::MockSourceBufferPrivate::isFull):
* platform/mock/mediasource/MockSourceBufferPrivate.h:

LayoutTests:

* media/media-source/media-source-append-failed-expected.txt: Added.
* media/media-source/media-source-append-failed.html: Added.
* media/media-source/mock-media-source.js:

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (158927 => 158928)


--- trunk/LayoutTests/ChangeLog	2013-11-08 18:28:06 UTC (rev 158927)
+++ trunk/LayoutTests/ChangeLog	2013-11-08 18:30:29 UTC (rev 158928)
@@ -1,3 +1,14 @@
+2013-10-30  Jer Noble  <[email protected]>
+
+        [MSE] Bring SourceBuffer.append up to the most recent spec.
+        https://bugs.webkit.org/show_bug.cgi?id=123377
+
+        Reviewed by Eric Carlson.
+
+        * media/media-source/media-source-append-failed-expected.txt: Added.
+        * media/media-source/media-source-append-failed.html: Added.
+        * media/media-source/mock-media-source.js:
+
 2013-11-08  Michał Pakuła vel Rutka  <[email protected]>
 
         Unreviewed EFL gardening

Added: trunk/LayoutTests/media/media-source/media-source-append-failed-expected.txt (0 => 158928)


--- trunk/LayoutTests/media/media-source/media-source-append-failed-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/media/media-source/media-source-append-failed-expected.txt	2013-11-08 18:30:29 UTC (rev 158928)
@@ -0,0 +1,9 @@
+
+RUN(video.src = ""
+EVENT(sourceopen)
+RUN(sourceBuffer = source.addSourceBuffer("video/mock; codecs=mock"))
+RUN(sourceBuffer.appendBuffer(initSegment))
+EVENT(updatestart)
+EVENT(sourceended)
+END OF TEST
+

Added: trunk/LayoutTests/media/media-source/media-source-append-failed.html (0 => 158928)


--- trunk/LayoutTests/media/media-source/media-source-append-failed.html	                        (rev 0)
+++ trunk/LayoutTests/media/media-source/media-source-append-failed.html	2013-11-08 18:30:29 UTC (rev 158928)
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <title>mock-media-source</title>
+    <script src=""
+    <script src=""
+    <script>
+    var source;
+    var sourceBuffer;
+    var initSegment;
+
+    if (window.internals)
+        internals.initializeMockMediaSource();
+
+    function runTest() {
+        findMediaElement();
+
+        source = new MediaSource();
+        waitForEventOn(source, 'sourceopen', sourceOpen);
+        run('video.src = ""
+    }
+
+    function sourceOpen() {
+        run('sourceBuffer = source.addSourceBuffer("video/mock; codecs=mock")');
+
+        waitForEventOn(sourceBuffer, 'updatestart');
+        waitForEventOn(sourceBuffer, 'update');
+        waitForEventOn(sourceBuffer, 'updateend');
+        waitForEventOn(source, 'sourceended', endTest);
+        initSegment = makeAnInvalidBox();
+        run('sourceBuffer.appendBuffer(initSegment)');
+    }
+    
+    </script>
+</head>
+<body _onload_="runTest()">
+    <video></video>
+</body>
+</html>

Modified: trunk/LayoutTests/media/media-source/mock-media-source.js (158927 => 158928)


--- trunk/LayoutTests/media/media-source/mock-media-source.js	2013-11-08 18:28:06 UTC (rev 158927)
+++ trunk/LayoutTests/media/media-source/mock-media-source.js	2013-11-08 18:30:29 UTC (rev 158928)
@@ -69,4 +69,15 @@
     return buffer;
 }
 
+function makeAnInvalidBox() {
+    var byteLength = 12;
+    var buffer = new ArrayBuffer(byteLength);
+    var array = new Uint8Array(buffer);
+    array.set(stringToArray('invl'));
 
+    var view = new DataView(buffer);
+    view.setUint32(8, 0xFFFF, true);
+
+    return buffer;
+}
+

Modified: trunk/Source/WebCore/ChangeLog (158927 => 158928)


--- trunk/Source/WebCore/ChangeLog	2013-11-08 18:28:06 UTC (rev 158927)
+++ trunk/Source/WebCore/ChangeLog	2013-11-08 18:30:29 UTC (rev 158928)
@@ -1,3 +1,24 @@
+2013-10-30  Jer Noble  <[email protected]>
+
+        [MSE] Bring SourceBuffer.append up to the most recent spec.
+        https://bugs.webkit.org/show_bug.cgi?id=123377
+
+        Reviewed by Eric Carlson.
+
+        Test: media/media-source/media-source-append-failed.html
+
+        Bring the MediaSource append() implementation up to the current spec.
+
+        * Modules/mediasource/SourceBuffer.cpp:
+        (WebCore::SourceBuffer::appendBufferInternal):
+        (WebCore::SourceBuffer::appendBufferTimerFired):
+        * platform/graphics/SourceBufferPrivate.h:
+        * platform/mock/mediasource/MockSourceBufferPrivate.cpp:
+        (WebCore::MockSourceBufferPrivate::append):
+        (WebCore::MockSourceBufferPrivate::evictCodedFrames):
+        (WebCore::MockSourceBufferPrivate::isFull):
+        * platform/mock/mediasource/MockSourceBufferPrivate.h:
+
 2013-11-07  Jer Noble  <[email protected]>
 
         [Mac] Crash at com.apple.WebCore: WebCore::MediaPlayerPrivateAVFoundationObjC::tracksDidChange + 26

Modified: trunk/Source/WebCore/Modules/mediasource/SourceBuffer.cpp (158927 => 158928)


--- trunk/Source/WebCore/Modules/mediasource/SourceBuffer.cpp	2013-11-08 18:28:06 UTC (rev 158927)
+++ trunk/Source/WebCore/Modules/mediasource/SourceBuffer.cpp	2013-11-08 18:30:29 UTC (rev 158928)
@@ -35,6 +35,7 @@
 
 #include "AudioTrackList.h"
 #include "Event.h"
+#include "ExceptionCodePlaceholder.h"
 #include "GenericEventQueue.h"
 #include "HTMLMediaElement.h"
 #include "InbandTextTrack.h"
@@ -272,28 +273,42 @@
     // https://dvcs.w3.org/hg/html-media/raw-file/default/media-source/media-source.html#widl-SourceBuffer-appendBuffer-void-ArrayBufferView-data
 
     // Step 1 is enforced by the caller.
-    // 2. If this object has been removed from the sourceBuffers attribute of the parent media source then throw an INVALID_STATE_ERR exception and abort these steps.
-    // 3. If the updating attribute equals true, then throw an INVALID_STATE_ERR exception and abort these steps.
+    // 2. Run the prepare append algorithm.
+    // Section 3.5.4 Prepare AppendAlgorithm
+
+    // 1. If the SourceBuffer has been removed from the sourceBuffers attribute of the parent media source
+    // then throw an INVALID_STATE_ERR exception and abort these steps.
+    // 2. If the updating attribute equals true, then throw an INVALID_STATE_ERR exception and abort these steps.
     if (isRemoved() || m_updating) {
         ec = INVALID_STATE_ERR;
         return;
     }
 
-    // 4. If the readyState attribute of the parent media source is in the "ended" state then run the following steps: ...
+    // 3. If the readyState attribute of the parent media source is in the "ended" state then run the following steps:
+    // 3.1. Set the readyState attribute of the parent media source to "open"
+    // 3.2. Queue a task to fire a simple event named sourceopen at the parent media source .
     m_source->openIfInEndedState();
 
-    // Steps 5-6
+    // 4. Run the coded frame eviction algorithm.
+    m_private->evictCodedFrames();
 
-    // 7. Add data to the end of the input buffer.
+    // 5. If the buffer full flag equals true, then throw a QUOTA_EXCEEDED_ERR exception and abort these step.
+    if (m_private->isFull()) {
+        ec = QUOTA_EXCEEDED_ERR;
+        return;
+    }
+
+    // NOTE: Return to 3.2 appendBuffer()
+    // 3. Add data to the end of the input buffer.
     m_pendingAppendData.append(data, size);
 
-    // 8. Set the updating attribute to true.
+    // 4. Set the updating attribute to true.
     m_updating = true;
 
-    // 9. Queue a task to fire a simple event named updatestart at this SourceBuffer object.
+    // 5. Queue a task to fire a simple event named updatestart at this SourceBuffer object.
     scheduleEvent(eventNames().updatestartEvent);
 
-    // 10. Asynchronously run the buffer append algorithm.
+    // 6. Asynchronously run the buffer append algorithm.
     m_appendBufferTimer.startOneShot(0);
 }
 
@@ -301,11 +316,10 @@
 {
     ASSERT(m_updating);
 
-    // Section 3.5.4 Buffer Append Algorithm
+    // Section 3.5.5 Buffer Append Algorithm
     // https://dvcs.w3.org/hg/html-media/raw-file/default/media-source/media-source.html#sourcebuffer-buffer-append
 
     // 1. Run the segment parser loop algorithm.
-    // Step 2 doesn't apply since we run Step 1 synchronously here.
     size_t appendSize = m_pendingAppendData.size();
     if (!appendSize) {
         // Resize buffer for 0 byte appends so we always have a valid pointer.
@@ -313,11 +327,40 @@
         // that it can clear its end of stream state if necessary.
         m_pendingAppendData.resize(1);
     }
-    m_private->append(m_pendingAppendData.data(), appendSize);
 
+    // Section 3.5.1 Segment Parser Loop
+    // https://dvcs.w3.org/hg/html-media/raw-file/tip/media-source/media-source.html#sourcebuffer-segment-parser-loop
+    // When the segment parser loop algorithm is invoked, run the following steps:
+
+    SourceBufferPrivate::AppendResult result = SourceBufferPrivate::AppendSucceeded;
+    do {
+        // 1. Loop Top: If the input buffer is empty, then jump to the need more data step below.
+        if (!m_pendingAppendData.size())
+            break;
+
+        result = m_private->append(m_pendingAppendData.data(), appendSize);
+        m_pendingAppendData.clear();
+
+        // 2. If the input buffer contains bytes that violate the SourceBuffer byte stream format specification,
+        // then run the end of stream algorithm with the error parameter set to "decode" and abort this algorithm.
+        if (result == SourceBufferPrivate::ParsingFailed) {
+            m_source->endOfStream(decodeError(), IgnorableExceptionCode());
+            break;
+        }
+
+        // NOTE: Steps 3 - 6 enforced by sourceBufferPrivateDidReceiveInitializationSegment() and
+        // sourceBufferPrivateDidReceiveSample below.
+
+        // 7. Need more data: Return control to the calling algorithm.
+    } while (0);
+
+    // NOTE: return to Section 3.5.5
+    // 2.If the segment parser loop algorithm in the previous step was aborted, then abort this algorithm.
+    if (result != SourceBufferPrivate::AppendSucceeded)
+        return;
+
     // 3. Set the updating attribute to false.
     m_updating = false;
-    m_pendingAppendData.clear();
 
     // 4. Queue a task to fire a simple event named update at this SourceBuffer object.
     scheduleEvent(eventNames().updateEvent);
@@ -389,8 +432,6 @@
 
 void SourceBuffer::sourceBufferPrivateDidReceiveInitializationSegment(SourceBufferPrivate*, const InitializationSegment& segment)
 {
-    m_appendState = ParsingInitSegment;
-
     // 3.5.7 Initialization Segment Received
     // https://dvcs.w3.org/hg/html-media/raw-file/default/media-source/media-source.html#sourcebuffer-init-segment-received
     // 1. Update the duration attribute if it currently equals NaN:

Modified: trunk/Source/WebCore/platform/graphics/SourceBufferPrivate.h (158927 => 158928)


--- trunk/Source/WebCore/platform/graphics/SourceBufferPrivate.h	2013-11-08 18:28:06 UTC (rev 158927)
+++ trunk/Source/WebCore/platform/graphics/SourceBufferPrivate.h	2013-11-08 18:30:29 UTC (rev 158928)
@@ -46,12 +46,20 @@
     virtual ~SourceBufferPrivate() { }
 
     virtual void setClient(SourceBufferPrivateClient*) = 0;
-    virtual void append(const unsigned char* data, unsigned length) = 0;
+
+    enum AppendResult {
+        AppendSucceeded,
+        ReadStreamFailed,
+        ParsingFailed,
+    };
+    virtual AppendResult append(const unsigned char* data, unsigned length) = 0;
     virtual void abort() = 0;
     virtual void removedFromMediaSource() = 0;
 
     virtual MediaPlayer::ReadyState readyState() const = 0;
     virtual void setReadyState(MediaPlayer::ReadyState) = 0;
+    virtual void evictCodedFrames() = 0;
+    virtual bool isFull() = 0;
 };
 
 }

Modified: trunk/Source/WebCore/platform/mock/mediasource/MockSourceBufferPrivate.cpp (158927 => 158928)


--- trunk/Source/WebCore/platform/mock/mediasource/MockSourceBufferPrivate.cpp	2013-11-08 18:28:06 UTC (rev 158927)
+++ trunk/Source/WebCore/platform/mock/mediasource/MockSourceBufferPrivate.cpp	2013-11-08 18:30:29 UTC (rev 158928)
@@ -106,11 +106,12 @@
     m_client = client;
 }
 
-void MockSourceBufferPrivate::append(const unsigned char* data, unsigned length)
+SourceBufferPrivate::AppendResult MockSourceBufferPrivate::append(const unsigned char* data, unsigned length)
 {
     m_inputBuffer.append(data, length);
+    AppendResult result = AppendSucceeded;
 
-    while (m_inputBuffer.size()) {
+    while (m_inputBuffer.size() && result == AppendSucceeded) {
         RefPtr<ArrayBuffer> buffer = ArrayBuffer::create(m_inputBuffer.data(), m_inputBuffer.size());
         size_t boxLength = MockBox::peekLength(buffer.get());
         if (boxLength > buffer->byteLength())
@@ -120,15 +121,16 @@
         if (type == MockInitializationBox::type()) {
             MockInitializationBox initBox = MockInitializationBox(buffer.get());
             didReceiveInitializationSegment(initBox);
-        }
-
-        if (type == MockSampleBox::type()) {
+        } else if (type == MockSampleBox::type()) {
             MockSampleBox sampleBox = MockSampleBox(buffer.get());
             didReceiveSample(sampleBox);
-        }
+        } else
+            result = ParsingFailed;
 
         m_inputBuffer.remove(0, boxLength);
     }
+
+    return result;
 }
 
 void MockSourceBufferPrivate::didReceiveInitializationSegment(const MockInitializationBox& initBox)
@@ -190,6 +192,16 @@
     m_parent->player()->setReadyState(readyState);
 }
 
+void MockSourceBufferPrivate::evictCodedFrames()
+{
+    // No-op.
+}
+
+bool MockSourceBufferPrivate::isFull()
+{
+    return false;
+}
+
 bool MockSourceBufferPrivate::hasVideo() const
 {
     if (!m_client)

Modified: trunk/Source/WebCore/platform/mock/mediasource/MockSourceBufferPrivate.h (158927 => 158928)


--- trunk/Source/WebCore/platform/mock/mediasource/MockSourceBufferPrivate.h	2013-11-08 18:28:06 UTC (rev 158927)
+++ trunk/Source/WebCore/platform/mock/mediasource/MockSourceBufferPrivate.h	2013-11-08 18:30:29 UTC (rev 158928)
@@ -58,11 +58,13 @@
 
     // SourceBufferPrivate overrides
     virtual void setClient(SourceBufferPrivateClient*) OVERRIDE;
-    virtual void append(const unsigned char* data, unsigned length) OVERRIDE;
+    virtual AppendResult append(const unsigned char* data, unsigned length) OVERRIDE;
     virtual void abort() OVERRIDE;
     virtual void removedFromMediaSource() OVERRIDE;
     virtual MediaPlayer::ReadyState readyState() const OVERRIDE;
     virtual void setReadyState(MediaPlayer::ReadyState) OVERRIDE;
+    virtual void evictCodedFrames() OVERRIDE;
+    virtual bool isFull() OVERRIDE;
 
     void didReceiveInitializationSegment(const MockInitializationBox&);
     void didReceiveSample(const MockSampleBox&);
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to