Title: [161613] trunk/Source/WebCore
Revision
161613
Author
jer.no...@apple.com
Date
2014-01-09 17:57:54 -0800 (Thu, 09 Jan 2014)

Log Message

[Mac] Scrubbing performance of HD content with software decoding is poor.
https://bugs.webkit.org/show_bug.cgi?id=126705

Reviewed by Eric Carlson.

Instead of issuing a new seek before the previous one completes, wait until that seek's
completion handler is called, and then issue the new seek. This has the added benefit of
coalescing multiple incoming seeks so that only the last one is acted upon.

Save the parameters passed into seekToTime and bind them together in a std::function
to be replayed once the in-flight seek completes. To handle the case where a completion
handler fires after the media player is destroyed, add a weakPtrFactory and pass a
WeakPtr into the completion handler.

Clean up some ivars which are no longer necessary: remove m_seekCount and m_seekTime.

* platform/graphics/avfoundation/MediaPlayerPrivateAVFoundation.cpp:
(WebCore::MediaPlayerPrivateAVFoundation::MediaPlayerPrivateAVFoundation): Initialize the
    WeakPtrFactory.
(WebCore::MediaPlayerPrivateAVFoundation::seekWithTolerance):
(WebCore::MediaPlayerPrivateAVFoundation::seeking): m_seekTime -> m_seeking.
(WebCore::MediaPlayerPrivateAVFoundation::seekCompleted):
* platform/graphics/avfoundation/MediaPlayerPrivateAVFoundation.h:
* platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.h:
(WebCore::MediaPlayerPrivateAVFoundationObjC::createWeakPtr):
* platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm:
(WebCore::MediaPlayerPrivateAVFoundationObjC::MediaPlayerPrivateAVFoundationObjC):
(WebCore::MediaPlayerPrivateAVFoundationObjC::seekToTime):
(WebCore::MediaPlayerPrivateAVFoundationObjC::finishSeek):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (161612 => 161613)


--- trunk/Source/WebCore/ChangeLog	2014-01-10 01:49:21 UTC (rev 161612)
+++ trunk/Source/WebCore/ChangeLog	2014-01-10 01:57:54 UTC (rev 161613)
@@ -1,3 +1,35 @@
+2014-01-09  Jer Noble  <jer.no...@apple.com>
+
+        [Mac] Scrubbing performance of HD content with software decoding is poor.
+        https://bugs.webkit.org/show_bug.cgi?id=126705
+
+        Reviewed by Eric Carlson.
+
+        Instead of issuing a new seek before the previous one completes, wait until that seek's
+        completion handler is called, and then issue the new seek. This has the added benefit of
+        coalescing multiple incoming seeks so that only the last one is acted upon.
+
+        Save the parameters passed into seekToTime and bind them together in a std::function
+        to be replayed once the in-flight seek completes. To handle the case where a completion
+        handler fires after the media player is destroyed, add a weakPtrFactory and pass a
+        WeakPtr into the completion handler.
+        
+        Clean up some ivars which are no longer necessary: remove m_seekCount and m_seekTime.
+
+        * platform/graphics/avfoundation/MediaPlayerPrivateAVFoundation.cpp:
+        (WebCore::MediaPlayerPrivateAVFoundation::MediaPlayerPrivateAVFoundation): Initialize the
+            WeakPtrFactory.
+        (WebCore::MediaPlayerPrivateAVFoundation::seekWithTolerance):
+        (WebCore::MediaPlayerPrivateAVFoundation::seeking): m_seekTime -> m_seeking.
+        (WebCore::MediaPlayerPrivateAVFoundation::seekCompleted):
+        * platform/graphics/avfoundation/MediaPlayerPrivateAVFoundation.h:
+        * platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.h:
+        (WebCore::MediaPlayerPrivateAVFoundationObjC::createWeakPtr):
+        * platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm:
+        (WebCore::MediaPlayerPrivateAVFoundationObjC::MediaPlayerPrivateAVFoundationObjC):
+        (WebCore::MediaPlayerPrivateAVFoundationObjC::seekToTime):
+        (WebCore::MediaPlayerPrivateAVFoundationObjC::finishSeek):
+
 2014-01-08  Jer Noble  <jer.no...@apple.com>
 
         [MSE][Mac] Report the intrinsic size of the media element

Modified: trunk/Source/WebCore/platform/graphics/avfoundation/MediaPlayerPrivateAVFoundation.cpp (161612 => 161613)


