Title: [206487] branches/safari-602.2.14.0-branch/Source/WebCore

Diff

Modified: branches/safari-602.2.14.0-branch/Source/WebCore/ChangeLog (206486 => 206487)


--- branches/safari-602.2.14.0-branch/Source/WebCore/ChangeLog	2016-09-28 01:31:42 UTC (rev 206486)
+++ branches/safari-602.2.14.0-branch/Source/WebCore/ChangeLog	2016-09-28 01:38:56 UTC (rev 206487)
@@ -1,3 +1,52 @@
+2016-09-27  Babak Shafiei  <bshaf...@apple.com>
+
+        Merge r206399. rdar://problem/28457219
+
+    2016-09-26  Wenson Hsieh  <wenson_hs...@apple.com>
+
+            Seeking video doesn't update seek position
+            https://bugs.webkit.org/show_bug.cgi?id=162575
+            <rdar://problem/28457219>
+
+            Reviewed by Jer Noble.
+
+            On ToT, seeking in a video causes the playhead to stutter, and does not actually update media remote's seek
+            position. This is partly due to how we do not update media remote with new information when beginning to respond
+            to remote seek commands, so media remote continues to think that a playing video is still playing despite the
+            user attempting to seek through it.
+
+            To fix this, we introduce timer-based guards around remote seek commands, such that a seek "gesture" begins when
+            we receive the first seek command and ends when no seek command has been received in a set amount of time (this
+            is 0.5 seconds, which is approximately what other clients around the platform use).
+
+            Also, when responding to a remote seek, perform the seek with no tolerance. This prevents the playhead from
+            stuttering at the end of a seek from the final requested destination of the seek to the last actually seeked
+            time in the video.
+
+            When beginning to seek, we must pause the media. Through existing mechanisms, this causes the media session
+            manager to update its Now Playing information, which informs media remote that we are no longer playing and
+            prevents us from stuttering. However, when ending a seek, we must also trigger an additional update to again
+            refresh media remote's view of the current time. This prevents a flicker when playing media after seeking.
+
+            Unit tests to be added in a follow-up due to time constraints.
+
+            * html/HTMLMediaElement.cpp:
+            (WebCore::HTMLMediaElement::HTMLMediaElement):
+            (WebCore::HTMLMediaElement::handleSeekToPlaybackPosition):
+            (WebCore::HTMLMediaElement::seekToPlaybackPositionEndedTimerFired):
+            (WebCore::HTMLMediaElement::didReceiveRemoteControlCommand):
+            * html/HTMLMediaElement.h:
+            * platform/audio/PlatformMediaSessionManager.h:
+            (WebCore::PlatformMediaSessionManager::scheduleUpdateNowPlayingInfo):
+            (WebCore::PlatformMediaSessionManager::sessionDidEndRemoteScrubbing):
+            (WebCore::PlatformMediaSessionManager::sessions): Deleted.
+            * platform/audio/mac/MediaSessionManagerMac.h:
+            * platform/audio/mac/MediaSessionManagerMac.mm:
+            (WebCore::PlatformMediaSessionManager::updateNowPlayingInfoIfNecessary):
+            (WebCore::MediaSessionManagerMac::scheduleUpdateNowPlayingInfo):
+            (WebCore::MediaSessionManagerMac::sessionDidEndRemoteScrubbing):
+            (WebCore::MediaSessionManagerMac::updateNowPlayingInfo):
+
 2016-09-26  Babak Shafiei  <bshaf...@apple.com>
 
         Merge r206241. rdar://problem/28450514

Modified: branches/safari-602.2.14.0-branch/Source/WebCore/html/HTMLMediaElement.cpp (206486 => 206487)


--- branches/safari-602.2.14.0-branch/Source/WebCore/html/HTMLMediaElement.cpp	2016-09-28 01:31:42 UTC (rev 206486)
+++ branches/safari-602.2.14.0-branch/Source/WebCore/html/HTMLMediaElement.cpp	2016-09-28 01:38:56 UTC (rev 206487)
@@ -405,6 +405,7 @@
     , m_playbackProgressTimer(*this, &HTMLMediaElement::playbackProgressTimerFired)
     , m_scanTimer(*this, &HTMLMediaElement::scanTimerFired)
     , m_playbackControlsManagerBehaviorRestrictionsTimer(*this, &HTMLMediaElement::playbackControlsManagerBehaviorRestrictionsTimerFired)
+    , m_seekToPlaybackPositionEndedTimer(*this, &HTMLMediaElement::seekToPlaybackPositionEndedTimerFired)
     , m_playedTimeRanges()
     , m_asyncEventQueue(*this)
     , m_requestedPlaybackRate(1)
@@ -467,6 +468,7 @@
     , m_mediaControlsDependOnPageScaleFactor(false)
     , m_haveSetUpCaptionContainer(false)
 #endif
+    , m_isScrubbingRemotely(false)
 #if ENABLE(VIDEO_TRACK)
     , m_tracksAreReady(true)
     , m_haveVisibleTextTrack(false)
