[iOS Media] Video buffer progress missing on iPhones
authordino@apple.com <dino@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 9 Mar 2015 04:55:11 +0000 (04:55 +0000)
committerdino@apple.com <dino@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 9 Mar 2015 04:55:11 +0000 (04:55 +0000)
https://bugs.webkit.org/show_bug.cgi?id=142462

Reviewed by Eric Carlson.

Source/WebCore:

The fullscreen controller on the iPhone idiom was using
the media duration as its maximum loaded time, meaning the
download progress was missing (it looked like everything
was already downloaded). The fix is to calculate
what the maximum buffered time is from the HTMLMediaElement,
and send that to the fullscreen controller.

* Modules/mediacontrols/mediaControlsiOS.js:
(ControllerIOS.prototype.drawTimelineBackground): While implementing
the native function I noticed that the JS controls forgot that
the buffered time ranges are ordered, and thus they don't need
to search through the array. The last range will be the highest.

* html/HTMLMediaElement.cpp:
(WebCore::HTMLMediaElement::maxBufferedTime): New helper function
to calculate the highest buffered time in the media source.
* html/HTMLMediaElement.h:

* platform/ios/WebVideoFullscreenInterface.h: New setBufferedTime method.
* platform/ios/WebVideoFullscreenInterfaceAVKit.h:

* platform/ios/WebVideoFullscreenInterfaceAVKit.mm:
(WebVideoFullscreenInterfaceAVKit::setDuration): No longer set
the loadedTimeRanges.
(WebVideoFullscreenInterfaceAVKit::setBufferedTime): Calculate a normalized
value of the maximum loaded/buffered time, and tell the platform controller
to show that range.

* platform/ios/WebVideoFullscreenModelVideoElement.mm:
(WebVideoFullscreenModelVideoElement::updateForEventName): Send the maximum
buffered time.

Source/WebKit2:

Coordinate the SetBufferedTime message between the Web and UI
processes.

* UIProcess/ios/WebVideoFullscreenManagerProxy.messages.in: New message SetBufferedTime.
* WebProcess/ios/WebVideoFullscreenManager.h:
* WebProcess/ios/WebVideoFullscreenManager.mm:
(WebKit::WebVideoFullscreenManager::setBufferedTime):

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

12 files changed:
Source/WebCore/ChangeLog
Source/WebCore/Modules/mediacontrols/mediaControlsiOS.js
Source/WebCore/html/HTMLMediaElement.cpp
Source/WebCore/html/HTMLMediaElement.h
Source/WebCore/platform/ios/WebVideoFullscreenInterface.h
Source/WebCore/platform/ios/WebVideoFullscreenInterfaceAVKit.h
Source/WebCore/platform/ios/WebVideoFullscreenInterfaceAVKit.mm
Source/WebCore/platform/ios/WebVideoFullscreenModelVideoElement.mm
Source/WebKit2/ChangeLog
Source/WebKit2/UIProcess/ios/WebVideoFullscreenManagerProxy.messages.in
Source/WebKit2/WebProcess/ios/WebVideoFullscreenManager.h
Source/WebKit2/WebProcess/ios/WebVideoFullscreenManager.mm

index 1cb11fb..4372d45 100644 (file)
@@ -1,3 +1,42 @@
+2015-03-08  Dean Jackson  <dino@apple.com>
+
+        [iOS Media] Video buffer progress missing on iPhones
+        https://bugs.webkit.org/show_bug.cgi?id=142462
+
+        Reviewed by Eric Carlson.
+
+        The fullscreen controller on the iPhone idiom was using
+        the media duration as its maximum loaded time, meaning the
+        download progress was missing (it looked like everything
+        was already downloaded). The fix is to calculate
+        what the maximum buffered time is from the HTMLMediaElement,
+        and send that to the fullscreen controller.
+
+        * Modules/mediacontrols/mediaControlsiOS.js:
+        (ControllerIOS.prototype.drawTimelineBackground): While implementing
+        the native function I noticed that the JS controls forgot that
+        the buffered time ranges are ordered, and thus they don't need
+        to search through the array. The last range will be the highest.
+
+        * html/HTMLMediaElement.cpp:
+        (WebCore::HTMLMediaElement::maxBufferedTime): New helper function
+        to calculate the highest buffered time in the media source.
+        * html/HTMLMediaElement.h:
+
+        * platform/ios/WebVideoFullscreenInterface.h: New setBufferedTime method.
+        * platform/ios/WebVideoFullscreenInterfaceAVKit.h:
+
+        * platform/ios/WebVideoFullscreenInterfaceAVKit.mm:
+        (WebVideoFullscreenInterfaceAVKit::setDuration): No longer set
+        the loadedTimeRanges.
+        (WebVideoFullscreenInterfaceAVKit::setBufferedTime): Calculate a normalized
+        value of the maximum loaded/buffered time, and tell the platform controller
+        to show that range.
+
+        * platform/ios/WebVideoFullscreenModelVideoElement.mm:
+        (WebVideoFullscreenModelVideoElement::updateForEventName): Send the maximum
+        buffered time.
+
 2015-03-08  Chris Dumez  <cdumez@apple.com>
 
         Crash in WebCore::NotificationCenter::stop()
