Title: [167440] trunk
Revision
167440
Author
jer.no...@apple.com
Date
2014-04-17 10:54:59 -0700 (Thu, 17 Apr 2014)

Log Message

[MSE] Multiple initialization segments with same codecs in tracks fail validation.
https://bugs.webkit.org/show_bug.cgi?id=131768

Source/WebCore:
Additional initialization segments added to the same SourceBuffer with the same
codec values will fail validation. Update the validation check to add the correct
codec information for the initial segment, and check against the correct codecs during
the validation step.

Additionally, after validation, if successful update the Audio, Video, and TextTracks
for the SourceBuffer with the updated initialization segment information.

Reviewed by Eric Carlson.

Test: media/media-source/media-source-multiple-initialization-segments.html

* Modules/mediasource/SourceBuffer.cpp:
(WebCore::SourceBuffer::appendBufferTimerFired): m_source may have been cleared
    as a result of the append, so check it before using.
(WebCore::SourceBuffer::sourceBufferPrivateDidEndStream): Call streamEndedWithError
    instead of endOfStream as the latter is safe to call within an update.
(WebCore::SourceBuffer::sourceBufferPrivateDidReceiveInitializationSegment): Ditto.
    Update the track lists if validation succeeds.
(WebCore::SourceBuffer::validateInitializationSegment): Switch the audio and video
    codec checks.

Add the ability for Audio, Video, and InbandTextTracks to replace their private tracks:
* html/track/AudioTrack.cpp:
(WebCore::AudioTrack::AudioTrack): Call updateKindFromPrivate().
(WebCore::AudioTrack::setPrivate):
(WebCore::AudioTrack::updateKindFromPrivate): Split out from constructor.
* html/track/AudioTrack.h:
* html/track/InbandTextTrack.cpp:
(WebCore::InbandTextTrack::InbandTextTrack): Call updateKindFromPrivate().
(WebCore::InbandTextTrack::setPrivate):
(WebCore::InbandTextTrack::setMode): Split up into setModeInternal().
(WebCore::InbandTextTrack::setModeInternal): Broke out from setMode().
(WebCore::InbandTextTrack::updateKindFromPrivate): Split out from constructor.
* html/track/InbandTextTrack.h:
* html/track/TextTrack.h:
(WebCore::TextTrack::isInband): Added, returns false.
* html/track/VideoTrack.cpp:
(WebCore::VideoTrack::VideoTrack): Call updateKindFromPrivate().
(WebCore::VideoTrack::setPrivate):
(WebCore::VideoTrack::updateKindFromPrivate):  Split out from constructor.
* html/track/VideoTrack.h:

LayoutTests:
Reviewed by Eric Carlson.

* media/media-source/media-source-multiple-initialization-segments-expected.txt: Added.
* media/media-source/media-source-multiple-initialization-segments.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (167439 => 167440)


--- trunk/LayoutTests/ChangeLog	2014-04-17 17:53:40 UTC (rev 167439)
+++ trunk/LayoutTests/ChangeLog	2014-04-17 17:54:59 UTC (rev 167440)
@@ -1,3 +1,13 @@
+2014-04-16  Jer Noble  <jer.no...@apple.com>
+
+        [MSE] Multiple initialization segments with same codecs in tracks fail validation.
+        https://bugs.webkit.org/show_bug.cgi?id=131768
+
+        Reviewed by Eric Carlson.
+
+        * media/media-source/media-source-multiple-initialization-segments-expected.txt: Added.
+        * media/media-source/media-source-multiple-initialization-segments.html: Added.
+
 2014-04-17  David Hyatt  <hy...@apple.com>
 
         [New Multicolumn] Column sets below spanners don't repaint properly.

Added: trunk/LayoutTests/media/media-source/media-source-multiple-initialization-segments-expected.txt (0 => 167440)


