[MSE] Add mock MediaSource classes for testing.
authorjer.noble@apple.com <jer.noble@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 7 Nov 2013 17:58:57 +0000 (17:58 +0000)
committerjer.noble@apple.com <jer.noble@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 7 Nov 2013 17:58:57 +0000 (17:58 +0000)
https://bugs.webkit.org/show_bug.cgi?id=123322

Reviewed by Eric Carlson.

Source/WebCore:

Tests: media/media-source/media-source-addsourcebuffer.html
       media/media-source/media-source-append-buffer.html
       media/media-source/media-source-canplaythrough.html
       media/media-source/media-source-closed.html
       media/media-source/media-source-play.html
       media/media-source/media-source-track-enabled.html
       media/media-source/media-source-tracks.html

Add mock implementation of platform MediaSource classes, allowing ports to test the
MediaSource API without having a platform implementation.

The MockMediaSource will support a byteformat defined in MockBox.h: a simple box-style media
format with an initialization segment containing a number of tracks, followed by a list of
samples.

Add a means to insert a new media engine factory at runtime, so the internals object can add
a MockMediaSourceMediaPlayer:
* platform/graphics/MediaPlayer.cpp:
(WebCore::MediaPlayerFactorySupport::callRegisterMediaEngine):
* platform/graphics/MediaPlayer.h:
* testing/Internals.cpp:
(WebCore::Internals::initializeMockMediaSource):
* testing/Internals.h:
* testing/Internals.idl:

For non-media-source supporting media engines, fail immediately when asked to load a media
source, so that the MockMediaSourceMediaPlayer will be instantiated as a fall-back:
* platform/graphics/avfoundation/MediaPlayerPrivateAVFoundation.cpp:
(WebCore::MediaPlayerPrivateAVFoundation::load):
* platform/graphics/avfoundation/MediaPlayerPrivateAVFoundation.h:
* platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm:
(WebCore::MediaPlayerPrivateAVFoundationObjC::supportsType):
* platform/graphics/mac/MediaPlayerPrivateQTKit.h:
* platform/graphics/mac/MediaPlayerPrivateQTKit.mm:
(WebCore::MediaPlayerPrivateQTKit::load):
(WebCore::MediaPlayerPrivateQTKit::supportsType):

Add new files to the project:
* WebCore.xcodeproj/project.pbxproj:
* Source/WebCore/WebCore.exp.in:

Update the MediaSource implementation:
* Modules/mediasource/MediaSource.cpp:
(WebCore::MediaSource::monitorSourceBuffers): Add a link to the spec.
* Modules/mediasource/SourceBuffer.cpp:
(WebCore::SourceBuffer::buffered): Ditto.
(WebCore::SourceBuffer::setTimestampOffset): Ditto.
(WebCore::SourceBuffer::validateInitializationSegment): Ditto.
(WebCore::SourceBuffer::sourceBufferPrivateDidReceiveInitializationSegment): Ditto. Also,
    bring the implementation up to date with part of the spec.
(WebCore::SourceBuffer::sourceBufferPrivateDidReceiveSample): Remove "Predicate" from
    SampleIsRandomAccessPredicate.

Add utility classes to parse and represent the bytestream supported by the MockMediaSource:
* platform/mock/mediasource/MockBox.cpp: Added.
(WebCore::MockBox::MockBox):
(WebCore::MockBox::peekType):
(WebCore::MockBox::peekLength):
(WebCore::MockTrackBox::MockTrackBox):
(WebCore::MockTrackBox::type):
(WebCore::MockInitializationBox::MockInitializationBox):
(WebCore::MockInitializationBox::type):
(WebCore::MockSampleBox::MockSampleBox):
(WebCore::MockSampleBox::type):
* platform/mock/mediasource/MockBox.h: Added.
(WebCore::MockBox::length):
(WebCore::MockBox::type):
(WebCore::MockTrackBox::trackID):
(WebCore::MockTrackBox::codec):
(WebCore::MockTrackBox::kind):
(WebCore::MockInitializationBox::duration):
(WebCore::MockInitializationBox::tracks):
(WebCore::MockSampleBox::presentationTimestamp):
(WebCore::MockSampleBox::decodeTimestamp):
(WebCore::MockSampleBox::duration):
(WebCore::MockSampleBox::trackID):
(WebCore::MockSampleBox::flags):
(WebCore::MockSampleBox::isSync):

Add a MediaPlayerPrivate implementation which uses MockMediaSource:
* platform/mock/mediasource/MockMediaPlayerMediaSource.cpp: Added.
(WebCore::MockMediaPlayerMediaSource::registerMediaEngine):
(WebCore::MockMediaPlayerMediaSource::create):
(WebCore::mimeTypeCache):
(WebCore::MockMediaPlayerMediaSource::getSupportedTypes):
(WebCore::MockMediaPlayerMediaSource::supportsType):
(WebCore::MockMediaPlayerMediaSource::MockMediaPlayerMediaSource):
(WebCore::MockMediaPlayerMediaSource::~MockMediaPlayerMediaSource):
(WebCore::MockMediaPlayerMediaSource::load):
(WebCore::MockMediaPlayerMediaSource::cancelLoad):
(WebCore::MockMediaPlayerMediaSource::play):
(WebCore::MockMediaPlayerMediaSource::pause):
(WebCore::MockMediaPlayerMediaSource::naturalSize):
(WebCore::MockMediaPlayerMediaSource::hasVideo):
(WebCore::MockMediaPlayerMediaSource::hasAudio):
(WebCore::MockMediaPlayerMediaSource::setVisible):
(WebCore::MockMediaPlayerMediaSource::seeking):
(WebCore::MockMediaPlayerMediaSource::paused):
(WebCore::MockMediaPlayerMediaSource::networkState):
(WebCore::MockMediaPlayerMediaSource::readyState):
(WebCore::MockMediaPlayerMediaSource::buffered):
(WebCore::MockMediaPlayerMediaSource::didLoadingProgress):
(WebCore::MockMediaPlayerMediaSource::setSize):
(WebCore::MockMediaPlayerMediaSource::paint):
(WebCore::MockMediaPlayerMediaSource::currentTimeDouble):
(WebCore::MockMediaPlayerMediaSource::durationDouble):
(WebCore::MockMediaPlayerMediaSource::seekDouble):
(WebCore::MockMediaPlayerMediaSource::advanceCurrentTime):
(WebCore::MockMediaPlayerMediaSource::updateDuration):
(WebCore::MockMediaPlayerMediaSource::setReadyState):
* platform/mock/mediasource/MockMediaPlayerMediaSource.h: Added.

Add a mock implementation of MediaSourcePrivate, which uses MockSourceBuffer:
* platform/mock/mediasource/MockMediaSourcePrivate.cpp: Added.
(WebCore::MockMediaSourcePrivate::create):
(WebCore::MockMediaSourcePrivate::MockMediaSourcePrivate):
(WebCore::MockMediaSourcePrivate::~MockMediaSourcePrivate):
(WebCore::MockMediaSourcePrivate::addSourceBuffer):
(WebCore::MockMediaSourcePrivate::removeSourceBuffer):
(WebCore::MockMediaSourcePrivate::duration):
(WebCore::MockMediaSourcePrivate::setDuration):
(WebCore::MockMediaSourcePrivate::markEndOfStream):
(WebCore::MockMediaSourcePrivate::unmarkEndOfStream):
(WebCore::MockMediaSourcePrivate::readyState):
(WebCore::MockMediaSourcePrivate::setReadyState):
(WebCore::MockMediaSourcePrivate::sourceBufferPrivateDidChangeActiveState):
(WebCore::MockSourceBufferPrivateHasAudio):
(WebCore::MockMediaSourcePrivate::hasAudio):
(WebCore::MockSourceBufferPrivateHasVideo):
(WebCore::MockMediaSourcePrivate::hasVideo):
* platform/mock/mediasource/MockMediaSourcePrivate.h: Added.
(WebCore::MockMediaSourcePrivate::activeSourceBuffers):
(WebCore::MockMediaSourcePrivate::player):

Add a mock implementation of SourceBufferPrivate, which uses MockBoxes to parse the
bytestream provided by SourceBuffer:
* platform/mock/mediasource/MockSourceBufferPrivate.cpp: Added.
(WebCore::MockMediaSample::create):
(WebCore::MockMediaSample::~MockMediaSample):
(WebCore::MockMediaSample::MockMediaSample):
(WebCore::MockMediaSample::platformSample):
(WebCore::MockMediaDescription::create):
(WebCore::MockMediaDescription::~MockMediaDescription):
(WebCore::MockMediaDescription::MockMediaDescription):
(WebCore::MockSourceBufferPrivate::create):
(WebCore::MockSourceBufferPrivate::MockSourceBufferPrivate):
(WebCore::MockSourceBufferPrivate::~MockSourceBufferPrivate):
(WebCore::MockSourceBufferPrivate::setClient):
(WebCore::MockSourceBufferPrivate::append):
(WebCore::MockSourceBufferPrivate::didReceiveInitializationSegment):
(WebCore::MockSourceBufferPrivate::didReceiveSample):
(WebCore::MockSourceBufferPrivate::abort):
(WebCore::MockSourceBufferPrivate::removedFromMediaSource):
(WebCore::MockSourceBufferPrivate::readyState):
(WebCore::MockSourceBufferPrivate::setReadyState):
(WebCore::MockSourceBufferPrivate::hasVideo):
(WebCore::MockSourceBufferPrivate::hasAudio):
* platform/mock/mediasource/MockSourceBufferPrivate.h: Added.

Create mock implementations of AudioTrackPrivate, VideoTrackPrivate, and TextTrackPrivate
which wrap the MockTrackBox class:
* platform/mock/mediasource/MockTracks.cpp: Added.
* platform/mock/mediasource/MockTracks.h: Added.
(WebCore::MockAudioTrackPrivate::create):
(WebCore::MockAudioTrackPrivate::~MockAudioTrackPrivate):
(WebCore::MockAudioTrackPrivate::id):
(WebCore::MockAudioTrackPrivate::MockAudioTrackPrivate):
(WebCore::MockTextTrackPrivate::create):
(WebCore::MockTextTrackPrivate::~MockTextTrackPrivate):
(WebCore::MockTextTrackPrivate::id):
(WebCore::MockTextTrackPrivate::MockTextTrackPrivate):
(WebCore::MockVideoTrackPrivate::create):
(WebCore::MockVideoTrackPrivate::~MockVideoTrackPrivate):
(WebCore::MockVideoTrackPrivate::id):
(WebCore::MockVideoTrackPrivate::MockVideoTrackPrivate):

LayoutTests:

* media/media-source/media-source-addsourcebuffer-expected.txt: Added.
* media/media-source/media-source-addsourcebuffer.html: Added.
* media/media-source/media-source-append-buffer-expected.txt: Added.
* media/media-source/media-source-append-buffer.html: Added.
* media/media-source/media-source-canplaythrough-expected.txt: Added.
* media/media-source/media-source-canplaythrough.html: Added.
* media/media-source/media-source-closed-expected.txt: Added.
* media/media-source/media-source-closed.html: Added.
* media/media-source/media-source-play-expected.txt: Added.
* media/media-source/media-source-play.html: Added.
* media/media-source/mock-media-source.js: Added.
* media/video-test.js:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@158853 268f45cc-cd09-0410-ab3c-d52691b4dbfc

38 files changed:
LayoutTests/ChangeLog
LayoutTests/media/media-source/media-source-addsourcebuffer-expected.txt [new file with mode: 0644]
LayoutTests/media/media-source/media-source-addsourcebuffer.html [new file with mode: 0644]
LayoutTests/media/media-source/media-source-append-buffer-expected.txt [new file with mode: 0644]
LayoutTests/media/media-source/media-source-append-buffer.html [new file with mode: 0644]
LayoutTests/media/media-source/media-source-canplaythrough-expected.txt [new file with mode: 0644]
LayoutTests/media/media-source/media-source-canplaythrough.html [new file with mode: 0644]
LayoutTests/media/media-source/media-source-closed-expected.txt [new file with mode: 0644]
LayoutTests/media/media-source/media-source-closed.html [new file with mode: 0644]
LayoutTests/media/media-source/media-source-play-expected.txt [new file with mode: 0644]
LayoutTests/media/media-source/media-source-play.html [new file with mode: 0644]
LayoutTests/media/media-source/media-source-track-enabled-expected.txt [new file with mode: 0644]
LayoutTests/media/media-source/media-source-track-enabled.html [new file with mode: 0644]
LayoutTests/media/media-source/media-source-tracks-expected.txt [new file with mode: 0644]
LayoutTests/media/media-source/media-source-tracks.html [new file with mode: 0644]
LayoutTests/media/media-source/mock-media-source.js [new file with mode: 0644]
LayoutTests/media/video-test.js
Source/WebCore/ChangeLog
Source/WebCore/Modules/mediasource/MediaSource.cpp
Source/WebCore/Modules/mediasource/SourceBuffer.cpp
Source/WebCore/WebCore.exp.in
Source/WebCore/WebCore.xcodeproj/project.pbxproj
Source/WebCore/html/HTMLMediaElement.cpp
Source/WebCore/platform/graphics/MediaPlayer.cpp
Source/WebCore/platform/graphics/MediaPlayer.h
Source/WebCore/platform/mock/mediasource/MockBox.cpp [new file with mode: 0644]
Source/WebCore/platform/mock/mediasource/MockBox.h [new file with mode: 0644]
Source/WebCore/platform/mock/mediasource/MockMediaPlayerMediaSource.cpp [new file with mode: 0644]
Source/WebCore/platform/mock/mediasource/MockMediaPlayerMediaSource.h [new file with mode: 0644]
Source/WebCore/platform/mock/mediasource/MockMediaSourcePrivate.cpp [new file with mode: 0644]
Source/WebCore/platform/mock/mediasource/MockMediaSourcePrivate.h [new file with mode: 0644]
Source/WebCore/platform/mock/mediasource/MockSourceBufferPrivate.cpp [new file with mode: 0644]
Source/WebCore/platform/mock/mediasource/MockSourceBufferPrivate.h [new file with mode: 0644]
Source/WebCore/platform/mock/mediasource/MockTracks.cpp [new file with mode: 0644]
Source/WebCore/platform/mock/mediasource/MockTracks.h [new file with mode: 0644]
Source/WebCore/testing/Internals.cpp
Source/WebCore/testing/Internals.h
Source/WebCore/testing/Internals.idl