index 75cb18f..e247364 100644 (file)
@@ -307,8 +307,9 @@ ControllerIOS.prototype = {
 
         var played = this.video.currentTime / this.video.duration;
         var buffered = 0;
-        for (var i = 0, end = this.video.buffered.length; i < end; ++i)
-            buffered = Math.max(this.video.buffered.end(i), buffered);
+        var bufferedRanges = this.video.buffered;
+        if (bufferedRanges && bufferedRanges.length)
+            buffered = Math.max(bufferedRanges.end(bufferedRanges.length - 1), buffered);
 
         buffered /= this.video.duration;
 
index bccd178..718c64d 100644 (file)
@@ -4377,6 +4377,16 @@ PassRefPtr<TimeRanges> HTMLMediaElement::buffered() const
     return TimeRanges::create(*m_player->buffered());
 }
 
+double HTMLMediaElement::maxBufferedTime() const
+{
+    RefPtr<TimeRanges> bufferedRanges = buffered();
+    unsigned numRanges = bufferedRanges->length();
+    if (!numRanges)
+        return 0;
+
+    return bufferedRanges->end(numRanges - 1, ASSERT_NO_EXCEPTION);
+}
+
 PassRefPtr<TimeRanges> HTMLMediaElement::played()
 {
     if (m_playing) {
index 31dfa76..41590ad 100644 (file)
@@ -446,6 +446,8 @@ public:
 
     bool isDisablingSleep() const { return m_sleepDisabler.get(); }
 
+    double maxBufferedTime() const;
+
 protected:
     HTMLMediaElement(const QualifiedName&, Document&, bool);
     virtual ~HTMLMediaElement();
index 64c8716..b89b6b0 100644 (file)
@@ -47,6 +47,7 @@ public:
     virtual void resetMediaState() = 0;
     virtual void setDuration(double) = 0;
     virtual void setCurrentTime(double currentTime, double anchorTime) = 0;
+    virtual void setBufferedTime(double bufferedTime) = 0;
     virtual void setRate(bool isPlaying, float playbackRate) = 0;
     virtual void setVideoDimensions(bool hasVideo, float width, float height) = 0;
     virtual void setSeekableRanges(const TimeRanges&) = 0;
index c95e90b..15e53d8 100644 (file)
@@ -76,6 +76,7 @@ public:
     WEBCORE_EXPORT virtual void resetMediaState() override;
     WEBCORE_EXPORT virtual void setDuration(double) override;
     WEBCORE_EXPORT virtual void setCurrentTime(double currentTime, double anchorTime) override;
+    WEBCORE_EXPORT virtual void setBufferedTime(double bufferedTime) override;
     WEBCORE_EXPORT virtual void setRate(bool isPlaying, float playbackRate) override;
     WEBCORE_EXPORT virtual void setVideoDimensions(bool hasVideo, float width, float height) override;
     WEBCORE_EXPORT virtual void setSeekableRanges(const TimeRanges&) override;
index c9fa41e..6f9092d 100644 (file)
@@ -721,8 +721,7 @@ void WebVideoFullscreenInterfaceAVKit::setDuration(double duration)
         playerController.contentDuration = duration;
         playerController.maxTime = duration;
         playerController.contentDurationWithinEndTimes = duration;
-        playerController.loadedTimeRanges = @[@0, @(duration)];
-        
+
         // FIXME: we take this as an indication that playback is ready.
         playerController.canPlay = YES;
         playerController.canPause = YES;
@@ -746,6 +745,22 @@ void WebVideoFullscreenInterfaceAVKit::setCurrentTime(double currentTime, double
     });
 }
 
