diff options
author | Michael Goddard <michael.goddard@nokia.com> | 2011-06-29 13:38:46 +1000 |
---|---|---|
committer | Michael Goddard <michael.goddard@nokia.com> | 2011-06-29 13:38:46 +1000 |
commit | 2a34e88c1e1ced28e75c487cd13402e1c9cf9fa3 (patch) | |
tree | e6c1b770c5c47212792a1f9344fa034ea3e54c44 /src/plugins/symbian/mmf | |
download | qtmultimedia-2a34e88c1e1ced28e75c487cd13402e1c9cf9fa3.tar.gz |
Initial copy of QtMultimediaKit.
Comes from original repo, with SHA1:
2c82d5611655e5967f5c5095af50c0991c4378b2
Diffstat (limited to 'src/plugins/symbian/mmf')
53 files changed, 11150 insertions, 0 deletions
diff --git a/src/plugins/symbian/mmf/audiosource/audiosource_s60.pri b/src/plugins/symbian/mmf/audiosource/audiosource_s60.pri new file mode 100644 index 000000000..7732600fa --- /dev/null +++ b/src/plugins/symbian/mmf/audiosource/audiosource_s60.pri @@ -0,0 +1,31 @@ +INCLUDEPATH += $$PWD + +DEFINES += AUDIOSOURCEUSED + +symbian:LIBS += -lmediaclientaudio \ + -lmmfcontrollerframework \ + -lefsrv \ + -lbafl \ + +!contains(S60_VERSION, 3.1) { + contains(audiorouting_s60_enabled,yes) { + #We use audioinputrouting.lib for recording audio from different sources -lmediaclientaudioinputstream \ -lcone \ + DEFINES += AUDIOINPUT_ROUTING + message("Audio Input Routing enabled onwards 3.2 SDK") + LIBS += -laudioinputrouting + } +} + +HEADERS += $$PWD/s60audioencodercontrol.h \ + $$PWD/s60audiomediarecordercontrol.h \ + $$PWD/s60audioendpointselector.h \ + $$PWD/s60audiocaptureservice.h \ + $$PWD/s60audiocapturesession.h \ + $$PWD/S60audiocontainercontrol.h + +SOURCES += $$PWD/s60audioencodercontrol.cpp \ + $$PWD/s60audiomediarecordercontrol.cpp \ + $$PWD/s60audioendpointselector.cpp \ + $$PWD/s60audiocaptureservice.cpp \ + $$PWD/s60audiocapturesession.cpp \ + $$PWD/S60audiocontainercontrol.cpp diff --git a/src/plugins/symbian/mmf/audiosource/s60audiocaptureservice.cpp b/src/plugins/symbian/mmf/audiosource/s60audiocaptureservice.cpp new file mode 100644 index 000000000..742ac8f82 --- /dev/null +++ b/src/plugins/symbian/mmf/audiosource/s60audiocaptureservice.cpp @@ -0,0 +1,98 @@ +/**************************************************************************** +** +** 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 "DebugMacros.h" +#include <QDebug> + +#include "s60audiocaptureservice.h" +#include "s60audiocapturesession.h" +#include "s60audioendpointselector.h" +#include "s60audioencodercontrol.h" +#include "s60audiomediarecordercontrol.h" +#include "s60audiocontainercontrol.h" + +S60AudioCaptureService::S60AudioCaptureService(QObject *parent): + QMediaService(parent) +{ + DP0("S60AudioCaptureService::S60AudioCaptureService +++"); + + m_session = new S60AudioCaptureSession(this); + m_encoderControl = new S60AudioEncoderControl(m_session,this); + m_recorderControl = new S60AudioMediaRecorderControl(m_session,this); + m_endpointSelector = new S60AudioEndpointSelector(m_session,this); + m_containerControl = new S60AudioContainerControl(m_session, this); + + DP0("S60AudioCaptureService::S60AudioCaptureService ---"); +} + +S60AudioCaptureService::~S60AudioCaptureService() +{ + DP0("S60AudioCaptureService::~S60AudioCaptureService +++"); + DP0("S60AudioCaptureService::~S60AudioCaptureService ---"); +} + +QMediaControl *S60AudioCaptureService::requestControl(const char *name) +{ + DP0("S60AudioCaptureService::requestControl"); + + if (qstrcmp(name,QMediaRecorderControl_iid) == 0) + return m_recorderControl; + + if (qstrcmp(name,QAudioEncoderControl_iid) == 0) + return m_encoderControl; + + if (qstrcmp(name,QAudioEndpointSelector_iid) == 0) + return m_endpointSelector; + + if (qstrcmp(name,QMediaContainerControl_iid) == 0) + return m_containerControl; + + return 0; +} + +void S60AudioCaptureService::releaseControl(QMediaControl *control) +{ + DP0("S60AudioCaptureService::releaseControl +++"); + + Q_UNUSED(control) + + DP0("S60AudioCaptureService::releaseControl ---"); +} diff --git a/src/plugins/symbian/mmf/audiosource/s60audiocaptureservice.h b/src/plugins/symbian/mmf/audiosource/s60audiocaptureservice.h new file mode 100644 index 000000000..86d71a994 --- /dev/null +++ b/src/plugins/symbian/mmf/audiosource/s60audiocaptureservice.h @@ -0,0 +1,75 @@ +/**************************************************************************** +** +** 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$ +** +****************************************************************************/ + +#ifndef S60AUDIOCAPTURESERVICE_H +#define S60AUDIOCAPTURESERVICE_H + +#include <QtCore/qobject.h> + +#include <qmediaservice.h> + +QT_USE_NAMESPACE + +class S60AudioCaptureSession; +class S60AudioEncoderControl; +class S60AudioMediaRecorderControl; +class S60AudioEndpointSelector; +class S60AudioContainerControl; + + +class S60AudioCaptureService : public QMediaService +{ + Q_OBJECT +public: + S60AudioCaptureService(QObject *parent = 0); + ~S60AudioCaptureService(); + + QMediaControl *requestControl(const char *name); + void releaseControl(QMediaControl *control); +private: + S60AudioCaptureSession *m_session; + S60AudioEncoderControl *m_encoderControl; + S60AudioEndpointSelector *m_endpointSelector; + S60AudioMediaRecorderControl *m_recorderControl; + S60AudioContainerControl *m_containerControl; +}; + +#endif // S60AUDIOCAPTURESERVICE_H diff --git a/src/plugins/symbian/mmf/audiosource/s60audiocapturesession.cpp b/src/plugins/symbian/mmf/audiosource/s60audiocapturesession.cpp new file mode 100644 index 000000000..79b6a53a0 --- /dev/null +++ b/src/plugins/symbian/mmf/audiosource/s60audiocapturesession.cpp @@ -0,0 +1,937 @@ +/**************************************************************************** +** +** 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 "DebugMacros.h" + +#include "s60audiocapturesession.h" +#include <QtCore/qdebug.h> +#include <QtCore/qurl.h> +#include <QDir> + +#include <mda/common/audio.h> +#include <mda/common/resource.h> +#include <mda/client/utility.h> +#include <mdaaudiosampleeditor.h> +#include <mmf/common/mmfcontrollerpluginresolver.h> +#include <mmf/common/mmfcontroller.h> +#include <badesca.h> +#include <bautils.h> +#include <f32file.h> + +#ifdef AUDIOINPUT_ROUTING +const QString S60AudioCaptureSession::microPhone("Microphone"); +const QString S60AudioCaptureSession::voiceCall("Voice Call"); +const QString S60AudioCaptureSession::fmRadio("FM Radio"); +#endif + +S60AudioCaptureSession::S60AudioCaptureSession(QObject *parent): + QObject(parent) + , m_recorderUtility(NULL) + , m_captureState(ENotInitialized) + , m_controllerIdMap(QHash<QString, ControllerData>()) + , m_audioCodeclist(QHash<QString, CodecData>()) + , m_error(QMediaRecorder::NoError) + , m_isMuted(false) +{ + DP0("S60AudioCaptureSession::S60AudioCaptureSession +++"); +#ifdef AUDIOINPUT_ROUTING + m_audioInput = NULL; + m_setActiveEndPoint = FALSE; + m_audioEndpoint = S60AudioCaptureSession::microPhone; +#endif //AUDIOINPUT_ROUTING + TRAPD(err, initializeSessionL()); + setError(err); + + DP0("S60AudioCaptureSession::S60AudioCaptureSession ---"); +} + +void S60AudioCaptureSession::initializeSessionL() +{ + DP0("S60AudioCaptureSession::initializeSessionL +++"); + + m_recorderUtility = CMdaAudioRecorderUtility::NewL(*this, 0, EMdaPriorityNormal, EMdaPriorityPreferenceTimeAndQuality); + updateAudioContainersL(); + populateAudioCodecsDataL(); + setDefaultSettings(); +#ifdef AUDIOINPUT_ROUTING + initAudioInputs(); +#endif + User::LeaveIfError(m_fsSession.Connect()); + m_captureState = EInitialized; + emit stateChanged(m_captureState); + + DP0("S60AudioCaptureSession::initializeSessionL ---"); +} + +void S60AudioCaptureSession::setError(TInt aError) +{ + DP0("S60AudioCaptureSession::setError +++"); + + DP1("S60AudioCaptureSession::setError:", aError); + + if (aError == KErrNone) + return; + + m_error = aError; + QMediaRecorder::Error recorderError = fromSymbianErrorToMultimediaError(m_error); + + // TODO: fix to user friendly string at some point + // These error string are only dev usable + QString symbianError; + symbianError.append("Symbian:"); + symbianError.append(QString::number(m_error)); + stop(); + emit error(recorderError, symbianError); + + DP0("S60AudioCaptureSession::setError ---"); +} + +QMediaRecorder::Error S60AudioCaptureSession::fromSymbianErrorToMultimediaError(int error) +{ + DP0("S60AudioCaptureSession::fromSymbianErrorToMultimediaError +++"); + + DP1("S60AudioCaptureSession::fromSymbianErrorToMultimediaError:", error); + + switch(error) { + case KErrNoMemory: + case KErrNotFound: + case KErrBadHandle: + case KErrAbort: + case KErrCorrupt: + case KErrGeneral: + case KErrPathNotFound: + case KErrUnknown: + case KErrNotReady: + case KErrInUse: + case KErrAccessDenied: + case KErrLocked: + case KErrPermissionDenied: + case KErrAlreadyExists: + return QMediaRecorder::ResourceError; + case KErrNotSupported: + case KErrArgument: + return QMediaRecorder::FormatError; + case KErrNone: + default: + DP0("S60AudioCaptureSession::fromSymbianErrorToMultimediaError: ---"); + return QMediaRecorder::NoError; + } +} + +S60AudioCaptureSession::~S60AudioCaptureSession() +{ + DP0("S60AudioCaptureSession::~S60AudioCaptureSession +++"); + //stop the utility before deleting it + stop(); + if (m_recorderUtility) + delete m_recorderUtility; + m_fsSession.Close(); + DP0("S60AudioCaptureSession::~S60AudioCaptureSession ---"); +} + +QAudioFormat S60AudioCaptureSession::format() const +{ + DP0("S60AudioCaptureSession::format"); + + return m_format; +} + +bool S60AudioCaptureSession::setFormat(const QAudioFormat &format) +{ + DP0("S60AudioCaptureSession::setFormat +++"); + + m_format = format; + + DP0("S60AudioCaptureSession::setFormat ---"); + + return true; +} + +QAudioEncoderSettings S60AudioCaptureSession::settings() const +{ + DP0("S60AudioCaptureSession::settings"); + + return m_audioEncoderSettings; +} + +bool S60AudioCaptureSession::setEncoderSettings(const QAudioEncoderSettings &setting) +{ + DP0("S60AudioCaptureSession::setEncoderSettings +++"); + + m_audioEncoderSettings = setting; + + DP0("S60AudioCaptureSession::setEncoderSettings ---"); + + return true; +} + +QStringList S60AudioCaptureSession::supportedAudioCodecs() const +{ + DP0("S60AudioCaptureSession::supportedAudioCodecs"); + + return m_audioCodeclist.keys(); +} + +QStringList S60AudioCaptureSession::supportedAudioContainers() const +{ + DP0("S60AudioCaptureSession::supportedAudioContainers"); + + return m_controllerIdMap.keys(); +} + +QString S60AudioCaptureSession::codecDescription(const QString &codecName) +{ + DP0("S60AudioCaptureSession::codecDescription +++"); + + if (m_audioCodeclist.keys().contains(codecName)) { + + DP0("S60AudioCaptureSession::codecDescription ---"); + return m_audioCodeclist.value(codecName).codecDescription; + } + else { + DP0("S60AudioCaptureSession::codecDescription ---"); + + return QString(); + } +} + +QString S60AudioCaptureSession::audioContainerDescription(const QString &containerName) +{ + DP0("S60AudioCaptureSession::audioContainerDescription +++"); + + if (m_controllerIdMap.keys().contains(containerName)) { + DP0("S60AudioCaptureSession::audioContainerDescription ---"); + + return m_controllerIdMap.value(containerName).destinationFormatDescription; + } + else { + DP0("S60AudioCaptureSession::audioContainerDescription ---"); + + return QString(); + } +} + +bool S60AudioCaptureSession::setAudioCodec(const QString &codecName) +{ + DP0("S60AudioCaptureSession::setAudioCodec"); + + QStringList codecs = supportedAudioCodecs(); + if(codecs.contains(codecName)) { + m_format.setCodec(codecName); + return true; + } + return false; +} + +bool S60AudioCaptureSession::setAudioContainer(const QString &containerMimeType) +{ + DP0("S60AudioCaptureSession::setAudioContainer"); + + QStringList containers = supportedAudioContainers(); + if (containerMimeType == "audio/mpeg") + { + m_container = "audio/mp4"; + return true; + } + if(containers.contains(containerMimeType)) { + m_container = containerMimeType; + return true; + } + return false; +} + +QString S60AudioCaptureSession::audioCodec() const +{ + DP0("S60AudioCaptureSession::audioCodec"); + + return m_format.codec(); +} + +QString S60AudioCaptureSession::audioContainer() const +{ + DP0("S60AudioCaptureSession::audioContainer"); + + return m_container; +} + +QUrl S60AudioCaptureSession::outputLocation() const +{ + DP0("S60AudioCaptureSession::outputLocation"); + + return m_sink; +} + +bool S60AudioCaptureSession::setOutputLocation(const QUrl& sink) +{ + DP0("S60AudioCaptureSession::setOutputLocation"); + + QString filename = QDir::toNativeSeparators(sink.toString()); + TPtrC16 path(reinterpret_cast<const TUint16*>(filename.utf16())); + TRAPD(err, BaflUtils::EnsurePathExistsL(m_fsSession,path)); + if (err == KErrNone) { + m_sink = sink; + setError(err); + return true; + }else { + setError(err); + return false; + } +} + +qint64 S60AudioCaptureSession::position() const +{ + DP0("S60AudioCaptureSession::position"); + + if ((m_captureState != ERecording) || !m_recorderUtility) + return 0; + + return m_recorderUtility->Duration().Int64() / 1000; +} + +void S60AudioCaptureSession::prepareSinkL() +{ + DP0("S60AudioCaptureSession::prepareSinkL +++"); + + /* If m_outputLocation is null, set a default location */ + if (m_sink.isEmpty()) { + QDir outputDir(QDir::rootPath()); + int lastImage = 0; + int fileCount = 0; + foreach(QString fileName, outputDir.entryList(QStringList() << "recordclip_*")) { + int imgNumber = fileName.mid(5, fileName.size() - 9).toInt(); + lastImage = qMax(lastImage, imgNumber); + if (outputDir.exists(fileName)) + fileCount += 1; + } + lastImage += fileCount; + m_sink = QUrl(QDir::toNativeSeparators(outputDir.canonicalPath() + QString("/recordclip_%1").arg(lastImage + 1, 4, 10, QLatin1Char('0')))); + } + + QString sink = QDir::toNativeSeparators(m_sink.toString()); + TPtrC16 path(reinterpret_cast<const TUint16*>(sink.utf16())); + if (BaflUtils::FileExists(m_fsSession, path)) + BaflUtils::DeleteFile(m_fsSession, path); + + int index = sink.lastIndexOf('.'); + if (index != -1) + sink.chop(sink.length()-index); + + sink.append(m_controllerIdMap.value(m_container).fileExtension); + m_sink.setUrl(sink); + + DP0("S60AudioCaptureSession::prepareSinkL ---"); +} + +void S60AudioCaptureSession::record() +{ + DP0("S60AudioCaptureSession::record +++"); + + if (!m_recorderUtility) + return; + + if (m_captureState == EInitialized || m_captureState == ERecordComplete) { + prepareSinkL(); + QString filename = m_sink.toString(); + TPtrC16 sink(reinterpret_cast<const TUint16*>(filename.utf16())); + TUid controllerUid(TUid::Uid(m_controllerIdMap.value(m_container).controllerUid)); + TUid formatUid(TUid::Uid(m_controllerIdMap.value(m_container).destinationFormatUid)); + + TRAPD(err,m_recorderUtility->OpenFileL(sink)); + setError(err); + }else if (m_captureState == EPaused) { + m_recorderUtility->SetPosition(m_pausedPosition); + TRAPD(error, m_recorderUtility->RecordL()); + setError(error); + m_captureState = ERecording; + emit stateChanged(m_captureState); + } + + DP0("S60AudioCaptureSession::record ---"); +} + +void S60AudioCaptureSession::mute(bool muted) +{ + DP0("S60AudioCaptureSession::mute +++"); + + if (!m_recorderUtility) + return; + + if (muted) + m_recorderUtility->SetGain(0); + else + m_recorderUtility->SetGain(m_recorderUtility->MaxGain()); + + m_isMuted = muted; + + DP0("S60AudioCaptureSession::mute ---"); +} + +bool S60AudioCaptureSession::muted() +{ + DP0("S60AudioCaptureSession::muted"); + + return m_isMuted; +} + +void S60AudioCaptureSession::setDefaultSettings() +{ + DP0("S60AudioCaptureSession::setDefaultSettings +++"); + + // Setting AMR to default format if supported + if (m_controllerIdMap.count() > 0) { + if ( m_controllerIdMap.contains("audio/amr")) + m_container = QString("audio/amr"); + else + m_container = m_controllerIdMap.keys()[0]; + } + if (m_audioCodeclist.keys().count() > 0) { + if (m_audioCodeclist.keys().contains("AMR")) { + m_format.setSampleSize(8); + m_format.setChannels(1); + m_format.setFrequency(8000); + m_format.setSampleType(QAudioFormat::SignedInt); + m_format.setCodec("AMR"); + }else + m_format.setCodec(m_audioCodeclist.keys()[0]); + } + + DP0("S60AudioCaptureSession::setDefaultSettings ---"); +} + +void S60AudioCaptureSession::pause() +{ + DP0("S60AudioCaptureSession::pause +++"); + + if (!m_recorderUtility) + return; + + m_pausedPosition = m_recorderUtility->Position(); + m_recorderUtility->Stop(); + m_captureState = EPaused; + emit stateChanged(m_captureState); + + DP0("S60AudioCaptureSession::pause ---"); +} + +void S60AudioCaptureSession::stop() +{ + DP0("S60AudioCaptureSession::stop +++"); + + if (!m_recorderUtility) + return; + + m_recorderUtility->Stop(); + +#ifdef AUDIOINPUT_ROUTING + //delete audio input instance before closing the utility. + if (m_audioInput) + { + delete m_audioInput; + m_audioInput = NULL; + } +#endif //AUDIOINPUT_ROUTING + + m_recorderUtility->Close(); + m_captureState = ERecordComplete; + emit stateChanged(m_captureState); +} + +#ifdef AUDIOINPUT_ROUTING + +void S60AudioCaptureSession::initAudioInputs() +{ + DP0(" S60AudioCaptureSession::initAudioInputs +++"); + + m_audioInputs[S60AudioCaptureSession::microPhone] = QString("Microphone associated with the currently active speaker."); + m_audioInputs[S60AudioCaptureSession::voiceCall] = QString("Audio stream associated with the current phone call."); + m_audioInputs[S60AudioCaptureSession::fmRadio] = QString("Audio of the currently tuned FM radio station."); + + DP0(" S60AudioCaptureSession::initAudioInputs ---"); +} + +#endif //AUDIOINPUT_ROUTING + +void S60AudioCaptureSession::setActiveEndpoint(const QString& audioEndpoint) +{ + DP0(" S60AudioCaptureSession::setActiveEndpoint +++"); + + if (!m_audioInputs.keys().contains(audioEndpoint)) + return; + + if (activeEndpoint().compare(audioEndpoint) != 0) { + m_audioEndpoint = audioEndpoint; +#ifdef AUDIOINPUT_ROUTING + m_setActiveEndPoint = TRUE; +#endif + } + + DP0(" S60AudioCaptureSession::setActiveEndpoint ---"); +} + +QList<QString> S60AudioCaptureSession::availableEndpoints() const +{ + DP0(" S60AudioCaptureSession::availableEndpoints"); + + return m_audioInputs.keys(); +} + +QString S60AudioCaptureSession::endpointDescription(const QString& name) const +{ + DP0(" S60AudioCaptureSession::endpointDescription +++"); + + if (m_audioInputs.keys().contains(name)) + return m_audioInputs.value(name); + return QString(); +} + +QString S60AudioCaptureSession::activeEndpoint() const +{ + DP0(" S60AudioCaptureSession::activeEndpoint"); + + QString inputSourceName = NULL; +#ifdef AUDIOINPUT_ROUTING + if (m_audioInput) { + CAudioInput::TAudioInputArray input = m_audioInput->AudioInput(); + inputSourceName = qStringFromTAudioInputPreference(input[0]); + } +#endif //AUDIOINPUT_ROUTING + return inputSourceName; +} + +QString S60AudioCaptureSession::defaultEndpoint() const +{ + DP0(" S60AudioCaptureSession::defaultEndpoint"); + +#ifdef AUDIOINPUT_ROUTING + return QString(S60AudioCaptureSession::microPhone); +#else + return NULL; +#endif +} + +#ifdef AUDIOINPUT_ROUTING + +void S60AudioCaptureSession::doSetAudioInputL(const QString& name) +{ + DP0(" S60AudioCaptureSession::doSetAudioInputL +++"); + DP1(" S60AudioCaptureSession::doSetAudioInputL:", name); + TInt err(KErrNone); + + if (!m_recorderUtility) + return; + + CAudioInput::TAudioInputPreference input = CAudioInput::EDefaultMic; + + if (name.compare(S60AudioCaptureSession::voiceCall) == 0) + input = CAudioInput::EVoiceCall; +// commented because they are not supported on 9.2 + else if (name.compare(S60AudioCaptureSession::fmRadio) == 0) + input = CAudioInput::EFMRadio; + else // S60AudioCaptureSession::microPhone + input = CAudioInput::EDefaultMic; + + RArray<CAudioInput::TAudioInputPreference> inputArray; + inputArray.Append(input); + + if (m_audioInput){ + TRAP(err,m_audioInput->SetAudioInputL(inputArray.Array())); + + if (err == KErrNone) { + emit activeEndpointChanged(name); + } + else{ + setError(err); + } + } + inputArray.Close(); + + DP0(" S60AudioCaptureSession::doSetAudioInputL ---"); +} + + +QString S60AudioCaptureSession::qStringFromTAudioInputPreference(CAudioInput::TAudioInputPreference input) const +{ + DP0(" S60AudioCaptureSession::qStringFromTAudioInputPreference"); + + if (input == CAudioInput::EVoiceCall) + return S60AudioCaptureSession::voiceCall; + else if (input == CAudioInput::EFMRadio) + return S60AudioCaptureSession::fmRadio; + else + return S60AudioCaptureSession::microPhone; // CAudioInput::EDefaultMic +} +#endif //AUDIOINPUT_ROUTING + + +void S60AudioCaptureSession::MoscoStateChangeEvent(CBase* aObject, + TInt aPreviousState, TInt aCurrentState, TInt aErrorCode) +{ + DP0("S60AudioCaptureSession::MoscoStateChangeEvent +++"); + + if (aErrorCode==KErrNone) { + TRAPD(err, MoscoStateChangeEventL(aObject, aPreviousState, aCurrentState, NULL)); + setError(err); + } + else { + setError(aErrorCode); + } + DP1("S60AudioCaptureSession::MoscoStateChangeEvent, aErrorCode:", aErrorCode); + DP0("S60AudioCaptureSession::MoscoStateChangeEvent ---"); +} + +void S60AudioCaptureSession::MoscoStateChangeEventL(CBase* aObject, + TInt aPreviousState, TInt aCurrentState, TInt aErrorCode) +{ + DP0("S60AudioCaptureSession::MoscoStateChangeEventL +++"); + + DP5("S60AudioCaptureSession::MoscoStateChangeEventL - aPreviousState:", aPreviousState, + "aCurrentState:", aCurrentState, "aErrorCode:", aErrorCode); + if (aObject != m_recorderUtility) + return; + + switch(aCurrentState) { + case CMdaAudioClipUtility::EOpen: { + if(aPreviousState == CMdaAudioClipUtility::ENotReady) { + applyAudioSettingsL(); + m_recorderUtility->SetGain(m_recorderUtility->MaxGain()); + TRAPD(err, m_recorderUtility->RecordL()); + setError(err); + m_captureState = EOpenCompelete; + emit stateChanged(m_captureState); + } + break; + } + case CMdaAudioClipUtility::ENotReady: { + m_captureState = EInitialized; + emit stateChanged(m_captureState); + break; + } + case CMdaAudioClipUtility::ERecording: { + m_captureState = ERecording; + emit stateChanged(m_captureState); + break; + } + default: { + break; + } + } + + DP0("S60AudioCaptureSession::MoscoStateChangeEventL ---"); +} + +void S60AudioCaptureSession::updateAudioContainersL() +{ + DP0("S60AudioCaptureSession::updateAudioContainersL +++"); + + CMMFControllerPluginSelectionParameters* pluginParameters = + CMMFControllerPluginSelectionParameters::NewLC(); + CMMFFormatSelectionParameters* formatParameters = + CMMFFormatSelectionParameters::NewLC(); + + pluginParameters->SetRequiredRecordFormatSupportL(*formatParameters); + + RArray<TUid> ids; + CleanupClosePushL(ids); + User::LeaveIfError(ids.Append(KUidMediaTypeAudio)); + + pluginParameters->SetMediaIdsL(ids, + CMMFPluginSelectionParameters::EAllowOnlySuppliedMediaIds); + + RMMFControllerImplInfoArray controllers; + CleanupResetAndDestroyPushL(controllers); + + //Get all audio record controllers/formats that are supported + pluginParameters->ListImplementationsL(controllers); + + for (TInt index=0; index<controllers.Count(); index++) { + const RMMFFormatImplInfoArray& recordFormats = + controllers[index]->RecordFormats(); + for (TInt j=0; j<recordFormats.Count(); j++) { + const CDesC8Array& mimeTypes = recordFormats[j]->SupportedMimeTypes(); + const CDesC8Array& fileExtensions = recordFormats[j]->SupportedFileExtensions(); + TInt mimeCount = mimeTypes.Count(); + TInt fileExtCount = fileExtensions.Count(); + + if (mimeCount > 0 && fileExtCount > 0) { + TPtrC8 extension = fileExtensions[0]; + TPtrC8 mimeType = mimeTypes[0]; + QString type = QString::fromUtf8((char *)mimeType.Ptr(), mimeType.Length()); + + if (type != "audio/basic") { + ControllerData data; + data.controllerUid = controllers[index]->Uid().iUid; + data.destinationFormatUid = recordFormats[j]->Uid().iUid; + data.destinationFormatDescription = QString::fromUtf16( + recordFormats[j]->DisplayName().Ptr(), + recordFormats[j]->DisplayName().Length()); + data.fileExtension = QString::fromUtf8((char *)extension.Ptr(), extension.Length()); + m_controllerIdMap[type] = data; + } + } + } + } + CleanupStack::PopAndDestroy(4);//controllers, ids, formatParameters, pluginParameters + + DP0("S60AudioCaptureSession::updateAudioContainersL ---"); +} + +void S60AudioCaptureSession::retrieveSupportedAudioSampleRatesL() +{ + DP0("S60AudioCaptureSession::retrieveSupportedAudioSampleRatesL +++"); + + if (!m_recorderUtility) { + DP0("No RecorderUtility"); + return; + } + + m_supportedSampleRates.clear(); + + RArray<TUint> supportedSampleRates; + CleanupClosePushL(supportedSampleRates); + m_recorderUtility->GetSupportedSampleRatesL(supportedSampleRates); + for (TInt j = 0; j < supportedSampleRates.Count(); j++ ) + m_supportedSampleRates.append(supportedSampleRates[j]); + + CleanupStack::PopAndDestroy(&supportedSampleRates); + + DP0("S60AudioCaptureSession::retrieveSupportedAudioSampleRatesL ---"); +} + +QList<int> S60AudioCaptureSession::supportedAudioSampleRates(const QAudioEncoderSettings &settings) const +{ + DP0("S60AudioCaptureSession::supportedAudioSampleRates +++"); + + QList<int> supportedSampleRates; + + if (!settings.codec().isEmpty()) { + if (settings.codec() == "AMR") + supportedSampleRates.append(8000); + else + supportedSampleRates = m_supportedSampleRates; + }else + supportedSampleRates = m_supportedSampleRates; + + DP0("S60AudioCaptureSession::supportedAudioSampleRates ---"); + + return supportedSampleRates; +} + +void S60AudioCaptureSession::populateAudioCodecsDataL() +{ + DP0("S60AudioCaptureSession::populateAudioCodecsDataL +++"); + + if (!m_recorderUtility) { + DP0("No RecorderUtility"); + + return; + } + + if (m_controllerIdMap.contains("audio/amr")) { + CodecData data; + data.codecDescription = QString("GSM AMR Codec"); + m_audioCodeclist[QString("AMR")]=data; + } + if (m_controllerIdMap.contains("audio/basic")) { + CodecData data; + data.fourCC = KMMFFourCCCodeALAW; + data.codecDescription = QString("Sun/Next ""Au"" audio codec"); + m_audioCodeclist[QString("AULAW")]=data; + } + if (m_controllerIdMap.contains("audio/wav")) { + CodecData data; + data.fourCC = KMMFFourCCCodePCM16; + data.codecDescription = QString("Pulse code modulation"); + m_audioCodeclist[QString("PCM")]=data; + } + if (m_controllerIdMap.contains("audio/mp4")) { + CodecData data; + data.fourCC = KMMFFourCCCodeAAC; + data.codecDescription = QString("Advanced Audio Codec"); + m_audioCodeclist[QString("AAC")]=data; + } + + // default samplerates + m_supportedSampleRates << 96000 << 88200 << 64000 << 48000 << 44100 << 32000 << 24000 << 22050 << 16000 << 12000 << 11025 << 8000; + + DP0("S60AudioCaptureSession::populateAudioCodecsDataL ---"); +} + +void S60AudioCaptureSession::applyAudioSettingsL() +{ + DP0("S60AudioCaptureSession::applyAudioSettingsL +++"); + + if (!m_recorderUtility) + return; + +#ifdef AUDIOINPUT_ROUTING + //CAudioInput needs to be re-initialized every time recording starts + if (m_audioInput) { + delete m_audioInput; + m_audioInput = NULL; + } + + if (m_setActiveEndPoint) { + m_audioInput = CAudioInput::NewL(*m_recorderUtility); + doSetAudioInputL(m_audioEndpoint); + } +#endif //AUDIOINPUT_ROUTING + + if (m_format.codec() == "AMR") + return; + + TFourCC fourCC = m_audioCodeclist.value(m_format.codec()).fourCC; + + if (m_format.codec() == "PCM") + fourCC = determinePCMFormat(); + + RArray<TFourCC> supportedDataTypes; + CleanupClosePushL(supportedDataTypes); + TRAPD(err,m_recorderUtility->GetSupportedDestinationDataTypesL(supportedDataTypes)); + TInt num = supportedDataTypes.Count(); + if (num > 0 ) { + supportedDataTypes.SortUnsigned(); + int index = supportedDataTypes.Find(fourCC.FourCC()); + if (index != KErrNotFound) { + TRAPD(err,m_recorderUtility->SetDestinationDataTypeL(supportedDataTypes[index])); + } + } + + supportedDataTypes.Reset(); + CleanupStack::PopAndDestroy(&supportedDataTypes); + + if (m_recorderUtility->DestinationSampleRateL() != m_format.frequency()) { + + RArray<TUint> supportedSampleRates; + CleanupClosePushL(supportedSampleRates); + m_recorderUtility->GetSupportedSampleRatesL(supportedSampleRates); + for (TInt i = 0; i < supportedSampleRates.Count(); i++ ) { + TUint supportedSampleRate = supportedSampleRates[i]; + if (supportedSampleRate == m_format.frequency()) { + m_recorderUtility->SetDestinationSampleRateL(m_format.frequency()); + break; + } + } + supportedSampleRates.Reset(); + CleanupStack::PopAndDestroy(&supportedSampleRates); + } + + /* If requested channel setting is different than current one */ + if (m_recorderUtility->DestinationNumberOfChannelsL() != m_format.channels()) { + RArray<TUint> supportedChannels; + CleanupClosePushL(supportedChannels); + m_recorderUtility->GetSupportedNumberOfChannelsL(supportedChannels); + for (TInt l = 0; l < supportedChannels.Count(); l++ ) { + if (supportedChannels[l] == m_format.channels()) { + m_recorderUtility->SetDestinationNumberOfChannelsL(m_format.channels()); + break; + } + } + supportedChannels.Reset(); + CleanupStack::PopAndDestroy(&supportedChannels); + } + + if (!(m_format.codec().compare("pcm",Qt::CaseInsensitive) == 0)) { + if (m_recorderUtility->DestinationBitRateL() != m_audioEncoderSettings.bitRate()) { + RArray<TUint> supportedBitRates; + CleanupClosePushL(supportedBitRates); + m_recorderUtility->GetSupportedBitRatesL(supportedBitRates); + for (TInt l = 0; l < supportedBitRates.Count(); l++ ) { + if (supportedBitRates[l] == m_audioEncoderSettings.bitRate()) { + m_recorderUtility->SetDestinationBitRateL(m_audioEncoderSettings.bitRate()); + break; + } + } + supportedBitRates.Reset(); + CleanupStack::PopAndDestroy(&supportedBitRates); + } + } + + DP0("S60AudioCaptureSession::applyAudioSettingsL ---"); +} + +TFourCC S60AudioCaptureSession::determinePCMFormat() +{ + DP0("S60AudioCaptureSession::determinePCMFormat +++"); + + TFourCC fourCC; + + if (m_format.sampleSize() == 8) { + // 8 bit + switch (m_format.sampleType()) { + case QAudioFormat::SignedInt: { + fourCC.Set(KMMFFourCCCodePCM8); + break; + } + case QAudioFormat::UnSignedInt: { + fourCC.Set(KMMFFourCCCodePCMU8); + break; + } + case QAudioFormat::Float: + case QAudioFormat::Unknown: + default: { + fourCC.Set(KMMFFourCCCodePCM8); + break; + } + } + } else if (m_format.sampleSize() == 16) { + // 16 bit + switch (m_format.sampleType()) { + case QAudioFormat::SignedInt: { + fourCC.Set(m_format.byteOrder()==QAudioFormat::BigEndian? + KMMFFourCCCodePCM16B:KMMFFourCCCodePCM16); + break; + } + case QAudioFormat::UnSignedInt: { + fourCC.Set(m_format.byteOrder()==QAudioFormat::BigEndian? + KMMFFourCCCodePCMU16B:KMMFFourCCCodePCMU16); + break; + } + default: { + fourCC.Set(KMMFFourCCCodePCM16); + break; + } + } + } + + DP0("S60AudioCaptureSession::determinePCMFormat ---"); + + return fourCC; +} diff --git a/src/plugins/symbian/mmf/audiosource/s60audiocapturesession.h b/src/plugins/symbian/mmf/audiosource/s60audiocapturesession.h new file mode 100644 index 000000000..a541446e9 --- /dev/null +++ b/src/plugins/symbian/mmf/audiosource/s60audiocapturesession.h @@ -0,0 +1,193 @@ +/**************************************************************************** +** +** 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$ +** +****************************************************************************/ + +#ifndef S60AUDIOCAPTURESESSION_H +#define S60AUDIOCAPTURESESSION_H + +#include <qmobilityglobal.h> +#include <QtCore/qobject.h> +#include <QFile> +#include <QUrl> +#include <QList> +#include <QHash> +#include <QMap> +#include "qaudioformat.h" +#include <qmediarecorder.h> + +#include <mda/common/audio.h> +#include <mda/common/resource.h> +#include <mda/client/utility.h> +#include <mdaaudiosampleeditor.h> +#include <mmf/common/mmfutilities.h> + +#ifdef AUDIOINPUT_ROUTING +#include <audioinput.h> +#endif //AUDIOINPUT_ROUTING + +QT_BEGIN_NAMESPACE +struct ControllerData +{ + int controllerUid; + int destinationFormatUid; + QString destinationFormatDescription; + QString fileExtension; +}; + +struct CodecData +{ + TFourCC fourCC; + QString codecDescription; +}; +QT_END_NAMESPACE + +QT_USE_NAMESPACE + +class S60AudioCaptureSession : public QObject, public MMdaObjectStateChangeObserver +{ + Q_OBJECT + Q_PROPERTY(qint64 position READ position NOTIFY positionChanged) + Q_ENUMS(TAudioCaptureState) +public: + + enum TAudioCaptureState + { + ENotInitialized = 0, + EInitialized, + EOpenCompelete, + ERecording, + EPaused, + ERecordComplete + }; + + S60AudioCaptureSession(QObject *parent = 0); + ~S60AudioCaptureSession(); + + QAudioFormat format() const; + bool setFormat(const QAudioFormat &format); + QAudioEncoderSettings settings() const; + bool setEncoderSettings(const QAudioEncoderSettings &setting); + QStringList supportedAudioCodecs() const; + QString codecDescription(const QString &codecName); + bool setAudioCodec(const QString &codecName); + QString audioCodec() const; + QString audioContainer() const; + QStringList supportedAudioContainers() const; + bool setAudioContainer(const QString &containerMimeType); + QString audioContainerDescription(const QString &containerName); + QList<int> supportedAudioSampleRates(const QAudioEncoderSettings &settings) const; + QUrl outputLocation() const; + bool setOutputLocation(const QUrl& sink); + qint64 position() const; + void record(); + void pause(); + void stop(); + void mute(bool muted); + bool muted(); + + QString activeEndpoint() const; + QString defaultEndpoint() const; + QList<QString> availableEndpoints() const; + QString endpointDescription(const QString& name) const; + +#ifdef AUDIOINPUT_ROUTING + static const QString microPhone; + static const QString voiceCall; + static const QString fmRadio; +#endif //AUDIOINPUT_ROUTING +private: + void initializeSessionL(); + void setError(TInt aError); + QMediaRecorder::Error fromSymbianErrorToMultimediaError(int error); + void prepareSinkL(); + void updateAudioContainersL(); + void populateAudioCodecsDataL(); + void retrieveSupportedAudioSampleRatesL(); + void applyAudioSettingsL(); + TFourCC determinePCMFormat(); + void setDefaultSettings(); + // MMdaObjectStateChangeObserver + void MoscoStateChangeEvent(CBase* aObject, TInt aPreviousState, + TInt aCurrentState, TInt aErrorCode); + void MoscoStateChangeEventL(CBase* aObject, TInt aPreviousState, + TInt aCurrentState, TInt aErrorCode); + +#ifdef AUDIOINPUT_ROUTING + QString qStringFromTAudioInputPreference(CAudioInput::TAudioInputPreference input) const; + void initAudioInputs(); + void doSetAudioInputL(const QString& name); +#endif //AUDIOINPUT_ROUTING + +public Q_SLOTS: + void setActiveEndpoint(const QString& audioEndpoint); + + +Q_SIGNALS: + void stateChanged(S60AudioCaptureSession::TAudioCaptureState); + void positionChanged(qint64 position); + void error(int error, const QString &errorString); + void activeEndpointChanged(const QString &audioEndpoint); +private: + QString m_container; + QUrl m_sink; + TTimeIntervalMicroSeconds m_pausedPosition; + CMdaAudioRecorderUtility *m_recorderUtility; + TAudioCaptureState m_captureState; + QAudioFormat m_format; + QAudioEncoderSettings m_audioEncoderSettings; + QHash<QString, ControllerData> m_controllerIdMap; + QHash<QString, CodecData> m_audioCodeclist; + QList<int> m_supportedSampleRates; + int m_error; + bool m_isMuted; + RFs m_fsSession; + +#ifdef AUDIOINPUT_ROUTING + bool m_setActiveEndPoint; + CAudioInput *m_audioInput; + +#endif //AUDIOINPUT_ROUTING + QMap<QString, QString> m_audioInputs; + QString m_audioEndpoint; + + +}; + +#endif // S60AUDIOCAPTURESESSION_H diff --git a/src/plugins/symbian/mmf/audiosource/s60audiocontainercontrol.cpp b/src/plugins/symbian/mmf/audiosource/s60audiocontainercontrol.cpp new file mode 100644 index 000000000..d6c2d5db2 --- /dev/null +++ b/src/plugins/symbian/mmf/audiosource/s60audiocontainercontrol.cpp @@ -0,0 +1,96 @@ +/**************************************************************************** +** +** 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 "DebugMacros.h" + +#include "s60audiocontainercontrol.h" +#include "s60audiocapturesession.h" +#include <QtCore/qdebug.h> + +S60AudioContainerControl::S60AudioContainerControl(QObject *parent) + : QMediaContainerControl(parent) +{ + DP0("S60AudioContainerControl::S60AudioContainerControl(QObject *parent) +++"); + + DP0("S60AudioContainerControl::S60AudioContainerControl(QObject *parent) ---"); + +} + +S60AudioContainerControl::S60AudioContainerControl(QObject *session, QObject *parent) + : QMediaContainerControl(parent) +{ + DP0("S60AudioContainerControl::S60AudioContainerControl(QObject *session, QObject *parent) +++"); + + m_session = qobject_cast<S60AudioCaptureSession*>(session); + + DP0("S60AudioContainerControl::S60AudioContainerControl(QObject *session, QObject *parent) ---"); +} + +QStringList S60AudioContainerControl::supportedContainers() const +{ + DP0("S60AudioContainerControl::supportedContainers"); + + return m_session->supportedAudioContainers(); +} + +QString S60AudioContainerControl::containerMimeType() const +{ + DP0("S60AudioContainerControl::containerMimeType"); + + return m_session->audioContainer(); +} + +void S60AudioContainerControl::setContainerMimeType(const QString &containerMimeType) +{ + DP0("S60AudioContainerControl::setContainerMimeType +++"); + + m_session->setAudioContainer(containerMimeType); + + DP0("S60AudioContainerControl::setContainerMimeType ---"); +} + +QString S60AudioContainerControl::containerDescription(const QString &containerMimeType) const +{ + DP0("S60AudioContainerControl::containerDescription"); + + return m_session->audioContainerDescription(containerMimeType); +} + diff --git a/src/plugins/symbian/mmf/audiosource/s60audiocontainercontrol.h b/src/plugins/symbian/mmf/audiosource/s60audiocontainercontrol.h new file mode 100644 index 000000000..4c3498d0f --- /dev/null +++ b/src/plugins/symbian/mmf/audiosource/s60audiocontainercontrol.h @@ -0,0 +1,70 @@ +/**************************************************************************** +** +** 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$ +** +****************************************************************************/ + +#ifndef S60AUDIOFORMATCONTROL_H +#define S60AUDIOFORMATCONTROL_H + +#include "qmediacontainercontrol.h" +#include <QtCore/qstringlist.h> + + +QT_USE_NAMESPACE + +class S60AudioCaptureSession; + +class S60AudioContainerControl : public QMediaContainerControl +{ +Q_OBJECT +public: + S60AudioContainerControl(QObject *parent = 0); + S60AudioContainerControl(QObject *session, QObject *parent = 0); + virtual ~S60AudioContainerControl() {}; + + QStringList supportedContainers() const; + QString containerMimeType() const; + void setContainerMimeType(const QString &containerMimeType); + QString containerDescription(const QString &containerMimeType) const; + +private: + S60AudioCaptureSession* m_session; +}; + +#endif // S60AUDIOFORMATCONTROL_H diff --git a/src/plugins/symbian/mmf/audiosource/s60audioencodercontrol.cpp b/src/plugins/symbian/mmf/audiosource/s60audioencodercontrol.cpp new file mode 100644 index 000000000..b3d02a94a --- /dev/null +++ b/src/plugins/symbian/mmf/audiosource/s60audioencodercontrol.cpp @@ -0,0 +1,235 @@ +/**************************************************************************** +** +** 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 "DebugMacros.h" + +#include "s60audioencodercontrol.h" +#include "s60audiocapturesession.h" + +#include "qaudioformat.h" + +#include <QtCore/qdebug.h> + +S60AudioEncoderControl::S60AudioEncoderControl(QObject *session, QObject *parent) + :QAudioEncoderControl(parent), m_quality(QtMultimediaKit::NormalQuality) +{ + DP0("S60AudioEncoderControl::S60AudioEncoderControl +++"); + + m_session = qobject_cast<S60AudioCaptureSession*>(session); + QAudioFormat fmt = m_session->format(); + // medium, 22050Hz mono S16 + fmt.setSampleType(QAudioFormat::SignedInt); + if (fmt.codec().compare("PCM", Qt::CaseInsensitive) == 0) { + fmt.setSampleSize(16); + fmt.setFrequency(22050); + } + fmt.setChannels(1); + m_session->setFormat(fmt); + m_settings.setChannelCount(fmt.channels()); + m_settings.setCodec(fmt.codec()); + m_settings.setSampleRate(fmt.sampleRate()); + + DP0("S60AudioEncoderControl::S60AudioEncoderControl ---"); +} + +S60AudioEncoderControl::~S60AudioEncoderControl() +{ + DP0("S60AudioEncoderControl::~S60AudioEncoderControl +++"); + + DP0("S60AudioEncoderControl::~S60AudioEncoderControl ---"); +} + +QStringList S60AudioEncoderControl::supportedAudioCodecs() const +{ + DP0("S60AudioEncoderControl::supportedAudioCodecs"); + + return m_session->supportedAudioCodecs(); +} + +QString S60AudioEncoderControl::codecDescription(const QString &codecName) const +{ + DP0("S60AudioEncoderControl::codecDescription"); + + return m_session->codecDescription(codecName); +} + +QtMultimediaKit::EncodingQuality S60AudioEncoderControl::quality() const +{ + DP0("S60AudioEncoderControl::quality"); + + return m_quality; +} + +void S60AudioEncoderControl::setQuality(QtMultimediaKit::EncodingQuality value, QAudioFormat &fmt) +{ + DP0("S60AudioEncoderControl::setQuality +++"); + + switch (value) { + case QtMultimediaKit::VeryLowQuality: + case QtMultimediaKit::LowQuality: + // low, 8000Hz mono U8 + fmt.setSampleType(QAudioFormat::UnSignedInt); + fmt.setSampleSize(8); + fmt.setFrequency(8000); + fmt.setChannels(1); + break; + case QtMultimediaKit::NormalQuality: + // medium, 22050Hz mono S16 + fmt.setSampleType(QAudioFormat::SignedInt); + fmt.setSampleSize(16); + fmt.setFrequency(22050); + fmt.setChannels(1); + break; + case QtMultimediaKit::HighQuality: + case QtMultimediaKit::VeryHighQuality: + // high, 44100Hz mono S16 + fmt.setSampleType(QAudioFormat::SignedInt); + fmt.setSampleSize(16); + fmt.setFrequency(44100); + fmt.setChannels(2); + break; + default: + break; + } + + DP0("S60AudioEncoderControl::setQuality ---"); +} + +QStringList S60AudioEncoderControl::supportedEncodingOptions(const QString &codec) const +{ + DP0("S60AudioEncoderControl::supportedEncodingOptions"); + + Q_UNUSED(codec) + QStringList list; + if (codec == "PCM") + list << "quality" << "channels" << "samplerate"; + return list; +} + +QVariant S60AudioEncoderControl::encodingOption(const QString &codec, const QString &name) const +{ + DP0("S60AudioEncoderControl::encodingOption"); + + if (codec == "PCM") { + QAudioFormat fmt = m_session->format(); + + if(qstrcmp(name.toLocal8Bit().constData(), "quality") == 0) { + return QVariant(quality()); + } + else if(qstrcmp(name.toLocal8Bit().constData(), "channels") == 0) { + return QVariant(fmt.channels()); + } + else if(qstrcmp(name.toLocal8Bit().constData(), "samplerate") == 0) { + return QVariant(fmt.frequency()); + } + } + return QVariant(); +} + +void S60AudioEncoderControl::setEncodingOption( + const QString &codec, const QString &name, const QVariant &value) +{ + DP0("S60AudioEncoderControl::setEncodingOption +++"); + + if (codec == "PCM") { + QAudioFormat fmt = m_session->format(); + + if(qstrcmp(name.toLocal8Bit().constData(), "quality") == 0) { + setQuality((QtMultimediaKit::EncodingQuality)value.toInt(), fmt); + } else if(qstrcmp(name.toLocal8Bit().constData(), "channels") == 0) { + fmt.setChannels(value.toInt()); + } else if(qstrcmp(name.toLocal8Bit().constData(), "samplerate") == 0) { + fmt.setFrequency(value.toInt()); + } + m_session->setFormat(fmt); + } + + DP0("S60AudioEncoderControl::setEncodingOption ---"); +} + +QList<int> S60AudioEncoderControl::supportedSampleRates(const QAudioEncoderSettings &settings, bool *continuous) const +{ + DP0("S60AudioEncoderControl::supportedSampleRates"); + + if (continuous) + *continuous = false; + + return m_session->supportedAudioSampleRates(settings); +} + +QAudioEncoderSettings S60AudioEncoderControl::audioSettings() const +{ + DP0("S60AudioEncoderControl::audioSettings"); + + return m_settings; +} + +void S60AudioEncoderControl::setAudioSettings(const QAudioEncoderSettings &settings) +{ + DP0("S60AudioEncoderControl::setAudioSettings +++"); + + QAudioFormat fmt = m_session->format(); + if (settings.encodingMode() == QtMultimediaKit::ConstantQualityEncoding) { + fmt.setCodec(settings.codec()); + setQuality(settings.quality(), fmt); + if (settings.sampleRate() > 0) { + fmt.setFrequency(settings.sampleRate()); + } + if (settings.channelCount() > 0) + fmt.setChannels(settings.channelCount()); + }else { + if (settings.sampleRate() == 8000) { + fmt.setSampleType(QAudioFormat::UnSignedInt); + fmt.setSampleSize(8); + } else { + fmt.setSampleType(QAudioFormat::SignedInt); + fmt.setSampleSize(16); + } + fmt.setCodec(settings.codec()); + fmt.setFrequency(settings.sampleRate()); + fmt.setChannels(settings.channelCount()); + } + m_session->setFormat(fmt); + m_session->setEncoderSettings(settings); + m_settings = settings; + + DP0("S60AudioEncoderControl::setAudioSettings ---"); +} diff --git a/src/plugins/symbian/mmf/audiosource/s60audioencodercontrol.h b/src/plugins/symbian/mmf/audiosource/s60audioencodercontrol.h new file mode 100644 index 000000000..236d7d522 --- /dev/null +++ b/src/plugins/symbian/mmf/audiosource/s60audioencodercontrol.h @@ -0,0 +1,82 @@ +/**************************************************************************** +** +** 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$ +** +****************************************************************************/ + +#ifndef AUDIOENCODERCONTROL_H +#define AUDIOENCODERCONTROL_H + +#include <qaudioencodercontrol.h> +#include <QtCore/qstringlist.h> +#include "qaudioformat.h" + +QT_USE_NAMESPACE + +class S60AudioCaptureSession; + +class S60AudioEncoderControl : public QAudioEncoderControl +{ + Q_OBJECT +public: + S60AudioEncoderControl(QObject *session, QObject *parent = 0); + virtual ~S60AudioEncoderControl(); + + QStringList supportedAudioCodecs() const; + QString codecDescription(const QString &codecName) const; + + QList<int> supportedSampleRates(const QAudioEncoderSettings &settings, bool *continuous = 0) const; + + QAudioEncoderSettings audioSettings() const; + void setAudioSettings(const QAudioEncoderSettings&); + + QStringList supportedEncodingOptions(const QString &codec) const; + QVariant encodingOption(const QString &codec, const QString &name) const; + void setEncodingOption(const QString &codec, const QString &name, const QVariant &value); + +private: + QtMultimediaKit::EncodingQuality quality() const; + void setQuality(QtMultimediaKit::EncodingQuality, QAudioFormat &format); + +private: + S60AudioCaptureSession* m_session; + QAudioEncoderSettings m_settings; + QtMultimediaKit::EncodingQuality m_quality; +}; + +#endif diff --git a/src/plugins/symbian/mmf/audiosource/s60audioendpointselector.cpp b/src/plugins/symbian/mmf/audiosource/s60audioendpointselector.cpp new file mode 100644 index 000000000..a2f909316 --- /dev/null +++ b/src/plugins/symbian/mmf/audiosource/s60audioendpointselector.cpp @@ -0,0 +1,100 @@ +/**************************************************************************** +** +** 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 "DebugMacros.h" + +#include "s60audiocapturesession.h" +#include "s60audioendpointselector.h" + +#include <qaudiodeviceinfo.h> + +S60AudioEndpointSelector::S60AudioEndpointSelector(QObject *session, QObject *parent) + :QAudioEndpointSelector(parent) +{ + DP0("S60AudioEndpointSelector::S60AudioEndpointSelector +++"); + m_session = qobject_cast<S60AudioCaptureSession*>(session); + + connect(m_session, SIGNAL(activeEndpointChanged(const QString &)), this, SIGNAL(activeEndpointChanged(const QString &))); + + DP0("S60AudioEndpointSelector::S60AudioEndpointSelector ---"); +} + +S60AudioEndpointSelector::~S60AudioEndpointSelector() +{ + DP0("S60AudioEndpointSelector::~S60AudioEndpointSelector +++"); + + DP0("S60AudioEndpointSelector::~S60AudioEndpointSelector ---"); +} + +QList<QString> S60AudioEndpointSelector::availableEndpoints() const +{ + DP0("S60AudioEndpointSelector::availableEndpoints"); + + return m_session->availableEndpoints(); +} + +QString S60AudioEndpointSelector::endpointDescription(const QString& name) const +{ + DP0("S60AudioEndpointSelector::endpointDescription"); + + return m_session->endpointDescription(name); +} + +QString S60AudioEndpointSelector::defaultEndpoint() const +{ + DP0("S60AudioEndpointSelector::defaultEndpoint"); + + return m_session->defaultEndpoint(); +} + +QString S60AudioEndpointSelector::activeEndpoint() const +{ + DP0("S60AudioEndpointSelector::activeEndpoint"); + + return m_session->activeEndpoint(); +} + +void S60AudioEndpointSelector::setActiveEndpoint(const QString& name) +{ + DP0("S60AudioEndpointSelector::setActiveEndpoint +++"); + m_session->setActiveEndpoint(name); + DP0("S60AudioEndpointSelector::setActiveEndpoint ---"); +} diff --git a/src/plugins/symbian/mmf/audiosource/s60audioendpointselector.h b/src/plugins/symbian/mmf/audiosource/s60audioendpointselector.h new file mode 100644 index 000000000..d89ce8765 --- /dev/null +++ b/src/plugins/symbian/mmf/audiosource/s60audioendpointselector.h @@ -0,0 +1,76 @@ +/**************************************************************************** +** +** 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$ +** +****************************************************************************/ + +#ifndef S60AUDIOENDPOINTSELECTOR_H +#define S60AUDIOENDPOINTSELECTOR_H + +#include <QStringList> + +#include <qaudioendpointselector.h> + +QT_USE_NAMESPACE + +class S60AudioCaptureSession; + +class S60AudioEndpointSelector : public QAudioEndpointSelector +{ + +Q_OBJECT + +public: + S60AudioEndpointSelector(QObject *session, QObject *parent = 0); + ~S60AudioEndpointSelector(); + + QList<QString> availableEndpoints() const; + QString endpointDescription(const QString& name) const; + QString defaultEndpoint() const; + QString activeEndpoint() const; + + +public Q_SLOTS: + void setActiveEndpoint(const QString& name); + +private: + + S60AudioCaptureSession* m_session; +}; + +#endif // S60AUDIOENDPOINTSELECTOR_H diff --git a/src/plugins/symbian/mmf/audiosource/s60audiomediarecordercontrol.cpp b/src/plugins/symbian/mmf/audiosource/s60audiomediarecordercontrol.cpp new file mode 100644 index 000000000..5d80033b3 --- /dev/null +++ b/src/plugins/symbian/mmf/audiosource/s60audiomediarecordercontrol.cpp @@ -0,0 +1,180 @@ +/**************************************************************************** +** +** 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 "DebugMacros.h" + +#include "s60audiomediarecordercontrol.h" +#include "s60audiocapturesession.h" + +#include <QtCore/qdebug.h> + +S60AudioMediaRecorderControl::S60AudioMediaRecorderControl(QObject *session, QObject *parent) + :QMediaRecorderControl(parent), m_state(QMediaRecorder::StoppedState) +{ + DP0("S60AudioMediaRecorderControl::S60AudioMediaRecorderControl +++"); + + m_session = qobject_cast<S60AudioCaptureSession*>(session); + connect(m_session, SIGNAL(positionChanged(qint64)), this, SIGNAL(durationChanged(qint64))); + connect(m_session, SIGNAL(stateChanged(S60AudioCaptureSession::TAudioCaptureState)), this, SLOT(updateState(S60AudioCaptureSession::TAudioCaptureState))); + connect(m_session,SIGNAL(error(int,const QString &)),this,SIGNAL(error(int,const QString &))); + + DP0("S60AudioMediaRecorderControl::S60AudioMediaRecorderControl ---"); +} + +S60AudioMediaRecorderControl::~S60AudioMediaRecorderControl() +{ + DP0("S60AudioMediaRecorderControl::~S60AudioMediaRecorderControl +++"); + + DP0("S60AudioMediaRecorderControl::~S60AudioMediaRecorderControl - - "); +} + +QUrl S60AudioMediaRecorderControl::outputLocation() const +{ + DP0("S60AudioMediaRecorderControl::outputLocation"); + + return m_session->outputLocation(); +} + +bool S60AudioMediaRecorderControl::setOutputLocation(const QUrl& sink) +{ + DP0("S60AudioMediaRecorderControl::setOutputLocation"); + + return m_session->setOutputLocation(sink); +} + +QMediaRecorder::State S60AudioMediaRecorderControl::convertState(S60AudioCaptureSession::TAudioCaptureState aState) const +{ + DP0("S60AudioMediaRecorderControl::convertState +++"); + + QMediaRecorder::State state = QMediaRecorder::StoppedState;; + switch (aState) { + case S60AudioCaptureSession::ERecording: + state = QMediaRecorder::RecordingState; + break; + case S60AudioCaptureSession::EPaused: + state = QMediaRecorder::PausedState; + break; + case S60AudioCaptureSession::ERecordComplete: + case S60AudioCaptureSession::ENotInitialized: + case S60AudioCaptureSession::EOpenCompelete: + case S60AudioCaptureSession::EInitialized: + state = QMediaRecorder::StoppedState; + break; + } + + DP1("S60AudioMediaRecorderControl::convertState:", state); + + DP0("S60AudioMediaRecorderControl::convertState ---"); + + return state; +} + +void S60AudioMediaRecorderControl::updateState(S60AudioCaptureSession::TAudioCaptureState aState) +{ + DP0("S60AudioMediaRecorderControl::updateState +++"); + + QMediaRecorder::State newState = convertState(aState); + if (m_state != newState) { + m_state = newState; + emit stateChanged(m_state); + } + + DP0("S60AudioMediaRecorderControl::updateState ---"); +} + +QMediaRecorder::State S60AudioMediaRecorderControl::state() const +{ + DP0("S60AudioMediaRecorderControl::state"); + + return m_state; +} + +qint64 S60AudioMediaRecorderControl::duration() const +{ + // DP0("S60AudioMediaRecorderControl::duration +++"); + + return m_session->position(); +} + +void S60AudioMediaRecorderControl::record() +{ + DP0("S60AudioMediaRecorderControl::record +++"); + + m_session->record(); + + DP0("S60AudioMediaRecorderControl::record ---"); +} + +void S60AudioMediaRecorderControl::pause() +{ + DP0("S60AudioMediaRecorderControl::pause +++"); + + m_session->pause(); + + DP0("S60AudioMediaRecorderControl::pause ---"); +} + +void S60AudioMediaRecorderControl::stop() +{ + DP0("S60AudioMediaRecorderControl::stop +++"); + + m_session->stop(); + + DP0("S60AudioMediaRecorderControl::stop ---"); +} + +bool S60AudioMediaRecorderControl::isMuted() const +{ + DP0("S60AudioMediaRecorderControl::isMuted"); + + return m_session->muted(); +} + +void S60AudioMediaRecorderControl::setMuted(bool muted) +{ + DP0("S60AudioMediaRecorderControl::setMuted +++"); + + DP1("S60AudioMediaRecorderControl::setMuted:", muted); + + m_session->mute(muted); + + DP0("S60AudioMediaRecorderControl::setMuted +++"); +} diff --git a/src/plugins/symbian/mmf/audiosource/s60audiomediarecordercontrol.h b/src/plugins/symbian/mmf/audiosource/s60audiomediarecordercontrol.h new file mode 100644 index 000000000..78e8f4870 --- /dev/null +++ b/src/plugins/symbian/mmf/audiosource/s60audiomediarecordercontrol.h @@ -0,0 +1,92 @@ +/**************************************************************************** +** +** 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$ +** +****************************************************************************/ + +#ifndef S60AUDIOMEDIARECORDERCONTROL_H +#define S60AUDIOMEDIARECORDERCONTROL_H + +#include <QtCore/qobject.h> +#include <QUrl> + +#include "qmediarecorder.h" +#include "qmediarecordercontrol.h" + +#include "s60audiocapturesession.h" + +QT_USE_NAMESPACE + +//class S60AudioCaptureSession; + +class S60AudioMediaRecorderControl : public QMediaRecorderControl +{ + Q_OBJECT +public: + S60AudioMediaRecorderControl(QObject *session,QObject *parent = 0); + ~S60AudioMediaRecorderControl(); + + QUrl outputLocation() const; + bool setOutputLocation(const QUrl &sink); + + QMediaRecorder::State state() const; + + qint64 duration() const; + + bool isMuted() const; + + void applySettings() {} + +private: + QMediaRecorder::State convertState(S60AudioCaptureSession::TAudioCaptureState aState) const; + +public slots: + void record(); + void pause(); + void stop(); + void setMuted(bool); + +private slots: + void updateState(S60AudioCaptureSession::TAudioCaptureState aState); + +private: + S60AudioCaptureSession* m_session; + QMediaRecorder::State m_state; +}; + +#endif diff --git a/src/plugins/symbian/mmf/inc/DebugMacros.h b/src/plugins/symbian/mmf/inc/DebugMacros.h new file mode 100644 index 000000000..449bef088 --- /dev/null +++ b/src/plugins/symbian/mmf/inc/DebugMacros.h @@ -0,0 +1,66 @@ +/**************************************************************************** +** +** Copyright (C) 2011 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 <QtCore/qdebug.h> + +#ifndef __DEBUGMACROS_H__ +#define __DEBUGMACROS_H__ + +// MACROS +#ifdef _DEBUG +#define DP0(string) qDebug()<<string +#define DP1(string,arg1) qDebug()<<string<<arg1 +#define DP2(string,arg1,arg2) qDebug()<<string<<arg1<<arg2 +#define DP3(string,arg1,arg2,arg3) qDebug()<<string<<arg1<<arg2<<arg3 +#define DP4(string,arg1,arg2,arg3,arg4) qDebug()<<string<<arg1<<arg2<<arg3<<arg4 +#define DP5(string,arg1,arg2,arg3,arg4,arg5) qDebug()<<string<<arg1<<arg2<<arg3<<arg4<<arg5 +#define DP6(string,arg1,arg2,arg3,arg4,arg5,arg6) qDebug()<<string<<arg1<<arg2<<arg3<<arg4<<arg5<<arg6 +#else +#define DP0(string) +#define DP1(string,arg1) +#define DP2(string,arg1,arg2) +#define DP3(string,arg1,arg2,arg3) +#define DP4(string,arg1,arg2,arg3,arg4) +#define DP5(string,arg1,arg2,arg3,arg4,arg5) +#define DP6(string,arg1,arg2,arg3,arg4,arg5,arg6) +#endif + +#endif //__DEBUGMACROS_H__ diff --git a/src/plugins/symbian/mmf/mediaplayer/mediaplayer_s60.pri b/src/plugins/symbian/mmf/mediaplayer/mediaplayer_s60.pri new file mode 100644 index 000000000..6ec64e2b6 --- /dev/null +++ b/src/plugins/symbian/mmf/mediaplayer/mediaplayer_s60.pri @@ -0,0 +1,92 @@ +INCLUDEPATH += $$PWD + +include (../../videooutput/videooutput.pri) + +LIBS *= -lmediaclientvideo \ + -lmediaclientaudio \ + -lws32 \ + -lfbscli \ + -lcone \ + -lmmfcontrollerframework \ + -lefsrv \ + -lbitgdi \ + -lapgrfx \ + -lapmime \ + -lcommdb \ + -lbafl + +# If support to DRM is wanted then comment out the following line +#CONFIG += drm_supported + +# We are building Symbian backend with media player support +DEFINES += HAS_MEDIA_PLAYER +# We are building media player with QVideoRendererControl support +#DEFINES += HAS_VIDEORENDERERCONTROL_IN_VIDEOPLAYER + +drm_supported { + LIBS += -ldrmaudioplayutility + DEFINES += S60_DRM_SUPPORTED +} + +HEADERS += \ + $$PWD/s60mediaplayercontrol.h \ + $$PWD/s60mediaplayerservice.h \ + $$PWD/s60mediaplayersession.h \ + $$PWD/s60mediametadataprovider.h \ + $$PWD/s60videoplayersession.h \ + $$PWD/s60videosurface.h \ + $$PWD/s60mediarecognizer.h \ + $$PWD/s60audioplayersession.h \ + $$PWD/ms60mediaplayerresolver.h \ + $$PWD/s60mediaplayeraudioendpointselector.h \ + $$PWD/s60mediastreamcontrol.h \ + $$PWD/s60medianetworkaccesscontrol.h + +SOURCES += \ + $$PWD/s60mediaplayercontrol.cpp \ + $$PWD/s60mediaplayerservice.cpp \ + $$PWD/s60mediaplayersession.cpp \ + $$PWD/s60mediametadataprovider.cpp \ + $$PWD/s60videoplayersession.cpp \ + $$PWD/s60videosurface.cpp \ + $$PWD/s60mediarecognizer.cpp \ + $$PWD/s60audioplayersession.cpp \ + $$PWD/s60mediaplayeraudioendpointselector.cpp \ + $$PWD/s60mediastreamcontrol.cpp \ + $$PWD/s60medianetworkaccesscontrol.cpp + +contains(DEFINES, HAS_VIDEORENDERERCONTROL_IN_VIDEOPLAYER) { + HEADERS += $$PWD/s60videorenderer.h + SOURCES += $$PWD/s60videorenderer.cpp +} + +contains(S60_VERSION, 3.1) { + #3.1 doesn't provide audio routing in videoplayer + contains(audiorouting_s60_enabled,yes) { + MMP_RULES += "$${LITERAL_HASH}ifndef WINSCW" \ + "MACRO HAS_AUDIOROUTING" \ + "LIBRARY audiooutputrouting.lib" \ + "$${LITERAL_HASH}endif" + message("Note: AudioOutput Routing API not supported for 3.1 winscw target and in videoplayer") + } + +} else { + contains(audiorouting_s60_enabled,yes) { + #We use audiooutputrouting.lib for directing audio output to speaker/earspeaker + DEFINES += HAS_AUDIOROUTING_IN_VIDEOPLAYER + DEFINES += HAS_AUDIOROUTING + message("Audiorouting_s60 enabled for post 3.1 sdk") + LIBS += -laudiooutputrouting + } + +} + +contains(S60_VERSION, 3.1) { + DEFINES += PLAY_RATE_NOT_SUPPORTED + message("S60 version 3.1 does not support setplaybackrate") +} +contains(S60_VERSION, 3.2) { + DEFINES += PLAY_RATE_NOT_SUPPORTED + message("S60 version 3.2 does not support setplaybackrate") +} + diff --git a/src/plugins/symbian/mmf/mediaplayer/ms60mediaplayerresolver.h b/src/plugins/symbian/mmf/mediaplayer/ms60mediaplayerresolver.h new file mode 100644 index 000000000..d836dae3e --- /dev/null +++ b/src/plugins/symbian/mmf/mediaplayer/ms60mediaplayerresolver.h @@ -0,0 +1,54 @@ +/**************************************************************************** +** +** 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$ +** +****************************************************************************/ +#ifndef MS60MEDIAPLAYERRESOLVER_H +#define MS60MEDIAPLAYERRESOLVER_H + +class S60MediaPlayerSession; + +class MS60MediaPlayerResolver +{ + public: + virtual S60MediaPlayerSession* PlayerSession() = 0; + virtual S60MediaPlayerSession* VideoPlayerSession() = 0; + virtual S60MediaPlayerSession* AudioPlayerSession() = 0; +}; + +#endif diff --git a/src/plugins/symbian/mmf/mediaplayer/s60audioplayersession.cpp b/src/plugins/symbian/mmf/mediaplayer/s60audioplayersession.cpp new file mode 100644 index 000000000..3a5386ce1 --- /dev/null +++ b/src/plugins/symbian/mmf/mediaplayer/s60audioplayersession.cpp @@ -0,0 +1,577 @@ +/**************************************************************************** +** +** 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 "DebugMacros.h" + +#include "s60audioplayersession.h" +#include <QtCore/qdebug.h> +#include <QtCore/qvariant.h> + +/*! + Constructs the CMdaAudioPlayerUtility object with given \a parent QObject. + + And Registers for Audio Loading Notifications. + +*/ + +S60AudioPlayerSession::S60AudioPlayerSession(QObject *parent) + : S60MediaPlayerSession(parent) + , m_player(0) + , m_audioEndpoint("Default") +{ + DP0("S60AudioPlayerSession::S60AudioPlayerSession +++"); + +#ifdef HAS_AUDIOROUTING + m_audioOutput = 0; +#endif //HAS_AUDIOROUTING + QT_TRAP_THROWING(m_player = CAudioPlayer::NewL(*this, 0, EMdaPriorityPreferenceNone)); + m_player->RegisterForAudioLoadingNotification(*this); + + DP0("S60AudioPlayerSession::S60AudioPlayerSession ---"); +} + + +/*! + Destroys the CMdaAudioPlayerUtility object. + + And Unregister the observer. + +*/ + +S60AudioPlayerSession::~S60AudioPlayerSession() +{ + DP0("S60AudioPlayerSession::~S60AudioPlayerSession +++"); +#ifdef HAS_AUDIOROUTING + if (m_audioOutput) + m_audioOutput->UnregisterObserver(*this); + delete m_audioOutput; +#endif + m_player->Close(); + delete m_player; + + DP0("S60AudioPlayerSession::~S60AudioPlayerSession ---"); +} + +/*! + + Opens the a file from \a path. + +*/ + +void S60AudioPlayerSession::doLoadL(const TDesC &path) +{ + DP0("S60AudioPlayerSession::doLoadL +++"); + +#ifdef HAS_AUDIOROUTING + // m_audioOutput needs to be reinitialized after MapcInitComplete + if (m_audioOutput) + m_audioOutput->UnregisterObserver(*this); + delete m_audioOutput; + m_audioOutput = NULL; +#endif //HAS_AUDIOROUTING + m_player->OpenFileL(path); + + DP0("S60AudioPlayerSession::doLoadL ---"); +} + +/*! + + Returns the duration of the audio sample in microseconds. + +*/ + +qint64 S60AudioPlayerSession::doGetDurationL() const +{ + // DP0("S60AudioPlayerSession::doGetDurationL"); + + return m_player->Duration().Int64() / qint64(1000); +} + +/*! + * Returns the current playback position in microseconds from the start of the clip. + +*/ + +qint64 S60AudioPlayerSession::doGetPositionL() const +{ + // DP0("S60AudioPlayerSession::doGetPositionL"); + + TTimeIntervalMicroSeconds ms = 0; + m_player->GetPosition(ms); + return ms.Int64() / qint64(1000); +} + +/*! + Returns TRUE if Video available or else FALSE + */ + +bool S60AudioPlayerSession::isVideoAvailable() +{ + DP0("S60AudioPlayerSession::isVideoAvailable"); + + return false; +} + +/*! + Returns TRUE if Audio available or else FALSE + */ +bool S60AudioPlayerSession::isAudioAvailable() +{ + DP0("S60AudioPlayerSession::isAudioAvailable"); + + return true; // this is a bit happy scenario, but we do emit error that we can't play +} + +/*! + Starts loading Media and sets media status to Buffering. + + */ + +void S60AudioPlayerSession::MaloLoadingStarted() +{ + DP0("S60AudioPlayerSession::MaloLoadingStarted +++"); + + buffering(); + + DP0("S60AudioPlayerSession::MaloLoadingStarted ---"); +} + + +/*! + Indicates loading Media is completed. + + And sets media status to Buffered. + + */ + +void S60AudioPlayerSession::MaloLoadingComplete() +{ + DP0("S60AudioPlayerSession::MaloLoadingComplete +++"); + + buffered(); + + DP0("S60AudioPlayerSession::MaloLoadingComplete ---"); +} + +/*! + Start or resume playing the current source. +*/ + +void S60AudioPlayerSession::doPlay() +{ + DP0("S60AudioPlayerSession::doPlay +++"); + + // For some reason loading progress callback are not called on emulator + // Same is the case with hardware. Will be fixed as part of QTMOBILITY-782. + + //#ifdef __WINSCW__ + buffering(); + //#endif + m_player->Play(); + //#ifdef __WINSCW__ + buffered(); + //#endif + + DP0("S60AudioPlayerSession::doPlay ---"); +} + + +/*! + Pause playing the current source. +*/ + + +void S60AudioPlayerSession::doPauseL() +{ + DP0("S60AudioPlayerSession::doPauseL +++"); + + m_player->Pause(); + + DP0("S60AudioPlayerSession::doPauseL ---"); +} + + +/*! + + Stop playing, and reset the play position to the beginning. +*/ + +void S60AudioPlayerSession::doStop() +{ + DP0("S60AudioPlayerSession::doStop +++"); + + m_player->Stop(); + + DP0("S60AudioPlayerSession::doStop ---"); +} + +/*! + Closes the current audio clip (allowing another clip to be opened) +*/ + +void S60AudioPlayerSession::doClose() +{ + DP0("S60AudioPlayerSession::doClose +++"); + +#ifdef HAS_AUDIOROUTING + if (m_audioOutput) { + m_audioOutput->UnregisterObserver(*this); + delete m_audioOutput; + m_audioOutput = NULL; + } +#endif + m_player->Close(); + + DP0("S60AudioPlayerSession::doClose ---"); +} + +/*! + + Changes the current playback volume to specified \a value. +*/ + +void S60AudioPlayerSession::doSetVolumeL(int volume) +{ + DP0("S60AudioPlayerSession::doSetVolumeL +++"); + + DP1("S60AudioPlayerSession::doSetVolumeL, Volume:", volume); + + m_player->SetVolume(volume * m_player->MaxVolume() / 100); + + DP0("S60AudioPlayerSession::doSetVolumeL ---"); +} + +/*! + Sets the current playback position to \a microSeconds from the start of the clip. +*/ + +void S60AudioPlayerSession::doSetPositionL(qint64 microSeconds) +{ + DP0("S60AudioPlayerSession::doSetPositionL +++"); + + DP1("S60AudioPlayerSession::doSetPositionL, Microseconds:", microSeconds); + + m_player->SetPosition(TTimeIntervalMicroSeconds(microSeconds)); + + DP0("S60AudioPlayerSession::doSetPositionL ---"); +} + +/*! + + Updates meta data entries in the current audio clip. +*/ + +void S60AudioPlayerSession::updateMetaDataEntriesL() +{ + DP0("S60AudioPlayerSession::updateMetaDataEntriesL +++"); + + metaDataEntries().clear(); + int numberOfMetaDataEntries = 0; + + //User::LeaveIfError(m_player->GetNumberOfMetaDataEntries(numberOfMetaDataEntries)); + m_player->GetNumberOfMetaDataEntries(numberOfMetaDataEntries); + + for (int i = 0; i < numberOfMetaDataEntries; i++) { + CMMFMetaDataEntry *entry = NULL; + entry = m_player->GetMetaDataEntryL(i); + metaDataEntries().insert(QString::fromUtf16(entry->Name().Ptr(), entry->Name().Length()), QString::fromUtf16(entry->Value().Ptr(), entry->Value().Length())); + delete entry; + } + emit metaDataChanged(); + + DP0("S60AudioPlayerSession::updateMetaDataEntriesL ---"); +} + +/*! + Sets the playbackRate with \a rate. +*/ + +void S60AudioPlayerSession::setPlaybackRate(qreal rate) +{ + DP0("S60AudioPlayerSession::setPlaybackRate +++"); + DP1("S60AudioPlayerSession::setPlaybackRate, Rate:", rate); + /*Since AudioPlayerUtility doesn't support set playback rate hence + * setPlaybackRate emits playbackRateChanged signal for 1.0x ie normal playback. + * For all other playBackRates it sets and emits error signal. + */ + if (rate == 1.0) { + emit playbackRateChanged(rate); + return; + } else { + int err = KErrNotSupported; + setAndEmitError(err); + } + DP0("S60AudioPlayerSession::setPlaybackRate ---"); +} + +/*! + + Returns the percentage of the audio clip loaded. +*/ + +int S60AudioPlayerSession::doGetBufferStatusL() const +{ + DP0("S60AudioPlayerSession::doGetBufferStatusL +++"); + + int progress = 0; + m_player->GetAudioLoadingProgressL(progress); + + DP0("S60AudioPlayerSession::doGetBufferStatusL ---"); + + return progress; +} + +/*! + + Defines required client behaviour when an attempt to open and initialise an audio sample has completed, + successfully or not. + + \a aError if KErrNone the sample is ready to play or else system wide error. + + \a aDuration The duration of the audio sample. +*/ + +#ifdef S60_DRM_SUPPORTED +void S60AudioPlayerSession::MdapcInitComplete(TInt aError, const TTimeIntervalMicroSeconds& aDuration) +#else +void S60AudioPlayerSession::MapcInitComplete(TInt aError, const TTimeIntervalMicroSeconds& aDuration) +#endif +{ + DP0("S60AudioPlayerSession::MdapcInitComplete +++"); + + DP1("S60AudioPlayerSession::MdapcInitComplete - aError", aError); + + Q_UNUSED(aDuration); + setError(aError); + if (KErrNone != aError) + return; +#ifdef HAS_AUDIOROUTING + TRAPD(err, + m_audioOutput = CAudioOutput::NewL(*m_player); + m_audioOutput->RegisterObserverL(*this); + ); + setActiveEndpoint(m_audioEndpoint); + setError(err); +#endif //HAS_AUDIOROUTING + if (KErrNone == aError) + loaded(); + + DP0("S60AudioPlayerSession::MdapcInitComplete ---"); +} + +/*! + Defines required client behaviour when an attempt to playback an audio sample has completed, + successfully or not. + + \a aError if KErrNone the playback completed or else system wide error. +*/ + + +#ifdef S60_DRM_SUPPORTED +void S60AudioPlayerSession::MdapcPlayComplete(TInt aError) +#else +void S60AudioPlayerSession::MapcPlayComplete(TInt aError) +#endif +{ + DP0("S60AudioPlayerSession::MdapcPlayComplete +++"); + + DP1("S60AudioPlayerSession::MdapcPlayComplete", aError); + + if (KErrNone == aError) + endOfMedia(); + else + setError(aError); + + DP0("S60AudioPlayerSession::MdapcPlayComplete ---"); +} + +/*! + Defiens which Audio End point to use. + + \a audioEndpoint audioEndpoint name. +*/ + +void S60AudioPlayerSession::doSetAudioEndpoint(const QString& audioEndpoint) +{ + DP0("S60AudioPlayerSession::doSetAudioEndpoint +++"); + + DP1("S60AudioPlayerSession::doSetAudioEndpoint - ", audioEndpoint); + + m_audioEndpoint = audioEndpoint; + + DP0("S60AudioPlayerSession::doSetAudioEndpoint ---"); +} + +/*! + + Returns audioEndpoint name. +*/ + +QString S60AudioPlayerSession::activeEndpoint() const +{ + DP0("S60AudioPlayerSession::activeEndpoint +++"); + + QString outputName = QString("Default"); +#ifdef HAS_AUDIOROUTING + if (m_audioOutput) { + CAudioOutput::TAudioOutputPreference output = m_audioOutput->AudioOutput(); + outputName = qStringFromTAudioOutputPreference(output); + } +#endif + DP1("S60AudioPlayerSession::activeEndpoint is :", outputName); + + DP0("S60AudioPlayerSession::activeEndpoint ---"); + return outputName; +} + +/*! + * Returns default Audio End point in use. +*/ + +QString S60AudioPlayerSession::defaultEndpoint() const +{ + DP0("S60AudioPlayerSession::defaultEndpoint +++"); + + QString outputName = QString("Default"); +#ifdef HAS_AUDIOROUTING + if (m_audioOutput) { + CAudioOutput::TAudioOutputPreference output = m_audioOutput->DefaultAudioOutput(); + outputName = qStringFromTAudioOutputPreference(output); + } +#endif + DP1("S60AudioPlayerSession::defaultEndpoint is :", outputName); + + DP0("S60AudioPlayerSession::defaultEndpoint ---"); + return outputName; +} + +/*! + Sets active end \a name as an Audio End point. +*/ + +void S60AudioPlayerSession::setActiveEndpoint(const QString& name) +{ + DP0("S60AudioPlayerSession::setActiveEndpoint +++"); + + DP1("S60AudioPlayerSession::setActiveEndpoint - ", name); + +#ifdef HAS_AUDIOROUTING + CAudioOutput::TAudioOutputPreference output = CAudioOutput::ENoPreference; + + if (name == QString("Default")) + output = CAudioOutput::ENoPreference; + else if (name == QString("All")) + output = CAudioOutput::EAll; + else if (name == QString("None")) + output = CAudioOutput::ENoOutput; + else if (name == QString("Earphone")) + output = CAudioOutput::EPrivate; + else if (name == QString("Speaker")) + output = CAudioOutput::EPublic; + + if (m_audioOutput) { + TRAPD(err, m_audioOutput->SetAudioOutputL(output)); + setError(err); + } +#endif + + DP0("S60AudioPlayerSession::setActiveEndpoint ---"); +} + +/*! + The default audio output has been changed. + + \a aAudioOutput Audio Output object. + + \a aNewDefault is CAudioOutput::TAudioOutputPreference. +*/ + + +#ifdef HAS_AUDIOROUTING +void S60AudioPlayerSession::DefaultAudioOutputChanged(CAudioOutput& aAudioOutput, + CAudioOutput::TAudioOutputPreference aNewDefault) +{ + DP0("S60AudioPlayerSession::DefaultAudioOutputChanged +++"); + + // Emit already implemented in setActiveEndpoint function + Q_UNUSED(aAudioOutput) + Q_UNUSED(aNewDefault) + + DP0("S60AudioPlayerSession::DefaultAudioOutputChanged ---"); +} + + +/*! + Converts CAudioOutput::TAudioOutputPreference enum to QString. + + \a output is CAudioOutput::TAudioOutputPreference enum value. + +*/ + +QString S60AudioPlayerSession::qStringFromTAudioOutputPreference(CAudioOutput::TAudioOutputPreference output) const +{ + DP0("S60AudioPlayerSession::qStringFromTAudioOutputPreference"); + + if (output == CAudioOutput::ENoPreference) + return QString("Default"); + else if (output == CAudioOutput::EAll) + return QString("All"); + else if (output == CAudioOutput::ENoOutput) + return QString("None"); + else if (output == CAudioOutput::EPrivate) + return QString("Earphone"); + else if (output == CAudioOutput::EPublic) + return QString("Speaker"); + return QString("Default"); +} +#endif + +/*! + Return True if its Seekable or else False. +*/ + +bool S60AudioPlayerSession::getIsSeekable() const +{ + DP0("S60AudioPlayerSession::getIsSeekable"); + + return ETrue; +} + diff --git a/src/plugins/symbian/mmf/mediaplayer/s60audioplayersession.h b/src/plugins/symbian/mmf/mediaplayer/s60audioplayersession.h new file mode 100644 index 000000000..80228ef0a --- /dev/null +++ b/src/plugins/symbian/mmf/mediaplayer/s60audioplayersession.h @@ -0,0 +1,136 @@ +/**************************************************************************** +** +** 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$ +** +****************************************************************************/ + +#ifndef S60AUDIOPLAYERSESSION_H +#define S60AUDIOPLAYERSESSION_H + +#include <QtCore/qobject.h> +#include "s60mediaplayersession.h" + +#ifdef S60_DRM_SUPPORTED +#include <drmaudiosampleplayer.h> +typedef CDrmPlayerUtility CAudioPlayer; +typedef MDrmAudioPlayerCallback MAudioPlayerObserver; +#else +#include <mdaaudiosampleplayer.h> +typedef CMdaAudioPlayerUtility CAudioPlayer; +typedef MMdaAudioPlayerCallback MAudioPlayerObserver; +#endif + +#ifdef HAS_AUDIOROUTING +#include <AudioOutput.h> +#include <MAudioOutputObserver.h> +#endif //HAS_AUDIOROUTING + +class S60AudioPlayerSession : public S60MediaPlayerSession + , public MAudioPlayerObserver + , public MAudioLoadingObserver +#ifdef HAS_AUDIOROUTING + , public MAudioOutputObserver +#endif +{ + Q_OBJECT +public: + S60AudioPlayerSession(QObject *parent); + ~S60AudioPlayerSession(); + + //From S60MediaPlayerSession + bool isVideoAvailable(); + bool isAudioAvailable(); + + // From MAudioLoadingObserver + void MaloLoadingStarted(); + void MaloLoadingComplete(); + +#ifdef HAS_AUDIOROUTING + // From MAudioOutputObserver + void DefaultAudioOutputChanged( CAudioOutput& aAudioOutput, + CAudioOutput::TAudioOutputPreference aNewDefault ); +#endif //HAS_AUDIOROUTING + +public: + // From S60MediaPlayerAudioEndpointSelector + QString activeEndpoint() const; + QString defaultEndpoint() const; + void setPlaybackRate(qreal rate); +public Q_SLOTS: + void setActiveEndpoint(const QString& name); + +protected: + //From S60MediaPlayerSession + void doLoadL(const TDesC &path); + void doLoadUrlL(const TDesC &path){Q_UNUSED(path)/*empty implementation*/} + void doPlay(); + void doStop(); + void doClose(); + void doPauseL(); + void doSetVolumeL(int volume); + qint64 doGetPositionL() const; + void doSetPositionL(qint64 microSeconds); + void updateMetaDataEntriesL(); + int doGetBufferStatusL() const; + qint64 doGetDurationL() const; + void doSetAudioEndpoint(const QString& audioEndpoint); + bool getIsSeekable() const; +private: +#ifdef S60_DRM_SUPPORTED + // From MMdaAudioPlayerCallback + void MdapcInitComplete(TInt aError, const TTimeIntervalMicroSeconds& aDuration); + void MdapcPlayComplete(TInt aError); +#else + // From MDrmAudioPlayerCallback + void MapcInitComplete(TInt aError, const TTimeIntervalMicroSeconds& aDuration); + void MapcPlayComplete(TInt aError); +#endif + +#ifdef HAS_AUDIOROUTING + QString qStringFromTAudioOutputPreference(CAudioOutput::TAudioOutputPreference output) const; +#endif //HAS_AUDIOROUTING + +private: + CAudioPlayer *m_player; +#ifdef HAS_AUDIOROUTING + CAudioOutput *m_audioOutput; +#endif //HAS_AUDIOROUTING + QString m_audioEndpoint; +}; + +#endif diff --git a/src/plugins/symbian/mmf/mediaplayer/s60mediametadataprovider.cpp b/src/plugins/symbian/mmf/mediaplayer/s60mediametadataprovider.cpp new file mode 100644 index 000000000..85bfe65a3 --- /dev/null +++ b/src/plugins/symbian/mmf/mediaplayer/s60mediametadataprovider.cpp @@ -0,0 +1,146 @@ +/**************************************************************************** +** +** 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 "DebugMacros.h" + +#include "s60mediametadataprovider.h" +#include "s60mediaplayercontrol.h" +#include "s60mediaplayersession.h" +#include <QtCore/qdebug.h> + +/*! + * Typecasts the \a control object to S60MediaPlayerControl object. +*/ +S60MediaMetaDataProvider::S60MediaMetaDataProvider(QObject *control, QObject *parent) + : QMetaDataReaderControl(parent) + , m_control(NULL) +{ + DP0("S60MediaMetaDataProvider::S60MediaMetaDataProvider +++"); + + m_control = qobject_cast<S60MediaPlayerControl*>(control); + + DP0("S60MediaMetaDataProvider::S60MediaMetaDataProvider ---"); +} + +/*! + * Destructor +*/ + +S60MediaMetaDataProvider::~S60MediaMetaDataProvider() +{ + DP0("S60MediaMetaDataProvider::~S60MediaMetaDataProvider +++"); + DP0("S60MediaMetaDataProvider::~S60MediaMetaDataProvider ---"); +} + +/*! + * Returns TRUE if MetaData is Available or else FALSE. +*/ + +bool S60MediaMetaDataProvider::isMetaDataAvailable() const +{ + DP0("S60MediaMetaDataProvider::isMetaDataAvailable"); + + if (m_control->session()) + return m_control->session()->isMetadataAvailable(); + return false; +} + +/*! + * Always returns FLASE. +*/ +bool S60MediaMetaDataProvider::isWritable() const +{ + DP0("S60MediaMetaDataProvider::isWritable"); + + return false; +} + +/*! + * Returns when \a key meta data is found in metaData. +*/ + +QVariant S60MediaMetaDataProvider::metaData(QtMultimediaKit::MetaData key) const +{ + DP0("S60MediaMetaDataProvider::metaData"); + + if (m_control->session()) + return m_control->session()->metaData(key); + return QVariant(); +} + +/*! + * Returns available metaData. +*/ + +QList<QtMultimediaKit::MetaData> S60MediaMetaDataProvider::availableMetaData() const +{ + DP0("S60MediaMetaDataProvider::availableMetaData"); + + if (m_control->session()) + return m_control->session()->availableMetaData(); + return QList<QtMultimediaKit::MetaData>(); +} + +/*! + * Returns when \a key string is found in extended metaData. +*/ + +QVariant S60MediaMetaDataProvider::extendedMetaData(const QString &key) const +{ + DP0("S60MediaMetaDataProvider::extendedMetaData"); + + if (m_control->session()) + return m_control->session()->metaData(key); + return QVariant(); +} + +/*! + * Returns available Extended MetaData. +*/ + +QStringList S60MediaMetaDataProvider::availableExtendedMetaData() const +{ + DP0("S60MediaMetaDataProvider::availableExtendedMetaData"); + + if (m_control->session()) + return m_control->session()->availableExtendedMetaData(); + return QStringList(); +} diff --git a/src/plugins/symbian/mmf/mediaplayer/s60mediametadataprovider.h b/src/plugins/symbian/mmf/mediaplayer/s60mediametadataprovider.h new file mode 100644 index 000000000..eb995080d --- /dev/null +++ b/src/plugins/symbian/mmf/mediaplayer/s60mediametadataprovider.h @@ -0,0 +1,72 @@ +/**************************************************************************** +** +** 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$ +** +****************************************************************************/ + +#ifndef S60MEDIAMETADATAPROVIDER_H +#define S60MEDIAMETADATAPROVIDER_H + +#include <qmetadatareadercontrol.h> +#include "s60mediaplayercontrol.h" + +QT_USE_NAMESPACE + +class S60MediaPlayerControl; + +class S60MediaMetaDataProvider : public QMetaDataReaderControl +{ + Q_OBJECT + +public: + S60MediaMetaDataProvider(QObject *control, QObject *parent = 0); + ~S60MediaMetaDataProvider(); + + bool isMetaDataAvailable() const; + bool isWritable() const; + + QVariant metaData(QtMultimediaKit::MetaData key) const; + QList<QtMultimediaKit::MetaData> availableMetaData() const; + QVariant extendedMetaData(const QString &key) const ; + QStringList availableExtendedMetaData() const; + +private: + S60MediaPlayerControl *m_control; +}; + +#endif // S60VIDEOMETADATAPROVIDER_H diff --git a/src/plugins/symbian/mmf/mediaplayer/s60medianetworkaccesscontrol.cpp b/src/plugins/symbian/mmf/mediaplayer/s60medianetworkaccesscontrol.cpp new file mode 100644 index 000000000..dad69a691 --- /dev/null +++ b/src/plugins/symbian/mmf/mediaplayer/s60medianetworkaccesscontrol.cpp @@ -0,0 +1,144 @@ +/**************************************************************************** +** +** Copyright (C) 2011 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 "s60medianetworkaccesscontrol.h" + +#define KBuffersize 512 + +S60MediaNetworkAccessControl::S60MediaNetworkAccessControl(QObject *parent) + : QMediaNetworkAccessControl(parent) + , m_iapId(KUseDefaultIap) + , m_currentIndex(0) +{ +} + +void S60MediaNetworkAccessControl::accessPointChanged(int id) +{ + if (!m_IapIdList.isEmpty()) + m_NetworkObject = m_NetworkObjectList.at(m_IapIdList.indexOf(id)); + emit configurationChanged(m_NetworkObject); +} + +S60MediaNetworkAccessControl::~S60MediaNetworkAccessControl() +{ + m_NetworkObjectList.clear(); + m_IapIdList.clear(); +} + +void S60MediaNetworkAccessControl::resetIndex() +{ + m_currentIndex = 0; +} + +void S60MediaNetworkAccessControl::setConfigurations(const QList<QNetworkConfiguration> &configurations) +{ + if (!configurations.isEmpty()) { + m_currentIndex =0; + TRAPD(error, retriveAccesspointIDL(configurations)); + if (error != KErrNone) { + m_NetworkObjectList.clear(); + m_IapIdList.clear(); + } + } +} + +TBool S60MediaNetworkAccessControl::isLastAccessPoint() +{ + if (m_currentIndex == m_NetworkObjectList.size()) + return TRUE; + else + return FALSE; +} + +int S60MediaNetworkAccessControl::accessPointId() +{ + if (m_IapIdList.isEmpty()) + return m_iapId; + + m_iapId = m_IapIdList.at(m_currentIndex); + + if (isLastAccessPoint()) + m_currentIndex = 0; + else + m_currentIndex ++; + + return m_iapId; +} + +QNetworkConfiguration S60MediaNetworkAccessControl::currentConfiguration() const +{ + return m_NetworkObject; +} + +void S60MediaNetworkAccessControl::retriveAccesspointIDL(const QList<QNetworkConfiguration> &configurationList) +{ + m_NetworkObjectList.clear(); + m_IapIdList.clear(); + TBuf<KBuffersize> iapName; + TUint32 iapId; + TInt err; + + // open the IAP communications database + CCommsDatabase* commDB = CCommsDatabase::NewL(); + CleanupStack::PushL(commDB); + + // Open the IAP table + CCommsDbTableView* view = commDB->OpenTableLC(TPtrC(IAP)); + + for (int i=0;i<=configurationList.size()- 1;i++) { + QString accesspointname = configurationList.at(i).name(); + TBuf<KBuffersize> accesspointbuffer(accesspointname.utf16()); + // Point to the first entry + if (view->GotoFirstRecord() == KErrNone) { + do { + view->ReadTextL(TPtrC(COMMDB_NAME), iapName); + view->ReadUintL(TPtrC(COMMDB_ID), iapId); + if (accesspointbuffer == iapName) { + m_NetworkObjectList<<configurationList.at(i); + m_IapIdList<<iapId; + } + // Store name and ID to where you want to + } while (err = view->GotoNextRecord(), err == KErrNone); + } + } + CleanupStack::PopAndDestroy(); // view + CleanupStack::PopAndDestroy(); // commDB +} diff --git a/src/plugins/symbian/mmf/mediaplayer/s60medianetworkaccesscontrol.h b/src/plugins/symbian/mmf/mediaplayer/s60medianetworkaccesscontrol.h new file mode 100644 index 000000000..aea4dcab5 --- /dev/null +++ b/src/plugins/symbian/mmf/mediaplayer/s60medianetworkaccesscontrol.h @@ -0,0 +1,89 @@ +/**************************************************************************** +** +** Copyright (C) 2011 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$ +** +****************************************************************************/ + +#ifndef S60MEDIANETWORKACCESSCONTROL_H_ +#define S60MEDIANETWORKACCESSCONTROL_H_ + + +#include <QtCore/qobject.h> +#include <QtCore/qlist.h> +#include <QtCore/qstring.h> +#include <qmetaobject.h> +#include <QtNetwork/qnetworkconfiguration.h> +#include <commdbconnpref.h> +#include <commdb.h> +#include <mmf/common/mmfcontrollerframeworkbase.h> +#include <qmedianetworkaccesscontrol.h> +#include "s60mediaplayercontrol.h" + +QT_BEGIN_NAMESPACE +class QMediaPlayerControl; +class QMediaNetworkAccessControl; +class QNetworkConfiguration; +QT_END_NAMESPACE + +class S60MediaNetworkAccessControl : public QMediaNetworkAccessControl +{ + Q_OBJECT + +public: + + S60MediaNetworkAccessControl(QObject *parent = 0); + ~S60MediaNetworkAccessControl(); + + virtual void setConfigurations(const QList<QNetworkConfiguration> &configurations); + virtual QNetworkConfiguration currentConfiguration() const; + int accessPointId(); + TBool isLastAccessPoint(); + void resetIndex(); + +public Q_SLOTS: + void accessPointChanged(int); + +private: + void retriveAccesspointIDL(const QList<QNetworkConfiguration> &); + QList<int> m_IapIdList; + QList<QNetworkConfiguration> m_NetworkObjectList; + QNetworkConfiguration m_NetworkObject; + int m_iapId; + int m_currentIndex; +}; +#endif /* S60MEDIANETWORKACCESSCONTROL_H_ */ diff --git a/src/plugins/symbian/mmf/mediaplayer/s60mediaplayeraudioendpointselector.cpp b/src/plugins/symbian/mmf/mediaplayer/s60mediaplayeraudioendpointselector.cpp new file mode 100644 index 000000000..3ad64ef3b --- /dev/null +++ b/src/plugins/symbian/mmf/mediaplayer/s60mediaplayeraudioendpointselector.cpp @@ -0,0 +1,182 @@ +/**************************************************************************** +** +** 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 "DebugMacros.h" + +#include "s60mediaplayercontrol.h" +#include "s60mediaplayersession.h" +#include "s60mediaplayeraudioendpointselector.h" + +#include <QtGui/QIcon> +#include <QtCore/QDebug> + +/*! + Constructs a new audio endpoint selector with the given \a parent. +*/ + +S60MediaPlayerAudioEndpointSelector::S60MediaPlayerAudioEndpointSelector(QObject *control, QObject *parent) + :QAudioEndpointSelector(parent) + , m_control(0) +{ + DP0("S60MediaPlayerAudioEndpointSelector::S60MediaPlayerAudioEndpointSelector +++"); + + m_control = qobject_cast<S60MediaPlayerControl*>(control); + m_audioEndpointNames.append("Default"); + m_audioEndpointNames.append("All"); + m_audioEndpointNames.append("None"); + m_audioEndpointNames.append("Earphone"); + m_audioEndpointNames.append("Speaker"); + + DP0("S60MediaPlayerAudioEndpointSelector::S60MediaPlayerAudioEndpointSelector ---"); +} + +/*! + Destroys an audio endpoint selector. +*/ + +S60MediaPlayerAudioEndpointSelector::~S60MediaPlayerAudioEndpointSelector() +{ + DP0("S60MediaPlayerAudioEndpointSelector::~S60MediaPlayerAudioEndpointSelector +++"); + DP0("S60MediaPlayerAudioEndpointSelector::~S60MediaPlayerAudioEndpointSelector ---"); +} + +/*! + \return a list of available audio endpoints. +*/ + +QList<QString> S60MediaPlayerAudioEndpointSelector::availableEndpoints() const +{ + DP0("S60MediaPlayerAudioEndpointSelector::availableEndpoints"); + + return m_audioEndpointNames; +} + +/*! + \return the description of the endpoint name. +*/ + +QString S60MediaPlayerAudioEndpointSelector::endpointDescription(const QString& name) const +{ + DP0("S60MediaPlayerAudioEndpointSelector::endpointDescription"); + + if (name == QString("Default")) //ENoPreference + return QString("Used to indicate that the playing audio can be routed to" + "any speaker. This is the default value for audio."); + else if (name == QString("All")) //EAll + return QString("Used to indicate that the playing audio should be routed to all speakers."); + else if (name == QString("None")) //ENoOutput + return QString("Used to indicate that the playing audio should not be routed to any output."); + else if (name == QString("Earphone")) //EPrivate + return QString("Used to indicate that the playing audio should be routed to" + "the default private speaker. A private speaker is one that can only" + "be heard by one person."); + else if (name == QString("Speaker")) //EPublic + return QString("Used to indicate that the playing audio should be routed to" + "the default public speaker. A public speaker is one that can " + "be heard by multiple people."); + + return QString(); +} + +/*! + \return the name of the currently selected audio endpoint. +*/ + +QString S60MediaPlayerAudioEndpointSelector::activeEndpoint() const +{ + DP0("S60MediaPlayerAudioEndpointSelector::activeEndpoint"); + + if (m_control->session()) { + DP1("S60MediaPlayerAudioEndpointSelector::activeEndpoint - ", + m_control->session()->activeEndpoint()); + return m_control->session()->activeEndpoint(); + } + else { + DP1("S60MediaPlayerAudioEndpointSelector::activeEndpoint - ", + m_control->mediaControlSettings().audioEndpoint()); + return m_control->mediaControlSettings().audioEndpoint(); + } +} + +/*! + \return the name of the default audio endpoint. +*/ + +QString S60MediaPlayerAudioEndpointSelector::defaultEndpoint() const +{ + DP0("S60MediaPlayerAudioEndpointSelector::defaultEndpoint"); + + if (m_control->session()) { + DP1("S60MediaPlayerAudioEndpointSelector::defaultEndpoint - ", + m_control->session()->defaultEndpoint()); + return m_control->session()->defaultEndpoint(); + } + else { + DP1("S60MediaPlayerAudioEndpointSelector::defaultEndpoint - ", + m_control->mediaControlSettings().audioEndpoint()); + return m_control->mediaControlSettings().audioEndpoint(); + } +} + +/*! + Set the audio endpoint to \a name. +*/ + +void S60MediaPlayerAudioEndpointSelector::setActiveEndpoint(const QString& name) +{ + DP0("S60MediaPlayerAudioEndpointSelector::setActiveEndpoin +++"); + + DP1("S60MediaPlayerAudioEndpointSelector::setActiveEndpoint - ", name); + + QString oldEndpoint = m_control->mediaControlSettings().audioEndpoint(); + + if (name != oldEndpoint && (name == QString("Default") || name == QString("All") || + name == QString("None") || name == QString("Earphone") || name == QString("Speaker"))) { + + if (m_control->session()) { + m_control->session()->setActiveEndpoint(name); + emit activeEndpointChanged(name); + } + m_control->setAudioEndpoint(name); + } + + DP0("S60MediaPlayerAudioEndpointSelector::setActiveEndpoin ---"); +} diff --git a/src/plugins/symbian/mmf/mediaplayer/s60mediaplayeraudioendpointselector.h b/src/plugins/symbian/mmf/mediaplayer/s60mediaplayeraudioendpointselector.h new file mode 100644 index 000000000..eff49d47a --- /dev/null +++ b/src/plugins/symbian/mmf/mediaplayer/s60mediaplayeraudioendpointselector.h @@ -0,0 +1,77 @@ +/**************************************************************************** +** +** 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$ +** +****************************************************************************/ + +#ifndef S60MEDIAPLAYERAUDIOENDPOINTSELECTOR_H +#define S60MEDIAPLAYERAUDIOENDPOINTSELECTOR_H + +#include <QStringList> + +#include <qaudioendpointselector.h> + +QT_USE_NAMESPACE + +class S60MediaPlayerControl; +class S60MediaPlayerSession; + +class S60MediaPlayerAudioEndpointSelector : public QAudioEndpointSelector +{ + +Q_OBJECT + +public: + S60MediaPlayerAudioEndpointSelector(QObject *control, QObject *parent = 0); + ~S60MediaPlayerAudioEndpointSelector(); + + QList<QString> availableEndpoints() const ; + QString endpointDescription(const QString& name) const; + QString defaultEndpoint() const; + QString activeEndpoint() const; + +public Q_SLOTS: + void setActiveEndpoint(const QString& name); + +private: + S60MediaPlayerControl* m_control; + QString m_audioInput; + QList<QString> m_audioEndpointNames; +}; + +#endif // S60MEDIAPLAYERAUDIOENDPOINTSELECTOR_H diff --git a/src/plugins/symbian/mmf/mediaplayer/s60mediaplayercontrol.cpp b/src/plugins/symbian/mmf/mediaplayer/s60mediaplayercontrol.cpp new file mode 100644 index 000000000..2eeceedd8 --- /dev/null +++ b/src/plugins/symbian/mmf/mediaplayer/s60mediaplayercontrol.cpp @@ -0,0 +1,518 @@ + +/**************************************************************************** +** +** 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 "DebugMacros.h" + +#include "s60mediaplayercontrol.h" +#include "s60mediaplayersession.h" + +#include <QtCore/qdir.h> +#include <QtCore/qurl.h> +#include <QtCore/qdebug.h> + +/*! + Constructs a new media player control with the given \a parent. +*/ + +S60MediaPlayerControl::S60MediaPlayerControl(MS60MediaPlayerResolver& mediaPlayerResolver, QObject *parent) + : QMediaPlayerControl(parent), + m_mediaPlayerResolver(mediaPlayerResolver), + m_session(NULL), + m_stream(NULL) +{ + DP0("S60MediaPlayerControl::S60MediaPlayerControl +++"); + + DP0("S60MediaPlayerControl::S60MediaPlayerControl ---"); + +} + +/*! + Destroys a media player control. +*/ + +S60MediaPlayerControl::~S60MediaPlayerControl() +{ + DP0("S60MediaPlayerControl::~S60MediaPlayerControl +++"); + DP0("S60MediaPlayerControl::~S60MediaPlayerControl ---"); +} + +/*! + \return the current playback position in milliseconds. +*/ + +qint64 S60MediaPlayerControl::position() const +{ + // DP0("S60MediaPlayerControl::position"); + + if (m_session) + return m_session->position(); + return 0; +} + +/*! + \return the duration of the current media in milliseconds. +*/ + +qint64 S60MediaPlayerControl::duration() const +{ + // DP0("S60MediaPlayerControl::duration"); + + if (m_session) + return m_session->duration(); + return -1; +} + +/*! + \return the state of a player control. +*/ + +QMediaPlayer::State S60MediaPlayerControl::state() const +{ + DP0("S60MediaPlayerControl::state"); + + if (m_session) + return m_session->state(); + return QMediaPlayer::StoppedState; +} + +/*! + \return the status of the current media. +*/ + +QMediaPlayer::MediaStatus S60MediaPlayerControl::mediaStatus() const +{ + DP0("QMediaPlayer::mediaStatus"); + + if (m_session) + return m_session->mediaStatus(); + return m_mediaSettings.mediaStatus(); +} + +/*! + \return the buffering progress of the current media. Progress is measured in the percentage + of the buffer filled. +*/ + +int S60MediaPlayerControl::bufferStatus() const +{ + // DP0("S60MediaPlayerControl::bufferStatus"); + + if (m_session) + return m_session->bufferStatus(); + return 0; +} + +/*! + \return the audio volume of a player control. +*/ + +int S60MediaPlayerControl::volume() const +{ + DP0("S60MediaPlayerControl::volume"); + + if (m_session) + return m_session->volume(); + return m_mediaSettings.volume(); +} + +/*! + \return the mute state of a player control. +*/ + +bool S60MediaPlayerControl::isMuted() const +{ + DP0("S60MediaPlayerControl::isMuted"); + + if (m_session) + return m_session->isMuted(); + return m_mediaSettings.isMuted(); +} + +/*! + Identifies if the current media is seekable. + + \return true if it possible to seek within the current media, and false otherwise. +*/ + +bool S60MediaPlayerControl::isSeekable() const +{ + DP0("S60MediaPlayerControl::isSeekable"); + + if (m_session) + return m_session->isSeekable(); + return false; +} + +/*! + \return a range of times in milliseconds that can be played back. + + Usually for local files this is a continuous interval equal to [0..duration()] + or an empty time range if seeking is not supported, but for network sources + it refers to the buffered parts of the media. +*/ + +QMediaTimeRange S60MediaPlayerControl::availablePlaybackRanges() const +{ + DP0("S60MediaPlayerControl::availablePlaybackRanges"); + + QMediaTimeRange ranges; + + if(m_session && m_session->isSeekable()) + ranges.addInterval(0, m_session->duration()); + + return ranges; +} + +/*! + \return the rate of playback. +*/ + +qreal S60MediaPlayerControl::playbackRate() const +{ + DP0("S60MediaPlayerControl::playbackRate"); + + return m_mediaSettings.playbackRate(); +} + +/*! + Sets the \a rate of playback. +*/ + +void S60MediaPlayerControl::setPlaybackRate(qreal rate) +{ + DP0("S60MediaPlayerControl::setPlaybackRate +++"); + + DP1("S60MediaPlayerControl::setPlaybackRate - ", rate); + + //getting the current playbackrate + qreal currentPBrate = m_mediaSettings.playbackRate(); + //checking if we need to change the Playback rate + if (!qFuzzyCompare(currentPBrate,rate)) + { + if(m_session) + m_session->setPlaybackRate(rate); + + m_mediaSettings.setPlaybackRate(rate); + } + + DP0("S60MediaPlayerControl::setPlaybackRate ---"); +} + +/*! + Sets the playback \a pos of the current media. This will initiate a seek and it may take + some time for playback to reach the position set. +*/ + +void S60MediaPlayerControl::setPosition(qint64 pos) +{ + DP0("S60MediaPlayerControl::setPosition +++"); + + DP1("S60MediaPlayerControl::setPosition, Position:", pos); + + if (m_session) + m_session->setPosition(pos); + + DP0("S60MediaPlayerControl::setPosition ---"); +} + +/*! + Starts playback of the current media. + + If successful the player control will immediately enter the \l {QMediaPlayer::PlayingState} + {playing} state. +*/ + +void S60MediaPlayerControl::play() +{ + DP0("S60MediaPlayerControl::play +++"); + + if (m_session) + m_session->play(); + + DP0("S60MediaPlayerControl::play ---"); +} + +/*! + Pauses playback of the current media. + + If sucessful the player control will immediately enter the \l {QMediaPlayer::PausedState} + {paused} state. +*/ + +void S60MediaPlayerControl::pause() +{ + DP0("S60MediaPlayerControl::pause +++"); + + if (m_session) + m_session->pause(); + + DP0("S60MediaPlayerControl::pause ---"); +} + +/*! + Stops playback of the current media. + + If successful the player control will immediately enter the \l {QMediaPlayer::StoppedState} + {stopped} state. +*/ + +void S60MediaPlayerControl::stop() +{ + DP0("S60MediaPlayerControl::stop +++"); + + if (m_session) + m_session->stop(); + + DP0("S60MediaPlayerControl::stop ---"); +} + +/*! + Sets the audio \a volume of a player control. +*/ + +void S60MediaPlayerControl::setVolume(int volume) +{ + DP0("S60MediaPlayerControl::setVolume +++"); + + DP1("S60MediaPlayerControl::setVolume", volume); + + int boundVolume = qBound(0, volume, 100); + if (boundVolume == m_mediaSettings.volume()) + return; + + m_mediaSettings.setVolume(boundVolume); + + if (m_session) + m_session->setVolume(boundVolume); + + DP0("S60MediaPlayerControl::setVolume ---"); +} + +/*! + Sets the \a muted state of a player control. +*/ + +void S60MediaPlayerControl::setMuted(bool muted) +{ + DP0("S60MediaPlayerControl::setMuted +++"); + + DP1("S60MediaPlayerControl::setMuted - ", muted); + + if (m_mediaSettings.isMuted() == muted) + return; + + m_mediaSettings.setMuted(muted); + + if (m_session) + m_session->setMuted(muted); + + DP0("S60MediaPlayerControl::setMuted ---"); +} + +/*! + * \return the current media source. +*/ + +QMediaContent S60MediaPlayerControl::media() const +{ + DP0("S60MediaPlayerControl::media"); + + return m_currentResource; +} + +/*! + \return the current media stream. This is only a valid if a stream was passed to setMedia(). + + \sa setMedia() +*/ + +const QIODevice *S60MediaPlayerControl::mediaStream() const +{ + DP0("S60MediaPlayerControl::mediaStream"); + + return m_stream; +} + +/*! + Sets the current \a source media source. If a \a stream is supplied; data will be read from that + instead of attempting to resolve the media source. The media source may still be used to + supply media information such as mime type. + + Setting the media to a null QMediaContent will cause the control to discard all + information relating to the current media source and to cease all I/O operations related + to that media. +*/ + +void S60MediaPlayerControl::setMedia(const QMediaContent &source, QIODevice *stream) +{ + DP0("S60MediaPlayerControl::setMedia +++"); + + Q_UNUSED(stream) + + if ((m_session && m_currentResource == source) && m_session->isStreaming()) + { + m_session->load(source); + return; + } + + // we don't want to set & load media again when it is already loaded + if (m_session && m_currentResource == source) + return; + + // store to variable as session is created based on the content type. + m_currentResource = source; + S60MediaPlayerSession *newSession = m_mediaPlayerResolver.PlayerSession(); + m_mediaSettings.setMediaStatus(QMediaPlayer::UnknownMediaStatus); + + if (m_session) + m_session->reset(); + else { + emit mediaStatusChanged(QMediaPlayer::UnknownMediaStatus); + emit error(QMediaPlayer::NoError, QString()); + } + + m_session = newSession; + + if (m_session) + m_session->load(source); + else { + QMediaPlayer::MediaStatus status = (source.isNull()) ? QMediaPlayer::NoMedia : QMediaPlayer::InvalidMedia; + m_mediaSettings.setMediaStatus(status); + emit stateChanged(QMediaPlayer::StoppedState); + emit error((source.isNull()) ? QMediaPlayer::NoError : QMediaPlayer::ResourceError, + (source.isNull()) ? "" : tr("Media couldn't be resolved")); + emit mediaStatusChanged(status); + } + emit mediaChanged(m_currentResource); + + DP0("S60MediaPlayerControl::setMedia ---"); +} + +/*! + * \return media player session. +*/ +S60MediaPlayerSession* S60MediaPlayerControl::session() +{ + DP0("S60MediaPlayerControl::session"); + + return m_session; +} + +/*! + * Sets \a output as a VideoOutput. +*/ + +void S60MediaPlayerControl::setVideoOutput(QObject *output) +{ + DP0("S60MediaPlayerControl::setVideoOutput +++"); + + m_mediaPlayerResolver.VideoPlayerSession()->setVideoRenderer(output); + + DP0("S60MediaPlayerControl::setVideoOutput ---"); +} + +/*! + * \return TRUE if Audio available or else FALSE. +*/ + +bool S60MediaPlayerControl::isAudioAvailable() const +{ + DP0("S60MediaPlayerControl::isAudioAvailable"); + + if (m_session) + return m_session->isAudioAvailable(); + return false; +} + +/*! + * \return TRUE if Video available or else FALSE. +*/ + +bool S60MediaPlayerControl::isVideoAvailable() const +{ + DP0("S60MediaPlayerControl::isVideoAvailable"); + + if (m_session) + return m_session->isVideoAvailable(); + return false; +} + +/*! + * \return media settings. + * + * Media Settings include volume, muted, playbackRate, mediaStatus, audioEndpoint. +*/ +const S60MediaSettings& S60MediaPlayerControl::mediaControlSettings() const +{ + DP0("S60MediaPlayerControl::mediaControlSettings"); + return m_mediaSettings; +} + +/*! + * Set the audio endpoint to \a name. +*/ + +void S60MediaPlayerControl::setAudioEndpoint(const QString& name) +{ + DP0("S60MediaPlayerControl::setAudioEndpoint +++"); + + DP1("S60MediaPlayerControl::setAudioEndpoint - ", name); + + m_mediaSettings.setAudioEndpoint(name); + + DP0("S60MediaPlayerControl::setAudioEndpoint ---"); +} + +/*! + * Sets media type \a type as Unknown, Video, Audio, Data. +*/ + +void S60MediaPlayerControl::setMediaType(S60MediaSettings::TMediaType type) +{ + DP0("S60MediaPlayerControl::setMediaType +++"); + + DP1("S60MediaPlayerControl::setMediaType - ", type); + + m_mediaSettings.setMediaType(type); + + DP0("S60MediaPlayerControl::setMediaType ---"); +} diff --git a/src/plugins/symbian/mmf/mediaplayer/s60mediaplayercontrol.h b/src/plugins/symbian/mmf/mediaplayer/s60mediaplayercontrol.h new file mode 100644 index 000000000..caf6631a8 --- /dev/null +++ b/src/plugins/symbian/mmf/mediaplayer/s60mediaplayercontrol.h @@ -0,0 +1,148 @@ +/**************************************************************************** +** +** 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$ +** +****************************************************************************/ + +#ifndef S60MEDIAPLAYERCONTROL_H +#define S60MEDIAPLAYERCONTROL_H + +#include <QtCore/qobject.h> + +#include <qmediaplayercontrol.h> + +#include "ms60mediaplayerresolver.h" +#include <QtCore/qdebug.h> + +QT_BEGIN_NAMESPACE +class QMediaPlayer; +class QMediaTimeRange; +class QMediaContent; +QT_END_NAMESPACE + +QT_USE_NAMESPACE + +class S60MediaPlayerSession; +class S60MediaPlayerService; + +class S60MediaSettings +{ + +public: + S60MediaSettings() + : m_volume(30) + , m_muted(false) + , m_playbackRate(0) + , m_mediaStatus(QMediaPlayer::NoMedia) + , m_audioEndpoint(QString("Default")) + { + } + + enum TMediaType {Unknown, Video, Audio, Data}; + + void setVolume(int volume) { m_volume = volume; } + void setMuted(bool muted) { m_muted = muted; } + void setPlaybackRate(qreal rate) { m_playbackRate = rate; } + void setMediaStatus(QMediaPlayer::MediaStatus status) {m_mediaStatus=status;} + void setAudioEndpoint(const QString& audioEndpoint) { m_audioEndpoint = audioEndpoint; } + void setMediaType(S60MediaSettings::TMediaType type) { m_mediaType = type; } + + int volume() const { return m_volume; } + bool isMuted() const { return m_muted; } + qreal playbackRate() const { return m_playbackRate; } + QMediaPlayer::MediaStatus mediaStatus() const {return m_mediaStatus;} + QString audioEndpoint() const { return m_audioEndpoint; } + S60MediaSettings::TMediaType mediaType() const { return m_mediaType; } + +private: + int m_volume; + bool m_muted; + qreal m_playbackRate; + QMediaPlayer::MediaStatus m_mediaStatus; + QString m_audioEndpoint; + S60MediaSettings::TMediaType m_mediaType; +}; + +class S60MediaPlayerControl : public QMediaPlayerControl +{ + Q_OBJECT + +public: + S60MediaPlayerControl(MS60MediaPlayerResolver& mediaPlayerResolver, QObject *parent = 0); + ~S60MediaPlayerControl(); + + // from QMediaPlayerControl + virtual QMediaPlayer::State state() const; + virtual QMediaPlayer::MediaStatus mediaStatus() const; + virtual qint64 duration() const; + virtual qint64 position() const; + virtual void setPosition(qint64 pos); + virtual int volume() const; + virtual void setVolume(int volume); + virtual bool isMuted() const; + virtual void setMuted(bool muted); + virtual int bufferStatus() const; + virtual bool isAudioAvailable() const; + virtual bool isVideoAvailable() const; + virtual bool isSeekable() const; + virtual QMediaTimeRange availablePlaybackRanges() const; + virtual qreal playbackRate() const; + virtual void setPlaybackRate(qreal rate); + virtual QMediaContent media() const; + virtual const QIODevice *mediaStream() const; + virtual void setMedia(const QMediaContent&, QIODevice *); + virtual void play(); + virtual void pause(); + virtual void stop(); + + // Own methods + S60MediaPlayerSession* session(); + void setVideoOutput(QObject *output); + const S60MediaSettings& mediaControlSettings() const; + void setAudioEndpoint(const QString& name); + void setMediaType(S60MediaSettings::TMediaType type); + +private: + MS60MediaPlayerResolver &m_mediaPlayerResolver; + S60MediaPlayerSession *m_session; + QMediaContent m_currentResource; + QIODevice *m_stream; + S60MediaSettings m_mediaSettings; +}; + +#endif diff --git a/src/plugins/symbian/mmf/mediaplayer/s60mediaplayerservice.cpp b/src/plugins/symbian/mmf/mediaplayer/s60mediaplayerservice.cpp new file mode 100644 index 000000000..a1aabef90 --- /dev/null +++ b/src/plugins/symbian/mmf/mediaplayer/s60mediaplayerservice.cpp @@ -0,0 +1,326 @@ +/**************************************************************************** +** +** 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 "DebugMacros.h" + +#include <QtCore/qvariant.h> +#include <QtCore/qdebug.h> +#include <QtGui/qwidget.h> + +#include "s60mediaplayerservice.h" +#include "s60mediaplayercontrol.h" +#include "s60videoplayersession.h" +#include "s60audioplayersession.h" +#include "s60mediametadataprovider.h" +#include "s60mediarecognizer.h" +#include "s60videowidgetcontrol.h" +#include "s60videowindowcontrol.h" +#ifdef HAS_VIDEORENDERERCONTROL_IN_VIDEOPLAYER +#include "s60videorenderer.h" +#endif +#include "s60mediaplayeraudioendpointselector.h" +#include "s60medianetworkaccesscontrol.h" +#include "s60mediastreamcontrol.h" + +#include <qmediaplaylistnavigator.h> +#include <qmediaplaylist.h> + +/*! + Construct a media service with the given \a parent. +*/ + +S60MediaPlayerService::S60MediaPlayerService(QObject *parent) + : QMediaService(parent) + , m_control(NULL) + , m_videoPlayerSession(NULL) + , m_audioPlayerSession(NULL) + , m_metaData(NULL) + , m_audioEndpointSelector(NULL) + , m_streamControl(NULL) + , m_networkAccessControl(NULL) + , m_videoOutput(NULL) +{ + DP0("S60MediaPlayerService::S60MediaPlayerService +++"); + + m_control = new S60MediaPlayerControl(*this, this); + m_metaData = new S60MediaMetaDataProvider(m_control, this); + m_audioEndpointSelector = new S60MediaPlayerAudioEndpointSelector(m_control, this); + m_streamControl = new S60MediaStreamControl(m_control, this); + m_networkAccessControl = new S60MediaNetworkAccessControl(this); + + DP0("S60MediaPlayerService::S60MediaPlayerService ---"); +} + +/*! + Destroys a media service. +*/ + +S60MediaPlayerService::~S60MediaPlayerService() +{ + DP0("S60MediaPlayerService::~S60MediaPlayerService +++"); + DP0("S60MediaPlayerService::~S60MediaPlayerService ---"); +} + +/*! + \return a pointer to the media control, which matches the controller \a name. + + If the service does not implement the control, or if it is unavailable a + null pointer is returned instead. + + Controls must be returned to the service when no longer needed using the + releaseControl() function. +*/ + +QMediaControl *S60MediaPlayerService::requestControl(const char *name) +{ + DP0("S60MediaPlayerService::requestControl"); + + if (qstrcmp(name, QMediaPlayerControl_iid) == 0) + return m_control; + + if (qstrcmp(name, QMediaNetworkAccessControl_iid) == 0) + return m_networkAccessControl; + + if (qstrcmp(name, QMetaDataReaderControl_iid) == 0) + return m_metaData; + + if (qstrcmp(name, QAudioEndpointSelector_iid) == 0) + return m_audioEndpointSelector; + + if (qstrcmp(name, QMediaStreamsControl_iid) == 0) + return m_streamControl; + + if (!m_videoOutput) { + if (qstrcmp(name, QVideoWidgetControl_iid) == 0) { + m_videoOutput = new S60VideoWidgetControl(this); + } +#ifdef HAS_VIDEORENDERERCONTROL_IN_VIDEOPLAYER + else if (qstrcmp(name, QVideoRendererControl_iid) == 0) { + m_videoOutput = new S60VideoRenderer(this); + } +#endif /* HAS_VIDEORENDERERCONTROL_IN_VIDEOPLAYER */ + else if (qstrcmp(name, QVideoWindowControl_iid) == 0) { + m_videoOutput = new S60VideoWindowControl(this); + } + + if (m_videoOutput) { + m_control->setVideoOutput(m_videoOutput); + return m_videoOutput; + } + }else { + if (qstrcmp(name, QVideoWidgetControl_iid) == 0 || +#ifdef HAS_VIDEORENDERERCONTROL_IN_VIDEOPLAYER + qstrcmp(name, QVideoRendererControl_iid) == 0 || +#endif /* HAS_VIDEORENDERERCONTROL_IN_VIDEOPLAYER */ + qstrcmp(name, QVideoWindowControl_iid) == 0){ + return m_videoOutput; + } + } + return 0; +} + +/*! + Releases a \a control back to the service. +*/ + +void S60MediaPlayerService::releaseControl(QMediaControl *control) +{ + DP0("S60MediaPlayerService::releaseControl ++"); + + if (control == m_videoOutput) { + m_videoOutput = 0; + m_control->setVideoOutput(m_videoOutput); + } + + DP0("S60MediaPlayerService::releaseControl --"); +} + +/*! + * \return media player session(audio playersesion/video playersession) + * by recognizing whether media is audio or video and sets it on media type. +*/ +S60MediaPlayerSession* S60MediaPlayerService::PlayerSession() +{ + DP0("S60MediaPlayerService::PlayerSession"); + + QUrl url = m_control->media().canonicalUrl(); + + if (url.isEmpty() == true) { + return NULL; + } + + QScopedPointer<S60MediaRecognizer> mediaRecognizer(new S60MediaRecognizer); + S60MediaRecognizer::MediaType mediaType = mediaRecognizer->mediaType(url); + mediaRecognizer.reset(); + + switch (mediaType) { + case S60MediaRecognizer::Video: + case S60MediaRecognizer::Url: { + m_control->setMediaType(S60MediaSettings::Video); + return VideoPlayerSession(); + } + case S60MediaRecognizer::Audio: { + m_control->setMediaType(S60MediaSettings::Audio); + return AudioPlayerSession(); + } + default: + m_control->setMediaType(S60MediaSettings::Unknown); + break; + } + + return NULL; +} + +/*! + * \return media playersession (videoplayersession). + * constructs the videoplayersession object and connects all the respective signals and slots. + * and initialises all the media settings. +*/ + +S60MediaPlayerSession* S60MediaPlayerService::VideoPlayerSession() +{ + DP0("S60MediaPlayerService::VideoPlayerSession +++"); + + if (!m_videoPlayerSession) { + m_videoPlayerSession = new S60VideoPlayerSession(this, m_networkAccessControl); + + connect(m_videoPlayerSession, SIGNAL(positionChanged(qint64)), + m_control, SIGNAL(positionChanged(qint64))); + connect(m_videoPlayerSession, SIGNAL(playbackRateChanged(qreal)), + m_control, SIGNAL(playbackRateChanged(qreal))); + connect(m_videoPlayerSession, SIGNAL(volumeChanged(int)), + m_control, SIGNAL(volumeChanged(int))); + connect(m_videoPlayerSession, SIGNAL(mutedChanged(bool)), + m_control, SIGNAL(mutedChanged(bool))); + connect(m_videoPlayerSession, SIGNAL(durationChanged(qint64)), + m_control, SIGNAL(durationChanged(qint64))); + connect(m_videoPlayerSession, SIGNAL(stateChanged(QMediaPlayer::State)), + m_control, SIGNAL(stateChanged(QMediaPlayer::State))); + connect(m_videoPlayerSession, SIGNAL(mediaStatusChanged(QMediaPlayer::MediaStatus)), + m_control, SIGNAL(mediaStatusChanged(QMediaPlayer::MediaStatus))); + connect(m_videoPlayerSession,SIGNAL(bufferStatusChanged(int)), + m_control, SIGNAL(bufferStatusChanged(int))); + connect(m_videoPlayerSession, SIGNAL(videoAvailableChanged(bool)), + m_control, SIGNAL(videoAvailableChanged(bool))); + connect(m_videoPlayerSession, SIGNAL(audioAvailableChanged(bool)), + m_control, SIGNAL(audioAvailableChanged(bool))); + connect(m_videoPlayerSession, SIGNAL(seekableChanged(bool)), + m_control, SIGNAL(seekableChanged(bool))); + connect(m_videoPlayerSession, SIGNAL(availablePlaybackRangesChanged(const QMediaTimeRange&)), + m_control, SIGNAL(availablePlaybackRangesChanged(const QMediaTimeRange&))); + connect(m_videoPlayerSession, SIGNAL(error(int, const QString &)), + m_control, SIGNAL(error(int, const QString &))); + connect(m_videoPlayerSession, SIGNAL(metaDataChanged()), + m_metaData, SIGNAL(metaDataChanged())); + connect(m_videoPlayerSession, SIGNAL(activeEndpointChanged(const QString&)), + m_audioEndpointSelector, SIGNAL(activeEndpointChanged(const QString&))); + connect(m_videoPlayerSession, SIGNAL(mediaChanged()), + m_streamControl, SLOT(handleStreamsChanged())); + connect(m_videoPlayerSession, SIGNAL(accessPointChanged(int)), + m_networkAccessControl, SLOT(accessPointChanged(int))); + + } + + m_videoPlayerSession->setVolume(m_control->mediaControlSettings().volume()); + m_videoPlayerSession->setMuted(m_control->mediaControlSettings().isMuted()); + m_videoPlayerSession->setAudioEndpoint(m_control->mediaControlSettings().audioEndpoint()); + + DP0("S60MediaPlayerService::VideoPlayerSession ---"); + + return m_videoPlayerSession; +} + +/*! + * \return media playersession (audioplayersession). + * constructs the audioplayersession object and connects all the respective signals and slots. + * and initialises all the media settings. +*/ + +S60MediaPlayerSession* S60MediaPlayerService::AudioPlayerSession() +{ + DP0("S60MediaPlayerService::AudioPlayerSession +++"); + + if (!m_audioPlayerSession) { + m_audioPlayerSession = new S60AudioPlayerSession(this); + + connect(m_audioPlayerSession, SIGNAL(positionChanged(qint64)), + m_control, SIGNAL(positionChanged(qint64))); + connect(m_audioPlayerSession, SIGNAL(playbackRateChanged(qreal)), + m_control, SIGNAL(playbackRateChanged(qreal))); + connect(m_audioPlayerSession, SIGNAL(volumeChanged(int)), + m_control, SIGNAL(volumeChanged(int))); + connect(m_audioPlayerSession, SIGNAL(mutedChanged(bool)), + m_control, SIGNAL(mutedChanged(bool))); + connect(m_audioPlayerSession, SIGNAL(durationChanged(qint64)), + m_control, SIGNAL(durationChanged(qint64))); + connect(m_audioPlayerSession, SIGNAL(stateChanged(QMediaPlayer::State)), + m_control, SIGNAL(stateChanged(QMediaPlayer::State))); + connect(m_audioPlayerSession, SIGNAL(mediaStatusChanged(QMediaPlayer::MediaStatus)), + m_control, SIGNAL(mediaStatusChanged(QMediaPlayer::MediaStatus))); + connect(m_audioPlayerSession,SIGNAL(bufferStatusChanged(int)), + m_control, SIGNAL(bufferStatusChanged(int))); + connect(m_audioPlayerSession, SIGNAL(videoAvailableChanged(bool)), + m_control, SIGNAL(videoAvailableChanged(bool))); + connect(m_audioPlayerSession, SIGNAL(audioAvailableChanged(bool)), + m_control, SIGNAL(audioAvailableChanged(bool))); + connect(m_audioPlayerSession, SIGNAL(seekableChanged(bool)), + m_control, SIGNAL(seekableChanged(bool))); + connect(m_audioPlayerSession, SIGNAL(availablePlaybackRangesChanged(const QMediaTimeRange&)), + m_control, SIGNAL(availablePlaybackRangesChanged(const QMediaTimeRange&))); + connect(m_audioPlayerSession, SIGNAL(error(int, const QString &)), + m_control, SIGNAL(error(int, const QString &))); + connect(m_audioPlayerSession, SIGNAL(metaDataChanged()), + m_metaData, SIGNAL(metaDataChanged())); + connect(m_audioPlayerSession, SIGNAL(activeEndpointChanged(const QString&)), + m_audioEndpointSelector, SIGNAL(activeEndpointChanged(const QString&))); + connect(m_audioPlayerSession, SIGNAL(mediaChanged()), + m_streamControl, SLOT(handleStreamsChanged())); + + } + + m_audioPlayerSession->setVolume(m_control->mediaControlSettings().volume()); + m_audioPlayerSession->setMuted(m_control->mediaControlSettings().isMuted()); + m_audioPlayerSession->setAudioEndpoint(m_control->mediaControlSettings().audioEndpoint()); + + DP0("S60MediaPlayerService::AudioPlayerSession ---"); + + return m_audioPlayerSession; +} diff --git a/src/plugins/symbian/mmf/mediaplayer/s60mediaplayerservice.h b/src/plugins/symbian/mmf/mediaplayer/s60mediaplayerservice.h new file mode 100644 index 000000000..d45ad45cc --- /dev/null +++ b/src/plugins/symbian/mmf/mediaplayer/s60mediaplayerservice.h @@ -0,0 +1,97 @@ +/**************************************************************************** +** +** 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$ +** +****************************************************************************/ + +#ifndef S60VIDEOPLAYERSERVICE_H +#define S60VIDEOPLAYERSERVICE_H + +#include <QtCore/qobject.h> +#include <qmediaservice.h> + +#include "ms60mediaplayerresolver.h" +#include "s60mediaplayeraudioendpointselector.h" + +QT_BEGIN_NAMESPACE +class QMediaMetaData; +class QMediaPlayerControl; +class QMediaPlaylist; +QT_END_NAMESPACE + +QT_USE_NAMESPACE + +class S60VideoPlayerSession; +class S60AudioPlayerSession; +class S60MediaPlayerControl; +class S60MediaMetaDataProvider; +class S60MediaStreamControl; +class S60MediaRecognizer; + +class QMediaPlaylistNavigator; +class S60MediaNetworkAccessControl; + +class S60MediaPlayerService : public QMediaService, public MS60MediaPlayerResolver +{ + Q_OBJECT + +public: + + S60MediaPlayerService(QObject *parent = 0); + ~S60MediaPlayerService(); + + QMediaControl *requestControl(const char *name); + void releaseControl(QMediaControl *control); + +protected: // From MS60MediaPlayerResolver + S60MediaPlayerSession* PlayerSession(); + S60MediaPlayerSession* VideoPlayerSession(); + S60MediaPlayerSession* AudioPlayerSession(); + +private: + S60MediaPlayerControl *m_control; + S60VideoPlayerSession *m_videoPlayerSession; + S60AudioPlayerSession *m_audioPlayerSession; + S60MediaMetaDataProvider *m_metaData; + S60MediaPlayerAudioEndpointSelector *m_audioEndpointSelector; + S60MediaStreamControl *m_streamControl; + S60MediaNetworkAccessControl *m_networkAccessControl; + QMediaControl *m_videoOutput; +}; + +#endif diff --git a/src/plugins/symbian/mmf/mediaplayer/s60mediaplayersession.cpp b/src/plugins/symbian/mmf/mediaplayer/s60mediaplayersession.cpp new file mode 100644 index 000000000..49a840a2d --- /dev/null +++ b/src/plugins/symbian/mmf/mediaplayer/s60mediaplayersession.cpp @@ -0,0 +1,1054 @@ +/**************************************************************************** +** +** 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 "DebugMacros.h" + +#include "s60mediaplayersession.h" + +#include <QtCore/qdebug.h> +#include <QtCore/qdir.h> +#include <QtCore/qvariant.h> +#include <QtCore/qtimer.h> +#include <mmf/common/mmferrors.h> +#include <qmediatimerange.h> + +/*! + Construct a media playersession with the given \a parent. +*/ + +S60MediaPlayerSession::S60MediaPlayerSession(QObject *parent) + : QObject(parent) + , m_stream(false) + , m_playbackRate(0) + , m_muted(false) + , m_volume(0) + , m_state(QMediaPlayer::StoppedState) + , m_mediaStatus(QMediaPlayer::NoMedia) + , m_progressTimer(new QTimer(this)) + , m_stalledTimer(new QTimer(this)) + , m_error(KErrNone) + , m_play_requested(false) + , m_seekable(true) +{ + DP0("S60MediaPlayerSession::S60MediaPlayerSession +++"); + + connect(m_progressTimer, SIGNAL(timeout()), this, SLOT(tick())); + connect(m_stalledTimer, SIGNAL(timeout()), this, SLOT(stalled())); + + DP0("S60MediaPlayerSession::S60MediaPlayerSession ---"); +} + +/*! + Destroys a media playersession. +*/ + +S60MediaPlayerSession::~S60MediaPlayerSession() +{ + DP0("S60MediaPlayerSession::~S60MediaPlayerSession +++"); + DP0("S60MediaPlayerSession::~S60MediaPlayerSession ---"); +} + +/*! + * \return the audio volume of a player session. +*/ +int S60MediaPlayerSession::volume() const +{ + DP1("S60MediaPlayerSession::volume", m_volume); + + return m_volume; +} + +/*! + Sets the audio \a volume of a player session. +*/ + +void S60MediaPlayerSession::setVolume(int volume) +{ + DP0("S60MediaPlayerSession::setVolume +++"); + + DP1("S60MediaPlayerSession::setVolume - ", volume); + + if (m_volume == volume) + return; + + m_volume = volume; + emit volumeChanged(m_volume); + + // Dont set symbian players volume until media loaded. + // Leaves with KerrNotReady although documentation says otherwise. + if (!m_muted && + ( mediaStatus() == QMediaPlayer::LoadedMedia + || (mediaStatus() == QMediaPlayer::StalledMedia && state() != QMediaPlayer::StoppedState) + || mediaStatus() == QMediaPlayer::BufferingMedia + || mediaStatus() == QMediaPlayer::BufferedMedia + || mediaStatus() == QMediaPlayer::EndOfMedia)) { + TRAPD(err, doSetVolumeL(m_volume)); + setError(err); + } + DP0("S60MediaPlayerSession::setVolume ---"); +} + +/*! + \return the mute state of a player session. +*/ + +bool S60MediaPlayerSession::isMuted() const +{ + DP1("S60MediaPlayerSession::isMuted", m_muted); + + return m_muted; +} + +/*! + Identifies if the current media is seekable. + + \return true if it possible to seek within the current media, and false otherwise. +*/ + +bool S60MediaPlayerSession::isSeekable() const +{ + DP1("S60MediaPlayerSession::isSeekable", m_seekable); + + return m_seekable; +} + +/*! + Sets the \a status of the current media. +*/ + +void S60MediaPlayerSession::setMediaStatus(QMediaPlayer::MediaStatus status) +{ + DP0("S60MediaPlayerSession::setMediaStatus +++"); + + if (m_mediaStatus == status) + return; + + m_mediaStatus = status; + + emit mediaStatusChanged(m_mediaStatus); + + if (m_play_requested && m_mediaStatus == QMediaPlayer::LoadedMedia) + play(); + + DP0("S60MediaPlayerSession::setMediaStatus ---"); +} + +/*! + Sets the \a state on media player. +*/ + +void S60MediaPlayerSession::setState(QMediaPlayer::State state) +{ + DP0("S60MediaPlayerSession::setState +++"); + + if (m_state == state) + return; + + m_state = state; + emit stateChanged(m_state); + + DP0("S60MediaPlayerSession::setState ---"); +} + +/*! + \return the state of a player session. +*/ + +QMediaPlayer::State S60MediaPlayerSession::state() const +{ + DP1("S60MediaPlayerSession::state", m_state); + + return m_state; +} + +/*! + \return the status of the current media. +*/ + +QMediaPlayer::MediaStatus S60MediaPlayerSession::mediaStatus() const +{ + DP1("S60MediaPlayerSession::mediaStatus", m_mediaStatus); + + return m_mediaStatus; +} + +/*! + * Loads the \a url for playback. + * If \a url is local file then it loads audio playersesion if its audio file. + * If it is a local video file then loads the video playersession. +*/ + +void S60MediaPlayerSession::load(const QMediaContent source) +{ + DP0("S60MediaPlayerSession::load +++"); + + m_source = source; + setMediaStatus(QMediaPlayer::LoadingMedia); + startStalledTimer(); + m_stream = (source.canonicalUrl().scheme() == "file")?false:true; + m_UrlPath = source.canonicalUrl(); + TRAPD(err, + if (m_stream) + doLoadUrlL(QString2TPtrC(source.canonicalUrl().toString())); + else + doLoadL(QString2TPtrC(QDir::toNativeSeparators(source.canonicalUrl().toLocalFile())))); + setError(err); + + DP0("S60MediaPlayerSession::load ---"); +} + +TBool S60MediaPlayerSession::isStreaming() +{ + return m_stream; +} + +/*! + Start or resume playing the current source. +*/ +void S60MediaPlayerSession::play() +{ + DP0("S60MediaPlayerSession::play +++"); + + if ( (state() == QMediaPlayer::PlayingState && m_play_requested == false) + || mediaStatus() == QMediaPlayer::UnknownMediaStatus + || mediaStatus() == QMediaPlayer::NoMedia + || mediaStatus() == QMediaPlayer::InvalidMedia) + return; + + setState(QMediaPlayer::PlayingState); + + if (mediaStatus() == QMediaPlayer::LoadingMedia || + (mediaStatus() == QMediaPlayer::StalledMedia && + state() == QMediaPlayer::StoppedState)) + { + m_play_requested = true; + return; + } + + m_play_requested = false; + m_duration = duration(); + setVolume(m_volume); + setMuted(m_muted); + startProgressTimer(); + doPlay(); + + DP0("S60MediaPlayerSession::play ---"); +} + +/*! + Pause playing the current source. +*/ + +void S60MediaPlayerSession::pause() +{ + DP0("S60MediaPlayerSession::pause +++"); + + if (state() != QMediaPlayer::PlayingState) + return; + + if (mediaStatus() == QMediaPlayer::NoMedia || + mediaStatus() == QMediaPlayer::InvalidMedia) + return; + + setState(QMediaPlayer::PausedState); + stopProgressTimer(); + TRAP_IGNORE(doPauseL()); + m_play_requested = false; + + DP0("S60MediaPlayerSession::pause ---"); +} + +/*! + Stop playing, and reset the play position to the beginning. +*/ + +void S60MediaPlayerSession::stop() +{ + DP0("S60MediaPlayerSession::stop +++"); + + if (state() == QMediaPlayer::StoppedState) + return; + + m_play_requested = false; + m_state = QMediaPlayer::StoppedState; + if (mediaStatus() == QMediaPlayer::BufferingMedia || + mediaStatus() == QMediaPlayer::BufferedMedia || + mediaStatus() == QMediaPlayer::StalledMedia) + setMediaStatus(QMediaPlayer::LoadedMedia); + if (mediaStatus() == QMediaPlayer::LoadingMedia) + setMediaStatus(QMediaPlayer::UnknownMediaStatus); + stopProgressTimer(); + stopStalledTimer(); + doStop(); + emit positionChanged(0); + emit stateChanged(m_state); + + DP0("S60MediaPlayerSession::stop ---"); +} + +/*! + * Stops the playback and closes the controllers. + * And resets all the flags and status, state to default values. +*/ + +void S60MediaPlayerSession::reset() +{ + DP0("S60MediaPlayerSession::reset +++"); + + m_play_requested = false; + setError(KErrNone, QString(), true); + stopProgressTimer(); + stopStalledTimer(); + doStop(); + doClose(); + setState(QMediaPlayer::StoppedState); + setMediaStatus(QMediaPlayer::UnknownMediaStatus); + setPosition(0); + + DP0("S60MediaPlayerSession::reset ---"); +} + +/*! + * Sets \a renderer as video renderer. +*/ + +void S60MediaPlayerSession::setVideoRenderer(QObject *renderer) +{ + DP0("S60MediaPlayerSession::setVideoRenderer +++"); + + Q_UNUSED(renderer); + + DP0("S60MediaPlayerSession::setVideoRenderer ---"); +} + +/*! + * the percentage of the temporary buffer filled before playback begins. + + When the player object is buffering; this property holds the percentage of + the temporary buffer that is filled. The buffer will need to reach 100% + filled before playback can resume, at which time the MediaStatus will be + BufferedMedia. + + \sa mediaStatus() +*/ + +int S60MediaPlayerSession::bufferStatus() +{ + DP0("S60MediaPlayerSession::bufferStatus"); + + if (state() ==QMediaPlayer::StoppedState) + return 0; + + if( mediaStatus() == QMediaPlayer::LoadingMedia + || mediaStatus() == QMediaPlayer::UnknownMediaStatus + || mediaStatus() == QMediaPlayer::NoMedia + || mediaStatus() == QMediaPlayer::InvalidMedia) + return 0; + + int progress = 0; + TRAPD(err, progress = doGetBufferStatusL()); + // If buffer status query not supported by codec return 100 + // do not set error + if(err == KErrNotSupported) + return 100; + + setError(err); + return progress; +} + +/*! + * return TRUE if Meta data is available in current media source. +*/ + +bool S60MediaPlayerSession::isMetadataAvailable() const +{ + DP0("S60MediaPlayerSession::isMetadataAvailable"); + + return !m_metaDataMap.isEmpty(); +} + +/*! + * \return the \a key meta data. +*/ +QVariant S60MediaPlayerSession::metaData(const QString &key) const +{ + DP0("S60MediaPlayerSession::metaData (const QString &key) const"); + + return m_metaDataMap.value(key); +} + +/*! + * \return the \a key meta data as QString. +*/ + +QVariant S60MediaPlayerSession::metaData(QtMultimediaKit::MetaData key) const +{ + DP0("S60MediaPlayerSession::metaData (QtMultimediaKit::MetaData key) const"); + + return metaData(metaDataKeyAsString(key)); +} + +/*! + * \return List of all available meta data from current media source. +*/ + +QList<QtMultimediaKit::MetaData> S60MediaPlayerSession::availableMetaData() const +{ + DP0("S60MediaPlayerSession::availableMetaData +++"); + + QList<QtMultimediaKit::MetaData> metaDataTags; + if (isMetadataAvailable()) { + for (int i = QtMultimediaKit::Title; i <= QtMultimediaKit::ThumbnailImage; i++) { + QString metaDataItem = metaDataKeyAsString((QtMultimediaKit::MetaData)i); + if (!metaDataItem.isEmpty()) { + if (!metaData(metaDataItem).isNull()) { + metaDataTags.append((QtMultimediaKit::MetaData)i); + } + } + } + } + + DP0("S60MediaPlayerSession::availableMetaData ---"); + + return metaDataTags; +} + +/*! + * \return all available extended meta data of current media source. +*/ + +QStringList S60MediaPlayerSession::availableExtendedMetaData() const +{ + DP0("S60MediaPlayerSession::availableExtendedMetaData"); + + return m_metaDataMap.keys(); +} + +/*! + * \return meta data \a key as QString. +*/ + +QString S60MediaPlayerSession::metaDataKeyAsString(QtMultimediaKit::MetaData key) const +{ + DP1("S60MediaPlayerSession::metaDataKeyAsString", key); + + switch(key) { + case QtMultimediaKit::Title: return "title"; + case QtMultimediaKit::AlbumArtist: return "artist"; + case QtMultimediaKit::Comment: return "comment"; + case QtMultimediaKit::Genre: return "genre"; + case QtMultimediaKit::Year: return "year"; + case QtMultimediaKit::Copyright: return "copyright"; + case QtMultimediaKit::AlbumTitle: return "album"; + case QtMultimediaKit::Composer: return "composer"; + case QtMultimediaKit::TrackNumber: return "albumtrack"; + case QtMultimediaKit::AudioBitRate: return "audiobitrate"; + case QtMultimediaKit::VideoBitRate: return "videobitrate"; + case QtMultimediaKit::Duration: return "duration"; + case QtMultimediaKit::MediaType: return "contenttype"; + case QtMultimediaKit::CoverArtImage: return "attachedpicture"; + case QtMultimediaKit::SubTitle: // TODO: Find the matching metadata keys + case QtMultimediaKit::Description: + case QtMultimediaKit::Category: + case QtMultimediaKit::Date: + case QtMultimediaKit::UserRating: + case QtMultimediaKit::Keywords: + case QtMultimediaKit::Language: + case QtMultimediaKit::Publisher: + case QtMultimediaKit::ParentalRating: + case QtMultimediaKit::RatingOrganisation: + case QtMultimediaKit::Size: + case QtMultimediaKit::AudioCodec: + case QtMultimediaKit::AverageLevel: + case QtMultimediaKit::ChannelCount: + case QtMultimediaKit::PeakValue: + case QtMultimediaKit::SampleRate: + case QtMultimediaKit::Author: + case QtMultimediaKit::ContributingArtist: + case QtMultimediaKit::Conductor: + case QtMultimediaKit::Lyrics: + case QtMultimediaKit::Mood: + case QtMultimediaKit::TrackCount: + case QtMultimediaKit::CoverArtUrlSmall: + case QtMultimediaKit::CoverArtUrlLarge: + case QtMultimediaKit::Resolution: + case QtMultimediaKit::PixelAspectRatio: + case QtMultimediaKit::VideoFrameRate: + case QtMultimediaKit::VideoCodec: + case QtMultimediaKit::PosterUrl: + case QtMultimediaKit::ChapterNumber: + case QtMultimediaKit::Director: + case QtMultimediaKit::LeadPerformer: + case QtMultimediaKit::Writer: + case QtMultimediaKit::CameraManufacturer: + case QtMultimediaKit::CameraModel: + case QtMultimediaKit::Event: + case QtMultimediaKit::Subject: + default: + break; + } + + return QString(); +} + +/*! + Sets the \a muted state of a player session. +*/ + +void S60MediaPlayerSession::setMuted(bool muted) +{ + DP0("S60MediaPlayerSession::setMuted +++"); + DP1("S60MediaPlayerSession::setMuted - ", muted); + + m_muted = muted; + emit mutedChanged(m_muted); + + if( m_mediaStatus == QMediaPlayer::LoadedMedia + || (m_mediaStatus == QMediaPlayer::StalledMedia && state() != QMediaPlayer::StoppedState) + || m_mediaStatus == QMediaPlayer::BufferingMedia + || m_mediaStatus == QMediaPlayer::BufferedMedia + || m_mediaStatus == QMediaPlayer::EndOfMedia) { + TRAPD(err, doSetVolumeL((m_muted)?0:m_volume)); + setError(err); + } + DP0("S60MediaPlayerSession::setMuted ---"); +} + +/*! + \return the duration of the current media in milliseconds. +*/ + +qint64 S60MediaPlayerSession::duration() const +{ + // DP0("S60MediaPlayerSession::duration"); + + if( mediaStatus() == QMediaPlayer::LoadingMedia + || mediaStatus() == QMediaPlayer::UnknownMediaStatus + || mediaStatus() == QMediaPlayer::NoMedia + || (mediaStatus() == QMediaPlayer::StalledMedia && state() == QMediaPlayer::StoppedState) + || mediaStatus() == QMediaPlayer::InvalidMedia) + return -1; + + qint64 pos = 0; + TRAP_IGNORE(pos = doGetDurationL()); + return pos; +} + +/*! + \return the current playback position in milliseconds. +*/ + +qint64 S60MediaPlayerSession::position() const +{ + // DP0("S60MediaPlayerSession::position"); + + if( mediaStatus() == QMediaPlayer::LoadingMedia + || mediaStatus() == QMediaPlayer::UnknownMediaStatus + || mediaStatus() == QMediaPlayer::NoMedia + || (mediaStatus() == QMediaPlayer::StalledMedia && state() == QMediaPlayer::StoppedState) + || mediaStatus() == QMediaPlayer::InvalidMedia) + return 0; + + qint64 pos = 0; + TRAP_IGNORE(pos = doGetPositionL()); + if (!m_play_requested && pos ==0 + && mediaStatus() != QMediaPlayer::LoadedMedia) + return m_duration; + return pos; +} + +/*! + Sets the playback \a pos of the current media. This will initiate a seek and it may take + some time for playback to reach the position set. +*/ + +void S60MediaPlayerSession::setPosition(qint64 pos) +{ + DP0("S60MediaPlayerSession::setPosition +++"); + + DP1("S60MediaPlayerSession::setPosition - ", pos); + + if (position() == pos) + return; + + QMediaPlayer::State originalState = state(); + + if (originalState == QMediaPlayer::PlayingState) + pause(); + + TRAPD(err, doSetPositionL(pos * 1000)); + setError(err); + + if (err == KErrNone) { + if (mediaStatus() == QMediaPlayer::EndOfMedia) + setMediaStatus(QMediaPlayer::LoadedMedia); + } + else if (err == KErrNotSupported) { + m_seekable = false; + emit seekableChanged(m_seekable); + } + + if (originalState == QMediaPlayer::PlayingState) + play(); + + emit positionChanged(position()); + + DP0("S60MediaPlayerSession::setPosition ---"); +} + +/*! + * Set the audio endpoint to \a audioEndpoint. +*/ + +void S60MediaPlayerSession::setAudioEndpoint(const QString& audioEndpoint) +{ + DP0("S60MediaPlayerSession::setAudioEndpoint +++"); + + DP1("S60MediaPlayerSession::setAudioEndpoint - ", audioEndpoint); + + doSetAudioEndpoint(audioEndpoint); + + DP0("S60MediaPlayerSession::setAudioEndpoint ---"); +} + +/*! + * Loading of media source is completed. + * And ready for playback. Updates all the media status, state, settings etc. + * And emits the signals. +*/ + +void S60MediaPlayerSession::loaded() +{ + DP0("S60MediaPlayerSession::loaded +++"); + + stopStalledTimer(); + if (m_error == KErrNone || m_error == KErrMMPartialPlayback) { + setMediaStatus(QMediaPlayer::LoadedMedia); + TRAPD(err, updateMetaDataEntriesL()); + setError(err); + emit durationChanged(duration()); + emit positionChanged(0); + emit videoAvailableChanged(isVideoAvailable()); + emit audioAvailableChanged(isAudioAvailable()); + emit mediaChanged(); + + m_seekable = getIsSeekable(); + } + + DP0("S60MediaPlayerSession::loaded ---"); +} + +/*! + * Playback is completed as medai source reached end of media. +*/ +void S60MediaPlayerSession::endOfMedia() +{ + DP0("S60MediaPlayerSession::endOfMedia +++"); + + m_state = QMediaPlayer::StoppedState; + setMediaStatus(QMediaPlayer::EndOfMedia); + //there is a chance that user might have called play from EOF callback + //if we are already in playing state, do not send state change callback + if(m_state == QMediaPlayer::StoppedState) + emit stateChanged(QMediaPlayer::StoppedState); + emit positionChanged(m_duration); + + DP0("S60MediaPlayerSession::endOfMedia ---"); +} + +/*! + * The percentage of the temporary buffer filling before playback begins. + + When the player object is buffering; this property holds the percentage of + the temporary buffer that is filled. The buffer will need to reach 100% + filled before playback can resume, at which time the MediaStatus will be + BufferedMedia. + + \sa mediaStatus() +*/ + +void S60MediaPlayerSession::buffering() +{ + DP0("S60MediaPlayerSession::buffering +++"); + + startStalledTimer(); + setMediaStatus(QMediaPlayer::BufferingMedia); + +//Buffering cannot happen in stopped state. Hence update the state + if (state() == QMediaPlayer::StoppedState) + setState(QMediaPlayer::PausedState); + + DP0("S60MediaPlayerSession::buffering ---"); +} + +/*! + * Buffer is filled with data and to for continuing/start playback. +*/ + +void S60MediaPlayerSession::buffered() +{ + DP0("S60MediaPlayerSession::buffered +++"); + + stopStalledTimer(); + setMediaStatus(QMediaPlayer::BufferedMedia); + + DP0("S60MediaPlayerSession::buffered ---"); +} + +/*! + * Sets media status as stalled as waiting for the buffer to be filled to start playback. +*/ + +void S60MediaPlayerSession::stalled() +{ + DP0("S60MediaPlayerSession::stalled +++"); + + setMediaStatus(QMediaPlayer::StalledMedia); + + DP0("S60MediaPlayerSession::stalled ---"); +} + +/*! + * \return all the meta data entries in the current media source. +*/ + +QMap<QString, QVariant>& S60MediaPlayerSession::metaDataEntries() +{ + DP0("S60MediaPlayerSession::metaDataEntries"); + + return m_metaDataMap; +} + +/*! + * \return Error by converting Symbian specific error to Multimedia error. +*/ + +QMediaPlayer::Error S60MediaPlayerSession::fromSymbianErrorToMultimediaError(int error) +{ + DP0("S60MediaPlayerSession::fromSymbianErrorToMultimediaError"); + + DP1("S60MediaPlayerSession::fromSymbianErrorToMultimediaError - ", error); + + switch(error) { + case KErrNoMemory: + case KErrNotFound: + case KErrBadHandle: + case KErrAbort: + case KErrNotSupported: + case KErrCorrupt: + case KErrGeneral: + case KErrArgument: + case KErrPathNotFound: + case KErrDied: + case KErrServerTerminated: + case KErrServerBusy: + case KErrCompletion: + case KErrBadPower: + case KErrMMInvalidProtocol: + case KErrMMInvalidURL: + return QMediaPlayer::ResourceError; + + case KErrMMPartialPlayback: + return QMediaPlayer::FormatError; + + case KErrMMAudioDevice: + case KErrMMVideoDevice: + case KErrMMDecoder: + case KErrUnknown: + return QMediaPlayer::ServiceMissingError; + + case KErrMMNotEnoughBandwidth: + case KErrMMSocketServiceNotFound: + case KErrMMNetworkRead: + case KErrMMNetworkWrite: + case KErrMMServerSocket: + case KErrMMServerNotSupported: + case KErrMMUDPReceive: + case KErrMMMulticast: + case KErrMMProxyServer: + case KErrMMProxyServerNotSupported: + case KErrMMProxyServerConnect: + case KErrCouldNotConnect: + return QMediaPlayer::NetworkError; + + case KErrNotReady: + case KErrInUse: + case KErrAccessDenied: + case KErrLocked: + case KErrMMDRMNotAuthorized: + case KErrPermissionDenied: + case KErrCancel: + case KErrAlreadyExists: + return QMediaPlayer::AccessDeniedError; + + case KErrNone: + return QMediaPlayer::NoError; + + default: + return QMediaPlayer::ResourceError; + } +} + +/*! + * \return error. + */ + +int S60MediaPlayerSession::error() const +{ + DP1("S60MediaPlayerSession::error", m_error); + + return m_error; +} + +/*! + * Sets the error. + * * If playback complete/prepare complete ..., etc with successful then sets error as ZERO + * else Multimedia error. +*/ + +void S60MediaPlayerSession::setError(int error, const QString &errorString, bool forceReset) +{ + DP0("S60MediaPlayerSession::setError +++"); + + DP5("S60MediaPlayerSession::setError - error:", error,"errorString:", errorString, "forceReset:", forceReset); + + if( forceReset ) { + m_error = KErrNone; + emit this->error(QMediaPlayer::NoError, QString()); + return; + } + + // If error does not change and m_error is reseted without forceReset flag + if (error == m_error || + (m_error != KErrNone && error == KErrNone)) + return; + + m_error = error; + QMediaPlayer::Error mediaError = fromSymbianErrorToMultimediaError(m_error); + QString symbianError = QString(errorString); + + if (mediaError != QMediaPlayer::NoError) { + // TODO: fix to user friendly string at some point + // These error string are only dev usable + symbianError.append("Symbian:"); + symbianError.append(QString::number(m_error)); + } + + emit this->error(mediaError, symbianError); + + if (m_error == KErrInUse) { + pause(); + } else if (mediaError != QMediaPlayer::NoError) { + m_play_requested = false; + setMediaStatus(QMediaPlayer::InvalidMedia); + stop(); + } +} + +void S60MediaPlayerSession::setAndEmitError(int error) +{ + m_error = error; + QMediaPlayer::Error rateError = fromSymbianErrorToMultimediaError(error); + QString symbianError; + symbianError.append("Symbian:"); + symbianError.append(QString::number(error)); + emit this->error(rateError, symbianError); + + DP0("S60MediaPlayerSession::setError ---"); +} + +/*! + * emits the signal if there is a changes in position and buffering status. + */ + +void S60MediaPlayerSession::tick() +{ + DP0("S60MediaPlayerSession::tick +++"); + + emit positionChanged(position()); + + if (bufferStatus() < 100) + emit bufferStatusChanged(bufferStatus()); + + DP0("S60MediaPlayerSession::tick ---"); +} + +/*! + * Starts the timer once the media source starts buffering. +*/ + +void S60MediaPlayerSession::startProgressTimer() +{ + DP0("S60MediaPlayerSession::startProgressTimer +++"); + + m_progressTimer->start(500); + + DP0("S60MediaPlayerSession::startProgressTimer ---"); +} + +/*! + * Stops the timer once the media source finished buffering. +*/ + +void S60MediaPlayerSession::stopProgressTimer() +{ + DP0("S60MediaPlayerSession::stopProgressTimer +++"); + + m_progressTimer->stop(); + + DP0("S60MediaPlayerSession::stopProgressTimer ---"); +} + +/*! + * Starts the timer while waiting for some events to happen like source buffering or call backs etc. + * So that if the events doesn't occur before stalled timer stops, it'll set the error/media status etc. +*/ + +void S60MediaPlayerSession::startStalledTimer() +{ + DP0("S60MediaPlayerSession::startStalledTimer +++"); + + m_stalledTimer->start(30000); + + DP0("S60MediaPlayerSession::startStalledTimer ---"); +} + +/*! + * Stops the timer when some events occurred while waiting for them. + * media source started buffering or call back is received etc. +*/ + +void S60MediaPlayerSession::stopStalledTimer() +{ + DP0("S60MediaPlayerSession::stopStalledTimer +++"); + + m_stalledTimer->stop(); + + DP0("S60MediaPlayerSession::stopStalledTimer ---"); +} + +/*! + * \return Converted Symbian specific Descriptor to QString. +*/ + +QString S60MediaPlayerSession::TDesC2QString(const TDesC& aDescriptor) +{ + DP0("S60MediaPlayerSession::TDesC2QString"); + + return QString::fromUtf16(aDescriptor.Ptr(), aDescriptor.Length()); +} + +/*! + * \return Converted QString to non-modifiable pointer Descriptor. +*/ + +TPtrC S60MediaPlayerSession::QString2TPtrC( const QString& string ) +{ + DP0("S60MediaPlayerSession::QString2TPtrC"); + + // Returned TPtrC is valid as long as the given parameter is valid and unmodified + return TPtrC16(static_cast<const TUint16*>(string.utf16()), string.length()); +} + +/*! + * \return Converted Symbian TRect object to QRect object. +*/ + +QRect S60MediaPlayerSession::TRect2QRect(const TRect& tr) +{ + DP0("S60MediaPlayerSession::TRect2QRect"); + + return QRect(tr.iTl.iX, tr.iTl.iY, tr.Width(), tr.Height()); +} + +/*! + * \return converted QRect object to Symbian specific TRec object. + */ + +TRect S60MediaPlayerSession::QRect2TRect(const QRect& qr) +{ + DP0("S60MediaPlayerSession::QRect2TRect"); + + return TRect(TPoint(qr.left(), qr.top()), TSize(qr.width(), qr.height())); +} + +/*! + \fn bool S60MediaPlayerSession::isVideoAvailable(); + + + Returns TRUE if Video is available. +*/ + +/*! + \fn bool S60MediaPlayerSession::isAudioAvailable(); + + + Returns TRUE if Audio is available. +*/ + +/*! + \fn void S60MediaPlayerSession::setPlaybackRate (qreal rate); + + + Sets \a rate play back rate on media source. getIsSeekable +*/ + +/*! + \fn bool S60MediaPlayerSession::getIsSeekable () const; + + + \return TRUE if Seekable possible on current media source else FALSE. +*/ + +/*! + \fn QString S60MediaPlayerSession::activeEndpoint () const; + + + \return active end point name.. +*/ + +/*! + \fn QString S60MediaPlayerSession::defaultEndpoint () const; + + + \return default end point name. +*/ + diff --git a/src/plugins/symbian/mmf/mediaplayer/s60mediaplayersession.h b/src/plugins/symbian/mmf/mediaplayer/s60mediaplayersession.h new file mode 100644 index 000000000..e6889d101 --- /dev/null +++ b/src/plugins/symbian/mmf/mediaplayer/s60mediaplayersession.h @@ -0,0 +1,187 @@ +/**************************************************************************** +** +** 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$ +** +****************************************************************************/ + +#ifndef S60MEDIAPLAYERSESSION_H +#define S60MEDIAPLAYERSESSION_H + +#include <QtCore/qobject.h> +#include <QtCore/qurl.h> +#include <QtCore/qpair.h> +#include <qmediaplayer.h> +#include <e32cmn.h> // for TDesC +#include <QRect> +#include "s60mediaplayerservice.h" + + +_LIT( KSeekable, "Seekable" ); +_LIT( KFalse, "0"); + +QT_BEGIN_NAMESPACE +class QMediaTimeRange; +QT_END_NAMESPACE + +class QTimer; + +class S60MediaPlayerSession : public QObject +{ + Q_OBJECT + +public: + S60MediaPlayerSession(QObject *parent); + virtual ~S60MediaPlayerSession(); + + // for player control interface to use + QMediaPlayer::State state() const; + QMediaPlayer::MediaStatus mediaStatus() const; + qint64 duration() const; + qint64 position() const; + void setPosition(qint64 pos); + int volume() const; + void setVolume(int volume); + bool isMuted() const; + void setMuted(bool muted); + virtual bool isVideoAvailable() = 0; + virtual bool isAudioAvailable() = 0; + bool isSeekable() const; + void play(); + void pause(); + void stop(); + void reset(); + bool isMetadataAvailable() const; + QVariant metaData(const QString &key) const; + QVariant metaData(QtMultimediaKit::MetaData key) const; + QList<QtMultimediaKit::MetaData> availableMetaData() const; + QStringList availableExtendedMetaData() const; + QString metaDataKeyAsString(QtMultimediaKit::MetaData key) const; + void load(const QMediaContent source); + int bufferStatus(); + virtual void setVideoRenderer(QObject *renderer); + void setMediaStatus(QMediaPlayer::MediaStatus); + void setState(QMediaPlayer::State state); + void setAudioEndpoint(const QString& audioEndpoint); + virtual void setPlaybackRate(qreal rate) = 0; + virtual bool getIsSeekable() const { return ETrue; } + TBool isStreaming(); + +protected: + virtual void doLoadL(const TDesC &path) = 0; + virtual void doLoadUrlL(const TDesC &path) = 0; + virtual void doPlay() = 0; + virtual void doStop() = 0; + virtual void doClose() = 0; + virtual void doPauseL() = 0; + virtual void doSetVolumeL(int volume) = 0; + virtual void doSetPositionL(qint64 microSeconds) = 0; + virtual qint64 doGetPositionL() const = 0; + virtual void updateMetaDataEntriesL() = 0; + virtual int doGetBufferStatusL() const = 0; + virtual qint64 doGetDurationL() const = 0; + virtual void doSetAudioEndpoint(const QString& audioEndpoint) = 0; + +public: + // From S60MediaPlayerAudioEndpointSelector + virtual QString activeEndpoint() const = 0; + virtual QString defaultEndpoint() const = 0; +public Q_SLOTS: + virtual void setActiveEndpoint(const QString& name) = 0; + +protected: + int error() const; + void setError(int error, const QString &errorString = QString(), bool forceReset = false); + void setAndEmitError(int error); + void loaded(); + void buffering(); + void buffered(); + void endOfMedia(); + QMap<QString, QVariant>& metaDataEntries(); + QMediaPlayer::Error fromSymbianErrorToMultimediaError(int error); + void startProgressTimer(); + void stopProgressTimer(); + void startStalledTimer(); + void stopStalledTimer(); + QString TDesC2QString(const TDesC& aDescriptor); + TPtrC QString2TPtrC( const QString& string ); + QRect TRect2QRect(const TRect& tr); + TRect QRect2TRect(const QRect& qr); + +protected slots: + void tick(); + void stalled(); + +signals: + void durationChanged(qint64 duration); + void positionChanged(qint64 position); + void stateChanged(QMediaPlayer::State state); + void mediaStatusChanged(QMediaPlayer::MediaStatus mediaStatus); + void videoAvailableChanged(bool videoAvailable); + void audioAvailableChanged(bool audioAvailable); + void bufferStatusChanged(int percentFilled); + void seekableChanged(bool); + void availablePlaybackRangesChanged(const QMediaTimeRange&); + void metaDataChanged(); + void error(int error, const QString &errorString); + void activeEndpointChanged(const QString &name); + void mediaChanged(); + void playbackRateChanged(qreal rate); + void volumeChanged(int volume); + void mutedChanged(bool muted); + +protected: + QUrl m_UrlPath; + bool m_stream; + QMediaContent m_source; + +private: + qreal m_playbackRate; + QMap<QString, QVariant> m_metaDataMap; + bool m_muted; + int m_volume; + QMediaPlayer::State m_state; + QMediaPlayer::MediaStatus m_mediaStatus; + QTimer *m_progressTimer; + QTimer *m_stalledTimer; + int m_error; + bool m_play_requested; + bool m_seekable; + qint64 m_duration; +}; + +#endif diff --git a/src/plugins/symbian/mmf/mediaplayer/s60mediarecognizer.cpp b/src/plugins/symbian/mmf/mediaplayer/s60mediarecognizer.cpp new file mode 100644 index 000000000..48b565c34 --- /dev/null +++ b/src/plugins/symbian/mmf/mediaplayer/s60mediarecognizer.cpp @@ -0,0 +1,167 @@ +/**************************************************************************** +** +** 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 "DebugMacros.h" + +#include "s60mediarecognizer.h" +#include <e32def.h> +#include <e32cmn.h> +#include <QtCore/qurl.h> +#include <QtCore/qdir.h> +#include <QtCore/qdebug.h> + +#include <apgcli.h> + +static const TInt KMimeTypePrefixLength = 6; // "audio/" or "video/" + +_LIT(KMimeTypePrefixAudio, "audio/"); +_LIT(KMimeTypePrefixVideo, "video/"); +_LIT(KMimeTypeRingingTone, "application/vnd.nokia.ringing-tone"); + +/*! + Construct a media Recognizer with the given \a parent. +*/ + +S60MediaRecognizer::S60MediaRecognizer(QObject *parent) : QObject(parent) +{ + DP0("S60MediaRecognizer::S60MediaRecognizer +++"); + DP0("S60MediaRecognizer::S60MediaRecognizer ---"); +} + +/*! + Destroys a media Recognizer. +*/ + +S60MediaRecognizer::~S60MediaRecognizer() +{ + DP0("S60MediaRecognizer::~S60MediaRecognizer +++"); + + m_file.Close(); + m_fileServer.Close(); + m_recognizer.Close(); + + DP0("S60MediaRecognizer::~S60MediaRecognizer ---"); +} + +/*! + * \return media type of \a url. + * \a url may be a streaming link or a local file. + * If \a url is local file then identifies the media type and returns it. +*/ + +S60MediaRecognizer::MediaType S60MediaRecognizer::mediaType(const QUrl &url) +{ + DP0("S60MediaRecognizer::mediaType"); + + bool isStream = (url.scheme() == "file")?false:true; + + if (isStream) + return Url; + else + return identifyMediaType(QDir::cleanPath(url.toLocalFile())); +} + +/*! + * \return Media type of \a file name by recognizing its mimetype whether its audio or video. +*/ + +S60MediaRecognizer::MediaType S60MediaRecognizer::identifyMediaType(const QString& fileName) +{ + DP0("S60MediaRecognizer::identifyMediaType +++"); + + DP1("S60MediaRecognizer::identifyMediaType - ", fileName); + + S60MediaRecognizer::MediaType result = Video; // default to videoplayer + bool recognizerOpened = false; + + TInt err = m_recognizer.Connect(); + if (err == KErrNone) { + recognizerOpened = true; + } + + err = m_fileServer.Connect(); + if (err == KErrNone) { + recognizerOpened = true; + } + + // This is needed for sharing file handles for the recognizer + err = m_fileServer.ShareProtected(); + if (err == KErrNone) { + recognizerOpened = true; + } + + if (recognizerOpened) { + m_file.Close(); + err = m_file.Open(m_fileServer, QString2TPtrC(QDir::toNativeSeparators(fileName)), EFileRead | + EFileShareReadersOnly); + + if (err == KErrNone) { + TDataRecognitionResult recognizerResult; + err = m_recognizer.RecognizeData(m_file, recognizerResult); + if (err == KErrNone) { + const TPtrC mimeType = recognizerResult.iDataType.Des(); + + if (mimeType.Left(KMimeTypePrefixLength).Compare(KMimeTypePrefixAudio) == 0 || + mimeType.Compare(KMimeTypeRingingTone) == 0) { + result = Audio; + } else if (mimeType.Left(KMimeTypePrefixLength).Compare(KMimeTypePrefixVideo) == 0) { + result = Video; + } + } + } + } + + DP0("S60MediaRecognizer::identifyMediaType ---"); + + return result; +} + +/*! + * \return Symbian modifiable pointer descriptor from a QString \a string. + */ + +TPtrC S60MediaRecognizer::QString2TPtrC( const QString& string ) +{ + DP1("S60MediaRecognizer::QString2TPtrC - ", string); + + // Returned TPtrC is valid as long as the given parameter is valid and unmodified + return TPtrC16(static_cast<const TUint16*>(string.utf16()), string.length()); +} diff --git a/src/plugins/symbian/mmf/mediaplayer/s60mediarecognizer.h b/src/plugins/symbian/mmf/mediaplayer/s60mediarecognizer.h new file mode 100644 index 000000000..bdd0caabe --- /dev/null +++ b/src/plugins/symbian/mmf/mediaplayer/s60mediarecognizer.h @@ -0,0 +1,79 @@ +/**************************************************************************** +** +** 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$ +** +****************************************************************************/ + +#ifndef S60MEDIARECOGNIZER_H_ +#define S60MEDIARECOGNIZER_H_ + +#include <QtCore/qobject.h> + +#include <apgcli.h> +#include <f32file.h> + +class QUrl; + +class S60MediaRecognizer : public QObject +{ + Q_OBJECT + +public: + enum MediaType { + Audio, + Video, + Url, + NotSupported = -1 + }; + + S60MediaRecognizer(QObject *parent = 0); + ~S60MediaRecognizer(); + + S60MediaRecognizer::MediaType mediaType(const QUrl &url); + S60MediaRecognizer::MediaType identifyMediaType(const QString& fileName); + +protected: + TPtrC QString2TPtrC( const QString& string ); + +private: + RApaLsSession m_recognizer; + RFile m_file; + RFs m_fileServer; +}; + +#endif /* S60MEDIARECOGNIZER_H_ */ diff --git a/src/plugins/symbian/mmf/mediaplayer/s60mediastreamcontrol.cpp b/src/plugins/symbian/mmf/mediaplayer/s60mediastreamcontrol.cpp new file mode 100644 index 000000000..9a2ce5c02 --- /dev/null +++ b/src/plugins/symbian/mmf/mediaplayer/s60mediastreamcontrol.cpp @@ -0,0 +1,201 @@ +/**************************************************************************** +** +** 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 "DebugMacros.h" + +#include "s60mediastreamcontrol.h" +#include "s60mediaplayersession.h" +#include "s60mediaplayercontrol.h" +#include <qmediastreamscontrol.h> + +#include <QtCore/qdir.h> +#include <QtCore/qurl.h> +#include <QtCore/qdebug.h> + +/*! + Constructs a new media streams control with the given \a control. +*/ + +S60MediaStreamControl::S60MediaStreamControl(QObject *control, QObject *parent) + : QMediaStreamsControl(parent) + , m_control(NULL) + , m_mediaType(S60MediaSettings::Unknown) +{ + DP0("S60MediaStreamControl::S60MediaStreamControl +++"); + + m_control = qobject_cast<S60MediaPlayerControl*>(control); + m_mediaType = m_control->mediaControlSettings().mediaType(); + + DP0("S60MediaStreamControl::S60MediaStreamControl ---"); +} + +/*! + Destroys a media streams control. +*/ + +S60MediaStreamControl::~S60MediaStreamControl() +{ + DP0("S60MediaStreamControl::~S60MediaStreamControl +++"); + DP0("S60MediaStreamControl::~S60MediaStreamControl ---"); +} + +/*! + \return the number of media streams. +*/ + +int S60MediaStreamControl::streamCount() +{ + DP0("S60MediaStreamControl::streamCount"); + + int streamCount = 0; + if (m_control->isAudioAvailable()) + streamCount++; + if (m_control->isVideoAvailable()) + streamCount++; + DP1("S60MediaStreamControl::streamCount", streamCount); + + return streamCount; +} + +/*! + \return the type of a media \a streamNumber. +*/ + +QMediaStreamsControl::StreamType S60MediaStreamControl::streamType(int streamNumber) +{ + DP0("S60MediaStreamControl::streamType +++"); + + DP1("S60MediaStreamControl::streamType - ", streamNumber); + + Q_UNUSED(streamNumber); + + QMediaStreamsControl::StreamType type = QMediaStreamsControl::UnknownStream; + + if (m_control->mediaControlSettings().mediaType() == S60MediaSettings::Video) + type = QMediaStreamsControl::VideoStream; + else + type = QMediaStreamsControl::AudioStream; + + DP0("S60MediaStreamControl::streamType ---"); + + return type; +} + +/*! + \return the meta-data value of \a key for a given \a streamNumber. + + Useful metadata keya are QtMultimediaKit::Title, QtMultimediaKit::Description and QtMultimediaKit::Language. +*/ + +QVariant S60MediaStreamControl::metaData(int streamNumber, QtMultimediaKit::MetaData key) +{ + DP0("S60MediaStreamControl::metaData"); + + Q_UNUSED(streamNumber); + + if (m_control->session()) { + if (m_control->session()->isMetadataAvailable()) + return m_control->session()->metaData(key); + } + return QVariant(); +} + +/*! + \return true if the media \a streamNumber is active else false. +*/ + +bool S60MediaStreamControl::isActive(int streamNumber) +{ + DP0("S60MediaStreamControl::isActive +++"); + + DP1("S60MediaStreamControl::isActive - ", streamNumber); + + if (m_control->mediaControlSettings().mediaType() == S60MediaSettings::Video) { + switch (streamNumber) { + case 1: + return m_control->isVideoAvailable(); + case 2: + return m_control->isAudioAvailable(); + default: + break; + } + } + + DP0("S60MediaStreamControl::isActive ---"); + + return m_control->isAudioAvailable(); +} + +/*! + Sets the active \a streamNumber of a media \a state. + + Symbian MMF does not support enabling or disabling specific media streams. + + Setting the active state of a media stream to true will activate it. If any other stream + of the same type was previously active it will be deactivated. Setting the active state fo a + media stream to false will deactivate it. +*/ + +void S60MediaStreamControl::setActive(int streamNumber, bool state) +{ + DP0("S60MediaStreamControl::setActive +++"); + + DP2("S60MediaStreamControl::setActive - ", streamNumber, state); + + Q_UNUSED(streamNumber); + Q_UNUSED(state); + // Symbian MMF does not support enabling or disabling specific media streams + + DP0("S60MediaStreamControl::setActive ---"); +} + +/*! + The signal is emitted when the available streams list is changed. +*/ + +void S60MediaStreamControl::handleStreamsChanged() +{ + DP0("S60MediaStreamControl::handleStreamsChanged +++"); + + emit streamsChanged(); + + DP0("S60MediaStreamControl::handleStreamsChanged ---"); +} diff --git a/src/plugins/symbian/mmf/mediaplayer/s60mediastreamcontrol.h b/src/plugins/symbian/mmf/mediaplayer/s60mediastreamcontrol.h new file mode 100644 index 000000000..702ebc7b2 --- /dev/null +++ b/src/plugins/symbian/mmf/mediaplayer/s60mediastreamcontrol.h @@ -0,0 +1,79 @@ +/**************************************************************************** +** +** 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$ +** +****************************************************************************/ + +#ifndef S60MEDIASTREAMCONTROL_H +#define S60MEDIASTREAMCONTROL_H + +#include <QVariant> + +#include "s60mediaplayercontrol.h" + +#include <qmediastreamscontrol.h> +#include <qtmedianamespace.h> + +QT_USE_NAMESPACE + +class S60MediaPlayerControl; +class S60MediaSettings; + +class S60MediaStreamControl : public QMediaStreamsControl +{ + Q_OBJECT +public: + S60MediaStreamControl(QObject *session, QObject *parent = 0); + ~S60MediaStreamControl(); + + // from QMediaStreamsControl + int streamCount(); + QMediaStreamsControl::StreamType streamType(int streamNumber); + QVariant metaData(int streamNumber, QtMultimediaKit::MetaData key); + bool isActive(int streamNumber); + void setActive(int streamNumber, bool state); + +public Q_SLOTS: + void handleStreamsChanged(); + +private: + S60MediaPlayerControl *m_control; + S60MediaSettings::TMediaType m_mediaType; +}; + +#endif //S60MEDIASTREAMCONTROL_H diff --git a/src/plugins/symbian/mmf/mediaplayer/s60videooutputinterface.h b/src/plugins/symbian/mmf/mediaplayer/s60videooutputinterface.h new file mode 100644 index 000000000..f5388dbbc --- /dev/null +++ b/src/plugins/symbian/mmf/mediaplayer/s60videooutputinterface.h @@ -0,0 +1,62 @@ +/**************************************************************************** +** +** 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$ +** +****************************************************************************/ + +#ifndef S60VIDEOOUTPUTINTERFACE_H +#define S60VIDEOOUTPUTINTERFACE_H + +#include <QtCore/qglobal.h> +#include <QtGui/qwindowdefs.h> +#include <coecntrl.h> + +class S60VideoOutputInterface +{ +public: + RWindow *videoWindowHandle() const { return videoWinId() ? static_cast<RWindow *>(videoWinId()->DrawableWindow()) : 0 ; } + virtual WId videoWinId() const = 0; + // If VIDEOOUTPUT_GRAPHICS_SURFACES is defined, the return value is the video + // rectangle relative to the video window. If not, the return value is the + // absolute screen rectangle. + virtual QRect videoDisplayRect() const = 0; + virtual Qt::AspectRatioMode videoAspectRatio() const = 0; +}; + +#endif // S60VIDEOOUTPUTINTERFACE_H + diff --git a/src/plugins/symbian/mmf/mediaplayer/s60videoplayersession.cpp b/src/plugins/symbian/mmf/mediaplayer/s60videoplayersession.cpp new file mode 100644 index 000000000..49d511ca2 --- /dev/null +++ b/src/plugins/symbian/mmf/mediaplayer/s60videoplayersession.cpp @@ -0,0 +1,1124 @@ +/**************************************************************************** +** +** 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 "DebugMacros.h" + +#include "s60videoplayersession.h" +#include "s60mediaplayerservice.h" +#include "s60videowidgetcontrol.h" +#include "s60videowidgetdisplay.h" +#include "s60videowindowcontrol.h" +#include "s60videowindowdisplay.h" + +#include <QtCore/QTimer> +#include <QtGui/QApplication> +#include <QtGui/QDesktopWidget> +#include <QtGui/QSymbianEvent> +#include <QtGui/QWidget> + +#include <coecntrl.h> +#include <coemain.h> // For CCoeEnv +#include <w32std.h> +#include <mmf/common/mmferrors.h> +#include <mmf/common/mmfcontrollerframeworkbase.h> +#include <MMFROPCustomCommandConstants.h> +#ifdef HTTP_COOKIES_ENABLED +#include <MMFSessionInfoCustomCommandConstants.h> +#endif + +const QString DefaultAudioEndpoint = QLatin1String("Default"); +const TUid KHelixUID = {0x101F8514}; + +//Hard-coding the command to support older versions. +const TInt KMMFROPControllerEnablePausedLoadingStatus = 7; + +TVideoRotation videoRotation(qreal angle) +{ + // Convert to clockwise + angle = 360.0f - angle; + while (angle >= 360.0f) + angle -= 360.0f; + TVideoRotation result = EVideoRotationNone; + if (angle >= 45.0f && angle < 135.0f) + result = EVideoRotationClockwise90; + else if (angle >= 135.0f && angle < 225.0f) + result = EVideoRotationClockwise180; + else if (angle >= 225.0f && angle < 315.0f) + result = EVideoRotationClockwise270; + return result; +} + +S60VideoPlayerEventHandler *S60VideoPlayerEventHandler::m_instance = 0; +QCoreApplication::EventFilter S60VideoPlayerEventHandler::m_eventFilter = 0; +QList<ApplicationFocusObserver *> S60VideoPlayerEventHandler::m_applicationFocusObservers; + +S60VideoPlayerEventHandler *S60VideoPlayerEventHandler::instance() +{ + if (!m_instance) + m_instance = new S60VideoPlayerEventHandler(); + return m_instance; +} + +S60VideoPlayerEventHandler::S60VideoPlayerEventHandler() +{ + m_eventFilter = QCoreApplication::instance()->setEventFilter(filterEvent); +} + +S60VideoPlayerEventHandler::~S60VideoPlayerEventHandler() +{ + QCoreApplication::instance()->setEventFilter(m_eventFilter); +} + +void S60VideoPlayerEventHandler::addApplicationFocusObserver(ApplicationFocusObserver *observer) +{ + m_applicationFocusObservers.append(observer); +} + +void S60VideoPlayerEventHandler::removeApplicationFocusObserver(ApplicationFocusObserver *observer) +{ + m_applicationFocusObservers.removeAt(m_applicationFocusObservers.indexOf(observer)); + if (m_applicationFocusObservers.count() == 0) { + delete m_instance; + m_instance = 0; + } +} + +bool S60VideoPlayerEventHandler::filterEvent(void *message, long *result) +{ + if (const QSymbianEvent *symbianEvent = reinterpret_cast<const QSymbianEvent*>(message)) { + switch (symbianEvent->type()) { + case QSymbianEvent::WindowServerEvent: + { + const TWsEvent *wsEvent = symbianEvent->windowServerEvent(); + if (EEventFocusLost == wsEvent->Type() || EEventFocusGained == wsEvent->Type()) { + for (QList<ApplicationFocusObserver *>::const_iterator it = m_applicationFocusObservers.constBegin(); + it != m_applicationFocusObservers.constEnd(); ++it) { + if (EEventFocusLost == wsEvent->Type()) + (*it)->applicationLostFocus(); + else if (EEventFocusGained == wsEvent->Type()) + (*it)->applicationGainedFocus(); + } + } + } + break; + default: + break; + } + } + bool ret = false; + if (m_eventFilter) + ret = m_eventFilter(message, result); + return ret; +} + +/*! + Constructs the CVideoPlayerUtility2 object with given \a service and \a object. + And Registers for Video Loading Notifications. +*/ +S60VideoPlayerSession::S60VideoPlayerSession(QMediaService *service, S60MediaNetworkAccessControl *object) + : S60MediaPlayerSession(service) + , m_accessPointId(0) + , m_wsSession(&CCoeEnv::Static()->WsSession()) + , m_screenDevice(CCoeEnv::Static()->ScreenDevice()) + , m_service(service) + , m_player(0) +#ifndef VIDEOOUTPUT_GRAPHICS_SURFACES + , m_dsaActive(false) + , m_dsaStopped(false) +#endif + , m_videoOutputControl(0) + , m_videoOutputDisplay(0) + , m_displayWindow(0) +#ifdef HAS_AUDIOROUTING_IN_VIDEOPLAYER + , m_audioOutput(0) +#endif + , m_audioEndpoint(DefaultAudioEndpoint) + , m_pendingChanges(0) + , m_backendInitiatedPause(false) +#ifdef HTTP_COOKIES_ENABLED + , m_destinationPckg(KUidInterfaceMMFControllerSessionInfo) +#endif +{ + DP0("S60VideoPlayerSession::S60VideoPlayerSession +++"); + + m_networkAccessControl = object; +#ifdef VIDEOOUTPUT_GRAPHICS_SURFACES + QT_TRAP_THROWING(m_player = CVideoPlayerUtility2::NewL( + *this, + 0, + EMdaPriorityPreferenceNone + )); + m_player->RegisterForVideoLoadingNotification(*this); +#else + RWindow *window = 0; + QRect extentRect; + QWidget *widget = QApplication::activeWindow(); + if (!widget) + widget = QApplication::allWidgets().at(0); + Q_ASSERT(widget); + WId wid = widget->effectiveWinId(); + if (!wid) + wid = widget->winId(); + window = static_cast<RWindow *>(wid->DrawableWindow()); + extentRect = QRect(widget->mapToGlobal(widget->pos()), widget->size()); + TRect clipRect = QRect2TRect(extentRect); + const TRect desktopRect = QRect2TRect(QApplication::desktop()->screenGeometry()); + clipRect.Intersection(desktopRect); + QT_TRAP_THROWING(m_player = CVideoPlayerUtility::NewL( + *this, + 0, + EMdaPriorityPreferenceNone, + *m_wsSession, + *m_screenDevice, + *window, + QRect2TRect(extentRect), + clipRect)); + m_dsaActive = true; + m_player->RegisterForVideoLoadingNotification(*this); +#endif // VIDEOOUTPUT_GRAPHICS_SURFACES + S60VideoPlayerEventHandler::instance()->addApplicationFocusObserver(this); + DP0("S60VideoPlayerSession::S60VideoPlayerSession ---"); +} + +/*! + Destroys the CVideoPlayerUtility2 object. + + And Unregister the observer. +*/ + +S60VideoPlayerSession::~S60VideoPlayerSession() +{ + DP0("S60VideoPlayerSession::~S60VideoPlayerSession +++"); + S60VideoPlayerEventHandler::instance()->removeApplicationFocusObserver(this); +#ifdef HAS_AUDIOROUTING_IN_VIDEOPLAYER + if (m_audioOutput) + m_audioOutput->UnregisterObserver(*this); + delete m_audioOutput; +#endif + m_player->Close(); + delete m_player; + + DP0("S60VideoPlayerSession::~S60VideoPlayerSession ---"); +} + +void S60VideoPlayerSession::applicationGainedFocus() +{ + if (m_backendInitiatedPause) { + m_backendInitiatedPause = false; + play(); + } + if (QMediaPlayer::PausedState == state()) { + TRAPD(err, m_player->RefreshFrameL()); + setError(err); + } +} + +void S60VideoPlayerSession::applicationLostFocus() +{ + if (QMediaPlayer::PlayingState == state()) { + m_backendInitiatedPause = true; + pause(); + } +} + +/*! + + Opens the a file from \a path. +*/ + +void S60VideoPlayerSession::doLoadL(const TDesC &path) +{ + DP0("S60VideoPlayerSession::doLoadL +++"); + +#ifdef HAS_AUDIOROUTING_IN_VIDEOPLAYER + // m_audioOutput needs to be reinitialized after MapcInitComplete + if (m_audioOutput) + m_audioOutput->UnregisterObserver(*this); + delete m_audioOutput; + m_audioOutput = NULL; +#endif + m_player->OpenFileL(path, KHelixUID); + + DP0("S60VideoPlayerSession::doLoadL ---"); +} + +/*! + Sets the playbackRate with \a rate. +*/ + +void S60VideoPlayerSession::setPlaybackRate(qreal rate) +{ + DP0("S60VideoPlayerSession::setPlaybackRate +++"); + + DP1("S60VideoPlayerSession::setPlaybackRate - ", rate); + + /* + * setPlaybackRate is not supported in S60 3.1 and 3.2 + * This flag will be defined for 3.1 and 3.2 + */ +#ifndef PLAY_RATE_NOT_SUPPORTED + //setPlayVelocity requires rate in the form of + //50 = 0.5x ;100 = 1.x ; 200 = 2.x ; 300 = 3.x + //so multiplying rate with 100 + TRAPD(err, m_player->SetPlayVelocityL((TInt)(rate*100))); + if (KErrNone == err) + emit playbackRateChanged(rate); + else + setError(err); +#endif + + DP0("S60VideoPlayerSession::setPlaybackRate ---"); +} + +/*! + + Opens the a Url from \a path for streaming the source. +*/ + +void S60VideoPlayerSession::doLoadUrlL(const TDesC &path) +{ + DP0("S60VideoPlayerSession::doLoadUrlL +++"); + +#ifdef HAS_AUDIOROUTING_IN_VIDEOPLAYER + // m_audioOutput needs to be reinitialized after MapcInitComplete + if (m_audioOutput) + m_audioOutput->UnregisterObserver(*this); + delete m_audioOutput; + m_audioOutput = NULL; +#endif + m_accessPointId = m_networkAccessControl->accessPointId(); + m_player->OpenUrlL(path, m_accessPointId, KNullDesC8, KHelixUID); + + DP0("S60VideoPlayerSession::doLoadUrlL ---"); +} + +/*! + + Returns the percentage of the video clip loaded. +*/ + +int S60VideoPlayerSession::doGetBufferStatusL() const +{ + // DP0("S60VideoPlayerSession::doGetBufferStatusL +++"); + + int progress = 0; + m_player->GetVideoLoadingProgressL(progress); + + // DP0("S60VideoPlayerSession::doGetBufferStatusL ---"); + + return progress; +} + +/*! + Returns the duration of the video sample in microseconds. +*/ + +qint64 S60VideoPlayerSession::doGetDurationL() const +{ + // DP0("S60VideoPlayerSession::doGetDurationL"); + + return m_player->DurationL().Int64() / qint64(1000); +} + +/*! + * Sets the \a videooutput for video rendering. +*/ + +void S60VideoPlayerSession::setVideoRenderer(QObject *videoOutput) +{ + DP0("S60VideoPlayerSession::setVideoRenderer +++"); + if (videoOutput != m_videoOutputControl) { + if (m_videoOutputDisplay) { + disconnect(m_videoOutputDisplay); + m_videoOutputDisplay->disconnect(this); + m_videoOutputDisplay = 0; + } + if (videoOutput) { + if (S60VideoWidgetControl *control = qobject_cast<S60VideoWidgetControl *>(videoOutput)) + m_videoOutputDisplay = control->display(); + if (!m_videoOutputDisplay) + return; + m_videoOutputDisplay->setNativeSize(m_nativeSize); + connect(this, SIGNAL(nativeSizeChanged(QSize)), m_videoOutputDisplay, SLOT(setNativeSize(QSize))); + connect(m_videoOutputDisplay, SIGNAL(windowHandleChanged(RWindow *)), this, SLOT(windowHandleChanged())); + connect(m_videoOutputDisplay, SIGNAL(displayRectChanged(QRect, QRect)), this, SLOT(displayRectChanged())); + connect(m_videoOutputDisplay, SIGNAL(aspectRatioModeChanged(Qt::AspectRatioMode)), this, SLOT(aspectRatioChanged())); + connect(m_videoOutputDisplay, SIGNAL(rotationChanged(qreal)), this, SLOT(rotationChanged())); +#ifndef VIDEOOUTPUT_GRAPHICS_SURFACES + connect(m_videoOutputDisplay, SIGNAL(beginVideoWindowNativePaint()), this, SLOT(suspendDirectScreenAccess())); + connect(m_videoOutputDisplay, SIGNAL(endVideoWindowNativePaint()), this, SLOT(resumeDirectScreenAccess())); +#endif + } + m_videoOutputControl = videoOutput; + windowHandleChanged(); + } + + DP0("S60VideoPlayerSession::setVideoRenderer ---"); +} + +/*! + * Apply the pending changes for window. +*/ +void S60VideoPlayerSession::applyPendingChanges(bool force) +{ + DP0("S60VideoPlayerSession::applyPendingChanges +++"); + + if ( force + || QMediaPlayer::LoadedMedia == mediaStatus() + || QMediaPlayer::StalledMedia == mediaStatus() + || QMediaPlayer::BufferingMedia == mediaStatus() + || QMediaPlayer::BufferedMedia == mediaStatus() + || QMediaPlayer::EndOfMedia == mediaStatus()) { + int error = KErrNone; + RWindow *const window = m_videoOutputDisplay ? m_videoOutputDisplay->windowHandle() : 0; + const QRect extentRect = m_videoOutputDisplay ? m_videoOutputDisplay->extentRect() : QRect(); + const QRect clipRect = m_videoOutputDisplay ? m_videoOutputDisplay->clipRect() : QRect(); +#ifdef VIDEOOUTPUT_GRAPHICS_SURFACES + if (m_pendingChanges & WindowHandle) { + if (m_displayWindow) { + m_player->RemoveDisplayWindow(*m_displayWindow); + m_displayWindow = 0; + } + if (window) { + TRAP(error, m_player->AddDisplayWindowL(*m_wsSession, *m_screenDevice, + *window, + QRect2TRect(extentRect), + QRect2TRect(clipRect))); + if (KErrNone == error) + m_displayWindow = window; + } + m_pendingChanges = ScaleFactors; + } + if (KErrNone == error && (m_pendingChanges & DisplayRect) && m_displayWindow) { + TRAP(error, m_player->SetVideoExtentL(*m_displayWindow, QRect2TRect(extentRect))); + if (KErrNone == error) + TRAP(error, m_player->SetWindowClipRectL(*m_displayWindow, QRect2TRect(clipRect))); + m_pendingChanges ^= DisplayRect; + m_pendingChanges |= ScaleFactors; + } +#else + if (m_pendingChanges & WindowHandle || m_pendingChanges & DisplayRect) { + if (window) { + TRAP(error, m_player->SetDisplayWindowL(*m_wsSession, *m_screenDevice, + *window, + QRect2TRect(extentRect), + QRect2TRect(clipRect))); + if (KErrNone == error) + m_displayWindow = window; + } + m_dsaActive = (KErrNone == error); + m_dsaStopped = false; + m_pendingChanges = ScaleFactors; + } + +#endif // VIDEOOUTPUT_GRAPHICS_SURFACES + if (KErrNone == error && (m_pendingChanges & ScaleFactors) && m_displayWindow && m_videoOutputDisplay) { + const TVideoRotation rotation = videoRotation(m_videoOutputDisplay->rotation()); + const bool swap = (rotation == EVideoRotationClockwise90 || rotation == EVideoRotationClockwise270); + const QSize extentSize = swap ? QSize(extentRect.height(), extentRect.width()) : extentRect.size(); + QSize scaled = m_nativeSize; + if (m_videoOutputDisplay->aspectRatioMode() == Qt::IgnoreAspectRatio) + scaled.scale(extentSize, Qt::IgnoreAspectRatio); + else if (m_videoOutputDisplay->aspectRatioMode() == Qt::KeepAspectRatio) + scaled.scale(extentSize, Qt::KeepAspectRatio); + else if (m_videoOutputDisplay->aspectRatioMode() == Qt::KeepAspectRatioByExpanding) + scaled.scale(extentSize, Qt::KeepAspectRatioByExpanding); + const qreal width = qreal(scaled.width()) / qreal(m_nativeSize.width()) * qreal(100); + const qreal height = qreal(scaled.height()) / qreal(m_nativeSize.height()) * qreal(100); +#ifdef VIDEOOUTPUT_GRAPHICS_SURFACES + TRAP(error, m_player->SetScaleFactorL(*m_displayWindow, width, height)); +#else + static const TBool antialias = ETrue; + TRAP(error, m_player->SetScaleFactorL(width, height, antialias)); +#endif // VIDEOOUTPUT_GRAPHICS_SURFACES + m_pendingChanges ^= ScaleFactors; + } + if (KErrNone == error && (m_pendingChanges && Rotation) && m_displayWindow && m_videoOutputDisplay) { + const TVideoRotation rotation = videoRotation(m_videoOutputDisplay->rotation()); +#ifdef VIDEOOUTPUT_GRAPHICS_SURFACES + TRAP(error, m_player->SetRotationL(*m_displayWindow, rotation)); +#else + TRAP(error, m_player->SetRotationL(rotation)); +#endif // VIDEOOUTPUT_GRAPHICS_SURFACES + m_pendingChanges ^= Rotation; + } + setError(error); + } + + DP0("S60VideoPlayerSession::applyPendingChanges ---"); +} + +/*! + * \return TRUE if video is available. +*/ + +bool S60VideoPlayerSession::isVideoAvailable() +{ + DP0("S60VideoPlayerSession::isVideoAvailable"); + +#ifdef PRE_S60_50_PLATFORM + return true; // this is not supported in pre 5th platforms +#else + if ( mediaStatus() == QMediaPlayer::LoadingMedia + || mediaStatus() == QMediaPlayer::UnknownMediaStatus + || mediaStatus() == QMediaPlayer::NoMedia + || (mediaStatus() == QMediaPlayer::StalledMedia && state() == QMediaPlayer::StoppedState) + || mediaStatus() == QMediaPlayer::InvalidMedia) + return false; + + if (m_player) { + bool videoAvailable = false; + TRAPD(err, videoAvailable = m_player->VideoEnabledL()); + setError(err); + return videoAvailable; + } else { + return false; + } +#endif + +} + +/*! + * \return TRUE if Audio available. +*/ + +bool S60VideoPlayerSession::isAudioAvailable() +{ + DP0("S60VideoPlayerSession::isAudioAvailable"); + + if ( mediaStatus() == QMediaPlayer::LoadingMedia + || mediaStatus() == QMediaPlayer::UnknownMediaStatus + || mediaStatus() == QMediaPlayer::NoMedia + || (mediaStatus() == QMediaPlayer::StalledMedia && state() == QMediaPlayer::StoppedState) + || mediaStatus() == QMediaPlayer::InvalidMedia) + return false; + + if (m_player) { + bool audioAvailable = false; + TRAPD(err, audioAvailable = m_player->AudioEnabledL()); + setError(err); + return audioAvailable; + } else { + return false; + } +} + +/*! + Start or resume playing the current source. +*/ + +void S60VideoPlayerSession::doPlay() +{ + DP0("S60VideoPlayerSession::doPlay +++"); + + m_player->Play(); + + DP0("S60VideoPlayerSession::doPlay ---"); +} + +/*! + Pause playing the current source. +*/ + +void S60VideoPlayerSession::doPauseL() +{ + DP0("S60VideoPlayerSession::doPauseL +++"); + + m_player->PauseL(); + + DP0("S60VideoPlayerSession::doPauseL ---"); +} + +/*! + + Stop playing, and reset the play position to the beginning. +*/ + +void S60VideoPlayerSession::doStop() +{ + DP0("S60VideoPlayerSession::doStop +++"); + + if (m_stream) + m_networkAccessControl->resetIndex(); + + m_player->Stop(); + + DP0("S60VideoPlayerSession::doStop ---"); +} + +/*! + Closes the current audio clip (allowing another clip to be opened) +*/ + +void S60VideoPlayerSession::doClose() +{ + DP0("S60VideoPlayerSession::doClose +++"); + +#ifdef HAS_AUDIOROUTING_IN_VIDEOPLAYER + if (m_audioOutput) { + m_audioOutput->UnregisterObserver(*this); + delete m_audioOutput; + m_audioOutput = NULL; + } +#endif + + m_player->Close(); + +// close will remove the window handle in media clint video. +// So mark it in pending changes. + m_pendingChanges |= WindowHandle; + + DP0("S60VideoPlayerSession::doClose ---"); +} + +/*! + * Returns the current playback position in microseconds from the start of the clip. + +*/ + +qint64 S60VideoPlayerSession::doGetPositionL() const +{ + // DP0("S60VideoPlayerSession::doGetPositionL"); + + return m_player->PositionL().Int64() / qint64(1000); +} + +/*! + Sets the current playback position to \a microSeconds from the start of the clip. +*/ + +void S60VideoPlayerSession::doSetPositionL(qint64 microSeconds) +{ + // DP0("S60VideoPlayerSession::doSetPositionL"); + + m_player->SetPositionL(TTimeIntervalMicroSeconds(microSeconds)); +} + +/*! + + Changes the current playback volume to specified \a value. +*/ + +void S60VideoPlayerSession::doSetVolumeL(int volume) +{ + DP0("S60VideoPlayerSession::doSetVolumeL +++"); + + DP1("S60VideoPlayerSession::doSetVolumeL - ", volume); + + m_player->SetVolumeL(volume * m_player->MaxVolume() / 100); + + DP0("S60VideoPlayerSession::doSetVolumeL ---"); +} + +/*! + * Notification to the client that the opening of the video clip has completed. + * If successful then an \a aError will be ZERO else system wide error. +*/ + +void S60VideoPlayerSession::MvpuoOpenComplete(TInt aError) +{ + DP0("S60VideoPlayerSession::MvpuoOpenComplete +++"); + + DP1("S60VideoPlayerSession::MvpuoOpenComplete - aError:", aError); + + setError(aError); +#ifdef HTTP_COOKIES_ENABLED + if (KErrNone == aError) { + TInt err(KErrNone); + const QByteArray userAgentString("User-Agent"); + TInt uasize = m_source.canonicalRequest().rawHeader(userAgentString).size(); + TPtrC8 userAgent((const unsigned char*)(m_source.canonicalRequest().rawHeader(userAgentString).constData()), uasize); + if (userAgent.Length()) { + err = m_player->CustomCommandSync(m_destinationPckg, EMMFSetSessionInfo, _L8("User-Agent"), userAgent); + if (err != KErrNone) { + setError(err); + return; + } + } + const QByteArray refererString("Referer"); + TInt refsize = m_source.canonicalRequest().rawHeader(refererString).size(); + TPtrC8 referer((const unsigned char*)m_source.canonicalRequest().rawHeader(refererString).constData(),refsize); + if (referer.Length()) { + err = m_player->CustomCommandSync(m_destinationPckg, EMMFSetSessionInfo, _L8("Referer"), referer); + if (err != KErrNone) { + setError(err); + return; + } + } + const QByteArray cookieString("Cookie"); + TInt cksize = m_source.canonicalRequest().rawHeader(cookieString).size(); + TPtrC8 cookie((const unsigned char*)m_source.canonicalRequest().rawHeader(cookieString).constData(),cksize); + if (cookie.Length()) { + err = m_player->CustomCommandSync(m_destinationPckg, EMMFSetSessionInfo, _L8("Cookie"), cookie); + if (err != KErrNone) { + setError(err); + return; + } + } + m_player->Prepare(); + } +#else + if (KErrNone == aError) + m_player->Prepare(); +#endif + const TMMFMessageDestinationPckg dest( KUidInterfaceMMFROPController ); + TRAP_IGNORE(m_player->CustomCommandSync(dest, KMMFROPControllerEnablePausedLoadingStatus, KNullDesC8, KNullDesC8)); + + DP0("S60VideoPlayerSession::MvpuoOpenComplete ---"); +} + +/*! + * Notification to the client that the opening of the video clip has been preapred. + * If successful then an \a aError will be ZERO else system wide error. +*/ + +void S60VideoPlayerSession::MvpuoPrepareComplete(TInt aError) +{ + DP0("S60VideoPlayerSession::MvpuoPrepareComplete +++"); + + DP1("S60VideoPlayerSession::MvpuoPrepareComplete - aError:", aError); + + if (KErrNone == aError && m_stream) { + emit accessPointChanged(m_accessPointId); + } + if (KErrCouldNotConnect == aError && !(m_networkAccessControl->isLastAccessPoint())) { + load(m_source); + return; + } + TInt error = aError; + if (KErrNone == error || KErrMMPartialPlayback == error) { + TSize originalSize; + TRAP(error, m_player->VideoFrameSizeL(originalSize)); + if (KErrNone == error) { + m_nativeSize = QSize(originalSize.iWidth, originalSize.iHeight); + emit nativeSizeChanged(m_nativeSize); + m_pendingChanges |= ScaleFactors; +#ifdef HAS_AUDIOROUTING_IN_VIDEOPLAYER + Q_ASSERT(!m_audioOutput); + TRAP(error, m_audioOutput = CAudioOutput::NewL(*m_player)); + if (KErrNone == error) { + TRAP(error, m_audioOutput->RegisterObserverL(*this)); + if (KErrNone == error) + setActiveEndpoint(m_audioEndpoint); + } +#endif + } + if (KErrNone == error) { + applyPendingChanges(true); // force apply even though state is not Loaded + if (KErrNone == this->error()) // applyPendingChanges() can call setError() + loaded(); + } + } else { + setError(error); + } + + DP0("S60VideoPlayerSession::MvpuoPrepareComplete ---"); +} + +/*! + * Notification that frame requested by a call to GetFrameL is ready. +*/ + +void S60VideoPlayerSession::MvpuoFrameReady(CFbsBitmap &aFrame, TInt aError) +{ + DP0("S60VideoPlayerSession::MvpuoFrameReady +++"); + + Q_UNUSED(aFrame); + Q_UNUSED(aError); + + DP0("S60VideoPlayerSession::MvpuoFrameReady ---"); +} + +/*! + * Notification that video playback has completed. + * If successful then \a aError will be ZERO else system wide error. + * This not called if playback is explicitly stopped by calling stop. +*/ + +void S60VideoPlayerSession::MvpuoPlayComplete(TInt aError) +{ + DP0("S60VideoPlayerSession::MvpuoPlayComplete +++"); + + DP1("S60VideoPlayerSession::MvpuoPlayComplete - aError", aError); + + if (m_stream) + m_networkAccessControl->resetIndex(); + + if (aError != KErrNone) { + setError(aError); + doClose(); + } else { + endOfMedia(); + } + + DP0("S60VideoPlayerSession::MvpuoPlayComplete ---"); +} + + +/*! + * General \a event notification from controller. + * These events are specified by the supplier of the controller. +*/ + +void S60VideoPlayerSession::MvpuoEvent(const TMMFEvent &aEvent) +{ + DP0("S60VideoPlayerSession::MvpuoEvent +++"); + + Q_UNUSED(aEvent); + + DP0("S60VideoPlayerSession::MvpuoEvent ---"); +} + +/*! + + Updates meta data entries in the current video clip. +*/ + +void S60VideoPlayerSession::updateMetaDataEntriesL() +{ + DP0("S60VideoPlayerSession::updateMetaDataEntriesL +++"); + + metaDataEntries().clear(); + int numberOfMetaDataEntries = 0; + numberOfMetaDataEntries = m_player->NumberOfMetaDataEntriesL(); + for (int i = 0; i < numberOfMetaDataEntries; i++) { + CMMFMetaDataEntry *entry = NULL; + entry = m_player->MetaDataEntryL(i); + metaDataEntries().insert(TDesC2QString(entry->Name()), TDesC2QString(entry->Value())); + delete entry; + } + emit metaDataChanged(); + + DP0("S60VideoPlayerSession::updateMetaDataEntriesL ---"); +} + +/*! + * Apply the window changes when window handle changes. +*/ + +void S60VideoPlayerSession::windowHandleChanged() +{ + DP0("S60VideoPlayerSession::windowHandleChanged +++"); + + m_pendingChanges |= WindowHandle; + applyPendingChanges(); + + DP0("S60VideoPlayerSession::windowHandleChanged ---"); +} + +/*! + * Apply the window changes when display Rect changes. +*/ + +void S60VideoPlayerSession::displayRectChanged() +{ + DP0("S60VideoPlayerSession::displayRectChanged +++"); + + m_pendingChanges |= DisplayRect; + applyPendingChanges(); + + DP0("S60VideoPlayerSession::displayRectChanged ---"); +} + +/*! + * Apply the window changes when aspect Ratio changes. +*/ + +void S60VideoPlayerSession::aspectRatioChanged() +{ + DP0("S60VideoPlayerSession::aspectRatioChanged +++"); + + m_pendingChanges |= ScaleFactors; + applyPendingChanges(); + + DP0("S60VideoPlayerSession::aspectRatioChanged ---"); +} + +void S60VideoPlayerSession::rotationChanged() +{ + m_pendingChanges |= ScaleFactors; + m_pendingChanges |= Rotation; + applyPendingChanges(); +} + +#ifndef VIDEOOUTPUT_GRAPHICS_SURFACES +void S60VideoPlayerSession::suspendDirectScreenAccess() +{ + DP0("S60VideoPlayerSession::suspendDirectScreenAccess +++"); + + m_dsaStopped = stopDirectScreenAccess(); + + DP0("S60VideoPlayerSession::suspendDirectScreenAccess ---"); +} + +void S60VideoPlayerSession::resumeDirectScreenAccess() +{ + DP0("S60VideoPlayerSession::resumeDirectScreenAccess +++"); + + if (!m_dsaStopped) + return; + startDirectScreenAccess(); + m_dsaStopped = false; + + DP0("S60VideoPlayerSession::resumeDirectScreenAccess ---"); +} + +void S60VideoPlayerSession::startDirectScreenAccess() +{ + DP0("S60VideoPlayerSession::startDirectScreenAccess +++"); + + if (m_dsaActive) + return; + TRAPD(err, m_player->StartDirectScreenAccessL()); + if (err == KErrNone) + m_dsaActive = true; + setError(err); + + DP0("S60VideoPlayerSession::startDirectScreenAccess ---"); +} + +bool S60VideoPlayerSession::stopDirectScreenAccess() +{ + DP0("S60VideoPlayerSession::stopDirectScreenAccess"); + + if (!m_dsaActive) + return false; + TRAPD(err, m_player->StopDirectScreenAccessL()); + if (err == KErrNone) + m_dsaActive = false; + setError(err); + return true; +} +#endif + +/*! + * The percentage of the temporary buffer filling before playback begins. +*/ + +void S60VideoPlayerSession::MvloLoadingStarted() +{ + DP0("S60VideoPlayerSession::MvloLoadingStarted +++"); + + buffering(); + + DP0("S60VideoPlayerSession::MvloLoadingStarted ---"); +} + +/*! + * Buffer is filled with data and to for continuing/start playback. +*/ + +void S60VideoPlayerSession::MvloLoadingComplete() +{ + DP0("S60VideoPlayerSession::MvloLoadingComplete +++"); + + buffered(); + + DP0("S60VideoPlayerSession::MvloLoadingComplete ---"); +} + +/*! + Defiens which Audio End point to use. + + \a audioEndpoint audioEndpoint name. +*/ + +void S60VideoPlayerSession::doSetAudioEndpoint(const QString& audioEndpoint) +{ + DP0("S60VideoPlayerSession::doSetAudioEndpoint +++"); + + DP1("S60VideoPlayerSession::doSetAudioEndpoint - ", audioEndpoint); + + m_audioEndpoint = audioEndpoint; + + DP0("S60VideoPlayerSession::doSetAudioEndpoint ---"); +} + +/*! + + Returns audioEndpoint name. +*/ + +QString S60VideoPlayerSession::activeEndpoint() const +{ + DP0("S60VideoPlayerSession::activeEndpoint +++"); + + QString outputName = m_audioEndpoint; +#ifdef HAS_AUDIOROUTING_IN_VIDEOPLAYER + if (m_audioOutput) { + CAudioOutput::TAudioOutputPreference output = m_audioOutput->AudioOutput(); + outputName = qStringFromTAudioOutputPreference(output); + } +#endif + + DP1("S60VideoPlayerSession::activeEndpoint- outputName:", outputName); + DP0("S60VideoPlayerSession::activeEndpoint ---"); + return outputName; +} + +/*! + * Returns default Audio End point in use. +*/ + +QString S60VideoPlayerSession::defaultEndpoint() const +{ + DP0("S60VideoPlayerSession::defaultEndpoint +++"); + + QString outputName = DefaultAudioEndpoint; +#ifdef HAS_AUDIOROUTING_IN_VIDEOPLAYER + if (m_audioOutput) { + CAudioOutput::TAudioOutputPreference output = m_audioOutput->DefaultAudioOutput(); + outputName = qStringFromTAudioOutputPreference(output); + } +#endif + + DP1("S60VideoPlayerSession::defaultEndpoint, outputName:", outputName); + DP0("S60VideoPlayerSession::defaultEndpoint ---"); + + return outputName; +} + +/*! + Sets active end \a name as an Audio End point. +*/ + +void S60VideoPlayerSession::setActiveEndpoint(const QString& name) +{ + DP0("S60VideoPlayerSession::setActiveEndpoint +++"); + + DP1("S60VideoPlayerSession::setActiveEndpoint - ", name); + +#ifdef HAS_AUDIOROUTING_IN_VIDEOPLAYER + CAudioOutput::TAudioOutputPreference output = CAudioOutput::ENoPreference; + if (name == DefaultAudioEndpoint) + output = CAudioOutput::ENoPreference; + else if (name == QString("All")) + output = CAudioOutput::EAll; + else if (name == QString("None")) + output = CAudioOutput::ENoOutput; + else if (name == QString("Earphone")) + output = CAudioOutput::EPrivate; + else if (name == QString("Speaker")) + output = CAudioOutput::EPublic; + if (m_audioOutput) { + TRAPD(err, m_audioOutput->SetAudioOutputL(output)); + setError(err); + } +#endif + + DP0("S60VideoPlayerSession::setActiveEndpoint ---"); +} + +/*! + The default Audio output has been changed. + + \a aAudioOutput Audio Output object. + + \a aNewDefault is CAudioOutput::TAudioOutputPreference. +*/ + +#ifdef HAS_AUDIOROUTING_IN_VIDEOPLAYER +void S60VideoPlayerSession::DefaultAudioOutputChanged( CAudioOutput& aAudioOutput, + CAudioOutput::TAudioOutputPreference aNewDefault) +{ + DP0("S60VideoPlayerSession::DefaultAudioOutputChanged +++"); + + // Emit already implemented in setActiveEndpoint function + Q_UNUSED(aAudioOutput) + Q_UNUSED(aNewDefault) + + DP0("S60VideoPlayerSession::DefaultAudioOutputChanged ---"); +} + +/*! + * \return CAudioOutput::ENoOutput by converting it to QString. +*/ + +QString S60VideoPlayerSession::qStringFromTAudioOutputPreference(CAudioOutput::TAudioOutputPreference output) const +{ + DP0("S60VideoPlayerSession::qStringFromTAudioOutputPreference"); + + if (output == CAudioOutput::ENoPreference) + return QString("Default"); + else if (output == CAudioOutput::EAll) + return QString("All"); + else if (output == CAudioOutput::ENoOutput) + return QString("None"); + else if (output == CAudioOutput::EPrivate) + return QString("Earphone"); + else if (output == CAudioOutput::EPublic) + return QString("Speaker"); + return QString("Default"); +} +#endif //HAS_AUDIOROUTING_IN_VIDEOPLAYER) + +/*! + * \return TRUE if video is Seekable else FALSE. +*/ + +bool S60VideoPlayerSession::getIsSeekable() const +{ + DP0("S60VideoPlayerSession::getIsSeekable +++"); + + bool seekable = ETrue; + int numberOfMetaDataEntries = 0; + + TRAPD(err, numberOfMetaDataEntries = m_player->NumberOfMetaDataEntriesL()); + if (err) + return seekable; + + for (int i = 0; i < numberOfMetaDataEntries; i++) { + CMMFMetaDataEntry *entry = NULL; + TRAP(err, entry = m_player->MetaDataEntryL(i)); + + if (err) + return seekable; + + if (!entry->Name().Compare(KSeekable)) { + if (!entry->Value().Compare(KFalse)) + seekable = EFalse; + break; + } + } + DP0("S60VideoPlayerSession::getIsSeekable ---"); + + return seekable; +} diff --git a/src/plugins/symbian/mmf/mediaplayer/s60videoplayersession.h b/src/plugins/symbian/mmf/mediaplayer/s60videoplayersession.h new file mode 100644 index 000000000..f73683af8 --- /dev/null +++ b/src/plugins/symbian/mmf/mediaplayer/s60videoplayersession.h @@ -0,0 +1,218 @@ +/**************************************************************************** +** +** Copyright (C) 2009 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$ +** +****************************************************************************/ + +#ifndef S60VIDEOPLAYERSESSION_H +#define S60VIDEOPLAYERSESSION_H + +#include "s60mediaplayersession.h" +#include "s60mediaplayeraudioendpointselector.h" +#include "s60medianetworkaccesscontrol.h" +#include "s60videodisplay.h" + +#ifdef VIDEOOUTPUT_GRAPHICS_SURFACES +#include <videoplayer2.h> +#else +#include <videoplayer.h> +#endif // VIDEOOUTPUT_GRAPHICS_SURFACES + +#include <QtCore/QCoreApplication> +#include <QtGui/qwidget.h> +#include <qvideowidget.h> + +#ifdef HAS_AUDIOROUTING_IN_VIDEOPLAYER +#include <AudioOutput.h> +#include <MAudioOutputObserver.h> +#endif // HAS_AUDIOROUTING_IN_VIDEOPLAYER + +class QTimer; +class S60MediaNetworkAccessControl; +class S60VideoDisplay; + +// Helper classes to pass Symbian events from WServ to the S60VideoPlayerSession +// so it can control video player on certain events if required + +class ApplicationFocusObserver +{ +public: + virtual void applicationGainedFocus() = 0; + virtual void applicationLostFocus() = 0; +}; + +class S60VideoPlayerEventHandler : public QObject +{ +public: + static S60VideoPlayerEventHandler *instance(); + static bool filterEvent(void *message, long *result); + void addApplicationFocusObserver(ApplicationFocusObserver* observer); + void removeApplicationFocusObserver(ApplicationFocusObserver* observer); +private: + S60VideoPlayerEventHandler(); + ~S60VideoPlayerEventHandler(); +private: + static S60VideoPlayerEventHandler *m_instance; + static QList<ApplicationFocusObserver *> m_applicationFocusObservers; + static QCoreApplication::EventFilter m_eventFilter; +}; + +class S60VideoPlayerSession : public S60MediaPlayerSession + , public MVideoPlayerUtilityObserver + , public MVideoLoadingObserver +#ifdef HAS_AUDIOROUTING_IN_VIDEOPLAYER + , public MAudioOutputObserver +#endif // HAS_AUDIOROUTING_IN_VIDEOPLAYER + , public ApplicationFocusObserver +{ + Q_OBJECT +public: + S60VideoPlayerSession(QMediaService *service, S60MediaNetworkAccessControl *object); + ~S60VideoPlayerSession(); + + // From S60MediaPlayerSession + bool isVideoAvailable(); + bool isAudioAvailable(); + void setVideoRenderer(QObject *renderer); + + // From MVideoLoadingObserver + void MvloLoadingStarted(); + void MvloLoadingComplete(); + void setPlaybackRate(qreal rate); +#ifdef HAS_AUDIOROUTING_IN_VIDEOPLAYER + // From MAudioOutputObserver + void DefaultAudioOutputChanged(CAudioOutput& aAudioOutput, + CAudioOutput::TAudioOutputPreference aNewDefault); +#endif + + // From S60MediaPlayerAudioEndpointSelector + QString activeEndpoint() const; + QString defaultEndpoint() const; + + // ApplicationFocusObserver + void applicationGainedFocus(); + void applicationLostFocus(); + +signals: + void nativeSizeChanged(QSize); + +public Q_SLOTS: + void setActiveEndpoint(const QString& name); + +signals: + void accessPointChanged(int); + +protected: + // From S60MediaPlayerSession + void doLoadL(const TDesC &path); + void doLoadUrlL(const TDesC &path); + void doPlay(); + void doStop(); + void doClose(); + void doPauseL(); + void doSetVolumeL(int volume); + qint64 doGetPositionL() const; + void doSetPositionL(qint64 microSeconds); + void updateMetaDataEntriesL(); + int doGetBufferStatusL() const; + qint64 doGetDurationL() const; + void doSetAudioEndpoint(const QString& audioEndpoint); + bool getIsSeekable() const; + +private slots: + void windowHandleChanged(); + void displayRectChanged(); + void aspectRatioChanged(); + void rotationChanged(); +#ifndef VIDEOOUTPUT_GRAPHICS_SURFACES + void suspendDirectScreenAccess(); + void resumeDirectScreenAccess(); +#endif + +private: + void applyPendingChanges(bool force = false); +#ifndef VIDEOOUTPUT_GRAPHICS_SURFACES + void startDirectScreenAccess(); + bool stopDirectScreenAccess(); +#endif +#ifdef HAS_AUDIOROUTING_IN_VIDEOPLAYER + QString qStringFromTAudioOutputPreference(CAudioOutput::TAudioOutputPreference output) const; +#endif + + // From MVideoPlayerUtilityObserver + void MvpuoOpenComplete(TInt aError); + void MvpuoPrepareComplete(TInt aError); + void MvpuoFrameReady(CFbsBitmap &aFrame, TInt aError); + void MvpuoPlayComplete(TInt aError); + void MvpuoEvent(const TMMFEvent &aEvent); + +private: + int m_accessPointId; + S60MediaNetworkAccessControl* m_networkAccessControl; + RWsSession *const m_wsSession; + CWsScreenDevice *const m_screenDevice; + QMediaService *const m_service; +#ifdef VIDEOOUTPUT_GRAPHICS_SURFACES + CVideoPlayerUtility2 *m_player; +#else + CVideoPlayerUtility *m_player; + bool m_dsaActive; + bool m_dsaStopped; +#endif // VIDEOOUTPUT_GRAPHICS_SURFACES + QObject *m_videoOutputControl; + S60VideoDisplay *m_videoOutputDisplay; + RWindow *m_displayWindow; + QSize m_nativeSize; +#ifdef HTTP_COOKIES_ENABLED + TMMFMessageDestinationPckg m_destinationPckg; +#endif +#ifdef HAS_AUDIOROUTING_IN_VIDEOPLAYER + CAudioOutput *m_audioOutput; +#endif + QString m_audioEndpoint; + enum Parameter { + WindowHandle = 0x1, + DisplayRect = 0x2, + ScaleFactors = 0x4, + Rotation = 0x8 + }; + QFlags<Parameter> m_pendingChanges; + bool m_backendInitiatedPause; +}; + +#endif diff --git a/src/plugins/symbian/mmf/mediaplayer/s60videorenderer.cpp b/src/plugins/symbian/mmf/mediaplayer/s60videorenderer.cpp new file mode 100644 index 000000000..2de6896a0 --- /dev/null +++ b/src/plugins/symbian/mmf/mediaplayer/s60videorenderer.cpp @@ -0,0 +1,95 @@ +/**************************************************************************** +** +** 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 "DebugMacros.h" + +#include "s60videorenderer.h" + +#include <QtCore/qcoreevent.h> +#include <QtGui/qapplication.h> + +/*! + Constructs a new video renderer media end point with the given \a parent. +*/ + +S60VideoRenderer::S60VideoRenderer(QObject *parent) + : QVideoRendererControl(parent) +{ + DP0("S60VideoRenderer::S60VideoRenderer +++"); + + DP0("S60VideoRenderer::S60VideoRenderer ---"); + +} + +/*! + Destroys a video renderer media end point. +*/ + +S60VideoRenderer::~S60VideoRenderer() +{ + DP0("S60VideoRenderer::~S60VideoRenderer +++"); + DP0("S60VideoRenderer::~S60VideoRenderer ---"); +} + +/*! + \return the surface a video producer renders to. +*/ + +QAbstractVideoSurface *S60VideoRenderer::surface() const +{ + DP0("S60VideoRenderer::surface"); + + return m_surface; +} + +/*! + Sets the \a surface a video producer renders to. +*/ + +void S60VideoRenderer::setSurface(QAbstractVideoSurface *surface) +{ + DP0("S60VideoRenderer::setSurface +++"); + + m_surface = surface; + + DP0("S60VideoRenderer::setSurface ---"); +} + diff --git a/src/plugins/symbian/mmf/mediaplayer/s60videorenderer.h b/src/plugins/symbian/mmf/mediaplayer/s60videorenderer.h new file mode 100644 index 000000000..6e90d42c3 --- /dev/null +++ b/src/plugins/symbian/mmf/mediaplayer/s60videorenderer.h @@ -0,0 +1,66 @@ +/**************************************************************************** +** +** 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$ +** +****************************************************************************/ + +#ifndef S60VIDEORENDERER_H +#define S60VIDEORENDERER_H + +#include <QtCore/qobject.h> +#include <qvideorenderercontrol.h> + +QT_USE_NAMESPACE + +class S60VideoRenderer : public QVideoRendererControl +{ + Q_OBJECT + +public: + S60VideoRenderer(QObject *parent = 0); + virtual ~S60VideoRenderer(); + + QAbstractVideoSurface *surface() const; + void setSurface(QAbstractVideoSurface *surface); + +private: + + QAbstractVideoSurface *m_surface; +}; + +#endif // S60VIDEORENDERER_H diff --git a/src/plugins/symbian/mmf/mediaplayer/s60videosurface.cpp b/src/plugins/symbian/mmf/mediaplayer/s60videosurface.cpp new file mode 100644 index 000000000..563d33b40 --- /dev/null +++ b/src/plugins/symbian/mmf/mediaplayer/s60videosurface.cpp @@ -0,0 +1,372 @@ +/**************************************************************************** +** +** 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 "DebugMacros.h" + +#include <qvideosurfaceformat.h> + +#include "s60videosurface.h" +/*! + * Constructs a video surface with the given \a parent. +*/ + +S60VideoSurface::S60VideoSurface(QObject *parent) + : QAbstractVideoSurface(parent) + , m_winId(0) +{ + DP0("S60VideoSurface::S60VideoSurface +++"); + DP0("S60VideoSurface::S60VideoSurface ---"); +} + +/*! + * Destroys video surface. +*/ + +S60VideoSurface::~S60VideoSurface() +{ + DP0("S60VideoSurface::~S60VideoSurface +++"); + DP0("S60VideoSurface::~S60VideoSurface ---"); +} + +/*! + \return the ID of the window a video surface end point renders to. +*/ + +WId S60VideoSurface::winId() const +{ + DP0("S60VideoSurface::winId"); + + return m_winId; +} + +/*! + Sets the \a id of the window a video surface end point renders to. +*/ + +void S60VideoSurface::setWinId(WId id) +{ + DP0("S60VideoSurface::setWinId +++"); + + m_winId = id; + + DP0("S60VideoSurface::setWinId ---"); +} + +/*! + \return the sub-rect of a window where video is displayed. +*/ + +QRect S60VideoSurface::displayRect() const +{ + DP0("S60VideoSurface::displayRect"); + + return m_displayRect; +} + +/*! + Sets the sub-\a rect of a window where video is displayed. +*/ + +void S60VideoSurface::setDisplayRect(const QRect &rect) +{ + DP0("S60VideoSurface::setDisplayRect +++"); + + m_displayRect = rect; + + DP0("S60VideoSurface::setDisplayRect ---"); +} + +/*! + \return the brightness adjustment applied to a video surface. + + Valid brightness values range between -100 and 100, the default is 0. +*/ + +int S60VideoSurface::brightness() const +{ + DP0("S60VideoSurface::brightness"); + + return 0; +} + +/*! + Sets a \a brightness adjustment for a video surface. + + Valid brightness values range between -100 and 100, the default is 0. +*/ + +void S60VideoSurface::setBrightness(int brightness) +{ + DP0("S60VideoSurface::setBrightness +++"); + + DP1("S60VideoSurface::setBrightness - brightness:", brightness); + + Q_UNUSED(brightness); + + DP0("S60VideoSurface::setBrightness ---"); +} + +/*! + \return the contrast adjustment applied to a video surface. + + Valid contrast values range between -100 and 100, the default is 0. +*/ + +int S60VideoSurface::contrast() const +{ + DP0("S60VideoSurface::contrast"); + + return 0; +} + +/*! + Sets the \a contrast adjustment for a video surface. + + Valid contrast values range between -100 and 100, the default is 0. +*/ + +void S60VideoSurface::setContrast(int contrast) +{ + DP0("S60VideoSurface::setContrast +++"); + + DP1("S60VideoSurface::setContrast - ", contrast); + + Q_UNUSED(contrast); + + DP0("S60VideoSurface::setContrast ---"); +} + +/*! + \return the hue adjustment applied to a video surface. + + Value hue values range between -100 and 100, the default is 0. +*/ + +int S60VideoSurface::hue() const +{ + DP0("S60VideoSurface::hue"); + + return 0; +} + +/*! + Sets a \a hue adjustment for a video surface. + + Valid hue values range between -100 and 100, the default is 0. +*/ + +void S60VideoSurface::setHue(int hue) +{ + DP0("S60VideoSurface::setHue +++"); + + DP1("S60VideoSurface::setHue - ", hue); + + Q_UNUSED(hue); + + DP0("S60VideoSurface::setHue ---"); +} + +/*! + \return the saturation adjustment applied to a video surface. + + Value saturation values range between -100 and 100, the default is 0. +*/ + +int S60VideoSurface::saturation() const +{ + DP0("S60VideoSurface::saturation"); + + return 0; +} + +/*! + Sets a \a saturation adjustment for a video surface. + + Valid saturation values range between -100 and 100, the default is 0. +*/ + +void S60VideoSurface::setSaturation(int saturation) +{ + DP0("S60VideoSurface::setSaturation +++"); + + DP1("S60VideoSurface::setSaturation - ", saturation); + + Q_UNUSED(saturation); + + DP0("S60VideoSurface::setSaturation ---"); +} + +/*! + * \return ZERO. \a attribute, \a minimum, \a maximum are not used. +*/ +int S60VideoSurface::getAttribute(const char *attribute, int minimum, int maximum) const +{ + DP0("S60VideoSurface::getAttribute +++"); + + Q_UNUSED(attribute); + Q_UNUSED(minimum); + Q_UNUSED(maximum); + + DP0("S60VideoSurface::getAttribute ---"); + + return 0; +} + +/*! + * Sets the \a attribute, \a minimum, \a maximum. + * But never used. +*/ + +void S60VideoSurface::setAttribute(const char *attribute, int value, int minimum, int maximum) +{ + DP0("S60VideoSurface::setAttribute +++"); + + Q_UNUSED(attribute); + Q_UNUSED(value); + Q_UNUSED(minimum); + Q_UNUSED(maximum); + + DP0("S60VideoSurface::setAttribute ---"); + +} + +/*! + * \return ZERO. + * \a value, \a fromLower, \a fromUpper, \a toLower, \a toUpper are never used. +*/ + +int S60VideoSurface::redistribute( + int value, int fromLower, int fromUpper, int toLower, int toUpper) +{ + DP0("S60VideoSurface::redistribute +++"); + + Q_UNUSED(value); + Q_UNUSED(fromLower); + Q_UNUSED(fromUpper); + Q_UNUSED(toLower); + Q_UNUSED(toUpper); + + DP0("S60VideoSurface::redistribute ---"); + + return 0; +} + +/*! + * \return List of video surface supported Pixel Formats. +*/ + +QList<QVideoFrame::PixelFormat> S60VideoSurface::supportedPixelFormats( + QAbstractVideoBuffer::HandleType handleType) const +{ + DP0("S60VideoSurface::supportedPixelFormats +++"); + + Q_UNUSED(handleType); + QList<QVideoFrame::PixelFormat> list; + + DP0("S60VideoSurface::supportedPixelFormats ---"); + + return list; +} + +/*! + * \return always FALSE, as \a format never used. +*/ + +bool S60VideoSurface::start(const QVideoSurfaceFormat &format) +{ + DP0("S60VideoSurface::start"); + + Q_UNUSED(format); + return false; +} + +/*! + * Stops video surface. +*/ +void S60VideoSurface::stop() +{ + DP0("S60VideoSurface::stop +++"); + + DP0("S60VideoSurface::stop ---"); + +} + +/*! + * \return always FALS, as \a format is never used. +*/ +bool S60VideoSurface::present(const QVideoFrame &frame) +{ + DP0("S60VideoSurface::present"); + + Q_UNUSED(frame); + return false; +} + +/*! + * \return always FALSE. +*/ + +bool S60VideoSurface::findPort() +{ + DP0("S60VideoSurface::findPort"); + + return false; +} + +void S60VideoSurface::querySupportedFormats() +{ + DP0("S60VideoSurface::querySupportedFormats +++"); + + DP0("S60VideoSurface::querySupportedFormats ---"); + +} + +/*! + * \return always FLASE, as \a format never used. +*/ + +bool S60VideoSurface::isFormatSupported(const QVideoSurfaceFormat &format) const +{ + DP0("S60VideoSurface::isFormatSupported"); + + Q_UNUSED(format); + return false; +} diff --git a/src/plugins/symbian/mmf/mediaplayer/s60videosurface.h b/src/plugins/symbian/mmf/mediaplayer/s60videosurface.h new file mode 100644 index 000000000..9f13755b7 --- /dev/null +++ b/src/plugins/symbian/mmf/mediaplayer/s60videosurface.h @@ -0,0 +1,106 @@ +/**************************************************************************** +** +** 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$ +** +****************************************************************************/ + +#ifndef S60VIDEOSURFACE_H +#define S60VIDEOSURFACE_H + +#include <QtGui/qwidget.h> +#include <qabstractvideosurface.h> + +class S60VideoSurface : public QAbstractVideoSurface +{ + Q_OBJECT +public: + S60VideoSurface(QObject *parent = 0); + ~S60VideoSurface(); + + WId winId() const; + void setWinId(WId id); + + QRect displayRect() const; + void setDisplayRect(const QRect &rect); + + int brightness() const; + void setBrightness(int brightness); + + int contrast() const; + void setContrast(int contrast); + + int hue() const; + void setHue(int hue); + + int saturation() const; + void setSaturation(int saturation); + + QList<QVideoFrame::PixelFormat> supportedPixelFormats( + QAbstractVideoBuffer::HandleType handleType = QAbstractVideoBuffer::NoHandle) const; + + bool isFormatSupported(const QVideoSurfaceFormat &format) const; + + bool start(const QVideoSurfaceFormat &format); + void stop(); + + bool present(const QVideoFrame &frame); + +private: + WId m_winId; + //XvPortID m_portId; + //GC m_gc; + //XvImage *m_image; + QList<QVideoFrame::PixelFormat> m_supportedPixelFormats; + QVector<int> m_formatIds; + QRect m_viewport; + QRect m_displayRect; + QPair<int, int> m_brightnessRange; + QPair<int, int> m_contrastRange; + QPair<int, int> m_hueRange; + QPair<int, int> m_saturationRange; + + bool findPort(); + void querySupportedFormats(); + + int getAttribute(const char *attribute, int minimum, int maximum) const; + void setAttribute(const char *attribute, int value, int minimum, int maximum); + + static int redistribute(int value, int fromLower, int fromUpper, int toLower, int toUpper); +}; + +#endif diff --git a/src/plugins/symbian/mmf/mmf.pro b/src/plugins/symbian/mmf/mmf.pro new file mode 100644 index 000000000..2bae03e59 --- /dev/null +++ b/src/plugins/symbian/mmf/mmf.pro @@ -0,0 +1,58 @@ +TEMPLATE = lib + +CONFIG += plugin +TARGET = $$qtLibraryTarget(qtmultimediakit_mmfengine) +PLUGIN_TYPE = mediaservice +include (../../../../common.pri) +qtAddLibrary(QtMultimediaKit) + +#includes here so that all defines are added here also +include(mediaplayer/mediaplayer_s60.pri) +include(radio/radio.pri) + +QT += network + +# we include mmf audiorecording only if we are not building openmaxal based backend +!contains(openmaxal_symbian_enabled, yes) { + message("Enabling mmf mediarecording backend") + include(audiosource/audiosource_s60.pri) +} + +DEPENDPATH += . +INCLUDEPATH += . \ + $${SOURCE_DIR}/include \ + $${SOURCE_DIR}/src/multimedia \ + $${SOURCE_DIR}/src/multimedia/audio \ + $${SOURCE_DIR}/src/multimedia/video \ + $${SOURCE_DIR}/plugins/multimedia/symbian/mmf/inc \ + $${SOURCE_DIR} + + +HEADERS += s60mediaserviceplugin.h \ + s60formatsupported.h + +SOURCES += s60mediaserviceplugin.cpp \ + s60formatsupported.cpp + +contains(S60_VERSION, 3.2)|contains(S60_VERSION, 3.1) { + DEFINES += PRE_S60_50_PLATFORM +} +contains(mmf_http_cookies_enabled, yes) { + DEFINES += HTTP_COOKIES_ENABLED +} +load(data_caging_paths) +TARGET.EPOCALLOWDLLDATA = 1 +TARGET.UID3=0x2002AC76 +TARGET.CAPABILITY = ALL -TCB +MMP_RULES += EXPORTUNFROZEN + +#make a sis package from plugin + api + stub (plugin) +pluginDep.sources = $${TARGET}.dll +pluginDep.path = $${QT_PLUGINS_BASE_DIR}/$${PLUGIN_TYPE} +DEPLOYMENT += pluginDep + +#Media API spesific deployment +QtMediaDeployment.sources = QtMultimediaKit.dll +QtMediaDeployment.path = /sys/bin + +DEPLOYMENT += QtMediaDeployment diff --git a/src/plugins/symbian/mmf/radio/radio.pri b/src/plugins/symbian/mmf/radio/radio.pri new file mode 100644 index 000000000..a4703d126 --- /dev/null +++ b/src/plugins/symbian/mmf/radio/radio.pri @@ -0,0 +1,24 @@ +INCLUDEPATH += $$PWD + +contains(tunerlib_s60_enabled, yes) { + + LIBS += -ltunerutility + DEFINES += TUNERLIBUSED + INCLUDEPATH += $${EPOCROOT}epoc32/include/mmf/common + + HEADERS += $$PWD/s60radiotunercontrol_31.h + SOURCES += $$PWD/s60radiotunercontrol_31.cpp +} + +contains(radioutility_s60_enabled, yes) { + LIBS += -lradio_utility + DEFINES += RADIOUTILITYLIBUSED + + HEADERS += $$PWD/s60radiotunercontrol_since32.h + SOURCES += $$PWD/s60radiotunercontrol_since32.cpp +} + +contains(tunerlib_s60_enabled, yes)|contains(radioutility_s60_enabled, yes) { + HEADERS += $$PWD/s60radiotunerservice.h + SOURCES += $$PWD/s60radiotunerservice.cpp +} diff --git a/src/plugins/symbian/mmf/radio/s60radiotunercontrol_31.cpp b/src/plugins/symbian/mmf/radio/s60radiotunercontrol_31.cpp new file mode 100644 index 000000000..b7627e312 --- /dev/null +++ b/src/plugins/symbian/mmf/radio/s60radiotunercontrol_31.cpp @@ -0,0 +1,603 @@ +/**************************************************************************** +** +** 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 "DebugMacros.h" + +#include "s60radiotunercontrol_31.h" +#include "s60radiotunerservice.h" + +#include <QtCore/qdebug.h> +#include <QFile> + +// from AudioPreference.h +const TInt KAudioPriorityFMRadio = 79; +const TUint KAudioPrefRadioAudioEvent = 0x03000001; + +S60RadioTunerControl::S60RadioTunerControl(QObject *parent) + : QRadioTunerControl(parent) + , m_error(0) + , m_tunerState(0) + , m_apiTunerState(QRadioTuner::StoppedState) + , m_audioInitializationComplete(false) + , m_radioError(QRadioTuner::NoError) + , m_muted(false) + , m_isStereo(true) + , m_stereoMode(QRadioTuner::Auto) + , m_signal(0) + , m_currentBand(QRadioTuner::FM) + , m_currentFreq(87500000) + , m_scanning(false) + , m_vol(50) +{ + DP0("S60RadioTunerControl::S60RadioTunerControl +++"); + + initRadio(); + + DP0("S60RadioTunerControl::S60RadioTunerControl ---"); +} + +S60RadioTunerControl::~S60RadioTunerControl() +{ + DP0("S60RadioTunerControl::~S60RadioTunerControl +++"); + + if (m_tunerUtility) { + m_tunerUtility->Close(); + m_tunerUtility->CancelNotifyChange(); + m_tunerUtility->CancelNotifySignalStrength(); + m_tunerUtility->CancelNotifyStereoChange(); + delete m_tunerUtility; + } + if (m_audioPlayerUtility) { + m_audioPlayerUtility = NULL; + } + + DP0("S60RadioTunerControl::~S60RadioTunerControl ---"); +} + +bool S60RadioTunerControl::initRadio() +{ + DP0("S60RadioTunerControl::initRadio +++"); + + m_available = false; + + TRAPD(tunerError, m_tunerUtility = CMMTunerUtility::NewL(*this, CMMTunerUtility::ETunerBandFm, 1, + CMMTunerUtility::ETunerAccessPriorityNormal)); + if (tunerError != KErrNone) { + m_radioError = QRadioTuner::OpenError; + return m_available; + } + + TRAPD(playerError, m_audioPlayerUtility = m_tunerUtility->TunerPlayerUtilityL(*this)); + if (playerError != KErrNone) { + m_radioError = QRadioTuner::OpenError; + return m_available; + } + + TRAPD(initializeError, m_audioPlayerUtility->InitializeL(KAudioPriorityFMRadio, + TMdaPriorityPreference(KAudioPrefRadioAudioEvent))); + if (initializeError != KErrNone) { + m_radioError = QRadioTuner::OpenError; + return m_available; + } + + m_tunerUtility->NotifyChange(*this); + m_tunerUtility->NotifyStereoChange(*this); + m_tunerUtility->NotifySignalStrength(*this); + + TFrequency freq(m_currentFreq); + m_tunerUtility->Tune(freq); + + m_available = true; + + DP0("S60RadioTunerControl::initRadio ---"); + + return m_available; +} + +void S60RadioTunerControl::start() +{ + DP0("S60RadioTunerControl::start +++"); + + if (!m_audioInitializationComplete) { + TFrequency freq(m_currentFreq); + m_tunerUtility->Tune(freq); + } else { + m_audioPlayerUtility->Play(); + } + + m_apiTunerState = QRadioTuner::ActiveState; + emit stateChanged(m_apiTunerState); + + DP0("S60RadioTunerControl::start ---"); +} + +void S60RadioTunerControl::stop() +{ + DP0("S60RadioTunerControl::stop +++"); + + if (m_audioPlayerUtility) { + m_audioPlayerUtility->Stop(); + m_apiTunerState = QRadioTuner::StoppedState; + emit stateChanged(m_apiTunerState); + } + + DP0("S60RadioTunerControl::stop ---"); +} + +QRadioTuner::State S60RadioTunerControl::state() const +{ + DP0("S60RadioTunerControl::state"); + + return m_apiTunerState; +} + +QRadioTuner::Band S60RadioTunerControl::band() const +{ + DP0("S60RadioTunerControl::band"); + + return m_currentBand; +} + +bool S60RadioTunerControl::isBandSupported(QRadioTuner::Band b) const +{ + DP0("S60RadioTunerControl::isBandSupported"); + + if(b == QRadioTuner::FM) + return true; + else if(b == QRadioTuner::LW) + return false; + else if(b == QRadioTuner::AM) + return true; + else if(b == QRadioTuner::SW) + return false; + else + return false; +} + +void S60RadioTunerControl::setBand(QRadioTuner::Band b) +{ + DP0("S60RadioTunerControl::setBand +++"); + + QRadioTuner::Band tempBand = b; + if (tempBand != m_currentBand) { + m_currentBand = b; + emit bandChanged(m_currentBand); + } + + DP0("S60RadioTunerControl::setBand ---"); +} + +int S60RadioTunerControl::frequency() const +{ + DP0("S60RadioTunerControl::frequency"); + + return m_currentFreq; +} + +void S60RadioTunerControl::setFrequency(int frequency) +{ + DP0("S60RadioTunerControl::setFrequency +++"); + + m_currentFreq = frequency; + TFrequency freq(m_currentFreq); + m_tunerUtility->Tune(freq); + + DP0("S60RadioTunerControl::setFrequency ---"); +} + +int S60RadioTunerControl::frequencyStep(QRadioTuner::Band b) const +{ + DP0("S60RadioTunerControl::frequencyStep +++"); + + int step = 0; + + if(b == QRadioTuner::FM) + step = 100000; // 100kHz steps + else if(b == QRadioTuner::LW) + step = 1000; // 1kHz steps + else if(b == QRadioTuner::AM) + step = 1000; // 1kHz steps + else if(b == QRadioTuner::SW) + step = 500; // 500Hz steps + + DP1("S60RadioTunerControl::frequencyStep, Step:", step); + DP0("S60RadioTunerControl::frequencyStep ---"); + + return step; +} + +QPair<int,int> S60RadioTunerControl::frequencyRange(QRadioTuner::Band band) const +{ + DP0("S60RadioTunerControl::frequencyRange +++"); + + TFrequency bottomFreq; + TFrequency topFreq; + int bandError = KErrNone; + + if (m_tunerUtility){ + bandError = m_tunerUtility->GetFrequencyBandRange(bottomFreq, topFreq); + if (!bandError) { + return qMakePair<int,int>(bottomFreq.iFrequency, topFreq.iFrequency); + } + } + + DP0("S60RadioTunerControl::frequencyRange ---"); + + return qMakePair<int,int>(0,0); +} + +CMMTunerUtility::TTunerBand S60RadioTunerControl::getNativeBand(QRadioTuner::Band b) const +{ + DP0("S60RadioTunerControl::getNativeBand"); + + // api match to native s60 bands + if (b == QRadioTuner::AM) + return CMMTunerUtility::ETunerBandAm; + else if (b == QRadioTuner::FM) + return CMMTunerUtility::ETunerBandFm; + else if (b == QRadioTuner::LW) + return CMMTunerUtility::ETunerBandLw; + else + return CMMTunerUtility::ETunerNoBand; +} + +bool S60RadioTunerControl::isStereo() const +{ + DP0("S60RadioTunerControl::isStereo"); + + return m_isStereo; +} + +QRadioTuner::StereoMode S60RadioTunerControl::stereoMode() const +{ + DP0("S60RadioTunerControl::stereoMode"); + + return m_stereoMode; +} + +void S60RadioTunerControl::setStereoMode(QRadioTuner::StereoMode mode) +{ + DP0("S60RadioTunerControl::setStereoMode +++"); + + m_stereoMode = mode; + if (m_tunerUtility) { + if (QRadioTuner::ForceMono == mode) + m_tunerUtility->ForceMonoReception(true); + else + m_tunerUtility->ForceMonoReception(false); + } + + DP0("S60RadioTunerControl::setStereoMode ---"); +} + +int S60RadioTunerControl::signalStrength() const +{ + DP0("S60RadioTunerControl::signalStrength +++"); + + // return value is a percentage value + if (m_tunerUtility) { + TInt maxSignalStrength; + TInt currentSignalStrength; + m_error = m_tunerUtility->GetMaxSignalStrength(maxSignalStrength); + if (m_error == KErrNone) { + m_error = m_tunerUtility->GetSignalStrength(currentSignalStrength); + if (m_error == KErrNone) { + if (maxSignalStrength == 0 || currentSignalStrength == 0) { + return 0; + } + m_signal = ((TInt64)currentSignalStrength) * 100 / maxSignalStrength; + } + } + } + + DP1("S60RadioTunerControl::signalStrength, m_signal:", m_signal); + DP0("S60RadioTunerControl::signalStrength ---"); + + return m_signal; +} + +int S60RadioTunerControl::volume() const +{ + DP0("S60RadioTunerControl::volume"); + + return m_vol; +} + +void S60RadioTunerControl::setVolume(int volume) +{ + DP0("S60RadioTunerControl::setVolume +++"); + DP1("S60RadioTunerControl::setVolume: ", volume); + + if (m_audioPlayerUtility) { + m_vol = volume; + TInt error = m_audioPlayerUtility->SetVolume(volume/10); + emit volumeChanged(m_vol); + } + + DP0("S60RadioTunerControl::setVolume ---"); +} + +bool S60RadioTunerControl::isMuted() const +{ + DP0("S60RadioTunerControl::isMuted"); + + return m_muted; +} + +void S60RadioTunerControl::setMuted(bool muted) +{ + DP0("S60RadioTunerControl::setMuted +++"); + + DP1("S60RadioTunerControl::setMuted:", muted); + + if (m_audioPlayerUtility && m_audioInitializationComplete) { + m_muted = muted; + m_audioPlayerUtility->Mute(m_muted); + emit mutedChanged(m_muted); + } + + DP0("S60RadioTunerControl::setMuted ---"); +} + +bool S60RadioTunerControl::isSearching() const +{ + DP0("S60RadioTunerControl::isSearching"); + + if (m_tunerUtility) { + TUint32 tempState; + m_tunerUtility->GetState(tempState); + if (tempState == CMMTunerUtility::ETunerStateRetuning || m_scanning) { + return true; + } else + return false; + } + return true; +} + +void S60RadioTunerControl::cancelSearch() +{ + DP0("S60RadioTunerControl::cancelSearch +++"); + + m_tunerUtility->CancelRetune(); + m_scanning = false; + emit searchingChanged(false); + + DP0("S60RadioTunerControl::cancelSearch ---"); +} + +void S60RadioTunerControl::searchForward() +{ + DP0("S60RadioTunerControl::searchForward +++"); + + m_scanning = true; + setVolume(m_vol); + m_tunerUtility->StationSeek(CMMTunerUtility::ESearchDirectionUp); + emit searchingChanged(true); + + DP0("S60RadioTunerControl::searchForward ---"); +} + +void S60RadioTunerControl::searchBackward() +{ + DP0("S60RadioTunerControl::searchBackward +++"); + + m_scanning = true; + setVolume(m_vol); + m_tunerUtility->StationSeek(CMMTunerUtility::ESearchDirectionDown); + emit searchingChanged(true); + + DP0("S60RadioTunerControl::searchBackward ---"); +} + +bool S60RadioTunerControl::isValid() const +{ + DP0("S60RadioTunerControl::isValid"); + + return m_available; +} + +bool S60RadioTunerControl::isAvailable() const +{ + DP0("S60RadioTunerControl::isAvailable"); + + return m_available; +} + +QtMultimediaKit::AvailabilityError S60RadioTunerControl::availabilityError() const +{ + DP0("S60RadioTunerControl::availabilityError"); + + if (m_available) + return QtMultimediaKit::NoError; + else + return QtMultimediaKit::ResourceError; +} + +QRadioTuner::Error S60RadioTunerControl::error() const +{ + DP1("QtMultimediaKit::NoError", m_radioError); + + return m_radioError; +} + +QString S60RadioTunerControl::errorString() const +{ + DP1("S60RadioTunerControl::errorString", m_errorString); + + return m_errorString; +} + +void S60RadioTunerControl::MToTuneComplete(TInt aError) +{ + DP0("S60RadioTunerControl::MToTuneComplete +++"); + DP1("S60RadioTunerControl::MToTuneComplete, aError:",aError); + + if (aError == KErrNone) { + m_scanning = false; + m_audioPlayerUtility->Play(); + if (!m_audioInitializationComplete) { + TRAPD(initializeError, m_audioPlayerUtility->InitializeL(KAudioPriorityFMRadio, + TMdaPriorityPreference(KAudioPrefRadioAudioEvent))); + if (initializeError != KErrNone) { + m_radioError = QRadioTuner::OpenError; + } + } + } + + DP0("S60RadioTunerControl::MToTuneComplete ---"); +} + +void S60RadioTunerControl::MTcoFrequencyChanged(const TFrequency& aOldFrequency, const TFrequency& aNewFrequency) +{ + DP0("S60RadioTunerControl::MTcoFrequencyChanged +++"); + + m_currentFreq = aNewFrequency.iFrequency; + m_scanning = false; + emit frequencyChanged(m_currentFreq); + + DP0("S60RadioTunerControl::MTcoFrequencyChanged ---"); +} + +void S60RadioTunerControl::MTcoStateChanged(const TUint32& aOldState, const TUint32& aNewState) +{ + DP0("S60RadioTunerControl::MTcoStateChanged +++"); + + if (aNewState == CMMTunerUtility::ETunerStateActive) { + m_apiTunerState = QRadioTuner::ActiveState; + } + if (aNewState == CMMTunerUtility::ETunerStatePlaying) { + m_apiTunerState = QRadioTuner::ActiveState; + } + if (aOldState != aNewState){ + emit stateChanged(m_apiTunerState); + } + + DP0("S60RadioTunerControl::MTcoStateChanged ---"); +} + +void S60RadioTunerControl::MTcoAntennaDetached() +{ + DP0("S60RadioTunerControl::MTcoAntennaDetached +++"); + + DP0("S60RadioTunerControl::MTcoAntennaDetached ---"); + + // no actions +} + +void S60RadioTunerControl::MTcoAntennaAttached() +{ + DP0("S60RadioTunerControl::MTcoAntennaAttached +++"); + + DP0("S60RadioTunerControl::MTcoAntennaAttached ---"); + + // no actions +} + +void S60RadioTunerControl::FlightModeChanged(TBool aFlightMode) +{ + DP0("S60RadioTunerControl::FlightModeChanged +++"); + + DP0("S60RadioTunerControl::FlightModeChanged ---"); + + // no actions +} + +void S60RadioTunerControl::MTsoStereoReceptionChanged(TBool aStereo) +{ + DP0("S60RadioTunerControl::MTsoStereoReceptionChanged +++"); + DP1("S60RadioTunerControl::MTsoStereoReceptionChanged, aStereo:", aStereo); + m_isStereo = aStereo; + emit stereoStatusChanged(aStereo); + + DP0("S60RadioTunerControl::MTsoStereoReceptionChanged ---"); +} + +void S60RadioTunerControl::MTsoForcedMonoChanged(TBool aForcedMono) +{ + DP0("S60RadioTunerControl::MTsoForcedMonoChanged +++"); + DP1("S60RadioTunerControl::MTsoForcedMonoChanged, aForcedMono:", aForcedMono); + + if (aForcedMono) { + m_stereoMode = QRadioTuner::ForceMono; + } + + DP0("S60RadioTunerControl::MTsoForcedMonoChanged ---"); +} + +void S60RadioTunerControl::MssoSignalStrengthChanged(TInt aNewSignalStrength) +{ + DP0("S60RadioTunerControl::MssoSignalStrengthChanged +++"); + DP1("S60RadioTunerControl::MssoSignalStrengthChanged, aNewSignalStrength:", aNewSignalStrength); + + m_signal = aNewSignalStrength; + emit signalStrengthChanged(m_signal); + + DP0("S60RadioTunerControl::MssoSignalStrengthChanged ---"); +} + +void S60RadioTunerControl::MTapoInitializeComplete(TInt aError) +{ + DP0("S60RadioTunerControl::MTapoInitializeComplete +++"); + DP1("S60RadioTunerControl::MTapoInitializeComplete, aError:", aError); + if (aError == KErrNone) { + m_audioInitializationComplete = true; + m_available = true; + m_audioPlayerUtility->Play(); + m_apiTunerState = QRadioTuner::ActiveState; + emit stateChanged(m_apiTunerState); + } else if (aError != KErrNone) { + m_radioError = QRadioTuner::OpenError; + } + + DP0("S60RadioTunerControl::MTapoInitializeComplete ---"); +} + +void S60RadioTunerControl::MTapoPlayEvent(TEventType aEvent, TInt aError, TAny* aAdditionalInfo) +{ + DP0("S60RadioTunerControl::MTapoPlayEvent +++"); + + DP0("S60RadioTunerControl::MTapoPlayEvent ---"); + + // no actions +} + + + diff --git a/src/plugins/symbian/mmf/radio/s60radiotunercontrol_31.h b/src/plugins/symbian/mmf/radio/s60radiotunercontrol_31.h new file mode 100644 index 000000000..c8bb8d362 --- /dev/null +++ b/src/plugins/symbian/mmf/radio/s60radiotunercontrol_31.h @@ -0,0 +1,161 @@ +/**************************************************************************** +** +** 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$ +** +****************************************************************************/ + +#ifndef S60RADIOTUNERCONTROL_H +#define S60RADIOTUNERCONTROL_H + +#include <QtCore/qobject.h> +#include <qradiotunercontrol.h> +#include <qradiotuner.h> +#include <tuner.h> + +class S60RadioTunerService; + +QT_USE_NAMESPACE + +class S60RadioTunerControl + : public QRadioTunerControl + , public MMMTunerObserver + , public MMMTunerStereoObserver + , public MMMSignalStrengthObserver + , public MMMTunerChangeObserver + , public MMMTunerAudioPlayerObserver +{ + Q_OBJECT +public: + S60RadioTunerControl(QObject *parent = 0); + ~S60RadioTunerControl(); + + QRadioTuner::State state() const; + + QRadioTuner::Band band() const; + void setBand(QRadioTuner::Band b); + bool isBandSupported(QRadioTuner::Band b) const; + + int frequency() const; + int frequencyStep(QRadioTuner::Band b) const; + QPair<int,int> frequencyRange(QRadioTuner::Band b) const; + void setFrequency(int frequency); + + bool isStereo() const; + QRadioTuner::StereoMode stereoMode() const; + void setStereoMode(QRadioTuner::StereoMode mode); + + int signalStrength() const; + + int volume() const; + void setVolume(int volume); + + bool isMuted() const; + void setMuted(bool muted); + + bool isSearching() const; + void searchForward(); + void searchBackward(); + void cancelSearch(); + + bool isValid() const; + + bool isAvailable() const; + QtMultimediaKit::AvailabilityError availabilityError() const; + + void start(); + void stop(); + + QRadioTuner::Error error() const; + QString errorString() const; + + //MMMTunerObserver + void MToTuneComplete(TInt aError); + + //MMMTunerChangeObserver + void MTcoFrequencyChanged(const TFrequency& aOldFrequency, const TFrequency& aNewFrequency); + void MTcoStateChanged(const TUint32& aOldState, const TUint32& aNewState); + void MTcoAntennaDetached(); + void MTcoAntennaAttached(); + void FlightModeChanged(TBool aFlightMode); + + //MMMTunerStereoObserver + void MTsoStereoReceptionChanged(TBool aStereo); + void MTsoForcedMonoChanged(TBool aForcedMono); + + //MMMSignalStrengthObserver + void MssoSignalStrengthChanged(TInt aNewSignalStrength); + + //MMMTunerAudioPlayerObserver + void MTapoInitializeComplete(TInt aError); + void MTapoPlayEvent(TEventType aEvent, TInt aError, TAny* aAdditionalInfo); + +private slots: + + +private: + bool initRadio(); + CMMTunerUtility::TTunerBand getNativeBand(QRadioTuner::Band b) const; + + mutable int m_error; + CMMTunerUtility *m_tunerUtility; + CMMTunerAudioPlayerUtility *m_audioPlayerUtility; + + bool m_audioInitializationComplete; + bool m_muted; + bool m_isStereo; + bool m_available; + int m_step; + int m_vol; + mutable int m_signal; + bool m_scanning; + bool forward; + QRadioTuner::Band m_currentBand; + qint64 m_currentFreq; + + QRadioTuner::Error m_radioError; + QRadioTuner::StereoMode m_stereoMode; + QString m_errorString; + //caps meaning what the tuner can do. + TTunerCapabilities m_currentTunerCapabilities; + long m_tunerState; + QRadioTuner::State m_apiTunerState; + +}; + +#endif + diff --git a/src/plugins/symbian/mmf/radio/s60radiotunercontrol_since32.cpp b/src/plugins/symbian/mmf/radio/s60radiotunercontrol_since32.cpp new file mode 100644 index 000000000..991c6b8e4 --- /dev/null +++ b/src/plugins/symbian/mmf/radio/s60radiotunercontrol_since32.cpp @@ -0,0 +1,685 @@ +/**************************************************************************** +** +** 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 "DebugMacros.h" + +#include "s60radiotunercontrol_since32.h" +#include "s60radiotunerservice.h" + +#include <QtCore/qdebug.h> +#include <RadioFmTunerUtility.h> + +S60RadioTunerControl::S60RadioTunerControl(QObject *parent) + : QRadioTunerControl(parent) + , m_error(0) + , m_radioUtility(NULL) + , m_fmTunerUtility(NULL) + , m_playerUtility(NULL) + , m_maxVolume(100) + , m_audioInitializationComplete(false) + , m_muted(false) + , m_isStereo(true) + , m_vol(50) + , m_signal(0) + , m_scanning(false) + , m_currentBand(QRadioTuner::FM) + , m_currentFreq(87500000) + , m_radioError(QRadioTuner::NoError) + , m_stereoMode(QRadioTuner::Auto) + , m_apiTunerState(QRadioTuner::StoppedState) + , m_previousSignal(0) + , m_volChangeRequired(false) + , m_signalStrengthTimer(new QTimer(this)) +{ + DP0("S60RadioTunerControl::S60RadioTunerControl +++"); + bool retValue = initRadio(); + if (!retValue) { + m_errorString = QString(tr("Initialize Error.")); + emit error(QRadioTuner::ResourceError); + } else { + connect(m_signalStrengthTimer, SIGNAL(timeout()), this, SLOT(changeSignalStrength())); + } + DP0("S60RadioTunerControl::S60RadioTunerControl ---"); +} + +S60RadioTunerControl::~S60RadioTunerControl() +{ + DP0("S60RadioTunerControl::~S60RadioTunerControl +++"); + + if (m_fmTunerUtility) { + m_fmTunerUtility->Close(); + } + + if (m_playerUtility) { + m_playerUtility->Close(); + } + + delete m_radioUtility; + + DP0("S60RadioTunerControl::~S60RadioTunerControl ---"); +} + +QRadioTuner::State S60RadioTunerControl::state() const +{ + DP0("S60RadioTunerControl::state"); + + return m_apiTunerState; +} + +QRadioTuner::Band S60RadioTunerControl::band() const +{ + DP0("S60RadioTunerControl::band"); + + return m_currentBand; +} + +bool S60RadioTunerControl::isBandSupported(QRadioTuner::Band b) const +{ + DP0("S60RadioTunerControl::isBandSupported"); + if (b == QRadioTuner::FM) + return true; + else if (b == QRadioTuner::LW) + return false; + else if (b == QRadioTuner::AM) + return false; + else if (b == QRadioTuner::SW) + return false; + else if (b == QRadioTuner::FM2) + return false; + else + return false; +} + +void S60RadioTunerControl::changeSignalStrength() + { + + int currentSignal = signalStrength(); + if (currentSignal != m_previousSignal) + { + m_previousSignal = currentSignal; + emit signalStrengthChanged(currentSignal); + } + } +void S60RadioTunerControl::setBand(QRadioTuner::Band b) +{ + DP0("S60RadioTunerControl::setBand +++"); + QRadioTuner::Band tempBand = b; + if (tempBand != m_currentBand ) { + if (isBandSupported(tempBand)){ + m_currentBand = b; + emit bandChanged(m_currentBand); + } + else { + switch(tempBand) + { + case QRadioTuner::FM : + m_errorString = QString(tr("Band FM not Supported")); + break; + case QRadioTuner::AM : + m_errorString = QString(tr("Band AM not Supported")); + break; + case QRadioTuner::SW : + m_errorString = QString(tr("Band SW not Supported")); + break; + case QRadioTuner::LW : + m_errorString = QString(tr("Band LW not Supported")); + break; + case QRadioTuner::FM2 : + m_errorString = QString(tr("Band FM2 not Supported")); + break; + default : + m_errorString = QString("Band %1 not Supported").arg(tempBand); + break; + } + emit error(QRadioTuner::OutOfRangeError); + } + } + + DP0("S60RadioTunerControl::setBand ---"); +} + +int S60RadioTunerControl::frequency() const +{ + DP0("S60RadioTunerControl::frequency"); + + return m_currentFreq; +} + +void S60RadioTunerControl::setFrequency(int frequency) +{ + DP0("S60RadioTunerControl::setFrequency +++"); + DP1("S60RadioTunerControl::setFrequency, frequency:", frequency); + + m_currentFreq = frequency; + m_fmTunerUtility->SetFrequency(m_currentFreq); + + DP0("S60RadioTunerControl::setFrequency ---"); +} +int S60RadioTunerControl::frequencyStep(QRadioTuner::Band b) const +{ + DP0("S60RadioTunerControl::frequencyStep +++"); + + int step = 0; + if (b == QRadioTuner::FM) + step = 100000; // 100kHz steps + else if(b == QRadioTuner::LW) + step = 1000; // 1kHz steps + else if (b == QRadioTuner::AM) + step = 1000; // 1kHz steps + else if(b == QRadioTuner::SW) + step = 500; // 500Hz steps + DP1("S60RadioTunerControl::frequencyStep, Step:", step); + DP0("S60RadioTunerControl::frequencyStep ---"); + + return step; +} + +QPair<int,int> S60RadioTunerControl::frequencyRange(QRadioTuner::Band band) const +{ + DP0("S60RadioTunerControl::frequencyRange +++"); + + int bottomFreq; + int topFreq; + + int bandError = KErrNone; + TFmRadioFrequencyRange range; + + if (m_fmTunerUtility) { + bandError = m_fmTunerUtility->GetFrequencyRange(range, bottomFreq, topFreq); + } + if (!bandError) { + return qMakePair<int,int>(bottomFreq, topFreq); + } + + DP0("S60RadioTunerControl::frequencyRange ---"); + + return qMakePair<int,int>(0,0); +} + +bool S60RadioTunerControl::isStereo() const +{ + DP0("S60RadioTunerControl::isStereo"); + + return m_isStereo; +} + +QRadioTuner::StereoMode S60RadioTunerControl::stereoMode() const +{ + DP0("S60RadioTunerControl::stereoMode"); + + return m_stereoMode; +} + +void S60RadioTunerControl::setStereoMode(QRadioTuner::StereoMode mode) +{ + DP0("S60RadioTunerControl::setStereoMode +++"); + + if (m_fmTunerUtility) { + if (QRadioTuner::ForceMono == mode) { + m_fmTunerUtility->ForceMonoReception(true); + m_stereoMode = QRadioTuner::ForceMono; + m_isStereo = false; + } else { + m_fmTunerUtility->ForceMonoReception(false); + m_isStereo = true; + m_stereoMode = QRadioTuner::ForceStereo; + } + } + + DP0("S60RadioTunerControl::setStereoMode ---"); +} + +int S60RadioTunerControl::signalStrength() const +{ + DP0("S60RadioTunerControl::signalStrength +++"); + + // return value is a percentage value + if (m_fmTunerUtility) { + TInt maxSignalStrength; + TInt currentSignalStrength; + m_error = m_fmTunerUtility->GetMaxSignalStrength(maxSignalStrength); + + if (m_error == KErrNone) { + m_error = m_fmTunerUtility->GetSignalStrength(currentSignalStrength); + if (m_error == KErrNone) { + if (currentSignalStrength == 0 || maxSignalStrength == 0) { + return currentSignalStrength; + } + m_signal = ((TInt64)currentSignalStrength) * 100 / maxSignalStrength; + } + } + } + + DP1("S60RadioTunerControl::signalStrength, m_signal:", m_signal); + DP0("S60RadioTunerControl::signalStrength ---"); + + return m_signal; +} + +int S60RadioTunerControl::volume() const +{ + DP0("S60RadioTunerControl::volume"); + + return m_vol; +} + +void S60RadioTunerControl::setVolume(int volume) +{ + DP0("S60RadioTunerControl::setVolume +++"); + DP1("S60RadioTunerControl::setVolume, Volume:", volume); + + int boundVolume = qBound(0, volume, 100); + + if (m_vol == boundVolume ) + return; + + if (!m_muted && m_playerUtility) { + m_vol = boundVolume; + // Don't set volume until State is in Active State. + if (state() == QRadioTuner::ActiveState ) { + m_playerUtility->SetVolume(m_vol*m_volMultiplier); + + } else { + m_volChangeRequired = TRUE; + emit volumeChanged(boundVolume); + } + } + DP0("S60RadioTunerControl::setVolume ---"); +} + +bool S60RadioTunerControl::isMuted() const +{ + DP0("S60RadioTunerControl::isMuted"); + + return m_muted; +} + +void S60RadioTunerControl::setMuted(bool muted) +{ + DP0("S60RadioTunerControl::setMuted +++"); + DP1("S60RadioTunerControl::setMuted, Muted:", muted); + if (m_playerUtility) { + m_muted = muted; + m_playerUtility->Mute(m_muted); + } + DP0("S60RadioTunerControl::setMuted ---"); +} + +bool S60RadioTunerControl::isSearching() const +{ + DP0("S60RadioTunerControl::isSearching"); + + return m_scanning; +} + +void S60RadioTunerControl::cancelSearch() +{ + DP0("S60RadioTunerControl::cancelSearch +++"); + + m_fmTunerUtility->CancelStationSeek(); + m_scanning = false; + emit searchingChanged(false); + + DP0("S60RadioTunerControl::cancelSearch ---"); +} + +void S60RadioTunerControl::searchForward() +{ + DP0("S60RadioTunerControl::searchForward +++"); + m_fmTunerUtility->StationSeek(true); + m_scanning = true; + emit searchingChanged(m_scanning); + DP0("S60RadioTunerControl::searchForward ---"); +} + +void S60RadioTunerControl::searchBackward() +{ + DP0("S60RadioTunerControl::searchBackward +++"); + m_fmTunerUtility->StationSeek(false); + m_scanning = true; + emit searchingChanged(m_scanning); + DP0("S60RadioTunerControl::searchBackward ---"); +} + +bool S60RadioTunerControl::isValid() const +{ + DP0("S60RadioTunerControl::isValid"); + + return m_available; +} + +bool S60RadioTunerControl::initRadio() +{ + DP0("S60RadioTunerControl::initRadio +++"); + m_available = false; + // create an instance of Radio Utility factory and indicate + // FM Radio is a primary client + TRAPD(utilityError, + m_radioUtility = CRadioUtility::NewL(ETrue); + // Get a tuner utility + m_fmTunerUtility = &m_radioUtility->RadioFmTunerUtilityL(*this); + // we want to listen radio in offline mode too + m_fmTunerUtility->EnableTunerInOfflineMode(ETrue); + // Get a player utility + m_playerUtility = &m_radioUtility->RadioPlayerUtilityL(*this); + ); + if (utilityError != KErrNone) { + m_radioError = QRadioTuner::ResourceError; + return m_available; + } + + m_tunerControl = false; + + m_available = true; + DP1("S60RadioTunerControl::initRadio, m_available:", m_available); + DP0("S60RadioTunerControl::initRadio ---"); + return m_available; +} + +bool S60RadioTunerControl::isAvailable() const +{ + DP0("S60RadioTunerControl::isAvailable"); + + return m_available; +} + +QtMultimediaKit::AvailabilityError S60RadioTunerControl::availabilityError() const +{ + DP0("S60RadioTunerControl::availabilityError"); + if (m_available) + return QtMultimediaKit::NoError; + else + return QtMultimediaKit::ResourceError; +} + +void S60RadioTunerControl::start() +{ + DP0("S60RadioTunerControl::start +++"); + if (!m_tunerControl) { + m_fmTunerUtility->RequestTunerControl(); + } else { + m_playerUtility->Play(); + } + m_signalStrengthTimer->start(3000); + + DP0("S60RadioTunerControl::start ---"); +} + +void S60RadioTunerControl::stop() +{ + DP0("S60RadioTunerControl::stop +++"); + if (m_playerUtility) { + m_playerUtility->Stop(); + } + m_signalStrengthTimer->stop(); + DP0("S60RadioTunerControl::stop ---"); +} + +QRadioTuner::Error S60RadioTunerControl::error() const +{ + DP1("S60RadioTunerControl::error", m_radioError); + + return m_radioError; +} +QString S60RadioTunerControl::errorString() const +{ + DP1("S60RadioTunerControl::errorString", m_errorString); + + return m_errorString; +} + +void S60RadioTunerControl::MrpoStateChange(TPlayerState aState, TInt aError) +{ + DP0("S60RadioTunerControl::MrpoStateChange +++"); + if (aError == KErrNone){ + m_radioError = QRadioTuner::NoError; + if (aState == ERadioPlayerIdle) { + m_apiTunerState = QRadioTuner::StoppedState; + } else if (aState == ERadioPlayerPlaying) { + m_apiTunerState = QRadioTuner::ActiveState; + //Apply pending volume changes. + if(m_volChangeRequired){ + setVolume(m_vol); + } + } + } else { + m_apiTunerState = QRadioTuner::StoppedState; + } + emit stateChanged(m_apiTunerState); + DP0("S60RadioTunerControl::MrpoStateChange ---"); +} + +void S60RadioTunerControl::MrpoVolumeChange(TInt aVolume) +{ + DP0("S60RadioTunerControl::MrpoVolumeChange +++"); + DP1("S60RadioTunerControl::MrpoVolumeChange, aVolume:", aVolume); + m_vol = (aVolume/m_volMultiplier); + if (!m_volChangeRequired) { + emit volumeChanged(m_vol); + + } else { + m_volChangeRequired = false; + } + DP0("S60RadioTunerControl::MrpoVolumeChange ---"); +} + +void S60RadioTunerControl::MrpoMuteChange(TBool aMute) +{ + DP0("S60RadioTunerControl::MrpoMuteChange +++"); + DP1("S60RadioTunerControl::MrpoMuteChange, aMute:", aMute); + m_muted = aMute; + emit mutedChanged(m_muted); + DP0("S60RadioTunerControl::MrpoMuteChange ---"); +} + +void S60RadioTunerControl::MrpoBalanceChange(TInt aLeftPercentage, TInt aRightPercentage) +{ + DP0("S60RadioTunerControl::MrpoBalanceChange +++"); + + DP0("S60RadioTunerControl::MrpoBalanceChange ---"); + + // no actions +} + +void S60RadioTunerControl::MrftoRequestTunerControlComplete(TInt aError) +{ + DP0("S60RadioTunerControl::MrftoRequestTunerControlComplete +++"); + DP1("S60RadioTunerControl::MrftoRequestTunerControlComplete, aError:", aError); + if (aError == KErrNone) { + m_playerUtility->GetMaxVolume(m_maxVolume); + m_volMultiplier = float(m_maxVolume)/float(100); + m_radioError = QRadioTuner::NoError; + m_tunerControl = true; + m_available = true; + m_fmTunerUtility->SetFrequency(m_currentFreq); + m_playerUtility->Play(); + int signal = signalStrength(); + if (m_signal != signal) { + emit signalStrengthChanged(signal); + m_signal = signal; + } + + } else if (aError == KFmRadioErrAntennaNotConnected) { + m_radioError = QRadioTuner::OpenError; + m_errorString = QString(tr("Antenna Not Connected")); + emit error(m_radioError); + } else if (aError == KErrAlreadyExists){ + m_radioError = QRadioTuner::ResourceError; + m_errorString = QString(tr("Resource Error.")); + emit error(m_radioError); + } else if (aError == KFmRadioErrFrequencyOutOfBandRange) { + m_radioError = QRadioTuner::OutOfRangeError; + m_errorString = QString(tr("Frequency out of band range")); + emit error(m_radioError); + }else{ + m_radioError = QRadioTuner::OpenError; + m_errorString = QString(tr("Unknown Error.")); + emit error(m_radioError); + } + + DP0("S60RadioTunerControl::MrftoRequestTunerControlComplete ---"); +} + +void S60RadioTunerControl::MrftoSetFrequencyRangeComplete(TInt aError) +{ + DP0("S60RadioTunerControl::MrftoSetFrequencyRangeComplete +++"); + DP1("S60RadioTunerControl::MrftoSetFrequencyRangeComplete, aError:", aError); + if (aError == KFmRadioErrFrequencyOutOfBandRange || KFmRadioErrFrequencyNotValid) { + m_radioError = QRadioTuner::OutOfRangeError; + m_errorString = QString(tr("Frequency Out of Band Range or Frequency Not Valid")); + emit error(m_radioError); + } else if (aError == KFmRadioErrHardwareFaulty || KFmRadioErrOfflineMode) { + m_radioError = QRadioTuner::OpenError; + m_errorString = QString(tr("Hardware failure or RadioInOfflineMode")); + emit error(m_radioError); + } + DP0("S60RadioTunerControl::MrftoSetFrequencyRangeComplete ---"); +} + +void S60RadioTunerControl::MrftoSetFrequencyComplete(TInt aError) +{ + DP0("S60RadioTunerControl::MrftoSetFrequencyComplete +++"); + DP1("S60RadioTunerControl::MrftoSetFrequencyComplete, aError", aError); + if (aError == KErrNone) { + m_radioError = QRadioTuner::NoError; + } else if (aError == KFmRadioErrFrequencyOutOfBandRange || KFmRadioErrFrequencyNotValid) { + m_radioError = QRadioTuner::OutOfRangeError; + m_errorString = QString(tr("Frequency Out of range or not Valid.")); + emit error(m_radioError); + } else if (aError == KFmRadioErrHardwareFaulty || KFmRadioErrOfflineMode) { + m_radioError = QRadioTuner::OpenError; + m_errorString = QString("Hardware failure or Radio In Offline Mode"); + emit error(m_radioError); + } + DP0("S60RadioTunerControl::MrftoSetFrequencyComplete ---"); +} + +void S60RadioTunerControl::MrftoStationSeekComplete(TInt aError, TInt aFrequency) +{ + DP0("S60RadioTunerControl::MrftoStationSeekComplete +++"); + DP3("S60RadioTunerControl::MrftoStationSeekComplete, aError:", aError, " Frequency:", aFrequency); + m_scanning = false; + if (aError == KErrNone) { + m_radioError = QRadioTuner::NoError; + m_currentFreq = aFrequency; + emit searchingChanged(m_scanning); + } else { + m_radioError = QRadioTuner::OpenError; + emit searchingChanged(m_scanning); + m_errorString = QString("Scanning Error"); + emit error(m_radioError); + } + DP0("S60RadioTunerControl::MrftoStationSeekComplete ---"); +} + +void S60RadioTunerControl::MrftoFmTransmitterStatusChange(TBool aActive) +{ + DP0("S60RadioTunerControl::MrftoFmTransmitterStatusChange +++"); + + DP0("S60RadioTunerControl::MrftoFmTransmitterStatusChange ---"); + + //no actions +} + +void S60RadioTunerControl::MrftoAntennaStatusChange(TBool aAttached) +{ + DP0("S60RadioTunerControl::MrftoAntennaStatusChange +++"); + DP1("S60RadioTunerControl::MrftoAntennaStatusChange, aAttached:", aAttached); + if (aAttached && m_tunerControl) { + m_playerUtility->Play(); + } + DP0("S60RadioTunerControl::MrftoAntennaStatusChange ---"); +} + +void S60RadioTunerControl::MrftoOfflineModeStatusChange(TBool /*aOfflineMode*/) +{ + DP0("S60RadioTunerControl::MrftoOfflineModeStatusChange +++"); + + DP0("S60RadioTunerControl::MrftoOfflineModeStatusChange ---"); + + +} + +void S60RadioTunerControl::MrftoFrequencyRangeChange(TFmRadioFrequencyRange aBand /*, TInt aMinFreq, TInt aMaxFreq*/) +{ + DP0("S60RadioTunerControl::MrftoFrequencyRangeChange +++"); + if (aBand == EFmRangeEuroAmerica) { + setBand(QRadioTuner::FM); + } + DP0("S60RadioTunerControl::MrftoFrequencyRangeChange ---"); +} + +void S60RadioTunerControl::MrftoFrequencyChange(TInt aNewFrequency) +{ + DP0("S60RadioTunerControl::MrftoFrequencyChange +++"); + DP1("S60RadioTunerControl::MrftoFrequencyChange, aNewFrequency:", aNewFrequency); + m_currentFreq = aNewFrequency; + emit frequencyChanged(m_currentFreq); + + int signal = signalStrength(); + if (m_signal != signal) { + emit signalStrengthChanged(signal); + m_signal = signal; + } + DP0("S60RadioTunerControl::MrftoFrequencyChange ---"); +} + +void S60RadioTunerControl::MrftoForcedMonoChange(TBool aForcedMono) +{ + DP0("S60RadioTunerControl::MrftoForcedMonoChange +++"); + DP1("S60RadioTunerControl::MrftoForcedMonoChange, aForcedMono:", aForcedMono); + if (aForcedMono) { + m_stereoMode = QRadioTuner::ForceMono; + } else { + m_stereoMode = QRadioTuner::ForceStereo; + } + emit stereoStatusChanged(!aForcedMono); + DP0("S60RadioTunerControl::MrftoForcedMonoChange ---"); +} + +void S60RadioTunerControl::MrftoSquelchChange(TBool aSquelch) +{ + DP0("S60RadioTunerControl::MrftoSquelchChange"); + + DP1("S60RadioTunerControl::MrftoSquelchChange, aSquelch:", aSquelch); + + // no actions +} diff --git a/src/plugins/symbian/mmf/radio/s60radiotunercontrol_since32.h b/src/plugins/symbian/mmf/radio/s60radiotunercontrol_since32.h new file mode 100644 index 000000000..481d64c67 --- /dev/null +++ b/src/plugins/symbian/mmf/radio/s60radiotunercontrol_since32.h @@ -0,0 +1,296 @@ +/**************************************************************************** +** +** 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$ +** +****************************************************************************/ + +#ifndef S60RADIOTUNERCONTROL_H +#define S60RADIOTUNERCONTROL_H + +#include <QtCore/qobject.h> +#include <QtCore/qtimer.h> +#include <qradiotunercontrol.h> +#include <qradiotuner.h> + +#include <RadioUtility.h> +#include <RadioFmTunerUtility.h> +#include <RadioPlayerUtility.h> + +class S60RadioTunerService; +class CFMRadioEngineCallObserver; + +QT_USE_NAMESPACE + +class S60RadioTunerControl + : public QRadioTunerControl + , public MRadioPlayerObserver + , public MRadioFmTunerObserver +{ + Q_OBJECT +public: + S60RadioTunerControl(QObject *parent = 0); + ~S60RadioTunerControl(); + + QRadioTuner::State state() const; + + QRadioTuner::Band band() const; + void setBand(QRadioTuner::Band b); + bool isBandSupported(QRadioTuner::Band b) const; + + int frequency() const; + int frequencyStep(QRadioTuner::Band b) const; + QPair<int,int> frequencyRange(QRadioTuner::Band b) const; + void setFrequency(int frequency); + + bool isStereo() const; + QRadioTuner::StereoMode stereoMode() const; + void setStereoMode(QRadioTuner::StereoMode mode); + + int signalStrength() const; + + int volume() const; + void setVolume(int volume); + + bool isMuted() const; + void setMuted(bool muted); + + bool isSearching() const; + void searchForward(); + void searchBackward(); + void cancelSearch(); + + bool isValid() const; + + bool isAvailable() const; + QtMultimediaKit::AvailabilityError availabilityError() const; + + void start(); + void stop(); + + QRadioTuner::Error error() const; + QString errorString() const; + + /** + * From MRadioPlayerObserver. + * Called when Radio state changed. + * + * @since S60 3.2 + * @param aState Radio player state + * @param aError A standard system error code, only used when aState is ERadioPlayerIdle + */ + void MrpoStateChange(TPlayerState aState, TInt aError); + + /** + * From MRadioPlayerObserver. + * Called when volume changes. This may be caused by other applications. + * + * @since S60 3.2 + * @param aVolume Current volume. + */ + void MrpoVolumeChange(TInt aVolume); + + /** + * From MRadioPlayerObserver. + * Called when mute setting changes. This may be caused by other applications. + * + * @since S60 3.2 + * @param aMute ETrue indicates audio is muted. + */ + void MrpoMuteChange(TBool aMute); + + /** + * From MRadioPlayerObserver. + * Called when mute setting changes. This may be caused by other applications. + * + * Called when balance setting changes. This may be caused by other applications. + * + * @since S60 3.2 + * Left speaker volume percentage. This can be any value from zero to 100. + * Zero value means left speaker is muted. + * @param aRightPercentage + * Right speaker volume percentage. This can be any value from zero to 100. + * Zero value means right speaker is muted. + */ + void MrpoBalanceChange(TInt aLeftPercentage, TInt aRightPercentage); + + + /** + * From MRadioFmTunerObserver. + * Called when Request for tuner control completes. + * + * @since S60 3.2 + * @param aError A standard system error code or FM tuner error (TFmRadioTunerError). + */ + void MrftoRequestTunerControlComplete(TInt aError); + + /** + * From MRadioFmTunerObserver. + * Set frequency range complete event. This event is asynchronous and is received after + * a call to CRadioFmTunerUtility::SetFrequencyRange. + * + * @since S60 3.2 + * @param aError A standard system error code or FM tuner error (TFmRadioTunerError). + */ + void MrftoSetFrequencyRangeComplete(TInt aError); + + /** + * From MRadioFmTunerObserver. + * Set frequency complete event. This event is asynchronous and is received after a call to + * CRadioFmTunerUtility::SetFrequency. + * + * @since S60 3.2 + * @param aError A standard system error code or FM tuner error (TFmRadioTunerError). + */ + void MrftoSetFrequencyComplete(TInt aError); + + /** + * From MRadioFmTunerObserver. + * Station seek complete event. This event is asynchronous and is received after a call to + * CRadioFmTunerUtility::StationSeek. + * + * @since S60 3.2 + * @param aError A standard system error code or FM tuner error (TFmRadioTunerError). + * @param aFrequency The frequency(Hz) of the radio station that was found. + */ + void MrftoStationSeekComplete(TInt aError, TInt aFrequency); + + /** + * From MRadioFmTunerObserver. + * Called when FM Transmitter status changes (if one is present in the device). Tuner receiver + * is forced to be turned off due to hardware conflicts when FM transmitter is activated. + * + * @since S60 3.2 + * @param aActive ETrue if FM transmitter is active; EFalse otherwise. + */ + void MrftoFmTransmitterStatusChange(TBool aActive); + + /** + * From MRadioFmTunerObserver. + * Called when antenna status changes. + * + * @since S60 3.2 + * @param aAttached ETrue if antenna is attached; EFalse otherwise. + */ + void MrftoAntennaStatusChange(TBool aAttached); + + /** + * From MRadioFmTunerObserver. + * Called when offline mode status changes. + * @since S60 3.2 + * + ** @param aAttached ETrue if offline mode is enabled; EFalse otherwise. + */ + void MrftoOfflineModeStatusChange(TBool aOfflineMode); + + /** + * From MRadioFmTunerObserver. + * Called when the frequency range changes. This may be caused by other applications. + * + * @since S60 3.2 + * @param aNewRange New frequency range. + */ + void MrftoFrequencyRangeChange(TFmRadioFrequencyRange aBand /*, TInt aMinFreq, TInt aMaxFreq*/); + + /** + * From MRadioFmTunerObserver. + * Called when the tuned frequency changes. This may be caused by other + * applications or RDS if AF/TA is enabled. + * + * @since S60 3.2 + * @param aNewFrequency The new tuned frequency(Hz). + */ + void MrftoFrequencyChange(TInt aNewFrequency); + + /** + * From MRadioFmTunerObserver. + * Called when the forced mono status change. This may be caused by other applications. + * + * @since S60 3.2 + * @param aForcedMono ETrue if forced mono mode is enabled; EFalse otherwise. + */ + void MrftoForcedMonoChange(TBool aForcedMono); + + /** + * From MRadioFmTunerObserver. + * Called when the squelch (muting the frequencies without broadcast) status change. + * This may be caused by other applications. + * + * @since S60 3.2 + * @param aSquelch ETrue if squelch is enabled; EFalse otherwise. + */ + void MrftoSquelchChange(TBool aSquelch); + +private: + bool initRadio(); + + mutable int m_error; + + CRadioUtility* m_radioUtility; + CRadioFmTunerUtility* m_fmTunerUtility; + CRadioPlayerUtility* m_playerUtility; + TInt m_maxVolume; + TReal m_volMultiplier; + + bool m_tunerControl; + bool m_audioInitializationComplete; + bool m_muted; + bool m_isStereo; + bool m_available; + int m_vol; + bool m_volChangeRequired; + mutable int m_signal; + int m_previousSignal; + bool m_scanning; + QRadioTuner::Band m_currentBand; + qint64 m_currentFreq; + + QRadioTuner::Error m_radioError; + QRadioTuner::StereoMode m_stereoMode; + QString m_errorString; + QRadioTuner::State m_apiTunerState; + QTimer *m_signalStrengthTimer; + +Q_SIGNALS: + void error(QRadioTuner::Error) const; + +protected slots: + void changeSignalStrength(); +}; + +#endif + diff --git a/src/plugins/symbian/mmf/radio/s60radiotunerservice.cpp b/src/plugins/symbian/mmf/radio/s60radiotunerservice.cpp new file mode 100644 index 000000000..99b0bf0d2 --- /dev/null +++ b/src/plugins/symbian/mmf/radio/s60radiotunerservice.cpp @@ -0,0 +1,83 @@ +/**************************************************************************** +** +** 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 "DebugMacros.h" + +#include "s60radiotunerservice.h" + + +S60RadioTunerService::S60RadioTunerService(QObject *parent) + : QMediaService(parent) +{ + DP0("S60RadioTunerService::S60RadioTunerService +++"); + + m_playerControl = new S60RadioTunerControl(this); + + DP0("S60RadioTunerService::S60RadioTunerService ---"); +} + +S60RadioTunerService::~S60RadioTunerService() +{ + DP0("S60RadioTunerService::~S60RadioTunerService +++"); + + delete m_playerControl; + + DP0("S60RadioTunerService::~S60RadioTunerService ---"); +} + +QMediaControl *S60RadioTunerService::requestControl(const char* name) +{ + DP0("S60RadioTunerService::requestControl"); + + if (qstrcmp(name, QRadioTunerControl_iid) == 0) + return m_playerControl; + + return 0; +} + +void S60RadioTunerService::releaseControl(QMediaControl *control) +{ + DP0("S60RadioTunerService::releaseControl +++"); + + Q_UNUSED(control); + + DP0("S60RadioTunerService::releaseControl ---"); +} diff --git a/src/plugins/symbian/mmf/radio/s60radiotunerservice.h b/src/plugins/symbian/mmf/radio/s60radiotunerservice.h new file mode 100644 index 000000000..92e3eb7f8 --- /dev/null +++ b/src/plugins/symbian/mmf/radio/s60radiotunerservice.h @@ -0,0 +1,71 @@ +/**************************************************************************** +** +** 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$ +** +****************************************************************************/ + +#ifndef S60RADIOTUNERSERVICE_H +#define S60RADIOTUNERSERVICE_H + +#include <QtCore/qobject.h> + +#include <qmediaservice.h> + +#ifdef TUNERLIBUSED +#include "s60radiotunercontrol_31.h" +#else +#include "s60radiotunercontrol_since32.h" +#endif + +QT_USE_NAMESPACE + +class S60RadioTunerService : public QMediaService +{ + Q_OBJECT +public: + S60RadioTunerService(QObject *parent = 0); + ~S60RadioTunerService(); + + QMediaControl *requestControl(const char* name); + void releaseControl(QMediaControl *control); + +private: + S60RadioTunerControl *m_playerControl; +}; + +#endif diff --git a/src/plugins/symbian/mmf/s60formatsupported.cpp b/src/plugins/symbian/mmf/s60formatsupported.cpp new file mode 100644 index 000000000..e892008ab --- /dev/null +++ b/src/plugins/symbian/mmf/s60formatsupported.cpp @@ -0,0 +1,121 @@ +/**************************************************************************** +** +** 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 "s60formatsupported.h" + + + +S60FormatSupported::S60FormatSupported() +{} + +S60FormatSupported::~S60FormatSupported() +{ + if (m_controllerparam) { + delete m_controllerparam; + m_controllerparam = NULL; + } +} + +QStringList S60FormatSupported::supportedPlayMimeTypesL() +{ + + RArray<TUid> mediaIds; //search for both audio and video + + RMMFControllerImplInfoArray iControllers; + + m_controllerparam = CMMFControllerPluginSelectionParameters::NewL(); + + m_playformatparam = CMMFFormatSelectionParameters::NewL(); + + mediaIds.Append(KUidMediaTypeAudio); + + mediaIds.Append(KUidMediaTypeVideo); + + m_controllerparam->SetMediaIdsL(mediaIds, CMMFPluginSelectionParameters::EAllowOtherMediaIds); + + m_controllerparam->SetRequiredPlayFormatSupportL(*m_playformatparam); + + m_controllerparam->ListImplementationsL(iControllers); + + CDesC8ArrayFlat* controllerArray = new (ELeave) CDesC8ArrayFlat(1); + + for (TInt i = 0; i < iControllers.Count(); i++) { + for (TInt j = 0; j < (iControllers[i]->PlayFormats()).Count(); j++) { + const CDesC8Array& iarr = (iControllers[i]->PlayFormats()[j]->SupportedMimeTypes()); + + TInt count = iarr.Count(); + + for (TInt k = 0; k < count; k++) { + TPtrC8 ptr = iarr.MdcaPoint(k); + + HBufC8* n = HBufC8::NewL(ptr.Length()); + + TPtr8 ptr1 = n->Des(); + + ptr1.Copy((TUint8*) ptr.Ptr(), ptr.Length()); + + controllerArray->AppendL(ptr1); + } + } + } + +// converting CDesC8Array to QStringList + for (TInt x = 0; x < controllerArray->Count(); x++) { + m_supportedplaymime.append(QString::fromUtf8( + (const char*) (controllerArray->MdcaPoint(x).Ptr()), + controllerArray->MdcaPoint(x).Length())); + } + + // populating the list with only audio and controller mime types + QStringList tempaudio = m_supportedplaymime.filter(QString("audio")); + QStringList tempvideo = m_supportedplaymime.filter(QString("video")); + + m_supportedplaymime.clear(); + + m_supportedplaymime = tempaudio + tempvideo; + + mediaIds.Close(); + delete controllerArray; + iControllers.ResetAndDestroy(); + + return m_supportedplaymime; +} diff --git a/src/plugins/symbian/mmf/s60formatsupported.h b/src/plugins/symbian/mmf/s60formatsupported.h new file mode 100644 index 000000000..3b5a3ffe6 --- /dev/null +++ b/src/plugins/symbian/mmf/s60formatsupported.h @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** 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$ +** +****************************************************************************/ + +#ifndef S60FORMATSUPPORTED_H_ +#define S60FORMATSUPPORTED_H_ + +#include <mmf/common/mmfcontrollerpluginresolver.h> +#include <mmf/server/mmfdatasourcesink.hrh> +#include <qstringlist.h> +#include <badesca.h> +#include <qstring.h> + +class S60FormatSupported +{ +public: + S60FormatSupported(); + ~S60FormatSupported(); + + QStringList supportedPlayMimeTypesL(); + +private: + + CMMFFormatSelectionParameters* m_playformatparam; + CMMFControllerPluginSelectionParameters* m_controllerparam; + QStringList m_supportedplaymime; +}; +#endif /* S60FORMATSUPPORTED_H_ */ diff --git a/src/plugins/symbian/mmf/s60mediaserviceplugin.cpp b/src/plugins/symbian/mmf/s60mediaserviceplugin.cpp new file mode 100644 index 000000000..cfb77255f --- /dev/null +++ b/src/plugins/symbian/mmf/s60mediaserviceplugin.cpp @@ -0,0 +1,115 @@ +/**************************************************************************** +** +** 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 <QtCore/qstring.h> +#include <QtCore/qdebug.h> + +#include "s60mediaserviceplugin.h" +#if defined(TUNERLIBUSED) || defined(RADIOUTILITYLIBUSED) +#include "s60radiotunerservice.h" +#endif +#ifdef HAS_MEDIA_PLAYER +#include "s60mediaplayerservice.h" +#endif +#ifdef AUDIOSOURCEUSED +#include "s60audiocaptureservice.h" +#endif /* AUDIOSOURCEUSED */ + +QStringList S60MediaServicePlugin::keys() const +{ + QStringList list; +#if defined(TUNERLIBUSED) || defined(RADIOUTILITYLIBUSED) + list << QLatin1String(Q_MEDIASERVICE_RADIO); +#endif + +#ifdef HAS_MEDIA_PLAYER + list << QLatin1String(Q_MEDIASERVICE_MEDIAPLAYER); +#endif +#ifdef AUDIOSOURCEUSED + list << QLatin1String(Q_MEDIASERVICE_AUDIOSOURCE); +#endif /* AUDIOSOURCEUSED */ + return list; +} + +QMediaService* S60MediaServicePlugin::create(QString const& key) +{ +#ifdef HAS_MEDIA_PLAYER + if (key == QLatin1String(Q_MEDIASERVICE_MEDIAPLAYER)) + return new S60MediaPlayerService; +#endif +#ifdef AUDIOSOURCEUSED + if (key == QLatin1String(Q_MEDIASERVICE_AUDIOSOURCE)) + return new S60AudioCaptureService; +#endif /* AUDIOSOURCEUSED */ +#if defined(TUNERLIBUSED) || defined(RADIOUTILITYLIBUSED) + if (key == QLatin1String(Q_MEDIASERVICE_RADIO)) + return new S60RadioTunerService; +#endif + + return 0; +} + +void S60MediaServicePlugin::release(QMediaService *service) +{ + delete service; +} + +QtMultimediaKit::SupportEstimate S60MediaServicePlugin::hasSupport(const QString &mimeType, const QStringList& codecs) const +{ + Q_UNUSED(mimeType); + Q_UNUSED(codecs); + return QtMultimediaKit::PreferredService; +} + +QStringList S60MediaServicePlugin::supportedMimeTypes() const +{ + if (m_supportedmimetypes.isEmpty()) { + TInt err; + S60FormatSupported* formats = new (ELeave) S60FormatSupported(); + if (formats) { + TRAP(err, m_supportedmimetypes = formats->supportedPlayMimeTypesL()); + delete formats; + } + } + return m_supportedmimetypes; +} + +Q_EXPORT_PLUGIN2(qtmultimediakit_mmfengine, S60MediaServicePlugin); diff --git a/src/plugins/symbian/mmf/s60mediaserviceplugin.h b/src/plugins/symbian/mmf/s60mediaserviceplugin.h new file mode 100644 index 000000000..b2140dd6f --- /dev/null +++ b/src/plugins/symbian/mmf/s60mediaserviceplugin.h @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** 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$ +** +****************************************************************************/ + + +#ifndef S60SERVICEPLUGIN_H +#define S60SERVICEPLUGIN_H + +#include <QtCore/qobject.h> +#include <qmediaservice.h> +#include <qmediaserviceproviderplugin.h> +#include "s60formatsupported.h" + +QT_USE_NAMESPACE + +class S60MediaServicePlugin : public QMediaServiceProviderPlugin,public QMediaServiceSupportedFormatsInterface +{ + Q_OBJECT + Q_INTERFACES(QMediaServiceSupportedFormatsInterface) +public: + + QStringList keys() const; + QMediaService* create(QString const& key); + void release(QMediaService *service); + + QtMultimediaKit::SupportEstimate hasSupport(const QString &mimeType, const QStringList& codecs) const; + QStringList supportedMimeTypes() const; +private: + mutable QStringList m_supportedmimetypes; +}; + +#endif // S60SERVICEPLUGIN_H |