blob: 2ae6a3d6e8d1f680c9dff5a1aca68cf92ffeb873 [file] [log] [blame]
/* 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 "audioplayer.h"
#include "utils.h"
QT_BEGIN_NAMESPACE
using namespace Phonon;
using namespace Phonon::MMF;
/*! \class MMF::AudioPlayer
\internal
*/
//-----------------------------------------------------------------------------
// Constructor / destructor
//-----------------------------------------------------------------------------
MMF::AudioPlayer::AudioPlayer(MediaObject *parent, const AbstractPlayer *player)
: AbstractMediaPlayer(parent, player)
, m_totalTime(0)
{
construct();
}
void MMF::AudioPlayer::construct()
{
TRACE_CONTEXT(AudioPlayer::AudioPlayer, EAudioApi);
TRACE_ENTRY_0();
NativePlayer *player = 0;
QT_TRAP_THROWING(player = NativePlayer::NewL(*this, 0, EMdaPriorityPreferenceNone));
m_player.reset(player);
m_player->RegisterForAudioLoadingNotification(*this);
TRACE_EXIT_0();
}
MMF::AudioPlayer::~AudioPlayer()
{
TRACE_CONTEXT(AudioPlayer::~AudioPlayer, EAudioApi);
TRACE_ENTRY_0();
TRACE_EXIT_0();
}
MMF::AudioPlayer::NativePlayer *MMF::AudioPlayer::nativePlayer() const
{
return m_player.data();
}
//-----------------------------------------------------------------------------
// Public API
//-----------------------------------------------------------------------------
void MMF::AudioPlayer::doPlay()
{
m_player->Play();
}
void MMF::AudioPlayer::doPause()
{
m_player->Pause();
}
void MMF::AudioPlayer::doStop()
{
m_player->Stop();
}
void MMF::AudioPlayer::doSeek(qint64 ms)
{
m_player->SetPosition(TTimeIntervalMicroSeconds(ms * 1000));
}
int MMF::AudioPlayer::setDeviceVolume(int mmfVolume)
{
/* In SDK 3.1, SetVolume() returns void. If we're compiling against
* 3.1, we handle it with ifdefs. However, if we compile against a later
* SDK but are _running_ against 3.1, we avoid returning from an undefined
* stack by doing a runtime check of the SDK version. */
#if !defined(__SERIES60_31__)
const int err = m_player->SetVolume(mmfVolume);
if (QSysInfo::s60Version() >= QSysInfo::SV_S60_3_2)
return err;
else
return KErrNone;
#else
m_player->SetVolume(mmfVolume);
return KErrNone;
#endif
}
int MMF::AudioPlayer::openFile(const QString &fileName)
{
const QHBufC nativeFileName(QDir::toNativeSeparators(fileName));
TRAPD(err, m_player->OpenFileL(*nativeFileName));
return err;
}
int MMF::AudioPlayer::openFile(RFile& file)
{
TRAPD(err, m_player->OpenFileL(file));
#ifdef QT_PHONON_MMF_AUDIO_DRM
if (KErrNone == err) {
// There appears to be a bug in the CDrmPlayerUtility implementation (at least
// in S60 5.x) whereby the player does not check whether the loading observer
// pointer is null before dereferencing it. Therefore we must register for
// loading notification, even though we do nothing in the callback functions.
m_player->RegisterForAudioLoadingNotification(*this);
}
#endif
return err;
}
int MMF::AudioPlayer::openUrl(const QString& /*url*/, int /*iap*/)
{
// Streaming playback is generally not supported by the implementation
// of the audio player API, so we use CVideoPlayerUtility for both
// audio and video streaming.
Utils::panic(AudioUtilityUrlNotSupported);
// Silence warning
return 0;
}
int MMF::AudioPlayer::openDescriptor(const TDesC8 &des)
{
TRAPD(err, m_player->OpenDesL(des));
return err;
}
int MMF::AudioPlayer::bufferStatus() const
{
int result = 0;
TRAP_IGNORE(m_player->GetAudioLoadingProgressL(result));
return result;
}
void MMF::AudioPlayer::doClose()
{
m_player->Close();
}
bool MMF::AudioPlayer::hasVideo() const
{
return false;
}
qint64 MMF::AudioPlayer::getCurrentTime() const
{
TRACE_CONTEXT(AudioPlayer::getCurrentTime, EAudioApi);
TTimeIntervalMicroSeconds us;
const TInt err = m_player->GetPosition(us);
qint64 result = 0;
if (KErrNone == err) {
result = toMilliSeconds(us);
} else {
TRACE("GetPosition err %d", err);
// If we don't cast away constness here, we simply have to ignore
// the error.
const_cast<AudioPlayer*>(this)->setError(tr("Getting position failed"), err);
}
return result;
}
qint64 MMF::AudioPlayer::totalTime() const
{
return m_totalTime;
}
//-----------------------------------------------------------------------------
// Symbian multimedia client observer callbacks
//-----------------------------------------------------------------------------
#ifdef QT_PHONON_MMF_AUDIO_DRM
void MMF::AudioPlayer::MdapcInitComplete(TInt aError,
const TTimeIntervalMicroSeconds &)
#else
void MMF::AudioPlayer::MapcInitComplete(TInt aError,
const TTimeIntervalMicroSeconds &)
#endif
{
TRACE_CONTEXT(AudioPlayer::MapcInitComplete, EAudioInternal);
TRACE_ENTRY("state %d error %d", state(), aError);
__ASSERT_ALWAYS(LoadingState == state() ||
progressiveDownloadStalled() && BufferingState == state(),
Utils::panic(InvalidStatePanic));
if (KErrNone == aError) {
maxVolumeChanged(m_player->MaxVolume());
m_totalTime = toMilliSeconds(m_player->Duration());
emit totalTimeChanged(m_totalTime);
}
loadingComplete(aError);
TRACE_EXIT_0();
}
#ifdef QT_PHONON_MMF_AUDIO_DRM
void MMF::AudioPlayer::MdapcPlayComplete(TInt aError)
#else
void MMF::AudioPlayer::MapcPlayComplete(TInt aError)
#endif
{
TRACE_CONTEXT(AudioPlayer::MapcPlayComplete, EAudioInternal);
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();
}
#ifdef QT_PHONON_MMF_AUDIO_DRM
void MMF::AudioPlayer::MaloLoadingStarted()
{
}
void MMF::AudioPlayer::MaloLoadingComplete()
{
}
#endif // QT_PHONON_MMF_AUDIO_DRM
//-----------------------------------------------------------------------------
// MAudioLoadingObserver callbacks
//-----------------------------------------------------------------------------
void MMF::AudioPlayer::MaloLoadingStarted()
{
bufferingStarted();
}
void MMF::AudioPlayer::MaloLoadingComplete()
{
bufferingComplete();
}
//-----------------------------------------------------------------------------
// Private functions
//-----------------------------------------------------------------------------
int MMF::AudioPlayer::numberOfMetaDataEntries() const
{
int numberOfEntries = 0;
m_player->GetNumberOfMetaDataEntries(numberOfEntries); // ignoring return code
return numberOfEntries;
}
QPair<QString, QString> MMF::AudioPlayer::metaDataEntry(int index) const
{
CMMFMetaDataEntry *entry = 0;
QT_TRAP_THROWING(entry = m_player->GetMetaDataEntryL(index));
return QPair<QString, QString>(qt_TDesC2QString(entry->Name()), qt_TDesC2QString(entry->Value()));
}
QT_END_NAMESPACE