From 2fc515ea1eaa0f7ffb56c4dadee560095c3374bd Mon Sep 17 00:00:00 2001 From: Jochen Seemann Date: Mon, 4 Dec 2017 22:33:03 +0100 Subject: AVFoundation: implement bufferState This add support for the buffer status with AVPlayerItem.playbackLikelyToKeepUp. It only supports buffer status values of 0 and 100. Change-Id: I5779ea360fe9c497ecc0236e442850422d96ac87 Reviewed-by: Christian Stromme --- .../mediaplayer/avfmediaplayercontrol.mm | 1 + .../mediaplayer/avfmediaplayersession.h | 5 ++++ .../mediaplayer/avfmediaplayersession.mm | 34 ++++++++++++++++++++-- 3 files changed, 37 insertions(+), 3 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/avfoundation/mediaplayer/avfmediaplayercontrol.mm b/src/plugins/avfoundation/mediaplayer/avfmediaplayercontrol.mm index 5f7bae1c8..bf7ebb4a0 100644 --- a/src/plugins/avfoundation/mediaplayer/avfmediaplayercontrol.mm +++ b/src/plugins/avfoundation/mediaplayer/avfmediaplayercontrol.mm @@ -60,6 +60,7 @@ void AVFMediaPlayerControl::setSession(AVFMediaPlayerSession *session) connect(m_session, SIGNAL(positionChanged(qint64)), this, SIGNAL(positionChanged(qint64))); connect(m_session, SIGNAL(durationChanged(qint64)), this, SIGNAL(durationChanged(qint64))); + connect(m_session, SIGNAL(bufferStatusChanged(int)), this, SIGNAL(bufferStatusChanged(int))); connect(m_session, SIGNAL(stateChanged(QMediaPlayer::State)), this, SIGNAL(stateChanged(QMediaPlayer::State))); connect(m_session, SIGNAL(mediaStatusChanged(QMediaPlayer::MediaStatus)), diff --git a/src/plugins/avfoundation/mediaplayer/avfmediaplayersession.h b/src/plugins/avfoundation/mediaplayer/avfmediaplayersession.h index ef854e23f..1e4311140 100644 --- a/src/plugins/avfoundation/mediaplayer/avfmediaplayersession.h +++ b/src/plugins/avfoundation/mediaplayer/avfmediaplayersession.h @@ -105,10 +105,14 @@ public Q_SLOTS: void processLoadStateChange(); void processLoadStateFailure(); + + void processBufferStateChange(int bufferStatus); + Q_SIGNALS: void positionChanged(qint64 position); void durationChanged(qint64 duration); void stateChanged(QMediaPlayer::State newState); + void bufferStatusChanged(int bufferStatus); void mediaStatusChanged(QMediaPlayer::MediaStatus status); void volumeChanged(int volume); void mutedChanged(bool muted); @@ -176,6 +180,7 @@ private: qint64 m_requestedPosition; qint64 m_duration; + int m_bufferStatus; bool m_videoAvailable; bool m_audioAvailable; bool m_seekable; diff --git a/src/plugins/avfoundation/mediaplayer/avfmediaplayersession.mm b/src/plugins/avfoundation/mediaplayer/avfmediaplayersession.mm index f4eb8a4ea..923aeabe6 100644 --- a/src/plugins/avfoundation/mediaplayer/avfmediaplayersession.mm +++ b/src/plugins/avfoundation/mediaplayer/avfmediaplayersession.mm @@ -52,7 +52,8 @@ static NSString* const AVF_TRACKS_KEY = @"tracks"; static NSString* const AVF_PLAYABLE_KEY = @"playable"; //AVPlayerItem keys -static NSString* const AVF_STATUS_KEY = @"status"; +static NSString* const AVF_STATUS_KEY = @"status"; +static NSString* const AVF_BUFFER_LIKELY_KEEP_UP_KEY = @"playbackLikelyToKeepUp"; //AVPlayer keys static NSString* const AVF_RATE_KEY = @"rate"; @@ -60,6 +61,7 @@ static NSString* const AVF_CURRENT_ITEM_KEY = @"currentItem"; static void *AVFMediaPlayerSessionObserverRateObservationContext = &AVFMediaPlayerSessionObserverRateObservationContext; static void *AVFMediaPlayerSessionObserverStatusObservationContext = &AVFMediaPlayerSessionObserverStatusObservationContext; +static void *AVFMediaPlayerSessionObserverBufferLikelyToKeepUpContext = &AVFMediaPlayerSessionObserverBufferLikelyToKeepUpContext; static void *AVFMediaPlayerSessionObserverCurrentItemObservationContext = &AVFMediaPlayerSessionObserverCurrentItemObservationContext; @interface AVFMediaPlayerSessionObserver : NSObject @@ -70,6 +72,7 @@ static void *AVFMediaPlayerSessionObserverCurrentItemObservationContext = &AVFMe AVPlayerItem *m_playerItem; AVPlayerLayer *m_playerLayer; NSURL *m_URL; + BOOL m_bufferIsLikelyToKeepUp; } @property (readonly, getter=player) AVPlayer* m_player; @@ -100,6 +103,7 @@ static void *AVFMediaPlayerSessionObserverCurrentItemObservationContext = &AVFMe return nil; self->m_session = session; + self->m_bufferIsLikelyToKeepUp = FALSE; return self; } @@ -139,6 +143,7 @@ static void *AVFMediaPlayerSessionObserverCurrentItemObservationContext = &AVFMe { if (m_playerItem) { [m_playerItem removeObserver:self forKeyPath:AVF_STATUS_KEY]; + [m_playerItem removeObserver:self forKeyPath:AVF_BUFFER_LIKELY_KEEP_UP_KEY]; [[NSNotificationCenter defaultCenter] removeObserver:self name:AVPlayerItemDidPlayToEndTimeNotification @@ -216,6 +221,11 @@ static void *AVFMediaPlayerSessionObserverCurrentItemObservationContext = &AVFMe options:NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew context:AVFMediaPlayerSessionObserverStatusObservationContext]; + [m_playerItem addObserver:self + forKeyPath:AVF_BUFFER_LIKELY_KEEP_UP_KEY + options:NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew + context:AVFMediaPlayerSessionObserverBufferLikelyToKeepUpContext]; + //When the player item has played to its end time we'll toggle //the movie controller Pause button to be the Play button [[NSNotificationCenter defaultCenter] addObserver:self @@ -329,6 +339,15 @@ static void *AVFMediaPlayerSessionObserverCurrentItemObservationContext = &AVFMe break; } } + else if (context == AVFMediaPlayerSessionObserverBufferLikelyToKeepUpContext) + { + const bool isPlaybackLikelyToKeepUp = [m_playerItem isPlaybackLikelyToKeepUp]; + if (isPlaybackLikelyToKeepUp != m_bufferIsLikelyToKeepUp) { + m_bufferIsLikelyToKeepUp = isPlaybackLikelyToKeepUp; + QMetaObject::invokeMethod(m_session, "processBufferStateChange", Qt::AutoConnection, + Q_ARG(int, isPlaybackLikelyToKeepUp ? 100 : 0)); + } + } //AVPlayer "rate" property value observer. else if (context == AVFMediaPlayerSessionObserverRateObservationContext) { @@ -386,6 +405,7 @@ AVFMediaPlayerSession::AVFMediaPlayerSession(AVFMediaPlayerService *service, QOb , m_rate(1.0) , m_requestedPosition(-1) , m_duration(0) + , m_bufferStatus(0) , m_videoAvailable(false) , m_audioAvailable(false) , m_seekable(false) @@ -526,11 +546,10 @@ qint64 AVFMediaPlayerSession::duration() const int AVFMediaPlayerSession::bufferStatus() const { - //BUG: bufferStatus may be relevant? #ifdef QT_DEBUG_AVF qDebug() << Q_FUNC_INFO; #endif - return 100; + return m_bufferStatus; } int AVFMediaPlayerSession::volume() const @@ -892,6 +911,15 @@ void AVFMediaPlayerSession::processLoadStateFailure() Q_EMIT stateChanged((m_state = QMediaPlayer::StoppedState)); } +void AVFMediaPlayerSession::processBufferStateChange(int bufferStatus) +{ + if (bufferStatus == m_bufferStatus) + return; + + m_bufferStatus = bufferStatus; + Q_EMIT bufferStatusChanged(bufferStatus); +} + void AVFMediaPlayerSession::processPositionChange() { if (m_state == QMediaPlayer::StoppedState) -- cgit v1.2.3