index f94145a..a6b8227 100644 (file)
@@ -1,3 +1,23 @@
+2013-10-24  Jer Noble  <jer.noble@apple.com>
+
+        [MSE] Add mock MediaSource classes for testing.
+        https://bugs.webkit.org/show_bug.cgi?id=123322
+
+        Reviewed by Eric Carlson.
+
+        * media/media-source/media-source-addsourcebuffer-expected.txt: Added.
+        * media/media-source/media-source-addsourcebuffer.html: Added.
+        * media/media-source/media-source-append-buffer-expected.txt: Added.
+        * media/media-source/media-source-append-buffer.html: Added.
+        * media/media-source/media-source-canplaythrough-expected.txt: Added.
+        * media/media-source/media-source-canplaythrough.html: Added.
+        * media/media-source/media-source-closed-expected.txt: Added.
+        * media/media-source/media-source-closed.html: Added.
+        * media/media-source/media-source-play-expected.txt: Added.
+        * media/media-source/media-source-play.html: Added.
+        * media/media-source/mock-media-source.js: Added.
+        * media/video-test.js:
+
 2013-11-07  Samuel White  <samuel_white@apple.com>
 
         AX: DRT AccessibilityUIElement::isFocused methods should be finished.
diff --git a/LayoutTests/media/media-source/media-source-addsourcebuffer-expected.txt b/LayoutTests/media/media-source/media-source-addsourcebuffer-expected.txt
new file mode 100644 (file)
index 0000000..bb3964e
--- /dev/null
@@ -0,0 +1,12 @@
+
+TEST(source.addSourceBuffer("invalid")) THROWS(DOMException.NOT_SUPPORTED_ERR) OK
+TEST(source.addSourceBuffer("")) THROWS(DOMException.INVALID_ACCESS_ERR) OK
+EXPECTED (MediaSource.isTypeSupported("invalid") == 'false') OK
+EXPECTED (MediaSource.isTypeSupported("video/mock; codecs=mock") == 'true') OK
+RUN(video.src = URL.createObjectURL(source))
+EVENT(sourceopen)
+RUN(sourceBuffer = source.addSourceBuffer("video/mock; codecs=mock"))
+EXPECTED (source.sourceBuffers[0] == '[object SourceBuffer]') OK
+EXPECTED (source.activeSourceBuffers[0] == '[object SourceBuffer]') OK
+END OF TEST
+
diff --git a/LayoutTests/media/media-source/media-source-addsourcebuffer.html b/LayoutTests/media/media-source/media-source-addsourcebuffer.html
new file mode 100644 (file)
index 0000000..396c53c
--- /dev/null
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <title>mock-media-source</title>
+    <script src="mock-media-source.js"></script>
+    <script src="../video-test.js"></script>
+    <script>
+    var source;
+    var sourceBuffer;
+
+    if (window.internals)
+        internals.initializeMockMediaSource();
+
+    function runTest() {
+        findMediaElement();
+
+        source = new MediaSource();
+        testDOMException('source.addSourceBuffer("invalid")', 'DOMException.NOT_SUPPORTED_ERR');
+        testDOMException('source.addSourceBuffer("")', 'DOMException.INVALID_ACCESS_ERR');
+        testExpected('MediaSource.isTypeSupported("invalid")', false);
+        testExpected('MediaSource.isTypeSupported("video/mock; codecs=mock")', true);
+
+        waitForEvent('sourceopen', sourceOpen, false, false, source);
+        run('video.src = URL.createObjectURL(source)');
+    }
+
+    function sourceOpen() {
+        run('sourceBuffer = source.addSourceBuffer("video/mock; codecs=mock")');
+        testExpected('source.sourceBuffers[0]', sourceBuffer);
+        testExpected('source.activeSourceBuffers[0]', sourceBuffer);
+        endTest();
+    }
+    
+    </script>
+</head>
+<body onload="runTest()">
+    <video></video>
+</body>
+</html>
\ No newline at end of file
diff --git a/LayoutTests/media/media-source/media-source-append-buffer-expected.txt b/LayoutTests/media/media-source/media-source-append-buffer-expected.txt
new file mode 100644 (file)
index 0000000..09c698f
--- /dev/null
@@ -0,0 +1,12 @@
+
+RUN(video.src = URL.createObjectURL(source))
+EVENT(sourceopen)
+RUN(sourceBuffer = source.addSourceBuffer("video/mock; codecs=mock"))
+RUN(sourceBuffer.appendBuffer(initSegment))
+EXPECTED (sourceBuffer.updating == 'true') OK
+EVENT(updatestart)
+EVENT(update)
+EVENT(updateend)
+EXPECTED (sourceBuffer.updating == 'false') OK
+END OF TEST
+
diff --git a/LayoutTests/media/media-source/media-source-append-buffer.html b/LayoutTests/media/media-source/media-source-append-buffer.html
new file mode 100644 (file)
index 0000000..5ea2fec
--- /dev/null
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <title>mock-media-source</title>
+    <script src="mock-media-source.js"></script>
+    <script src="../video-test.js"></script>
+    <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 = URL.createObjectURL(source)');
+    }
+
+    function sourceOpen() {
+        run('sourceBuffer = source.addSourceBuffer("video/mock; codecs=mock")');
+
+        waitForEventOn(sourceBuffer, 'updatestart');
+        waitForEventOn(sourceBuffer, 'update');
+        waitForEventOn(sourceBuffer, 'updateend', updateEnd);
+        initSegment = makeAInit(100, [makeATrack(1, 'mock', TRACK_KIND.VIDEO)]);
+        run('sourceBuffer.appendBuffer(initSegment)');
+        testExpected('sourceBuffer.updating', true);
+    }
+    
+    function updateEnd() {
+        testExpected('sourceBuffer.updating', false);
+        endTest();
+    }
+
+    </script>
+</head>
+<body onload="runTest()">
+    <video></video>
+</body>
+</html>
diff --git a/LayoutTests/media/media-source/media-source-canplaythrough-expected.txt b/LayoutTests/media/media-source/media-source-canplaythrough-expected.txt
new file mode 100644 (file)
index 0000000..42ec573
--- /dev/null
@@ -0,0 +1,8 @@
+
+RUN(video.src = URL.createObjectURL(source))
+EVENT(loadedmetadata)
+EVENT(loadeddata)
+EVENT(canplay)
+EVENT(canplaythrough)
+END OF TEST
+
diff --git a/LayoutTests/media/media-source/media-source-canplaythrough.html b/LayoutTests/media/media-source/media-source-canplaythrough.html
new file mode 100644 (file)
index 0000000..6e91f76
--- /dev/null
@@ -0,0 +1,51 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <title>mock-media-source</title>
+    <script src="mock-media-source.js"></script>
+    <script src="../video-test.js"></script>
+    <script>
+    var source;
+    var sourceBuffer;
+
+    var requestLength = 200000;
+    var nextRequest = 0;
+    var totalLength = 100;
+
+    if (window.internals)
+        internals.initializeMockMediaSource();
+
+    function runTest() {
+        findMediaElement();
+        source = new MediaSource();
+        source.addEventListener('sourceopen', startLoad);
+        waitForEvent('loadedmetadata');
+        waitForEvent('loadeddata');
+        waitForEvent('canplay');
+        waitForEventAndEnd('canplaythrough');
+        run('video.src = URL.createObjectURL(source)');
+    }
+
+    function startLoad() {
+        sourceBuffer = source.addSourceBuffer('video/mock; codecs="mock"');
+        sourceBuffer.addEventListener('update', sourceUpdated);
+        nextRequest = 0;
+
+        // Make an init segment with 1 video track
+        var init = makeAInit(100, [makeATrack(1, 'mock', TRACK_KIND.VIDEO)]);
+        sourceBuffer.appendBuffer(init)
+    }
+
+    function sourceUpdated() {
+        source.activeSourceBuffers.length;
+        if (nextRequest < totalLength) {
+            sourceBuffer.appendBuffer(makeASample(nextRequest, nextRequest, 1, 1, 0));
+            ++nextRequest;
+        }
+    }
+    </script>
+</head>
+<body onload="runTest()">
+    <video controls width=960 height=510></video>
+</body>
+</html>
diff --git a/LayoutTests/media/media-source/media-source-closed-expected.txt b/LayoutTests/media/media-source/media-source-closed-expected.txt
new file mode 100644 (file)
index 0000000..cd33e13
--- /dev/null
@@ -0,0 +1,7 @@
+
+EXPECTED (source.readyState == 'closed') OK
+EVENT(sourceopen)
+RUN(video.src = "")
+EVENT(sourceclose)
+END OF TEST
+
diff --git a/LayoutTests/media/media-source/media-source-closed.html b/LayoutTests/media/media-source/media-source-closed.html
new file mode 100644 (file)
index 0000000..22c821e
--- /dev/null
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <title>mock-media-source</title>
+    <script src="mock-media-source.js"></script>
+    <script src="../video-test.js"></script>
+    <script>
+    var source;
+    var sourceBuffer;
+    var sourceTag;
+
+    if (window.internals)
+        internals.initializeMockMediaSource();
+
+    function runTest() {
+        findMediaElement();
+
+        source = new MediaSource();
+        testExpected('source.readyState', 'closed');
+
+        waitForEventOn(source, 'sourceopen', sourceOpen);
+        video.src = URL.createObjectURL(source);
+    }
+
+    function sourceOpen() {
+        waitForEventOn(source, 'sourceclose', endTest);
+        run('video.src = ""');
+    }
+    
+    </script>
+</head>
+<body onload="runTest()">
+    <video></video>
+</body>
+</html>
\ No newline at end of file
diff --git a/LayoutTests/media/media-source/media-source-play-expected.txt b/LayoutTests/media/media-source/media-source-play-expected.txt
new file mode 100644 (file)
index 0000000..592a9af
--- /dev/null
@@ -0,0 +1,14 @@
+
+EXPECTED (source.readyState == 'closed') OK
+EVENT(sourceopen)
+RUN(sourceBuffer = source.addSourceBuffer("video/mock; codecs=mock"))
+RUN(sourceBuffer.appendBuffer(initSegment))
+EVENT(updateend)
+RUN(sourceBuffer.appendBuffer(sample))
+EVENT(updateend)
+RUN(source.duration = 1)
+RUN(source.endOfStream())
+RUN(video.play())
+EVENT(ended)
+END OF TEST
+
diff --git a/LayoutTests/media/media-source/media-source-play.html b/LayoutTests/media/media-source/media-source-play.html
new file mode 100644 (file)
index 0000000..9657ae4
--- /dev/null
@@ -0,0 +1,51 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <title>mock-media-source</title>
+    <script src="mock-media-source.js"></script>
+    <script src="../video-test.js"></script>
+    <script>
+    var source;
+    var sourceBuffer;
+    var initSegment;
+    var sample;
+
+    if (window.internals)
+        internals.initializeMockMediaSource();
+
+    function runTest() {
+        findMediaElement();
+
+        source = new MediaSource();
+        testExpected('source.readyState', 'closed');
+
+        waitForEventOn(source, 'sourceopen', sourceOpen);
+        video.src = URL.createObjectURL(source);
+    }
+
+    function sourceOpen() {
+        run('sourceBuffer = source.addSourceBuffer("video/mock; codecs=mock")');
+        waitForEventOn(sourceBuffer, 'updateend', loadSamples, false, true);
+        initSegment = makeAInit(100, [makeATrack(1, 'mock', TRACK_KIND.VIDEO)]);
+        run('sourceBuffer.appendBuffer(initSegment)');
+    }
+
+    function loadSamples() {
+        sample = makeASample(0, 0, 10, 1, 0);
+        waitForEventOn(sourceBuffer, 'updateend', play, false, true);
+        run('sourceBuffer.appendBuffer(sample)');
+    }
+
+    function play() {
+        waitForEvent('ended', endTest);
+        run('source.duration = 1');
+        run('source.endOfStream()');
+        run('video.play()');
+    }
+    
+    </script>
+</head>
+<body onload="runTest()">
+    <video></video>
+</body>
+</html>
diff --git a/LayoutTests/media/media-source/media-source-track-enabled-expected.txt b/LayoutTests/media/media-source/media-source-track-enabled-expected.txt
new file mode 100644 (file)
index 0000000..d78fa09
--- /dev/null
@@ -0,0 +1,15 @@
+
+RUN(video.src = URL.createObjectURL(source))
+EVENT(sourceopen)
+RUN(sourceBuffer = source.addSourceBuffer("video/mock; codecs=mock"))
+RUN(sourceBuffer.appendBuffer(initSegment))
+EXPECTED (sourceBuffer.updating == 'true') OK
+EVENT(updatestart)
+EVENT(update)
+EVENT(updateend)
+EXPECTED (sourceBuffer.updating == 'false') OK
+EXPECTED (sourceBuffer.videoTracks.length == '1') OK
+EXPECTED (sourceBuffer.videoTracks[0].selected == 'true') OK
+EXPECTED (source.activeSourceBuffers.length == '1') OK
+END OF TEST
+
diff --git a/LayoutTests/media/media-source/media-source-track-enabled.html b/LayoutTests/media/media-source/media-source-track-enabled.html
new file mode 100644 (file)
index 0000000..00284be
--- /dev/null
@@ -0,0 +1,49 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <title>mock-media-source</title>
+    <script src="mock-media-source.js"></script>
+    <script src="../video-test.js"></script>
+    <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 = URL.createObjectURL(source)');
+    }
+
+    function sourceOpen() {
+        run('sourceBuffer = source.addSourceBuffer("video/mock; codecs=mock")');
+
+        waitForEventOn(sourceBuffer, 'updatestart');
+        waitForEventOn(sourceBuffer, 'update');
+        waitForEventOn(sourceBuffer, 'updateend', updateEnd);
+        initSegment = makeAInit(100, [
+            makeATrack(1, 'mock', TRACK_KIND.VIDEO),
+        ]);
+        run('sourceBuffer.appendBuffer(initSegment)');
+        testExpected('sourceBuffer.updating', true);
+    }
+    
+    function updateEnd() {
+        testExpected('sourceBuffer.updating', false);
+        testExpected('sourceBuffer.videoTracks.length', 1);
+        testExpected('sourceBuffer.videoTracks[0].selected', true);
+        testExpected('source.activeSourceBuffers.length', 1);
+        endTest();
+    }
+
+    </script>
+</head>
+<body onload="runTest()">
+    <video></video>
+</body>
+</html>
diff --git a/LayoutTests/media/media-source/media-source-tracks-expected.txt b/LayoutTests/media/media-source/media-source-tracks-expected.txt
new file mode 100644 (file)
index 0000000..0227219
--- /dev/null
@@ -0,0 +1,15 @@
+
+RUN(video.src = URL.createObjectURL(source))
+EVENT(sourceopen)
+RUN(sourceBuffer = source.addSourceBuffer("video/mock; codecs=mock"))
+RUN(sourceBuffer.appendBuffer(initSegment))
+EXPECTED (sourceBuffer.updating == 'true') OK
+EVENT(updatestart)
+EVENT(update)
+EVENT(updateend)
+EXPECTED (sourceBuffer.updating == 'false') OK
+EXPECTED (sourceBuffer.videoTracks.length == '1') OK
+EXPECTED (sourceBuffer.audioTracks.length == '2') OK
+EXPECTED (sourceBuffer.textTracks.length == '3') OK
+END OF TEST
+
diff --git a/LayoutTests/media/media-source/media-source-tracks.html b/LayoutTests/media/media-source/media-source-tracks.html
new file mode 100644 (file)
index 0000000..dd1ccbd
--- /dev/null
@@ -0,0 +1,54 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <title>mock-media-source</title>
+    <script src="mock-media-source.js"></script>
+    <script src="../video-test.js"></script>
+    <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 = URL.createObjectURL(source)');
+    }
+
+    function sourceOpen() {
+        run('sourceBuffer = source.addSourceBuffer("video/mock; codecs=mock")');
+
+        waitForEventOn(sourceBuffer, 'updatestart');
+        waitForEventOn(sourceBuffer, 'update');
+        waitForEventOn(sourceBuffer, 'updateend', updateEnd);
+        initSegment = makeAInit(100, [
+            makeATrack(1, 'mock', TRACK_KIND.VIDEO),
+            makeATrack(2, 'mock', TRACK_KIND.AUDIO),
+            makeATrack(3, 'mock', TRACK_KIND.AUDIO),
+            makeATrack(4, 'mock', TRACK_KIND.TEXT),
+            makeATrack(5, 'mock', TRACK_KIND.TEXT),
+            makeATrack(6, 'mock', TRACK_KIND.TEXT),
+        ]);
+        run('sourceBuffer.appendBuffer(initSegment)');
+        testExpected('sourceBuffer.updating', true);
+    }
+    
+    function updateEnd() {
+        testExpected('sourceBuffer.updating', false);
+        testExpected('sourceBuffer.videoTracks.length', 1);
+        testExpected('sourceBuffer.audioTracks.length', 2);
+        testExpected('sourceBuffer.textTracks.length', 3);
+        endTest();
+    }
+
+    </script>
+</head>
+<body onload="runTest()">
+    <video></video>
+</body>
+</html>
diff --git a/LayoutTests/media/media-source/mock-media-source.js b/LayoutTests/media/media-source/mock-media-source.js
new file mode 100644 (file)
index 0000000..f552c60
--- /dev/null
@@ -0,0 +1,72 @@
+var TRACK_KIND = {
+    AUDIO: 0,
+    VIDEO: 1,
+    TEXT: 2,
+};
+
+function stringToArray(string) {
+    return string.split("").map(function(c){ return c.charCodeAt(0); });
+}
+
+function makeASample(presentationTime, decodeTime, duration, trackID, flags) {
+    var byteLength = 29;
+    var buffer = new ArrayBuffer(byteLength);
+    var array = new Uint8Array(buffer);
+    array.set(stringToArray('smpl'));
+
+    var view = new DataView(buffer);
+    view.setUint32(4, byteLength, true);
+
+    var timeScale = 1000;
+    view.setInt32(8, timeScale, true);
+    view.setInt32(12, presentationTime * timeScale, true);
+    view.setInt32(16, decodeTime * timeScale, true);
+    view.setInt32(20, duration * timeScale, true);
+    view.setInt32(24, trackID, true);
+    view.setUint8(28, flags);
+
+    return buffer;
+}
+
+function makeATrack(trackID, codec, flags) {
+    var byteLength = 17;
+    var buffer = new ArrayBuffer(byteLength);
+    var array = new Uint8Array(buffer);
+    array.set(stringToArray('trak'));
+
+    var view = new DataView(buffer);
+    view.setUint32(4, byteLength, true);
+    view.setInt32(8, trackID, true);
+
+    var codecArray = new Uint8Array(buffer, 12, 4);
+    codecArray.set(stringToArray(codec));
+
+    view.setUint8(16, flags, true);
+
+    return buffer;
+}
+
+function makeAInit(duration, tracks) {
+    var byteLength = 16 + (17 * tracks.length);
+    var buffer = new ArrayBuffer(byteLength);
+    var array = new Uint8Array(buffer);
+    array.set(stringToArray('init'));
+
+    var view = new DataView(buffer);
+    var timeScale = 1000;
+    view.setUint32(4, byteLength, true);
+    view.setInt32(8, duration * timeScale, true);
+    view.setInt32(12, timeScale, true);
+
+    var offset = 16;
+    tracks.forEach(function(track){
+        var sourceArray = new Uint8Array(track);
+        var destArray = new Uint8Array(buffer, offset, sourceArray.byteLength);
+        destArray.set(sourceArray);
+        offset += sourceArray.byteLength;
+    });
+
+    return buffer;
+}
+
+
index 059837b..cab3fdf 100644 (file)
@@ -202,6 +202,11 @@ function waitForEventAndTest(eventName, testFuncString, endit)
     mediaElement.addEventListener(eventName, _eventCallback, true);
 }
 