--- trunk/Source/WebCore/platform/graphics/avfoundation/MediaPlayerPrivateAVFoundation.cpp	2014-01-10 01:49:21 UTC (rev 161612)
+++ trunk/Source/WebCore/platform/graphics/avfoundation/MediaPlayerPrivateAVFoundation.cpp	2014-01-10 01:57:54 UTC (rev 161613)
@@ -47,6 +47,7 @@
 
 MediaPlayerPrivateAVFoundation::MediaPlayerPrivateAVFoundation(MediaPlayer* player)
     : m_player(player)
+    , m_weakPtrFactory(this)
     , m_queuedNotifications()
     , m_queueMutex()
     , m_networkState(MediaPlayer::Empty)
@@ -58,7 +59,6 @@
     , m_cachedDuration(MediaPlayer::invalidTime())
     , m_reportedDuration(MediaPlayer::invalidTime())
     , m_maxTimeLoadedAtLastDidLoadingProgress(MediaPlayer::invalidTime())
-    , m_seekTo(MediaPlayer::invalidTime())
     , m_requestedRate(1)
     , m_delayCallbacks(0)
     , m_delayCharacteristicsChangedNotification(0)
@@ -76,7 +76,7 @@
     , m_inbandTrackConfigurationPending(false)
     , m_characteristicsChanged(false)
     , m_shouldMaintainAspectRatio(true)
-    , m_seekCount(0)
+    , m_seeking(false)
 {
     LOG(Media, "MediaPlayerPrivateAVFoundation::MediaPlayerPrivateAVFoundation(%p)", this);
 }
@@ -271,6 +271,15 @@
 
 void MediaPlayerPrivateAVFoundation::seekWithTolerance(double time, double negativeTolerance, double positiveTolerance)
 {
+    if (m_seeking) {
+        LOG(Media, "MediaPlayerPrivateAVFoundation::seekWithTolerance(%p) - save pending seek", this);
+        m_pendingSeek = [this, time, negativeTolerance, positiveTolerance]() {
+            seekWithTolerance(time, negativeTolerance, positiveTolerance);
+        };
+        return;
+    }
+    m_seeking = true;
+
     if (!metaDataAvailable())
         return;
 
@@ -284,9 +293,7 @@
         currentTrack()->beginSeeking();
     
     LOG(Media, "MediaPlayerPrivateAVFoundation::seek(%p) - seeking to %f", this, time);
-    m_seekTo = time;
 
-    ++m_seekCount;
     seekToTime(time, negativeTolerance, positiveTolerance);
 }
 
@@ -311,7 +318,7 @@
     if (!metaDataAvailable())
         return false;
 
-    return m_seekTo != MediaPlayer::invalidTime();
+    return m_seeking;
 }
 
 IntSize MediaPlayerPrivateAVFoundation::naturalSize() const
@@ -639,14 +646,20 @@
     LOG(Media, "MediaPlayerPrivateAVFoundation::seekCompleted(%p) - finished = %d", this, finished);
     UNUSED_PARAM(finished);
 
-    ASSERT(m_seekCount);
-    if (--m_seekCount)
+    m_seeking = false;
+
+    std::function<void()> pendingSeek;
+    std::swap(pendingSeek, m_pendingSeek);
+
+    if (pendingSeek) {
+        LOG(Media, "MediaPlayerPrivateAVFoundation::seekCompleted(%p) - issuing pending seek", this);
+        pendingSeek();
         return;
+    }
 
     if (currentTrack())
         currentTrack()->endSeeking();
 
-    m_seekTo = MediaPlayer::invalidTime();
     updateStates();
     m_player->timeChanged();
 }

Modified: trunk/Source/WebCore/platform/graphics/avfoundation/MediaPlayerPrivateAVFoundation.h (161612 => 161613)


--- trunk/Source/WebCore/platform/graphics/avfoundation/MediaPlayerPrivateAVFoundation.h	2014-01-10 01:49:21 UTC (rev 161612)
+++ trunk/Source/WebCore/platform/graphics/avfoundation/MediaPlayerPrivateAVFoundation.h	2014-01-10 01:57:54 UTC (rev 161613)
@@ -32,8 +32,10 @@
 #include "InbandTextTrackPrivateAVF.h"
 #include "MediaPlayerPrivate.h"
 #include "Timer.h"
+#include <functional>
 #include <wtf/Functional.h>
 #include <wtf/RetainPtr.h>