--- trunk/LayoutTests/media/media-source/media-source-multiple-initialization-segments-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/media/media-source/media-source-multiple-initialization-segments-expected.txt	2014-04-17 17:54:59 UTC (rev 167440)
@@ -0,0 +1,14 @@
+
+RUN(video.src = ""
+EVENT(sourceopen)
+RUN(sourceBuffer = source.addSourceBuffer("video/mock; codecs=mock"))
+RUN(sourceBuffer.appendBuffer(initSegment))
+EVENT(updateend)
+Test that a replacement initialization segment containing a track with the same codec but a different trackID succeeds.
+RUN(sourceBuffer.appendBuffer(initSegment))
+EVENT(updateend)
+Test that a replacement initialization segment containing a track with a different codec but the same trackID fails.
+RUN(sourceBuffer.appendBuffer(initSegment))
+EVENT(sourceended)
+END OF TEST
+

Added: trunk/LayoutTests/media/media-source/media-source-multiple-initialization-segments.html (0 => 167440)


--- trunk/LayoutTests/media/media-source/media-source-multiple-initialization-segments.html	                        (rev 0)
+++ trunk/LayoutTests/media/media-source/media-source-multiple-initialization-segments.html	2014-04-17 17:54:59 UTC (rev 167440)
@@ -0,0 +1,64 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <title>mock-media-source</title>
+    <script src=""
+    <script src=""
+    <script>
+    var source;
+    var sourceBuffer;
+    var initSegment;
+
+    if (window.internals)
+        internals.initializeMockMediaSource();
+
+    function runTest() {
+        findMediaElement();
+
+        source = new MediaSource();
+        waitForEventOn(source, 'sourceopen', sourceOpen);
+        waitForEventOn(source, 'sourceended', sourceEnded);
+        run('video.src = ""
+    }
+
+    function sourceOpen() {
+        run('sourceBuffer = source.addSourceBuffer("video/mock; codecs=mock")');
+
+        waitForEventOn(sourceBuffer, 'updateend', firstUpdate, false, true);
+        initSegment = makeAInit(100, [
+            makeATrack(1, 'mock', TRACK_KIND.VIDEO),
+        ]);
+        run('sourceBuffer.appendBuffer(initSegment)');
+    }
+
+    function sourceEnded() {
+        if (!expected)
+            logResult(Failed, 'Unexpected "sourceended" event');
+        endTest();
+    }
+    
+    function firstUpdate() {
+        consoleWrite('Test that a replacement initialization segment containing a track with the same codec but a different trackID succeeds.')
+        waitForEventOn(sourceBuffer, 'updateend', secondUpdate, false, true);
+        initSegment = makeAInit(100, [
+            makeATrack(2, 'mock', TRACK_KIND.VIDEO),
+        ]);
+        run('sourceBuffer.appendBuffer(initSegment)');
+    }
+
+    function secondUpdate() {
+        consoleWrite('Test that a replacement initialization segment containing a track with a different codec but the same trackID fails.')
+        waitForEventOn(sourceBuffer, 'updateend', endTest, false, true);
+        expected = true;
+        initSegment = makeAInit(100, [
+            makeATrack(2, '!moc', TRACK_KIND.VIDEO),
+        ]);
+        run('sourceBuffer.appendBuffer(initSegment)');
+    }
+
+    </script>
+</head>
+<body _onload_="runTest()">
+    <video></video>
+</body>
+</html>

Modified: trunk/Source/WebCore/ChangeLog (167439 => 167440)


--- trunk/Source/WebCore/ChangeLog	2014-04-17 17:53:40 UTC (rev 167439)
+++ trunk/Source/WebCore/ChangeLog	2014-04-17 17:54:59 UTC (rev 167440)
@@ -1,3 +1,51 @@
+2014-04-16  Jer Noble  <jer.no...@apple.com>
+
+        [MSE] Multiple initialization segments with same codecs in tracks fail validation.
+        https://bugs.webkit.org/show_bug.cgi?id=131768
+
+        Additional initialization segments added to the same SourceBuffer with the same
+        codec values will fail validation. Update the validation check to add the correct
+        codec information for the initial segment, and check against the correct codecs during
+        the validation step.
+
+        Additionally, after validation, if successful update the Audio, Video, and TextTracks
+        for the SourceBuffer with the updated initialization segment information.
+
+        Reviewed by Eric Carlson.
+
+        Test: media/media-source/media-source-multiple-initialization-segments.html
+
+        * Modules/mediasource/SourceBuffer.cpp:
+        (WebCore::SourceBuffer::appendBufferTimerFired): m_source may have been cleared
+            as a result of the append, so check it before using.
+        (WebCore::SourceBuffer::sourceBufferPrivateDidEndStream): Call streamEndedWithError
+            instead of endOfStream as the latter is safe to call within an update.
+        (WebCore::SourceBuffer::sourceBufferPrivateDidReceiveInitializationSegment): Ditto.
+            Update the track lists if validation succeeds.
+        (WebCore::SourceBuffer::validateInitializationSegment): Switch the audio and video
+            codec checks.
+
+        Add the ability for Audio, Video, and InbandTextTracks to replace their private tracks:
+        * html/track/AudioTrack.cpp:
+        (WebCore::AudioTrack::AudioTrack): Call updateKindFromPrivate().
+        (WebCore::AudioTrack::setPrivate):
+        (WebCore::AudioTrack::updateKindFromPrivate): Split out from constructor.
+        * html/track/AudioTrack.h:
+        * html/track/InbandTextTrack.cpp:
+        (WebCore::InbandTextTrack::InbandTextTrack): Call updateKindFromPrivate().
+        (WebCore::InbandTextTrack::setPrivate):
+        (WebCore::InbandTextTrack::setMode): Split up into setModeInternal().
+        (WebCore::InbandTextTrack::setModeInternal): Broke out from setMode().
+        (WebCore::InbandTextTrack::updateKindFromPrivate): Split out from constructor.
+        * html/track/InbandTextTrack.h:
+        * html/track/TextTrack.h:
+        (WebCore::TextTrack::isInband): Added, returns false.
+        * html/track/VideoTrack.cpp:
+        (WebCore::VideoTrack::VideoTrack): Call updateKindFromPrivate().
+        (WebCore::VideoTrack::setPrivate):
+        (WebCore::VideoTrack::updateKindFromPrivate):  Split out from constructor.
+        * html/track/VideoTrack.h:
+
 2014-04-17  David Hyatt  <hy...@apple.com>
 
         [New Multicolumn] Column sets below spanners don't repaint properly.

Modified: trunk/Source/WebCore/Modules/mediasource/SourceBuffer.cpp (167439 => 167440)


--- trunk/Source/WebCore/Modules/mediasource/SourceBuffer.cpp	2014-04-17 17:53:40 UTC (rev 167439)
+++ trunk/Source/WebCore/Modules/mediasource/SourceBuffer.cpp	2014-04-17 17:54:59 UTC (rev 167440)
@@ -508,7 +508,8 @@
     // 5. Queue a task to fire a simple event named updateend at this SourceBuffer object.
     scheduleEvent(eventNames().updateendEvent);
 
-    m_source->monitorSourceBuffers();
+    if (m_source)
+        m_source->monitorSourceBuffers();
     for (auto iter = m_trackBufferMap.begin(), end = m_trackBufferMap.end(); iter != end; ++iter)
         provideMediaData(iter->value, iter->key);
 }
@@ -645,7 +646,7 @@
 void SourceBuffer::sourceBufferPrivateDidEndStream(SourceBufferPrivate*, const WTF::AtomicString& error)
 {
     if (!isRemoved())
-        m_source->endOfStream(error, IgnorableExceptionCode());
+        m_source->streamEndedWithError(error, IgnorableExceptionCode());
 }
 
 void SourceBuffer::sourceBufferPrivateDidReceiveInitializationSegment(SourceBufferPrivate*, const InitializationSegment& segment)
@@ -668,17 +669,51 @@
     // 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.
     if (!segment.audioTracks.size() && !segment.videoTracks.size() && !segment.textTracks.size())
-        m_source->endOfStream(decodeError(), IgnorableExceptionCode());
+        m_source->streamEndedWithError(decodeError(), IgnorableExceptionCode());
 
 
     // 3. If the first initialization segment flag is true, then run the following steps:
     if (m_receivedFirstInitializationSegment) {
         if (!validateInitializationSegment(segment)) {
-            m_source->endOfStream(decodeError(), IgnorableExceptionCode());
+            m_source->streamEndedWithError(decodeError(), IgnorableExceptionCode());
             return;
         }
         // 3.2 Add the appropriate track descriptions from this initialization segment to each of the track buffers.
-        // NOTE: No changes to make
+        ASSERT(segment.audioTracks.size() == audioTracks()->length());
+        for (auto& audioTrackInfo : segment.audioTracks) {
+            if (audioTracks()->length() == 1) {
+                audioTracks()->item(0)->setPrivate(audioTrackInfo.track);
+                break;
+            }
+
+            auto audioTrack = audioTracks()->getTrackById(audioTrackInfo.track->id());
+            ASSERT(audioTrack);
+            audioTrack->setPrivate(audioTrackInfo.track);
+        }
+
+        ASSERT(segment.videoTracks.size() == videoTracks()->length());
+        for (auto& videoTrackInfo : segment.videoTracks) {
+            if (videoTracks()->length() == 1) {
+                videoTracks()->item(0)->setPrivate(videoTrackInfo.track);
+                break;
+            }
+
+            auto videoTrack = videoTracks()->getTrackById(videoTrackInfo.track->id());
+            ASSERT(videoTrack);
+            videoTrack->setPrivate(videoTrackInfo.track);
+        }
+
+        ASSERT(segment.textTracks.size() == textTracks()->length());
+        for (auto& textTrackInfo : segment.textTracks) {
+            if (textTracks()->length() == 1) {
+                toInbandTextTrack(textTracks()->item(0))->setPrivate(textTrackInfo.track);
+                break;
+            }
+
+            auto textTrack = textTracks()->getTrackById(textTrackInfo.track->id());
+            ASSERT(textTrack);
+            toInbandTextTrack(textTrack)->setPrivate(textTrackInfo.track);
+        }
     }
 
     // 4. Let active track flag equal false.
@@ -726,6 +761,8 @@
 
             // 5.2.9 Add the track description for this track to the track buffer.
             trackBuffer.description = it->description;
+
+            m_audioCodecs.append(trackBuffer.description->codec());
         }
 
         // 5.3 For each video track in the initialization segment, run following steps:
