| 1 | /* This file is part of the KDE project.
|
|---|
| 2 |
|
|---|
| 3 | Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
|
|---|
| 4 |
|
|---|
| 5 | This library is free software: you can redistribute it and/or modify
|
|---|
| 6 | it under the terms of the GNU Lesser General Public License as published by
|
|---|
| 7 | the Free Software Foundation, either version 2.1 or 3 of the License.
|
|---|
| 8 |
|
|---|
| 9 | This library is distributed in the hope that it will be useful,
|
|---|
| 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|---|
| 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|---|
| 12 | GNU Lesser General Public License for more details.
|
|---|
| 13 |
|
|---|
| 14 | You should have received a copy of the GNU Lesser General Public License
|
|---|
| 15 | along with this library. If not, see <http://www.gnu.org/licenses/>.
|
|---|
| 16 |
|
|---|
| 17 | */
|
|---|
| 18 |
|
|---|
| 19 | #include <QStringList>
|
|---|
| 20 | #include <QtPlugin>
|
|---|
| 21 |
|
|---|
| 22 | #include <apgcli.h> // for RApaLsSession
|
|---|
| 23 | #include <apmrec.h> // for CDataTypeArray
|
|---|
| 24 | #include <apmstd.h> // for TDataType
|
|---|
| 25 |
|
|---|
| 26 | #include "abstractaudioeffect.h"
|
|---|
| 27 | #include "audiooutput.h"
|
|---|
| 28 | #include "audioplayer.h"
|
|---|
| 29 | #include "backend.h"
|
|---|
| 30 | #include "effectfactory.h"
|
|---|
| 31 | #include "mediaobject.h"
|
|---|
| 32 | #include "utils.h"
|
|---|
| 33 | #include "videowidget.h"
|
|---|
| 34 |
|
|---|
| 35 | QT_BEGIN_NAMESPACE
|
|---|
| 36 |
|
|---|
| 37 | using namespace Phonon;
|
|---|
| 38 | using namespace Phonon::MMF;
|
|---|
| 39 |
|
|---|
| 40 | /*! \class MMF::Backend
|
|---|
| 41 | \internal
|
|---|
| 42 | */
|
|---|
| 43 |
|
|---|
| 44 | Backend::Backend(QObject *parent)
|
|---|
| 45 | : QObject(parent)
|
|---|
| 46 | #ifndef PHONON_MMF_VIDEO_SURFACES
|
|---|
| 47 | , m_ancestorMoveMonitor(new AncestorMoveMonitor(this))
|
|---|
| 48 | #endif
|
|---|
| 49 | , m_effectFactory(new EffectFactory(this))
|
|---|
| 50 | {
|
|---|
| 51 | TRACE_CONTEXT(Backend::Backend, EBackend);
|
|---|
| 52 | TRACE_ENTRY_0();
|
|---|
| 53 |
|
|---|
| 54 | setProperty("identifier", QLatin1String("phonon_mmf"));
|
|---|
| 55 | setProperty("backendName", QLatin1String("MMF"));
|
|---|
| 56 | setProperty("backendComment", QLatin1String("Backend using Symbian Multimedia Framework (MMF)"));
|
|---|
| 57 | setProperty("backendVersion", QLatin1String("0.1"));
|
|---|
| 58 | setProperty("backendWebsite", QLatin1String("http://qt.nokia.com/"));
|
|---|
| 59 |
|
|---|
| 60 | TRACE_EXIT_0();
|
|---|
| 61 | }
|
|---|
| 62 |
|
|---|
| 63 | QObject *Backend::createObject(BackendInterface::Class c, QObject *parent, const QList<QVariant> &args)
|
|---|
| 64 | {
|
|---|
| 65 | TRACE_CONTEXT(Backend::createObject, EBackend);
|
|---|
| 66 | TRACE_ENTRY("class %d", c);
|
|---|
| 67 |
|
|---|
| 68 | QObject* result = 0;
|
|---|
| 69 |
|
|---|
| 70 | switch (c) {
|
|---|
| 71 | case AudioOutputClass:
|
|---|
| 72 | result = new AudioOutput(this, parent);
|
|---|
| 73 | break;
|
|---|
| 74 |
|
|---|
| 75 | case MediaObjectClass:
|
|---|
| 76 | result = new MediaObject(parent);
|
|---|
| 77 | break;
|
|---|
| 78 |
|
|---|
| 79 | case VolumeFaderEffectClass:
|
|---|
| 80 | case VisualizationClass:
|
|---|
| 81 | case VideoDataOutputClass:
|
|---|
| 82 | case EffectClass:
|
|---|
| 83 | {
|
|---|
| 84 | Q_ASSERT(args.count() == 1);
|
|---|
| 85 | Q_ASSERT(args.first().type() == QVariant::Int);
|
|---|
| 86 | const EffectFactory::Type type =
|
|---|
| 87 | static_cast<EffectFactory::Type>(args.first().toInt());
|
|---|
| 88 | return m_effectFactory->createAudioEffect(type, parent);
|
|---|
| 89 | }
|
|---|
| 90 |
|
|---|
| 91 | case VideoWidgetClass:
|
|---|
| 92 | {
|
|---|
| 93 | VideoWidget *widget = new VideoWidget(qobject_cast<QWidget *>(parent));
|
|---|
| 94 | #ifndef PHONON_MMF_VIDEO_SURFACES
|
|---|
| 95 | widget->setAncestorMoveMonitor(m_ancestorMoveMonitor.data());
|
|---|
| 96 | #endif
|
|---|
| 97 | result = widget;
|
|---|
| 98 | }
|
|---|
| 99 | break;
|
|---|
| 100 |
|
|---|
| 101 | default:
|
|---|
| 102 | TRACE_PANIC(InvalidBackendInterfaceClass);
|
|---|
| 103 | }
|
|---|
| 104 |
|
|---|
| 105 | TRACE_RETURN("0x%08x", result);
|
|---|
| 106 | }
|
|---|
| 107 |
|
|---|
| 108 | QList<int> Backend::objectDescriptionIndexes(ObjectDescriptionType type) const
|
|---|
| 109 | {
|
|---|
| 110 | TRACE_CONTEXT(Backend::objectDescriptionIndexes, EAudioApi);
|
|---|
| 111 | TRACE_ENTRY_0();
|
|---|
| 112 | QList<int> retval;
|
|---|
| 113 |
|
|---|
| 114 | switch(type)
|
|---|
| 115 | {
|
|---|
| 116 | case EffectType:
|
|---|
| 117 | retval.append(m_effectFactory->effectIndexes());
|
|---|
| 118 | break;
|
|---|
| 119 | case AudioOutputDeviceType:
|
|---|
| 120 | // We only have one possible output device, but we need at least
|
|---|
| 121 | // one.
|
|---|
| 122 | retval.append(AudioOutput::AudioOutputDeviceID);
|
|---|
| 123 | break;
|
|---|
| 124 | default:
|
|---|
| 125 | ;
|
|---|
| 126 | }
|
|---|
| 127 |
|
|---|
| 128 | TRACE_EXIT_0();
|
|---|
| 129 | return retval;
|
|---|
| 130 | }
|
|---|
| 131 |
|
|---|
| 132 | QHash<QByteArray, QVariant> Backend::objectDescriptionProperties(ObjectDescriptionType type, int index) const
|
|---|
| 133 | {
|
|---|
| 134 | TRACE_CONTEXT(Backend::connectNodes, EBackend);
|
|---|
| 135 |
|
|---|
| 136 | switch (type) {
|
|---|
| 137 | case EffectType:
|
|---|
| 138 | return m_effectFactory->audioEffectDescriptions(EffectFactory::Type(index));
|
|---|
| 139 | case AudioOutputDeviceType:
|
|---|
| 140 | return AudioOutput::audioOutputDescription(index);
|
|---|
| 141 | default:
|
|---|
| 142 | return QHash<QByteArray, QVariant>();
|
|---|
| 143 | }
|
|---|
| 144 | }
|
|---|
| 145 |
|
|---|
| 146 | bool Backend::startConnectionChange(QSet<QObject *>)
|
|---|
| 147 | {
|
|---|
| 148 | return true;
|
|---|
| 149 | }
|
|---|
| 150 |
|
|---|
| 151 | bool Backend::connectNodes(QObject *sourceObject, QObject *targetObject)
|
|---|
| 152 | {
|
|---|
| 153 | TRACE_CONTEXT(Backend::connectNodes, EBackend);
|
|---|
| 154 | TRACE_ENTRY("source 0x%08x target 0x%08x", sourceObject, targetObject);
|
|---|
| 155 |
|
|---|
| 156 | MediaNode *const source = qobject_cast<MediaNode *>(sourceObject);
|
|---|
| 157 | MediaNode *const target = qobject_cast<MediaNode *>(targetObject);
|
|---|
| 158 |
|
|---|
| 159 | Q_ASSERT_X(source, Q_FUNC_INFO, "source is not a MediaNode");
|
|---|
| 160 | Q_ASSERT_X(target, Q_FUNC_INFO, "target is not a MediaNode");
|
|---|
| 161 |
|
|---|
| 162 | return source->connectOutput(target);
|
|---|
| 163 | }
|
|---|
| 164 |
|
|---|
| 165 | bool Backend::disconnectNodes(QObject *sourceObject, QObject *targetObject)
|
|---|
| 166 | {
|
|---|
| 167 | TRACE_CONTEXT(Backend::disconnectNodes, EBackend);
|
|---|
| 168 | TRACE_ENTRY("source 0x%08x target 0x%08x", sourceObject, targetObject);
|
|---|
| 169 |
|
|---|
| 170 | MediaNode *const source = qobject_cast<MediaNode *>(sourceObject);
|
|---|
| 171 | MediaNode *const target = qobject_cast<MediaNode *>(targetObject);
|
|---|
| 172 |
|
|---|
| 173 | Q_ASSERT_X(source, Q_FUNC_INFO, "source is not a MediaNode");
|
|---|
| 174 | Q_ASSERT_X(target, Q_FUNC_INFO, "target is not a MediaNode");
|
|---|
| 175 |
|
|---|
| 176 | return source->disconnectOutput(target);
|
|---|
| 177 | }
|
|---|
| 178 |
|
|---|
| 179 | bool Backend::endConnectionChange(QSet<QObject *>)
|
|---|
| 180 | {
|
|---|
| 181 | return true;
|
|---|
| 182 | }
|
|---|
| 183 |
|
|---|
| 184 | void getAvailableMimeTypesL(QStringList& result)
|
|---|
| 185 | {
|
|---|
| 186 | RApaLsSession apaSession;
|
|---|
| 187 | User::LeaveIfError(apaSession.Connect());
|
|---|
| 188 | CleanupClosePushL(apaSession);
|
|---|
| 189 |
|
|---|
| 190 | static const TInt DataTypeArrayGranularity = 8;
|
|---|
| 191 | CDataTypeArray* array = new(ELeave) CDataTypeArray(DataTypeArrayGranularity);
|
|---|
| 192 | CleanupStack::PushL(array);
|
|---|
| 193 |
|
|---|
| 194 | apaSession.GetSupportedDataTypesL(*array);
|
|---|
| 195 |
|
|---|
| 196 | for (TInt i = 0; i < array->Count(); ++i) {
|
|---|
| 197 | const TPtrC mimeType = array->At(i).Des();
|
|---|
| 198 | const MediaType mediaType = Utils::mimeTypeToMediaType(mimeType);
|
|---|
| 199 | if (MediaTypeAudio == mediaType or MediaTypeVideo == mediaType) {
|
|---|
| 200 | result.append(qt_TDesC2QString(mimeType));
|
|---|
| 201 | }
|
|---|
| 202 | }
|
|---|
| 203 |
|
|---|
| 204 | CleanupStack::PopAndDestroy(2); // apaSession, array
|
|---|
| 205 | }
|
|---|
| 206 |
|
|---|
| 207 | QStringList Backend::availableMimeTypes() const
|
|---|
| 208 | {
|
|---|
| 209 | QStringList result;
|
|---|
| 210 |
|
|---|
| 211 | // There is no way to return an error from this function, so we just
|
|---|
| 212 | // have to trap and ignore exceptions...
|
|---|
| 213 | TRAP_IGNORE(getAvailableMimeTypesL(result));
|
|---|
| 214 |
|
|---|
| 215 | result.sort();
|
|---|
| 216 |
|
|---|
| 217 | return result;
|
|---|
| 218 | }
|
|---|
| 219 |
|
|---|
| 220 | Q_EXPORT_PLUGIN2(phonon_mmf, Phonon::MMF::Backend);
|
|---|
| 221 |
|
|---|
| 222 | QT_END_NAMESPACE
|
|---|
| 223 |
|
|---|