@@ -4560,6 +4562,37 @@
     m_playbackControlsManagerBehaviorRestrictionsTimer.startOneShot(HideMediaControlsAfterEndedDelay);
 }
 
+void HTMLMediaElement::handleSeekToPlaybackPosition(double position)
+{
+#if PLATFORM(MAC)
+    // FIXME: This should ideally use faskSeek, but this causes MediaRemote's playhead to flicker upon release.
+    // Please see <rdar://problem/28457219> for more details.
+    seek(MediaTime::createWithDouble(position));
+    m_seekToPlaybackPositionEndedTimer.stop();
+    m_seekToPlaybackPositionEndedTimer.startOneShot(0.5);
+
+    if (!m_isScrubbingRemotely) {
+        m_isScrubbingRemotely = true;
+        if (!paused())
+            pauseInternal();
+    }
+#else
+    fastSeek(position);
+#endif
+}
+
+void HTMLMediaElement::seekToPlaybackPositionEndedTimerFired()
+{
+#if PLATFORM(MAC)
+    if (!m_isScrubbingRemotely)
+        return;
+
+    PlatformMediaSessionManager::sharedManager().sessionDidEndRemoteScrubbing(*m_mediaSession);
+    m_isScrubbingRemotely = false;
+    m_seekToPlaybackPositionEndedTimer.stop();
+#endif
+}
+
 void HTMLMediaElement::mediaPlayerVolumeChanged(MediaPlayer*)
 {
     LOG(Media, "HTMLMediaElement::mediaPlayerVolumeChanged(%p)", this);
@@ -6992,7 +7025,7 @@
     case PlatformMediaSession::SeekToPlaybackPositionCommand:
         ASSERT(argument);
         if (argument)
-            fastSeek(argument->asDouble);
+            handleSeekToPlaybackPosition(argument->asDouble);
         break;
     default:
         { } // Do nothing

Modified: branches/safari-602.2.14.0-branch/Source/WebCore/html/HTMLMediaElement.h (206486 => 206487)


--- branches/safari-602.2.14.0-branch/Source/WebCore/html/HTMLMediaElement.h	2016-09-28 01:31:42 UTC (rev 206486)
+++ branches/safari-602.2.14.0-branch/Source/WebCore/html/HTMLMediaElement.h	2016-09-28 01:38:56 UTC (rev 206487)
@@ -810,6 +810,8 @@
     void setControllerJSProperty(const char*, JSC::JSValue);
 
     void addBehaviorRestrictionsOnEndIfNecessary();
+    void handleSeekToPlaybackPosition(double);
+    void seekToPlaybackPositionEndedTimerFired();
 
     Timer m_pendingActionTimer;
     Timer m_progressEventTimer;
@@ -816,6 +818,7 @@
     Timer m_playbackProgressTimer;
     Timer m_scanTimer;
     Timer m_playbackControlsManagerBehaviorRestrictionsTimer;
+    Timer m_seekToPlaybackPositionEndedTimer;
     GenericTaskQueue<Timer> m_seekTaskQueue;
     GenericTaskQueue<Timer> m_resizeTaskQueue;
     GenericTaskQueue<Timer> m_shadowDOMTaskQueue;
@@ -968,6 +971,8 @@
     bool m_haveSetUpCaptionContainer : 1;
 #endif
 
+    bool m_isScrubbingRemotely : 1;
+
 #if ENABLE(VIDEO_TRACK)
     bool m_tracksAreReady : 1;
     bool m_haveVisibleTextTrack : 1;

Modified: branches/safari-602.2.14.0-branch/Source/WebCore/platform/audio/PlatformMediaSessionManager.h (206486 => 206487)


--- branches/safari-602.2.14.0-branch/Source/WebCore/platform/audio/PlatformMediaSessionManager.h	2016-09-28 01:31:42 UTC (rev 206486)
+++ branches/safari-602.2.14.0-branch/Source/WebCore/platform/audio/PlatformMediaSessionManager.h	2016-09-28 01:38:56 UTC (rev 206487)
@@ -51,6 +51,7 @@
 
     virtual ~PlatformMediaSessionManager() { }
 
+    virtual void scheduleUpdateNowPlayingInfo() { }
     bool has(PlatformMediaSession::MediaType) const;
     int count(PlatformMediaSession::MediaType) const;
     bool activeAudioSessionRequired() const;
@@ -85,6 +86,7 @@
     virtual bool sessionWillBeginPlayback(PlatformMediaSession&);
     virtual void sessionWillEndPlayback(PlatformMediaSession&);
     virtual bool sessionCanLoadMedia(const PlatformMediaSession&) const;
+    virtual void sessionDidEndRemoteScrubbing(const PlatformMediaSession&) { };
     virtual void clientCharacteristicsChanged(PlatformMediaSession&) { }
 
 #if PLATFORM(IOS)

Modified: branches/safari-602.2.14.0-branch/Source/WebCore/platform/audio/mac/MediaSessionManagerMac.h (206486 => 206487)


--- branches/safari-602.2.14.0-branch/Source/WebCore/platform/audio/mac/MediaSessionManagerMac.h	2016-09-28 01:31:42 UTC (rev 206486)
+++ branches/safari-602.2.14.0-branch/Source/WebCore/platform/audio/mac/MediaSessionManagerMac.h	2016-09-28 01:38:56 UTC (rev 206487)
@@ -27,6 +27,7 @@
 
 #if PLATFORM(MAC)
 
+#include "GenericTaskQueue.h"
 #include "PlatformMediaSessionManager.h"
 #include <wtf/RetainPtr.h>
 
@@ -41,10 +42,12 @@
 
     MediaSessionManagerMac();
 
+    void scheduleUpdateNowPlayingInfo() override;
     void removeSession(PlatformMediaSession&) override;
 
     bool sessionWillBeginPlayback(PlatformMediaSession&) override;
     void sessionWillEndPlayback(PlatformMediaSession&) override;
+    void sessionDidEndRemoteScrubbing(const PlatformMediaSession&) override;
     void clientCharacteristicsChanged(PlatformMediaSession&) override;
 
     void updateNowPlayingInfo();
@@ -51,11 +54,9 @@
 
     PlatformMediaSession* nowPlayingEligibleSession();
 
-    double m_reportedRate { 0 };
-    double m_reportedDuration { 0 };
-    String m_reportedTitle;
     bool m_nowPlayingActive { false };
     bool m_isInBackground { false };
+    GenericTaskQueue<Timer> m_nowPlayingUpdateTaskQueue;
 };
 
 } // namespace WebCore

