aboutsummaryrefslogtreecommitdiff
path: root/src/base/QXmppRtpPacket.cpp
blob: 37d4eb7b94f7a472f71eec316ebeeff2cad7417d (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
/*
 * Copyright (C) 2008-2014 The QXmpp developers
 *
 * Author:
 *  Jeremy Lainé
 *
 * Source:
 *  https://github.com/qxmpp-project/qxmpp
 *
 * This file is a part of QXmpp library.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 */

#include <QDataStream>

#include "QXmppRtpPacket.h"

#define RTP_VERSION 2

QXmppRtpPacket::QXmppRtpPacket()
    : marker(false)
    , type(0)
    , ssrc(0)
    , sequence(0)
    , stamp(0)
{
}

QXmppRtpPacket::~QXmppRtpPacket()
{
}

/// Parses an RTP packet.
///
/// \param ba

bool QXmppRtpPacket::decode(const QByteArray &ba)
{
    if (ba.isEmpty())
        return false;

    // fixed header
    quint8 tmp;
    QDataStream stream(ba);
    stream >> tmp;
    const quint8 cc = (tmp >> 1) & 0xf;
    const int hlen = 12 + 4 * cc;
    if ((tmp >> 6) != RTP_VERSION || ba.size() < hlen)
        return false;
    stream >> tmp;
    marker = (tmp >> 7);
    type = tmp & 0x7f;
    stream >> sequence;
    stream >> stamp;
    stream >> ssrc;

    // contributing source IDs
    csrc.clear();
    quint32 src;
    for (int i = 0; i < cc; ++i) {
        stream >> src;
        csrc << src;
    }

    // retrieve payload
    payload = ba.right(ba.size() - hlen);
    return true;
}

/// Encodes an RTP packet.

QByteArray QXmppRtpPacket::encode() const
{
    Q_ASSERT(csrc.size() < 16);

    // fixed header
    QByteArray ba;
    ba.resize(payload.size() + 12 + 4 * csrc.size());
    QDataStream stream(&ba, QIODevice::WriteOnly);
    stream << quint8((RTP_VERSION << 6) |
                     ((csrc.size() & 0xf) << 1));
    stream << quint8((type & 0x7f) | (marker << 7));
    stream << sequence;
    stream << stamp;
    stream << ssrc;

    // contributing source ids
    foreach (const quint32 &src, csrc)
        stream << src;

    stream.writeRawData(payload.constData(), payload.size());
    return ba;
}

/// Returns a string representation of the RTP header.

QString QXmppRtpPacket::toString() const
{
    return QString("RTP packet seq %1 stamp %2 marker %3 type %4 size %5").arg(
        QString::number(sequence),
        QString::number(stamp),
        QString::number(marker),
        QString::number(type),
        QString::number(payload.size()));
}