@@ -764,6 +801,8 @@
 
             // 5.3.9 Add the track description for this track to the track buffer.
             trackBuffer.description = it->description;
+
+            m_videoCodecs.append(trackBuffer.description->codec());
         }
 
         // 5.4 For each text track in the initialization segment, run following steps:
@@ -797,6 +836,8 @@
 
             // 5.4.8 Add the track description for this track to the track buffer.
             trackBuffer.description = it->description;
+
+            m_textCodecs.append(trackBuffer.description->codec());
         }
 
         // 5.5 If active track flag equals true, then run the following steps:
@@ -844,12 +885,12 @@
 
     //   * The codecs for each track, match what was specified in the first initialization segment.
     for (auto it = segment.audioTracks.begin(); it != segment.audioTracks.end(); ++it) {
-        if (!m_videoCodecs.contains(it->description->codec()))
+        if (!m_audioCodecs.contains(it->description->codec()))
             return false;
     }
 
     for (auto it = segment.videoTracks.begin(); it != segment.videoTracks.end(); ++it) {
-        if (!m_audioCodecs.contains(it->description->codec()))
+        if (!m_videoCodecs.contains(it->description->codec()))
             return false;
     }
 

Modified: trunk/Source/WebCore/html/track/AudioTrack.cpp (167439 => 167440)