Modified: branches/safari-602.2.14.0-branch/Source/WebCore/platform/audio/mac/MediaSessionManagerMac.mm (206486 => 206487)


--- branches/safari-602.2.14.0-branch/Source/WebCore/platform/audio/mac/MediaSessionManagerMac.mm	2016-09-28 01:31:42 UTC (rev 206486)
+++ branches/safari-602.2.14.0-branch/Source/WebCore/platform/audio/mac/MediaSessionManagerMac.mm	2016-09-28 01:38:56 UTC (rev 206487)
@@ -56,7 +56,7 @@
 void PlatformMediaSessionManager::updateNowPlayingInfoIfNecessary()
 {
     if (auto existingManager = (MediaSessionManagerMac *)PlatformMediaSessionManager::sharedManagerIfExists())
-        existingManager->updateNowPlayingInfo();
+        existingManager->scheduleUpdateNowPlayingInfo();
 }
 
 MediaSessionManagerMac::MediaSessionManagerMac()
@@ -69,6 +69,12 @@
 {
 }
 
+void MediaSessionManagerMac::scheduleUpdateNowPlayingInfo()
+{
+    if (!m_nowPlayingUpdateTaskQueue.hasPendingTasks())
+        m_nowPlayingUpdateTaskQueue.enqueueTask(std::bind(&MediaSessionManagerMac::updateNowPlayingInfo, this));
+}
+
 bool MediaSessionManagerMac::sessionWillBeginPlayback(PlatformMediaSession& session)
 {
     if (!PlatformMediaSessionManager::sessionWillBeginPlayback(session))
@@ -79,6 +85,11 @@
     return true;
 }
 
+void MediaSessionManagerMac::sessionDidEndRemoteScrubbing(const PlatformMediaSession&)
+{
+    scheduleUpdateNowPlayingInfo();
+}
+
 void MediaSessionManagerMac::removeSession(PlatformMediaSession& session)
 {
     PlatformMediaSessionManager::removeSession(session);
@@ -123,9 +134,6 @@
             LOG(Media, "MediaSessionManagerMac::updateNowPlayingInfo - clearing now playing info");
             MRMediaRemoteSetNowPlayingInfo(nullptr);
             m_nowPlayingActive = false;
-            m_reportedTitle = "";
-            m_reportedRate = 0;
-            m_reportedDuration = 0;
             MRMediaRemoteSetNowPlayingApplicationPlaybackStateForOrigin(MRMediaRemoteGetLocalOrigin(), kMRPlaybackStateStopped, dispatch_get_main_queue(), ^(MRMediaRemoteError error) {
 #if LOG_DISABLED
                 UNUSED_PARAM(error);
@@ -146,16 +154,6 @@
     String title = currentSession->title();
     double duration = currentSession->duration();
     double rate = currentSession->state() == PlatformMediaSession::Playing ? 1 : 0;
-    if (m_reportedTitle == title && m_reportedRate == rate && m_reportedDuration == duration) {
-        m_nowPlayingActive = true;
-        LOG(Media, "MediaSessionManagerMac::updateNowPlayingInfo - nothing new to show");
-        return;
-    }
-
-    m_reportedRate = rate;
-    m_reportedDuration = duration;
-    m_reportedTitle = title;
-
     auto info = adoptCF(CFDictionaryCreateMutable(kCFAllocatorDefault, 4, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
 
     if (!title.isEmpty())
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to