Fix TimeRanges layering violations
authoreric.carlson@apple.com <eric.carlson@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 21 Feb 2014 22:04:06 +0000 (22:04 +0000)
committereric.carlson@apple.com <eric.carlson@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 21 Feb 2014 22:04:06 +0000 (22:04 +0000)
https://bugs.webkit.org/show_bug.cgi?id=128717

Reviewed by NOBODY (OOPS!).

Source/WebCore:

No new tests, no functionality changed.

* CMakeLists.txt:
* GNUmakefile.list.am: Add PlatformTimeRanges.

* Modules/mediasource/MediaSource.cpp:
(WebCore::MediaSource::buffered): TimeRanges -> PlatformTimeRanges.
* Modules/mediasource/MediaSource.h:

* Modules/mediasource/SourceBuffer.cpp:
(WebCore::SourceBuffer::sourceBufferPrivateDidReceiveSample): TimeRanges* -> TimeRanges&.

* WebCore.exp.in: Update for signature changes.

* WebCore.vcxproj/WebCore.vcxproj:
* WebCore.vcxproj/WebCore.vcxproj.filters:
* WebCore.xcodeproj/project.pbxproj: Add PlatformTimeRanges.

* html/HTMLMediaElement.cpp:
(WebCore::HTMLMediaElement::percentLoaded): Create TimeRanges from PlatformTimeRanges.
(WebCore::HTMLMediaElement::buffered): Ditto.
(WebCore::HTMLMediaElement::seekable): Ditto.

* html/MediaController.cpp:
(MediaController::buffered): TimeRanges* -> TimeRanges&.
(MediaController::seekable): Ditto.
(MediaController::played): Ditto.

Move all of the logic into PlatformTimeRanges. Change API to take TimeRanges& instead of TimeRanges*.
* html/TimeRanges.cpp:
(WebCore::TimeRanges::create): Move to .cpp from .h.
(WebCore::TimeRanges::TimeRanges): Initialize the PlatformTimeRanges member variable.
(WebCore::TimeRanges::start): Passthrough to PlatformTimeRanges.
(WebCore::TimeRanges::end): Ditto.
(WebCore::TimeRanges::invert): Ditto.
(WebCore::TimeRanges::copy): Ditto.
(WebCore::TimeRanges::intersectWith): Ditto.
(WebCore::TimeRanges::unionWith): Ditto.
(WebCore::TimeRanges::length): Ditto.
(WebCore::TimeRanges::add): Ditto.
(WebCore::TimeRanges::contain): Ditto.
(WebCore::TimeRanges::find): Ditto.
(WebCore::TimeRanges::nearest): Ditto.
(WebCore::TimeRanges::totalDuration): Ditto.
* html/TimeRanges.h:

* platform/graphics/MediaPlayer.cpp:
(WebCore::NullMediaPlayerPrivate::buffered): TimeRanges -> PlatformTimeRanges.
(WebCore::MediaPlayer::buffered): Ditto.
(WebCore::MediaPlayer::seekable): Ditto.
* platform/graphics/MediaPlayer.h:
* platform/graphics/MediaPlayerPrivate.h:

* platform/graphics/MediaSourcePrivateClient.h:

* platform/graphics/PlatformTimeRanges.cpp: Added.
* platform/graphics/PlatformTimeRanges.h: Added.

* platform/graphics/avfoundation/MediaPlayerPrivateAVFoundation.cpp:
(WebCore::MediaPlayerPrivateAVFoundation::buffered): TimeRanges -> PlatformTimeRanges.
(WebCore::MediaPlayerPrivateAVFoundation::loadedTimeRangesChanged): Drive-by fix to log
    FunctionType notifications. ASSERT when passed an unknown notification.

* platform/graphics/avfoundation/MediaPlayerPrivateAVFoundation.h:
* platform/graphics/avfoundation/cf/MediaPlayerPrivateAVFoundationCF.cpp:
(WebCore::MediaPlayerPrivateAVFoundationCF::platformBufferedTimeRanges):  TimeRanges -> PlatformTimeRanges.
* platform/graphics/avfoundation/cf/MediaPlayerPrivateAVFoundationCF.h:
* platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.h:
* platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm:
(WebCore::MediaPlayerPrivateAVFoundationObjC::currentTime): Ditto.
(WebCore::MediaPlayerPrivateAVFoundationObjC::platformBufferedTimeRanges): Ditto.

* platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.h:
* platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.mm:
(WebCore::MediaPlayerPrivateMediaSourceAVFObjC::seekable): Ditto.
(WebCore::MediaPlayerPrivateMediaSourceAVFObjC::buffered): Ditto.

* platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp:
(WebCore::MediaPlayerPrivateGStreamer::buffered): Ditto.
* platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.h:

* platform/graphics/ios/MediaPlayerPrivateIOS.h:
* platform/graphics/ios/MediaPlayerPrivateIOS.mm:
(WebCore::MediaPlayerPrivateIOS::buffered): Ditto.

* platform/graphics/mac/MediaPlayerPrivateQTKit.h:
* platform/graphics/mac/MediaPlayerPrivateQTKit.mm:
(WebCore::MediaPlayerPrivateQTKit::buffered): Ditto.

* platform/graphics/win/MediaPlayerPrivateQuickTimeVisualContext.cpp:
(WebCore::MediaPlayerPrivateQuickTimeVisualContext::buffered): Ditto.
* platform/graphics/win/MediaPlayerPrivateQuickTimeVisualContext.h:

* platform/graphics/wince/MediaPlayerPrivateWinCE.h:

* platform/mock/mediasource/MockMediaPlayerMediaSource.cpp:
(WebCore::MockMediaPlayerMediaSource::buffered): Ditto.
(WebCore::MockMediaPlayerMediaSource::advanceCurrentTime): Ditto.
* platform/mock/mediasource/MockMediaPlayerMediaSource.h:

Source/WebKit:

* WebKit.vcxproj/WebKitExportGenerator/WebKitExports.def.in: TimeRanges::create(void) for Internals.

Tools:

* TestWebKitAPI/Tests/WebCore/TimeRanges.cpp: TimeRanges* -> TimeRanges&.
(TestWebKitAPI::TEST):

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

43 files changed:
Source/WebCore/CMakeLists.txt
Source/WebCore/ChangeLog
Source/WebCore/GNUmakefile.list.am
Source/WebCore/Modules/mediasource/MediaSource.cpp
Source/WebCore/Modules/mediasource/MediaSource.h
Source/WebCore/Modules/mediasource/SourceBuffer.cpp
Source/WebCore/WebCore.exp.in
Source/WebCore/WebCore.vcxproj/WebCore.vcxproj
Source/WebCore/WebCore.vcxproj/WebCore.vcxproj.filters
Source/WebCore/WebCore.xcodeproj/project.pbxproj
Source/WebCore/html/HTMLMediaElement.cpp
Source/WebCore/html/MediaController.cpp
Source/WebCore/html/TimeRanges.cpp
Source/WebCore/html/TimeRanges.h
Source/WebCore/platform/graphics/MediaPlayer.cpp
Source/WebCore/platform/graphics/MediaPlayer.h
Source/WebCore/platform/graphics/MediaPlayerPrivate.h
Source/WebCore/platform/graphics/MediaSourcePrivateClient.h
Source/WebCore/platform/graphics/PlatformTimeRanges.cpp [new file with mode: 0644]
Source/WebCore/platform/graphics/PlatformTimeRanges.h [new file with mode: 0644]
Source/WebCore/platform/graphics/avfoundation/MediaPlayerPrivateAVFoundation.cpp
Source/WebCore/platform/graphics/avfoundation/MediaPlayerPrivateAVFoundation.h
Source/WebCore/platform/graphics/avfoundation/cf/MediaPlayerPrivateAVFoundationCF.cpp
Source/WebCore/platform/graphics/avfoundation/cf/MediaPlayerPrivateAVFoundationCF.h
Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.h
Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm
Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.h
Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.mm
Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp
Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.h
Source/WebCore/platform/graphics/ios/MediaPlayerPrivateIOS.h
Source/WebCore/platform/graphics/ios/MediaPlayerPrivateIOS.mm
Source/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.h
Source/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.mm
Source/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeVisualContext.cpp
Source/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeVisualContext.h
Source/WebCore/platform/graphics/wince/MediaPlayerPrivateWinCE.h
Source/WebCore/platform/mock/mediasource/MockMediaPlayerMediaSource.cpp
Source/WebCore/platform/mock/mediasource/MockMediaPlayerMediaSource.h
Source/WebKit/ChangeLog
Source/WebKit/WebKit.vcxproj/WebKitExportGenerator/WebKitExports.def.in
Tools/ChangeLog
Tools/TestWebKitAPI/Tests/WebCore/TimeRanges.cpp