+function waitForEventOn(element, eventName, func, endit, oneTimeOnly)
+{
+    waitForEvent(eventName, func, endit, oneTimeOnly, element);
+}
+
 function testDOMException(testString, exceptionString)
 {
     try {
index 2467eec..d7d8ce4 100644 (file)
@@ -1,3 +1,187 @@
+2013-10-30  Jer Noble  <jer.noble@apple.com>
+
+        [MSE] Add mock MediaSource classes for testing.
+        https://bugs.webkit.org/show_bug.cgi?id=123322
+
+        Reviewed by Eric Carlson.
+
+        Tests: media/media-source/media-source-addsourcebuffer.html
+               media/media-source/media-source-append-buffer.html
+               media/media-source/media-source-canplaythrough.html
+               media/media-source/media-source-closed.html
+               media/media-source/media-source-play.html
+               media/media-source/media-source-track-enabled.html
+               media/media-source/media-source-tracks.html
+
+
+        Add mock implementation of platform MediaSource classes, allowing ports to test the
+        MediaSource API without having a platform implementation.
+
+        The MockMediaSource will support a byteformat defined in MockBox.h: a simple box-style media
+        format with an initialization segment containing a number of tracks, followed by a list of
+        samples.
+
+        Add a means to insert a new media engine factory at runtime, so the internals object can add
+        a MockMediaSourceMediaPlayer:
+        * platform/graphics/MediaPlayer.cpp:
+        (WebCore::MediaPlayerFactorySupport::callRegisterMediaEngine):
+        * platform/graphics/MediaPlayer.h:
+        * testing/Internals.cpp:
+        (WebCore::Internals::initializeMockMediaSource):
+        * testing/Internals.h:
+        * testing/Internals.idl:
+
+        For non-media-source supporting media engines, fail immediately when asked to load a media
+        source, so that the MockMediaSourceMediaPlayer will be instantiated as a fall-back:
+        * platform/graphics/avfoundation/MediaPlayerPrivateAVFoundation.cpp:
+        (WebCore::MediaPlayerPrivateAVFoundation::load):
+        * platform/graphics/avfoundation/MediaPlayerPrivateAVFoundation.h:
+        * platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm:
+        (WebCore::MediaPlayerPrivateAVFoundationObjC::supportsType):
+        * platform/graphics/mac/MediaPlayerPrivateQTKit.h:
+        * platform/graphics/mac/MediaPlayerPrivateQTKit.mm:
+        (WebCore::MediaPlayerPrivateQTKit::load):
+        (WebCore::MediaPlayerPrivateQTKit::supportsType):
+
+        Add new files to the project:
+        * WebCore.xcodeproj/project.pbxproj:
+        * Source/WebCore/WebCore.exp.in:
+
+        Update the MediaSource implementation:
+        * Modules/mediasource/MediaSource.cpp:
+        (WebCore::MediaSource::monitorSourceBuffers): Add a link to the spec.
+        * Modules/mediasource/SourceBuffer.cpp:
+        (WebCore::SourceBuffer::buffered): Ditto.
+        (WebCore::SourceBuffer::setTimestampOffset): Ditto.
+        (WebCore::SourceBuffer::validateInitializationSegment): Ditto.
+        (WebCore::SourceBuffer::sourceBufferPrivateDidReceiveInitializationSegment): Ditto. Also,
+            bring the implementation up to date with part of the spec.
+        (WebCore::SourceBuffer::sourceBufferPrivateDidReceiveSample): Remove "Predicate" from
+            SampleIsRandomAccessPredicate.
+
+        Add utility classes to parse and represent the bytestream supported by the MockMediaSource:
+        * platform/mock/mediasource/MockBox.cpp: Added.
+        (WebCore::MockBox::MockBox):
+        (WebCore::MockBox::peekType):
+        (WebCore::MockBox::peekLength):
+        (WebCore::MockTrackBox::MockTrackBox):
+        (WebCore::MockTrackBox::type):
+        (WebCore::MockInitializationBox::MockInitializationBox):
+        (WebCore::MockInitializationBox::type):
+        (WebCore::MockSampleBox::MockSampleBox):
+        (WebCore::MockSampleBox::type):
+        * platform/mock/mediasource/MockBox.h: Added.
+        (WebCore::MockBox::length):
+        (WebCore::MockBox::type):
+        (WebCore::MockTrackBox::trackID):
+        (WebCore::MockTrackBox::codec):
+        (WebCore::MockTrackBox::kind):
+        (WebCore::MockInitializationBox::duration):
+        (WebCore::MockInitializationBox::tracks):
+        (WebCore::MockSampleBox::presentationTimestamp):
+        (WebCore::MockSampleBox::decodeTimestamp):
+        (WebCore::MockSampleBox::duration):
+        (WebCore::MockSampleBox::trackID):
+        (WebCore::MockSampleBox::flags):
+        (WebCore::MockSampleBox::isSync):
+
+        Add a MediaPlayerPrivate implementation which uses MockMediaSource:
+        * platform/mock/mediasource/MockMediaPlayerMediaSource.cpp: Added.
+        (WebCore::MockMediaPlayerMediaSource::registerMediaEngine):
+        (WebCore::MockMediaPlayerMediaSource::create):
+        (WebCore::mimeTypeCache):
+        (WebCore::MockMediaPlayerMediaSource::getSupportedTypes):
+        (WebCore::MockMediaPlayerMediaSource::supportsType):
+        (WebCore::MockMediaPlayerMediaSource::MockMediaPlayerMediaSource):
+        (WebCore::MockMediaPlayerMediaSource::~MockMediaPlayerMediaSource):
+        (WebCore::MockMediaPlayerMediaSource::load):
+        (WebCore::MockMediaPlayerMediaSource::cancelLoad):
+        (WebCore::MockMediaPlayerMediaSource::play):
+        (WebCore::MockMediaPlayerMediaSource::pause):
+        (WebCore::MockMediaPlayerMediaSource::naturalSize):
+        (WebCore::MockMediaPlayerMediaSource::hasVideo):
+        (WebCore::MockMediaPlayerMediaSource::hasAudio):
+        (WebCore::MockMediaPlayerMediaSource::setVisible):
+        (WebCore::MockMediaPlayerMediaSource::seeking):
+        (WebCore::MockMediaPlayerMediaSource::paused):
+        (WebCore::MockMediaPlayerMediaSource::networkState):
+        (WebCore::MockMediaPlayerMediaSource::readyState):
+        (WebCore::MockMediaPlayerMediaSource::buffered):
+        (WebCore::MockMediaPlayerMediaSource::didLoadingProgress):
+        (WebCore::MockMediaPlayerMediaSource::setSize):
+        (WebCore::MockMediaPlayerMediaSource::paint):
+        (WebCore::MockMediaPlayerMediaSource::currentTimeDouble):
+        (WebCore::MockMediaPlayerMediaSource::durationDouble):
+        (WebCore::MockMediaPlayerMediaSource::seekDouble):
+        (WebCore::MockMediaPlayerMediaSource::advanceCurrentTime):
+        (WebCore::MockMediaPlayerMediaSource::updateDuration):
+        (WebCore::MockMediaPlayerMediaSource::setReadyState):
+        * platform/mock/mediasource/MockMediaPlayerMediaSource.h: Added.
+
+        Add a mock implementation of MediaSourcePrivate, which uses MockSourceBuffer:
+        * platform/mock/mediasource/MockMediaSourcePrivate.cpp: Added.
+        (WebCore::MockMediaSourcePrivate::create):
+        (WebCore::MockMediaSourcePrivate::MockMediaSourcePrivate):
+        (WebCore::MockMediaSourcePrivate::~MockMediaSourcePrivate):
+        (WebCore::MockMediaSourcePrivate::addSourceBuffer):
+        (WebCore::MockMediaSourcePrivate::removeSourceBuffer):
+        (WebCore::MockMediaSourcePrivate::duration):
+        (WebCore::MockMediaSourcePrivate::setDuration):
+        (WebCore::MockMediaSourcePrivate::markEndOfStream):
+        (WebCore::MockMediaSourcePrivate::unmarkEndOfStream):
+        (WebCore::MockMediaSourcePrivate::readyState):
+        (WebCore::MockMediaSourcePrivate::setReadyState):
+        (WebCore::MockMediaSourcePrivate::sourceBufferPrivateDidChangeActiveState):
+        (WebCore::MockSourceBufferPrivateHasAudio):
+        (WebCore::MockMediaSourcePrivate::hasAudio):
+        (WebCore::MockSourceBufferPrivateHasVideo):
+        (WebCore::MockMediaSourcePrivate::hasVideo):
+        * platform/mock/mediasource/MockMediaSourcePrivate.h: Added.
+        (WebCore::MockMediaSourcePrivate::activeSourceBuffers):
+        (WebCore::MockMediaSourcePrivate::player):
+
+        Add a mock implementation of SourceBufferPrivate, which uses MockBoxes to parse the
+        bytestream provided by SourceBuffer:
+        * platform/mock/mediasource/MockSourceBufferPrivate.cpp: Added.
+        (WebCore::MockMediaSample::create):
+        (WebCore::MockMediaSample::~MockMediaSample):
+        (WebCore::MockMediaSample::MockMediaSample):
+        (WebCore::MockMediaSample::platformSample):
+        (WebCore::MockMediaDescription::create):
+        (WebCore::MockMediaDescription::~MockMediaDescription):
+        (WebCore::MockMediaDescription::MockMediaDescription):
+        (WebCore::MockSourceBufferPrivate::create):
+        (WebCore::MockSourceBufferPrivate::MockSourceBufferPrivate):
+        (WebCore::MockSourceBufferPrivate::~MockSourceBufferPrivate):
+        (WebCore::MockSourceBufferPrivate::setClient):
+        (WebCore::MockSourceBufferPrivate::append):
+        (WebCore::MockSourceBufferPrivate::didReceiveInitializationSegment):
+        (WebCore::MockSourceBufferPrivate::didReceiveSample):
+        (WebCore::MockSourceBufferPrivate::abort):
+        (WebCore::MockSourceBufferPrivate::removedFromMediaSource):
+        (WebCore::MockSourceBufferPrivate::readyState):
+        (WebCore::MockSourceBufferPrivate::setReadyState):
+        (WebCore::MockSourceBufferPrivate::hasVideo):
+        (WebCore::MockSourceBufferPrivate::hasAudio):
+        * platform/mock/mediasource/MockSourceBufferPrivate.h: Added.
+
+        Create mock implementations of AudioTrackPrivate, VideoTrackPrivate, and TextTrackPrivate
+        which wrap the MockTrackBox class:
+        * platform/mock/mediasource/MockTracks.cpp: Added.
+        * platform/mock/mediasource/MockTracks.h: Added.
+        (WebCore::MockAudioTrackPrivate::create):
+        (WebCore::MockAudioTrackPrivate::~MockAudioTrackPrivate):
+        (WebCore::MockAudioTrackPrivate::id):
+        (WebCore::MockAudioTrackPrivate::MockAudioTrackPrivate):
+        (WebCore::MockTextTrackPrivate::create):
+        (WebCore::MockTextTrackPrivate::~MockTextTrackPrivate):
+        (WebCore::MockTextTrackPrivate::id):
+        (WebCore::MockTextTrackPrivate::MockTextTrackPrivate):
+        (WebCore::MockVideoTrackPrivate::create):
+        (WebCore::MockVideoTrackPrivate::~MockVideoTrackPrivate):
+        (WebCore::MockVideoTrackPrivate::id):
+        (WebCore::MockVideoTrackPrivate::MockVideoTrackPrivate):
+
 2013-11-07  Thiago de Barros Lacerda  <thiago.lacerda@openbossa.org>
 
         Changing MediaStreamDescriptor to MediaStreamPrivate
index d334437..6eef0c9 100644 (file)
@@ -398,6 +398,7 @@ 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();
index 57f3e0b..b600e04 100644 (file)
@@ -108,6 +108,7 @@ SourceBuffer::~SourceBuffer()
 PassRefPtr<TimeRanges> SourceBuffer::buffered(ExceptionCode& ec) const
 {
     // Section 3.1 buffered attribute steps.
+    // https://dvcs.w3.org/hg/html-media/raw-file/default/media-source/media-source.html#attributes-1
     // 1. 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.
     if (isRemoved()) {
@@ -132,6 +133,7 @@ double SourceBuffer::timestampOffset() const
 void SourceBuffer::setTimestampOffset(double offset, ExceptionCode& ec)
 {
     // Section 3.1 timestampOffset attribute setter steps.
+    // https://dvcs.w3.org/hg/html-media/raw-file/default/media-source/media-source.html#attributes-1
     // 1. 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.
     if (isRemoved()) {
@@ -390,9 +392,16 @@ void SourceBuffer::sourceBufferPrivateDidReceiveInitializationSegment(SourceBuff
     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:
-    if (std::isnan(m_source->duration()) && segment.duration.isValid())
-        m_source->setDuration(segment.duration.toDouble(), IGNORE_EXCEPTION);
+    if (std::isnan(m_source->duration())) {
+        // ↳ If the initialization segment contains a duration:
+        //   Run the duration change algorithm with new duration set to the duration in the initialization segment.
+        // ↳ Otherwise:
+        //   Run the duration change algorithm with new duration set to positive Infinity.
+        MediaTime newDuration = segment.duration.isValid() ? segment.duration : MediaTime::positiveInfiniteTime();
+        m_source->setDuration(newDuration.toDouble(), IGNORE_EXCEPTION);
+    }
 
     // 2. If the initialization segment has no audio, video, or text tracks, then run the end of stream
     // algorithm with the error parameter set to "decode" and abort these steps.
@@ -560,6 +569,9 @@ void SourceBuffer::sourceBufferPrivateDidReceiveInitializationSegment(SourceBuff
 
 bool SourceBuffer::validateInitializationSegment(const InitializationSegment& segment)
 {
+    // 3.5.7 Initialization Segment Received (ctd)
+    // https://dvcs.w3.org/hg/html-media/raw-file/default/media-source/media-source.html#sourcebuffer-init-segment-received
+
     // 3.1. Verify the following properties. If any of the checks fail then run the end of stream
     // algorithm with the error parameter set to "decode" and abort these steps.
     //   * The number of audio, video, and text tracks match what was in the first initialization segment.
@@ -656,7 +668,7 @@ public:
     }
 };
 
-class SampleIsRandomAccessPredicate {
+class SampleIsRandomAccess {
 public:
     bool operator()(std::pair<MediaTime, RefPtr<MediaSample>> value)
     {
@@ -842,7 +854,7 @@ void SourceBuffer::sourceBufferPrivateDidReceiveSample(SourceBufferPrivate*, Pas
             // Otherwise: Remove all coded frames between the coded frames removed in the previous step
             // and the next random access point after those removed frames.
             auto first_iter = std::upper_bound(trackBuffer.samples.begin(), trackBuffer.samples.end(), *erasedSamples.begin(), SampleLessThanComparator());
-            auto second_iter = std::find_if(first_iter, trackBuffer.samples.end(), SampleIsRandomAccessPredicate());
+            auto second_iter = std::find_if(first_iter, trackBuffer.samples.end(), SampleIsRandomAccess());
             if (first_iter != trackBuffer.samples.end()) {
                 trackBuffer.samples.erase(first_iter, second_iter);
                 erasedSamples.insert(first_iter, second_iter);
index 6b011c3..209a44e 100644 (file)
@@ -2897,3 +2897,11 @@ __ZN7WebCore12WorkerThread17workerThreadCountEv
 #if ENABLE(VIDEO_TRACK)
 __ZN7WebCore9PageGroup18captionPreferencesEv
 #endif
+
+#if ENABLE(VIDEO)
+__ZN7WebCore25MediaPlayerFactorySupport23callRegisterMediaEngineEPFvPFvPFN3WTF10PassOwnPtrINS_27MediaPlayerPrivateInterfaceEEEPNS_11MediaPlayerEEPFvRNS1_7HashSetINS1_6StringENS1_10StringHashENS1_10HashTraitsISA_EEEEEPFNS5_12SupportsTypeERKNS_28MediaEngineSupportParametersEEPFvRNS1_6VectorISA_Lm0ENS1_15CrashOnOverflowEEEEPFvvEPFvRKSA_EEE
+#endif
+
+#if ENABLE(MEDIA_SOURCE)
+__ZN7WebCore26MockMediaPlayerMediaSource19registerMediaEngineEPFvPFN3WTF10PassOwnPtrINS_27MediaPlayerPrivateInterfaceEEEPNS_11MediaPlayerEEPFvRNS1_7HashSetINS1_6StringENS1_10StringHashENS1_10HashTraitsISA_EEEEEPFNS5_12SupportsTypeERKNS_28MediaEngineSupportParametersEEPFvRNS1_6VectorISA_Lm0ENS1_15CrashOnOverflowEEEEPFvvEPFvRKSA_EE
+#endif
index e7e7835..c5dbe38 100644 (file)
                CDEE393717974259001D7580 /* PublicURLManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CDEE393617974259001D7580 /* PublicURLManager.cpp */; };
                CDEF4FD717E85C8F00AEE24B /* GridLength.h in Headers */ = {isa = PBXBuildFile; fileRef = CDEF4FD617E85C8F00AEE24B /* GridLength.h */; settings = {ATTRIBUTES = (Private, ); }; };
                CDF2B004181F059C00F2B424 /* MediaDescription.h in Headers */ = {isa = PBXBuildFile; fileRef = CDF2B003181F059C00F2B424 /* MediaDescription.h */; };
+               CDF2B0101820540600F2B424 /* MockBox.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CDF2B0061820540600F2B424 /* MockBox.cpp */; };
+               CDF2B0111820540600F2B424 /* MockBox.h in Headers */ = {isa = PBXBuildFile; fileRef = CDF2B0071820540600F2B424 /* MockBox.h */; };
+               CDF2B0121820540600F2B424 /* MockMediaPlayerMediaSource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CDF2B0081820540600F2B424 /* MockMediaPlayerMediaSource.cpp */; };
+               CDF2B0131820540600F2B424 /* MockMediaPlayerMediaSource.h in Headers */ = {isa = PBXBuildFile; fileRef = CDF2B0091820540600F2B424 /* MockMediaPlayerMediaSource.h */; };
+               CDF2B0141820540600F2B424 /* MockMediaSourcePrivate.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CDF2B00A1820540600F2B424 /* MockMediaSourcePrivate.cpp */; };
+               CDF2B0151820540600F2B424 /* MockMediaSourcePrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = CDF2B00B1820540600F2B424 /* MockMediaSourcePrivate.h */; };
+               CDF2B0161820540700F2B424 /* MockSourceBufferPrivate.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CDF2B00C1820540600F2B424 /* MockSourceBufferPrivate.cpp */; };
+               CDF2B0171820540700F2B424 /* MockSourceBufferPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = CDF2B00D1820540600F2B424 /* MockSourceBufferPrivate.h */; };
+               CDF2B0181820540700F2B424 /* MockTracks.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CDF2B00E1820540600F2B424 /* MockTracks.cpp */; };
+               CDF2B0191820540700F2B424 /* MockTracks.h in Headers */ = {isa = PBXBuildFile; fileRef = CDF2B00F1820540600F2B424 /* MockTracks.h */; };
                CDF65CC8145B1E7500C4C7AA /* MediaController.h in Headers */ = {isa = PBXBuildFile; fileRef = CD27F6E4145767870078207D /* MediaController.h */; settings = {ATTRIBUTES = (Private, ); }; };
                CDF65CCA145B448800C4C7AA /* MediaControllerInterface.h in Headers */ = {isa = PBXBuildFile; fileRef = CDF65CC9145B43A700C4C7AA /* MediaControllerInterface.h */; settings = {ATTRIBUTES = (Private, ); }; };
                CE057FA51220731100A476D5 /* DocumentMarkerController.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CE057FA31220731100A476D5 /* DocumentMarkerController.cpp */; };
                CDEE393817974274001D7580 /* URLRegistry.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = URLRegistry.h; sourceTree = "<group>"; };
                CDEF4FD617E85C8F00AEE24B /* GridLength.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GridLength.h; path = style/GridLength.h; sourceTree = "<group>"; };
                CDF2B003181F059C00F2B424 /* MediaDescription.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MediaDescription.h; sourceTree = "<group>"; };
+               CDF2B0061820540600F2B424 /* MockBox.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MockBox.cpp; sourceTree = "<group>"; };
+               CDF2B0071820540600F2B424 /* MockBox.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MockBox.h; sourceTree = "<group>"; };
+               CDF2B0081820540600F2B424 /* MockMediaPlayerMediaSource.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MockMediaPlayerMediaSource.cpp; sourceTree = "<group>"; };
+               CDF2B0091820540600F2B424 /* MockMediaPlayerMediaSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MockMediaPlayerMediaSource.h; sourceTree = "<group>"; };
+               CDF2B00A1820540600F2B424 /* MockMediaSourcePrivate.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MockMediaSourcePrivate.cpp; sourceTree = "<group>"; };
+               CDF2B00B1820540600F2B424 /* MockMediaSourcePrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MockMediaSourcePrivate.h; sourceTree = "<group>"; };
+               CDF2B00C1820540600F2B424 /* MockSourceBufferPrivate.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MockSourceBufferPrivate.cpp; sourceTree = "<group>"; };
+               CDF2B00D1820540600F2B424 /* MockSourceBufferPrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MockSourceBufferPrivate.h; sourceTree = "<group>"; };
+               CDF2B00E1820540600F2B424 /* MockTracks.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MockTracks.cpp; sourceTree = "<group>"; };
+               CDF2B00F1820540600F2B424 /* MockTracks.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MockTracks.h; sourceTree = "<group>"; };
                CDF65CC9145B43A700C4C7AA /* MediaControllerInterface.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MediaControllerInterface.h; sourceTree = "<group>"; };
                CDF65CCC145B6AFE00C4C7AA /* JSHTMLMediaElementCustom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSHTMLMediaElementCustom.cpp; sourceTree = "<group>"; };
                CE057FA31220731100A476D5 /* DocumentMarkerController.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DocumentMarkerController.cpp; sourceTree = "<group>"; };
                59C77F101054591C00506104 /* mock */ = {
                        isa = PBXGroup;
                        children = (
+                               CDF2B005182053DF00F2B424 /* mediasource */,
                                07C59B6117F4CF87000FBCBB /* MockMediaStreamCenter.cpp */,
                                07C59B6217F4CF87000FBCBB /* MockMediaStreamCenter.h */,
                                59309A1011F4AE5800250603 /* DeviceOrientationClientMock.cpp */,
                        name = MediaControls;
                        sourceTree = "<group>";
                };
+               CDF2B005182053DF00F2B424 /* mediasource */ = {
+                       isa = PBXGroup;
+                       children = (
+                               CDF2B0061820540600F2B424 /* MockBox.cpp */,
+                               CDF2B0071820540600F2B424 /* MockBox.h */,
+                               CDF2B0081820540600F2B424 /* MockMediaPlayerMediaSource.cpp */,
+                               CDF2B0091820540600F2B424 /* MockMediaPlayerMediaSource.h */,
+                               CDF2B00A1820540600F2B424 /* MockMediaSourcePrivate.cpp */,
+                               CDF2B00B1820540600F2B424 /* MockMediaSourcePrivate.h */,
+                               CDF2B00C1820540600F2B424 /* MockSourceBufferPrivate.cpp */,
+                               CDF2B00D1820540600F2B424 /* MockSourceBufferPrivate.h */,
+                               CDF2B00E1820540600F2B424 /* MockTracks.cpp */,
+                               CDF2B00F1820540600F2B424 /* MockTracks.h */,
+                       );
+                       path = mediasource;
+                       sourceTree = "<group>";
+               };
                CE79D68617F220ED00815C00 /* ios */ = {
                        isa = PBXGroup;
                        children = (
                                85E7118F0AC5D5350053270F /* DOMCharacterDataInternal.h in Headers */,
                                85089CD90A98C42800A275AA /* DOMComment.h in Headers */,
                                078E093717D16B2C00420AA1 /* MediaStreamPrivate.h in Headers */,
+                               CDF2B0151820540600F2B424 /* MockMediaSourcePrivate.h in Headers */,
                                85E711900AC5D5350053270F /* DOMCommentInternal.h in Headers */,
                                BC1A37AF097C715F0019F3D8 /* DOMCore.h in Headers */,
                                BC60D6E90D28D83400B9918F /* DOMCoreException.h in Headers */,
                                078E091817D14D1C00420AA1 /* MediaStreamTrack.h in Headers */,
                                8AC822FD180FC03300FB64D5 /* RenderNamedFlowFragment.h in Headers */,
                                51D719D9181106E00016DC51 /* IDBIndex.h in Headers */,
+                               CDF2B0191820540700F2B424 /* MockTracks.h in Headers */,
                                316FE0820E6CCC2800BF6088 /* DOMWebKitCSSKeyframesRuleInternal.h in Headers */,
                                498391500F1E76B400C23782 /* DOMWebKitCSSMatrix.h in Headers */,
                                498391520F1E76B400C23782 /* DOMWebKitCSSMatrixInternal.h in Headers */,
                                31611E630E1C4E1400F6A579 /* DOMWebKitCSSTransformValueInternal.h in Headers */,
                                3F2B33EB165AF15600E3987C /* DOMWebKitCSSViewportRule.h in Headers */,
                                3F2B33ED165AF15600E3987C /* DOMWebKitCSSViewportRuleInternal.h in Headers */,
+                               CDF2B0171820540700F2B424 /* MockSourceBufferPrivate.h in Headers */,
                                8A195932147EA16E00D1EA61 /* DOMWebKitNamedFlow.h in Headers */,
                                8A195934147EA16E00D1EA61 /* DOMWebKitNamedFlowInternal.h in Headers */,
                                31C0FF4C0E4CEFDD007D6FE5 /* DOMWebKitTransitionEvent.h in Headers */,
                                514C767A0CE923A1007EF3CD /* ResourceHandleClient.h in Headers */,
                                514C767B0CE923A1007EF3CD /* ResourceHandleInternal.h in Headers */,
                                51E4143416A6596300C633C7 /* ResourceHandleTypes.h in Headers */,
+                               CDF2B0111820540600F2B424 /* MockBox.h in Headers */,
                                656D373F0ADBA5DE00A4554D /* ResourceLoader.h in Headers */,
                                D0A3A7311405A39800FB8ED3 /* ResourceLoaderOptions.h in Headers */,
                                51AF503616F100F60095B2E8 /* ResourceLoaderTypes.h in Headers */,
                                A824B4650E2EF2EA0081A7B7 /* TextRun.h in Headers */,
                                448B1B7A0F3A2F9B0047A9E2 /* TextSizeAdjustment.h in Headers */,
                                B2C3DA4B0D006C1D00EF6F26 /* TextStream.h in Headers */,
+                               CDF2B0131820540600F2B424 /* MockMediaPlayerMediaSource.h in Headers */,
                                9759E94014EF1CF80026A2DD /* TextTrack.h in Headers */,
                                9759E94314EF1CF80026A2DD /* TextTrackCue.h in Headers */,
                                071A9EC3168FBC55002629F9 /* TextTrackCueGeneric.h in Headers */,
                                D359D792129CA3C00006E5D2 /* DOMHTMLDetailsElement.mm in Sources */,
                                85BA4D0C0AA688680088052D /* DOMHTMLDirectoryElement.mm in Sources */,
                                85BA4D0E0AA688680088052D /* DOMHTMLDivElement.mm in Sources */,
+                               CDF2B0141820540600F2B424 /* MockMediaSourcePrivate.cpp in Sources */,
                                85BA4D100AA688680088052D /* DOMHTMLDListElement.mm in Sources */,
                                85BCBC140ABBA87D00381160 /* DOMHTMLDocument.mm in Sources */,
                                85DF2EEE0AA387CB00AD64C5 /* DOMHTMLElement.mm in Sources */,
                                31C0FF4A0E4CEFDD007D6FE5 /* DOMWebKitAnimationEvent.mm in Sources */,
                                A2E8AE4116A498CF006BB3AA /* DOMWebKitCSSFilterRule.mm in Sources */,
                                3106037A143281CD00ABF4BA /* DOMWebKitCSSFilterValue.mm in Sources */,
+                               CDF2B0101820540600F2B424 /* MockBox.cpp in Sources */,
                                316FE07E0E6CCC2800BF6088 /* DOMWebKitCSSKeyframeRule.mm in Sources */,
                                316FE0810E6CCC2800BF6088 /* DOMWebKitCSSKeyframesRule.mm in Sources */,
                                498391510F1E76B400C23782 /* DOMWebKitCSSMatrix.mm in Sources */,
                                A871DC290A15205700B12A68 /* HTMLTitleElement.cpp in Sources */,
                                977B3877122883E900B81FF8 /* HTMLTokenizer.cpp in Sources */,
                                0707568B142262D600414161 /* HTMLTrackElement.cpp in Sources */,
+                               CDF2B0121820540600F2B424 /* MockMediaPlayerMediaSource.cpp in Sources */,
                                977B37251228721700B81FF8 /* HTMLTreeBuilder.cpp in Sources */,
                                9B7E78BD16F16CC600126914 /* HTMLTreeBuilderSimulator.cpp in Sources */,
                                A8EA79F30A1916DF00A8EF5F /* HTMLUListElement.cpp in Sources */,
                                431A308813B8F978007791E4 /* SVGAnimatedBoolean.cpp in Sources */,
                                43A625F913B3304000AC94B8 /* SVGAnimatedColor.cpp in Sources */,
                                71CC7A20152A0BFE009EEAF9 /* SVGAnimatedEnumeration.cpp in Sources */,
+                               CDF2B0161820540700F2B424 /* MockSourceBufferPrivate.cpp in Sources */,
                                43F6FD9613BCD0B100224052 /* SVGAnimatedInteger.cpp in Sources */,
                                1A3586E115264F950022A659 /* SVGAnimatedIntegerOptionalInteger.cpp in Sources */,
                                8AC822FC180FC03300FB64D5 /* RenderNamedFlowFragment.cpp in Sources */,
                                8476C9EF11DF6A5800555B02 /* SVGPathParser.cpp in Sources */,
                                B2227A800D00BF220071B782 /* SVGPathSegList.cpp in Sources */,
                                8476C9E511DF6A0B00555B02 /* SVGPathSegListBuilder.cpp in Sources */,
+                               CDF2B0181820540700F2B424 /* MockTracks.cpp in Sources */,
                                08FF102012950F5A00F00276 /* SVGPathSegListPropertyTearOff.cpp in Sources */,
                                84B6B977120F13E500B8EFAF /* SVGPathSegListSource.cpp in Sources */,
                                8419D2B9120E0C7600141F8F /* SVGPathStringBuilder.cpp in Sources */,
index 565a159..d1694a8 100644 (file)
@@ -1437,8 +1437,8 @@ void HTMLMediaElement::audioTrackEnabledChanged(AudioTrack* track)
 {
     if (!RuntimeEnabledFeatures::sharedFeatures().webkitVideoTrackEnabled())
         return;
-    ASSERT_UNUSED(track, m_audioTracks->contains(track));
-    m_audioTracks->scheduleChangeEvent();
+    if (m_audioTracks && m_audioTracks->contains(track))
+        m_audioTracks->scheduleChangeEvent();
 }
 
 void HTMLMediaElement::textTrackModeChanged(TextTrack* track)
@@ -1478,8 +1478,8 @@ void HTMLMediaElement::videoTrackSelectedChanged(VideoTrack* track)
 {
     if (!RuntimeEnabledFeatures::sharedFeatures().webkitVideoTrackEnabled())
         return;
-    ASSERT_UNUSED(track, m_videoTracks->contains(track));
-    m_videoTracks->scheduleChangeEvent();
+    if (m_videoTracks && m_videoTracks->contains(track))
+        m_videoTracks->scheduleChangeEvent();
 }
 
 void HTMLMediaElement::textTrackKindChanged(TextTrack* track)
index 6ec71c8..d64ab34 100644 (file)
@@ -1215,6 +1215,11 @@ size_t MediaPlayer::extraMemoryCost() const
     return m_private->extraMemoryCost();
 }
 
+void MediaPlayerFactorySupport::callRegisterMediaEngine(MediaEngineRegister registerMediaEngine)
+{
+    registerMediaEngine(addMediaEngine);
+}
+
 }
 
 #endif
index 2d823bd..5b221bb 100644 (file)
@@ -549,6 +549,12 @@ typedef void (*MediaEngineClearMediaCacheForSite)(const String&);
 
 typedef void (*MediaEngineRegistrar)(CreateMediaEnginePlayer, MediaEngineSupportedTypes, MediaEngineSupportsType,
     MediaEngineGetSitesInMediaCache, MediaEngineClearMediaCache, MediaEngineClearMediaCacheForSite);
+typedef void (*MediaEngineRegister)(MediaEngineRegistrar);
+
+class MediaPlayerFactorySupport {
+public:
+    static void callRegisterMediaEngine(MediaEngineRegister);
+};
 
 }
 
diff --git a/Source/WebCore/platform/mock/mediasource/MockBox.cpp b/Source/WebCore/platform/mock/mediasource/MockBox.cpp
new file mode 100644 (file)
index 0000000..286e81b
--- /dev/null
@@ -0,0 +1,141 @@
+/*
+ * Copyright (C) 2013 Apple 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:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``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 APPLE COMPUTER, INC. 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 "MockBox.h"
+
+#if ENABLE(MEDIA_SOURCE)
+
+#include <runtime/ArrayBuffer.h>
+#include <runtime/DataView.h>
+#include <runtime/Int8Array.h>
+#include <wtf/text/StringBuilder.h>
+
+namespace WebCore {
+
+MockBox::MockBox(ArrayBuffer* data)
+{
+    m_type = peekType(data);
+    m_length = peekLength(data);
+    ASSERT(m_length >= 8);
+}
+
+String MockBox::peekType(ArrayBuffer* data)
+{
+    StringBuilder builder;
+    RefPtr<Int8Array> array = JSC::Int8Array::create(data, 0, 4);
+    for (int i = 0; i < 4; ++i)
+        builder.append(array->item(i));
+    return builder.toString();
+}
+
+size_t MockBox::peekLength(ArrayBuffer* data)
+{
+    RefPtr<JSC::DataView> view = JSC::DataView::create(data, 0, data->byteLength());
+    return view->get<uint32_t>(4, true);
+}
+
+MockTrackBox::MockTrackBox(ArrayBuffer* data)
+    : MockBox(data)
+{
+    ASSERT(m_length == 17);
+
+    RefPtr<JSC::DataView> view = JSC::DataView::create(data, 0, data->byteLength());
+    m_trackID = view->get<int32_t>(8, true);
+
+    StringBuilder builder;
+    RefPtr<Int8Array> array = JSC::Int8Array::create(data, 12, 4);
+    for (int i = 0; i < 4; ++i)
+        builder.append(array->item(i));
+    m_codec = builder.toString();
+
+    m_kind = static_cast<TrackKind>(view->get<uint8_t>(16, true));
+}
+
+const String& MockTrackBox::type()
+{
+    DEFINE_STATIC_LOCAL(String, trak, (ASCIILiteral("trak")));
+    return trak;
+}
+
+MockInitializationBox::MockInitializationBox(ArrayBuffer* data)
+    : MockBox(data)
+{
+    ASSERT(m_length >= 13);
+
+    RefPtr<JSC::DataView> view = JSC::DataView::create(data, 0, data->byteLength());
+    int32_t timeValue = view->get<int32_t>(8, true);
+    int32_t timeScale = view->get<int32_t>(12, true);
+    m_duration = MediaTime(timeValue, timeScale);
+    
+    size_t offset = 16;
+
+    while (offset < m_length) {
+        RefPtr<ArrayBuffer> subBuffer = data->slice(offset);
+        if (MockBox::peekType(subBuffer.get()) != MockTrackBox::type())
+            break;
+
+        MockTrackBox trackBox(subBuffer.get());
+        offset += trackBox.length();
+        m_tracks.append(trackBox);
+    }
+}
+
+const String& MockInitializationBox::type()
+{
+    DEFINE_STATIC_LOCAL(String, init, (ASCIILiteral("init")));
+    return init;
+}
+
+MockSampleBox::MockSampleBox(ArrayBuffer* data)
+    : MockBox(data)
+{
+    ASSERT(m_length == 29);
+
+    RefPtr<JSC::DataView> view = JSC::DataView::create(data, 0, data->byteLength());
+    int32_t timeScale = view->get<int32_t>(8, true);
+
+    int32_t timeValue = view->get<int32_t>(12, true);
+    m_presentationTimestamp = MediaTime(timeValue, timeScale);
+
+    timeValue = view->get<int32_t>(16, true);
+    m_decodeTimestamp = MediaTime(timeValue, timeScale);
+
+    timeValue = view->get<int32_t>(20, true);
+    m_duration = MediaTime(timeValue, timeScale);
+
+    m_trackID = view->get<int32_t>(24, true);
+    m_flags = view->get<uint8_t>(28, true);
+}
+
+const String& MockSampleBox::type()
+{
+    DEFINE_STATIC_LOCAL(String, smpl, (ASCIILiteral("smpl")));
+    return smpl;
+}
+
+}
+
+#endif
diff --git a/Source/WebCore/platform/mock/mediasource/MockBox.h b/Source/WebCore/platform/mock/mediasource/MockBox.h
new file mode 100644 (file)
index 0000000..3f0c0d3
--- /dev/null
@@ -0,0 +1,147 @@
+/*
+ * Copyright (C) 2013 Apple 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:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``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 APPLE COMPUTER, INC. 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 MockBox_h
+#define MockBox_h
+
+#if ENABLE(MEDIA_SOURCE)
+
+#include <wtf/MediaTime.h>
+#include <wtf/text/WTFString.h>
+
+namespace JSC {
+class ArrayBuffer;
+}
+
+namespace WebCore {
+
+// A MockBox represents a ISO-BMFF like data structure. Data in the
+// structure is little-endian. The layout of the data structure as follows:
+//
+// 4 bytes : 4CC : identifier
+// 4 bytes : unsigned : length
+// 
+class MockBox {
+public:
+    static String peekType(JSC::ArrayBuffer*);
+    static size_t peekLength(JSC::ArrayBuffer*);
+
+    size_t length() const { return m_length; }
+    const String& type() const { return m_type; }
+
+protected:
+    MockBox(JSC::ArrayBuffer*);
+
+    size_t m_length;
+    String m_type;
+};
+
+// A MockTrackBox extends MockBox and expects the following
+// data structure:
+//
+// 4 bytes : 4CC : identifier = 'trak'
+// 4 bytes : unsigned : length = 17
+// 4 bytes : signed : track ID
+// 4 bytes : 4CC : codec
+// 1 byte  : unsigned : kind
+// 
+class MockTrackBox FINAL : public MockBox {
+public:
+    static const String& type();
+    MockTrackBox(JSC::ArrayBuffer*);
+
+    int32_t trackID() const { return m_trackID; }
+
+    const String& codec() const { return m_codec; }
+
+    enum TrackKind { Audio, Video, Text };
+    TrackKind kind() const { return m_kind; }
+
+protected:
+    uint8_t m_trackID;
+    String m_codec;
+    TrackKind m_kind;
+};
+
+// A MockInitializationBox extends MockBox and contains 0 or more
+// MockTrackBoxes. It expects the following data structure:
+//
+// 4 bytes : 4CC : identifier = 'init'
+// 4 bytes : unsigned : length = 16 + (13 * num tracks)
+// 4 bytes : signed : duration time value
+// 4 bytes : signed : duration time scale
+// N bytes : MockTrackBoxes : tracks
+//
+class MockInitializationBox FINAL : public MockBox {
+public:
+    static const String& type();
+    MockInitializationBox(JSC::ArrayBuffer*);
+
+    MediaTime duration() const { return m_duration; }
+    const Vector<MockTrackBox>& tracks() const { return m_tracks; }
+
+protected:
+    MediaTime m_duration;
+    Vector<MockTrackBox> m_tracks;
+};
+
+// A MockSampleBox extends MockBox and expects the following data structure:
+//
+// 4 bytes : 4CC : identifier = 'smpl'
+// 4 bytes : unsigned : length = 29
+// 4 bytes : signed : time scale
+// 4 bytes : signed : presentation time value
+// 4 bytes : signed : decode time value
+// 4 bytes : signed : duration time value
+// 4 bytes : signed : track ID
+// 1 byte  : unsigned : flags
+//
+class MockSampleBox FINAL : public MockBox {
+public:
+    static const String& type();
+    MockSampleBox(JSC::ArrayBuffer*);
+
+    MediaTime presentationTimestamp() const { return m_presentationTimestamp; }
+    MediaTime decodeTimestamp() const { return m_decodeTimestamp; }
+    MediaTime duration() const { return m_duration; }
+    int32_t trackID() const { return m_trackID; }
+    uint8_t flags() const { return m_flags; }
+
+    enum { IsSync = 1 << 0 };
+    bool isSync() const { return m_flags & IsSync; }
+
+protected:
+    MediaTime m_presentationTimestamp;
+    MediaTime m_decodeTimestamp;
+    MediaTime m_duration;
+    int32_t m_trackID;
+    uint8_t m_flags;
+};
+
+}
+
+#endif
+
+#endif
diff --git a/Source/WebCore/platform/mock/mediasource/MockMediaPlayerMediaSource.cpp b/Source/WebCore/platform/mock/mediasource/MockMediaPlayerMediaSource.cpp
new file mode 100644 (file)
index 0000000..d6fdf14
--- /dev/null
@@ -0,0 +1,232 @@
+/*
+ * Copyright (C) 2013 Apple 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:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``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 APPLE COMPUTER, INC. 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 "MockMediaPlayerMediaSource.h"
+
+#if ENABLE(MEDIA_SOURCE)
+
+#include "ExceptionCodePlaceholder.h"
+#include "HTMLMediaSource.h"
+#include "MediaPlayer.h"
+#include "MockMediaSourcePrivate.h"
+#include <wtf/Functional.h>
+#include <wtf/MainThread.h>
+#include <wtf/text/WTFString.h>
+
+namespace WebCore {
+
+// MediaPlayer Enigne Support
+void MockMediaPlayerMediaSource::registerMediaEngine(MediaEngineRegistrar registrar)
+{
+    registrar(create, getSupportedTypes, supportsType, 0, 0, 0);
+}
+
+PassOwnPtr<MediaPlayerPrivateInterface> MockMediaPlayerMediaSource::create(MediaPlayer* player)
+{
+    return adoptPtr(new MockMediaPlayerMediaSource(player));
+}
+
+static HashSet<String> mimeTypeCache()
+{
+    DEFINE_STATIC_LOCAL(HashSet<String>, cache, ());
+    static bool isInitialized = false;
+
+    if (!isInitialized) {
+        isInitialized = true;
+        cache.add(ASCIILiteral("video/mock"));
+    }
+
+    return cache;
+}
+
+void MockMediaPlayerMediaSource::getSupportedTypes(HashSet<String>& supportedTypes)
+{
+    supportedTypes = mimeTypeCache();
+}
+
+MediaPlayer::SupportsType MockMediaPlayerMediaSource::supportsType(const MediaEngineSupportParameters& parameters)
+{
+    if (!parameters.isMediaSource)
+        return MediaPlayer::IsNotSupported;
+
+    if (!mimeTypeCache().contains(parameters.type))
+        return MediaPlayer::IsNotSupported;
+
+    if (parameters.codecs.isEmpty())
+        return MediaPlayer::MayBeSupported;
+
+    return parameters.codecs == "mock" ? MediaPlayer::IsSupported : MediaPlayer::MayBeSupported;
+}
+
+MockMediaPlayerMediaSource::MockMediaPlayerMediaSource(MediaPlayer* player)
+    : m_player(player)
+    , m_currentTime(0)
+    , m_duration(0)
+    , m_readyState(MediaPlayer::HaveNothing)
+    , m_networkState(MediaPlayer::Empty)
+    , m_playing(false)
+{
+}
+
+MockMediaPlayerMediaSource::~MockMediaPlayerMediaSource()
+{
+}
+
+void MockMediaPlayerMediaSource::load(const String&)
+{
+    ASSERT_NOT_REACHED();
+}
+
+void MockMediaPlayerMediaSource::load(const String&, PassRefPtr<HTMLMediaSource> source)
+{
+    m_mediaSource = source;
+    m_mediaSourcePrivate = MockMediaSourcePrivate::create(this);
+    m_mediaSource->setPrivateAndOpen(*m_mediaSourcePrivate);
+}
+
+void MockMediaPlayerMediaSource::cancelLoad()
+{
+}
+
+void MockMediaPlayerMediaSource::play()
+{
+    m_playing = 1;
+    callOnMainThread(bind(&MockMediaPlayerMediaSource::advanceCurrentTime, this));
+}
+
+void MockMediaPlayerMediaSource::pause()
+{
+    m_playing = 0;
+}
+
+IntSize MockMediaPlayerMediaSource::naturalSize() const
+{
+    return IntSize();
+}
+
+bool MockMediaPlayerMediaSource::hasVideo() const
+{
+    return m_mediaSourcePrivate ? m_mediaSourcePrivate->hasVideo() : false;
+}
+
+bool MockMediaPlayerMediaSource::hasAudio() const
+{
+    return m_mediaSourcePrivate ? m_mediaSourcePrivate->hasAudio() : false;
+}
+
+void MockMediaPlayerMediaSource::setVisible(bool)
+{
+}
+
+bool MockMediaPlayerMediaSource::seeking() const
+{
+    return false;
+}
+
+bool MockMediaPlayerMediaSource::paused() const
+{
+    return !m_playing;
+}
+
+MediaPlayer::NetworkState MockMediaPlayerMediaSource::networkState() const
+{
+    return m_networkState;
+}
+
+MediaPlayer::ReadyState MockMediaPlayerMediaSource::readyState() const
+{
+    return m_readyState;
+}
+
+PassRefPtr<TimeRanges> MockMediaPlayerMediaSource::buffered() const
+{
+    return m_mediaSource ? m_mediaSource->buffered() : TimeRanges::create();
+}
+
+bool MockMediaPlayerMediaSource::didLoadingProgress() const
+{
+    return false;
+}
+
+void MockMediaPlayerMediaSource::setSize(const IntSize&)
+{
+}
+
+void MockMediaPlayerMediaSource::paint(GraphicsContext*, const IntRect&)
+{
+}
+
+double MockMediaPlayerMediaSource::currentTimeDouble() const
+{
+    return m_currentTime;
+}
+
+double MockMediaPlayerMediaSource::durationDouble() const
+{
+    return m_duration;
+}
+
+void MockMediaPlayerMediaSource::seekDouble(double time)
+{
+    m_currentTime = std::min(time, m_duration);
+    m_player->timeChanged();
+
+    if (m_playing)
+        callOnMainThread(bind(&MockMediaPlayerMediaSource::advanceCurrentTime, this));
+}
+
+void MockMediaPlayerMediaSource::advanceCurrentTime()
+{
+    RefPtr<TimeRanges> buffered = this->buffered();
+    size_t pos = buffered->find(m_currentTime);
+    if (pos == notFound)
+        return;
+
+    m_currentTime = std::min(m_duration, buffered->end(pos, IGNORE_EXCEPTION));
+    m_player->timeChanged();
+}
+
+void MockMediaPlayerMediaSource::updateDuration(double duration)
+{
+    if (m_duration == duration)
+        return;
+
+    m_duration = duration;
+    m_player->durationChanged();
+}
+
+void MockMediaPlayerMediaSource::setReadyState(MediaPlayer::ReadyState readyState)
+{
+    if (readyState == m_readyState)
+        return;
+
+    m_readyState = readyState;
+    m_player->readyStateChanged();
+}
+
+}
+
+#endif
diff --git a/Source/WebCore/platform/mock/mediasource/MockMediaPlayerMediaSource.h b/Source/WebCore/platform/mock/mediasource/MockMediaPlayerMediaSource.h
new file mode 100644 (file)
index 0000000..b067d8b
--- /dev/null
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2013 Apple 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:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``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 APPLE COMPUTER, INC. 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 MockMediaPlayerMediaSource_h
+#define MockMediaPlayerMediaSource_h
+
+#if ENABLE(MEDIA_SOURCE)
+
+#include "MediaPlayerPrivate.h"
+
+namespace WebCore {
+
+class MediaSource;
+class MockMediaSourcePrivate;
+
+class MockMediaPlayerMediaSource : public MediaPlayerPrivateInterface {
+public:
+    // MediaPlayer Engine Support
+    static void registerMediaEngine(MediaEngineRegistrar);
+    static PassOwnPtr<MediaPlayerPrivateInterface> create(MediaPlayer*);
+    static void getSupportedTypes(HashSet<String>& types);
+    static MediaPlayer::SupportsType supportsType(const MediaEngineSupportParameters&);
+
+    virtual ~MockMediaPlayerMediaSource();
+
+    void advanceCurrentTime();
+    void updateDuration(double);
+
+    virtual MediaPlayer::ReadyState readyState() const OVERRIDE;
+    void setReadyState(MediaPlayer::ReadyState);
+
+private:
+    MockMediaPlayerMediaSource(MediaPlayer*);
+
+    // MediaPlayerPrivate Overrides
+    virtual void load(const String& url) OVERRIDE;
+    virtual void load(const String& url, PassRefPtr<HTMLMediaSource>) OVERRIDE;
+    virtual void cancelLoad() OVERRIDE;
+    virtual void play() OVERRIDE;
+    virtual void pause() OVERRIDE;
+    virtual IntSize naturalSize() const OVERRIDE;
+    virtual bool hasVideo() const OVERRIDE;
+    virtual bool hasAudio() const OVERRIDE;
+    virtual void setVisible(bool) OVERRIDE;
+    virtual bool seeking() const OVERRIDE;
+    virtual bool paused() const OVERRIDE;
+    virtual MediaPlayer::NetworkState networkState() const OVERRIDE;
+    virtual PassRefPtr<TimeRanges> buffered() const OVERRIDE;
+    virtual bool didLoadingProgress() const OVERRIDE;
+    virtual void setSize(const IntSize&) OVERRIDE;
+    virtual void paint(GraphicsContext*, const IntRect&) OVERRIDE;
+    virtual double currentTimeDouble() const OVERRIDE;
+    virtual double durationDouble() const OVERRIDE;
+    virtual void seekDouble(double time) OVERRIDE;
+
+    MediaPlayer* m_player;
+    RefPtr<HTMLMediaSource> m_mediaSource;
+    RefPtr<MockMediaSourcePrivate> m_mediaSourcePrivate;
+
+    double m_currentTime;
+    double m_duration;
+    MediaPlayer::ReadyState m_readyState;
+    MediaPlayer::NetworkState m_networkState;
+    bool m_playing;
+};
+
+}
+
+#endif // ENABLE(MEDIA_SOURCE)
+
+#endif // MockMediaPlayerMediaSource_h
+
diff --git a/Source/WebCore/platform/mock/mediasource/MockMediaSourcePrivate.cpp b/Source/WebCore/platform/mock/mediasource/MockMediaSourcePrivate.cpp
new file mode 100644 (file)
index 0000000..be148f5
--- /dev/null
@@ -0,0 +1,151 @@
+/*
+ * Copyright (C) 2013 Apple 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:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``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 APPLE COMPUTER, INC. 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 "MockMediaSourcePrivate.h"
+
+#if ENABLE(MEDIA_SOURCE)
+
+#include "ContentType.h"
+#include "ExceptionCodePlaceholder.h"
+#include "MockMediaPlayerMediaSource.h"
+#include "MockSourceBufferPrivate.h"
+
+namespace WebCore {
+
+RefPtr<MockMediaSourcePrivate> MockMediaSourcePrivate::create(MockMediaPlayerMediaSource* parent)
+{
+    return adoptRef(new MockMediaSourcePrivate(parent));
+}
+
+MockMediaSourcePrivate::MockMediaSourcePrivate(MockMediaPlayerMediaSource* parent)
+    : m_player(parent)
+    , m_duration(0)
+    , m_isEnded(false)
+{
+}
+
+MockMediaSourcePrivate::~MockMediaSourcePrivate()
+{
+}
+
+MediaSourcePrivate::AddStatus MockMediaSourcePrivate::addSourceBuffer(const ContentType& contentType, RefPtr<SourceBufferPrivate>& outPrivate)
+{
+    MediaEngineSupportParameters parameters;
+    parameters.isMediaSource = true;
+    parameters.type = contentType.type();
+    parameters.codecs = contentType.parameter(ASCIILiteral("codecs"));
+    if (MockMediaPlayerMediaSource::supportsType(parameters) == MediaPlayer::IsNotSupported)
+        return NotSupported;
+
+    m_sourceBuffers.append(MockSourceBufferPrivate::create(this));
+    outPrivate = m_sourceBuffers.last();
+
+    return Ok;
+}
+
+void MockMediaSourcePrivate::removeSourceBuffer(SourceBufferPrivate* buffer)
+{
+    ASSERT(m_sourceBuffers.contains(buffer));
+
+    size_t pos = m_activeSourceBuffers.find(buffer);
+    if (pos != notFound)
+        m_activeSourceBuffers.remove(pos);
+
+    pos = m_sourceBuffers.find(buffer);
+    m_sourceBuffers.remove(pos);
+}
+
+double MockMediaSourcePrivate::duration()
+{
+    return m_duration;
+}
+
+void MockMediaSourcePrivate::setDuration(double duration)
+{
+    if (duration == m_duration)
+        return;
+
+    m_duration = duration;
+    m_player->updateDuration(duration);
+}
+
+void MockMediaSourcePrivate::markEndOfStream(EndOfStreamStatus status)
+{
+    UNUSED_PARAM(status);
+    m_isEnded = true;
+}
+
+void MockMediaSourcePrivate::unmarkEndOfStream()
+{
+    m_isEnded = false;
+}
+
+MediaPlayer::ReadyState MockMediaSourcePrivate::readyState() const
+{
+    return m_player->readyState();
+}
+
+void MockMediaSourcePrivate::setReadyState(MediaPlayer::ReadyState readyState)
+{
+    m_player->setReadyState(readyState);
+}
+
+void MockMediaSourcePrivate::sourceBufferPrivateDidChangeActiveState(MockSourceBufferPrivate* buffer, bool active)
+{
+    if (active && !m_activeSourceBuffers.contains(buffer))
+        m_activeSourceBuffers.append(buffer);
+
+    if (!active) {
+        size_t position = m_activeSourceBuffers.find(buffer);
+        if (position != notFound)
+            m_activeSourceBuffers.remove(position);
+    }
+}
+
+static bool MockSourceBufferPrivateHasAudio(PassRefPtr<MockSourceBufferPrivate> prpSourceBuffer)
+{
+    return prpSourceBuffer->hasAudio();
+}
+
+bool MockMediaSourcePrivate::hasAudio() const
+{
+    return std::any_of(m_activeSourceBuffers.begin(), m_activeSourceBuffers.end(), MockSourceBufferPrivateHasAudio);
+}
+
+static bool MockSourceBufferPrivateHasVideo(PassRefPtr<MockSourceBufferPrivate> prpSourceBuffer)
+{
+    return prpSourceBuffer->hasVideo();
+}
+
+bool MockMediaSourcePrivate::hasVideo() const
+{
+    return std::any_of(m_activeSourceBuffers.begin(), m_activeSourceBuffers.end(), MockSourceBufferPrivateHasVideo);
+}
+
+};
+
+#endif
+
diff --git a/Source/WebCore/platform/mock/mediasource/MockMediaSourcePrivate.h b/Source/WebCore/platform/mock/mediasource/MockMediaSourcePrivate.h
new file mode 100644 (file)
index 0000000..d640dd6
--- /dev/null
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2013 Apple 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:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``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 APPLE COMPUTER, INC. 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 MockMediaSourcePrivate_h
+#define MockMediaSourcePrivate_h
+
+#if ENABLE(MEDIA_SOURCE)
+
+#include "MediaSourcePrivate.h"
+
+namespace WebCore {
+
+class MockMediaPlayerMediaSource;
+class MockSourceBufferPrivate;
+class TimeRanges;
+
+class MockMediaSourcePrivate FINAL : public MediaSourcePrivate {
+public:
+    static RefPtr<MockMediaSourcePrivate> create(MockMediaPlayerMediaSource*);
+    virtual ~MockMediaSourcePrivate();
+
+    const Vector<MockSourceBufferPrivate*>& activeSourceBuffers() const { return m_activeSourceBuffers; }
+
+    bool hasAudio() const;
+    bool hasVideo() const;
+
+    MockMediaPlayerMediaSource* player() const { return m_player; }
+
+private:
+    MockMediaSourcePrivate(MockMediaPlayerMediaSource*);
+
+    // MediaSourcePrivate Overrides
+    virtual AddStatus addSourceBuffer(const ContentType&, RefPtr<SourceBufferPrivate>&) OVERRIDE;
+    virtual double duration() OVERRIDE;
+    virtual void setDuration(double) OVERRIDE;
+    virtual void markEndOfStream(EndOfStreamStatus) OVERRIDE;
+    virtual void unmarkEndOfStream() OVERRIDE;
+    virtual MediaPlayer::ReadyState readyState() const OVERRIDE;
+    virtual void setReadyState(MediaPlayer::ReadyState) OVERRIDE;
+
+    void sourceBufferPrivateDidChangeActiveState(MockSourceBufferPrivate*, bool active);
+    void removeSourceBuffer(SourceBufferPrivate*);
+
+    friend class MockSourceBufferPrivate;
+
+    MockMediaPlayerMediaSource* m_player;
+    double m_duration;
+    Vector<RefPtr<MockSourceBufferPrivate>> m_sourceBuffers;
+    Vector<MockSourceBufferPrivate*> m_activeSourceBuffers;
+    bool m_isEnded;
+};
+
+}
+
+#endif // ENABLE(MEDIA_SOURCE)
+
+#endif // MockMediaSourcePrivate_h
+
diff --git a/Source/WebCore/platform/mock/mediasource/MockSourceBufferPrivate.cpp b/Source/WebCore/platform/mock/mediasource/MockSourceBufferPrivate.cpp
new file mode 100644 (file)
index 0000000..2c386dc
--- /dev/null
@@ -0,0 +1,212 @@
+/*
+ * Copyright (C) 2013 Apple 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:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``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 APPLE COMPUTER, INC. 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 "MockSourceBufferPrivate.h"
+
+#if ENABLE(MEDIA_SOURCE)
+
+#include "MediaDescription.h"
+#include "MediaPlayer.h"
+#include "MediaSample.h"
+#include "MockBox.h"
+#include "MockMediaPlayerMediaSource.h"
+#include "MockMediaSourcePrivate.h"
+#include "MockTracks.h"
+#include "SourceBufferPrivateClient.h"
+#include <map>
+#include <runtime/ArrayBuffer.h>
+
+namespace WebCore {
+
+class MockMediaSample FINAL : public MediaSample {
+public:
+    static RefPtr<MockMediaSample> create(const MockSampleBox& box) { return adoptRef(new MockMediaSample(box)); }
+    virtual ~MockMediaSample() { }
+
+    virtual MediaTime presentationTime() const OVERRIDE { return m_box.presentationTimestamp(); }
+    virtual MediaTime decodeTime() const OVERRIDE { return m_box.decodeTimestamp(); }
+    virtual MediaTime duration() const OVERRIDE { return m_box.duration(); }
+    virtual AtomicString trackID() const OVERRIDE { return m_id; }
+
+    virtual SampleFlags flags() const OVERRIDE { return None; }
+    virtual PlatformSample platformSample() OVERRIDE;
+
+protected:
+    MockMediaSample(const MockSampleBox& box)
+        : m_box(box)
+        , m_id(String::format("%d", box.trackID()))
+    {
+    }
+
+    MockSampleBox m_box;
+    AtomicString m_id;
+};
+
+PlatformSample MockMediaSample::platformSample()
+{
+    PlatformSample sample = { PlatformSample::MockSampleBoxType, { &m_box } };
+    return sample;
+}
+
+class MockMediaDescription FINAL : public MediaDescription {
+public:
+    static RefPtr<MockMediaDescription> create(const MockTrackBox& box) { return adoptRef(new MockMediaDescription(box)); }
+    virtual ~MockMediaDescription() { }
+
+    virtual AtomicString codec() const OVERRIDE { return m_box.codec(); }
+    virtual bool isVideo() const OVERRIDE { return m_box.kind() == MockTrackBox::Video; }
+    virtual bool isAudio() const OVERRIDE { return m_box.kind() == MockTrackBox::Audio; }
+    virtual bool isText() const OVERRIDE { return m_box.kind() == MockTrackBox::Text; }
+
+protected:
+    MockMediaDescription(const MockTrackBox& box) : m_box(box) { }
+    MockTrackBox m_box;
+};
+
+RefPtr<MockSourceBufferPrivate> MockSourceBufferPrivate::create(MockMediaSourcePrivate* parent)
+{
+    return adoptRef(new MockSourceBufferPrivate(parent));
+}
+
+MockSourceBufferPrivate::MockSourceBufferPrivate(MockMediaSourcePrivate* parent)
+    : m_parent(parent)
+    , m_client(0)
+{
+}
+
+MockSourceBufferPrivate::~MockSourceBufferPrivate()
+{
+}
+
+void MockSourceBufferPrivate::setClient(SourceBufferPrivateClient* client)
+{
+    m_client = client;
+}
+
+void MockSourceBufferPrivate::append(const unsigned char* data, unsigned length)
+{
+    m_inputBuffer.append(data, length);
+
+    while (m_inputBuffer.size()) {
+        RefPtr<ArrayBuffer> buffer = ArrayBuffer::create(m_inputBuffer.data(), m_inputBuffer.size());
+        size_t boxLength = MockBox::peekLength(buffer.get());
+        if (boxLength > buffer->byteLength())
+            break;
+
+        String type = MockBox::peekType(buffer.get());
+        if (type == MockInitializationBox::type()) {
+            MockInitializationBox initBox = MockInitializationBox(buffer.get());
+            didReceiveInitializationSegment(initBox);
+        }
+
+        if (type == MockSampleBox::type()) {
+            MockSampleBox sampleBox = MockSampleBox(buffer.get());
+            didReceiveSample(sampleBox);
+        }
+
+        m_inputBuffer.remove(0, boxLength);
+    }
+}
+
+void MockSourceBufferPrivate::didReceiveInitializationSegment(const MockInitializationBox& initBox)
+{
+    if (!m_client)
+        return;
+
+    SourceBufferPrivateClient::InitializationSegment segment;
+    segment.duration = initBox.duration();
+
+    for (auto it = initBox.tracks().begin(); it != initBox.tracks().end(); ++it) {
+        const MockTrackBox& trackBox = *it;
+        if (trackBox.kind() == MockTrackBox::Video) {
+            SourceBufferPrivateClient::InitializationSegment::VideoTrackInformation info;
+            info.track = MockVideoTrackPrivate::create(trackBox);
+            info.description = MockMediaDescription::create(trackBox);
+            segment.videoTracks.append(info);
+        } else if (trackBox.kind() == MockTrackBox::Audio) {
+            SourceBufferPrivateClient::InitializationSegment::AudioTrackInformation info;
+            info.track = MockAudioTrackPrivate::create(trackBox);
+            info.description = MockMediaDescription::create(trackBox);
+            segment.audioTracks.append(info);
+        } else if (trackBox.kind() == MockTrackBox::Text) {
+            SourceBufferPrivateClient::InitializationSegment::TextTrackInformation info;
+            info.track = MockTextTrackPrivate::create(trackBox);
+            info.description = MockMediaDescription::create(trackBox);
+            segment.textTracks.append(info);
+        }
+    }
+
+    m_client->sourceBufferPrivateDidReceiveInitializationSegment(this, segment);
+}
+
+
+void MockSourceBufferPrivate::didReceiveSample(const MockSampleBox& sampleBox)
+{
+    if (!m_client)
+        return;
+
+    m_client->sourceBufferPrivateDidReceiveSample(this, MockMediaSample::create(sampleBox));
+}
+
+void MockSourceBufferPrivate::abort()
+{
+}
+
+void MockSourceBufferPrivate::removedFromMediaSource()
+{
+    m_parent->removeSourceBuffer(this);
+}
+
+MediaPlayer::ReadyState MockSourceBufferPrivate::readyState() const
+{
+    return m_parent->player()->readyState();
+}
+
+void MockSourceBufferPrivate::setReadyState(MediaPlayer::ReadyState readyState)
+{
+    m_parent->player()->setReadyState(readyState);
+}
+
+bool MockSourceBufferPrivate::hasVideo() const
+{
+    if (!m_client)
+        return false;
+
+    return m_client->sourceBufferPrivateHasVideo(this);
+}
+
+bool MockSourceBufferPrivate::hasAudio() const
+{
+    if (!m_client)
+        return false;
+
+    return m_client->sourceBufferPrivateHasAudio(this);
+}
+
+}
+
+#endif
+
diff --git a/Source/WebCore/platform/mock/mediasource/MockSourceBufferPrivate.h b/Source/WebCore/platform/mock/mediasource/MockSourceBufferPrivate.h
new file mode 100644 (file)
index 0000000..256bbf9
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2013 Apple 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:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``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 APPLE COMPUTER, INC. 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 MockSourceBufferPrivate_h
+#define MockSourceBufferPrivate_h
+
+#if ENABLE(MEDIA_SOURCE)
+
+#include "SourceBufferPrivate.h"
+#include <wtf/HashMap.h>
+#include <wtf/MediaTime.h>
+#include <wtf/RefPtr.h>
+#include <wtf/RetainPtr.h>
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+class AudioTrackPrivate;
+class InbandTextTrackPrivate;
+class MockInitializationBox;
+class MockMediaSourcePrivate;
+class MockSampleBox;
+class TimeRanges;
+class VideoTrackPrivate;
+
+class MockSourceBufferPrivate : public SourceBufferPrivate {
+public:
+    static RefPtr<MockSourceBufferPrivate> create(MockMediaSourcePrivate*);
+    virtual ~MockSourceBufferPrivate();
+
+    bool hasVideo() const;
+    bool hasAudio() const;
+
+private:
+    explicit MockSourceBufferPrivate(MockMediaSourcePrivate*);
+
+    // SourceBufferPrivate overrides
+    virtual void setClient(SourceBufferPrivateClient*) OVERRIDE;
+    virtual void 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;
+
+    void didReceiveInitializationSegment(const MockInitializationBox&);
+    void didReceiveSample(const MockSampleBox&);
+
+    MockMediaSourcePrivate* m_parent;
+    SourceBufferPrivateClient* m_client;
+
+    Vector<char> m_inputBuffer;
+};
+
+}
+
+#endif // ENABLE(MEDIA_SOURCE) && USE(AVFOUNDATION)
+
+#endif
+
diff --git a/Source/WebCore/platform/mock/mediasource/MockTracks.cpp b/Source/WebCore/platform/mock/mediasource/MockTracks.cpp
new file mode 100644 (file)
index 0000000..8f8840d
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2013 Apple 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:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``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 APPLE COMPUTER, INC. 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 "MockTracks.h"
diff --git a/Source/WebCore/platform/mock/mediasource/MockTracks.h b/Source/WebCore/platform/mock/mediasource/MockTracks.h
new file mode 100644 (file)
index 0000000..3f8eded
--- /dev/null
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2013 Apple 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:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``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 APPLE COMPUTER, INC. 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 MockTracks_h
+#define MockTracks_h
+
+#if ENABLE(MEDIA_SOURCE)
+
+#include "AudioTrackPrivate.h"
+#include "InbandTextTrackPrivate.h"
+#include "MockBox.h"
+#include "VideoTrackPrivate.h"
+
+namespace WebCore {
+
+class MockAudioTrackPrivate : public AudioTrackPrivate {
+public:
+    static RefPtr<MockAudioTrackPrivate> create(const MockTrackBox& box) { return adoptRef(new MockAudioTrackPrivate(box)); }
+    virtual ~MockAudioTrackPrivate() { }
+
+    virtual AtomicString id() const { return m_id; }
+
+protected:
+    MockAudioTrackPrivate(const MockTrackBox& box)
+        : m_box(box)
+        , m_id(String::format("%d", box.trackID()))
+    {
+    }
+    MockTrackBox m_box;
+    AtomicString m_id;
+};
+
+class MockTextTrackPrivate : public InbandTextTrackPrivate {
+public:
+    static RefPtr<MockTextTrackPrivate> create(const MockTrackBox& box) { return adoptRef(new MockTextTrackPrivate(box)); }
+    virtual ~MockTextTrackPrivate() { }
+
+    virtual AtomicString id() const { return m_id; }
+
+protected:
+    MockTextTrackPrivate(const MockTrackBox& box)
+        : InbandTextTrackPrivate(InbandTextTrackPrivate::Generic)
+        , m_box(box)
+        , m_id(String::format("%d", box.trackID()))
+    {
+    }
+    MockTrackBox m_box;
+    AtomicString m_id;
+};
+
+
+class MockVideoTrackPrivate : public VideoTrackPrivate {
+public:
+    static RefPtr<MockVideoTrackPrivate> create(const MockTrackBox& box) { return adoptRef(new MockVideoTrackPrivate(box)); }
+    virtual ~MockVideoTrackPrivate() { }
+
+    virtual AtomicString id() const { return m_id; }
+
+protected:
+    MockVideoTrackPrivate(const MockTrackBox& box)
+        : m_box(box)
+        , m_id(String::format("%d", box.trackID()))
+    {
+    }
+    MockTrackBox m_box;
+    AtomicString m_id;
+};
+
+}
+
+#endif
+
+#endif
index efbb81d..e3af0f0 100644 (file)
@@ -70,6 +70,7 @@
 #include "Language.h"
 #include "MainFrame.h"
 #include "MallocStatistics.h"
+#include "MediaPlayer.h"
 #include "MemoryCache.h"
 #include "MemoryInfo.h"
 #include "Page.h"
 #include "RTCPeerConnectionHandlerMock.h"
 #endif
 
+#if ENABLE(MEDIA_SOURCE)
+#include "MockMediaPlayerMediaSource.h"
+#endif
+
 namespace WebCore {
 
 using namespace HTMLNames;
@@ -2167,4 +2172,11 @@ bool Internals::isPluginUnavailabilityIndicatorObscured(Element* element, Except
     return embed->isReplacementObscured();
 }
 
+#if ENABLE(MEDIA_SOURCE)
+void Internals::initializeMockMediaSource()
+{
+    MediaPlayerFactorySupport::callRegisterMediaEngine(MockMediaPlayerMediaSource::registerMediaEngine);
+}
+#endif
+
 }
index 495dcb5..b81f5f5 100644 (file)
@@ -325,6 +325,10 @@ public:
 
     bool isPluginUnavailabilityIndicatorObscured(Element*, ExceptionCode&);
 
+#if ENABLE(MEDIA_SOURCE)
+    void initializeMockMediaSource();
+#endif
+
 private:
     explicit Internals(Document*);
     Document* contextDocument() const;
index a7eae59..f1841d6 100644 (file)
     [RaisesException] boolean isPluginUnavailabilityIndicatorObscured(Element element);
 
     [RaisesException] ClientRect selectionBounds();
+    
+    [Conditional=MEDIA_SOURCE] void initializeMockMediaSource();
 };