aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremy Lainé <jeremy.laine@m4x.org>2015-08-26 11:10:42 +0200
committerJeremy Lainé <jeremy.laine@m4x.org>2015-08-26 11:10:42 +0200
commitb817f5f29ab27ad3920c06e8808225cf4c17e022 (patch)
treedd5850d63582fb3c0fafbac85f456c789af1757b
parent4b6e41029da81b5bb096ff66e4c1225355057d88 (diff)
downloadqxmpp-b817f5f29ab27ad3920c06e8808225cf4c17e022.tar.gz
RTCP: start decoding receiver reports
-rw-r--r--src/base/QXmppRtcpPacket.cpp65
-rw-r--r--src/base/QXmppRtcpPacket.h12
-rw-r--r--tests/qxmpprtcppacket/tst_qxmpprtcppacket.cpp56
3 files changed, 96 insertions, 37 deletions
diff --git a/src/base/QXmppRtcpPacket.cpp b/src/base/QXmppRtcpPacket.cpp
index 7394fa97..7baf25c4 100644
--- a/src/base/QXmppRtcpPacket.cpp
+++ b/src/base/QXmppRtcpPacket.cpp
@@ -36,12 +36,16 @@ enum DescriptionType {
class QXmppRtcpPacketPrivate : public QSharedData
{
public:
+ QXmppRtcpPacketPrivate();
+
/// Number of report blocks.
quint8 count;
/// Payload type.
quint8 type;
/// Raw payload data.
QByteArray payload;
+ // Sender SSRC (for receiver / sender reports only).
+ quint32 ssrc;
QXmppRtcpSenderReport senderReport;
QList<QXmppRtcpReceiverReport> receiverReports;
@@ -66,7 +70,6 @@ public:
bool read(QDataStream &stream);
void write(QDataStream &stream) const;
- quint32 ssrc;
quint64 ntpStamp;
quint32 rtpStamp;
quint32 packetCount;
@@ -153,17 +156,19 @@ bool QXmppRtcpPacket::read(QDataStream &stream)
d->receiverReports.clear();
d->senderReport = QXmppRtcpSenderReport();
d->sourceDescriptions.clear();
- if (d->type == SenderReport) {
- if (!d->senderReport.d->read(s))
+ d->ssrc = 0;
+ if (d->type == ReceiverReport || d->type == SenderReport) {
+ s >> d->ssrc;
+ if (d->type == SenderReport && !d->senderReport.d->read(s))
return false;
- for (int j = 0; j < d->count; ++j) {
+ for (int i = 0; i < d->count; ++i) {
QXmppRtcpReceiverReport receiverReport;
if (!receiverReport.d->read(s))
return false;
d->receiverReports << receiverReport;
}
} else if (d->type == SourceDescription) {
- for (int j = 0; j < d->count; ++j) {
+ for (int i = 0; i < d->count; ++i) {
QXmppRtcpSourceDescription desc;
if (!desc.d->read(s))
return false;
@@ -179,9 +184,13 @@ void QXmppRtcpPacket::write(QDataStream &stream) const
quint8 count;
QDataStream s(&payload, QIODevice::WriteOnly);
- if (d->type == SenderReport) {
- count = 0;
- d->senderReport.d->write(s);
+ if (d->type == ReceiverReport || d->type == SenderReport) {
+ count = d->receiverReports.size();
+ s << d->ssrc;
+ if (d->type == SenderReport)
+ d->senderReport.d->write(s);
+ foreach (const QXmppRtcpReceiverReport &report, d->receiverReports)
+ report.d->write(s);
} else if (d->type == SourceDescription) {
count = d->sourceDescriptions.size();
foreach (const QXmppRtcpSourceDescription &desc, d->sourceDescriptions)
@@ -227,6 +236,24 @@ void QXmppRtcpPacket::setSourceDescriptions(const QList<QXmppRtcpSourceDescripti
d->sourceDescriptions = descriptions;
}
+/// Returns the RTCP packet's source SSRC.
+///
+/// This is only applicable for Sender Reports or Receiver Reports.
+
+quint32 QXmppRtcpPacket::ssrc() const
+{
+ return d->ssrc;
+}
+
+/// Sets the RTCP packet's source SSRC.
+///
+/// This is only applicable for Sender Reports or Receiver Reports.
+
+void QXmppRtcpPacket::setSsrc(quint32 ssrc)
+{
+ d->ssrc = ssrc;
+}
+
/// Returns the RTCP packet type.
quint8 QXmppRtcpPacket::type() const
@@ -243,6 +270,13 @@ void QXmppRtcpPacket::setType(quint8 type)
d->type = type;
}
+QXmppRtcpPacketPrivate::QXmppRtcpPacketPrivate()
+ : count(0)
+ , type(0)
+ , ssrc(0)
+{
+}
+
/// Constructs an empty receiver report.
QXmppRtcpReceiverReport::QXmppRtcpReceiverReport()
@@ -331,16 +365,6 @@ void QXmppRtcpSenderReport::setRtpStamp(quint32 rtpStamp)
d->rtpStamp = rtpStamp;
}
-quint32 QXmppRtcpSenderReport::ssrc() const
-{
- return d->ssrc;
-}
-
-void QXmppRtcpSenderReport::setSsrc(quint32 ssrc)
-{
- d->ssrc = ssrc;
-}
-
quint32 QXmppRtcpSenderReport::octetCount() const
{
return d->octetCount;
@@ -362,8 +386,7 @@ void QXmppRtcpSenderReport::setPacketCount(quint32 count)
}
QXmppRtcpSenderReportPrivate::QXmppRtcpSenderReportPrivate()
- : ssrc(0)
- , ntpStamp(0)
+ : ntpStamp(0)
, rtpStamp(0)
, packetCount(0)
, octetCount(0)
@@ -372,7 +395,6 @@ QXmppRtcpSenderReportPrivate::QXmppRtcpSenderReportPrivate()
bool QXmppRtcpSenderReportPrivate::read(QDataStream &stream)
{
- stream >> ssrc;
stream >> ntpStamp;
stream >> rtpStamp;
stream >> packetCount;
@@ -382,7 +404,6 @@ bool QXmppRtcpSenderReportPrivate::read(QDataStream &stream)
void QXmppRtcpSenderReportPrivate::write(QDataStream &stream) const
{
- stream << ssrc;
stream << ntpStamp;
stream << rtpStamp;
stream << packetCount;
diff --git a/src/base/QXmppRtcpPacket.h b/src/base/QXmppRtcpPacket.h
index 9e682369..7e516579 100644
--- a/src/base/QXmppRtcpPacket.h
+++ b/src/base/QXmppRtcpPacket.h
@@ -59,9 +59,6 @@ public:
bool read(QDataStream &stream);
void write(QDataStream &stream) const;
- quint8 type() const;
- void setType(quint8 type);
-
QList<QXmppRtcpReceiverReport> receiverReports() const;
void setReceiverReports(const QList<QXmppRtcpReceiverReport> &reports);
@@ -71,6 +68,12 @@ public:
QList<QXmppRtcpSourceDescription> sourceDescriptions() const;
void setSourceDescriptions(const QList<QXmppRtcpSourceDescription> &descriptions);
+ quint32 ssrc() const;
+ void setSsrc(quint32 ssrc);
+
+ quint8 type() const;
+ void setType(quint8 type);
+
private:
QSharedDataPointer<QXmppRtcpPacketPrivate> d;
};
@@ -103,9 +106,6 @@ public:
quint32 rtpStamp() const;
void setRtpStamp(quint32 rtpStamp);
- quint32 ssrc() const;
- void setSsrc(quint32 ssrc);
-
quint32 octetCount() const;
void setOctetCount(quint32 count);
diff --git a/tests/qxmpprtcppacket/tst_qxmpprtcppacket.cpp b/tests/qxmpprtcppacket/tst_qxmpprtcppacket.cpp
index 0cdb4019..acfa093e 100644
--- a/tests/qxmpprtcppacket/tst_qxmpprtcppacket.cpp
+++ b/tests/qxmpprtcppacket/tst_qxmpprtcppacket.cpp
@@ -31,7 +31,9 @@ class tst_QXmppRtcpPacket : public QObject
private slots:
void testBad();
+ void testReceiverReport();
void testSenderReport();
+ void testSenderReportWithReceiverReport();
void testSourceDescription();
};
@@ -43,47 +45,83 @@ void tst_QXmppRtcpPacket::testBad()
QCOMPARE(packet.decode(QByteArray()), false);
}
+void tst_QXmppRtcpPacket::testReceiverReport()
+{
+ const QByteArray data = QByteArray::fromHex("81c9000741f3bca22886dfa00000000000005eb90000001000000000fffbdae2");
+
+ QXmppRtcpPacket packet;
+ QVERIFY(packet.decode(data));
+
+ QCOMPARE(packet.receiverReports().size(), 1);
+ QCOMPARE(packet.receiverReports()[0].ssrc(), quint32(679927712));
+ QCOMPARE(packet.senderReport().ntpStamp(), quint64(0));
+ QCOMPARE(packet.senderReport().octetCount(), quint32(0));
+ QCOMPARE(packet.senderReport().packetCount(), quint32(0));
+ QCOMPARE(packet.senderReport().rtpStamp(), quint32(0));
+ QCOMPARE(packet.sourceDescriptions().size(), 0);
+ QCOMPARE(packet.ssrc(), quint32(1106492578));
+ QCOMPARE(packet.type(), quint8(QXmppRtcpPacket::ReceiverReport));
+
+ QCOMPARE(packet.encode(), data);
+}
+
void tst_QXmppRtcpPacket::testSenderReport()
{
- QByteArray data("\x80\xc8\x00\x06\x27\xa6\xe4\xc1\xd9\x7f\xec\x7d\x92\xac\xd9\xe8\xdd\x9e\x32\x57\x00\x00\x00\x74\x00\x00\x48\x80", 28);
+ const QByteArray data = QByteArray::fromHex("80c8000627a6e4c1d97fec7d92acd9e8dd9e32570000007400004880");
QXmppRtcpPacket packet;
QVERIFY(packet.decode(data));
- QCOMPARE(packet.type(), quint8(QXmppRtcpPacket::SenderReport));
QCOMPARE(packet.receiverReports().size(), 0);
-
QCOMPARE(packet.senderReport().ntpStamp(), quint64(15672505252348484072ULL));
QCOMPARE(packet.senderReport().octetCount(), quint32(18560));
QCOMPARE(packet.senderReport().packetCount(), quint32(116));
QCOMPARE(packet.senderReport().rtpStamp(), quint32(3718132311));
- QCOMPARE(packet.senderReport().ssrc(), quint32(665248961));
+ QCOMPARE(packet.ssrc(), quint32(665248961));
+ QCOMPARE(packet.type(), quint8(QXmppRtcpPacket::SenderReport));
+ QCOMPARE(packet.sourceDescriptions().size(), 0);
+
+ QCOMPARE(packet.encode(), data);
+}
+
+void tst_QXmppRtcpPacket::testSenderReportWithReceiverReport()
+{
+ const QByteArray data = QByteArray::fromHex("81c8000c3efeb4decf80b8156fd6542c0000014000000003000001e081bc22520000000000007db50000002500000000fffbd605");
+ QXmppRtcpPacket packet;
+ QVERIFY(packet.decode(data));
+
+ QCOMPARE(packet.receiverReports().size(), 1);
+ QCOMPARE(packet.receiverReports()[0].ssrc(), quint32(2176590418));
+ QCOMPARE(packet.senderReport().ntpStamp(), quint64(14952153165080187948ULL));
+ QCOMPARE(packet.senderReport().octetCount(), quint32(480));
+ QCOMPARE(packet.senderReport().packetCount(), quint32(3));
+ QCOMPARE(packet.senderReport().rtpStamp(), quint32(320));
QCOMPARE(packet.sourceDescriptions().size(), 0);
+ QCOMPARE(packet.ssrc(), quint32(1056879838));
+ QCOMPARE(packet.type(), quint8(QXmppRtcpPacket::SenderReport));
QCOMPARE(packet.encode(), data);
}
void tst_QXmppRtcpPacket::testSourceDescription()
{
- QByteArray data("\x81\xca\x00\x0c\x27\xa6\xe4\xc1\x01\x26\x7b\x64\x30\x33\x61\x37\x63\x34\x38\x2d\x64\x39\x30\x36\x2d\x34\x62\x39\x61\x2d\x39\x38\x32\x30\x2d\x31\x31\x31\x38\x30\x32\x64\x63\x64\x35\x37\x38\x7d\x00\x00\x00\x00", 52);
+ const QByteArray data = QByteArray::fromHex("81ca000c27a6e4c101267b64303361376334382d643930362d346239612d393832302d3131313830326463643537387d00000000");
QXmppRtcpPacket packet;
QVERIFY(packet.decode(data));
- QCOMPARE(packet.type(), quint8(QXmppRtcpPacket::SourceDescription));
QCOMPARE(packet.receiverReports().size(), 0);
-
QCOMPARE(packet.senderReport().ntpStamp(), quint64(0));
QCOMPARE(packet.senderReport().octetCount(), quint32(0));
QCOMPARE(packet.senderReport().packetCount(), quint32(0));
QCOMPARE(packet.senderReport().rtpStamp(), quint32(0));
- QCOMPARE(packet.senderReport().ssrc(), quint32(0));
-
QCOMPARE(packet.sourceDescriptions().size(), 1);
QCOMPARE(packet.sourceDescriptions()[0].cname(), QLatin1String("{d03a7c48-d906-4b9a-9820-111802dcd578}"));
QCOMPARE(packet.sourceDescriptions()[0].name(), QString());
QCOMPARE(packet.sourceDescriptions()[0].ssrc(), quint32(665248961));
+ QCOMPARE(packet.ssrc(), quint32(0));
+ QCOMPARE(packet.type(), quint8(QXmppRtcpPacket::SourceDescription));
QCOMPARE(packet.encode(), data);
}