Phonon

mediasource.cpp
1/* This file is part of the KDE project
2 Copyright (C) 2007 Matthias Kretz <kretz@kde.org>
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 2.1 of the License, or (at your option) version 3, or any
8 later version accepted by the membership of KDE e.V. (or its
9 successor approved by the membership of KDE e.V.), Nokia Corporation
10 (or its successors, if any) and the KDE Free Qt Foundation, which shall
11 act as a proxy defined in Section 6 of version 3 of the license.
12
13 This library is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
17
18 You should have received a copy of the GNU Lesser General Public
19 License along with this library. If not, see <http://www.gnu.org/licenses/>.
20
21*/
22
23#include "mediasource.h"
24#include "mediasource_p.h"
25#include "iodevicestream_p.h"
26#include "abstractmediastream_p.h"
27#include "globalconfig.h"
28
29#include <QFileInfo>
30#include <QFile>
31
32namespace Phonon
33{
34
35MediaSource::MediaSource(MediaSourcePrivate &dd)
36 : d(&dd)
37{
38}
39
40MediaSource::MediaSource()
41 : d(new MediaSourcePrivate(Empty))
42{
43}
44
46 : d(new MediaSourcePrivate(LocalFile))
47{
48 if (filename.startsWith(QLatin1String(":/")) || filename.startsWith(QLatin1String("qrc:///"))) {
49#ifndef QT_NO_PHONON_ABSTRACTMEDIASTREAM
50 d->url.setScheme("qrc");
51 d->url.setPath(filename.mid(filename.startsWith(QLatin1Char(':')) ? 1 : 6));
52
53 // QFile needs :/ syntax
54 QString path(QLatin1Char(':') + d->url.path());
55
56 if (QFile::exists(path)) {
57 d->type = Stream;
58 d->ioDevice = new QFile(path);
59 d->setStream(new IODeviceStream(d->ioDevice, d->ioDevice));
60 } else {
61 d->type = Invalid;
62 }
63#else
64 d->type = Invalid;
65#endif //QT_NO_PHONON_ABSTRACTMEDIASTREAM
66 } else {
67 const QFileInfo fileinfo(filename);
68 if (fileinfo.exists()) {
69 d->url = QUrl::fromLocalFile(fileinfo.absoluteFilePath());
70 if (!d->url.host().isEmpty()) {
71 // filename points to a file on a network share (eg \\host\share\path)
72 d->type = Url;
73 }
74 } else {
75 d->url = filename;
76 if (d->url.isValid()) {
77 d->type = Url;
78 } else {
79 d->type = Invalid;
80 }
81 }
82 }
83}
84
86 : d(new MediaSourcePrivate(Url))
87{
88 if (url.isValid()) {
89 if (url.scheme() == QLatin1String("qrc")) {
90#ifndef QT_NO_PHONON_ABSTRACTMEDIASTREAM
91 // QFile needs :/ syntax
92 QString path(QLatin1Char(':') + url.path());
93
94 if (QFile::exists(path)) {
95 d->type = Stream;
96 d->ioDevice = new QFile(path);
97 d->setStream(new IODeviceStream(d->ioDevice, d->ioDevice));
98 } else {
99 d->type = Invalid;
100 }
101#else
102 d->type = Invalid;
103#endif //QT_NO_PHONON_ABSTRACTMEDIASTREAM
104 }
105 d->url = url;
106 } else {
107 d->type = Invalid;
108 }
109}
110
111MediaSource::MediaSource(DiscType dt, const QString &deviceName)
112 : d(new MediaSourcePrivate(Disc))
113{
114 if (dt == NoDisc) {
115 d->type = Invalid;
116 return;
117 }
118 d->discType = dt;
119 d->deviceName = deviceName;
120}
121
122// NOTE: this is deprecated
123MediaSource::MediaSource(const DeviceAccess &)
124 : d(new MediaSourcePrivate(Invalid))
125{
126}
127
128#ifndef PHONON_NO_AUDIOCAPTURE
130 : d(new MediaSourcePrivate(CaptureDevice))
131{
132 d->setCaptureDevices(device, VideoCaptureDevice());
133}
134#endif //PHONON_NO_AUDIOCAPTURE
135
136#ifndef PHONON_NO_VIDEOCAPTURE
138 : d(new MediaSourcePrivate(CaptureDevice))
139{
140 d->setCaptureDevices(AudioCaptureDevice(), device);
141}
142#endif //PHONON_NO_VIDEOCAPTURE
143
144#if !defined(PHONON_NO_VIDEOCAPTURE) && !defined(PHONON_NO_AUDIOCAPTURE)
145MediaSource::MediaSource(CaptureCategory category)
146 : d(new MediaSourcePrivate(AudioVideoCapture))
147{
148 d->setCaptureDevices(category);
149}
150
151MediaSource::MediaSource(Capture::DeviceType deviceType, CaptureCategory category)
152 : d(new MediaSourcePrivate(CaptureDevice))
153{
154 d->setCaptureDevice(deviceType, category);
155}
156#endif // !PHONON_NO_VIDEOCAPTURE && !PHONON_NO_AUDIOCAPTURE
157
158#ifndef QT_NO_PHONON_ABSTRACTMEDIASTREAM
160 : d(new MediaSourcePrivate(Stream))
161{
162 if (stream) {
163 d->setStream(stream);
164 } else {
165 d->type = Invalid;
166 }
167}
168
170 : d(new MediaSourcePrivate(Stream))
171{
172 if (ioDevice) {
173 d->setStream(new IODeviceStream(ioDevice, ioDevice));
174 d->ioDevice = ioDevice;
175 } else {
176 d->type = Invalid;
177 }
178}
179#endif //QT_NO_PHONON_ABSTRACTMEDIASTREAM
180
181/* post 4.0
182MediaSource::MediaSource(const QList<MediaSource> &mediaList)
183 : d(new MediaSourcePrivate(Link))
184{
185 d->linkedSources = mediaList;
186 foreach (MediaSource ms, mediaList) {
187 Q_ASSERT(ms.type() != Link);
188 }
189}
190
191QList<MediaSource> MediaSource::substreams() const
192{
193 return d->linkedSources;
194}
195*/
196
200
201MediaSourcePrivate::~MediaSourcePrivate()
202{
203#ifndef QT_NO_PHONON_ABSTRACTMEDIASTREAM
204 if (autoDelete) {
205 //here we use deleteLater because this object
206 //might be destroyed from another thread
207 if (stream)
208 stream->deleteLater();
209 if (ioDevice)
210 ioDevice->deleteLater();
211 }
212#endif //QT_NO_PHONON_ABSTRACTMEDIASTREAM
213}
214
216 : d(rhs.d)
217{
218}
219
221{
222 d = rhs.d;
223 return *this;
224}
225
227{
228 return d == rhs.d;
229}
230
231void MediaSource::setAutoDelete(bool autoDelete)
232{
233 d->autoDelete = autoDelete;
234}
235
237{
238 return d->autoDelete;
239}
240
242{
243#ifndef QT_NO_PHONON_ABSTRACTMEDIASTREAM
244 if (d->type == Stream && d->stream == nullptr) {
245 return Invalid;
246 }
247#endif //QT_NO_PHONON_ABSTRACTMEDIASTREAM
248 return d->type;
249}
250
252{
253 return d->url.toLocalFile();
254}
255
257{
258 return Mrl(d->url);
259}
260
262{
263 return d->url;
264}
265
266DiscType MediaSource::discType() const
267{
268 return d->discType;
269}
270
272{
273#ifndef PHONON_NO_AUDIOCAPTURE
274 if (d->audioCaptureDevice.isValid())
275 return d->audioDeviceAccessList;
276#endif
277
278#ifndef PHONON_NO_VIDEOCAPTURE
279 if (d->videoCaptureDevice.isValid())
280 return d->videoDeviceAccessList;
281#endif
282
283 return d->audioDeviceAccessList; // It should be invalid
284}
285
287{
288 return d->audioDeviceAccessList;
289}
290
292{
293 return d->videoDeviceAccessList;
294}
295
297{
298 return d->deviceName;
299}
300
301#ifndef QT_NO_PHONON_ABSTRACTMEDIASTREAM
303{
304 return d->stream;
305}
306
307void MediaSourcePrivate::setStream(AbstractMediaStream *s)
308{
309 stream = s;
310}
311#endif //QT_NO_PHONON_ABSTRACTMEDIASTREAM
312
313#ifndef PHONON_NO_AUDIOCAPTURE
315{
316 return d->audioCaptureDevice;
317}
318#endif //PHONON_NO_AUDIOCAPTURE
319
320#ifndef PHONON_NO_VIDEOCAPTURE
322{
323 return d->videoCaptureDevice;
324}
325#endif //PHONON_NO_VIDEOCAPTURE
326
327#if !defined(PHONON_NO_VIDEOCAPTURE) && !defined(PHONON_NO_AUDIOCAPTURE)
328void MediaSourcePrivate::setCaptureDevice(Capture::DeviceType deviceType, CaptureCategory category)
329{
330 switch (deviceType) {
331 case Capture::VideoType: {
332 setCaptureDevices(AudioCaptureDevice(),
333 VideoCaptureDevice::fromIndex(GlobalConfig().videoCaptureDeviceFor(category)));
334 break;
335 }
336 case Capture::AudioType: {
337 setCaptureDevices(
338 AudioCaptureDevice::fromIndex(GlobalConfig().audioCaptureDeviceFor(category)), VideoCaptureDevice());
339 break;
340 }
341 }
342}
343
344void MediaSourcePrivate::setCaptureDevices(CaptureCategory category)
345{
346 setCaptureDevices(
347 AudioCaptureDevice::fromIndex(GlobalConfig().audioCaptureDeviceFor(category)),
348 VideoCaptureDevice::fromIndex(GlobalConfig().videoCaptureDeviceFor(category)));
349}
350
351void MediaSourcePrivate::setCaptureDevices(const AudioCaptureDevice &audioDevice, const VideoCaptureDevice &videoDevice)
352{
353 audioCaptureDevice = audioDevice;
354 videoCaptureDevice = videoDevice;
355
356 if (audioDevice.propertyNames().contains("deviceAccessList") &&
357 !audioDevice.property("deviceAccessList").value<DeviceAccessList>().isEmpty()) {
358 audioDeviceAccessList = audioDevice.property("deviceAccessList").value<DeviceAccessList>();
359 }
360
361 if (videoDevice.propertyNames().contains("deviceAccessList") &&
362 !videoDevice.property("deviceAccessList").value<DeviceAccessList>().isEmpty()) {
363 videoDeviceAccessList = videoDevice.property("deviceAccessList").value<DeviceAccessList>();
364 }
365
366 bool validAudio = !audioDeviceAccessList.isEmpty();
367 bool validVideo = !videoDeviceAccessList.isEmpty();
369 if (validAudio && validVideo)
371 else if (validAudio || validVideo)
373}
374#endif // !PHONON_NO_VIDEOCAPTURE && !PHONON_NO_AUDIOCAPTURE
375
376QDebug operator <<(QDebug dbg, const Phonon::MediaSource &source)
377{
378 switch (source.type()) {
380 dbg.nospace() << "Invalid()";
381 break;
383 dbg.nospace() << "LocalFile(" << source.url() << ")";
384 break;
385 case MediaSource::Url:
386 dbg.nospace() << "Url(" << source.url() << ")";
387 break;
389 dbg.nospace() << "Disc(";
390 switch (source.discType()) {
391 case NoDisc:
392 dbg.nospace() << "NoDisc";
393 break;
394 case Cd:
395 dbg.nospace() << "Cd: " << source.deviceName();
396 break;
397 case Dvd:
398 dbg.nospace() << "Dvd: " << source.deviceName();
399 break;
400 case Vcd:
401 dbg.nospace() << "Vcd: " << source.deviceName();
402 break;
403 case BluRay:
404 dbg.nospace() << "BluRay: " << source.deviceName();
405 break;
406 }
407 dbg.nospace() << ")";
408 break;
409 case MediaSource::Stream: {
410 dbg.nospace() << "Stream(IOAddr: " << source.d->ioDevice;
411 QObject *qiodevice = qobject_cast<QObject *>(source.d->ioDevice);
412 if (qiodevice)
413 dbg.nospace() << " IOClass: " << qiodevice->metaObject()->className();
414
415 dbg.nospace() << "; StreamAddr: " << source.stream();
416 QObject *qstream = qobject_cast<QObject *>(source.stream());
417 if (qstream)
418 dbg.nospace() << " StreamClass: " << qstream->metaObject()->className();
419
420 dbg.nospace() << ")";
421 break;
422 }
425 dbg.nospace() << "AudioVideoCapture(A:" << source.audioCaptureDevice().name()
426 << "/V: " << source.videoCaptureDevice().name() << ")";
427 break;
429 dbg.nospace() << "Empty()";
430 break;
431 }
432
433 return dbg.maybeSpace();
434}
435
436} // namespace Phonon
437
438// vim: sw=4 sts=4 et tw=100
Base class for custom media data streams.
Note that all constructors of this class are implicit, so that you can simply write.
MediaSource & operator=(const MediaSource &rhs)
Assigns rhs to this MediaSource and returns a reference to this MediaSource.
const DeviceAccessList & audioDeviceAccessList() const
Returns the access list for the audio device used for capture.
Mrl mrl() const
Returns the MRL of the MediaSource if type() == URL or type() == LocalFile; otherwise returns Mrl().
DiscType discType() const
Returns the disc type of the MediaSource if type() == Disc; otherwise returns NoDisc.
bool operator==(const MediaSource &rhs) const
Returns true if this MediaSource is equal to rhs; otherwise returns false.
QString deviceName() const
Returns the device name of the MediaSource if type() == Disc; otherwise returns QString().
AudioCaptureDevice audioCaptureDevice() const
Returns the audio capture device for the media source if applicable.
const DeviceAccessList & videoDeviceAccessList() const
Returns the access list for the video device used for capture.
AbstractMediaStream * stream() const
Returns the media stream of the MediaSource if type() == Stream; otherwise returns 0.
MediaSource()
Creates an empty MediaSource.
Type type() const
Returns the type of the MediaSource (depends on the constructor that was used).
QUrl url() const
Returns the url of the MediaSource if type() == URL or type() == LocalFile; otherwise returns QUrl().
QString fileName() const
Returns the file name of the MediaSource if type() == LocalFile; otherwise returns QString().
const DeviceAccessList & deviceAccessList() const
Returns the access list for the device of this media source.
~MediaSource()
Destroys the MediaSource object.
void setAutoDelete(bool enable)
Tell the MediaSource to take ownership of the AbstractMediaStream or QIODevice that was passed in the...
Type
Identifies the type of media described by the MediaSource object.
Definition mediasource.h:72
@ Url
The MediaSource object describes a URL, which can be both a local file and a file on the network.
Definition mediasource.h:85
@ Stream
The MediaSource object describes a data stream.
Definition mediasource.h:97
@ Disc
The MediaSource object describes a disc.
Definition mediasource.h:89
@ Invalid
The MediaSource object does not describe any valid source.
Definition mediasource.h:76
@ CaptureDevice
The MediaSource object describes a single capture device.
@ AudioVideoCapture
The MediaSource object describes one device for video capture and one for audio capture.
@ Empty
An empty MediaSource.
@ LocalFile
The MediaSource object describes a local file.
Definition mediasource.h:80
VideoCaptureDevice videoCaptureDevice() const
Returns the video capture device for the media source if applicable.
bool autoDelete() const
Returns the setting of the auto-delete option.
Media Resource Locator - A QUrl particularly for MediaSources.
Definition mrl.h:47
Provides a tuple of enduser visible name and description.
static ObjectDescription< T > fromIndex(int index)
Returns a new description object that describes the device/effect/codec/... with the given index.
QString name() const
Returns the name of the capture source.
VehicleSection::Type type(QStringView coachNumber, QStringView coachClassification)
QDebug & maybeSpace()
QDebug & nospace()
bool exists() const const
QString absoluteFilePath() const const
bool exists(const QString &path)
const char * className() const const
virtual const QMetaObject * metaObject() const const
QString mid(qsizetype position, qsizetype n) const const
bool startsWith(QChar c, Qt::CaseSensitivity cs) const const
QUrl fromLocalFile(const QString &localFile)
bool isValid() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Mon Nov 4 2024 16:29:17 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.