~ubuntu-branches/ubuntu/oneiric/psi/oneiric

« back to all changes in this revision

Viewing changes to src/psimedia/psimedia.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Jan Niehusmann
  • Date: 2009-09-25 17:49:51 UTC
  • mfrom: (6.1.3 sid)
  • Revision ID: james.westby@ubuntu.com-20090925174951-lvm7kdap82o8xhn3
Tags: 0.13-1
* Updated to upstream version 0.13
* Set Standards-Version to 3.8.3

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (C) 2008-2009  Barracuda Networks, Inc.
 
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) any later version.
 
8
 *
 
9
 * This library is distributed in the hope that it will be useful,
 
10
 * but WITHANY WARRANTY; without even the implied warranty of
 
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
12
 * Lesser General Public License for more details.
 
13
 *
 
14
 * You should have received a copy of the GNU Lesser General Public
 
15
 * License along with this library; if not, write to the Free Software
 
16
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 
17
 * 02110-1301  USA
 
18
 *
 
19
 */
 
20
 
 
21
#include "psimedia.h"
 
22
 
 
23
#include <QCoreApplication>
 
24
#include <QPluginLoader>
 
25
 
 
26
#ifdef QT_GUI_LIB
 
27
#include <QPainter>
 
28
#endif
 
29
 
 
30
#include "psimediaprovider.h"
 
