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();
}];
}