--- trunk/Source/WebCore/html/track/AudioTrack.cpp	2014-04-17 17:53:40 UTC (rev 167439)
+++ trunk/Source/WebCore/html/track/AudioTrack.cpp	2014-04-17 17:54:59 UTC (rev 167440)
@@ -84,33 +84,7 @@
     , m_private(trackPrivate)
 {
     m_private->setClient(this);
-
-    switch (m_private->kind()) {
-    case AudioTrackPrivate::Alternative:
-        setKind(AudioTrack::alternativeKeyword());
-        break;
-    case AudioTrackPrivate::Description:
-        setKind(AudioTrack::descriptionKeyword());
-        break;
-    case AudioTrackPrivate::Main:
-        setKind(AudioTrack::mainKeyword());
-        break;
-    case AudioTrackPrivate::MainDesc:
-        setKind(AudioTrack::mainDescKeyword());
-        break;
-    case AudioTrackPrivate::Translation:
-        setKind(AudioTrack::translationKeyword());
-        break;
-    case AudioTrackPrivate::Commentary:
-        setKind(AudioTrack::commentaryKeyword());
-        break;
-    case AudioTrackPrivate::None:
-        setKind(emptyString());
-        break;
-    default:
-        ASSERT_NOT_REACHED();
-        break;
-    }
+    updateKindFromPrivate();
 }
 
 AudioTrack::~AudioTrack()