index 51eb327..17f1341 100644 (file)
@@ -1910,6 +1910,7 @@ set(WebCore_SOURCES
     platform/graphics/Path.cpp
     platform/graphics/PathTraversalState.cpp
     platform/graphics/Pattern.cpp
+    platform/graphics/PlatformTimeRanges.cpp
     platform/graphics/Region.cpp
     platform/graphics/RoundedRect.cpp
     platform/graphics/SVGGlyph.cpp
index 603fd59..4f59dac 100644 (file)
@@ -1,3 +1,110 @@
+2014-02-21  Eric Carlson  <eric.carlson@apple.com>
+
+        Fix TimeRanges layering violations
+        https://bugs.webkit.org/show_bug.cgi?id=128717
+
+        Reviewed by Jer Noble.
+
+        No new tests, no functionality changed.
+
+        * CMakeLists.txt:
+        * GNUmakefile.list.am: Add PlatformTimeRanges.
+
+        * Modules/mediasource/MediaSource.cpp:
+        (WebCore::MediaSource::buffered): TimeRanges -> PlatformTimeRanges.
+        * Modules/mediasource/MediaSource.h:
+
+        * Modules/mediasource/SourceBuffer.cpp:
+        (WebCore::SourceBuffer::sourceBufferPrivateDidReceiveSample): TimeRanges* -> TimeRanges&.
+
+        * WebCore.exp.in: Update for signature changes.
+
+        * WebCore.vcxproj/WebCore.vcxproj:
+        * WebCore.vcxproj/WebCore.vcxproj.filters:
+        * WebCore.xcodeproj/project.pbxproj: Add PlatformTimeRanges.
+
+        * html/HTMLMediaElement.cpp:
+        (WebCore::HTMLMediaElement::percentLoaded): Create TimeRanges from PlatformTimeRanges.
+        (WebCore::HTMLMediaElement::buffered): Ditto.
+        (WebCore::HTMLMediaElement::seekable): Ditto.
+
+        * html/MediaController.cpp:
+        (MediaController::buffered): TimeRanges* -> TimeRanges&.
+        (MediaController::seekable): Ditto.
+        (MediaController::played): Ditto.
+
+        Move all of the logic into PlatformTimeRanges. Change API to take TimeRanges& instead of TimeRanges*.
+        * html/TimeRanges.cpp:
+        (WebCore::TimeRanges::create): Move to .cpp from .h.
+        (WebCore::TimeRanges::TimeRanges): Initialize the PlatformTimeRanges member variable.
+        (WebCore::TimeRanges::start): Passthrough to PlatformTimeRanges.
+        (WebCore::TimeRanges::end): Ditto.
+        (WebCore::TimeRanges::invert): Ditto.
+        (WebCore::TimeRanges::copy): Ditto.
+        (WebCore::TimeRanges::intersectWith): Ditto.
+        (WebCore::TimeRanges::unionWith): Ditto.
+        (WebCore::TimeRanges::length): Ditto.
+        (WebCore::TimeRanges::add): Ditto.
+        (WebCore::TimeRanges::contain): Ditto.
+        (WebCore::TimeRanges::find): Ditto.
+        (WebCore::TimeRanges::nearest): Ditto.
+        (WebCore::TimeRanges::totalDuration): Ditto.
+        * html/TimeRanges.h:
+
+        * platform/graphics/MediaPlayer.cpp:
+        (WebCore::NullMediaPlayerPrivate::buffered): TimeRanges -> PlatformTimeRanges.
+        (WebCore::MediaPlayer::buffered): Ditto.
+        (WebCore::MediaPlayer::seekable): Ditto.
+        * platform/graphics/MediaPlayer.h:
+        * platform/graphics/MediaPlayerPrivate.h:
+
+        * platform/graphics/MediaSourcePrivateClient.h:
+
+        * platform/graphics/PlatformTimeRanges.cpp: Added.
+        * platform/graphics/PlatformTimeRanges.h: Added.
+
+        * platform/graphics/avfoundation/MediaPlayerPrivateAVFoundation.cpp:
+        (WebCore::MediaPlayerPrivateAVFoundation::buffered): TimeRanges -> PlatformTimeRanges.
+        (WebCore::MediaPlayerPrivateAVFoundation::loadedTimeRangesChanged): Drive-by fix to log
+            FunctionType notifications. ASSERT when passed an unknown notification.
+
+        * platform/graphics/avfoundation/MediaPlayerPrivateAVFoundation.h:
+        * platform/graphics/avfoundation/cf/MediaPlayerPrivateAVFoundationCF.cpp:
+        (WebCore::MediaPlayerPrivateAVFoundationCF::platformBufferedTimeRanges):  TimeRanges -> PlatformTimeRanges.
+        * platform/graphics/avfoundation/cf/MediaPlayerPrivateAVFoundationCF.h:
+        * platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.h:
+        * platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm:
+        (WebCore::MediaPlayerPrivateAVFoundationObjC::currentTime): Ditto.
+        (WebCore::MediaPlayerPrivateAVFoundationObjC::platformBufferedTimeRanges): Ditto.
+
+        * platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.h:
+        * platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.mm:
+        (WebCore::MediaPlayerPrivateMediaSourceAVFObjC::seekable): Ditto.
+        (WebCore::MediaPlayerPrivateMediaSourceAVFObjC::buffered): Ditto.
+
+        * platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp:
+        (WebCore::MediaPlayerPrivateGStreamer::buffered): Ditto.
+        * platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.h:
+
+        * platform/graphics/ios/MediaPlayerPrivateIOS.h:
+        * platform/graphics/ios/MediaPlayerPrivateIOS.mm:
+        (WebCore::MediaPlayerPrivateIOS::buffered): Ditto.
+
+        * platform/graphics/mac/MediaPlayerPrivateQTKit.h:
+        * platform/graphics/mac/MediaPlayerPrivateQTKit.mm:
+        (WebCore::MediaPlayerPrivateQTKit::buffered): Ditto.
+
+        * platform/graphics/win/MediaPlayerPrivateQuickTimeVisualContext.cpp:
+        (WebCore::MediaPlayerPrivateQuickTimeVisualContext::buffered): Ditto.
+        * platform/graphics/win/MediaPlayerPrivateQuickTimeVisualContext.h:
+
+        * platform/graphics/wince/MediaPlayerPrivateWinCE.h:
+
+        * platform/mock/mediasource/MockMediaPlayerMediaSource.cpp:
+        (WebCore::MockMediaPlayerMediaSource::buffered): Ditto.
+        (WebCore::MockMediaPlayerMediaSource::advanceCurrentTime): Ditto.
+        * platform/mock/mediasource/MockMediaPlayerMediaSource.h:
+
 2014-02-21  Enrica Casucci  <enrica@apple.com>
 
         Support WebSelections in WK2 on iOS.
index 86cca78..17a60ca 100644 (file)
@@ -5338,6 +5338,8 @@ webcore_platform_sources += \
        Source/WebCore/platform/graphics/MediaPlayer.cpp \
        Source/WebCore/platform/graphics/MediaPlayer.h \
        Source/WebCore/platform/graphics/MediaPlayerPrivate.h \
+       Source/WebCore/platform/graphics/PlatformTimeRanges.cpp \
+       Source/WebCore/platform/graphics/PlatformTimeRanges.h \
        Source/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGLCommon.cpp \
        Source/WebCore/platform/graphics/opengl/TemporaryOpenGLSetting.cpp \
        Source/WebCore/platform/graphics/opengl/TemporaryOpenGLSetting.h \
index 594aea2..9cb36e7 100644 (file)
@@ -131,7 +131,7 @@ double MediaSource::duration() const
     return isClosed() ? std::numeric_limits<float>::quiet_NaN() : m_private->duration();
 }
 
-PassRefPtr<TimeRanges> MediaSource::buffered() const
+std::unique_ptr<PlatformTimeRanges> MediaSource::buffered() const
 {
     // Implements MediaSource algorithm for HTMLMediaElement.buffered.
     // https://dvcs.w3.org/hg/html-media/raw-file/default/media-source/media-source.html#htmlmediaelement-extensions
@@ -139,7 +139,7 @@ PassRefPtr<TimeRanges> MediaSource::buffered() const
 
     // 1. If activeSourceBuffers.length equals 0 then return an empty TimeRanges object and abort these steps.
     if (ranges.isEmpty())
-        return TimeRanges::create();
+        return PlatformTimeRanges::create();
 
     // 2. Let active ranges be the ranges returned by buffered for each SourceBuffer object in activeSourceBuffers.
     // 3. Let highest end time be the largest range end time in the active ranges.
@@ -152,7 +152,7 @@ PassRefPtr<TimeRanges> MediaSource::buffered() const
 
     // Return an empty range if all ranges are empty.
     if (highestEndTime < 0)
-        return TimeRanges::create();
+        return PlatformTimeRanges::create();
 
     // 4. Let intersection ranges equal a TimeRange object containing a single range from 0 to highest end time.
     RefPtr<TimeRanges> intersectionRanges = TimeRanges::create(0, highestEndTime);
@@ -169,10 +169,10 @@ PassRefPtr<TimeRanges> MediaSource::buffered() const
 
         // 5.3 Let new intersection ranges equal the the intersection between the intersection ranges and the source ranges.
         // 5.4 Replace the ranges in intersection ranges with the new intersection ranges.
-        intersectionRanges->intersectWith(sourceRanges);
+        intersectionRanges->intersectWith(*sourceRanges);
     }
 
-    return intersectionRanges.release();
+    return PlatformTimeRanges::create(intersectionRanges->ranges());
 }
 
 class SourceBufferBufferedDoesNotContainTime {
index ed0084c..70fe309 100644 (file)
@@ -72,7 +72,7 @@ public:
     // MediaSourcePrivateClient
     virtual void setPrivateAndOpen(PassRef<MediaSourcePrivate>) override;
     virtual double duration() const override;
-    virtual PassRefPtr<TimeRanges> buffered() const override;
+    virtual std::unique_ptr<PlatformTimeRanges> buffered() const override;
 
     bool attachToElement(HTMLMediaElement*);
     void close();
index e642179..be9ceb3 100644 (file)
@@ -967,7 +967,7 @@ void SourceBuffer::sourceBufferPrivateDidReceiveSample(SourceBufferPrivate*, Pas
             }
 
             erasedRanges->invert();
-            m_buffered->intersectWith(erasedRanges.get());
+            m_buffered->intersectWith(*erasedRanges.get());
         }
 
         // 1.17 If spliced audio frame is set:
index 4b9beda..840c163 100644 (file)
@@ -1423,8 +1423,10 @@ __ZN7WebCore9plainTextEPKNS_5RangeENS_20TextIteratorBehaviorEb
 __ZN7WebCore9toElementEN3JSC7JSValueE
 __ZN7WebCore9unionRectERKN3WTF6VectorINS_9FloatRectELm0ENS0_15CrashOnOverflowEEE
 __ZN7WebCore10Pasteboard21createForCopyAndPasteEv
-__ZN7WebCore10TimeRanges13intersectWithEPKS0_
+__ZN7WebCore10TimeRanges6createEv
+__ZN7WebCore10TimeRanges6createEdd
 __ZN7WebCore10TimeRangesC1Edd
+__ZN7WebCore10TimeRanges13intersectWithERKS0_
 __ZN7WebCore13SelectionRectC1ERKNS_7IntRectEbi
 __ZNK3JSC8Bindings10RootObject12globalObjectEv
 __ZNK3WTF6String14createCFStringEv
@@ -1462,6 +1464,7 @@ __ZNK7WebCore10StorageMap8containsERKN3WTF6StringE
 __ZNK7WebCore10TimeRanges3endEjRi
 __ZNK7WebCore10TimeRanges4copyEv
 __ZNK7WebCore10TimeRanges5startEjRi
+__ZNK7WebCore10TimeRanges6lengthEv
 __ZNK7WebCore11FrameLoader10isCompleteEv
 __ZNK7WebCore11FrameLoader14cancelledErrorERKNS_15ResourceRequestE
 __ZNK7WebCore11FrameLoader14frameHasLoadedEv
index b64da1e..ad5f145 100644 (file)
     <ClCompile Include="..\platform\graphics\Path.cpp" />
     <ClCompile Include="..\platform\graphics\PathTraversalState.cpp" />
     <ClCompile Include="..\platform\graphics\Pattern.cpp" />