+void WebVideoFullscreenInterfaceAVKit::setBufferedTime(double bufferedTime)
+{
+    RefPtr<WebVideoFullscreenInterfaceAVKit> strongThis(this);
+
+    dispatch_async(dispatch_get_main_queue(), [strongThis, bufferedTime] {
+        WebAVPlayerController* playerController = strongThis->m_playerController.get();
+        double duration = playerController.contentDuration;
+        double normalizedBufferedTime;
+        if (!duration)
+            normalizedBufferedTime = 0;
+        else
+            normalizedBufferedTime = bufferedTime / duration;
+        playerController.loadedTimeRanges = @[@0, @(normalizedBufferedTime)];
+    });
+}
+
 void WebVideoFullscreenInterfaceAVKit::setRate(bool isPlaying, float playbackRate)
 {
     RefPtr<WebVideoFullscreenInterfaceAVKit> strongThis(this);
index 0a9c6aa..ff7e1cd 100644 (file)
@@ -120,6 +120,7 @@ void WebVideoFullscreenModelVideoElement::updateForEventName(const WTF::AtomicSt
     if (all
         || eventName == eventNames().timeupdateEvent) {
         m_videoFullscreenInterface->setCurrentTime(m_videoElement->currentTime(), [[NSProcessInfo processInfo] systemUptime]);
+        m_videoFullscreenInterface->setBufferedTime(m_videoElement->maxBufferedTime());
         // FIXME: 130788 - find a better event to update seekable ranges from.
         m_videoFullscreenInterface->setSeekableRanges(*m_videoElement->seekable());
     }
index 49fae2f..6a518a4 100644 (file)
@@ -1,3 +1,18 @@
+2015-03-08  Dean Jackson  <dino@apple.com>
+
+        [iOS Media] Video buffer progress missing on iPhones
+        https://bugs.webkit.org/show_bug.cgi?id=142462
+
+        Reviewed by Eric Carlson.
+
+        Coordinate the SetBufferedTime message between the Web and UI
+        processes.
+
+        * UIProcess/ios/WebVideoFullscreenManagerProxy.messages.in: New message SetBufferedTime.
+        * WebProcess/ios/WebVideoFullscreenManager.h:
+        * WebProcess/ios/WebVideoFullscreenManager.mm:
+        (WebKit::WebVideoFullscreenManager::setBufferedTime):
+
 2015-03-08  Sam Weinig  <sam@webkit.org>
 
         [Content Extensions] Add scaffolding for the WKUserContentExtensionStore
index c728c0b..7460402 100644 (file)
@@ -24,6 +24,7 @@
 messages -> WebVideoFullscreenManagerProxy {
     ResetMediaState()
     SetCurrentTime(double currentTime, double hostTime)
+    SetBufferedTime(double bufferedTime)
     SetVideoDimensions(bool hasVideo, unsigned width, unsigned height)
     SetSeekableRangesVector(Vector<std::pair<double, double>> ranges);
     SetCanPlayFastReverse(bool value);
index 334eaec..b338276 100644 (file)
@@ -71,6 +71,7 @@ protected:
     virtual void resetMediaState() override;
     virtual void setDuration(double) override;
     virtual void setCurrentTime(double currentTime, double anchorTime) override;
+    virtual void setBufferedTime(double bufferedTime) override;
     virtual void setRate(bool isPlaying, float playbackRate) override;
     virtual void setVideoDimensions(bool hasVideo, float width, float height) override;
     virtual void setSeekableRanges(const WebCore::TimeRanges&) override;
index 9ceeb8b..1c9a358 100644 (file)
@@ -134,6 +134,11 @@ void WebVideoFullscreenManager::setCurrentTime(double currentTime, double anchor
     m_page->send(Messages::WebVideoFullscreenManagerProxy::SetCurrentTime(currentTime, anchorTime), m_page->pageID());
 }
 
+void WebVideoFullscreenManager::setBufferedTime(double bufferedTime)
+{
+    m_page->send(Messages::WebVideoFullscreenManagerProxy::SetBufferedTime(bufferedTime), m_page->pageID());
+}
+
 void WebVideoFullscreenManager::setRate(bool isPlaying, float playbackRate)
 {
     m_page->send(Messages::WebVideoFullscreenManagerProxy::SetRate(isPlaying, playbackRate), m_page->pageID());