qtmobility/plugins/multimedia/symbian/mediaplayer/s60mediaplayersession.cpp
changeset 4 90517678cc4f
parent 1 2b40d63a9c3d
child 5 453da2cfceef
equal deleted inserted replaced
1:2b40d63a9c3d 4:90517678cc4f
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the Qt Mobility Components.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    24 ** In addition, as a special exception, Nokia gives you certain additional
       
    25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 
       
    42 #include "s60mediaplayersession.h"
       
    43 
       
    44 #include <QtCore/qdebug.h>
       
    45 #include <QtCore/qdir.h>
       
    46 #include <QtCore/qvariant.h>
       
    47 #include <QtCore/qtimer.h>
       
    48 #include <QtCore/private/qcore_symbian_p.h>
       
    49 #include <mmf/common/mmferrors.h>
       
    50 #include <qmediatimerange.h>
       
    51 
       
    52 S60MediaPlayerSession::S60MediaPlayerSession(QObject *parent)
       
    53     : QObject(parent)
       
    54     , m_playbackRate(0)
       
    55     , m_muted(false)
       
    56     , m_volume(0)
       
    57     , m_state(QMediaPlayer::StoppedState)
       
    58     , m_mediaStatus(QMediaPlayer::NoMedia)
       
    59     , m_timer(new QTimer(this))
       
    60     , m_error(KErrNone)
       
    61     , m_localMediaFile(true)
       
    62     , m_play_requested(false)
       
    63 {    
       
    64     connect(m_timer, SIGNAL(timeout()), this, SLOT(tick()));
       
    65 }
       
    66 
       
    67 S60MediaPlayerSession::~S60MediaPlayerSession()
       
    68 {
       
    69 }
       
    70 
       
    71 int S60MediaPlayerSession::volume() const
       
    72 {
       
    73     return m_volume;
       
    74 }
       
    75 
       
    76 void S60MediaPlayerSession::setVolume(int volume)
       
    77 {
       
    78     if (m_volume == volume)
       
    79         return;
       
    80     
       
    81     m_volume = volume;
       
    82     // Dont set symbian players volume until media loaded.
       
    83     // Leaves with KerrNotReady although documentation says otherwise.
       
    84     if (!m_muted && m_mediaStatus == QMediaPlayer::LoadedMedia) {
       
    85         TRAPD(err, doSetVolumeL(m_volume));
       
    86         setError(err);
       
    87     }
       
    88 }
       
    89 
       
    90 bool S60MediaPlayerSession::isMuted() const
       
    91 {
       
    92     return m_muted;
       
    93 }
       
    94 
       
    95 bool S60MediaPlayerSession::isSeekable() const
       
    96 {
       
    97     if (m_metaDataMap.isEmpty())
       
    98         return true;
       
    99     return m_metaDataMap.value("seekable").toBool();
       
   100 }
       
   101 
       
   102 void S60MediaPlayerSession::setMediaStatus(QMediaPlayer::MediaStatus status)
       
   103 {
       
   104     if (m_mediaStatus == status)
       
   105         return;
       
   106     
       
   107     m_mediaStatus = status;
       
   108     
       
   109     if (m_mediaStatus == QMediaPlayer::InvalidMedia)
       
   110         setError(KErrNotSupported);
       
   111     
       
   112     emit mediaStatusChanged(m_mediaStatus);
       
   113     if (m_play_requested)
       
   114         play();
       
   115 }
       
   116 
       
   117 void S60MediaPlayerSession::setState(QMediaPlayer::State state)
       
   118 {
       
   119     if (m_state == state)
       
   120         return;
       
   121     
       
   122     m_state = state;
       
   123     emit stateChanged(m_state);
       
   124 }
       
   125 
       
   126 QMediaPlayer::State S60MediaPlayerSession::state() const 
       
   127 { 
       
   128     return m_state; 
       
   129 }
       
   130 
       
   131 QMediaPlayer::MediaStatus S60MediaPlayerSession::mediaStatus() const 
       
   132 { 
       
   133     return m_mediaStatus; 
       
   134 }
       
   135 
       
   136 void S60MediaPlayerSession::load(const QUrl &url)
       
   137 {
       
   138     // Reset error status on load
       
   139     setError(KErrNone);
       
   140     m_localMediaFile = true;
       
   141     doStop();
       
   142     setMediaStatus(QMediaPlayer::LoadingMedia);
       
   143     TRAPD(err, doLoadL(qt_QString2TPtrC(QDir::toNativeSeparators(url.toLocalFile()))));
       
   144     setError(err);
       
   145 }
       
   146 
       
   147 void S60MediaPlayerSession::loadUrl(const QUrl &url)
       
   148 {
       
   149     // Reset error status on load
       
   150     setError(KErrNone);
       
   151     m_localMediaFile = false;
       
   152     doStop();
       
   153     setMediaStatus(QMediaPlayer::LoadingMedia);
       
   154     TRAPD(err, doLoadUrlL(qt_QString2TPtrC(url.toString())));
       
   155     setError(err);
       
   156 }
       
   157 
       
   158 void S60MediaPlayerSession::play()
       
   159 {
       
   160     if (state() == QMediaPlayer::PlayingState)
       
   161         return;
       
   162     
       
   163     if (mediaStatus() != QMediaPlayer::LoadedMedia) {
       
   164         m_play_requested = true;
       
   165         return;
       
   166     }
       
   167     
       
   168     m_play_requested = false;
       
   169     setState(QMediaPlayer::PlayingState);
       
   170     m_timer->start(1000);
       
   171     doPlay();
       
   172 }
       
   173 
       
   174 void S60MediaPlayerSession::pause()
       
   175 {
       
   176     m_timer->stop();
       
   177     setState(QMediaPlayer::PausedState);
       
   178     TRAPD(err, doPauseL());
       
   179     setError(err);
       
   180 }
       
   181 
       
   182 void S60MediaPlayerSession::stop()
       
   183 {
       
   184     setState(QMediaPlayer::StoppedState);
       
   185     m_timer->stop();
       
   186     doStop();
       
   187     emit positionChanged(0);
       
   188 }
       
   189 
       
   190 void S60MediaPlayerSession::setVideoRenderer(QObject *renderer)
       
   191 {
       
   192     Q_UNUSED(renderer);   
       
   193 }
       
   194 
       
   195 int S60MediaPlayerSession::mediaLoadingProgress()
       
   196 {
       
   197     int progress = 0;
       
   198     TRAPD(err, progress = doGetMediaLoadingProgressL());
       
   199     setError(err);
       
   200     return progress;
       
   201 }
       
   202 
       
   203 bool S60MediaPlayerSession::isMetadataAvailable() const
       
   204 {
       
   205     return !m_metaDataMap.isEmpty();    
       
   206 }
       
   207 
       
   208 QVariant S60MediaPlayerSession::metaData(const QString &key) const
       
   209 {
       
   210     return m_metaDataMap.value(key);    
       
   211 }
       
   212 
       
   213 QMap<QString, QVariant> S60MediaPlayerSession::availableMetaData() const
       
   214 {
       
   215     return m_metaDataMap;
       
   216 }
       
   217 
       
   218 void S60MediaPlayerSession::setMuted(bool muted)
       
   219 {
       
   220     if (m_muted == muted)
       
   221         return;
       
   222     
       
   223     m_muted = muted;
       
   224     
       
   225     if (m_mediaStatus == QMediaPlayer::LoadedMedia) {
       
   226         TRAPD(err, doSetVolumeL((m_muted)?0:m_volume));
       
   227         setError(err);
       
   228     }
       
   229 }
       
   230 
       
   231 qint64 S60MediaPlayerSession::duration() const
       
   232 {
       
   233     qint64 pos = 0;
       
   234     //Cannot seterror since const, error ignored
       
   235     TRAP_IGNORE(pos = doGetDurationL());
       
   236     return pos;
       
   237 }
       
   238 
       
   239 qint64 S60MediaPlayerSession::position() const
       
   240 {
       
   241     qint64 pos = 0;
       
   242     //Cannot seterror since const, error ignored
       
   243     TRAP_IGNORE(pos = doGetPositionL());
       
   244     return pos;
       
   245 }
       
   246 
       
   247 void S60MediaPlayerSession::setPosition(qint64 pos)
       
   248 {
       
   249     if (position() == pos)
       
   250         return;
       
   251     
       
   252     if (state() == QMediaPlayer::PlayingState) 
       
   253         pause();
       
   254 
       
   255     TRAPD(err, doSetPositionL(pos * 1000));
       
   256     setError(err);
       
   257 
       
   258     if (state() == QMediaPlayer::PausedState)
       
   259         play();
       
   260 
       
   261     emit positionChanged(position());
       
   262 }
       
   263 
       
   264 void S60MediaPlayerSession::initComplete()
       
   265 {
       
   266     if (m_error == KErrNone) {
       
   267         setMediaStatus(QMediaPlayer::LoadedMedia);
       
   268         TRAPD(err, updateMetaDataEntriesL());
       
   269         setError(err);
       
   270         setVolume(m_volume);
       
   271         setMuted(m_muted);
       
   272         emit durationChanged(duration());
       
   273     } else {
       
   274         setError(m_error);
       
   275     }
       
   276 }
       
   277 
       
   278 void S60MediaPlayerSession::playComplete()
       
   279 {
       
   280     setMediaStatus(QMediaPlayer::EndOfMedia);
       
   281     setState(QMediaPlayer::StoppedState);
       
   282     emit positionChanged(0);
       
   283 }
       
   284 
       
   285 QMap<QString, QVariant>& S60MediaPlayerSession::metaDataEntries()
       
   286 {
       
   287     return m_metaDataMap;
       
   288 }
       
   289 
       
   290 QMediaPlayer::Error S60MediaPlayerSession::fromSymbianErrorToMultimediaError(int error)
       
   291 {
       
   292     switch(error) {
       
   293         case KErrNoMemory:
       
   294         case KErrNotFound:
       
   295         case KErrBadHandle:
       
   296         case KErrMMAudioDevice:
       
   297         case KErrMMVideoDevice:
       
   298             return QMediaPlayer::ResourceError;
       
   299             
       
   300         case KErrMMDecoder:
       
   301         case KErrNotSupported:
       
   302         case KErrCorrupt:
       
   303             return QMediaPlayer::FormatError;
       
   304             
       
   305         case KErrMMNotEnoughBandwidth:
       
   306         case KErrMMSocketServiceNotFound:
       
   307         case KErrMMNetworkRead:
       
   308         case KErrMMNetworkWrite:
       
   309         case KErrMMServerSocket:
       
   310         case KErrMMServerNotSupported:
       
   311         case KErrMMUDPReceive:
       
   312         case KErrMMInvalidProtocol:
       
   313         case KErrMMInvalidURL:
       
   314         case KErrMMMulticast:
       
   315         case KErrMMProxyServer:
       
   316         case KErrMMProxyServerNotSupported:
       
   317         case KErrMMProxyServerConnect:
       
   318             return QMediaPlayer::NetworkError;
       
   319             
       
   320         case KErrNotReady:
       
   321         case KErrInUse:
       
   322         case KErrAccessDenied:
       
   323         case KErrLocked:
       
   324         case KErrMMDRMNotAuthorized:
       
   325         case KErrPermissionDenied:
       
   326             return QMediaPlayer::AccessDeniedError;
       
   327             
       
   328         case KErrMMPartialPlayback:   
       
   329         case KErrNone:
       
   330         default:
       
   331             return QMediaPlayer::NoError;
       
   332     }
       
   333 }
       
   334 
       
   335 void S60MediaPlayerSession::setError(int error, const QString &errorString)
       
   336 {
       
   337     if (error == m_error)
       
   338         return;
       
   339     
       
   340     m_error = error;
       
   341     QMediaPlayer::Error mediaError = fromSymbianErrorToMultimediaError(m_error);
       
   342     QString symbianError = QString(errorString);
       
   343 
       
   344     if (mediaError != QMediaPlayer::NoError) {
       
   345         m_play_requested = false;
       
   346         // TODO: fix to user friendly string at some point
       
   347         // These error string are only dev usable
       
   348         symbianError.append("Symbian:");
       
   349         symbianError.append(QString::number(m_error));
       
   350     }
       
   351      
       
   352     emit this->error(mediaError, symbianError);
       
   353     switch(mediaError){
       
   354         case QMediaPlayer::FormatError:
       
   355             setMediaStatus(QMediaPlayer::InvalidMedia);
       
   356             break;
       
   357         case QMediaPlayer::ResourceError:
       
   358         case QMediaPlayer::NetworkError:
       
   359         case QMediaPlayer::AccessDeniedError:
       
   360         case QMediaPlayer::ServiceMissingError:
       
   361             setMediaStatus(QMediaPlayer::NoMedia);
       
   362             break;
       
   363         default:
       
   364             break;
       
   365     }
       
   366 }
       
   367 
       
   368 void S60MediaPlayerSession::tick()
       
   369 {
       
   370     emit positionChanged(position());
       
   371     
       
   372     if (mediaFileLocal() && mediaLoadingProgress() != 100)
       
   373     	emit bufferStatusChanged(mediaLoadingProgress());
       
   374 }
       
   375 
       
   376 bool S60MediaPlayerSession::mediaFileLocal() const
       
   377 {
       
   378     return m_localMediaFile; 
       
   379 }
       
   380 void S60MediaPlayerSession::setMediaFileLocal(bool localMediaFile)
       
   381 {
       
   382     if (m_localMediaFile == localMediaFile)
       
   383         return;
       
   384     
       
   385     m_localMediaFile = localMediaFile;
       
   386 }