+    <ClCompile Include="..\platform\graphics\PlatformTimeRanges.cpp" />
     <ClCompile Include="..\platform\graphics\Region.cpp" />
     <ClCompile Include="..\platform\graphics\RoundedRect.cpp" />
     <ClCompile Include="..\platform\graphics\SegmentedFontData.cpp" />
     <ClInclude Include="..\platform\graphics\PathTraversalState.h" />
     <ClInclude Include="..\platform\graphics\Pattern.h" />
     <ClInclude Include="..\platform\graphics\PlatformLayer.h" />
+    <ClInclude Include="..\platform\graphics\PlatformTimeRanges.h" />
     <ClInclude Include="..\platform\graphics\Region.h" />
     <ClInclude Include="..\platform\graphics\RoundedRect.h" />
     <ClInclude Include="..\platform\graphics\SegmentedFontData.h" />
index aef8f09..c55f027 100644 (file)
     <ClCompile Include="..\platform\graphics\Region.cpp">
       <Filter>platform\graphics</Filter>
     </ClCompile>
+    <ClCompile Include="..\platform\graphics\PlatformTimeRanges.cpp">
+      <Filter>platform\graphics</Filter>
+    </ClCompile>
     <ClCompile Include="..\platform\graphics\RoundedRect.cpp">
       <Filter>platform\graphics</Filter>
     </ClCompile>
     <ClInclude Include="..\platform\graphics\PlatformLayer.h">
       <Filter>platform\graphics</Filter>
     </ClInclude>
+    <ClInclude Include="..\platform\graphics\PlatformTimeRanges.h">
+      <Filter>platform\graphics</Filter>
+    </ClInclude>
     <ClInclude Include="..\platform\graphics\Region.h">
       <Filter>platform\graphics</Filter>
     </ClInclude>
index e2b965e..54d03f0 100644 (file)
                073BE35017D181A6002BD431 /* RTCPeerConnectionHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 07221BA817CF0AD400848E51 /* RTCPeerConnectionHandler.cpp */; };
                074300A50F4B8BCF008076CD /* MediaPlayerPrivateIOS.mm in Sources */ = {isa = PBXBuildFile; fileRef = 074300A30F4B8BCF008076CD /* MediaPlayerPrivateIOS.mm */; };
                074300A60F4B8BCF008076CD /* MediaPlayerPrivateIOS.h in Headers */ = {isa = PBXBuildFile; fileRef = 074300A40F4B8BCF008076CD /* MediaPlayerPrivateIOS.h */; };
+               074E82BA18A69F0E007EF54C /* PlatformTimeRanges.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 074E82B818A69F0E007EF54C /* PlatformTimeRanges.cpp */; };
+               074E82BB18A69F0E007EF54C /* PlatformTimeRanges.h in Headers */ = {isa = PBXBuildFile; fileRef = 074E82B918A69F0E007EF54C /* PlatformTimeRanges.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0753860214489E9800B78452 /* CachedTextTrack.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0753860014489E9800B78452 /* CachedTextTrack.cpp */; };
                0753860314489E9800B78452 /* CachedTextTrack.h in Headers */ = {isa = PBXBuildFile; fileRef = 0753860114489E9800B78452 /* CachedTextTrack.h */; };
                076306D017E1478D005A7C4E /* MediaStreamTrackSourcesCallback.h in Headers */ = {isa = PBXBuildFile; fileRef = 076306CC17E1478D005A7C4E /* MediaStreamTrackSourcesCallback.h */; settings = {ATTRIBUTES = (Private, ); }; };
                073BE34717D17E7A002BD431 /* JSNavigatorUserMediaSuccessCallback.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSNavigatorUserMediaSuccessCallback.h; sourceTree = "<group>"; };
                074300A30F4B8BCF008076CD /* MediaPlayerPrivateIOS.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MediaPlayerPrivateIOS.mm; sourceTree = "<group>"; };
                074300A40F4B8BCF008076CD /* MediaPlayerPrivateIOS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MediaPlayerPrivateIOS.h; sourceTree = "<group>"; };
+               074E82B818A69F0E007EF54C /* PlatformTimeRanges.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PlatformTimeRanges.cpp; sourceTree = "<group>"; };
+               074E82B918A69F0E007EF54C /* PlatformTimeRanges.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PlatformTimeRanges.h; sourceTree = "<group>"; };
                0753860014489E9800B78452 /* CachedTextTrack.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CachedTextTrack.cpp; sourceTree = "<group>"; };
                0753860114489E9800B78452 /* CachedTextTrack.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CachedTextTrack.h; sourceTree = "<group>"; };
                076306CC17E1478D005A7C4E /* MediaStreamTrackSourcesCallback.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MediaStreamTrackSourcesCallback.h; sourceTree = "<group>"; };
                                0562F9601573F88F0031CA16 /* PlatformLayer.h */,
                                072847E216EBC5B00043CFA4 /* PlatformTextTrack.h */,
                                072847E316EBC5B00043CFA4 /* PlatformTextTrackMenu.h */,
+                               074E82B818A69F0E007EF54C /* PlatformTimeRanges.cpp */,
+                               074E82B918A69F0E007EF54C /* PlatformTimeRanges.h */,
                                BCAB417F13E356E800D8AAF3 /* Region.cpp */,
                                BCAB418013E356E800D8AAF3 /* Region.h */,
                                A73F95FC12C97BFE0031AAF9 /* RoundedRect.cpp */,
                                297BE3D616C03C0B003316BD /* PlatformSpeechSynthesisVoice.h in Headers */,
                                297BE3D716C03C0E003316BD /* PlatformSpeechSynthesizer.h in Headers */,
                                1AD8F81B11CAB9E900E93E54 /* PlatformStrategies.h in Headers */,
+                               074E82BB18A69F0E007EF54C /* PlatformTimeRanges.h in Headers */,
                                935C476B09AC4D4F00A6AAB4 /* PlatformWheelEvent.h in Headers */,
                                31D591B316697A6C00E6BF02 /* PlugInClient.h in Headers */,
                                A9C6E4F40D745E48006442E9 /* PluginData.h in Headers */,
                                297BE3DA16C043D8003316BD /* PlatformSpeechSynthesizer.cpp in Sources */,
                                297BE3D816C03CCE003316BD /* PlatformSpeechSynthesizerMac.mm in Sources */,
                                1AD8F81C11CAB9E900E93E54 /* PlatformStrategies.cpp in Sources */,
+                               074E82BA18A69F0E007EF54C /* PlatformTimeRanges.cpp in Sources */,
                                A9C6E4F30D745E48006442E9 /* PluginData.cpp in Sources */,
                                97205ABB1239292700B17380 /* PluginDocument.cpp in Sources */,
                                1ADA14100E1AE5D900023EE5 /* PluginMainThreadScheduler.cpp in Sources */,
index fa59bc9..5dd55df 100644 (file)
@@ -3075,10 +3075,11 @@ double HTMLMediaElement::percentLoaded() const
         return 0;
 
     double buffered = 0;
-    RefPtr<TimeRanges> timeRanges = m_player->buffered();
+    bool ignored;
+    std::unique_ptr<PlatformTimeRanges> timeRanges = m_player->buffered();
     for (unsigned i = 0; i < timeRanges->length(); ++i) {
-        double start = timeRanges->start(i, IGNORE_EXCEPTION);
-        double end = timeRanges->end(i, IGNORE_EXCEPTION);
+        double start = timeRanges->start(i, ignored);
+        double end = timeRanges->end(i, ignored);
         buffered += end - start;
     }
     return buffered / duration;
@@ -4112,10 +4113,10 @@ PassRefPtr<TimeRanges> HTMLMediaElement::buffered() const
 
 #if ENABLE(MEDIA_SOURCE)
     if (m_mediaSource)
-        return m_mediaSource->buffered();
+        return TimeRanges::create(*m_mediaSource->buffered());
 #endif
 
-    return m_player->buffered();
+    return TimeRanges::create(*m_player->buffered());
 }
 
 PassRefPtr<TimeRanges> HTMLMediaElement::played()
@@ -4134,7 +4135,10 @@ PassRefPtr<TimeRanges> HTMLMediaElement::played()
 
 PassRefPtr<TimeRanges> HTMLMediaElement::seekable() const
 {
-    return m_player ? m_player->seekable() : TimeRanges::create();
+    if (m_player)
+        return TimeRanges::create(*m_player->seekable());
+
+    return TimeRanges::create();
 }
 
 bool HTMLMediaElement::potentiallyPlaying() const
index a90cb66..e542683 100644 (file)
@@ -95,7 +95,7 @@ PassRefPtr<TimeRanges> MediaController::buffered() const
     // user agent has buffered, at the time the attribute is evaluated.
     RefPtr<TimeRanges> bufferedRanges = m_mediaElements.first()->buffered();
     for (size_t index = 1; index < m_mediaElements.size(); ++index)
-        bufferedRanges->intersectWith(m_mediaElements[index]->buffered().get());
+        bufferedRanges->intersectWith(*m_mediaElements[index]->buffered().get());
     return bufferedRanges;
 }
 
@@ -109,7 +109,7 @@ PassRefPtr<TimeRanges> MediaController::seekable() const
     // user agent is able to seek to, at the time the attribute is evaluated.
     RefPtr<TimeRanges> seekableRanges = m_mediaElements.first()->seekable();
     for (size_t index = 1; index < m_mediaElements.size(); ++index)
-        seekableRanges->intersectWith(m_mediaElements[index]->seekable().get());
+        seekableRanges->intersectWith(*m_mediaElements[index]->seekable().get());
     return seekableRanges;
 }
 
@@ -123,7 +123,7 @@ PassRefPtr<TimeRanges> MediaController::played()
     // user agent has so far rendered, at the time the attribute is evaluated.
     RefPtr<TimeRanges> playedRanges = m_mediaElements.first()->played();
     for (size_t index = 1; index < m_mediaElements.size(); ++index)
-        playedRanges->unionWith(m_mediaElements[index]->played().get());
+        playedRanges->unionWith(*m_mediaElements[index]->played().get());
     return playedRanges;
 }
 
index 34b70a3..ce36af5 100644 (file)
 
 #include "ExceptionCode.h"
 #include "ExceptionCodePlaceholder.h"
