| 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 | #include "backend.h"
|
|---|
| 19 | #include <QtCore/QDebug>
|
|---|
| 20 | #include <QtCore/QSet>
|
|---|
| 21 | #include <QtCore/QVariant>
|
|---|
| 22 | #include <QtCore/QtPlugin>
|
|---|
| 23 |
|
|---|
| 24 | #include "backendheader.h"
|
|---|
| 25 |
|
|---|
| 26 | #include "videowidget.h"
|
|---|
| 27 | #include "audiooutput.h"
|
|---|
| 28 | #include "mediaobject.h"
|
|---|
| 29 | #include "videoeffect.h"
|
|---|
| 30 | #include "medianode.h"
|
|---|
| 31 | #include "audiodevice.h"
|
|---|
| 32 | #include "audiomixer.h"
|
|---|
| 33 | #include "backendinfo.h"
|
|---|
| 34 | #include "quicktimeaudioplayer.h"
|
|---|
| 35 |
|
|---|
| 36 | #include "audiograph.h"
|
|---|
| 37 | #include "audiomixer.h"
|
|---|
| 38 | #include "audiooutput.h"
|
|---|
| 39 | #include "audiosplitter.h"
|
|---|
| 40 | #include "audioeffects.h"
|
|---|
| 41 |
|
|---|
| 42 | QT_BEGIN_NAMESPACE
|
|---|
| 43 |
|
|---|
| 44 | namespace Phonon
|
|---|
| 45 | {
|
|---|
| 46 | namespace QT7
|
|---|
| 47 | {
|
|---|
| 48 |
|
|---|
| 49 | Backend::Backend()
|
|---|
| 50 | {
|
|---|
| 51 | IMPLEMENTED << "Creating backend QT7";
|
|---|
| 52 | }
|
|---|
| 53 |
|
|---|
| 54 | Backend::Backend(QObject *parent, const QStringList &) : QObject(parent)
|
|---|
| 55 | {
|
|---|
| 56 | IMPLEMENTED << "Creating backend QT7";
|
|---|
| 57 | setProperty("identifier", QLatin1String("Mac OS X/QuickTime7"));
|
|---|
| 58 | setProperty("backendName", QLatin1String("Mac OS X/QuickTime7"));
|
|---|
| 59 | setProperty("backendComment", QLatin1String("Developed by Trolltech"));
|
|---|
| 60 | setProperty("backendVersion", QLatin1String("0.1"));
|
|---|
| 61 | setProperty("backendIcon", QLatin1String(""));
|
|---|
| 62 | setProperty("backendWebsite", QLatin1String("http://qt.nokia.com/"));
|
|---|
| 63 | }
|
|---|
| 64 |
|
|---|
| 65 | Backend::~Backend()
|
|---|
| 66 | {
|
|---|
| 67 | }
|
|---|
| 68 |
|
|---|
| 69 | bool Backend::quickTime7Available()
|
|---|
| 70 | {
|
|---|
| 71 | static bool ok = BackendInfo::isQuickTimeVersionAvailable(0x0700);
|
|---|
| 72 | if (!ok){
|
|---|
| 73 | static bool messageWritten = false;
|
|---|
| 74 | if (!messageWritten && qgetenv("PHONON_DEBUG") == "1"){
|
|---|
| 75 | messageWritten = true;
|
|---|
| 76 | QString str("WARNING: Phonon backend plugin need QuickTime 7 or newer to work.");
|
|---|
| 77 | str += " This computer has version "
|
|---|
| 78 | + BackendInfo::quickTimeVersionString()
|
|---|
| 79 | + " installed.";
|
|---|
| 80 | qWarning(str.toAscii().data());
|
|---|
| 81 | }
|
|---|
| 82 | return false;
|
|---|
| 83 | }
|
|---|
| 84 | return true;
|
|---|
| 85 | }
|
|---|
| 86 |
|
|---|
| 87 | QObject *Backend::createObject(BackendInterface::Class c, QObject *parent, const QList<QVariant> &args)
|
|---|
| 88 | {
|
|---|
| 89 | if (!quickTime7Available())
|
|---|
| 90 | return 0;
|
|---|
| 91 |
|
|---|
| 92 | switch (c) {
|
|---|
| 93 | case MediaObjectClass:
|
|---|
| 94 | IMPLEMENTED << "Creating new MediaObjectClass.";
|
|---|
| 95 | return new MediaObject(parent);
|
|---|
| 96 | break;
|
|---|
| 97 | case VolumeFaderEffectClass:
|
|---|
| 98 | IMPLEMENTED << "Creating new VolumeFaderEffectClass.";
|
|---|
| 99 | return new AudioMixer(parent);
|
|---|
| 100 | break;
|
|---|
| 101 | case AudioOutputClass:
|
|---|
| 102 | IMPLEMENTED << "Creating new AudioOutputClass.";
|
|---|
| 103 | return new AudioOutput(parent);
|
|---|
| 104 | break;
|
|---|
| 105 | case AudioDataOutputClass:
|
|---|
| 106 | NOT_IMPLEMENTED << "Creating new AudioDataOutputClass.";
|
|---|
| 107 | break;
|
|---|
| 108 | case VisualizationClass:
|
|---|
| 109 | NOT_IMPLEMENTED << "Creating new VisualizationClass.";
|
|---|
| 110 | break;
|
|---|
| 111 | case VideoDataOutputClass:
|
|---|
| 112 | NOT_IMPLEMENTED << "Creating new VideoDataOutputClass.";
|
|---|
| 113 | break;
|
|---|
| 114 | case EffectClass:
|
|---|
| 115 | IMPLEMENTED << "Creating new EffectClass.";
|
|---|
| 116 | return new AudioEffect(args[0].toInt());
|
|---|
| 117 | break;
|
|---|
| 118 | case VideoWidgetClass:
|
|---|
| 119 | IMPLEMENTED << "Creating new VideoWidget.";
|
|---|
| 120 | return new VideoWidget(parent);
|
|---|
| 121 | break;
|
|---|
| 122 | default:
|
|---|
| 123 | return 0;
|
|---|
| 124 | }
|
|---|
| 125 | return 0;
|
|---|
| 126 | }
|
|---|
| 127 |
|
|---|
| 128 | bool Backend::startConnectionChange(QSet<QObject *> objects)
|
|---|
| 129 | {
|
|---|
| 130 | IMPLEMENTED;
|
|---|
| 131 | QList<AudioGraph *> notifiedGraphs;
|
|---|
| 132 | for (int i=0; i<objects.size(); i++){
|
|---|
| 133 | MediaNode *node = qobject_cast<MediaNode*>(objects.values()[i]);
|
|---|
| 134 | if (node && node->m_audioGraph && !notifiedGraphs.contains(node->m_audioGraph)){
|
|---|
| 135 | MediaNodeEvent event(MediaNodeEvent::StartConnectionChange);
|
|---|
| 136 | node->m_audioGraph->notify(&event);
|
|---|
| 137 | notifiedGraphs << node->m_audioGraph;
|
|---|
| 138 | }
|
|---|
| 139 | }
|
|---|
| 140 | return true;
|
|---|
| 141 | }
|
|---|
| 142 |
|
|---|
| 143 | bool Backend::endConnectionChange(QSet<QObject *> objects)
|
|---|
| 144 | {
|
|---|
| 145 | IMPLEMENTED;
|
|---|
| 146 | QList<AudioGraph *> notifiedGraphs;
|
|---|
| 147 | for (int i=0; i<objects.size(); i++){
|
|---|
| 148 | MediaNode *node = qobject_cast<MediaNode*>(objects.values()[i]);
|
|---|
| 149 | if (node && node->m_audioGraph && !notifiedGraphs.contains(node->m_audioGraph)){
|
|---|
| 150 | MediaNodeEvent event(MediaNodeEvent::EndConnectionChange);
|
|---|
| 151 | node->m_audioGraph->notify(&event);
|
|---|
| 152 | notifiedGraphs << node->m_audioGraph;
|
|---|
| 153 | }
|
|---|
| 154 | }
|
|---|
| 155 | return true;
|
|---|
| 156 | }
|
|---|
| 157 |
|
|---|
| 158 | bool Backend::connectNodes(QObject *aSource, QObject *aSink)
|
|---|
| 159 | {
|
|---|
| 160 | IMPLEMENTED;
|
|---|
| 161 | MediaNode *source = qobject_cast<MediaNode*>(aSource);
|
|---|
| 162 | if (!source) return false;
|
|---|
| 163 | MediaNode *sink = qobject_cast<MediaNode*>(aSink);
|
|---|
| 164 | if (!sink) return false;
|
|---|
| 165 |
|
|---|
| 166 | return source->connectToSink(sink);
|
|---|
| 167 | }
|
|---|
| 168 |
|
|---|
| 169 |
|
|---|
| 170 | bool Backend::disconnectNodes(QObject *aSource, QObject *aSink)
|
|---|
| 171 | {
|
|---|
| 172 | IMPLEMENTED;
|
|---|
| 173 | MediaNode *source = qobject_cast<MediaNode*>(aSource);
|
|---|
| 174 | if (!source) return false;
|
|---|
| 175 | MediaNode *sink = qobject_cast<MediaNode*>(aSink);
|
|---|
| 176 | if (!sink) return false;
|
|---|
| 177 |
|
|---|
| 178 | return source->disconnectToSink(sink);
|
|---|
| 179 | }
|
|---|
| 180 |
|
|---|
| 181 |
|
|---|
| 182 | QStringList Backend::availableMimeTypes() const
|
|---|
| 183 | {
|
|---|
| 184 | IMPLEMENTED;
|
|---|
| 185 | return BackendInfo::quickTimeMimeTypes(BackendInfo::In);
|
|---|
| 186 | }
|
|---|
| 187 |
|
|---|
| 188 | /**
|
|---|
| 189 | * Returns a set of indexes that acts as identifiers for the various properties
|
|---|
| 190 | * this backend supports for the given ObjectDescriptionType.
|
|---|
| 191 | * More information for a given property/index can be
|
|---|
| 192 | * looked up in Backend::objectDescriptionProperties(...).
|
|---|
| 193 | */
|
|---|
| 194 | QList<int> Backend::objectDescriptionIndexes(ObjectDescriptionType type) const
|
|---|
| 195 | {
|
|---|
| 196 | QList<int> ret;
|
|---|
| 197 |
|
|---|
| 198 | switch (type){
|
|---|
| 199 | case AudioOutputDeviceType:{
|
|---|
| 200 | IMPLEMENTED_SILENT << "Creating index set for type: AudioOutputDeviceType";
|
|---|
| 201 | QList<AudioDeviceID> devices = AudioDevice::devices(AudioDevice::Out);
|
|---|
| 202 | for (int i=0; i<devices.size(); i++)
|
|---|
| 203 | ret << int(devices[i]);
|
|---|
| 204 | break; }
|
|---|
| 205 | case EffectType:{
|
|---|
| 206 | IMPLEMENTED_SILENT << "Creating index set for type: EffectType";
|
|---|
| 207 | if (QuickTimeAudioPlayer::soundPlayerIsAwailable())
|
|---|
| 208 | ret = AudioEffect::effectList();
|
|---|
| 209 | break; }
|
|---|
| 210 |
|
|---|
| 211 | #if 0 // will be awailable in a later version of phonon.
|
|---|
| 212 | case AudioCaptureDeviceType:{
|
|---|
| 213 | IMPLEMENTED_SILENT << "Creating index set for type: AudioCaptureDeviceType";
|
|---|
| 214 | QList<AudioDeviceID> devices = AudioDevice::devices(AudioDevice::In).keys();
|
|---|
| 215 | for (int i=0; i<devices.size(); i++)
|
|---|
| 216 | ret <<int(devices[i]);
|
|---|
| 217 | break; }
|
|---|
| 218 | case VideoEffectType:{
|
|---|
| 219 | // Just count the number of filters awailable (c), and
|
|---|
| 220 | // add return a set with the numbers 1..c inserted:
|
|---|
| 221 | IMPLEMENTED_SILENT << "Creating index set for type: VideoEffectType";
|
|---|
| 222 | QList<QtCore/QString> filters = objc_getCiFilterInfo()->filterDisplayNames;
|
|---|
| 223 | for (int i=0; i<filters.size(); i++)
|
|---|
| 224 | ret << insert(i);
|
|---|
| 225 | break; }
|
|---|
| 226 | #endif
|
|---|
| 227 | default:
|
|---|
| 228 | NOT_IMPLEMENTED;
|
|---|
| 229 | break;
|
|---|
| 230 | }
|
|---|
| 231 | return ret;
|
|---|
| 232 | }
|
|---|
| 233 |
|
|---|
| 234 | QHash<QByteArray, QVariant> Backend::objectDescriptionProperties(ObjectDescriptionType type, int index) const
|
|---|
| 235 | {
|
|---|
| 236 | QHash<QByteArray, QVariant> ret;
|
|---|
| 237 |
|
|---|
| 238 | switch (type){
|
|---|
| 239 | case AudioOutputDeviceType:{
|
|---|
| 240 | IMPLEMENTED_SILENT << "Creating description hash for type: AudioOutputDeviceType";
|
|---|
| 241 | ret.insert("name", AudioDevice::deviceSourceNameElseDeviceName(index));
|
|---|
| 242 | ret.insert("description", AudioDevice::deviceNameElseDeviceSourceName(index));
|
|---|
| 243 | break; }
|
|---|
| 244 | case EffectType:{
|
|---|
| 245 | AudioEffect e(index);
|
|---|
| 246 | ret.insert("name", e.name());
|
|---|
| 247 | ret.insert("description", e.description());
|
|---|
| 248 | break; }
|
|---|
| 249 |
|
|---|
| 250 | #if 0 // will be awailable in a later version of phonon.
|
|---|
| 251 | case VideoEffectType:{
|
|---|
| 252 | // Get list of effects, pick out filter at index, and return its name:
|
|---|
| 253 | IMPLEMENTED_SILENT << "Creating description hash for type: VideoEffectType";
|
|---|
| 254 | QList<QtCore/QString> filters = objc_getCiFilterInfo()->filterDisplayNames;
|
|---|
| 255 | ret.insert("name", filters[index]);
|
|---|
| 256 | case AudioCaptureDeviceType:{
|
|---|
| 257 | IMPLEMENTED_SILENT << "Creating description hash for type: AudioCaptureDeviceType";
|
|---|
| 258 | QMap<AudioDeviceID, QString> devices = AudioDevice::devices(AudioDevice::In);
|
|---|
| 259 | ret.insert("name", devices.value(index));
|
|---|
| 260 | break; }
|
|---|
| 261 | #endif
|
|---|
| 262 | default:
|
|---|
| 263 | NOT_IMPLEMENTED;
|
|---|
| 264 | break;
|
|---|
| 265 | }
|
|---|
| 266 |
|
|---|
| 267 | return ret;
|
|---|
| 268 | }
|
|---|
| 269 |
|
|---|
| 270 | Q_EXPORT_PLUGIN2(phonon_qt7, Backend)
|
|---|
| 271 | }}
|
|---|
| 272 |
|
|---|
| 273 | QT_END_NAMESPACE
|
|---|
| 274 |
|
|---|
| 275 | #include "moc_backend.cpp"
|
|---|
| 276 |
|
|---|