/* This file is part of the KDE project. Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). This library is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 2.1 or 3 of the License. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include #include #include // for RApaLsSession #include // for CDataTypeArray #include // for TDataType #include "abstractaudioeffect.h" #include "audiooutput.h" #include "audioplayer.h" #include "backend.h" #include "effectfactory.h" #include "mediaobject.h" #include "utils.h" #include "videowidget.h" QT_BEGIN_NAMESPACE using namespace Phonon; using namespace Phonon::MMF; /*! \class MMF::Backend \internal */ Backend::Backend(QObject *parent) : QObject(parent) #ifndef PHONON_MMF_VIDEO_SURFACES , m_ancestorMoveMonitor(new AncestorMoveMonitor(this)) #endif , m_effectFactory(new EffectFactory(this)) { TRACE_CONTEXT(Backend::Backend, EBackend); TRACE_ENTRY_0(); setProperty("identifier", QLatin1String("phonon_mmf")); setProperty("backendName", QLatin1String("MMF")); setProperty("backendComment", QLatin1String("Backend using Symbian Multimedia Framework (MMF)")); setProperty("backendVersion", QLatin1String("0.1")); setProperty("backendWebsite", QLatin1String("http://qt.nokia.com/")); TRACE_EXIT_0(); } QObject *Backend::createObject(BackendInterface::Class c, QObject *parent, const QList &args) { TRACE_CONTEXT(Backend::createObject, EBackend); TRACE_ENTRY("class %d", c); QObject* result = 0; switch (c) { case AudioOutputClass: result = new AudioOutput(this, parent); break; case MediaObjectClass: result = new MediaObject(parent); break; case VolumeFaderEffectClass: case VisualizationClass: case VideoDataOutputClass: case EffectClass: { Q_ASSERT(args.count() == 1); Q_ASSERT(args.first().type() == QVariant::Int); const EffectFactory::Type type = static_cast(args.first().toInt()); return m_effectFactory->createAudioEffect(type, parent); } case VideoWidgetClass: { VideoWidget *widget = new VideoWidget(qobject_cast(parent)); #ifndef PHONON_MMF_VIDEO_SURFACES widget->setAncestorMoveMonitor(m_ancestorMoveMonitor.data()); #endif result = widget; } break; default: TRACE_PANIC(InvalidBackendInterfaceClass); } TRACE_RETURN("0x%08x", result); } QList Backend::objectDescriptionIndexes(ObjectDescriptionType type) const { TRACE_CONTEXT(Backend::objectDescriptionIndexes, EAudioApi); TRACE_ENTRY_0(); QList retval; switch(type) { case EffectType: retval.append(m_effectFactory->effectIndexes()); break; case AudioOutputDeviceType: // We only have one possible output device, but we need at least // one. retval.append(AudioOutput::AudioOutputDeviceID); break; default: ; } TRACE_EXIT_0(); return retval; } QHash Backend::objectDescriptionProperties(ObjectDescriptionType type, int index) const { TRACE_CONTEXT(Backend::connectNodes, EBackend); switch (type) { case EffectType: return m_effectFactory->audioEffectDescriptions(EffectFactory::Type(index)); case AudioOutputDeviceType: return AudioOutput::audioOutputDescription(index); default: return QHash(); } } bool Backend::startConnectionChange(QSet) { return true; } bool Backend::connectNodes(QObject *sourceObject, QObject *targetObject) { TRACE_CONTEXT(Backend::connectNodes, EBackend); TRACE_ENTRY("source 0x%08x target 0x%08x", sourceObject, targetObject); MediaNode *const source = qobject_cast(sourceObject); MediaNode *const target = qobject_cast(targetObject); Q_ASSERT_X(source, Q_FUNC_INFO, "source is not a MediaNode"); Q_ASSERT_X(target, Q_FUNC_INFO, "target is not a MediaNode"); return source->connectOutput(target); } bool Backend::disconnectNodes(QObject *sourceObject, QObject *targetObject) { TRACE_CONTEXT(Backend::disconnectNodes, EBackend); TRACE_ENTRY("source 0x%08x target 0x%08x", sourceObject, targetObject); MediaNode *const source = qobject_cast(sourceObject); MediaNode *const target = qobject_cast(targetObject); Q_ASSERT_X(source, Q_FUNC_INFO, "source is not a MediaNode"); Q_ASSERT_X(target, Q_FUNC_INFO, "target is not a MediaNode"); return source->disconnectOutput(target); } bool Backend::endConnectionChange(QSet) { return true; } void getAvailableMimeTypesL(QStringList& result) { RApaLsSession apaSession; User::LeaveIfError(apaSession.Connect()); CleanupClosePushL(apaSession); static const TInt DataTypeArrayGranularity = 8; CDataTypeArray* array = new(ELeave) CDataTypeArray(DataTypeArrayGranularity); CleanupStack::PushL(array); apaSession.GetSupportedDataTypesL(*array); for (TInt i = 0; i < array->Count(); ++i) { const TPtrC mimeType = array->At(i).Des(); const MediaType mediaType = Utils::mimeTypeToMediaType(mimeType); if (MediaTypeAudio == mediaType or MediaTypeVideo == mediaType) { result.append(qt_TDesC2QString(mimeType)); } } CleanupStack::PopAndDestroy(2); // apaSession, array } QStringList Backend::availableMimeTypes() const { QStringList result; // There is no way to return an error from this function, so we just // have to trap and ignore exceptions... TRAP_IGNORE(getAvailableMimeTypesL(result)); result.sort(); return result; } Q_EXPORT_PLUGIN2(phonon_mmf, Phonon::MMF::Backend); QT_END_NAMESPACE