Commit ed03cbf2 authored by jer.noble@apple.com's avatar jer.noble@apple.com

2011-04-06 Jer Noble <jer.noble@apple.com>

        Reviewed by Maciej Stachowiak.

        AVF: MediaPlayerPrivateAVFoundation never reaches playable state.
        https://bugs.webkit.org/show_bug.cgi?id=57962

        Add support for a new AVPlayerItem API which will notify clients when their
        seek completes.  This requires a new Notification type to be passed to the main
        thread in MediaPlayerPrivateAVFoundation.

        * platform/graphics/avfoundation/MediaPlayerPrivateAVFoundation.cpp:
        (WebCore::MediaPlayerPrivateAVFoundation::seekCompleted): Added.
        (WebCore::MediaPlayerPrivateAVFoundation::scheduleMainThreadNotification): Added two new
            overloaded functions which take a Notification; and a Notification::Type and boolean.
        (WebCore::MediaPlayerPrivateAVFoundation::dispatchNotification): Support new SeekCompleted
            Notification type.
        * platform/graphics/avfoundation/MediaPlayerPrivateAVFoundation.h:
        (WebCore::MediaPlayerPrivateAVFoundation::Notification::Notification): Added one new constructor.
        (WebCore::MediaPlayerPrivateAVFoundation::Notification::finished): Added ivar and accessor.
        * platform/graphics/avfoundation/MediaPlayerPrivateAVFoundationObjC.mm:
        (WebCore::MediaPlayerPrivateAVFoundationObjC::seekToTime): Call new AVPlayerItem API.
        (-[WebCoreAVFMovieObserver seekCompleted:]): Added.

