summaryrefslogtreecommitdiffstats
path: root/src/plugins/symbian/openmaxal/mediaplayer/xaplaysessionimpl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/symbian/openmaxal/mediaplayer/xaplaysessionimpl.cpp')
-rw-r--r--src/plugins/symbian/openmaxal/mediaplayer/xaplaysessionimpl.cpp1259
1 files changed, 1259 insertions, 0 deletions
diff --git a/src/plugins/symbian/openmaxal/mediaplayer/xaplaysessionimpl.cpp b/src/plugins/symbian/openmaxal/mediaplayer/xaplaysessionimpl.cpp
new file mode 100644
index 000000000..88a06807f
--- /dev/null
+++ b/src/plugins/symbian/openmaxal/mediaplayer/xaplaysessionimpl.cpp
@@ -0,0 +1,1259 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QString>
+#include <QVariant>
+#include <QList>
+#include <QStringList>
+#include <QImage>
+
+#include "xaplaysessionimpl.h"
+#include "xaplaysessioncommon.h"
+#include "xacommon.h"
+
+#ifdef USE_VIDEOPLAYERUTILITY
+#include <COECNTRL.H>
+#endif
+
+_LIT8(K8WAVMIMETYPE, "audio/wav");
+
+#define RET_ERR_IF_ERR(e) \
+ if (e != 0) {\
+ return e; \
+ } \
+
+#define MAX_NUMBER_INTERFACES 20
+const TUint KPlayPosUpdatePeriod = 1000;
+
+/* Local functions for callback registation */
+void MediaPlayerCallback( XAObjectItf caller,
+ const void *pContext,
+ XAuint32 event,
+ XAresult result,
+ XAuint32 param,
+ void *pInterface);
+
+void PlayItfCallback( XAPlayItf caller,
+ void *pContext,
+ XAuint32 event);
+
+void PrefetchItfCallback( XAPrefetchStatusItf caller,
+ void * pContext,
+ XAuint32 event);
+
+void StreamInformationItfCallback( XAStreamInformationItf caller,
+ XAuint32 eventId,
+ XAuint32 streamIndex,
+ void * pEventData,
+ void * pContext);
+
+XAPlaySessionImpl::XAPlaySessionImpl(XAPlayObserver& parent)
+:mParent(parent),
+mEOEngine(NULL),
+mMOPlayer(NULL),
+mPlayItf(NULL),
+mSeekItf(NULL),
+mURIName(NULL),
+mWAVMime(NULL),
+mbMetadataAvailable(EFalse),
+mbVolEnabled(EFalse),
+mbMuteEnabled(EFalse),
+mbPrefetchStatusChange(EFalse),
+mbStreamInfoAvailable(EFalse),
+mbPlaybackRateItfAvailable(EFalse),
+mbScalable(EFalse),
+mCurrAspectRatioMode(Qt::KeepAspectRatio)
+#ifdef USE_VIDEOPLAYERUTILITY
+, mVideoPlayUtil(NULL)
+, mActiveSchedulerWait(NULL)
+#endif
+{
+}
+
+XAPlaySessionImpl::~XAPlaySessionImpl()
+{
+ if (mMOPlayer)
+ (*mMOPlayer)->Destroy(mMOPlayer);
+
+ if (mEOEngine)
+ (*mEOEngine)->Destroy(mEOEngine);
+
+ delete mURIName;
+ delete mWAVMime;
+
+ //clear metadata datastructures
+ alKeyMap.clear();
+ keyMap.clear();
+ extendedKeyMap.clear();
+
+#ifdef USE_VIDEOPLAYERUTILITY
+ delete mVideoPlayUtil;
+ if (mActiveSchedulerWait && \
+ mActiveSchedulerWait->IsStarted()) {
+ mActiveSchedulerWait->AsyncStop();
+ }
+
+ delete mActiveSchedulerWait;
+#endif
+
+}
+
+TInt XAPlaySessionImpl::postConstruct()
+{
+ TInt retVal;
+ XAresult xaRes;
+ XAEngineOption engineOption[] = { (XAuint32) XA_ENGINEOPTION_THREADSAFE,
+ (XAuint32) XA_BOOLEAN_TRUE
+ };
+ XAEngineItf engineItf;
+
+ mNativeDisplay.locatorType = XA_DATALOCATOR_NATIVEDISPLAY;
+ mNativeDisplay.hWindow = NULL;
+ mNativeDisplay.hDisplay = NULL;
+ mVideoSink.pLocator = (void*)&mNativeDisplay;
+ mVideoSink.pFormat = NULL;
+
+ // Create and realize Engine object
+ xaRes = xaCreateEngine (&mEOEngine, 1, engineOption, 0, NULL, NULL);
+ retVal = mapError(xaRes, ETrue);
+ RET_ERR_IF_ERR(retVal);
+ xaRes = (*mEOEngine)->Realize(mEOEngine, XA_BOOLEAN_FALSE);
+ retVal = mapError(xaRes, ETrue);
+ RET_ERR_IF_ERR(retVal);
+
+ // Create and realize Output Mix object to be used by player
+ xaRes = (*mEOEngine)->GetInterface(mEOEngine, XA_IID_ENGINE, (void**) &engineItf);
+ retVal = mapError(xaRes, ETrue);
+ RET_ERR_IF_ERR(retVal);
+
+ TRAP(retVal, mWAVMime = HBufC8::NewL(K8WAVMIMETYPE().Length() + 1));
+ RET_ERR_IF_ERR(retVal);
+ TPtr8 ptr = mWAVMime->Des();
+ ptr = K8WAVMIMETYPE(); // copy uri name into local variable
+ ptr.PtrZ(); // append zero terminator to end of URI
+
+#ifdef USE_VIDEOPLAYERUTILITY
+ TRAP(retVal, mVideoPlayUtil =
+ CVideoPlayerUtility2::NewL( *this,
+ EMdaPriorityNormal,
+ EMdaPriorityPreferenceTimeAndQuality)
+ );
+ mActiveSchedulerWait = new CActiveSchedulerWait;
+#endif
+
+ return retVal;
+}
+
+TInt XAPlaySessionImpl::addNativeDisplay(RWindow* window, RWsSession* wssession)
+ {
+ TInt retVal(KErrNotReady);
+
+ if (!mMOPlayer && !mPlayItf) {
+ // window can only be set before player creation
+ mNativeDisplay.locatorType = XA_DATALOCATOR_NATIVEDISPLAY;
+ mNativeDisplay.hWindow = (void*)window;
+ mNativeDisplay.hDisplay = (void*)wssession;
+ retVal = KErrNone;
+ }
+ return retVal;
+}
+
+TInt XAPlaySessionImpl::updateNativeDisplay(RWindow* /*window*/, RWsSession* /*wssession*/)
+{
+ return KErrNone;
+}
+
+TInt XAPlaySessionImpl::removeNativeDisplay(RWindow* /*window*/, RWsSession* /*wssession*/)
+{
+ return KErrNone;
+}
+
+TInt XAPlaySessionImpl::load(const TDesC& aURI)
+{
+ TInt retVal;
+ XAresult xaRes;
+ XAEngineItf engineItf;
+ XADynamicSourceItf dynamicSourceItf;
+ XAboolean required[MAX_NUMBER_INTERFACES];
+ XAInterfaceID iidArray[MAX_NUMBER_INTERFACES];
+ XAuint32 noOfInterfaces = 0;
+ TInt i;
+
+ XAmillisecond dur(0);
+ TPtr8 uriPtr(0,0,0);
+ TPtr8 mimeTypePtr(0,0,0);
+
+#ifdef USE_VIDEOPLAYERUTILITY
+ TRAP(m_VPError, mVideoPlayUtil->OpenFileL(_L("C:\\data\\test.3gp")));
+ if (m_VPError)
+ return 0;
+
+ if(!mActiveSchedulerWait->IsStarted())
+ mActiveSchedulerWait->Start();
+
+ if (m_VPError)
+ return 0;
+
+ mVideoPlayUtil->Prepare();
+
+ if(!mActiveSchedulerWait->IsStarted())
+ mActiveSchedulerWait->Start();
+
+ return 0;
+#endif
+
+ delete mURIName;
+ mURIName = NULL;
+ TRAP(retVal, mURIName = HBufC8::NewL(aURI.Length()+1));
+ RET_ERR_IF_ERR(retVal);
+ uriPtr.Set(mURIName->Des());
+
+ // This has to be done here since we can not destroy the Player
+ // in the Resource Lost callback.
+ if (mbMediaPlayerUnrealized) {
+ if (mMOPlayer) {
+ (*mMOPlayer)->Destroy(mMOPlayer);
+ mMOPlayer = NULL;
+ }
+ }
+
+ //py uri name into local variable
+ //TODO fix copy issue from 16 bit to 8 bit
+ uriPtr.Copy(aURI);
+
+ //If media player object already exists, just switch source
+ //using dynamic source interface
+ if (mMOPlayer && mPlayItf) {
+ dynamicSourceItf = NULL;
+ xaRes = (*mMOPlayer)->GetInterface(mMOPlayer, XA_IID_DYNAMICSOURCE, &dynamicSourceItf);
+ retVal = mapError(xaRes, ETrue);
+ RET_ERR_IF_ERR(retVal);
+
+ //Setup the data source
+ //TODO Hard coded locator type
+ mUri.locatorType = XA_DATALOCATOR_URI;
+
+ //append zero terminator to end of URI
+ mUri.URI = (XAchar*) uriPtr.PtrZ();
+
+ //TODO Hard coded locator type
+ mMime.containerType = XA_CONTAINERTYPE_WAV;
+
+ //TODO Hard coded locator type
+ mMime.formatType = XA_DATAFORMAT_MIME;
+ mimeTypePtr.Set(mWAVMime->Des());
+ mMime.mimeType = (XAchar*)mimeTypePtr.Ptr();
+ mDataSource.pFormat = (void*)&mMime;
+ mDataSource.pLocator = (void*)&mUri;
+
+ xaRes = (*dynamicSourceItf)->SetSource(dynamicSourceItf, &mDataSource);
+ retVal = mapError(xaRes, ETrue);
+ RET_ERR_IF_ERR(retVal);
+ }
+ else { // Create media player object
+
+ // Setup the data source
+ // TODO Hard coded locator type
+ mUri.locatorType = XA_DATALOCATOR_URI;
+
+ //append zero terminator to end of URI
+ mUri.URI = (XAchar*) uriPtr.PtrZ();
+
+ //TODO Hard coded locator type
+ mMime.containerType = XA_CONTAINERTYPE_WAV;
+
+ //TODO Hard coded locator type
+ mMime.formatType = XA_DATAFORMAT_MIME;
+ mimeTypePtr.Set(mWAVMime->Des());
+ mMime.mimeType = (XAchar*)mimeTypePtr.Ptr();
+ mDataSource.pFormat = (void*)&mMime;
+ mDataSource.pLocator = (void*)&mUri;
+
+ //Setup the audio data sink
+ mLocatorOutputDevice.locatorType = XA_DATALOCATOR_IODEVICE;
+ mLocatorOutputDevice.deviceType = 6;
+ mAudioSink.pLocator = (void*) &mLocatorOutputDevice;
+ mAudioSink.pFormat = NULL;
+
+ //Init arrays required[] and iidArray[]
+ for (i = 0; i < MAX_NUMBER_INTERFACES; i++) {
+ required[i] = XA_BOOLEAN_FALSE;
+ iidArray[i] = XA_IID_NULL;
+ }
+
+ noOfInterfaces = 0;
+ required[noOfInterfaces] = XA_BOOLEAN_FALSE;
+ iidArray[noOfInterfaces] = XA_IID_SEEK;
+ noOfInterfaces++;
+ required[noOfInterfaces] = XA_BOOLEAN_FALSE;
+ iidArray[noOfInterfaces] = XA_IID_DYNAMICSOURCE;
+ noOfInterfaces++;
+ required[noOfInterfaces] = XA_BOOLEAN_FALSE;
+ iidArray[noOfInterfaces] = XA_IID_METADATAEXTRACTION;
+ noOfInterfaces++;
+ required[noOfInterfaces] = XA_BOOLEAN_FALSE;
+ iidArray[noOfInterfaces] = XA_IID_NOKIALINEARVOLUME;
+ noOfInterfaces++;
+ required[noOfInterfaces] = XA_BOOLEAN_FALSE;
+ iidArray[noOfInterfaces] = XA_IID_NOKIAVOLUMEEXT;
+ noOfInterfaces++;
+ required[noOfInterfaces] = XA_BOOLEAN_FALSE;
+ iidArray[noOfInterfaces] = XA_IID_PREFETCHSTATUS;
+ noOfInterfaces++;
+ required[noOfInterfaces] = XA_BOOLEAN_FALSE;
+ iidArray[noOfInterfaces] = XA_IID_STREAMINFORMATION;
+ noOfInterfaces++;
+ required[noOfInterfaces] = XA_BOOLEAN_FALSE;
+ iidArray[noOfInterfaces] = XA_IID_PLAYBACKRATE;
+ noOfInterfaces++;
+ required[noOfInterfaces] = XA_BOOLEAN_FALSE;
+ iidArray[noOfInterfaces] = XA_IID_VIDEOPOSTPROCESSING;
+ noOfInterfaces++;
+
+ xaRes = (*mEOEngine)->GetInterface(mEOEngine, XA_IID_ENGINE, (void**) &engineItf);
+ retVal = mapError(xaRes, ETrue);
+ RET_ERR_IF_ERR(retVal);
+
+ xaRes = (*engineItf)->CreateMediaPlayer(engineItf,
+ &mMOPlayer,
+ &mDataSource,
+ NULL,
+ &mAudioSink,
+ &mVideoSink,
+ NULL,
+ NULL,
+ noOfInterfaces,
+ iidArray,
+ required);
+ retVal = mapError(xaRes, ETrue);
+ RET_ERR_IF_ERR(retVal);
+
+ xaRes = (*mMOPlayer)->Realize(mMOPlayer, XA_BOOLEAN_FALSE);
+ retVal = mapError(xaRes, ETrue);
+ RET_ERR_IF_ERR(retVal);
+
+ mbMediaPlayerUnrealized = FALSE;
+
+ xaRes = (*mMOPlayer)->RegisterCallback(mMOPlayer, MediaPlayerCallback, (void*)this);
+ retVal = mapError(xaRes, ETrue);
+ RET_ERR_IF_ERR(retVal);
+
+ xaRes = (*mMOPlayer)->GetInterface(mMOPlayer, XA_IID_PLAY, &mPlayItf);
+ retVal = mapError(xaRes, ETrue);
+ RET_ERR_IF_ERR(retVal);
+
+ xaRes = (*mPlayItf)->RegisterCallback(mPlayItf, PlayItfCallback, (void*)this);
+ retVal = mapError(xaRes, ETrue);
+ RET_ERR_IF_ERR(retVal);
+
+ xaRes = (*mPlayItf)->SetPositionUpdatePeriod(mPlayItf, (XAmillisecond)KPlayPosUpdatePeriod);
+ retVal = mapError(xaRes, ETrue);
+ RET_ERR_IF_ERR(retVal);
+
+ xaRes = (*mPlayItf)->SetCallbackEventsMask( mPlayItf,
+ ( XA_PLAYEVENT_HEADATEND |
+ XA_PLAYEVENT_HEADATNEWPOS |
+ XA_PLAYEVENT_HEADMOVING )
+ );
+ retVal = mapError(xaRes, ETrue);
+ RET_ERR_IF_ERR(retVal);
+
+ xaRes = (*mMOPlayer)->GetInterface(mMOPlayer, XA_IID_SEEK, &mSeekItf);
+ retVal = mapError(xaRes, ETrue);
+
+ //Metadata
+ xaRes = (*mMOPlayer)->GetInterface(mMOPlayer, XA_IID_METADATAEXTRACTION, &mMetadataExtItf);
+ if(mapError(xaRes, ETrue)==KErrNone) {
+ mbMetadataAvailable = ETrue;
+ setupALKeyMap(); //done only once at creation of meadia player
+ }
+
+ //volume
+ xaRes = (*mMOPlayer)->GetInterface(mMOPlayer, XA_IID_NOKIALINEARVOLUME, &mNokiaLinearVolumeItf);
+ if(mapError(xaRes, ETrue)==KErrNone)
+ mbVolEnabled = ETrue;
+
+ xaRes = (*mMOPlayer)->GetInterface(mMOPlayer, XA_IID_NOKIAVOLUMEEXT, &mNokiaVolumeExtItf);
+ if(mapError(xaRes, ETrue)==KErrNone)
+ mbMuteEnabled = ETrue;
+
+ //buffer status
+ xaRes = (*mMOPlayer)->GetInterface(mMOPlayer, XA_IID_PREFETCHSTATUS, &mPrefetchStatusItf);
+ if(mapError(xaRes, ETrue)==KErrNone) {
+ mbPrefetchStatusChange = ETrue;
+ (*mPrefetchStatusItf)->RegisterCallback(mPrefetchStatusItf, PrefetchItfCallback, (void*)this);
+ (*mPrefetchStatusItf)->SetCallbackEventsMask(mPrefetchStatusItf, XA_PREFETCHEVENT_FILLLEVELCHANGE);
+ }
+
+ //stream information
+ xaRes = (*mMOPlayer)->GetInterface(mMOPlayer, XA_IID_STREAMINFORMATION, &mStreamInformationItf);
+ if(mapError(xaRes, ETrue)==KErrNone) {
+ mbStreamInfoAvailable = ETrue;
+ mParent.cbStreamInformation(ETrue); //indicate first time
+ (*mStreamInformationItf)->RegisterStreamChangeCallback(mStreamInformationItf, StreamInformationItfCallback, (void*)this);
+ }
+
+ //playback rate
+ xaRes = (*mMOPlayer)->GetInterface(mMOPlayer, XA_IID_PLAYBACKRATE, &mPlaybackRateItf);
+ if(mapError(xaRes, ETrue)==KErrNone)
+ mbPlaybackRateItfAvailable = ETrue;
+
+
+ //videopostprocessing
+ xaRes = (*mMOPlayer)->GetInterface(mMOPlayer, XA_IID_VIDEOPOSTPROCESSING, &mVideoPostProcessingItf);
+ if(mapError(xaRes, ETrue)==KErrNone)
+ mbScalable = ETrue;
+
+ }
+
+ if(mbMetadataAvailable) {
+ keyMap.clear();
+ extendedKeyMap.clear();
+ setupMetaData(); //done every time source is changed
+ }
+ else { //send signal for seekable
+ mParent.cbSeekableChanged(ETrue);
+ }
+
+ mCurPosition = 0;
+ mParent.cbPositionChanged(mCurPosition);
+
+ xaRes = (*mPlayItf)->GetDuration(mPlayItf, &dur);
+ retVal = mapError(xaRes, ETrue);
+ RET_ERR_IF_ERR(retVal);
+
+ mDuration = dur;
+ mParent.cbDurationChanged(mDuration);
+
+ return retVal;
+}
+
+void XAPlaySessionImpl::unload()
+{
+ mPlayItf = NULL;
+ mSeekItf = NULL;
+
+ //Metadata
+ mbMetadataAvailable = FALSE;
+ mMetadataExtItf = NULL;
+ alKeyMap.clear();
+ keyMap.clear();
+ extendedKeyMap.clear();
+ //Volume
+ mNokiaLinearVolumeItf = NULL;
+ mbVolEnabled = FALSE;
+ mNokiaVolumeExtItf = NULL;
+ mbMuteEnabled = NULL;
+
+ //buffer status
+ mPrefetchStatusItf = NULL;
+ mbPrefetchStatusChange = FALSE;
+
+ //stream information
+ mStreamInformationItf = NULL;
+ mbStreamInfoAvailable = FALSE;
+ mbAudioStream = FALSE;
+ mbVideoStream = FALSE;
+ mNumStreams = 0;
+
+ //Playbackrate
+ mPlaybackRateItf = NULL;
+ mbPlaybackRateItfAvailable = FALSE;
+
+ mVideoPostProcessingItf = NULL;
+ mbScalable = FALSE;
+ mCurrAspectRatioMode = Qt::KeepAspectRatio;
+
+ //internal
+ mCurPosition = 0; // in milliseconds
+ mDuration = 0; // in milliseconds
+
+
+ mbMediaPlayerUnrealized = TRUE;
+
+ delete mURIName;
+ mURIName = NULL;
+
+}
+
+TInt XAPlaySessionImpl::play()
+{
+ TInt retVal(KErrGeneral);
+ XAresult xaRes;
+ XAuint32 state;
+
+#ifdef USE_VIDEOPLAYERUTILITY
+ mVideoPlayUtil->Play();
+ return 0;
+#endif
+
+ if (!mMOPlayer || !mPlayItf)
+ return retVal;
+
+ xaRes = (*mPlayItf)->GetPlayState(mPlayItf, &state);
+ retVal = mapError(xaRes, ETrue);
+ RET_ERR_IF_ERR(retVal);
+
+ if ((state == XA_PLAYSTATE_STOPPED) ||
+ (state == XA_PLAYSTATE_PAUSED)) {
+ xaRes = (*mPlayItf)->SetPlayState(mPlayItf, XA_PLAYSTATE_PLAYING);
+ retVal = mapError(xaRes, ETrue);
+ RET_ERR_IF_ERR(retVal);
+ }
+ return retVal;
+}
+
+TInt XAPlaySessionImpl::pause()
+{
+ TInt retVal(KErrGeneral);
+ XAresult xaRes;
+ XAuint32 state;
+
+#ifdef USE_VIDEOPLAYERUTILITY
+ TRAPD(err, mVideoPlayUtil->PauseL());
+ return 0;
+#endif
+
+ if (!mMOPlayer || !mPlayItf)
+ return retVal;
+
+ xaRes = (*mPlayItf)->GetPlayState(mPlayItf, &state);
+ retVal = mapError(xaRes, ETrue);
+ RET_ERR_IF_ERR(retVal);
+
+ if ((state == XA_PLAYSTATE_STOPPED) ||
+ (state == XA_PLAYSTATE_PLAYING)) {
+ xaRes = (*mPlayItf)->SetPlayState(mPlayItf, XA_PLAYSTATE_PAUSED);
+ retVal = mapError(xaRes, ETrue);
+ RET_ERR_IF_ERR(retVal);
+ }
+
+ return retVal;
+}
+
+TInt XAPlaySessionImpl::stop()
+{
+ TInt retVal(KErrGeneral);
+ XAresult xaRes;
+ XAuint32 state;
+
+#ifdef USE_VIDEOPLAYERUTILITY
+ mVideoPlayUtil->Stop();
+ return 0;
+#endif
+
+ if (!mMOPlayer || !mPlayItf)
+ return retVal;
+
+ xaRes = (*mPlayItf)->GetPlayState(mPlayItf, &state);
+ retVal = mapError(xaRes, ETrue);
+ RET_ERR_IF_ERR(retVal);
+
+ if ((state == XA_PLAYSTATE_PAUSED) ||
+ (state == XA_PLAYSTATE_PLAYING)) {
+ xaRes = (*mPlayItf)->SetPlayState(mPlayItf, XA_PLAYSTATE_STOPPED);
+ retVal = mapError(xaRes, ETrue);
+ RET_ERR_IF_ERR(retVal);
+ mCurPosition += KPlayPosUpdatePeriod;
+ mParent.cbPositionChanged(mCurPosition);
+ }
+
+ return retVal;
+}
+
+TInt XAPlaySessionImpl::duration(TInt64& aDur)
+{
+ TInt retVal(KErrGeneral);
+
+#ifdef USE_VIDEOPLAYERUTILITY
+ TTimeIntervalMicroSeconds dur(0);
+ TRAPD(err, mVideoPlayUtil->DurationL());
+ if (!err)
+ aDur = dur.Int64() / 1000;
+ return 0;
+#endif
+ if (!mMOPlayer || !mPlayItf)
+ return retVal;
+ aDur = mDuration;
+ return retVal;
+}
+
+TInt XAPlaySessionImpl::position(TInt64& aPos)
+{
+ TInt retVal(KErrGeneral);
+#ifdef USE_VIDEOPLAYERUTILITY
+ TTimeIntervalMicroSeconds dur(0);
+ TRAPD(err, mVideoPlayUtil->PositionL());
+ if (!err)
+ aPos = dur.Int64() / 1000;
+ return 0;
+#endif
+
+/* XAresult xaRes;
+ XAmillisecond pos(0);*/
+
+ if (!mMOPlayer || !mPlayItf)
+ return retVal;
+
+ aPos = mCurPosition;
+ return retVal;
+}
+
+TInt XAPlaySessionImpl::getSeekable(TBool& seekable)
+{
+ TInt retVal(KErrGeneral);
+
+ if (!mMOPlayer || !mSeekItf)
+ return retVal;
+
+ retVal = ETrue;
+ seekable = ETrue;
+
+ return retVal;
+}
+
+TInt XAPlaySessionImpl::seek(TInt64 pos)
+{
+ TInt retVal(KErrGeneral);
+ XAresult xaRes;
+
+ if (!mMOPlayer || !mSeekItf)
+ return retVal;
+
+ xaRes = (*mSeekItf)->SetPosition(mSeekItf, (XAmillisecond)pos, XA_SEEKMODE_FAST);
+ retVal = mapError(xaRes, ETrue);
+ RET_ERR_IF_ERR(retVal);
+ mCurPosition = pos;
+
+ return retVal;
+}
+
+void XAPlaySessionImpl::cbMediaPlayer(XAObjectItf /*caller*/,
+ const void */*pContext*/,
+ XAuint32 event,
+ XAresult result,
+ XAuint32 /*param*/,
+ void */*pInterface*/)
+
+{
+ switch (event) {
+ case XA_OBJECT_EVENT_RESOURCES_LOST:
+ unload();
+ mParent.cbPlaybackStopped(result);
+ break;
+ case XA_OBJECT_EVENT_RUNTIME_ERROR:
+ {
+ switch (result) {
+ case XA_RESULT_RESOURCE_LOST:
+ unload();
+ mParent.cbPlaybackStopped(result);
+ break;
+ default:
+ break;
+ }; /* of switch (result) */
+ }
+ default:
+ break;
+ } /* of switch (event) */
+}
+
+void XAPlaySessionImpl::cbPlayItf(XAPlayItf /*caller*/,
+ void */*pContext*/,
+ XAuint32 event)
+{
+ switch(event) {
+ case XA_PLAYEVENT_HEADATEND:
+ mParent.cbPlaybackStopped(KErrNone);
+ break;
+ case XA_PLAYEVENT_HEADATMARKER:
+ break;
+ case XA_PLAYEVENT_HEADATNEWPOS:
+ mCurPosition += KPlayPosUpdatePeriod;
+ mParent.cbPositionChanged(mCurPosition);
+ break;
+ case XA_PLAYEVENT_HEADMOVING:
+ break;
+ case XA_PLAYEVENT_HEADSTALLED:
+ break;
+ default:
+ break;
+ }
+}
+
+void XAPlaySessionImpl::cbPrefetchItf(XAuint32 event)
+{
+ if(event == XA_PREFETCHEVENT_FILLLEVELCHANGE)
+ mParent.cbPrefetchStatusChanged();
+}
+
+void XAPlaySessionImpl::cbStreamInformationItf( XAuint32 /*eventId*/,
+ XAuint32 /*streamIndex*/,
+ void * /*pEventData*/)
+{
+ mParent.cbStreamInformation(EFalse);
+}
+
+void XAPlaySessionImpl::setAspectRatioMode(Qt::AspectRatioMode aspectRatioMode)
+{
+ if( !mbScalable ||
+ (mCurrAspectRatioMode == aspectRatioMode)) {
+ return;
+ }
+
+ XAuint32 scaleOptions;;
+ XAuint32 backgrndColor = 1;
+ XAuint32 renderingHints = 1;
+
+ switch(aspectRatioMode) {
+ case Qt::IgnoreAspectRatio:
+ scaleOptions = XA_VIDEOSCALE_STRETCH;
+ break;
+ case Qt::KeepAspectRatio:
+ scaleOptions = XA_VIDEOSCALE_FIT;
+ break;
+ case Qt::KeepAspectRatioByExpanding:
+ scaleOptions = XA_VIDEOSCALE_CROP;
+ break;
+ default:
+ return;
+ }
+
+ XAresult xaRes = (*mVideoPostProcessingItf)->SetScaleOptions(mVideoPostProcessingItf, \
+ scaleOptions, backgrndColor, renderingHints);
+ if(mapError(xaRes, ETrue) == KErrNone)
+ xaRes = (*mVideoPostProcessingItf)->Commit(mVideoPostProcessingItf);
+
+ if(mapError(xaRes, ETrue) == KErrNone)
+ mCurrAspectRatioMode = aspectRatioMode;
+}
+
+Qt::AspectRatioMode XAPlaySessionImpl::getAspectRatioMode()
+{
+ return mCurrAspectRatioMode;
+}
+
+
+#ifdef USE_VIDEOPLAYERUTILITY
+void XAPlaySessionImpl::MvpuoOpenComplete(TInt aError)
+{
+ TRACE_FUNCTION_ENTRY;
+ m_VPError = aError;
+ if (mActiveSchedulerWait->IsStarted())
+ mActiveSchedulerWait->AsyncStop();
+ TRACE_FUNCTION_EXIT;
+}
+
+void XAPlaySessionImpl::MvpuoPrepareComplete(TInt aError)
+{
+ TRACE_FUNCTION_ENTRY;
+ m_VPError = aError;
+ if (mActiveSchedulerWait->IsStarted())
+ mActiveSchedulerWait->AsyncStop();
+
+ RWindow* window = (RWindow*)mNativeDisplay.hWindow;
+ RWsSession* wssession = (RWsSession*)mNativeDisplay.hDisplay;
+
+ if (window) {
+ TRect videoExtent = TRect(window->Size());
+ TRect clipRect = TRect(window->Size());
+ TRAP_IGNORE(mVideoPlayUtil->AddDisplayWindowL(*wssession, *(CCoeEnv::Static()->ScreenDevice()), *window, videoExtent, clipRect));
+ TRAP_IGNORE(mVideoPlayUtil->SetAutoScaleL(*window, EAutoScaleBestFit));
+ }
+ TRACE_FUNCTION_EXIT;
+}
+
+void XAPlaySessionImpl::MvpuoFrameReady(CFbsBitmap& /*aFrame*/,TInt /*aError*/)
+{
+ TRACE_FUNCTION_ENTRY_EXIT;
+}
+
+void XAPlaySessionImpl::MvpuoPlayComplete(TInt /*aError*/)
+{
+ TRACE_FUNCTION_ENTRY;
+ mParent.cbPlaybackStopped_EOS();
+ TRACE_FUNCTION_EXIT;
+}
+
+void XAPlaySessionImpl::MvpuoEvent(const TMMFEvent& /*aEvent*/)
+{
+ TRACE_FUNCTION_ENTRY_EXIT;
+}
+
+#endif
+
+TInt XAPlaySessionImpl::mapError(XAresult xa_err, TBool /*debPrn*/)
+{
+ TInt retVal(KErrGeneral);
+
+ switch(xa_err) {
+ case XA_RESULT_SUCCESS:
+ retVal = KErrNone;
+ break;
+ case XA_RESULT_PRECONDITIONS_VIOLATED:
+ break;
+ case XA_RESULT_PARAMETER_INVALID:
+ break;
+ case XA_RESULT_MEMORY_FAILURE:
+ break;
+ case XA_RESULT_RESOURCE_ERROR:
+ break;
+ case XA_RESULT_RESOURCE_LOST:
+ break;
+ case XA_RESULT_IO_ERROR:
+ break;
+ case XA_RESULT_BUFFER_INSUFFICIENT:
+ break;
+ case XA_RESULT_CONTENT_CORRUPTED:
+ break;
+ case XA_RESULT_CONTENT_UNSUPPORTED:
+ break;
+ case XA_RESULT_CONTENT_NOT_FOUND:
+ break;
+ case XA_RESULT_PERMISSION_DENIED:
+ break;
+ case XA_RESULT_FEATURE_UNSUPPORTED:
+ break;
+ case XA_RESULT_INTERNAL_ERROR:
+ break;
+ case XA_RESULT_UNKNOWN_ERROR:
+ break;
+ case XA_RESULT_OPERATION_ABORTED:
+ break;
+ case XA_RESULT_CONTROL_LOST:
+ break;
+ default:
+ break;
+ }
+
+ return retVal;
+}
+
+
+QStringList XAPlaySessionImpl::availableExtendedMetaData () const
+{
+ QStringList retList;
+
+ //create a qlist with all keys in keyMap hash
+ QHashIterator<QString, int> it(extendedKeyMap);
+ while(it.hasNext()) {
+ it.next();
+ retList << it.key();
+ }
+
+ return retList;
+}
+
+QList<QtMultimediaKit::MetaData> XAPlaySessionImpl::availableMetaData () const
+{
+ QList<QtMultimediaKit::MetaData> retList;
+
+ //create a qlist with all keys in keyMap hash
+ QHashIterator<QtMultimediaKit::MetaData, int> it(keyMap);
+ while( it.hasNext() ) {
+ it.next();
+ retList << it.key();
+ }
+
+ return retList;
+}
+
+QVariant XAPlaySessionImpl::getMetaData( int alIndex ) const
+{
+ QVariant ret; //invalid variant
+
+ //find index for the given key
+ if(mMetadataExtItf) {
+ XAuint32 valueSize = 0;
+ XAresult res = (*mMetadataExtItf)->GetValueSize(mMetadataExtItf, alIndex, &valueSize);
+ if(res == XA_RESULT_SUCCESS) {
+ XAMetadataInfo * value = (XAMetadataInfo*)calloc(valueSize, 1);
+ if(value) {
+ res = (*mMetadataExtItf)->GetValue(mMetadataExtItf, alIndex, valueSize, value);
+ if(res == XA_RESULT_SUCCESS) {
+ if(value->encoding == XA_CHARACTERENCODING_ASCII)
+ ret = QVariant ((const char*)value->data);
+ else if(value->encoding == XA_CHARACTERENCODING_UTF16LE)
+ ret = QVariant(QString::fromUtf16((ushort*)value->data, (value->size/2)-1)); //dont include null terminating character
+ else if(value->encoding == XA_CHARACTERENCODING_BINARY)
+ ret = QVariant(QImage::fromData(value->data, value->size));
+ }
+
+ free(value);
+ }
+ }
+ }
+
+ return ret;
+}
+
+QVariant XAPlaySessionImpl::metaData( QtMultimediaKit::MetaData key ) const
+{
+ QVariant ret;
+ if(keyMap.contains(key))
+ ret = getMetaData(keyMap[key]);
+ return ret;
+}
+
+QVariant XAPlaySessionImpl::extendedMetaData(const QString & key ) const
+{
+ QVariant ret;
+ if(extendedKeyMap.contains(key))
+ ret = getMetaData(extendedKeyMap[key]);
+
+ return ret;
+}
+
+bool XAPlaySessionImpl::isMetaDataAvailable() const
+{
+ return ((keyMap.size()>0) || (extendedKeyMap.size()>0));
+}
+
+bool XAPlaySessionImpl::isWritable() const
+{
+ return false;
+}
+
+void XAPlaySessionImpl::setExtendedMetaData( const QString&, const QVariant&)
+{
+ //Do Nothing
+}
+
+void XAPlaySessionImpl::setMetaData( QtMultimediaKit::MetaData, const QVariant& )
+{
+ //Do Nothing
+}
+
+void XAPlaySessionImpl::setupALKeyMap()
+{
+ alKeyMap["KhronosTitle"] = QtMultimediaKit::Title;
+ alKeyMap["KhronosComment"] = QtMultimediaKit::Comment;
+ alKeyMap["KhronosTrackNumber"] = QtMultimediaKit::TrackNumber;
+ alKeyMap["KhronosAlbumArtJPEG"] = QtMultimediaKit::CoverArtImage;
+ alKeyMap["KhronosAlbumArtPNG"] = QtMultimediaKit::CoverArtImage;
+ alKeyMap["KhronosAlbum"] = QtMultimediaKit::AlbumTitle;
+ alKeyMap["KhronosArtist"] = QtMultimediaKit::AlbumArtist;
+ alKeyMap["KhronosGenre"] = QtMultimediaKit::Genre;
+ alKeyMap["KhronosYear"] = QtMultimediaKit::Year;
+ alKeyMap["KhronosYear"] = QtMultimediaKit::Date;
+ alKeyMap["KhronosRating"] = QtMultimediaKit::UserRating;
+ alKeyMap["KhronosCopyright"] = QtMultimediaKit::Copyright;
+ alKeyMap["Author"] = QtMultimediaKit::Author;
+ alKeyMap["Duration"] = QtMultimediaKit::Duration;
+ alKeyMap["Stream Count"] = QtMultimediaKit::ChannelCount;
+ alKeyMap["Composer"] = QtMultimediaKit::Composer;
+ alKeyMap["Resolution"] = QtMultimediaKit::Resolution;
+ alKeyMap["FrameRate"] = QtMultimediaKit::VideoFrameRate;
+ alKeyMap["ClipBitRate"] = QtMultimediaKit::VideoBitRate;
+ alKeyMap["Codec"] = QtMultimediaKit::VideoCodec;
+ alKeyMap["attachedpicture"] = QtMultimediaKit::CoverArtImage;
+
+ /*Keys not available
+ QtMedia::SubTitle
+ QtMedia::Description
+ QtMedia::Category
+ QtMedia::Keywords
+ QtMedia::Language
+ QtMedia::Publisher
+ QtMedia::ParentalRating
+ QtMedia::RatingOrganisation
+ QtMedia::Size
+ QtMedia::MediaType
+ QtMedia::AudioBitrate
+ QtMedia::AudioCodec
+ QtMedia::AverageLevel
+ QtMedia::PeakValue
+ QtMedia::Frequency
+ QtMedia::ContributingArtist
+ QtMedia::Conductor
+ QtMedia::Lyrics
+ QtMedia::Mood
+ QtMedia::TrackCount
+ QtMedia::PixelAspectRatio
+ QtMedia::PosterUri
+ QtMedia::ChapterNumber
+ QtMedia::Director
+ QtMedia::LeadPerformer
+ QtMedia::Writer */
+}
+
+TInt XAPlaySessionImpl::mapMetaDataKey(const char* asckey, QtMultimediaKit::MetaData& key)
+{
+ if(alKeyMap.contains(asckey)) {
+ key = alKeyMap[asckey];
+ return KErrNone;
+ }
+
+ return KErrNotFound;
+}
+
+TInt XAPlaySessionImpl::setupMetaData()
+{
+ XAresult res;
+ if(mMetadataExtItf) {
+ XAuint32 numItems = 0;
+ res = (*mMetadataExtItf)->GetItemCount(mMetadataExtItf, &numItems);
+ RET_ERR_IF_ERR(mapError(res, ETrue));
+
+ for(int i=0; i<numItems; ++i) {
+ XAuint32 keySize;
+ res = (*mMetadataExtItf)->GetKeySize(mMetadataExtItf, i, &keySize);
+ RET_ERR_IF_ERR(mapError(res, ETrue));
+
+ XAMetadataInfo *key = (XAMetadataInfo *)calloc(keySize,1);
+ if(key) {
+ res = (*mMetadataExtItf)->GetKey(mMetadataExtItf, i, keySize, key);
+ RET_ERR_IF_ERR(mapError(res, ETrue));
+
+ if(key->encoding == XA_CHARACTERENCODING_ASCII) { //only handle ASCII keys ignore others
+ QtMultimediaKit::MetaData qtKey;
+ if(mapMetaDataKey((const char*)key->data, qtKey) == KErrNone)//qt metadata
+ keyMap[qtKey] = i;
+ else //extended metadata
+ extendedKeyMap[(const char*)key->data] = i;
+ }
+
+ free(key);
+ }
+ }
+
+ //check for seek property to generate seekable signal
+ QVariant var = extendedMetaData("Seekable");
+ if(!var.isValid() || (var.toString() == "1"))
+ mParent.cbSeekableChanged(ETrue);
+ else
+ mParent.cbSeekableChanged(EFalse);
+
+ }
+
+ return KErrGeneral;
+}
+
+//Volume
+TInt XAPlaySessionImpl::volume(TInt& v)
+{
+ if(mbVolEnabled) {
+ XAresult res = (*mNokiaLinearVolumeItf)->GetVolumeLevel(mNokiaLinearVolumeItf, (XAuint32 *)&v);
+ return mapError(res, ETrue);
+ }
+
+ return KErrNotFound;
+}
+
+TInt XAPlaySessionImpl::setVolume(TInt v)
+{
+ if(mbVolEnabled) {
+ XAresult res = (*mNokiaLinearVolumeItf)->SetVolumeLevel(mNokiaLinearVolumeItf, (XAuint32*)&v);
+ return mapError(res, ETrue);
+ }
+
+ return KErrNotFound;
+}
+
+TInt XAPlaySessionImpl::setMute(TBool bMute)
+{
+ if(mbMuteEnabled) {
+ XAresult res = (*mNokiaVolumeExtItf)->SetMute(mNokiaVolumeExtItf, (XAboolean)bMute);
+ return mapError(res, ETrue);
+ }
+
+ return KErrNotFound;
+
+}
+
+TInt XAPlaySessionImpl::getMute(TBool& bIsMute)
+{
+ if(mbMuteEnabled) {
+ XAboolean xaMute;
+ XAresult res = (*mNokiaVolumeExtItf)->GetMute(mNokiaVolumeExtItf, &xaMute);
+ bIsMute = xaMute;
+ return mapError(res, ETrue);
+ }
+
+ return KErrNotFound;
+}
+
+
+TInt XAPlaySessionImpl::bufferStatus(TInt &bs)
+{
+ TInt ret = KErrNotFound;
+
+ if(mbPrefetchStatusChange) {
+ XApermille satusPerThousand;
+ XAresult res = (*mPrefetchStatusItf)->GetFillLevel(mPrefetchStatusItf, &satusPerThousand);
+ ret = mapError(res, ETrue);
+ if(ret == KErrNone)
+ bs = satusPerThousand/10.0; //convert to parts per hundred
+ }
+ return ret;
+}
+
+QMediaStreamsControl::StreamType XAPlaySessionImpl::mapStreamType(XAuint32& alStreamType)
+{
+ switch(alStreamType) {
+ case XA_DOMAINTYPE_AUDIO:
+ return QMediaStreamsControl::AudioStream;
+ case XA_DOMAINTYPE_VIDEO:
+ return QMediaStreamsControl::VideoStream;
+ case XA_DOMAINTYPE_IMAGE:
+ return QMediaStreamsControl::DataStream;
+ }
+ return QMediaStreamsControl::UnknownStream;
+}
+
+
+TInt XAPlaySessionImpl::numMediaStreams(TUint& numStreams)
+{
+ TInt ret = KErrNotFound;
+ numStreams = 0;
+ if(mbStreamInfoAvailable) {
+ XAMediaContainerInformation mediaContainerInfo;
+ XAresult res = (*mStreamInformationItf)->QueryMediaContainerInformation(mStreamInformationItf, &mediaContainerInfo);
+ ret = mapError(res, ETrue);
+ if(ret == KErrNone)
+ numStreams = mediaContainerInfo.numStreams;
+ }
+ return ret;
+}
+
+TInt XAPlaySessionImpl::streamType(TUint index, QMediaStreamsControl::StreamType& type)
+{
+ TInt ret = KErrNotFound;
+ type = QMediaStreamsControl::UnknownStream;
+ if(mbStreamInfoAvailable) {
+ XAuint32 strType;
+ XAresult res = (*mStreamInformationItf)->QueryStreamType(mStreamInformationItf, (XAuint32)(index+1), &strType);
+ ret = mapError(res, ETrue);
+ if(ret == KErrNone)
+ type = mapStreamType(strType);
+ }
+ return ret;
+}
+
+TInt XAPlaySessionImpl::isStreamActive(TUint index, TBool& isActive)
+{
+ TUint numStreams;
+ TInt ret = numMediaStreams(numStreams);
+ if((ret == KErrNone) && (index < numStreams)) {
+ isActive = EFalse;
+ if(numStreams > 0) {
+ //create array of bools
+ XAboolean *activeStreams = new XAboolean[numStreams+1];
+ XAresult res = (*mStreamInformationItf)->QueryActiveStreams(mStreamInformationItf, (XAuint32*)&numStreams, activeStreams);
+ ret = mapError(res, ETrue);
+ if(ret == KErrNone)
+ isActive = activeStreams[index+1];
+ delete[] activeStreams;
+ }
+ }
+ return ret;
+}
+
+TInt XAPlaySessionImpl::getPlaybackRate(TReal32 &rate)
+{
+ TInt ret = KErrNotFound;
+
+ if(mbPlaybackRateItfAvailable) {
+ XApermille perMilleRate = 0;
+ ret = (*mPlaybackRateItf)->GetRate(mPlaybackRateItf, &perMilleRate);
+ rate = perMilleRate / 1000.0;
+ }
+ return ret;
+}
+
+TInt XAPlaySessionImpl::setPlaybackRate(TReal32 rate)
+{
+ TInt ret = KErrNotFound;
+ if(mbPlaybackRateItfAvailable)
+ ret = (*mPlaybackRateItf)->SetRate(mPlaybackRateItf, (XApermille)(rate * 1000.0));
+ return ret;
+}
+
+
+/* Local function implementation */
+void MediaPlayerCallback( XAObjectItf caller,
+ const void *pContext,
+ XAuint32 event,
+ XAresult result,
+ XAuint32 param,
+ void *pInterface)
+{
+ if (pContext)
+ ((XAPlaySessionImpl*)pContext)->cbMediaPlayer( caller,
+ pContext,
+ event,
+ result,
+ param,
+ pInterface);
+}
+
+void PlayItfCallback( XAPlayItf caller,
+ void *pContext,
+ XAuint32 event)
+{
+ if (pContext)
+ ((XAPlaySessionImpl*)pContext)->cbPlayItf(caller,
+ pContext,
+ event);
+}
+
+void PrefetchItfCallback( XAPrefetchStatusItf /*caller*/,
+ void *pContext,
+ XAuint32 event)
+{
+ if (pContext)
+ ((XAPlaySessionImpl*)pContext)->cbPrefetchItf(event);
+}
+
+void StreamInformationItfCallback( XAStreamInformationItf /*caller*/,
+ XAuint32 eventId,
+ XAuint32 streamIndex,
+ void * pEventData,
+ void * pContext)
+{
+ if (pContext)
+ ((XAPlaySessionImpl*)pContext)->cbStreamInformationItf( eventId,
+ streamIndex,
+ pEventData);
+}
+
+
+
+// End of file