diff options
author | Dmytro Poplavskiy <dmytro.poplavskiy@nokia.com> | 2010-02-19 02:05:42 (GMT) |
---|---|---|
committer | Dmytro Poplavskiy <dmytro.poplavskiy@nokia.com> | 2010-02-19 02:05:42 (GMT) |
commit | 7b8f7efa9c71dfea7d1182824e921cf261ce1c6f (patch) | |
tree | 200e856b4735b1249c2c249010135f0b0aee7ac0 /src | |
parent | 50fe29b569849d05db1625fa30fbd8618a941c5a (diff) | |
download | Qt-7b8f7efa9c71dfea7d1182824e921cf261ce1c6f.zip Qt-7b8f7efa9c71dfea7d1182824e921cf261ce1c6f.tar.gz Qt-7b8f7efa9c71dfea7d1182824e921cf261ce1c6f.tar.bz2 |
QuickTime playback backend: Listen for movie load state changes.
To start playback and notify video output
when movie reached playable state.
Diffstat (limited to 'src')
-rw-r--r-- | src/plugins/mediaservices/qt7/mediaplayer/qt7playersession.h | 4 | ||||
-rw-r--r-- | src/plugins/mediaservices/qt7/mediaplayer/qt7playersession.mm | 135 |
2 files changed, 111 insertions, 28 deletions
diff --git a/src/plugins/mediaservices/qt7/mediaplayer/qt7playersession.h b/src/plugins/mediaservices/qt7/mediaplayer/qt7playersession.h index 2a6bab7..8187f72 100644 --- a/src/plugins/mediaservices/qt7/mediaplayer/qt7playersession.h +++ b/src/plugins/mediaservices/qt7/mediaplayer/qt7playersession.h @@ -93,6 +93,8 @@ public: bool isSeekable() const; qreal playbackRate() const; + +public slots: void setPlaybackRate(qreal rate); void setPosition(qint64 pos); @@ -105,6 +107,8 @@ public: void setMuted(bool muted); void processEOS(); + void processStateChange(); + void processVolumeChange(); signals: void positionChanged(qint64 position); diff --git a/src/plugins/mediaservices/qt7/mediaplayer/qt7playersession.mm b/src/plugins/mediaservices/qt7/mediaplayer/qt7playersession.mm index d9bb646..9ea33e4 100644 --- a/src/plugins/mediaservices/qt7/mediaplayer/qt7playersession.mm +++ b/src/plugins/mediaservices/qt7/mediaplayer/qt7playersession.mm @@ -68,6 +68,7 @@ QT_BEGIN_NAMESPACE - (QTMovieObserver *) initWithPlayerSession:(QT7PlayerSession*)session; - (void) setMovie:(QTMovie *)movie; - (void) processEOS:(NSNotification *)notification; +- (void) processStateChange:(NSNotification *)notification; @end @implementation QTMovieObserver @@ -97,6 +98,12 @@ QT_BEGIN_NAMESPACE [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(processEOS:) name: QTMovieDidEndNotification object: m_movie]; + [[NSNotificationCenter defaultCenter] addObserver: self selector: + @selector(processStateChange:) name: QTMovieLoadStateDidChangeNotification object: m_movie]; + + [[NSNotificationCenter defaultCenter] addObserver: self selector: + @selector(processVolumeChange:) name: QTMovieVolumeDidChangeNotification object: m_movie]; + [movie retain]; } } @@ -107,6 +114,19 @@ QT_BEGIN_NAMESPACE m_session->processEOS(); } +- (void) processStateChange:(NSNotification *)notification +{ + Q_UNUSED(notification); + m_session->processStateChange(); +} + +- (void) processVolumeChange:(NSNotification *)notification +{ + Q_UNUSED(notification); + m_session->processVolumeChange(); +} + + @end static CFStringRef qString2CFStringRef(const QString &string) @@ -145,8 +165,6 @@ void QT7PlayerSession::setVideoOutput(QT7VideoOutput *output) if (m_videoOutput == output) return; - qDebug() << "set output" << output; - if (m_videoOutput) { m_videoOutput->setEnabled(false); m_videoOutput->setMovie(0); @@ -251,12 +269,11 @@ void QT7PlayerSession::setPosition(qint64 pos) void QT7PlayerSession::play() { - m_state = QMediaPlayer::PlayingState; - float preferredRate = [[(QTMovie*)m_QTMovie attributeForKey:@"QTMoviePreferredRateAttribute"] floatValue]; [(QTMovie*)m_QTMovie setRate:preferredRate*m_rate]; - emit stateChanged(m_state); + if (m_state != QMediaPlayer::PlayingState) + emit stateChanged(m_state = QMediaPlayer::PlayingState); } void QT7PlayerSession::pause() @@ -327,6 +344,7 @@ void QT7PlayerSession::setMedia(const QMediaContent &content, QIODevice *stream) m_resources = content; m_mediaStream = stream; + m_mediaStatus = QMediaPlayer::NoMedia; QUrl url; @@ -336,24 +354,15 @@ void QT7PlayerSession::setMedia(const QMediaContent &content, QIODevice *stream) return; NSError *err = 0; - QTDataReference *dataRef = 0; - - if ( url.scheme() == "file" ) { - NSString *nsFileName = (NSString *)qString2CFStringRef( url.toLocalFile() ); - dataRef = [QTDataReference dataReferenceWithReferenceToFile:nsFileName]; - } else { - NSString *urlString = (NSString *)qString2CFStringRef( url.toString() ); - NSURL *url = [NSURL URLWithString: urlString]; - dataRef = [QTDataReference dataReferenceWithReferenceToURL:url]; - } + NSString *urlString = (NSString *)qString2CFStringRef(url.toString()); NSDictionary *attr = [NSDictionary dictionaryWithObjectsAndKeys: - dataRef, QTMovieDataReferenceAttribute, - [NSNumber numberWithBool:YES], QTMovieOpenAsyncOKAttribute, - [NSNumber numberWithBool:YES], QTMovieIsActiveAttribute, - [NSNumber numberWithBool:YES], QTMovieResolveDataRefsAttribute, - [NSNumber numberWithBool:YES], QTMovieDontInteractWithUserAttribute, - nil]; + [NSURL URLWithString:urlString], QTMovieURLAttribute, + [NSNumber numberWithBool:YES], QTMovieOpenAsyncOKAttribute, + [NSNumber numberWithBool:YES], QTMovieIsActiveAttribute, + [NSNumber numberWithBool:YES], QTMovieResolveDataRefsAttribute, + [NSNumber numberWithBool:YES], QTMovieDontInteractWithUserAttribute, + nil]; m_QTMovie = [[QTMovie movieWithAttributes:attr error:&err] retain]; @@ -362,19 +371,15 @@ void QT7PlayerSession::setMedia(const QMediaContent &content, QIODevice *stream) m_QTMovie = 0; QString description = QString::fromUtf8([[err localizedDescription] UTF8String]); - qDebug() << "QT7PlayerSession::setMedia error" << description; emit error(QMediaPlayer::FormatError, description ); } else { [(QTMovieObserver*)m_movieObserver setMovie:(QTMovie*)m_QTMovie]; - if (m_videoOutput) { - m_videoOutput->setEnabled(true); + if (m_videoOutput) { m_videoOutput->setMovie(m_QTMovie); + m_videoOutput->setEnabled(true); } - - emit durationChanged(duration()); - emit audioAvailableChanged(isAudioAvailable()); - emit videoAvailableChanged(isVideoAvailable()); + processStateChange(); [(QTMovie*)m_QTMovie setMuted:m_muted]; setVolume(m_volume); @@ -406,6 +411,80 @@ void QT7PlayerSession::processEOS() emit mediaStatusChanged(m_mediaStatus); } +void QT7PlayerSession::processStateChange() +{ + signed long state = [[(QTMovie*)m_QTMovie attributeForKey:QTMovieLoadStateAttribute] + longValue]; + //qDebug() << "new State:" << state; + +#ifndef QUICKTIME_C_API_AVAILABLE + enum { + kMovieLoadStateError = -1L, + kMovieLoadStateLoading = 1000, + kMovieLoadStateLoaded = 2000, + kMovieLoadStatePlayable = 10000, + kMovieLoadStatePlaythroughOK = 20000, + kMovieLoadStateComplete = 100000 + }; +#endif + + QMediaPlayer::MediaStatus newStatus = QMediaPlayer::NoMedia; + bool isPlaying = (m_state != QMediaPlayer::StoppedState); + + if (state >= kMovieLoadStateComplete) { + newStatus = isPlaying ? QMediaPlayer::BufferedMedia : QMediaPlayer::LoadedMedia; + } else if (state >= kMovieLoadStatePlayable) + newStatus = isPlaying ? QMediaPlayer::BufferingMedia : QMediaPlayer::LoadingMedia; + else if (state >= kMovieLoadStateLoading) + newStatus = isPlaying ? QMediaPlayer::StalledMedia : QMediaPlayer::LoadingMedia; + + if (state == kMovieLoadStateError) { + newStatus = QMediaPlayer::InvalidMedia; + emit error(QMediaPlayer::FormatError, tr("Playback failed")); + } + + if (newStatus != m_mediaStatus) { + switch (newStatus) { + case QMediaPlayer::BufferedMedia: + case QMediaPlayer::BufferingMedia: + //delayed playback start is necessary for network sources + if (m_state == QMediaPlayer::PlayingState) { + QMetaObject::invokeMethod(this, "play", Qt::QueuedConnection); + } + //fall + case QMediaPlayer::LoadedMedia: + case QMediaPlayer::LoadingMedia: + emit durationChanged(duration()); + emit audioAvailableChanged(isAudioAvailable()); + emit videoAvailableChanged(isVideoAvailable()); + + //give output a change to re-read movie properties + if (m_videoOutput) + m_videoOutput->setMovie(m_QTMovie); + + break; + case QMediaPlayer::InvalidMedia: + emit stateChanged(m_state = QMediaPlayer::StoppedState); + default: + break; + } + + emit mediaStatusChanged(m_mediaStatus = newStatus); + } +} + +void QT7PlayerSession::processVolumeChange() +{ + if (!m_QTMovie) + return; + + int newVolume = qRound(100.0f*[((QTMovie*)m_QTMovie) volume]); + + if (newVolume != m_volume) { + emit volumeChanged(m_volume = newVolume); + } +} + #include "moc_qt7playersession.cpp" QT_END_NAMESPACE |