@@ -118,6 +92,22 @@
     m_private->setClient(0);
 }
 
+void AudioTrack::setPrivate(PassRefPtr<AudioTrackPrivate> trackPrivate)
+{
+    ASSERT(m_private);
+    ASSERT(trackPrivate);
+
+    if (m_private == trackPrivate)
+        return;
+
+    m_private->setClient(0);
+    m_private = trackPrivate;
+    m_private->setClient(this);
+
+    m_private->setEnabled(m_enabled);
+    updateKindFromPrivate();
+}
+
 bool AudioTrack::isValidKind(const AtomicString& value) const
 {
     if (value == alternativeKeyword())
@@ -184,6 +174,36 @@
     mediaElement()->removeAudioTrack(this);
 }
 
+void AudioTrack::updateKindFromPrivate()
+{
+    switch (m_private->kind()) {
+    case AudioTrackPrivate::Alternative:
+        setKind(AudioTrack::alternativeKeyword());
+        break;
+    case AudioTrackPrivate::Description:
+        setKind(AudioTrack::descriptionKeyword());
+        break;
+    case AudioTrackPrivate::Main:
+        setKind(AudioTrack::mainKeyword());
+        break;
+    case AudioTrackPrivate::MainDesc:
+        setKind(AudioTrack::mainDescKeyword());
+        break;
+    case AudioTrackPrivate::Translation:
+        setKind(AudioTrack::translationKeyword());
+        break;
+    case AudioTrackPrivate::Commentary:
+        setKind(AudioTrack::commentaryKeyword());
+        break;
+    case AudioTrackPrivate::None:
+        setKind(emptyString());
+        break;
+    default:
+        ASSERT_NOT_REACHED();
+        break;
+    }
+}
+
 } // namespace WebCore
 
 #endif

Modified: trunk/Source/WebCore/html/track/AudioTrack.h (167439 => 167440)


--- trunk/Source/WebCore/html/track/AudioTrack.h	2014-04-17 17:53:40 UTC (rev 167439)
+++ trunk/Source/WebCore/html/track/AudioTrack.h	2014-04-17 17:54:59 UTC (rev 167440)
@@ -69,6 +69,8 @@
 
     size_t inbandTrackIndex();
 
+    void setPrivate(PassRefPtr<AudioTrackPrivate>);
+
 protected:
     AudioTrack(AudioTrackClient*, PassRefPtr<AudioTrackPrivate>);
 
@@ -81,6 +83,8 @@
     virtual void languageChanged(TrackPrivateBase*, const AtomicString&) override;
     virtual void willRemove(TrackPrivateBase*) override;
 
+    void updateKindFromPrivate();
+
     bool m_enabled;
     AudioTrackClient* m_client;
 

Modified: trunk/Source/WebCore/html/track/InbandTextTrack.cpp (167439 => 167440)


--- trunk/Source/WebCore/html/track/InbandTextTrack.cpp	2014-04-17 17:53:40 UTC (rev 167439)
+++ trunk/Source/WebCore/html/track/InbandTextTrack.cpp	2014-04-17 17:54:59 UTC (rev 167440)
@@ -65,31 +65,7 @@
     , m_private(trackPrivate)
 {
     m_private->setClient(this);
-    
-    switch (m_private->kind()) {
-    case InbandTextTrackPrivate::Subtitles:
-        setKind(TextTrack::subtitlesKeyword());
-        break;
-    case InbandTextTrackPrivate::Captions:
-        setKind(TextTrack::captionsKeyword());
-        break;
-    case InbandTextTrackPrivate::Descriptions:
-        setKind(TextTrack::descriptionsKeyword());
-        break;
-    case InbandTextTrackPrivate::Chapters:
-        setKind(TextTrack::chaptersKeyword());
-        break;
-    case InbandTextTrackPrivate::Metadata:
-        setKind(TextTrack::metadataKeyword());
-        break;
-    case InbandTextTrackPrivate::Forced:
-        setKind(TextTrack::forcedKeyword());
-        break;
-    case InbandTextTrackPrivate::None:
-    default:
-        ASSERT_NOT_REACHED();
-        break;
-    }
+    updateKindFromPrivate();
 }
 
 InbandTextTrack::~InbandTextTrack()
