/src/3rdparty/phonon/mmf/abstractvideoplayer.cpp
https://bitbucket.org/ultra_iter/qt-vtl · C++ · 518 lines · 340 code · 123 blank · 55 comment · 39 complexity · bd097c4b368e3c5be718b8b1a469e295 MD5 · raw file
- /* This file is part of the KDE project.
- Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
- This library is free software: you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation, either version 2.1 or 3 of the License.
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Lesser General Public License for more details.
- You should have received a copy of the GNU Lesser General Public License
- along with this library. If not, see <http://www.gnu.org/licenses/>.
- */
- #include <QDir>
- #include <QUrl>
- #include <QTimer>
- #include <QWidget>
- #include <coemain.h> // for CCoeEnv
- #include "abstractvideoplayer.h"
- #include "utils.h"
- #ifndef QT_NO_DEBUG
- #include "objectdump.h"
- #endif
- QT_BEGIN_NAMESPACE
- using namespace Phonon;
- using namespace Phonon::MMF;
- /*! \class MMF::AbstractVideoPlayer
- \internal
- */
- //-----------------------------------------------------------------------------
- // Constructor / destructor
- //-----------------------------------------------------------------------------
- MMF::AbstractVideoPlayer::AbstractVideoPlayer(MediaObject *parent, const AbstractPlayer *player)
- : AbstractMediaPlayer(parent, player)
- , m_wsSession(CCoeEnv::Static()->WsSession())
- , m_screenDevice(*CCoeEnv::Static()->ScreenDevice())
- , m_window(0)
- , m_scaleWidth(1.0)
- , m_scaleHeight(1.0)
- , m_totalTime(0)
- {
- }
- void MMF::AbstractVideoPlayer::construct()
- {
- TRACE_CONTEXT(AbstractVideoPlayer::AbstractVideoPlayer, EVideoApi);
- TRACE_ENTRY_0();
- if (m_videoOutput) {
- initVideoOutput();
- m_window = m_videoOutput->videoWindow();
- }
- createPlayer();
- m_player->RegisterForVideoLoadingNotification(*this);
- TRACE_EXIT_0();
- }
- MMF::AbstractVideoPlayer::~AbstractVideoPlayer()
- {
- TRACE_CONTEXT(AbstractVideoPlayer::~AbstractVideoPlayer, EVideoApi);
- TRACE_ENTRY_0();
- // QObject destructor removes all signal-slot connections involving this
- // object, so we do not need to disconnect from m_videoOutput here.
- TRACE_EXIT_0();
- }
- CVideoPlayerUtility* MMF::AbstractVideoPlayer::nativePlayer() const
- {
- return m_player.data();
- }
- //-----------------------------------------------------------------------------
- // Public API
- //-----------------------------------------------------------------------------
- void MMF::AbstractVideoPlayer::doPlay()
- {
- TRACE_CONTEXT(AbstractVideoPlayer::doPlay, EVideoApi);
- handlePendingParametersChanged();
- m_player->Play();
- }
- void MMF::AbstractVideoPlayer::doPause()
- {
- TRACE_CONTEXT(AbstractVideoPlayer::doPause, EVideoApi);
- TRAPD(err, m_player->PauseL());
- if (KErrNone != err && state() != ErrorState) {
- TRACE("PauseL error %d", err);
- setError(tr("Pause failed"), err);
- }
- }
- void MMF::AbstractVideoPlayer::doStop()
- {
- m_player->Stop();
- }
- void MMF::AbstractVideoPlayer::doSeek(qint64 ms)
- {
- TRACE_CONTEXT(AbstractVideoPlayer::doSeek, EVideoApi);
- TRAPD(err, m_player->SetPositionL(TTimeIntervalMicroSeconds(ms * 1000)));
- if (KErrNone != err)
- setError(tr("Seek failed"), err);
- }
- int MMF::AbstractVideoPlayer::setDeviceVolume(int mmfVolume)
- {
- TRAPD(err, m_player->SetVolumeL(mmfVolume));
- return err;
- }
- int MMF::AbstractVideoPlayer::openFile(const QString &fileName)
- {
- const QHBufC nativeFileName(QDir::toNativeSeparators(fileName));
- TRAPD(err, m_player->OpenFileL(*nativeFileName));
- return err;
- }
- int MMF::AbstractVideoPlayer::openFile(RFile &file)
- {
- TRAPD(err, m_player->OpenFileL(file));
- return err;
- }
- int MMF::AbstractVideoPlayer::openUrl(const QString &url, int iap)
- {
- TRAPD(err, m_player->OpenUrlL(qt_QString2TPtrC(url), iap));
- return err;
- }
- int MMF::AbstractVideoPlayer::openDescriptor(const TDesC8 &des)
- {
- TRAPD(err, m_player->OpenDesL(des));
- return err;
- }
- int MMF::AbstractVideoPlayer::bufferStatus() const
- {
- int result = 0;
- TRAP_IGNORE(m_player->GetVideoLoadingProgressL(result));
- return result;
- }
- void MMF::AbstractVideoPlayer::doClose()
- {
- m_player->Close();
- }
- bool MMF::AbstractVideoPlayer::hasVideo() const
- {
- return true;
- }
- qint64 MMF::AbstractVideoPlayer::getCurrentTime() const
- {
- TRACE_CONTEXT(AbstractVideoPlayer::getCurrentTime, EVideoApi);
- TTimeIntervalMicroSeconds us;
- TRAPD(err, us = m_player->PositionL())
- qint64 result = 0;
- if (KErrNone == err) {
- result = toMilliSeconds(us);
- } else {
- TRACE("PositionL error %d", err);
- // If we don't cast away constness here, we simply have to ignore
- // the error.
- const_cast<AbstractVideoPlayer*>(this)->setError(tr("Getting position failed"), err);
- }
- return result;
- }
- qint64 MMF::AbstractVideoPlayer::totalTime() const
- {
- return m_totalTime;
- }
- //-----------------------------------------------------------------------------
- // Public slots
- //-----------------------------------------------------------------------------
- void MMF::AbstractVideoPlayer::videoWindowChanged()
- {
- TRACE_CONTEXT(AbstractVideoPlayer::videoWindowChanged, EVideoInternal);
- TRACE_ENTRY("state %d", state());
- m_window = m_videoOutput ? m_videoOutput->videoWindow() : 0;
- if (m_videoOutput)
- m_videoOutput->dump();
- handleVideoWindowChanged();
- TRACE_EXIT_0();
- }
- void MMF::AbstractVideoPlayer::aspectRatioChanged()
- {
- TRACE_CONTEXT(AbstractVideoPlayer::aspectRatioChanged, EVideoInternal);
- TRACE_ENTRY("state %d aspectRatio %d", state());
- if (m_videoOutput)
- updateScaleFactors(m_videoOutput->videoWindowSize());
- TRACE_EXIT_0();
- }
- void MMF::AbstractVideoPlayer::scaleModeChanged()
- {
- TRACE_CONTEXT(AbstractVideoPlayer::scaleModeChanged, EVideoInternal);
- TRACE_ENTRY("state %d", state());
- if (m_videoOutput)
- updateScaleFactors(m_videoOutput->videoWindowSize());
- TRACE_EXIT_0();
- }
- //-----------------------------------------------------------------------------
- // MVideoPlayerUtilityObserver callbacks
- //-----------------------------------------------------------------------------
- void MMF::AbstractVideoPlayer::MvpuoOpenComplete(TInt aError)
- {
- TRACE_CONTEXT(AbstractVideoPlayer::MvpuoOpenComplete, EVideoApi);
- TRACE_ENTRY("state %d error %d", state(), aError);
- __ASSERT_ALWAYS(LoadingState == state() ||
- progressiveDownloadStalled() && BufferingState == state(),
- Utils::panic(InvalidStatePanic));
- if (KErrNone == aError)
- m_player->Prepare();
- else
- setError(tr("Opening clip failed"), aError);
- TRACE_EXIT_0();
- }
- void MMF::AbstractVideoPlayer::MvpuoPrepareComplete(TInt aError)
- {
- TRACE_CONTEXT(AbstractVideoPlayer::MvpuoPrepareComplete, EVideoApi);
- TRACE_ENTRY("state %d error %d", state(), aError);
- __ASSERT_ALWAYS(LoadingState == state() ||
- progressiveDownloadStalled() && BufferingState == state(),
- Utils::panic(InvalidStatePanic));
- TRAPD(err, getVideoClipParametersL(aError));
- if (KErrNone == err) {
- if (m_videoOutput)
- m_videoOutput->dump();
- maxVolumeChanged(m_player->MaxVolume());
- if (m_videoOutput)
- m_videoOutput->setVideoSize(m_videoFrameSize);
- prepareCompleted();
- handlePendingParametersChanged();
- emit totalTimeChanged(totalTime());
- }
- loadingComplete(aError);
- TRACE_EXIT_0();
- }
- void MMF::AbstractVideoPlayer::getVideoClipParametersL(TInt aError)
- {
- User::LeaveIfError(aError);
- // Get frame size
- TSize size;
- m_player->VideoFrameSizeL(size);
- m_videoFrameSize = QSize(size.iWidth, size.iHeight);
- // Get duration
- m_totalTime = toMilliSeconds(m_player->DurationL());
- }
- void MMF::AbstractVideoPlayer::MvpuoFrameReady(CFbsBitmap &aFrame, TInt aError)
- {
- TRACE_CONTEXT(AbstractVideoPlayer::MvpuoFrameReady, EVideoApi);
- TRACE_ENTRY("state %d error %d", state(), aError);
- Q_UNUSED(aFrame);
- Q_UNUSED(aError); // suppress warnings in release builds
- TRACE_EXIT_0();
- }
- void MMF::AbstractVideoPlayer::MvpuoPlayComplete(TInt aError)
- {
- TRACE_CONTEXT(AbstractVideoPlayer::MvpuoPlayComplete, EVideoApi)
- TRACE_ENTRY("state %d error %d", state(), aError);
- // Call base class function which handles end of playback for both
- // audio and video clips.
- playbackComplete(aError);
- TRACE_EXIT_0();
- }
- void MMF::AbstractVideoPlayer::MvpuoEvent(const TMMFEvent &aEvent)
- {
- TRACE_CONTEXT(AbstractVideoPlayer::MvpuoEvent, EVideoApi);
- TRACE_ENTRY("state %d", state());
- Q_UNUSED(aEvent);
- TRACE_EXIT_0();
- }
- //-----------------------------------------------------------------------------
- // MVideoLoadingObserver callbacks
- //-----------------------------------------------------------------------------
- void MMF::AbstractVideoPlayer::MvloLoadingStarted()
- {
- bufferingStarted();
- }
- void MMF::AbstractVideoPlayer::MvloLoadingComplete()
- {
- bufferingComplete();
- }
- //-----------------------------------------------------------------------------
- // Video window updates
- //-----------------------------------------------------------------------------
- void MMF::AbstractVideoPlayer::videoOutputChanged()
- {
- TRACE_CONTEXT(AbstractVideoPlayer::videoOutputChanged, EVideoInternal);
- TRACE_ENTRY_0();
- if (m_videoOutput)
- initVideoOutput();
- videoWindowChanged();
- TRACE_EXIT_0();
- }
- void MMF::AbstractVideoPlayer::initVideoOutput()
- {
- Q_ASSERT(m_videoOutput);
- bool connected = connect(
- m_videoOutput, SIGNAL(videoWindowChanged()),
- this, SLOT(videoWindowChanged())
- );
- Q_ASSERT(connected);
- connected = connect(
- m_videoOutput, SIGNAL(aspectRatioChanged()),
- this, SLOT(aspectRatioChanged())
- );
- Q_ASSERT(connected);
- connected = connect(
- m_videoOutput, SIGNAL(scaleModeChanged()),
- this, SLOT(scaleModeChanged())
- );
- Q_ASSERT(connected);
- // Suppress warnings in release builds
- Q_UNUSED(connected);
- m_videoOutput->setVideoSize(m_videoFrameSize);
- }
- // Helper function for aspect ratio / scale mode handling
- QSize scaleToAspect(const QSize &srcRect, int aspectWidth, int aspectHeight)
- {
- const qreal aspectRatio = qreal(aspectWidth) / aspectHeight;
- int width = srcRect.width();
- int height = srcRect.width() / aspectRatio;
- if (height > srcRect.height()){
- height = srcRect.height();
- width = srcRect.height() * aspectRatio;
- }
- return QSize(width, height);
- }
- void MMF::AbstractVideoPlayer::updateScaleFactors(const QSize &windowSize, bool apply)
- {
- Q_ASSERT(m_videoOutput);
- if (m_videoFrameSize.isValid()) {
- QRect videoRect;
- // Calculate size of smallest rect which contains video frame size
- // and conforms to aspect ratio
- switch (m_videoOutput->aspectRatio()) {
- case Phonon::VideoWidget::AspectRatioAuto:
- videoRect.setSize(m_videoFrameSize);
- break;
- case Phonon::VideoWidget::AspectRatioWidget:
- videoRect.setSize(windowSize);
- break;
- case Phonon::VideoWidget::AspectRatio4_3:
- videoRect.setSize(scaleToAspect(m_videoFrameSize, 4, 3));
- break;
- case Phonon::VideoWidget::AspectRatio16_9:
- videoRect.setSize(scaleToAspect(m_videoFrameSize, 16, 9));
- break;
- }
- // Scale to fill the window width
- const int windowWidth = windowSize.width();
- const int windowHeight = windowSize.height();
- const qreal windowScaleFactor = qreal(windowWidth) / videoRect.width();
- int videoWidth = windowWidth;
- int videoHeight = videoRect.height() * windowScaleFactor;
- const qreal windowToVideoHeightRatio = qreal(windowHeight) / videoHeight;
- switch (m_videoOutput->scaleMode()) {
- case Phonon::VideoWidget::ScaleAndCrop:
- if (videoHeight < windowHeight) {
- videoWidth *= windowToVideoHeightRatio;
- videoHeight = windowHeight;
- }
- break;
- case Phonon::VideoWidget::FitInView:
- default:
- if (videoHeight > windowHeight) {
- videoWidth *= windowToVideoHeightRatio;
- videoHeight = windowHeight;
- }
- break;
- }
- // Calculate scale factors
- m_scaleWidth = 100.0f * videoWidth / m_videoFrameSize.width();
- m_scaleHeight = 100.0f * videoHeight / m_videoFrameSize.height();
- if (apply)
- parametersChanged(ScaleFactors);
- }
- }
- void MMF::AbstractVideoPlayer::parametersChanged(VideoParameters parameters)
- {
- if (state() == LoadingState || progressiveDownloadStalled() && BufferingState == state())
- m_pendingChanges |= parameters;
- else
- handleParametersChanged(parameters);
- }
- void MMF::AbstractVideoPlayer::handlePendingParametersChanged()
- {
- if (m_pendingChanges)
- handleParametersChanged(m_pendingChanges);
- m_pendingChanges = 0;
- }
- //-----------------------------------------------------------------------------
- // Metadata
- //-----------------------------------------------------------------------------
- int MMF::AbstractVideoPlayer::numberOfMetaDataEntries() const
- {
- int numberOfEntries = 0;
- TRAP_IGNORE(numberOfEntries = m_player->NumberOfMetaDataEntriesL());
- return numberOfEntries;
- }
- QPair<QString, QString> MMF::AbstractVideoPlayer::metaDataEntry(int index) const
- {
- CMMFMetaDataEntry *entry = 0;
- QT_TRAP_THROWING(entry = m_player->MetaDataEntryL(index));
- return QPair<QString, QString>(qt_TDesC2QString(entry->Name()), qt_TDesC2QString(entry->Value()));
- }
- QT_END_NAMESPACE