31
 
 
32
namespace PsiMedia {
 
33
 
 
34
static AudioParams importAudioParams(const PAudioParams &pp)
 
35
{
 
36
        AudioParams out;
 
37
        out.setCodec(pp.codec);
 
38
        out.setSampleRate(pp.sampleRate);
 
39
        out.setSampleSize(pp.sampleSize);
 
40
        out.setChannels(pp.channels);
 
41
        return out;
 
42
}
 
43
 
 
44
static PAudioParams exportAudioParams(const AudioParams &p)
 
45
{
 
46
        PAudioParams out;
 
47
        out.codec = p.codec();
 
48
        out.sampleRate = p.sampleRate();
 
49
        out.sampleSize = p.sampleSize();
 
50
        out.channels = p.channels();
 
51
        return out;
 
52
}
 
53
 
 
54
static VideoParams importVideoParams(const PVideoParams &pp)
 
55
{
 
56
        VideoParams out;
 
57
        out.setCodec(pp.codec);
 
58
        out.setSize(pp.size);
 
59
        out.setFps(pp.fps);
 
60
        return out;
 
61
}
 
62
 
 
63
static PVideoParams exportVideoParams(const VideoParams &p)
 
64
{
 
65
        PVideoParams out;
 
66
        out.codec = p.codec();
 
67
        out.size = p.size();
 
68
        out.fps = p.fps();
 
69
        return out;
 
70
}
 
71
 
 
72
static PayloadInfo importPayloadInfo(const PPayloadInfo &pp)
 
73
{
 
74
        PayloadInfo out;
 
75
        out.setId(pp.id);
 
76
        out.setName(pp.name);
 
77
        out.setClockrate(pp.clockrate);
 
78
        out.setChannels(pp.channels);
 
79
        out.setPtime(pp.ptime);
 
80
        out.setMaxptime(pp.maxptime);
 
81
        QList<PayloadInfo::Parameter> list;
 
82
        foreach(const PPayloadInfo::Parameter &pi, pp.parameters)
 
83
        {
 
84
                PayloadInfo::Parameter i;
 
85
                i.name = pi.name;
 
86
                i.value = pi.value;
 
87
                list += i;
 
88
        }
 
89
        out.setParameters(list);
 
90
        return out;
 
91
}
 
92
 
 
93
static PPayloadInfo exportPayloadInfo(const PayloadInfo &p)
 
94
{
 
95
        PPayloadInfo out;
 
96
        out.id = p.id();
 
97
        out.name = p.name();
 
98
        out.clockrate = p.clockrate();
 
99
        out.channels = p.channels();
 
100
        out.ptime = p.ptime();
 
101
        out.maxptime = p.maxptime();
 
102
        QList<PPayloadInfo::Parameter> list;
 
103
        foreach(const PayloadInfo::Parameter &i, p.parameters())
 
104
        {
 
105
                PPayloadInfo::Parameter pi;
 
106
                pi.name = i.name;
 
107
                pi.value = i.value;
 
108
                list += pi;
 
109
        }
 
110
        out.parameters = list;
 
111
        return out;
 
112
}
 
113
 
 
114
//----------------------------------------------------------------------------
 
115
// Global
 
116
//----------------------------------------------------------------------------
 
117
static Provider *g_provider = 0;
 
118
static QPluginLoader *g_pluginLoader = 0;
 
119
 
 
120
static void cleanupProvider();
 
121
 
 
122
static Provider *provider()
 
123
{
 
124
        if(!g_provider)
 
125
        {
 
126
                // static plugin around?
 
127
                Provider *provider = 0;
 
128
                QObjectList list = QPluginLoader::staticInstances();
 
129
                foreach(QObject *obj, list)
 
130
                {
 
131
                        Plugin *instance = qobject_cast<Plugin *>(obj);
 
132
                        if(!instance)
 
133
                                continue;
 
134
 
 
135
                        Provider *p = instance->createProvider();
 
136
                        if(p)
 
137
                        {
 
138
                                provider = p;
 
139
                                break;
 
140
                        }
 
141
                }
 
142
 
 
143
                if(provider)
 
144
                {
 
145
                        if(!provider->init(QString()))
 
146
                        {
 
147
                                delete provider;
 
148
                                return 0;
 
149
                        }
 
150
 
 
151
                        g_provider = provider;
 
152
                        qAddPostRoutine(cleanupProvider);
 
153
                }
 
154
        }
 
155
 
 
156
        return g_provider;
 
157
}
 
158
 
 
159
bool isSupported()
 
160
{
 
161
        return (provider() ? true : false);
 
162
}
 
163
 
 
164
PluginResult loadPlugin(const QString &fname, const QString &resourcePath)
 
165
{
 
166
        if(g_provider)
 
167
                return PluginSuccess;
 
168
 
 
169
        QPluginLoader *loader = new QPluginLoader(fname);
 
170
        if(!loader->load())
 
171
        {
 
172
                delete loader;
 
173
                return ErrorLoad;
 
174
        }
 
175
 
 
176
        Plugin *instance = qobject_cast<Plugin *>(loader->instance());
 
177
        if(!instance)
 
178
        {
 
179
                delete loader;
 
180
                return ErrorVersion;
 
181
        }
 
182
 
 
183
        Provider *provider = instance->createProvider();
 
184
        if(!provider)
 
185
        {
 
186
                loader->unload();
 
187
                delete loader;
 
188
                return ErrorInit;
 
189
        }
 
190
 
 
191
        if(!provider->init(resourcePath))
 
192
        {
 
193
                delete provider;
 
194
                loader->unload();
 
195
                delete loader;
 
196
                return ErrorInit;
 
197
        }
 
198
 
 
199
        g_provider = provider;
 
200
        g_pluginLoader = loader;
 
201
        qAddPostRoutine(cleanupProvider);
 
202
        return PluginSuccess;
 
203
}
 
204
 
 
205
void cleanupProvider()
 
206
{
 
207
        if(!g_provider)
 
208
                return;
 
209
 
 
210
        delete g_provider;
 
211
        g_provider = 0;
 
212
 
 
213
        if(g_pluginLoader)
 
214
        {
 
215
                g_pluginLoader->unload();
 
216
                delete g_pluginLoader;
 
217
                g_pluginLoader = 0;
 
218
        }
 
219
}
 
220
 
 
221
void unloadPlugin()
 
222
{
 
223
        cleanupProvider();
 
224
}
 
225
 
 
226
QString creditName()
 
227
{
 
228
        return provider()->creditName();
 
229
}
 
230
 
 
231
QString creditText()
 
232
{
 
233
        return provider()->creditText();
 
234
}
 
235
 
 
236
class Device::Private
 
237
{
 
238
public:
 
239
        Device::Type type;
 
240
        QString id;
 
241
        QString name;
 
242
};
 
243
 
 
244
class Global
 
245
{
 
246
public:
 
247
        static Device importDevice(const PDevice &pd)
 
248
        {
 
249
                Device dev;
 
250
                dev.d = new Device::Private;
 
251
                dev.d->type = (Device::Type)pd.type;
 
252
                dev.d->id = pd.id;
 
253
                dev.d->name = pd.name;
 
254
                return dev;
 
255
        }
 
256
};
 
257
 
 
258
//----------------------------------------------------------------------------
 
259
// Device
 
260
//----------------------------------------------------------------------------
 
261
Device::Device() :
 
262
        d(0)
 
263
{
 
264
}
 
265
 
 
266
Device::Device(const Device &other) :
 
267
        d(other.d ? new Private(*other.d) : 0)
 
268
{
 
269
}
 
270
 
 
271
Device::~Device()
 
272
{
 
273
        delete d;
 
274
}
 
275
 
 
276
Device & Device::operator=(const Device &other)
 
277
{
 
278
        if(d)
 
279
        {
 
280
                if(other.d)
 
281
                {
 
282
                        *d = *other.d;
 
283
                }
 
284
                else
 
285
                {
 
286
                        delete d;
 
287
                        d = 0;
 
288
                }
 
289
        }
 
290
        else
 
291
        {
 
292
                if(other.d)
 
293
                        d = new Private(*other.d);
 
294
        }
 
295
 
 
296
        return *this;
 
297
}
 
298
 
 
299
bool Device::isNull() const
 
300
{
 
301
        return (d ? false : true);
 
302
}
 
303
 
 
304
Device::Type Device::type() const
 
305
{
 
306
        return d->type;
 
307
}
 
308
 
 
309
QString Device::name() const
 
310
{
 
311
        return d->name;
 
312
}
 
313
 
 
314
QString Device::id() const
 
315
{
 
316
        return d->id;
 
317
}
 
318
 
 
319
#ifdef QT_GUI_LIB
 
320
//----------------------------------------------------------------------------
 
321
// VideoWidget
 
322
//----------------------------------------------------------------------------
 
323
class VideoWidgetPrivate : public QObject, public VideoWidgetContext
 
324
{
 
325
        Q_OBJECT
 
326
 
 
327
public:
 
328
        friend class VideoWidget;
 
329
 
 
330
        VideoWidget *q;
 
331
        QSize videoSize;
 
332
 
 
333
        VideoWidgetPrivate(VideoWidget *_q) :
 
334
                QObject(_q),
 
335
                q(_q)
 
336
        {
 
337
        }
 
338
 
 
339
        virtual QObject *qobject()
 
340
        {
 
341
                return this;
 
342
        }
 
343
 
 
344
        virtual QWidget *qwidget()
 
345
        {
 
346
                return q;
 
347
        }
 
348
 
 
349
        virtual void setVideoSize(const QSize &size)
 
350
        {
 
351
                videoSize = size;
 
352
                emit q->videoSizeChanged();
 
353
        }
 
354
 
 
355
signals:
 
356
        void resized(const QSize &newSize);
 
357
        void paintEvent(QPainter *p);
 
358
};
 
359
 
 
360
VideoWidget::VideoWidget(QWidget *parent) :
 
361
        QWidget(parent)
 
362
{
 
363
        d = new VideoWidgetPrivate(this);
 
364
}
 
365
 
 
366
VideoWidget::~VideoWidget()
 
367
{
 
368
        delete d;
 
369
}
 
370
 
 
371
QSize VideoWidget::sizeHint() const
 
372
{
 
373
        return d->videoSize;
 
374
}
 
375
 
 
376
void VideoWidget::paintEvent(QPaintEvent *event)
 
377
{
 
378
        Q_UNUSED(event);
 
379
        QPainter p(this);
 
380
        emit d->paintEvent(&p);
 
381
}
 
382
 
 
383
void VideoWidget::resizeEvent(QResizeEvent *event)
 
384
{
 
385
        Q_UNUSED(event);
 
386
        emit d->resized(size());
 
387
}
 
388
#endif
 
389
 
 
390
//----------------------------------------------------------------------------
 
391
// AudioParams
 
392
//----------------------------------------------------------------------------
 
393
class AudioParams::Private
 
394
{
 
395
public:
 
396
        QString codec;
 
397
        int sampleRate;
 
398
        int sampleSize;
 
399
        int channels;
 
400
 
 
401
        Private() :
 
402
                sampleRate(0),
 
403
                sampleSize(0),
 
404
                channels(0)
 
405
        {
 
406
        }
 
407
};
 
408
 
 
409
AudioParams::AudioParams() :
 
410
        d(new Private)
 
411
{
 
412
}
 
413
 
 
414
AudioParams::AudioParams(const AudioParams &other) :
 
415
        d(new Private(*other.d))
 
416
{
 
417
}
 
418
 
 
419
AudioParams::~AudioParams()
 
420
{
 
421
        delete d;
 
422
}
 
423
 
 
424
AudioParams & AudioParams::operator=(const AudioParams &other)
 
425
{
 
426
        *d = *other.d;
 
427
        return *this;
 
428
}
 
429
 
 
430
QString AudioParams::codec() const
 
431
{
 
432
        return d->codec;
 
433
}
 
434
 
 
435
int AudioParams::sampleRate() const
 
436
{
 
437
        return d->sampleRate;
 
438
}
 
439
 
 
440
int AudioParams::sampleSize() const
 
441
{
 
442
        return d->sampleSize;
 
443
}
 
444
 
 
445
int AudioParams::channels() const
 
446
{
 
447
        return d->channels;
 
448
}
 
449
 
 
450
void AudioParams::setCodec(const QString &s)
 
451
{
 
452
        d->codec = s;
 
453
}
 
454
 
 
455
void AudioParams::setSampleRate(int n)
 
456
{
 
457
        d->sampleRate = n;
 
458
}
 
459
 
 
460
void AudioParams::setSampleSize(int n)
 
461
{
 
462
        d->sampleSize = n;
 
463
}
 
464
 
 
465
void AudioParams::setChannels(int n)
 
466
{
 
467
        d->channels = n;
 
468
}
 
469
 
 
470
bool AudioParams::operator==(const AudioParams &other) const
 
471
{
 
472
        if(d->codec == other.d->codec &&
 
473
                d->sampleRate == other.d->sampleRate &&
 
474
                d->sampleSize == other.d->sampleSize &&
 
475
                d->channels == other.d->channels)
 
476
        {
 
477
                return true;
 
478
        }
 
479
        else
 
480
                return false;
 
481
}
 
482
 
 
483
//----------------------------------------------------------------------------
 
484
// VideoParams
 
485
//----------------------------------------------------------------------------
 
486
class VideoParams::Private
 
487
{
 
488
public:
 
489
        QString codec;
 
490
        QSize size;
 
491
        int fps;
 
492
 
 
493
        Private() :
 
494
                fps(0)
 
495
        {
 
496
        }
 
497
};
 
498
 
 
499
VideoParams::VideoParams() :
 
500
        d(new Private)
 
501
{
 
502
}
 
503
 
 
504
VideoParams::VideoParams(const VideoParams &other) :
 
505
        d(new Private(*other.d))
 
506
{
 
507
}
 
508
 
 
509
VideoParams::~VideoParams()
 
510
{
 
511
        delete d;
 
512
}
 
513
 
 
514
VideoParams & VideoParams::operator=(const VideoParams &other)
 
515
{
 
516
        *d = *other.d;
 
517
        return *this;
 
518
}
 
519
 
 
520
QString VideoParams::codec() const
 
521
{
 
522
        return d->codec;
 
523
}
 
524
 
 
525
QSize VideoParams::size() const
 
526
{
 
527
        return d->size;
 
528
}
 
529
 
 
530
int VideoParams::fps() const
 
531
{
 
532
        return d->fps;
 
533
}
 
534
 
 
535
void VideoParams::setCodec(const QString &s)
 
536
{
 
537
        d->codec = s;
 
538
}
 
539
 
 
540
void VideoParams::setSize(const QSize &s)
 
541
{
 
542
        d->size = s;
 
543
}
 
544
 
 
545
void VideoParams::setFps(int n)
 
546
{
 
547
        d->fps = n;
 
548
}
 
549
 
 
550
bool VideoParams::operator==(const VideoParams &other) const
 
551
{
 
552
        if(d->codec == other.d->codec &&
 
553
                d->size == other.d->size &&
 
554
                d->fps == other.d->fps)
 
555
        {
 
556
                return true;
 
557
        }
 
558
        else
 
559
                return false;
 
560
}
 
561
 
 
562
//----------------------------------------------------------------------------
 
563
// Features
 
564
//----------------------------------------------------------------------------
 
565
static QList<Device> importDevices(const QList<PDevice> &in)
 
566
{
 
567
        QList<Device> out;
 
568
        foreach(const PDevice &pd, in)
 
569
                out += Global::importDevice(pd);
 
570
        return out;
 
571
}
 
572
 
 
573
static QList<AudioParams> importAudioModes(const QList<PAudioParams> &in)
 
574
{
 
575
        QList<AudioParams> out;
 
576
        foreach(const PAudioParams &pp, in)
 
577
                out += importAudioParams(pp);
 
578
        return out;
 
579
}
 
580
 
 
581
static QList<VideoParams> importVideoModes(const QList<PVideoParams> &in)
 
582
{
 
583
        QList<VideoParams> out;
 
584
        foreach(const PVideoParams &pp, in)
 
585
                out += importVideoParams(pp);
 
586
        return out;
 
587
}
 
588
 
 
589
class Features::Private : public QObject
 
590
{
 
591
        Q_OBJECT
 
592
 
 
593
public:
 
594
        Features *q;
 
595
        FeaturesContext *c;
 
596
 
 
597
        QList<Device> audioOutputDevices;
 
598
        QList<Device> audioInputDevices;
 
599
        QList<Device> videoInputDevices;
 
600
        QList<AudioParams> supportedAudioModes;
 
601
        QList<VideoParams> supportedVideoModes;
 
602
 
 
603
        Private(Features *_q) :
 
604
                QObject(_q),
 
605
                q(_q)
 
606
        {
 
607
                c = provider()->createFeatures();
 
608
                c->qobject()->setParent(this);
 
609
                connect(c->qobject(), SIGNAL(finished()), SLOT(c_finished()));
 
610
        }
 
611
 
 
612
        ~Private()
 
613
        {
 
614
                delete c;
 
615
        }
 
616
 
 
617
        void clearResults()
 
618
        {
 
619
                audioOutputDevices.clear();
 
620
                audioInputDevices.clear();
 
621
                videoInputDevices.clear();
 
622
                supportedAudioModes.clear();
 
623
                supportedVideoModes.clear();
 
624
        }
 
625
 
 
626
        void importResults(const PFeatures &in)
 
627
        {
 
628
                audioOutputDevices = importDevices(in.audioOutputDevices);
 
629
                audioInputDevices = importDevices(in.audioInputDevices);
 
630
                videoInputDevices = importDevices(in.videoInputDevices);
 
631
                supportedAudioModes = importAudioModes(in.supportedAudioModes);
 
632
                supportedVideoModes = importVideoModes(in.supportedVideoModes);
 
633
        }
 
634
 
 
635
private slots:
 
636
        void c_finished()
 
637
        {
 
638
                importResults(c->results());
 
639
                emit q->finished();
 
640
        }
 
641
};
 
642
 
 
643
Features::Features(QObject *parent) :
 
644
        QObject(parent)
 
645
{
 
646
        d = new Private(this);
 
647
}
 
648
 
 
649
Features::~Features()
 
650
{
 
651
        delete d;
 
652
}
 
653
 
 
654
void Features::lookup(int types)
 
655
{
 
656
        int ptypes = 0;
 
657
        if(types & AudioOut)
 
658
                ptypes |= FeaturesContext::AudioOut;
 
659
        if(types & AudioIn)
 
660
                ptypes |= FeaturesContext::AudioIn;
 
661
        if(types & VideoIn)
 
662
                ptypes |= FeaturesContext::VideoIn;
 
663
        if(types & AudioModes)
 
664
                ptypes |= FeaturesContext::AudioModes;
 
665
        if(types & VideoModes)
 
666
                ptypes |= FeaturesContext::VideoModes;
 
667
 
 
668
        d->clearResults();
 
669
        d->c->lookup(ptypes);
 
670
}
 
671
 
 
672
bool Features::waitForFinished(int msecs)
 
673
{
 
674
        bool ok = d->c->waitForFinished(msecs);
 
675
        if(ok)
 
676
                d->importResults(d->c->results());
 
677
        return ok;
 
678
}
 
679
 
 
680
QList<Device> Features::audioOutputDevices()
 
681
{
 
682
        return d->audioOutputDevices;
 
683
}
 
684
 
 
685
QList<Device> Features::audioInputDevices()
 
686
{
 
687
        return d->audioInputDevices;
 
688
}
 
689
 
 
690
QList<Device> Features::videoInputDevices()
 
691
{
 
692
        return d->videoInputDevices;
 
693
}
 
694
 
 
695
QList<AudioParams> Features::supportedAudioModes()
 
696
{
 
697
        return d->supportedAudioModes;
 
698
}
 
699
 
 
700
QList<VideoParams> Features::supportedVideoModes()
 
701
{
 
702
        return d->supportedVideoModes;
 
703
}
 
704
 
 
705
//----------------------------------------------------------------------------
 
706
// RtpPacket
 
707
//----------------------------------------------------------------------------
 
708
class RtpPacket::Private : public QSharedData
 
709
{
 
710
public:
 
711
        QByteArray rawValue;
 
712
        int portOffset;
 
713
 
 
714
        Private(const QByteArray &_rawValue, int _portOffset) :
 
715
                rawValue(_rawValue),
 
716
                portOffset(_portOffset)
 
717
        {
 
718
        }
 
719
};
 
720
 
 
721
RtpPacket::RtpPacket() :
 
722
        d(0)
 
723
{
 
724
}
 
725
 
 
726
RtpPacket::RtpPacket(const QByteArray &rawValue, int portOffset) :
 
727
        d(new Private(rawValue, portOffset))
 
728
{
 
729
}
 
730
 
 
731
RtpPacket::RtpPacket(const RtpPacket &other) :
 
732
        d(other.d)
 
733
{
 
734
}
 
735
 
 
736
RtpPacket::~RtpPacket()
 
737
{
 
738
}
 
739
 
 
740
RtpPacket & RtpPacket::operator=(const RtpPacket &other)
 
741
{
 
742
        d = other.d;
 
743
        return *this;
 
744
}
 
745
 
 
746
bool RtpPacket::isNull() const
 
747
{
 
748
        return (d ? false : true);
 
749
}
 
750
 
 
751
QByteArray RtpPacket::rawValue() const
 
752
{
 
753
        return d->rawValue;
 
754
}
 
755
 
 
756
int RtpPacket::portOffset() const
 
757
{
 
758
        return d->portOffset;
 
759
}
 
760
 
 
761
//----------------------------------------------------------------------------
 
762
// RtpChannel
 
763
//----------------------------------------------------------------------------
 
764
class RtpChannelPrivate : public QObject
 
765
{
 
766
        Q_OBJECT
 
767
 
 
768
public:
 
769
        RtpChannel *q;
 
770
        RtpChannelContext *c;
 
771
        bool enabled;
 
772
        int readyReadListeners;
 
773
 
 
774
        RtpChannelPrivate(RtpChannel *_q) :
 
775
                QObject(_q),
 
776
                q(_q),
 
777
                c(0),
 
778
                enabled(false),
 
779
                readyReadListeners(0)
 
780
        {
 
781
        }
 
782
 
 
783
        void setContext(RtpChannelContext *_c)
 
784
        {
 
785
                if(c)
 
786
                {
 
787
                        c->qobject()->disconnect(this);
 
788
                        c->qobject()->setParent(0);
 
789
                        enabled = false;
 
790
                        c = 0;
 
791
                }
 
792
 
 
793
                if(!_c)
 
794
                        return;
 
795
 
 
796
                c = _c;
 
797
                c->qobject()->setParent(this);
 
798
                connect(c->qobject(), SIGNAL(readyRead()), SLOT(c_readyRead()));
 
799
                connect(c->qobject(), SIGNAL(packetsWritten(int)), SLOT(c_packetsWritten(int)));
 
800
                connect(c->qobject(), SIGNAL(destroyed()), SLOT(c_destroyed()));
 
801
 
 
802
                if(readyReadListeners > 0)
 
803
                {
 
804
                        enabled = true;
 
805
                        c->setEnabled(true);
 
806
                }
 
807
        }
 
808
 
 
809
private slots:
 
810
        void c_readyRead()
 
811
        {
 
812
                emit q->readyRead();
 
813
        }
 
814
 
 
815
        void c_packetsWritten(int count)
 
816
        {
 
817
                emit q->packetsWritten(count);
 
818
        }
 
819
 
 
820
        void c_destroyed()
 
821
        {
 
822
                enabled = false;
 
823
                c = 0;
 
824
        }
 
825
};
 
826
 
 
827
RtpChannel::RtpChannel()
 
828
{
 
829
        d = new RtpChannelPrivate(this);
 
830
}
 
831
 
 
832
RtpChannel::~RtpChannel()
 
833
{
 
834
        delete d;
 
835
}
 
836
 
 
837
int RtpChannel::packetsAvailable() const
 
838
{
 
839
        if(d->c)
 
840
                return d->c->packetsAvailable();
 
841
        else
 
842
                return 0;
 
843
}
 
844
 
 
845
RtpPacket RtpChannel::read()
 
846
{
 
847
        if(d->c)
 
848
        {
 
849
                PRtpPacket pp = d->c->read();
 
850
                return RtpPacket(pp.rawValue, pp.portOffset);
 
851
        }
 
852
        else
 
853
                return RtpPacket();
 
854
}
 
855
 
 
856
void RtpChannel::write(const RtpPacket &rtp)
 
857
{
 
858
        if(d->c)
 
859
        {
 
860
                if(!d->enabled)
 
861
                {
 
862
                        d->enabled = true;
 
863
                        d->c->setEnabled(true);
 
864
                }
 
865
 
 
866
                PRtpPacket pp;
 
867
                pp.rawValue = rtp.rawValue();
 
868
                pp.portOffset = rtp.portOffset();
 
869
                d->c->write(pp);
 
870
        }
 
871
}
 
872
 
 
873
void RtpChannel::connectNotify(const char *signal)
 
874
{
 
875
        int oldtotal = d->readyReadListeners;
 
876
 
 
877
        if(QLatin1String(signal) == QMetaObject::normalizedSignature(SIGNAL(readyRead())).data())
 
878
                ++d->readyReadListeners;
 
879
 
 
880
        int total = d->readyReadListeners;
 
881
        if(d->c && oldtotal == 0 && total > 0)
 
882
        {
 
883
                d->enabled = true;
 
884
                d->c->setEnabled(true);
 
885
        }
 
886
}
 
887
 
 
888
void RtpChannel::disconnectNotify(const char *signal)
 
889
{
 
890
        int oldtotal = d->readyReadListeners;
 
891
 
 
892
        if(QLatin1String(signal) == QMetaObject::normalizedSignature(SIGNAL(readyRead())).data())
 
893
                --d->readyReadListeners;
 
894
 
 
895
        int total = d->readyReadListeners;
 
896
        if(d->c && oldtotal > 0 && total == 0)
 
897
        {
 
898
                d->enabled = false;
 
899
                d->c->setEnabled(false);
 
900
        }
 
901
}
 
902
 
 
903
//----------------------------------------------------------------------------
 
904
// PayloadInfo
 
905
//----------------------------------------------------------------------------
 
906
bool PayloadInfo::Parameter::operator==(const PayloadInfo::Parameter &other) const
 
907
{
 
908
        // according to xep-167, parameter names are case-sensitive
 
909
        if(name == other.name && value == other.value)
 
910
                return true;
 
911
        else
 
912
                return false;
 
913
}
 
914
 
 
915
class PayloadInfo::Private
 
916
{
 
917
public:
 
918
        int id;
 
919
        QString name;
 
920
        int clockrate;
 
921
        int channels;
 
922
        int ptime;
 
923
        int maxptime;
 
924
        QList<PayloadInfo::Parameter> parameters;
 
925
 
 
926
        Private() :
 
927
                id(-1),
 
928
                clockrate(-1),
 
929
                channels(-1),
 
930
                ptime(-1),
 
931
                maxptime(-1)
 
932
        {
 
933
        }
 
934
 
 
935
        bool operator==(const Private &other) const
 
936
        {
 
937
                // according to xep-167, parameters are unordered
 
938
                if(id == other.id &&
 
939
                        name.compare(other.name, Qt::CaseInsensitive) &&
 
940
                        clockrate == other.clockrate &&
 
941
                        channels == other.channels &&
 
942
                        ptime == other.ptime &&
 
943
                        maxptime == other.maxptime &&
 
944
                        compareUnordered(parameters, other.parameters))
 
945
                {
 
946
                        return true;
 
947
                }
 
948
                else
 
949
                        return false;
 
950
        }
 
951
 
 
952
        static bool compareUnordered(const QList<PayloadInfo::Parameter> &a, const QList<PayloadInfo::Parameter> &b)
 
953
        {
 
954
                if(a.count() != b.count())
 
955
                        return false;
 
956
 
 
957
                // for every parameter in 'a'
 
958
                foreach(const PayloadInfo::Parameter &p, a)
 
959
                {
 
960
                        // make sure it is found in 'b'
 
961
                        if(!b.contains(p))
 
962
                                return false;
 
963
                }
 
964
 
 
965
                return true;
 
966
        }
 
967
};
 
968
 
 
969
PayloadInfo::PayloadInfo() :
 
970
        d(new Private)
 
971
{
 
972
}
 
973
 
 
974
PayloadInfo::PayloadInfo(const PayloadInfo &other) :
 
975
        d(new Private(*other.d))
 
976
{
 
977
}
 
978
 
 
979
PayloadInfo::~PayloadInfo()
 
980
{
 
981
        delete d;
 
982
}
 
983
 
 
984
PayloadInfo & PayloadInfo::operator=(const PayloadInfo &other)
 
985
{
 
986
        *d = *other.d;
 
987
        return *this;
 
988
}
 
989
 
 
990
bool PayloadInfo::isNull() const
 
991
{
 
992
        return (d->id == -1);
 
993
}
 
994
 
 
995
int PayloadInfo::id() const
 
996
{
 
997
        return d->id;
 
998
}
 
999
 
 
1000
QString PayloadInfo::name() const
 
1001
{
 
1002
        return d->name;
 
1003
}
 
1004
 
 
1005
int PayloadInfo::clockrate() const
 
1006
{
 
1007
        return d->clockrate;
 
1008
}
 
1009
 
 
1010
int PayloadInfo::channels() const
 
1011
{
 
1012
        return d->channels;
 
1013
}
 
1014
 
 
1015
int PayloadInfo::ptime() const
 
1016
{
 
1017
        return d->ptime;
 
1018
}
 
1019
 
 
1020
int PayloadInfo::maxptime() const
 
1021
{
 
1022
        return d->maxptime;
 
1023
}
 
1024
 
 
1025
QList<PayloadInfo::Parameter> PayloadInfo::parameters() const
 
1026
{
 
1027
        return d->parameters;
 
1028
}
 
1029
 
 
1030
void PayloadInfo::setId(int i)
 
1031
{
 
1032
        d->id = i;
 
1033
}
 
1034
 
 
1035
void PayloadInfo::setName(const QString &str)
 
1036
{
 
1037
        d->name = str;
 
1038
}
 
1039
 
 
1040
void PayloadInfo::setClockrate(int i)
 
1041
{
 
1042
        d->clockrate = i;
 
1043
}
 
1044
 
 
1045
void PayloadInfo::setChannels(int num)
 
1046
{
 
1047
        d->channels = num;
 
1048
}
 
1049
 
 
1050
void PayloadInfo::setPtime(int i)
 
1051
{
 
1052
        d->ptime = i;
 
1053
}
 
1054
 
 
1055
void PayloadInfo::setMaxptime(int i)
 
1056
{
 
1057
        d->maxptime = i;
 
1058
}
 
1059
 
 
1060
void PayloadInfo::setParameters(const QList<PayloadInfo::Parameter> &params)
 
1061
{
 
1062
        d->parameters = params;
 
1063
}
 
1064
 
 
1065
bool PayloadInfo::operator==(const PayloadInfo &other) const
 
1066
{
 
1067
        return (*d == *other.d);
 
1068
}
 
1069
 
 
1070
//----------------------------------------------------------------------------
 
1071
// RtpSession
 
1072
//----------------------------------------------------------------------------
 
1073
class RtpSessionPrivate : public QObject
 
1074
{
 
1075
        Q_OBJECT
 
1076
 
 
1077
public:
 
1078
        RtpSession *q;
 
1079
        RtpSessionContext *c;
 
1080
        RtpChannel audioRtpChannel;
 
1081
        RtpChannel videoRtpChannel;
 
1082
 
 
1083
        RtpSessionPrivate(RtpSession *_q) :
 
1084
                QObject(_q),
 
1085
                q(_q)
 
1086
        {
 
1087
                c = provider()->createRtpSession();
 
1088
                c->qobject()->setParent(this);
 
1089
                connect(c->qobject(), SIGNAL(started()), SLOT(c_started()));
 
1090
                connect(c->qobject(), SIGNAL(preferencesUpdated()), SLOT(c_preferencesUpdated()));
 
1091
                connect(c->qobject(), SIGNAL(audioOutputIntensityChanged(int)), SLOT(c_audioOutputIntensityChanged(int)));
 
1092
                connect(c->qobject(), SIGNAL(audioInputIntensityChanged(int)), SLOT(c_audioInputIntensityChanged(int)));
 
1093
                connect(c->qobject(), SIGNAL(stoppedRecording()), SLOT(c_stoppedRecording()));
 
1094
                connect(c->qobject(), SIGNAL(stopped()), SLOT(c_stopped()));
 
1095
                connect(c->qobject(), SIGNAL(finished()), SLOT(c_finished()));
 
1096
                connect(c->qobject(), SIGNAL(error()), SLOT(c_error()));
 
1097
        }
 
1098
 
 
1099
        ~RtpSessionPrivate()
 
1100
        {
 
1101
                delete c;
 
1102
        }
 
1103
 
 
1104
private slots:
 
1105
        void c_started()
 
1106
        {
 
1107
                audioRtpChannel.d->setContext(c->audioRtpChannel());
 
1108
                videoRtpChannel.d->setContext(c->videoRtpChannel());
 
1109
                emit q->started();
 
1110
        }
 
1111
 
 
1112
        void c_preferencesUpdated()
 
1113
        {
 
1114
                emit q->preferencesUpdated();
 
1115
        }
 
1116
 
 
1117
        void c_audioOutputIntensityChanged(int intensity)
 
1118
        {
 
1119
                emit q->audioOutputIntensityChanged(intensity);
 
1120
        }
 
1121
 
 
1122
        void c_audioInputIntensityChanged(int intensity)
 
1123
        {
 
1124
                emit q->audioInputIntensityChanged(intensity);
 
1125
        }
 
1126
 
 
1127
        void c_stoppedRecording()
 
1128
        {
 
1129
                emit q->stoppedRecording();
 
1130
        }
 
1131
 
 
1132
        void c_stopped()
 
1133
        {
 
1134
                audioRtpChannel.d->setContext(0);
 
1135
                videoRtpChannel.d->setContext(0);
 
1136
                emit q->stopped();
 
1137
        }
 
1138
 
 
1139
        void c_finished()
 
1140
        {
 
1141
                audioRtpChannel.d->setContext(0);
 
1142
                videoRtpChannel.d->setContext(0);
 
1143
                emit q->finished();
 
1144
        }
 
1145
 
 
1146
        void c_error()
 
1147
        {
 
1148
                audioRtpChannel.d->setContext(0);
 
1149
                videoRtpChannel.d->setContext(0);
 
1150
                emit q->error();
 
1151
        }
 
1152
};
 
1153
 
 
1154
RtpSession::RtpSession(QObject *parent) :
 
1155
        QObject(parent)
 
1156
{
 
1157
        d = new RtpSessionPrivate(this);
 
1158
}
 
1159
 
 
1160
RtpSession::~RtpSession()
 
1161
{
 
1162
        delete d;
 
1163
}
 
1164
 
 
1165
void RtpSession::reset()
 
1166
{
 
1167
        delete d;
 
1168
        d = new RtpSessionPrivate(this);
 
1169
}
 
1170
 
 
1171
void RtpSession::setAudioOutputDevice(const QString &deviceId)
 
1172
{
 
1173
        d->c->setAudioOutputDevice(deviceId);
 
1174
}
 
1175
 
 
1176
#ifdef QT_GUI_LIB
 
1177
void RtpSession::setVideoOutputWidget(VideoWidget *widget)
 
1178
{
 
1179
        d->c->setVideoOutputWidget(widget ? widget->d : 0);
 
1180
}
 
1181
#endif
 
1182
 
 
1183
void RtpSession::setAudioInputDevice(const QString &deviceId)
 
1184
{
 
1185
        d->c->setAudioInputDevice(deviceId);
 
1186
}
 
1187
 
 
1188
void RtpSession::setVideoInputDevice(const QString &deviceId)
 
1189
{
 
1190
        d->c->setVideoInputDevice(deviceId);
 
1191
}
 
1192
 
 
1193
void RtpSession::setFileInput(const QString &fileName)
 
1194
{
 
1195
        d->c->setFileInput(fileName);
 
1196
}
 
1197
 
 
1198
void RtpSession::setFileDataInput(const QByteArray &fileData)
 
1199
{
 
1200
        d->c->setFileDataInput(fileData);
 
1201
}
 
1202
 
 
1203
void RtpSession::setFileLoopEnabled(bool enabled)
 
1204
{
 
1205
        d->c->setFileLoopEnabled(enabled);
 
1206
}
 
1207
 
 
1208
#ifdef QT_GUI_LIB
 
1209
void RtpSession::setVideoPreviewWidget(VideoWidget *widget)
 
1210
{
 
1211
        d->c->setVideoPreviewWidget(widget ? widget->d : 0);
 
1212
}
 
1213
#endif
 
1214
 
 
1215
void RtpSession::setRecordingQIODevice(QIODevice *dev)
 
1216
{
 
1217
        d->c->setRecorder(dev);
 
1218
}
 
1219
 
 
1220
void RtpSession::stopRecording()
 
1221
{
 
1222
        d->c->stopRecording();
 
1223
}
 
1224
 
 
1225
void RtpSession::setLocalAudioPreferences(const QList<AudioParams> &params)
 
1226
{
 
1227
        QList<PAudioParams> list;
 
1228
        foreach(const AudioParams &p, params)
 
1229
                list += exportAudioParams(p);
 
1230
        d->c->setLocalAudioPreferences(list);
 
1231
}
 
1232
 
 
1233
void RtpSession::setLocalVideoPreferences(const QList<VideoParams> &params)
 
1234
{
 
1235
        QList<PVideoParams> list;
 
1236
        foreach(const VideoParams &p, params)
 
1237
                list += exportVideoParams(p);
 
1238
        d->c->setLocalVideoPreferences(list);
 
1239
}
 
1240
 
 
1241
void RtpSession::setMaximumSendingBitrate(int kbps)
 
1242
{
 
1243
        d->c->setMaximumSendingBitrate(kbps);
 
1244
}
 
1245
 
 
1246
void RtpSession::setRemoteAudioPreferences(const QList<PayloadInfo> &info)
 
1247
{
 
1248
        QList<PPayloadInfo> list;
 
1249
        foreach(const PayloadInfo &p, info)
 
1250
                list += exportPayloadInfo(p);
 
1251
        d->c->setRemoteAudioPreferences(list);
 
1252
}
 
1253
 
 
1254
void RtpSession::setRemoteVideoPreferences(const QList<PayloadInfo> &info)
 
1255
{
 
1256
        QList<PPayloadInfo> list;
 
1257
        foreach(const PayloadInfo &p, info)
 
1258
                list += exportPayloadInfo(p);
 
1259
        d->c->setRemoteVideoPreferences(list);
 
1260
}
 
1261
 
 
1262
void RtpSession::start()
 
1263
{
 
1264
        d->c->start();
 
1265
}
 
1266
 
 
1267
void RtpSession::updatePreferences()
 
1268
{
 
1269
        d->c->updatePreferences();
 
1270
}
 
1271
 
 
1272
void RtpSession::transmitAudio()
 
1273
{
 
1274
        d->c->transmitAudio();
 
1275
}
 
1276
 
 
1277
void RtpSession::transmitVideo()
 
1278
{
 
1279
        d->c->transmitVideo();
 
1280
}
 
1281
 
 
1282
void RtpSession::pauseAudio()
 
1283
{
 
1284
        d->c->pauseAudio();
 
1285
}
 
1286
 
 
1287
void RtpSession::pauseVideo()
 
1288
{
 
1289
        d->c->pauseVideo();
 
1290
}
 
1291
 
 
1292
void RtpSession::stop()
 
1293
{
 
1294
        d->c->stop();
 
1295
}
 
1296
 
 
1297
QList<PayloadInfo> RtpSession::localAudioPayloadInfo() const
 
1298
{
 
1299
        QList<PayloadInfo> out;
 
1300
        foreach(const PPayloadInfo &pp, d->c->localAudioPayloadInfo())
 
1301
                out += importPayloadInfo(pp);
 
1302
        return out;
 
1303
}
 
1304
 
 
1305
QList<PayloadInfo> RtpSession::localVideoPayloadInfo() const
 
1306
{
 
1307
        QList<PayloadInfo> out;
 
1308
        foreach(const PPayloadInfo &pp, d->c->localVideoPayloadInfo())
 
1309
                out += importPayloadInfo(pp);
 
1310
        return out;
 
1311
}
 
1312
 
 
1313
QList<PayloadInfo> RtpSession::remoteAudioPayloadInfo() const
 
1314
{
 
1315
        QList<PayloadInfo> out;
 
1316
        foreach(const PPayloadInfo &pp, d->c->remoteAudioPayloadInfo())
 
1317
                out += importPayloadInfo(pp);
 
1318
        return out;
 
1319
}
 
1320
 
 
1321
QList<PayloadInfo> RtpSession::remoteVideoPayloadInfo() const
 
1322
{
 
1323
        QList<PayloadInfo> out;
 
1324
        foreach(const PPayloadInfo &pp, d->c->remoteVideoPayloadInfo())
 
1325
                out += importPayloadInfo(pp);
 
1326
        return out;
 
1327
}
 
1328
 
 
1329
QList<AudioParams> RtpSession::audioParams() const
 
1330
{
 
1331
        QList<AudioParams> out;
 
1332
        foreach(const PAudioParams &pp, d->c->audioParams())
 
1333
                out += importAudioParams(pp);
 
1334
        return out;
 
1335
}
 
1336
 
 
1337
QList<VideoParams> RtpSession::videoParams() const
 
1338
{
 
1339
        QList<VideoParams> out;
 
1340
        foreach(const PVideoParams &pp, d->c->videoParams())
 
1341
                out += importVideoParams(pp);
 
1342
        return out;
 
1343
}
 
1344
 
 
1345
bool RtpSession::canTransmitAudio() const
 
1346
{
 
1347
        return d->c->canTransmitAudio();
 
1348
}
 
1349
 
 
1350
bool RtpSession::canTransmitVideo() const
 
1351
{
 
1352
        return d->c->canTransmitVideo();
 
1353
}
 
1354
 
 
1355
int RtpSession::outputVolume() const
 
1356
{
 
1357
        return d->c->outputVolume();
 
1358
}
 
1359
 
 
1360
void RtpSession::setOutputVolume(int level)
 
1361
{
 
1362
        d->c->setOutputVolume(level);
 
1363
}
 
1364
 
 
1365
int RtpSession::inputVolume() const
 
1366
{
 
1367
        return d->c->inputVolume();
 
1368
}
 
1369
 
 
1370
void RtpSession::setInputVolume(int level)
 
1371
{
 
1372
        d->c->setInputVolume(level);
 
1373
}
 
1374
 
 
1375
RtpSession::Error RtpSession::errorCode() const
 
1376
{
 
1377
        return (RtpSession::Error)d->c->errorCode();
 
1378
}
 
1379
 
 
1380
RtpChannel *RtpSession::audioRtpChannel()
 
1381
{
 
1382
        return &d->audioRtpChannel;
 
1383
}
 
1384
 
 
1385
RtpChannel *RtpSession::videoRtpChannel()
 
1386
{
 
1387
        return &d->videoRtpChannel;
 
1388
}
 
1389
 
 
1390
}
 
1391
 
 
1392
#include "psimedia.moc"