-#include <math.h>
 
 namespace WebCore {
 
-TimeRanges::TimeRanges(double start, double end)
+PassRefPtr<TimeRanges> TimeRanges::create()
 {
-    add(start, end);
+    return adoptRef(new TimeRanges);
 }
 
-PassRefPtr<TimeRanges> TimeRanges::copy() const
+PassRefPtr<TimeRanges> TimeRanges::create(double start, double end)
 {
-    RefPtr<TimeRanges> newSession = TimeRanges::create();
-    
-    unsigned size = m_ranges.size();
-    for (unsigned i = 0; i < size; i++)
-        newSession->add(m_ranges[i].m_start, m_ranges[i].m_end);
-    
-    return newSession.release();
+    return adoptRef(new TimeRanges(start, end));
 }
 
-void TimeRanges::invert()
+PassRefPtr<TimeRanges> TimeRanges::create(const PlatformTimeRanges& other)
 {
-    RefPtr<TimeRanges> inverted = TimeRanges::create();
-    double posInf = std::numeric_limits<double>::infinity();
-    double negInf = -std::numeric_limits<double>::infinity();
-
-    if (!m_ranges.size())
-        inverted->add(negInf, posInf);
-    else {
-        double start = m_ranges.first().m_start;
-        if (start != negInf)
-            inverted->add(negInf, start);
-
-        for (size_t index = 0; index + 1 < m_ranges.size(); ++index)
-            inverted->add(m_ranges[index].m_end, m_ranges[index + 1].m_start);
-
-        double end = m_ranges.last().m_end;
-        if (end != posInf)
-            inverted->add(end, posInf);
-    }
-
-    m_ranges.swap(inverted->m_ranges);
+    return adoptRef(new TimeRanges(other));
 }
 
-void TimeRanges::intersectWith(const TimeRanges* other)
+TimeRanges::TimeRanges()
 {
-    ASSERT(other);
-
-    if (other == this)
-        return;
-
-    RefPtr<TimeRanges> invertedOther = other->copy();
-    invertedOther->invert();
-
-    invert();
-    unionWith(invertedOther.get());
-    invert();
 }
 
-void TimeRanges::unionWith(const TimeRanges* other)
+TimeRanges::TimeRanges(double start, double end)
+    : m_ranges(PlatformTimeRanges(start, end))
 {
-    ASSERT(other);
-    RefPtr<TimeRanges> unioned = copy();
-    for (size_t index = 0; index < other->m_ranges.size(); ++index) {
-        const Range& range = other->m_ranges[index];
-        unioned->add(range.m_start, range.m_end);
-    }
+}
 
-    m_ranges.swap(unioned->m_ranges);
+TimeRanges::TimeRanges(const PlatformTimeRanges& other)
+    : m_ranges(other)
+{
 }
 
-double TimeRanges::start(unsigned index, ExceptionCode& ec) const 
-{ 
-    if (index >= length()) {
+double TimeRanges::start(unsigned index, ExceptionCode& ec) const
+{
+    bool valid;
+    double result = m_ranges.start(index, valid);
+
+    if (!valid) {
         ec = INDEX_SIZE_ERR;
         return 0;
     }
-    return m_ranges[index].m_start;
+    return result;
 }
 
 double TimeRanges::end(unsigned index, ExceptionCode& ec) const 
 { 
-    if (index >= length()) {
+    bool valid;
+    double result = m_ranges.end(index, valid);
+
+    if (!valid) {
         ec = INDEX_SIZE_ERR;
         return 0;
     }
-    return m_ranges[index].m_end;
-}
-
-void TimeRanges::add(double start, double end) 
-{
-    ASSERT(start <= end);
-    unsigned int overlappingArcIndex;
-    Range addedRange(start, end);
-
-    // For each present range check if we need to:
-    // - merge with the added range, in case we are overlapping or contiguous
-    // - Need to insert in place, we we are completely, not overlapping and not contiguous
-    // in between two ranges.
-    //
-    // TODO: Given that we assume that ranges are correctly ordered, this could be optimized.
-
-    for (overlappingArcIndex = 0; overlappingArcIndex < m_ranges.size(); overlappingArcIndex++) {
-        if (addedRange.isOverlappingRange(m_ranges[overlappingArcIndex])
-         || addedRange.isContiguousWithRange(m_ranges[overlappingArcIndex])) {
-            // We need to merge the addedRange and that range.
-            addedRange = addedRange.unionWithOverlappingOrContiguousRange(m_ranges[overlappingArcIndex]);
-            m_ranges.remove(overlappingArcIndex);
-            overlappingArcIndex--;
-        } else {
-            // Check the case for which there is no more to do
-            if (!overlappingArcIndex) {
-                if (addedRange.isBeforeRange(m_ranges[0])) {
-                    // First index, and we are completely before that range (and not contiguous, nor overlapping).
-                    // We just need to be inserted here.
-                    break;
-                }
-            } else {
-                if (m_ranges[overlappingArcIndex - 1].isBeforeRange(addedRange)
-                 && addedRange.isBeforeRange(m_ranges[overlappingArcIndex])) {
-                    // We are exactly after the current previous range, and before the current range, while
-                    // not overlapping with none of them. Insert here.
-                    break;
-                }
-            }
-        }
-    }
+    return result;
+}
 
-    // Now that we are sure we don't overlap with any range, just add it.
-    m_ranges.insert(overlappingArcIndex, addedRange);
+void TimeRanges::invert()
+{
+    m_ranges.invert();
+}
+
+PassRefPtr<TimeRanges> TimeRanges::copy() const
+{
+    return TimeRanges::create(m_ranges);
+}
+
+void TimeRanges::intersectWith(const TimeRanges& other)
+{
+    m_ranges.intersectWith(other.ranges());
+}
+
+void TimeRanges::unionWith(const TimeRanges& other)
+{
+    m_ranges.unionWith(other.ranges());
+}
+
+unsigned TimeRanges::length() const
+{
+    return m_ranges.length();
+}
+
+void TimeRanges::add(double start, double end)
+{
+    m_ranges.add(start, end);
 }
 
 bool TimeRanges::contain(double time) const
 {
-    return find(time) != notFound;
+    return m_ranges.contain(time);
 }
 
 size_t TimeRanges::find(double time) const
 {
-    for (unsigned n = 0; n < length(); n++) {
-        if (time >= start(n, IGNORE_EXCEPTION) && time <= end(n, IGNORE_EXCEPTION))
-            return n;
-    }
-    return notFound;
+    return m_ranges.find(time);
 }
 
 double TimeRanges::nearest(double time) const
 {
-    double closestDelta = std::numeric_limits<double>::infinity();
-    double closestTime = 0;
-    unsigned count = length();
-    for (unsigned ndx = 0; ndx < count; ndx++) {
-        double startTime = start(ndx, IGNORE_EXCEPTION);
-        double endTime = end(ndx, IGNORE_EXCEPTION);
-        if (time >= startTime && time <= endTime)
-            return time;
-        if (fabs(startTime - time) < closestDelta) {
-            closestTime = startTime;
-            closestDelta = fabsf(startTime - time);
-        }
-        if (fabs(endTime - time) < closestDelta) {
-            closestTime = endTime;
-            closestDelta = fabsf(endTime - time);
-        }
-    }
-    return closestTime;
+    return m_ranges.nearest(time);
 }
 
 double TimeRanges::totalDuration() const
 {
-    double total = 0;
-    for (unsigned n = 0; n < length(); n++)
-        total += fabs(end(n, IGNORE_EXCEPTION) - start(n, IGNORE_EXCEPTION));
-    return total;
+    return m_ranges.totalDuration();
 }
 
 }
index 72233be..73e1cb4 100644 (file)
@@ -26,6 +26,7 @@
 #ifndef TimeRanges_h
 #define TimeRanges_h
 
+#include "PlatformTimeRanges.h"
 #include <algorithm>
 #include <wtf/PassRefPtr.h>
 #include <wtf/RefCounted.h>
@@ -37,82 +38,36 @@ typedef int ExceptionCode;
 
 class TimeRanges : public RefCounted<TimeRanges> {
 public:
-    static PassRefPtr<TimeRanges> create() 
-    {
-        return adoptRef(new TimeRanges);
-    }
-    static PassRefPtr<TimeRanges> create(double start, double end)
-    {
-        return adoptRef(new TimeRanges(start, end));
-    }
+    static PassRefPtr<TimeRanges> create();
+    static PassRefPtr<TimeRanges> create(double start, double end);
+    static PassRefPtr<TimeRanges> create(const PlatformTimeRanges&);
 
-    PassRefPtr<TimeRanges> copy() const;
-    void invert();
-    void intersectWith(const TimeRanges*);
-    void unionWith(const TimeRanges*);
-
-    unsigned length() const { return m_ranges.size(); }
     double start(unsigned index, ExceptionCode&) const;
     double end(unsigned index, ExceptionCode&) const;
 
-    void add(double start, double end);
+    PassRefPtr<TimeRanges> copy() const;
+    void invert();
+    void intersectWith(const TimeRanges&);
+    void unionWith(const TimeRanges&);
     
-    bool contain(double time) const;
+    unsigned length() const;
 
-    size_t find(double time) const;
+    void add(double start, double end);
+    bool contain(double time) const;
     
+    size_t find(double time) const;
     double nearest(double time) const;
-
     double totalDuration() const;
 
+    const PlatformTimeRanges& ranges() const { return m_ranges; }
+
 private:
-    TimeRanges() { }
+    explicit TimeRanges();
     TimeRanges(double start, double end);
-    TimeRanges(const TimeRanges&);
-
-    // We consider all the Ranges to be semi-bounded as follow: [start, end[
-    struct Range {
-        Range() { }
-        Range(double start, double end)
-        {
-            m_start = start;
-            m_end = end;
-        }
-        double m_start;
-        double m_end;
+    TimeRanges(const PlatformTimeRanges&);
 
-        inline bool isPointInRange(double point) const
-        {
-            return m_start <= point && point < m_end;
-        }
-        
-        inline bool isOverlappingRange(const Range& range) const
-        {
-            return isPointInRange(range.m_start) || isPointInRange(range.m_end) || range.isPointInRange(m_start);
-        }
 
-        inline bool isContiguousWithRange(const Range& range) const
-        {
-            return range.m_start == m_end || range.m_end == m_start;
-        }
-        
-        inline Range unionWithOverlappingOrContiguousRange(const Range& range) const
-        {
-            Range ret;
-
-            ret.m_start = std::min(m_start, range.m_start);
-            ret.m_end = std::max(m_end, range.m_end);
-
-            return ret;
-        }
-
-        inline bool isBeforeRange(const Range& range) const
-        {
-            return range.m_start >= m_end;
-        }
-    };
-    
-    Vector<Range> m_ranges;
+    PlatformTimeRanges m_ranges;
 };
 
 } // namespace WebCore
index 475454e..42fa2ec 100644 (file)
@@ -36,8 +36,8 @@
 #include "Logging.h"
 #include "MIMETypeRegistry.h"
 #include "MediaPlayerPrivate.h"
+#include "PlatformTimeRanges.h"
 #include "Settings.h"
-#include "TimeRanges.h"
 #include <wtf/text/CString.h>
 
 #if ENABLE(VIDEO_TRACK)
@@ -127,7 +127,7 @@ public:
 
     virtual double maxTimeSeekableDouble() const { return 0; }
     virtual double minTimeSeekable() const { return 0; }
-    virtual PassRefPtr<TimeRanges> buffered() const { return TimeRanges::create(); }
+    virtual std::unique_ptr<PlatformTimeRanges> buffered() const { return PlatformTimeRanges::create(); }
 
     virtual unsigned totalBytes() const { return 0; }
     virtual bool didLoadingProgress() const { return false; }
@@ -703,12 +703,12 @@ void MediaPlayer::setPreservesPitch(bool preservesPitch)
     m_private->setPreservesPitch(preservesPitch);
 }
 
-PassRefPtr<TimeRanges> MediaPlayer::buffered()
+std::unique_ptr<PlatformTimeRanges> MediaPlayer::buffered()
 {
     return m_private->buffered();
 }
 
-PassRefPtr<TimeRanges> MediaPlayer::seekable()
+std::unique_ptr<PlatformTimeRanges> MediaPlayer::seekable()
 {
     return m_private->seekable();
 }
index 8ca9131..fc6558b 100644 (file)
@@ -128,12 +128,12 @@ class ContentType;
 class FrameView;
 class GraphicsContext;
 class GraphicsContext3D;
+class HostWindow;
 class IntRect;
 class IntSize;
 class MediaPlayer;
 struct MediaPlayerFactory;
-class TimeRanges;
-class HostWindow;
+class PlatformTimeRanges;
 
 #if PLATFORM(WIN) && USE(AVFOUNDATION)
 struct GraphicsDeviceAdapter;
@@ -352,8 +352,8 @@ public:
     bool preservesPitch() const;
     void setPreservesPitch(bool);
 
-    PassRefPtr<TimeRanges> buffered();
-    PassRefPtr<TimeRanges> seekable();
+    std::unique_ptr<PlatformTimeRanges> buffered();
+    std::unique_ptr<PlatformTimeRanges> seekable();
     double minTimeSeekable();
     double maxTimeSeekable();
 
index cccfb4e..8e2b356 100644 (file)
@@ -29,8 +29,9 @@
 #if ENABLE(VIDEO)
 
 #include "MediaPlayer.h"
-#include "TimeRanges.h"
+#include "PlatformTimeRanges.h"
 #include <wtf/Forward.h>
+#include <wtf/OwnPtr.h>
 
 namespace WebCore {
 
@@ -108,11 +109,11 @@ public:
     virtual MediaPlayer::NetworkState networkState() const = 0;
     virtual MediaPlayer::ReadyState readyState() const = 0;
 
-    virtual PassRefPtr<TimeRanges> seekable() const { return maxTimeSeekableDouble() ? TimeRanges::create(minTimeSeekable(), maxTimeSeekableDouble()) : TimeRanges::create(); }
+    virtual std::unique_ptr<PlatformTimeRanges> seekable() const { return maxTimeSeekableDouble() ? PlatformTimeRanges::create(minTimeSeekable(), maxTimeSeekableDouble()) : PlatformTimeRanges::create(); }
     virtual float maxTimeSeekable() const { return 0; }
     virtual double maxTimeSeekableDouble() const { return maxTimeSeekable(); }
     virtual double minTimeSeekable() const { return 0; }
-    virtual PassRefPtr<TimeRanges> buffered() const = 0;
+    virtual std::unique_ptr<PlatformTimeRanges> buffered() const = 0;
 
     virtual bool didLoadingProgress() const = 0;
 
index 22e456c..4071973 100644 (file)
@@ -28,7 +28,7 @@
 
 #if ENABLE(MEDIA_SOURCE)
 
-#include "TimeRanges.h"
+#include "PlatformTimeRanges.h"
 #include <wtf/RefCounted.h>
 
 namespace WebCore {
@@ -41,7 +41,7 @@ public:
 
     virtual void setPrivateAndOpen(PassRef<MediaSourcePrivate>) = 0;
     virtual double duration() const = 0;
-    virtual PassRefPtr<TimeRanges> buffered() const = 0;
+    virtual std::unique_ptr<PlatformTimeRanges> buffered() const = 0;
 };
 
 }
diff --git a/Source/WebCore/platform/graphics/PlatformTimeRanges.cpp b/Source/WebCore/platform/graphics/PlatformTimeRanges.cpp
new file mode 100644 (file)
index 0000000..4a457b5
--- /dev/null
@@ -0,0 +1,230 @@
+/*
+ * Copyright (C) 2014 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 "PlatformTimeRanges.h"
+
+#include <math.h>
+
+namespace WebCore {
+
+std::unique_ptr<PlatformTimeRanges> PlatformTimeRanges::create()
+{
+    return std::make_unique<PlatformTimeRanges>();
+}
+
+std::unique_ptr<PlatformTimeRanges> PlatformTimeRanges::create(double start, double end)
+{
+    return std::make_unique<PlatformTimeRanges>(start, end);
+}
+
+std::unique_ptr<PlatformTimeRanges> PlatformTimeRanges::create(const PlatformTimeRanges& other)
+{
+    return std::make_unique<PlatformTimeRanges>(other);
+}
+    
+PlatformTimeRanges::PlatformTimeRanges(double start, double end)
+{
+    add(start, end);
+}
+
+PlatformTimeRanges::PlatformTimeRanges(const PlatformTimeRanges& other)
+{
+    copy(other);
+}
+
+PlatformTimeRanges& PlatformTimeRanges::operator=(const PlatformTimeRanges& other)
+{
+    return copy(other);
+}
+
+PlatformTimeRanges& PlatformTimeRanges::copy(const PlatformTimeRanges& other)
+{
+    unsigned size = other.m_ranges.size();
+    for (unsigned i = 0; i < size; i++)
+        add(other.m_ranges[i].m_start, other.m_ranges[i].m_end);
+    
+    return *this;
+}
+
+void PlatformTimeRanges::invert()
+{
+    PlatformTimeRanges inverted;
+    double posInf = std::numeric_limits<double>::infinity();
+    double negInf = -std::numeric_limits<double>::infinity();
+
+    if (!m_ranges.size())
+        inverted.add(negInf, posInf);
+    else {
+        double start = m_ranges.first().m_start;
+        if (start != negInf)
+            inverted.add(negInf, start);
+
+        for (size_t index = 0; index + 1 < m_ranges.size(); ++index)
+            inverted.add(m_ranges[index].m_end, m_ranges[index + 1].m_start);
+
+        double end = m_ranges.last().m_end;
+        if (end != posInf)
+            inverted.add(end, posInf);
+    }
+
+    m_ranges.swap(inverted.m_ranges);
+}
+
+void PlatformTimeRanges::intersectWith(const PlatformTimeRanges& other)
+{
+    PlatformTimeRanges invertedOther(other);
+
+    invertedOther.invert();
+    invert();
+    unionWith(invertedOther);
+    invert();
+}
+
+void PlatformTimeRanges::unionWith(const PlatformTimeRanges& other)
+{
+    PlatformTimeRanges unioned(*this);
+
+    for (size_t index = 0; index < other.m_ranges.size(); ++index) {
+        const Range& range = other.m_ranges[index];
+        unioned.add(range.m_start, range.m_end);
+    }
+
+    m_ranges.swap(unioned.m_ranges);
+}
+
+double PlatformTimeRanges::start(unsigned index, bool& valid) const
+{ 
+    if (index >= length()) {
+        valid = false;
+        return 0;
+    }
+    
+    valid = true;
+    return m_ranges[index].m_start;
+}
+
+double PlatformTimeRanges::end(unsigned index, bool& valid) const
+{ 
+    if (index >= length()) {
+        valid = false;
+        return 0;
+    }
+
+    valid = true;
+    return m_ranges[index].m_end;
+}
+
+void PlatformTimeRanges::add(double start, double end)
+{
+    ASSERT(start <= end);
+    unsigned overlappingArcIndex;
+    Range addedRange(start, end);
+
+    // For each present range check if we need to:
+    // - merge with the added range, in case we are overlapping or contiguous
+    // - Need to insert in place, we we are completely, not overlapping and not contiguous
+    // in between two ranges.
+    //
+    // TODO: Given that we assume that ranges are correctly ordered, this could be optimized.
+
+    for (overlappingArcIndex = 0; overlappingArcIndex < m_ranges.size(); overlappingArcIndex++) {
+        if (addedRange.isOverlappingRange(m_ranges[overlappingArcIndex]) || addedRange.isContiguousWithRange(m_ranges[overlappingArcIndex])) {
+            // We need to merge the addedRange and that range.
+            addedRange = addedRange.unionWithOverlappingOrContiguousRange(m_ranges[overlappingArcIndex]);
+            m_ranges.remove(overlappingArcIndex);
+            overlappingArcIndex--;
+        } else {
+            // Check the case for which there is no more to do
+            if (!overlappingArcIndex) {
+                if (addedRange.isBeforeRange(m_ranges[0])) {
+                    // First index, and we are completely before that range (and not contiguous, nor overlapping).
+                    // We just need to be inserted here.
+                    break;
+                }
+            } else {
+                if (m_ranges[overlappingArcIndex - 1].isBeforeRange(addedRange) && addedRange.isBeforeRange(m_ranges[overlappingArcIndex])) {
+                    // We are exactly after the current previous range, and before the current range, while
+                    // not overlapping with none of them. Insert here.
+                    break;
+                }
+            }
+        }
+    }
+
+    // Now that we are sure we don't overlap with any range, just add it.
+    m_ranges.insert(overlappingArcIndex, addedRange);
+}
+
+bool PlatformTimeRanges::contain(double time) const
+{
+    return find(time) != notFound;
+}
+
+size_t PlatformTimeRanges::find(double time) const
+{
+    bool ignoreInvalid;
+    for (unsigned n = 0; n < length(); n++) {
+        if (time >= start(n, ignoreInvalid) && time <= end(n, ignoreInvalid))
+            return n;
+    }
+    return notFound;
+}
+
+double PlatformTimeRanges::nearest(double time) const
+{
+    double closestDelta = std::numeric_limits<double>::infinity();
+    double closestTime = 0;
+    unsigned count = length();
+    bool ignoreInvalid;
+
+    for (unsigned ndx = 0; ndx < count; ndx++) {
+        double startTime = start(ndx, ignoreInvalid);
+        double endTime = end(ndx, ignoreInvalid);
+        if (time >= startTime && time <= endTime)
+            return time;
+        if (fabs(startTime - time) < closestDelta) {
+            closestTime = startTime;
+            closestDelta = fabsf(startTime - time);
+        }
+        if (fabs(endTime - time) < closestDelta) {
+            closestTime = endTime;
+            closestDelta = fabsf(endTime - time);
+        }
+    }
+    return closestTime;
+}
+
+double PlatformTimeRanges::totalDuration() const
+{
+    double total = 0;
+    bool ignoreInvalid;
+
+    for (unsigned n = 0; n < length(); n++)
+        total += fabs(end(n, ignoreInvalid) - start(n, ignoreInvalid));
+    return total;
+}
+
+}
diff --git a/Source/WebCore/platform/graphics/PlatformTimeRanges.h b/Source/WebCore/platform/graphics/PlatformTimeRanges.h
new file mode 100644 (file)
index 0000000..7866833
--- /dev/null
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2014 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 PlatformTimeRanges_h
+#define PlatformTimeRanges_h
+
+#include <algorithm>
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefCounted.h>
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+class PlatformTimeRanges {
+public:
+    static std::unique_ptr<PlatformTimeRanges> create();
+    static std::unique_ptr<PlatformTimeRanges> create(double start, double end);
+    static std::unique_ptr<PlatformTimeRanges> create(const PlatformTimeRanges&);
+
+    explicit PlatformTimeRanges() { }
+    PlatformTimeRanges(double start, double end);
+    PlatformTimeRanges(const PlatformTimeRanges&);
+
+    PlatformTimeRanges& operator=(const PlatformTimeRanges&);
+
+    double start(unsigned index, bool& valid) const;
+    double end(unsigned index, bool& valid) const;
+
+    void invert();
+    void intersectWith(const PlatformTimeRanges&);
+    void unionWith(const PlatformTimeRanges&);
+
+    unsigned length() const { return m_ranges.size(); }
+
+    void add(double start, double end);
+    
+    bool contain(double time) const;
+
+    size_t find(double time) const;
+    
+    double nearest(double time) const;
+
+    double totalDuration() const;
+
+private:
+    PlatformTimeRanges& copy(const PlatformTimeRanges&);
+
+    // We consider all the Ranges to be semi-bounded as follow: [start, end[
+    struct Range {
+        Range() { }
+        Range(double start, double end)
+        {
+            m_start = start;
+            m_end = end;
+        }
+        double m_start;
+        double m_end;
+
+        inline bool isPointInRange(double point) const
+        {
+            return m_start <= point && point < m_end;
+        }
+        
+        inline bool isOverlappingRange(const Range& range) const
+        {
+            return isPointInRange(range.m_start) || isPointInRange(range.m_end) || range.isPointInRange(m_start);
+        }
+
+        inline bool isContiguousWithRange(const Range& range) const
+        {
+            return range.m_start == m_end || range.m_end == m_start;
+        }
+        
+        inline Range unionWithOverlappingOrContiguousRange(const Range& range) const
+        {
+            Range ret;
+
+            ret.m_start = std::min(m_start, range.m_start);
+            ret.m_end = std::max(m_end, range.m_end);
+
+            return ret;
+        }
+
+        inline bool isBeforeRange(const Range& range) const
+        {
+            return range.m_start >= m_end;
+        }
+    };
+    
+    Vector<Range> m_ranges;
+};
+
+} // namespace WebCore
+
+#endif
index 0f233d0..c5e12f1 100644 (file)
 #include "URL.h"
 #include "Logging.h"
 #include "PlatformLayer.h"
+#include "PlatformTimeRanges.h"
 #include "Settings.h"
 #include "SoftLinking.h"
-#include "TimeRanges.h"
 #include <CoreMedia/CoreMedia.h>
 #include <wtf/MainThread.h>
+#include <wtf/text/CString.h>
 
 namespace WebCore {
 
@@ -385,12 +386,12 @@ void MediaPlayerPrivateAVFoundation::setDelayCharacteristicsChangedNotification(
         characteristicsChanged();
 }
 
-PassRefPtr<TimeRanges> MediaPlayerPrivateAVFoundation::buffered() const
+std::unique_ptr<PlatformTimeRanges> MediaPlayerPrivateAVFoundation::buffered() const
 {
     if (!m_cachedLoadedTimeRanges)
         m_cachedLoadedTimeRanges = platformBufferedTimeRanges();
 
-    return m_cachedLoadedTimeRanges->copy();
+    return PlatformTimeRanges::create(*m_cachedLoadedTimeRanges);
 }
 
 double MediaPlayerPrivateAVFoundation::maxTimeSeekableDouble() const
@@ -620,7 +621,7 @@ void MediaPlayerPrivateAVFoundation::rateChanged()
 
 void MediaPlayerPrivateAVFoundation::loadedTimeRangesChanged()
 {
-    m_cachedLoadedTimeRanges = 0;
+    m_cachedLoadedTimeRanges = nullptr;
     m_cachedMaxTimeLoaded = 0;
     invalidateCachedDuration();
 }
@@ -768,8 +769,9 @@ static const char* notificationName(MediaPlayerPrivateAVFoundation::Notification
 {
 #define DEFINE_TYPE_STRING_CASE(type) case MediaPlayerPrivateAVFoundation::Notification::type: return #type;
     switch (notification.type()) {
-        FOR_EACH_MEDIAPLAYERPRIVATEAVFOUNDATION_NOTIFICATION_TYPE(DEFINE_TYPE_STRING_CASE)
-        default: return "";
+    FOR_EACH_MEDIAPLAYERPRIVATEAVFOUNDATION_NOTIFICATION_TYPE(DEFINE_TYPE_STRING_CASE)
+    case MediaPlayerPrivateAVFoundation::Notification::FunctionType: return "FunctionType";
+    default: ASSERT_NOT_REACHED(); return "";
     }
 #undef DEFINE_TYPE_STRING_CASE
 }
index aea02ff..da85955 100644 (file)
@@ -174,7 +174,7 @@ protected:
     virtual MediaPlayer::ReadyState readyState() const override { return m_readyState; }
     virtual double maxTimeSeekableDouble() const override;
     virtual double minTimeSeekable() const override;
-    virtual PassRefPtr<TimeRanges> buffered() const override;
+    virtual std::unique_ptr<PlatformTimeRanges> buffered() const override;
     virtual bool didLoadingProgress() const override;
     virtual void setSize(const IntSize&) override;
     virtual void paint(GraphicsContext*, const IntRect&) = 0;
@@ -229,7 +229,7 @@ protected:
     virtual float rate() const = 0;
     virtual void seekToTime(double time, double negativeTolerance, double positiveTolerance) = 0;
     virtual unsigned long long totalBytes() const = 0;
-    virtual PassRefPtr<TimeRanges> platformBufferedTimeRanges() const = 0;
+    virtual std::unique_ptr<PlatformTimeRanges> platformBufferedTimeRanges() const = 0;
     virtual double platformMaxTimeSeekable() const = 0;
     virtual double platformMinTimeSeekable() const = 0;
     virtual float platformMaxTimeLoaded() const = 0;
@@ -304,7 +304,7 @@ private:
     Vector<Notification> m_queuedNotifications;
     mutable Mutex m_queueMutex;
 
-    mutable RefPtr<TimeRanges> m_cachedLoadedTimeRanges;
+    mutable std::unique_ptr<PlatformTimeRanges> m_cachedLoadedTimeRanges;
 
     MediaPlayer::NetworkState m_networkState;
     MediaPlayer::ReadyState m_readyState;
index 5923d7d..6bd49a2 100644 (file)
@@ -618,16 +618,16 @@ static bool timeRangeIsValidAndNotEmpty(CMTime start, CMTime duration)
     return true;
 }
 
-PassRefPtr<TimeRanges> MediaPlayerPrivateAVFoundationCF::platformBufferedTimeRanges() const
+std::unique_ptr<PlatformTimeRanges> MediaPlayerPrivateAVFoundationCF::platformBufferedTimeRanges() const
 {
-    RefPtr<TimeRanges> timeRanges = TimeRanges::create();
+    auto timeRanges = PlatformTimeRanges::create();
 
     if (!avPlayerItem(m_avfWrapper))
-        return timeRanges.release();
+        return timeRanges;
 
     RetainPtr<CFArrayRef> loadedRanges = adoptCF(AVCFPlayerItemCopyLoadedTimeRanges(avPlayerItem(m_avfWrapper)));
     if (!loadedRanges)
-        return timeRanges.release();
+        return timeRanges;
 
     CFIndex rangeCount = CFArrayGetCount(loadedRanges.get());
     for (CFIndex i = 0; i < rangeCount; i++) {
@@ -642,7 +642,7 @@ PassRefPtr<TimeRanges> MediaPlayerPrivateAVFoundationCF::platformBufferedTimeRan
         }
     }
 
-    return timeRanges.release();
+    return timeRanges;
 }
 
 double MediaPlayerPrivateAVFoundationCF::platformMinTimeSeekable() const 
index 20b74e5..b443784 100644 (file)
@@ -78,7 +78,7 @@ private:
     virtual float rate() const;
     virtual void seekToTime(double time, double negativeTolerance, double positiveTolerance);
     virtual unsigned long long totalBytes() const;
-    virtual PassRefPtr<TimeRanges> platformBufferedTimeRanges() const;
+    virtual std::unique_ptr<PlatformTimeRanges> platformBufferedTimeRanges() const;
     virtual double platformMinTimeSeekable() const;
     virtual double platformMaxTimeSeekable() const;
     virtual float platformDuration() const;
index c977a03..611ac6d 100644 (file)
@@ -153,7 +153,7 @@ private:
     virtual float rate() const;
     virtual void seekToTime(double time, double negativeTolerance, double positiveTolerance);
     virtual unsigned long long totalBytes() const;
-    virtual PassRefPtr<TimeRanges> platformBufferedTimeRanges() const;
+    virtual std::unique_ptr<PlatformTimeRanges> platformBufferedTimeRanges() const;
     virtual double platformMinTimeSeekable() const;
     virtual double platformMaxTimeSeekable() const;
     virtual float platformDuration() const;
index ab27d2e..ee83d8b 100644 (file)
@@ -43,9 +43,9 @@
 #import "InbandTextTrackPrivateLegacyAVFObjC.h"
 #import "URL.h"
 #import "Logging.h"
+#import "PlatformTimeRanges.h"
 #import "SecurityOrigin.h"
 #import "SoftLinking.h"
-#import "TimeRanges.h"
 #import "UUID.h"
 #import "VideoTrackPrivateAVFObjC.h"
 #import "WebCoreAVFResourceLoader.h"
@@ -752,12 +752,12 @@ float MediaPlayerPrivateAVFoundationObjC::rate() const
     return m_cachedRate;
 }
 
-PassRefPtr<TimeRanges> MediaPlayerPrivateAVFoundationObjC::platformBufferedTimeRanges() const
+std::unique_ptr<PlatformTimeRanges> MediaPlayerPrivateAVFoundationObjC::platformBufferedTimeRanges() const
 {
-    RefPtr<TimeRanges> timeRanges = TimeRanges::create();
+    auto timeRanges = PlatformTimeRanges::create();
 
     if (!m_avPlayerItem)
-        return timeRanges.release();
+        return timeRanges;
 
     for (NSValue *thisRangeValue in m_cachedLoadedRanges.get()) {
         CMTimeRange timeRange = [thisRangeValue CMTimeRangeValue];
@@ -767,7 +767,7 @@ PassRefPtr<TimeRanges> MediaPlayerPrivateAVFoundationObjC::platformBufferedTimeR
             timeRanges->add(rangeStart, rangeEnd);
         }
     }
-    return timeRanges.release();
+    return timeRanges;
 }
 
 double MediaPlayerPrivateAVFoundationObjC::platformMinTimeSeekable() const
index 73d4b5a..bc92efc 100644 (file)
@@ -116,10 +116,10 @@ private:
     virtual bool seeking() const override;
     virtual void setRateDouble(double) override;
 
-    virtual PassRefPtr<TimeRanges> seekable() const override;
+    virtual std::unique_ptr<PlatformTimeRanges> seekable() const override;
     virtual double maxTimeSeekableDouble() const override;
     virtual double minTimeSeekable() const override;
-    virtual PassRefPtr<TimeRanges> buffered() const override;
+    virtual std::unique_ptr<PlatformTimeRanges> buffered() const override;
 
     virtual bool didLoadingProgress() const override;
 
index 57cdd9e..53972f8 100644 (file)
@@ -388,9 +388,9 @@ MediaPlayer::ReadyState MediaPlayerPrivateMediaSourceAVFObjC::readyState() const
     return m_readyState;
 }
 
-PassRefPtr<TimeRanges> MediaPlayerPrivateMediaSourceAVFObjC::seekable() const
+std::unique_ptr<PlatformTimeRanges> MediaPlayerPrivateMediaSourceAVFObjC::seekable() const
 {
-    return TimeRanges::create(minTimeSeekable(), maxTimeSeekableDouble());
+    return PlatformTimeRanges::create(minTimeSeekable(), maxTimeSeekableDouble());
 }
 
 double MediaPlayerPrivateMediaSourceAVFObjC::maxTimeSeekableDouble() const
@@ -403,7 +403,7 @@ double MediaPlayerPrivateMediaSourceAVFObjC::minTimeSeekable() const
     return startTimeDouble();
 }
 
-PassRefPtr<TimeRanges> MediaPlayerPrivateMediaSourceAVFObjC::buffered() const
+std::unique_ptr<PlatformTimeRanges> MediaPlayerPrivateMediaSourceAVFObjC::buffered() const
 {
     return m_mediaSource->buffered();
 }
index 31724eb..5e1667e 100644 (file)
@@ -890,22 +890,22 @@ void MediaPlayerPrivateGStreamer::setPreservesPitch(bool preservesPitch)
     m_preservesPitch = preservesPitch;
 }
 
-PassRefPtr<TimeRanges> MediaPlayerPrivateGStreamer::buffered() const
+std::unique_ptr<PlatformTimeRanges> MediaPlayerPrivateGStreamer::buffered() const
 {
-    RefPtr<TimeRanges> timeRanges = TimeRanges::create();
+    auto timeRanges = PlatformTimeRanges::create();
     if (m_errorOccured || isLiveStream())
-        return timeRanges.release();
+        return timeRanges;
 
 #if GST_CHECK_VERSION(0, 10, 31)
     float mediaDuration(duration());
     if (!mediaDuration || std::isinf(mediaDuration))
-        return timeRanges.release();
+        return timeRanges;
 
     GstQuery* query = gst_query_new_buffering(GST_FORMAT_PERCENT);
 
     if (!gst_element_query(m_playBin.get(), query)) {
         gst_query_unref(query);
-        return timeRanges.release();
+        return timeRanges;
     }
 
     for (guint index = 0; index < gst_query_get_n_buffering_ranges(query); index++) {
@@ -927,7 +927,7 @@ PassRefPtr<TimeRanges> MediaPlayerPrivateGStreamer::buffered() const
     if (!m_errorOccured && !isLiveStream() && loaded > 0)
         timeRanges->add(0, loaded);
 #endif
-    return timeRanges.release();
+    return timeRanges;
 }
 
 gboolean MediaPlayerPrivateGStreamer::handleMessage(GstMessage* message)
index 479a744..a370da3 100644 (file)
@@ -81,7 +81,7 @@ public:
     void setPreload(MediaPlayer::Preload);
     void fillTimerFired(Timer<MediaPlayerPrivateGStreamer>*);
 
-    PassRefPtr<TimeRanges> buffered() const;
+    std::unique_ptr<PlatformTimeRanges> buffered() const;
     float maxTimeSeekable() const;
     bool didLoadingProgress() const;
     unsigned totalBytes() const;
index 7a4f6c5..1788b49 100644 (file)
@@ -119,7 +119,7 @@ private:
     
     float maxTimeBuffered() const;
     virtual float maxTimeSeekable() const override;
-    virtual PassRefPtr<TimeRanges> buffered() const override;
+    virtual std::unique_ptr<PlatformTimeRanges> buffered() const override;
 
     virtual bool didLoadingProgress() const override;
     bool totalBytesKnown() const;
index 52bb019..2f96af2 100644 (file)
@@ -497,16 +497,16 @@ float MediaPlayerPrivateIOS::maxTimeSeekable() const
     return [m_mediaPlayerHelper.get() _maxTimeSeekable];
 }
 
-PassRefPtr<TimeRanges> MediaPlayerPrivateIOS::buffered() const
+std::unique_ptr<PlatformTimeRanges> MediaPlayerPrivateIOS::buffered()
 {
-    RefPtr<TimeRanges> timeRanges = TimeRanges::create();
+    auto timeRanges = PlatformTimeRanges::create();
 
     if (!m_mediaPlayerHelper)
-        return timeRanges.release();
+        return timeRanges;
 
     NSArray *ranges = [m_mediaPlayerHelper.get() _bufferedTimeRanges];
     if (!ranges)
-        return timeRanges.release();
+        return timeRanges;
 
     float timeRange[2];
     int count = [ranges count];
@@ -517,7 +517,7 @@ PassRefPtr<TimeRanges> MediaPlayerPrivateIOS::buffered() const
         timeRanges->add(timeRange[0], timeRange[1]);
     }
 
-    return timeRanges.release();
+    return timeRanges;
 }
 
 void MediaPlayerPrivateIOS::setSize(const IntSize&)
index abe5282..147be16 100644 (file)
@@ -120,7 +120,7 @@ private:
     MediaPlayer::NetworkState networkState() const { return m_networkState; }
     MediaPlayer::ReadyState readyState() const { return m_readyState; }
     
-    PassRefPtr<TimeRanges> buffered() const;
+    std::unique_ptr<PlatformTimeRanges> buffered() const;
     float maxTimeSeekable() const;
     bool didLoadingProgress() const;
     unsigned totalBytes() const;
index 97e7b1d..b8e829d 100644 (file)
@@ -39,9 +39,9 @@
 #import "Logging.h"
 #import "MIMETypeRegistry.h"
 #import "PlatformLayer.h"
+#import "PlatformTimeRanges.h"
 #import "SecurityOrigin.h"
 #import "SoftLinking.h"
-#import "TimeRanges.h"
 #import "WebCoreSystemInterface.h"
 #import <QTKit/QTKit.h>
 #import <objc/runtime.h>
@@ -917,13 +917,13 @@ void MediaPlayerPrivateQTKit::setPreservesPitch(bool preservesPitch)
     createQTMovie([movieAttributes.get() valueForKey:QTMovieURLAttribute], movieAttributes.get());
 }
 
-PassRefPtr<TimeRanges> MediaPlayerPrivateQTKit::buffered() const
+std::unique_ptr<PlatformTimeRanges> MediaPlayerPrivateQTKit::buffered() const
 {
-    RefPtr<TimeRanges> timeRanges = TimeRanges::create();
+    auto timeRanges = PlatformTimeRanges::create();
     float loaded = maxTimeLoaded();
     if (loaded > 0)
         timeRanges->add(0, loaded);
-    return timeRanges.release();
+    return timeRanges;
 }
 
 float MediaPlayerPrivateQTKit::maxTimeSeekable() const
index 3185e5b..1696059 100644 (file)
@@ -547,14 +547,15 @@ void MediaPlayerPrivateQuickTimeVisualContext::setClosedCaptionsVisible(bool vis
     m_movie->setClosedCaptionsVisible(visible);
 }
 
-PassRefPtr<TimeRanges> MediaPlayerPrivateQuickTimeVisualContext::buffered() const
+std::unique_ptr<PlatformTimeRanges> MediaPlayerPrivateQuickTimeVisualContext::buffered() const
 {
-    RefPtr<TimeRanges> timeRanges = TimeRanges::create();
+    auto timeRanges = PlatformTimeRanges::create();
+
     float loaded = maxTimeLoaded();
     // rtsp streams are not buffered
     if (!m_isStreaming && loaded > 0)
         timeRanges->add(0, loaded);
-    return timeRanges.release();
+    return timeRanges;
 }
 
 float MediaPlayerPrivateQuickTimeVisualContext::maxTimeSeekable() const
index c92b496..4628c64 100644 (file)
@@ -92,7 +92,7 @@ private:
     MediaPlayer::NetworkState networkState() const { return m_networkState; }
     MediaPlayer::ReadyState readyState() const { return m_readyState; }
     
-    PassRefPtr<TimeRanges> buffered() const;
+    std::unique_ptr<PlatformTimeRanges> buffered() const;
     float maxTimeSeekable() const;
     bool didLoadingProgress() const;
     unsigned totalBytes() const;
index a9b8bb2..09b42ef 100644 (file)
@@ -68,7 +68,7 @@ namespace WebCore {
         MediaPlayer::NetworkState networkState() const { return m_networkState; }
         MediaPlayer::ReadyState readyState() const { return m_readyState; }
 
-        PassRefPtr<TimeRanges> buffered() const;
+        std::unique_ptr<PlatformTimeRanges> buffered() const;
         float maxTimeSeekable() const;
         // FIXME: bytesLoaded() should be replaced with didLoadingProgress() (by somebody who can find the implementation of this class).
         unsigned bytesLoaded() const;
index 4ca885d..aa7ab34 100644 (file)
@@ -166,9 +166,12 @@ double MockMediaPlayerMediaSource::maxTimeSeekableDouble() const
     return m_duration;
 }
 
-PassRefPtr<TimeRanges> MockMediaPlayerMediaSource::buffered() const
+std::unique_ptr<PlatformTimeRanges> MockMediaPlayerMediaSource::buffered() const
 {
-    return m_mediaSource ? m_mediaSource->buffered() : TimeRanges::create();
+    if (m_mediaSource)
+        return m_mediaSource->buffered();
+
+    return PlatformTimeRanges::create();
 }
 
 bool MockMediaPlayerMediaSource::didLoadingProgress() const
@@ -209,12 +212,16 @@ void MockMediaPlayerMediaSource::seekWithTolerance(double time, double negativeT
 
 void MockMediaPlayerMediaSource::advanceCurrentTime()
 {
-    RefPtr<TimeRanges> buffered = this->buffered();
+    if (!m_mediaSource)
+        return;
+
+    auto buffered = m_mediaSource->buffered();
     size_t pos = buffered->find(m_currentTime.toDouble());
     if (pos == notFound)
         return;
 
-    m_currentTime = MediaTime::createWithDouble(std::min(m_duration, buffered->end(pos, IGNORE_EXCEPTION)));
+    bool ignoreError;
+    m_currentTime = MediaTime::createWithDouble(std::min(m_duration, buffered->end(pos, ignoreError)));
     m_player->timeChanged();
 }
 
index 3a060d4..080fbc7 100644 (file)
@@ -70,7 +70,7 @@ private:
     virtual bool paused() const override;
     virtual MediaPlayer::NetworkState networkState() const override;
     virtual double maxTimeSeekableDouble() const override;
-    virtual PassRefPtr<TimeRanges> buffered() const override;
+    virtual std::unique_ptr<PlatformTimeRanges> buffered() const override;
     virtual bool didLoadingProgress() const override;
     virtual void setSize(const IntSize&) override;
     virtual void paint(GraphicsContext*, const IntRect&) override;
index aaaa6bc..3a871e0 100644 (file)
@@ -1,3 +1,12 @@
+2014-02-21  Eric Carlson  <eric.carlson@apple.com>
+
+        Fix TimeRanges layering violations
+        https://bugs.webkit.org/show_bug.cgi?id=128717
+
+        Reviewed by Jer Noble.
+
+        * WebKit.vcxproj/WebKitExportGenerator/WebKitExports.def.in: TimeRanges::create(void) for Internals.
+
 2014-02-20  Enrique Ocaña González  <eocanha@igalia.com>
 
         WebKitGTK+ should stop using COMPILE_ASSERT_MATCHING_ENUM macros
index 49c2609..8b2ce80 100644 (file)
@@ -452,6 +452,7 @@ EXPORTS
         symbolWithPointer(?toJS@WebCore@@YA?AVJSValue@JSC@@PAVExecState@3@PAVJSDOMGlobalObject@1@PAVTimeRanges@1@@Z, ?toJS@WebCore@@YA?AVJSValue@JSC@@PEAVExecState@3@PEAVJSDOMGlobalObject@1@PEAVTimeRanges@1@@Z)
         symbolWithPointer(?nearest@TimeRanges@WebCore@@QBENN@Z, ?nearest@TimeRanges@WebCore@@QEBANN@Z)
         symbolWithPointer(?add@TimeRanges@WebCore@@QAEXNN@Z, ?add@TimeRanges@WebCore@@QEAAXNN@Z)
+        symbolWithPointer(?create@TimeRanges@WebCore@@SA?AV?$PassRefPtr@VTimeRanges@WebCore@@@WTF@@XZ, ?create@TimeRanges@WebCore@@SA?AV?$PassRefPtr@VTimeRanges@WebCore@@@WTF@@XZ)
 #if USE(GSTREAMER)
         symbolWithPointer(?simulateAudioInterruption@MediaPlayer@WebCore@@QAEXXZ, ?simulateAudioInterruption@MediaPlayer@WebCore@@QEAAXXZ)
 #endif
index 0a5ba16..ee3bf59 100644 (file)
@@ -1,3 +1,13 @@
+2014-02-21  Eric Carlson  <eric.carlson@apple.com>
+
+        Fix TimeRanges layering violations
+        https://bugs.webkit.org/show_bug.cgi?id=128717
+
+        Reviewed by Jer Noble.
+
+        * TestWebKitAPI/Tests/WebCore/TimeRanges.cpp: TimeRanges* -> TimeRanges&.
+        (TestWebKitAPI::TEST):
+
 2014-02-21  Diego Pino García  <dpino@igalia.com>
 
         Web Inspector: update check-webkit-style to flag single quotes in WebInspectorUI projects
index cea48da..9fa6587 100644 (file)
@@ -115,7 +115,7 @@ TEST(TimeRanges, IntersectWith_Self)
 
     ASSERT_RANGE("{ [0,2) }", ranges);
 
-    ranges->intersectWith(ranges.get());
+    ranges->intersectWith(*ranges.get());
 
     ASSERT_RANGE("{ [0,2) }", ranges);
 }
@@ -128,7 +128,7 @@ TEST(TimeRanges, IntersectWith_IdenticalRange)
     ASSERT_RANGE("{ [0,2) }", rangesA);
     ASSERT_RANGE("{ [0,2) }", rangesB);
 
-    rangesA->intersectWith(rangesB.get());
+    rangesA->intersectWith(*rangesB.get());
 
     ASSERT_RANGE("{ [0,2) }", rangesA);
     ASSERT_RANGE("{ [0,2) }", rangesB);
@@ -142,7 +142,7 @@ TEST(TimeRanges, IntersectWith_Empty)
     ASSERT_RANGE("{ [0,2) }", rangesA);
     ASSERT_RANGE("{ }", rangesB);
 
-    rangesA->intersectWith(rangesB.get());
+    rangesA->intersectWith(*rangesB.get());
 
     ASSERT_RANGE("{ }", rangesA);
     ASSERT_RANGE("{ }", rangesB);
@@ -150,6 +150,7 @@ TEST(TimeRanges, IntersectWith_Empty)
 
 TEST(TimeRanges, IntersectWith_DisjointRanges1)
 {
+    
     RefPtr<TimeRanges> rangesA = TimeRanges::create();
     RefPtr<TimeRanges> rangesB = TimeRanges::create();
 
@@ -162,7 +163,7 @@ TEST(TimeRanges, IntersectWith_DisjointRanges1)
     ASSERT_RANGE("{ [0,1) [4,5) }", rangesA);
     ASSERT_RANGE("{ [2,3) [6,7) }", rangesB);
 
-    rangesA->intersectWith(rangesB.get());
+    rangesA->intersectWith(*rangesB.get());
 
     ASSERT_RANGE("{ }", rangesA);
     ASSERT_RANGE("{ [2,3) [6,7) }", rangesB);
@@ -182,7 +183,7 @@ TEST(TimeRanges, IntersectWith_DisjointRanges2)
     ASSERT_RANGE("{ [0,1) [4,5) }", rangesA);
     ASSERT_RANGE("{ [1,4) [5,7) }", rangesB);
 
-    rangesA->intersectWith(rangesB.get());
+    rangesA->intersectWith(*rangesB.get());
 
     ASSERT_RANGE("{ }", rangesA);
     ASSERT_RANGE("{ [1,4) [5,7) }", rangesB);
@@ -202,7 +203,7 @@ TEST(TimeRanges, IntersectWith_CompleteOverlap1)
     ASSERT_RANGE("{ [1,3) [4,5) [6,9) }", rangesA);
     ASSERT_RANGE("{ [0,10) }", rangesB);
 
-    rangesA->intersectWith(rangesB.get());
+    rangesA->intersectWith(*rangesB.get());
 
     ASSERT_RANGE("{ [1,3) [4,5) [6,9) }", rangesA);
     ASSERT_RANGE("{ [0,10) }", rangesB);
@@ -222,7 +223,7 @@ TEST(TimeRanges, IntersectWith_CompleteOverlap2)
     ASSERT_RANGE("{ [1,3) [4,5) [6,9) }", rangesA);
     ASSERT_RANGE("{ [1,9) }", rangesB);
 
-    rangesA->intersectWith(rangesB.get());
+    rangesA->intersectWith(*rangesB.get());
 
     ASSERT_RANGE("{ [1,3) [4,5) [6,9) }", rangesA);
     ASSERT_RANGE("{ [1,9) }", rangesB);
@@ -241,7 +242,7 @@ TEST(TimeRanges, IntersectWith_Gaps1)
     ASSERT_RANGE("{ [0,2) [4,6) }", rangesA);
     ASSERT_RANGE("{ [1,5) }", rangesB);
 
-    rangesA->intersectWith(rangesB.get());
+    rangesA->intersectWith(*rangesB.get());
 
     ASSERT_RANGE("{ [1,2) [4,5) }", rangesA);
     ASSERT_RANGE("{ [1,5) }", rangesB);
@@ -261,7 +262,7 @@ TEST(TimeRanges, IntersectWith_Gaps2)
     ASSERT_RANGE("{ [0,2) [4,6) [8,10) }", rangesA);
     ASSERT_RANGE("{ [1,9) }", rangesB);
 
-    rangesA->intersectWith(rangesB.get());
+    rangesA->intersectWith(*rangesB.get());
 
     ASSERT_RANGE("{ [1,2) [4,6) [8,9) }", rangesA);
     ASSERT_RANGE("{ [1,9) }", rangesB);
@@ -282,7 +283,7 @@ TEST(TimeRanges, IntersectWith_Gaps3)
     ASSERT_RANGE("{ [0,2) [4,7) [8,10) }", rangesA);
     ASSERT_RANGE("{ [1,5) [6,9) }", rangesB);
 
-    rangesA->intersectWith(rangesB.get());
+    rangesA->intersectWith(*rangesB.get());
 
     ASSERT_RANGE("{ [1,2) [4,5) [6,7) [8,9) }", rangesA);
     ASSERT_RANGE("{ [1,5) [6,9) }", rangesB);