@@ -97,10 +73,30 @@
     m_private->setClient(0);
 }
 
+void InbandTextTrack::setPrivate(PassRefPtr<InbandTextTrackPrivate> trackPrivate)
+{
+    ASSERT(m_private);
+    ASSERT(trackPrivate);
+
+    if (m_private == trackPrivate)
+        return;
+
+    m_private->setClient(0);
+    m_private = trackPrivate;
+    m_private->setClient(this);
+
+    setModeInternal(mode());
+    updateKindFromPrivate();
+}
+
 void InbandTextTrack::setMode(const AtomicString& mode)
 {
     TextTrack::setMode(mode);
+    setModeInternal(mode);
+}
 
+void InbandTextTrack::setModeInternal(const AtomicString& mode)
+{
     if (mode == TextTrack::disabledKeyword())
         m_private->setMode(InbandTextTrackPrivate::Disabled);
     else if (mode == TextTrack::hiddenKeyword())
@@ -189,6 +185,34 @@
     mediaElement()->removeTextTrack(this);
 }
 
+void InbandTextTrack::updateKindFromPrivate()
+{
+    switch (m_private->kind()) {
+    case InbandTextTrackPrivate::Subtitles:
+        setKind(TextTrack::subtitlesKeyword());
+        break;
+    case InbandTextTrackPrivate::Captions:
+        setKind(TextTrack::captionsKeyword());
+        break;
+    case InbandTextTrackPrivate::Descriptions:
+        setKind(TextTrack::descriptionsKeyword());
+        break;
+    case InbandTextTrackPrivate::Chapters:
+        setKind(TextTrack::chaptersKeyword());
+        break;
+    case InbandTextTrackPrivate::Metadata:
+        setKind(TextTrack::metadataKeyword());
+        break;
+    case InbandTextTrackPrivate::Forced:
+        setKind(TextTrack::forcedKeyword());
+        break;
+    case InbandTextTrackPrivate::None:
+    default:
+        ASSERT_NOT_REACHED();
+        break;
+    }
+}
+
 } // namespace WebCore
 
 #endif

Modified: trunk/Source/WebCore/html/track/InbandTextTrack.h (167439 => 167440)


--- trunk/Source/WebCore/html/track/InbandTextTrack.h	2014-04-17 17:53:40 UTC (rev 167439)
+++ trunk/Source/WebCore/html/track/InbandTextTrack.h	2014-04-17 17:54:59 UTC (rev 167440)
@@ -50,9 +50,16 @@
 
     virtual AtomicString inBandMetadataTrackDispatchType() const;
 
+    void setPrivate(PassRefPtr<InbandTextTrackPrivate>);
+
+    virtual bool isInband() const override { return true; }
+
 protected:
     InbandTextTrack(ScriptExecutionContext*, TextTrackClient*, PassRefPtr<InbandTextTrackPrivate>);
 
+    void setModeInternal(const AtomicString&);
+    void updateKindFromPrivate();
+
     RefPtr<InbandTextTrackPrivate> m_private;
 
 private:
@@ -75,6 +82,8 @@
 #endif
 };
 
+TYPE_CASTS_BASE(InbandTextTrack, TextTrack, track, track->isInband(), track.isInband());
+
 } // namespace WebCore
 
 #endif

Modified: trunk/Source/WebCore/html/track/TextTrack.h (167439 => 167440)


--- trunk/Source/WebCore/html/track/TextTrack.h	2014-04-17 17:53:40 UTC (rev 167439)
+++ trunk/Source/WebCore/html/track/TextTrack.h	2014-04-17 17:54:59 UTC (rev 167440)
@@ -156,6 +156,8 @@
     virtual void setLanguage(const AtomicString&) override;
 #endif
 
+    virtual bool isInband() const { return false; }
+
     using RefCounted<TrackBase>::ref;
     using RefCounted<TrackBase>::deref;
 