+#include <wtf/WeakPtr.h>
 
 namespace WebCore {
 
@@ -139,6 +141,8 @@
     MediaPlayerPrivateAVFoundation(MediaPlayer*);
     virtual ~MediaPlayerPrivateAVFoundation();
 
+    WeakPtr<MediaPlayerPrivateAVFoundation> createWeakPtr() { return m_weakPtrFactory.createWeakPtr(); }
+
     // MediaPlayerPrivatePrivateInterface overrides.
     virtual void load(const String& url) OVERRIDE;
 #if ENABLE(MEDIA_SOURCE)
@@ -295,6 +299,10 @@
 private:
     MediaPlayer* m_player;
 
+    WeakPtrFactory<MediaPlayerPrivateAVFoundation> m_weakPtrFactory;
+
+    std::function<void()> m_pendingSeek;
+
     Vector<Notification> m_queuedNotifications;
     mutable Mutex m_queueMutex;
 
@@ -313,7 +321,6 @@
     mutable float m_cachedDuration;
     float m_reportedDuration;
     mutable float m_maxTimeLoadedAtLastDidLoadingProgress;
-    double m_seekTo;
     float m_requestedRate;
     mutable int m_delayCallbacks;
     int m_delayCharacteristicsChangedNotification;
@@ -331,7 +338,7 @@
     bool m_inbandTrackConfigurationPending;
     bool m_characteristicsChanged;
     bool m_shouldMaintainAspectRatio;
-    size_t m_seekCount;
+    bool m_seeking;
 };
 
 } // namespace WebCore

Modified: trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm (161612 => 161613)


--- trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm	2014-01-10 01:49:21 UTC (rev 161612)
+++ trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm	2014-01-10 01:57:54 UTC (rev 161613)
@@ -180,7 +180,6 @@
 -(void)disconnect;
 -(void)playableKnown;
 -(void)metadataLoaded;
--(void)seekCompleted:(BOOL)finished;
 -(void)didEnd:(NSNotification *)notification;
 -(void)observeValueForKeyPath:keyPath ofObject:(id)object change:(NSDictionary *)change context:(MediaPlayerAVFoundationObservationContext)context;
 #if HAVE(AVFOUNDATION_MEDIA_SELECTION_GROUP)
@@ -680,12 +679,20 @@
     // setCurrentTime generates several event callbacks, update afterwards.
     setDelayCallbacks(true);
 
-    WebCoreAVFMovieObserver *observer = m_objcObserver.get();
     CMTime cmTime = CMTimeMakeWithSeconds(time, 600);
     CMTime cmBefore = CMTimeMakeWithSeconds(negativeTolerance, 600);
     CMTime cmAfter = CMTimeMakeWithSeconds(positiveTolerance, 600);
+
+    __block auto weakThis = createWeakPtr();
+
     [m_avPlayerItem.get() seekToTime:cmTime toleranceBefore:cmBefore toleranceAfter:cmAfter completionHandler:^(BOOL finished) {
-        [observer seekCompleted:finished];
+        dispatch_async(dispatch_get_main_queue(), ^{
+            auto _this = weakThis.get();
+            if (!_this)
+                return;
+
+            _this->seekCompleted(finished);
+        });
     }];
 
     setDelayCallbacks(false);
@@ -1928,14 +1935,6 @@
     m_callback->scheduleMainThreadNotification(MediaPlayerPrivateAVFoundation::Notification::AssetPlayabilityKnown);
 }
 
-- (void)seekCompleted:(BOOL)finished
-{
-    if (!m_callback)
-        return;
-    
-    m_callback->scheduleMainThreadNotification(MediaPlayerPrivateAVFoundation::Notification::SeekCompleted, static_cast<bool>(finished));
-}
-
 - (void)didEnd:(NSNotification *)unusedNotification
 {
     UNUSED_PARAM(unusedNotification);

Modified: trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.mm (161612 => 161613)


--- trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.mm	2014-01-10 01:49:21 UTC (rev 161612)
+++ trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.mm	2014-01-10 01:57:54 UTC (rev 161613)
@@ -137,10 +137,9 @@
     // addPeriodicTimeObserverForInterval: throws an exception if you pass a non-numeric CMTime, so just use
     // an arbitrarily large time value of once an hour:
     m_timeJumpedObserver = [m_synchronizer addPeriodicTimeObserverForInterval:toCMTime(MediaTime::createWithDouble(3600)) queue:dispatch_get_main_queue() usingBlock:^(CMTime){
-        if (m_seeking) {
+        if (m_seeking)
             m_seeking = false;
-            m_player->timeChanged();
-        }
+        m_player->timeChanged();
     }];
 }
 
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to