~ubuntu-branches/ubuntu/trusty/digikam/trusty

« back to all changes in this revision

Viewing changes to extra/kipi-plugins/dlnaexport/extra/hupnp_av/src/mediarenderer/htransport_sinkservice_p.cpp

  • Committer: Package Import Robot
  • Author(s): Rohan Garg
  • Date: 2012-11-26 18:24:20 UTC
  • mfrom: (1.9.1) (3.1.23 experimental)
  • Revision ID: package-import@ubuntu.com-20121126182420-qoy6z0nx4ai0wzcl
Tags: 4:3.0.0~beta3-0ubuntu1
* New upstream release
  - Add build-deps :  libhupnp-dev, libqtgstreamer-dev, libmagickcore-dev
* Merge from debian, remaining changes:
  - Make sure libqt4-opengl-dev, libgl1-mesa-dev and libglu1-mesa-dev only
    install on i386,amd64 and powerpc
  - Depend on libtiff-dev instead of libtiff4-dev
  - Drop digikam breaks/replaces kipi-plugins-common since we're past the
    LTS release now
  - digikam to recommend mplayerthumbs | ffmpegthumbs. We currently only
    have latter in the archives, even though former is also supposed to
    be part of kdemultimedia. (LP: #890059)
  - kipi-plugins to recommend www-browser rather than konqueror directly
    since 2.8 no direct usage of konqueror is present in the flickr
    plugin anymore (LP: #1011211)
  - Keep kubuntu_mysqld_executable_name.diff
  - Don't install libkipi translations
  - Keep deps on libcv-dev, libcvaux-dev
  - Keep split packaging of libraries
  - Replace icons from KDE 3 time in debian/xpm.d/*.xpm with the new
    versions (LP: #658047)
* Update debian/not-installed

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *  Copyright (C) 2011 Tuomo Penttinen, all rights reserved.
 
3
 *
 
4
 *  Author: Tuomo Penttinen <tp@herqq.org>
 
5
 *
 
6
 *  This file is part of Herqq UPnP Av (HUPnPAv) library.
 
7
 *
 
8
 *  Herqq UPnP Av is free software: you can redistribute it and/or modify
 
9
 *  it under the terms of the GNU General Public License as published by
 
10
 *  the Free Software Foundation, either version 3 of the License, or
 
11
 *  (at your option) any later version.
 
12
 *
 
13
 *  Herqq UPnP Av 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
 
16
 *  GNU General Public License for more details.
 
17
 *
 
18
 *  You should have received a copy of the GNU General Public License
 
19
 *  along with Herqq UPnP Av. If not, see <http://www.gnu.org/licenses/>.
 
20
 */
 
21
 
 
22
#include "htransport_sinkservice_p.h"
 
23
#include "hmediarenderer_device_p.h"
 
24
#include "hmediarenderer_info.h"
 
25
#include "hrendererconnection_info.h"
 
26
#include "hrendererconnection.h"
 
27
 
 
28
#include "../transport/hmediainfo.h"
 
29
#include "../transport/hpositioninfo.h"
 
30
#include "../transport/htransportinfo.h"
 
31
#include "../transport/htransportaction.h"
 
32
#include "../transport/htransportsettings.h"
 
33
#include "../transport/hdevicecapabilities.h"
 
34
 
 
35
#include <HUpnpCore/private/hlogger_p.h>
 
36
 
 
37
#include <HUpnpCore/HUdn>
 
38
#include <HUpnpCore/HServiceId>
 
39
#include <HUpnpCore/HResourceType>
 
40
#include <HUpnpCore/HStateVariablesSetupData>
 
41
 
 
42
#include <QtCore/QSet>
 
43
#include <QtCore/QDir>
 
44
#include <QtCore/QFile>
 
45
#include <QtCore/QStringList>
 
46
#include <QtCore/QXmlStreamWriter>
 
47
 
 
48
namespace Herqq
 
49
{
 
50
 
 
51
namespace Upnp
 
52
{
 
53
 
 
54
namespace Av
 
55
{
 
56
 
 
57
/*******************************************************************************
 
58
 * HTransportSinkService
 
59
 ******************************************************************************/
 
60
HTransportSinkService::HTransportSinkService() :
 
61
    HAbstractTransportService(),
 
62
        m_owner(0), m_lastId(-1)
 
63
{
 
64
}
 
65
 
 
66
HTransportSinkService::~HTransportSinkService()
 
67
{
 
68
}
 
69
 
 
70
bool HTransportSinkService::init(HMediaRendererDevice* owner)
 
71
{
 
72
    Q_ASSERT(owner);
 
73
    m_owner = owner;
 
74
    return true;
 
75
}
 
76
 
 
77
qint32 HTransportSinkService::setAVTransportURI(
 
78
    quint32 instanceId, const QUrl& currentUri,
 
79
    const QString& currentUriMetaData)
 
80
{
 
81
    if (currentUri.isEmpty() || !currentUri.isValid())
 
82
    {
 
83
        return UpnpInvalidArgs;
 
84
    }
 
85
 
 
86
    HRendererConnection* mediaConnection =
 
87
        m_owner->findConnectionByAvTransportId(instanceId);
 
88
 
 
89
    if (!mediaConnection)
 
90
    {
 
91
        return HAvTransportInfo::InvalidInstanceId;
 
92
    }
 
93
 
 
94
    const HRendererConnectionInfo* info = mediaConnection->info();
 
95
    if (info->mediaInfo().currentUri() == currentUri)
 
96
    {
 
97
        return HAvTransportInfo::ContentBusy;
 
98
    }
 
99
 
 
100
    if (currentUri.host().isEmpty())
 
101
    {
 
102
        QString localPath = currentUri.toLocalFile();
 
103
        if (!QFile::exists(localPath) && !QDir(localPath).exists())
 
104
        {
 
105
            return HAvTransportInfo::ResourceNotFound;
 
106
        }
 
107
        // TODO
 
108
    }
 
109
 
 
110
    return mediaConnection->setResource(currentUri, currentUriMetaData);
 
111
}
 
112
 
 
113
qint32 HTransportSinkService::setNextAVTransportURI(
 
114
    quint32 instanceId, const QUrl& nextUri, const QString& nextUriMetaData)
 
115
{
 
116
    if (nextUri.isEmpty() || !nextUri.isValid())
 
117
    {
 
118
        return UpnpInvalidArgs;
 
119
    }
 
120
 
 
121
    HRendererConnection* mediaConnection =
 
122
        m_owner->findConnectionByAvTransportId(instanceId);
 
123
 
 
124
    if (!mediaConnection)
 
125
    {
 
126
        return HAvTransportInfo::InvalidInstanceId;
 
127
    }
 
128
 
 
129
    const HRendererConnectionInfo* info = mediaConnection->info();
 
130
    if (info->mediaInfo().currentUri() == nextUri)
 
131
    {
 
132
        return HAvTransportInfo::ContentBusy;
 
133
    }
 
134
    else if (info->mediaInfo().nextUri() == nextUri)
 
135
    {
 
136
        return UpnpSuccess;
 
137
    }
 
138
 
 
139
    if (nextUri.host().isEmpty())
 
140
    {
 
141
        QString localPath = nextUri.toLocalFile();
 
142
        if (!QFile::exists(localPath) && !QDir(localPath).exists())
 
143
        {
 
144
            return HAvTransportInfo::ResourceNotFound;
 
145
        }
 
146
        // TODO
 
147
    }
 
148
 
 
149
    return mediaConnection->setNextResource(nextUri, nextUriMetaData);
 
150
}
 
151
 
 
152
qint32 HTransportSinkService::getMediaInfo(quint32 instanceId, HMediaInfo* retVal)
 
153
{
 
154
    Q_ASSERT(retVal);
 
155
 
 
156
    HRendererConnection* mediaConnection =
 
157
        m_owner->findConnectionByAvTransportId(instanceId);
 
158
 
 
159
    if (!mediaConnection)
 
160
    {
 
161
        return HAvTransportInfo::InvalidInstanceId;
 
162
    }
 
163
 
 
164
    *retVal = mediaConnection->info()->mediaInfo();
 
165
    return UpnpSuccess;
 
166
}
 
167
 
 
168
qint32 HTransportSinkService::getMediaInfo_ext(
 
169
    quint32 instanceId, HMediaInfo* retVal)
 
170
{
 
171
    return getMediaInfo(instanceId, retVal);
 
172
}
 
173
 
 
174
qint32 HTransportSinkService::getTransportInfo(
 
175
    quint32 instanceId, HTransportInfo* retVal)
 
176
{
 
177
    Q_ASSERT(retVal);
 
178
 
 
179
    HRendererConnection* mediaConnection = m_owner->findConnectionByAvTransportId(instanceId);
 
180
    if (!mediaConnection)
 
181
    {
 
182
        return HAvTransportInfo::InvalidInstanceId;
 
183
    }
 
184
 
 
185
    *retVal = mediaConnection->info()->transportInfo();
 
186
    return UpnpSuccess;
 
187
}
 
188
 
 
189
qint32 HTransportSinkService::getPositionInfo(
 
190
    quint32 instanceId, HPositionInfo* retVal)
 
191
{
 
192
    Q_ASSERT(retVal);
 
193
 
 
194
    HRendererConnection* mediaConnection = m_owner->findConnectionByAvTransportId(instanceId);
 
195
    if (!mediaConnection)
 
196
    {
 
197
        return HAvTransportInfo::InvalidInstanceId;
 
198
    }
 
199
 
 
200
    *retVal = mediaConnection->info()->positionInfo();
 
201
    return UpnpSuccess;
 
202
}
 
203
 
 
204
qint32 HTransportSinkService::getDeviceCapabilities(
 
205
    quint32 instanceId, HDeviceCapabilities* retVal)
 
206
{
 
207
    Q_ASSERT(retVal);
 
208
 
 
209
    HRendererConnection* mediaConnection = m_owner->findConnectionByAvTransportId(instanceId);
 
210
    if (!mediaConnection)
 
211
    {
 
212
        return HAvTransportInfo::InvalidInstanceId;
 
213
    }
 
214
 
 
215
    *retVal = mediaConnection->info()->deviceCapabilities();
 
216
    return UpnpSuccess;
 
217
}
 
218
 
 
219
qint32 HTransportSinkService::stop(quint32 instanceId)
 
220
{
 
221
    HRendererConnection* mediaConnection =
 
222
        m_owner->findConnectionByAvTransportId(instanceId);
 
223
 
 
224
    if (!mediaConnection)
 
225
    {
 
226
        return HAvTransportInfo::InvalidInstanceId;
 
227
    }
 
228
 
 
229
    return mediaConnection->stop();
 
230
}
 
231
 
 
232
qint32 HTransportSinkService::play(
 
233
    quint32 instanceId, const QString& speed)
 
234
{
 
235
    HRendererConnection* mediaConnection =
 
236
        m_owner->findConnectionByAvTransportId(instanceId);
 
237
 
 
238
    if (!mediaConnection)
 
239
    {
 
240
        return HAvTransportInfo::InvalidInstanceId;
 
241
    }
 
242
 
 
243
    return mediaConnection->play(speed);
 
244
}
 
245
 
 
246
qint32 HTransportSinkService::pause(quint32 instanceId)
 
247
{
 
248
    HRendererConnection* mediaConnection =
 
249
        m_owner->findConnectionByAvTransportId(instanceId);
 
250
 
 
251
    if (!mediaConnection)
 
252
    {
 
253
        return HAvTransportInfo::InvalidInstanceId;
 
254
    }
 
255
 
 
256
    return mediaConnection->pause();
 
257
}
 
258
 
 
259
qint32 HTransportSinkService::record(quint32 instanceId)
 
260
{
 
261
    HRendererConnection* mediaConnection =
 
262
        m_owner->findConnectionByAvTransportId(instanceId);
 
263
 
 
264
    if (!mediaConnection)
 
265
    {
 
266
        return HAvTransportInfo::InvalidInstanceId;
 
267
    }
 
268
 
 
269
    return mediaConnection->record();
 
270
}
 
271
 
 
272
qint32 HTransportSinkService::seek(quint32 instanceId, const HSeekInfo& seekInfo)
 
273
{
 
274
    HRendererConnection* mediaConnection =
 
275
        m_owner->findConnectionByAvTransportId(instanceId);
 
276
 
 
277
    if (!mediaConnection)
 
278
    {
 
279
        return HAvTransportInfo::InvalidInstanceId;
 
280
    }
 
281
 
 
282
    return mediaConnection->seek(seekInfo);
 
283
}
 
284
 
 
285
qint32 HTransportSinkService::next(quint32 instanceId)
 
286
{
 
287
    HRendererConnection* mediaConnection =
 
288
        m_owner->findConnectionByAvTransportId(instanceId);
 
289
 
 
290
    if (!mediaConnection)
 
291
    {
 
292
        return HAvTransportInfo::InvalidInstanceId;
 
293
    }
 
294
 
 
295
    return mediaConnection->next();
 
296
}
 
297
 
 
298
qint32 HTransportSinkService::previous(quint32 instanceId)
 
299
{
 
300
    HRendererConnection* mediaConnection =
 
301
        m_owner->findConnectionByAvTransportId(instanceId);
 
302
 
 
303
    if (!mediaConnection)
 
304
    {
 
305
        return HAvTransportInfo::InvalidInstanceId;
 
306
    }
 
307
 
 
308
    return mediaConnection->previous();
 
309
}
 
310
 
 
311
qint32 HTransportSinkService::setPlayMode(
 
312
    quint32 instanceId, const HPlayMode& playMode)
 
313
{
 
314
    HRendererConnection* mediaConnection =
 
315
        m_owner->findConnectionByAvTransportId(instanceId);
 
316
 
 
317
    if (!mediaConnection)
 
318
    {
 
319
        return HAvTransportInfo::InvalidInstanceId;
 
320
    }
 
321
 
 
322
    return mediaConnection->setPlaymode(playMode);
 
323
}
 
324
 
 
325
qint32 HTransportSinkService::setRecordQualityMode(
 
326
    quint32 instanceId,  const HRecordQualityMode& rqMode)
 
327
{
 
328
    HRendererConnection* mediaConnection =
 
329
        m_owner->findConnectionByAvTransportId(instanceId);
 
330
 
 
331
    if (!mediaConnection)
 
332
    {
 
333
        return HAvTransportInfo::InvalidInstanceId;
 
334
    }
 
335
 
 
336
    return mediaConnection->setRecordQualityMode(rqMode);
 
337
}
 
338
 
 
339
qint32 HTransportSinkService::getTransportSettings(
 
340
    quint32 instanceId, HTransportSettings* retVal)
 
341
{
 
342
    Q_ASSERT(retVal);
 
343
 
 
344
    HRendererConnection* mediaConnection = m_owner->findConnectionByAvTransportId(instanceId);
 
345
    if (!mediaConnection)
 
346
    {
 
347
        return HAvTransportInfo::InvalidInstanceId;
 
348
    }
 
349
 
 
350
    *retVal = mediaConnection->info()->transportSettings();
 
351
    return UpnpSuccess;
 
352
}
 
353
 
 
354
qint32 HTransportSinkService::getCurrentTransportActions(
 
355
    quint32 instanceId, QSet<HTransportAction>* retVal)
 
356
{
 
357
    Q_ASSERT(retVal);
 
358
 
 
359
    HRendererConnection* mediaConnection = m_owner->findConnectionByAvTransportId(instanceId);
 
360
    if (!mediaConnection)
 
361
    {
 
362
        return HAvTransportInfo::InvalidInstanceId;
 
363
    }
 
364
 
 
365
    *retVal = mediaConnection->info()->currentTransportActions();
 
366
    return UpnpSuccess;
 
367
}
 
368
 
 
369
qint32 HTransportSinkService::getDrmState(
 
370
    quint32 instanceId, HAvTransportInfo::DrmState* retVal)
 
371
{
 
372
    Q_ASSERT(retVal);
 
373
 
 
374
    HRendererConnection* mediaConnection = m_owner->findConnectionByAvTransportId(instanceId);
 
375
    if (!mediaConnection)
 
376
    {
 
377
        return HAvTransportInfo::InvalidInstanceId;
 
378
    }
 
379
 
 
380
    *retVal = mediaConnection->info()->drmState();
 
381
    return UpnpSuccess;
 
382
}
 
383
 
 
384
//namespace
 
385
//{
 
386
//void addNamespaces(QXmlStreamReader& reader)
 
387
//{
 
388
//    QXmlStreamNamespaceDeclaration def(
 
389
//        "", "urn:schemas-upnp-org:av:avs");
 
390
//    QXmlStreamNamespaceDeclaration xsi(
 
391
//        "xsi", "http://www.w3.org/2001/XMLSchema-instance");
 
392
//    QXmlStreamNamespaceDeclaration xsiSchemaLocation(
 
393
//        "xsi:schemaLocation", "urn:schemas-upnp-org:av:avs\r\nhttp://www.upnp.org/schemas/av/avs.xsd");
 
394
 
 
395
//    reader.addExtraNamespaceDeclaration(def);
 
396
//    reader.addExtraNamespaceDeclaration(xsi);
 
397
//    reader.addExtraNamespaceDeclaration(xsiSchemaLocation);
 
398
//}
 
399
//}
 
400
 
 
401
qint32 HTransportSinkService::getStateVariables(
 
402
    quint32 instanceId, const QSet<QString>& stateVariableNames,
 
403
    QString* stateVariableValuePairs)
 
404
{
 
405
    HLOG2(H_AT, H_FUN, h_ptr->m_loggingIdentifier);
 
406
 
 
407
    Q_ASSERT(stateVariableValuePairs);
 
408
 
 
409
    HRendererConnection* mediaConnection = m_owner->findConnectionByAvTransportId(instanceId);
 
410
    if (!mediaConnection)
 
411
    {
 
412
        return HAvTransportInfo::InvalidInstanceId;
 
413
    }
 
414
 
 
415
    QString retVal;
 
416
    QXmlStreamWriter writer(&retVal);
 
417
 
 
418
    writer.setCodec("UTF-8");
 
419
    writer.writeStartDocument();
 
420
    writer.writeStartElement("stateVariableValuePairs");
 
421
    writer.writeDefaultNamespace("urn:schemas-upnp-org:av:avs");
 
422
    writer.writeAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance");
 
423
    writer.writeAttribute("xsi:schemaLocation",
 
424
        "urn:schemas-upnp-org:av:avs " \
 
425
        "http://www.upnp.org/schemas/av/avs.xsd");
 
426
 
 
427
    QSet<QString> stateVarNames;
 
428
    if (stateVariableNames.contains("*"))
 
429
    {
 
430
        stateVarNames = HAvTransportInfo::stateVariablesSetupData().names();
 
431
        QSet<QString>::iterator it = stateVarNames.begin();
 
432
        for(; it != stateVarNames.end();)
 
433
        {
 
434
            if (it->startsWith("A_ARG") || *it == "LastChange")
 
435
            {
 
436
                it = stateVarNames.erase(it);
 
437
            }
 
438
            else
 
439
            {
 
440
                ++it;
 
441
            }
 
442
        }
 
443
    }
 
444
    else
 
445
    {
 
446
        stateVarNames = stateVariableNames;
 
447
    }
 
448
 
 
449
    foreach(QString svName, stateVarNames)
 
450
    {
 
451
        svName = svName.trimmed();
 
452
        if (svName.compare("LastChange", Qt::CaseInsensitive) == 0 ||
 
453
            svName.startsWith("A_ARG", Qt::CaseInsensitive))
 
454
        {
 
455
            return HAvTransportInfo::InvalidStateVariableList;
 
456
        }
 
457
 
 
458
        bool ok = false;
 
459
        QString value = mediaConnection->info()->value(svName, &ok);
 
460
        if (ok)
 
461
        {
 
462
            writer.writeStartElement("stateVariable");
 
463
            writer.writeAttribute("variableName", svName);
 
464
            writer.writeCharacters(value);
 
465
            writer.writeEndElement();
 
466
        }
 
467
        else
 
468
        {
 
469
            HLOG_WARN(QString("Could not get the value of state variable [%1]").arg(svName));
 
470
            return HAvTransportInfo::InvalidStateVariableList;
 
471
        }
 
472
    }
 
473
    writer.writeEndElement();
 
474
 
 
475
    *stateVariableValuePairs = retVal;
 
476
    return UpnpSuccess;
 
477
}
 
478
 
 
479
qint32 HTransportSinkService::setStateVariables(
 
480
    quint32 instanceId, const HUdn& avtUdn,
 
481
    const HResourceType& serviceType, const HServiceId& serviceId,
 
482
    const QString& stateVariableValuePairs, QStringList* stateVariableList)
 
483
{
 
484
    HLOG2(H_AT, H_FUN, h_ptr->m_loggingIdentifier);
 
485
 
 
486
    Q_ASSERT(stateVariableList);
 
487
 
 
488
    HRendererConnection* mediaConnection = m_owner->findConnectionByAvTransportId(instanceId);
 
489
    if (!mediaConnection)
 
490
    {
 
491
        return HAvTransportInfo::InvalidInstanceId;
 
492
    }
 
493
 
 
494
    if (avtUdn.isValid(LooseChecks) && avtUdn != parentDevice()->info().udn())
 
495
    {
 
496
        HLOG_WARN(QString("setStateVariables() invoked with invalid UDN [%1]").arg(avtUdn.toString()));
 
497
        return UpnpInvalidArgs;
 
498
    }
 
499
    else if (serviceType.isValid() &&
 
500
            !HAvTransportInfo::supportedServiceType().compare(serviceType, HResourceType::Inclusive))
 
501
    {
 
502
        return HAvTransportInfo::InvalidServiceType;
 
503
    }
 
504
    else if (serviceId.isValid(LooseChecks) &&
 
505
             serviceId != HMediaRendererInfo::defaultAvTransportId())
 
506
    {
 
507
        return HAvTransportInfo::InvalidServiceId;
 
508
    }
 
509
 
 
510
    QXmlStreamReader reader(stateVariableValuePairs.trimmed());
 
511
    //addNamespaces(reader);
 
512
 
 
513
    if (reader.readNextStartElement())
 
514
    {
 
515
        if (reader.name().compare("stateVariableValuePairs", Qt::CaseInsensitive) != 0)
 
516
        {
 
517
            return UpnpInvalidArgs;
 
518
        }
 
519
    }
 
520
    else
 
521
    {
 
522
        if (reader.error() != QXmlStreamReader::NoError)
 
523
        {
 
524
            HLOG_WARN(QString("XML parse failed: %1").arg(reader.errorString()));
 
525
        }
 
526
        return UpnpInvalidArgs;
 
527
    }
 
528
 
 
529
    stateVariableList->clear();
 
530
    while(!reader.atEnd() && reader.readNextStartElement())
 
531
    {
 
532
        QStringRef name = reader.name();
 
533
        if (name == "stateVariable")
 
534
        {
 
535
            QXmlStreamAttributes attrs = reader.attributes();
 
536
            if (!attrs.hasAttribute(QString("variableName")))
 
537
            {
 
538
                HLOG_WARN(QString("Ignoring state variable value pair definition that lacks the [variableName] attribute."));
 
539
            }
 
540
            else
 
541
            {
 
542
                QString svName = attrs.value("variableName").toString();
 
543
                QString value = reader.readElementText().trimmed();
 
544
 
 
545
                if (mediaConnection->setValue(svName, value))
 
546
                {
 
547
                    stateVariableList->append(svName);
 
548
                }
 
549
                else
 
550
                {
 
551
                    HLOG_WARN(QString("Could not set the value of state variable [%1]").arg(svName));
 
552
                    stateVariableList->removeDuplicates();
 
553
                    return HAvTransportInfo::InvalidStateVariableValue;
 
554
                }
 
555
            }
 
556
        }
 
557
        else
 
558
        {
 
559
            HLOG_WARN(QString("Encountered unknown XML element: [%1]").arg(name.toString()));
 
560
        }
 
561
    }
 
562
 
 
563
    stateVariableList->removeDuplicates();
 
564
    return UpnpSuccess;
 
565
}
 
566
 
 
567
qint32 HTransportSinkService::nextId()
 
568
{
 
569
    return ++m_lastId;
 
570
}
 
571
 
 
572
}
 
573
}
 
574
}