Modified: trunk/Source/WebCore/html/track/VideoTrack.cpp (167439 => 167440)


--- trunk/Source/WebCore/html/track/VideoTrack.cpp	2014-04-17 17:53:40 UTC (rev 167439)
+++ trunk/Source/WebCore/html/track/VideoTrack.cpp	2014-04-17 17:54:59 UTC (rev 167440)
@@ -88,33 +88,7 @@
     , m_private(trackPrivate)
 {
     m_private->setClient(this);
-
-    switch (m_private->kind()) {
-    case VideoTrackPrivate::Alternative:
-        setKindInternal(VideoTrack::alternativeKeyword());
-        break;
-    case VideoTrackPrivate::Captions:
-        setKindInternal(VideoTrack::captionsKeyword());
-        break;
-    case VideoTrackPrivate::Main:
-        setKindInternal(VideoTrack::mainKeyword());
-        break;
-    case VideoTrackPrivate::Sign:
-        setKindInternal(VideoTrack::signKeyword());
-        break;
-    case VideoTrackPrivate::Subtitles:
-        setKindInternal(VideoTrack::subtitlesKeyword());
-        break;
-    case VideoTrackPrivate::Commentary:
-        setKindInternal(VideoTrack::commentaryKeyword());
-        break;
-    case VideoTrackPrivate::None:
-        setKindInternal(emptyString());
-        break;
-    default:
-        ASSERT_NOT_REACHED();
-        break;
-    }
+    updateKindFromPrivate();
 }
 
 VideoTrack::~VideoTrack()
@@ -122,6 +96,22 @@
     m_private->setClient(0);
 }
 
+void VideoTrack::setPrivate(PassRefPtr<VideoTrackPrivate> trackPrivate)
+{
+    ASSERT(m_private);
+    ASSERT(trackPrivate);
+
+    if (m_private == trackPrivate)
+        return;
+
+    m_private->setClient(nullptr);
+    m_private = trackPrivate;
+    m_private->setClient(this);
+
+    m_private->setSelected(m_selected);
+    updateKindFromPrivate();
+}
+
 bool VideoTrack::isValidKind(const AtomicString& value) const
 {
     if (value == alternativeKeyword())
@@ -231,6 +221,36 @@
 }
 #endif
 
+void VideoTrack::updateKindFromPrivate()
+{
+    switch (m_private->kind()) {
+    case VideoTrackPrivate::Alternative:
+        setKindInternal(VideoTrack::alternativeKeyword());
+        break;
+    case VideoTrackPrivate::Captions:
+        setKindInternal(VideoTrack::captionsKeyword());
+        break;
+    case VideoTrackPrivate::Main:
+        setKindInternal(VideoTrack::mainKeyword());
+        break;
+    case VideoTrackPrivate::Sign:
+        setKindInternal(VideoTrack::signKeyword());
+        break;
+    case VideoTrackPrivate::Subtitles:
+        setKindInternal(VideoTrack::subtitlesKeyword());
+        break;
+    case VideoTrackPrivate::Commentary:
+        setKindInternal(VideoTrack::commentaryKeyword());
+        break;
+    case VideoTrackPrivate::None:
+        setKindInternal(emptyString());
+        break;
+    default:
+        ASSERT_NOT_REACHED();
+        break;
+    }
+}
+
 } // namespace WebCore
 
 #endif

Modified: trunk/Source/WebCore/html/track/VideoTrack.h (167439 => 167440)


--- trunk/Source/WebCore/html/track/VideoTrack.h	2014-04-17 17:53:40 UTC (rev 167439)
+++ trunk/Source/WebCore/html/track/VideoTrack.h	2014-04-17 17:54:59 UTC (rev 167440)
@@ -77,6 +77,8 @@
 
     const MediaDescription& description() const;
 
+    void setPrivate(PassRefPtr<VideoTrackPrivate>);
+
 protected:
     VideoTrack(VideoTrackClient*, PassRefPtr<VideoTrackPrivate> privateTrack);
 
@@ -91,6 +93,8 @@
 
     virtual bool enabled() const override { return selected(); }
 
+    void updateKindFromPrivate();
+
     bool m_selected;
     VideoTrackClient* m_client;
 
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to