git-svn-id: svn://svn.chromium.org/blink/trunk@83196 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent 68c071f2
2011-04-06 Jer Noble <jer.noble@apple.com>
Reviewed by Maciej Stachowiak.
AVF: MediaPlayerPrivateAVFoundation never reaches playable state.
https://bugs.webkit.org/show_bug.cgi?id=57962
Add support for a new AVPlayerItem API which will notify clients when their
seek completes. This requires a new Notification type to be passed to the main
thread in MediaPlayerPrivateAVFoundation.
* platform/graphics/avfoundation/MediaPlayerPrivateAVFoundation.cpp:
(WebCore::MediaPlayerPrivateAVFoundation::seekCompleted): Added.
(WebCore::MediaPlayerPrivateAVFoundation::scheduleMainThreadNotification): Added two new
overloaded functions which take a Notification; and a Notification::Type and boolean.
(WebCore::MediaPlayerPrivateAVFoundation::dispatchNotification): Support new SeekCompleted
Notification type.
* platform/graphics/avfoundation/MediaPlayerPrivateAVFoundation.h:
(WebCore::MediaPlayerPrivateAVFoundation::Notification::Notification): Added one new constructor.
(WebCore::MediaPlayerPrivateAVFoundation::Notification::finished): Added ivar and accessor.
* platform/graphics/avfoundation/MediaPlayerPrivateAVFoundationObjC.mm:
(WebCore::MediaPlayerPrivateAVFoundationObjC::seekToTime): Call new AVPlayerItem API.
(-[WebCoreAVFMovieObserver seekCompleted:]): Added.
2011-04-07 Nancy Piedra <nancy.piedra@nokia.com>
Reviewed by Eric Carlson.
......@@ -568,6 +568,14 @@ void MediaPlayerPrivateAVFoundation::timeChanged(double time)
}
}
void MediaPlayerPrivateAVFoundation::seekCompleted(bool finished)
{
LOG(Media, "MediaPlayerPrivateAVFoundation::seekCompleted(%p) - finished = %d", this, finished);
if (finished)
m_seekTo = invalidTime;
}
void MediaPlayerPrivateAVFoundation::didEnd()
{
// Hang onto the current time and use it as duration from now on since we are definitely at
......@@ -631,12 +639,22 @@ void MediaPlayerPrivateAVFoundation::clearMainThreadPendingFlag()
void MediaPlayerPrivateAVFoundation::scheduleMainThreadNotification(Notification::Type type, double time)
{
LOG(Media, "MediaPlayerPrivateAVFoundation::scheduleMainThreadNotification(%p) - notification %d", this, static_cast<int>(type));
scheduleMainThreadNotification(Notification(type, time));
}
void MediaPlayerPrivateAVFoundation::scheduleMainThreadNotification(Notification::Type type, bool finished)
{
scheduleMainThreadNotification(Notification(type, finished));
}
void MediaPlayerPrivateAVFoundation::scheduleMainThreadNotification(Notification notification)
{
LOG(Media, "MediaPlayerPrivateAVFoundation::scheduleMainThreadNotification(%p) - notification %d", this, static_cast<int>(notification.type()));
m_queueMutex.lock();
// It is important to always process the properties in the order that we are notified,
// so always go through the queue because notifications happen on different threads.
m_queuedNotifications.append(Notification(type, time));
m_queuedNotifications.append(notification);
bool delayDispatch = m_delayCallbacks || !isMainThread();
if (delayDispatch && !m_mainThreadCallPending) {
......@@ -716,6 +734,9 @@ void MediaPlayerPrivateAVFoundation::dispatchNotification()
case Notification::PlayerTimeChanged:
timeChanged(notification.time());
break;
case Notification::SeekCompleted:
seekCompleted(notification.finished());
break;
case Notification::AssetMetadataLoaded:
metadataLoaded();
break;
......
......@@ -48,6 +48,7 @@ public:
virtual void loadedTimeRangesChanged();
virtual void seekableTimeRangesChanged();
virtual void timeChanged(double);
virtual void seekCompleted(bool);
virtual void didEnd();
class Notification {
......@@ -66,31 +67,45 @@ public:
AssetMetadataLoaded,
AssetPlayabilityKnown,
PlayerRateChanged,
PlayerTimeChanged
PlayerTimeChanged,
SeekCompleted,
};
Notification()
: m_type(None)
, m_time(0)
, m_finished(false)
{
}
Notification(Type type, double time)
: m_type(type)
, m_time(time)
, m_finished(false)
{
}
Notification(Type type, bool finished)
: m_type(type)
, m_time(0)
, m_finished(finished)
{
}
Type type() { return m_type; }
bool isValid() { return m_type != None; }
double time() { return m_time; }
bool finished() { return m_finished; }
private:
Type m_type;
double m_time;
bool m_finished;
};
void scheduleMainThreadNotification(Notification);
void scheduleMainThreadNotification(Notification::Type, double time = 0);
void scheduleMainThreadNotification(Notification::Type, bool completed);
void dispatchNotification();
void clearMainThreadPendingFlag();
......
......@@ -100,6 +100,7 @@ enum MediaPlayerAVFoundationObservationContext {
-(void)playableKnown;
-(void)metadataLoaded;
-(void)timeChanged:(double)time;
-(void)seekCompleted:(BOOL)finished;
-(void)didEnd:(NSNotification *)notification;
-(void)observeValueForKeyPath:keyPath ofObject:(id)object change:(NSDictionary *)change context:(MediaPlayerAVFoundationObservationContext)context;
@end
......@@ -408,14 +409,10 @@ void MediaPlayerPrivateAVFoundationObjC::seekToTime(float time)
// setCurrentTime generates several event callbacks, update afterwards.
setDelayCallbacks(true);
float now = currentTime();
if (time != now)
[m_avPlayerItem.get() seekToTime:CMTimeMakeWithSeconds(time, 600) toleranceBefore:kCMTimeZero toleranceAfter:kCMTimeZero];
else {
// Force a call to the "time changed" notifier manually because a seek to the current time is a noop
// so the seek will never seem to complete.
[m_objcObserver.get() timeChanged:now];
}
WebCoreAVFMovieObserver *observer = m_objcObserver.get();
[m_avPlayerItem.get() seekToTime:CMTimeMakeWithSeconds(time, 600) toleranceBefore:kCMTimeZero toleranceAfter:kCMTimeZero completionHandler:^(BOOL finished) {
[observer seekCompleted:finished];
}];
setDelayCallbacks(false);
}
......@@ -765,6 +762,14 @@ NSArray* itemKVOProperties()
m_callback->scheduleMainThreadNotification(MediaPlayerPrivateAVFoundation::Notification::PlayerTimeChanged, time);
}
- (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);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment