aboutsummaryrefslogtreecommitdiff
path: root/src/base
diff options
context:
space:
mode:
authorJeremy Lainé <jeremy.laine@m4x.org>2015-08-20 13:26:19 +0200
committerJeremy Lainé <jeremy.laine@m4x.org>2015-08-24 08:32:00 +0200
commit1c28cc6f1cca7c1cd941e6402027be2ee2c8c42b (patch)
tree0a1f058bf4e4b5f88ae11d672ccf9666bbfea6e8 /src/base
parentf87d817c2f3390d80a038007dcfaf588375319dd (diff)
downloadqxmpp-1c28cc6f1cca7c1cd941e6402027be2ee2c8c42b.tar.gz
use PIMPL + accessors for QXmppRtpPacket
Diffstat (limited to 'src/base')
-rw-r--r--src/base/QXmppCodec.cpp15
-rw-r--r--src/base/QXmppRtpChannel.cpp73
-rw-r--r--src/base/QXmppRtpPacket.cpp164
-rw-r--r--src/base/QXmppRtpPacket.h40
4 files changed, 214 insertions, 78 deletions
diff --git a/src/base/QXmppCodec.cpp b/src/base/QXmppCodec.cpp
index 97de1996..328fd043 100644
--- a/src/base/QXmppCodec.cpp
+++ b/src/base/QXmppCodec.cpp
@@ -676,7 +676,7 @@ QList<QXmppVideoFrame> QXmppTheoraDecoder::handlePacket(const QXmppRtpPacket &pa
QList<QXmppVideoFrame> frames;
// theora deframing: draft-ietf-avt-rtp-theora-00
- QDataStream stream(packet.payload);
+ QDataStream stream(packet.payload());
quint32 theora_header;
stream >> theora_header;
@@ -1185,9 +1185,10 @@ QXmppVideoFormat QXmppVpxDecoder::format() const
QList<QXmppVideoFrame> QXmppVpxDecoder::handlePacket(const QXmppRtpPacket &packet)
{
QList<QXmppVideoFrame> frames;
+ const QByteArray payload = packet.payload();
// vp8 deframing: http://tools.ietf.org/html/draft-westin-payload-vp8-00
- QDataStream stream(packet.payload);
+ QDataStream stream(payload);
quint8 vpx_header;
stream >> vpx_header;
@@ -1198,7 +1199,7 @@ QList<QXmppVideoFrame> QXmppVpxDecoder::handlePacket(const QXmppRtpPacket &packe
return frames;
}
- const int packetLength = packet.payload.size() - 1;
+ const int packetLength = payload.size() - 1;
#ifdef QXMPP_DEBUG_VPX
qDebug("Vpx fragment FI: %d, size %d", frag_type, packetLength);
#endif
@@ -1216,9 +1217,9 @@ QList<QXmppVideoFrame> QXmppVpxDecoder::handlePacket(const QXmppRtpPacket &packe
if (frag_type == NoFragment) {
// unfragmented packet
- if ((packet.payload[1] & 0x1) == 0 // is key frame
+ if ((payload[1] & 0x1) == 0 // is key frame
|| packet.sequence == sequence) {
- if (d->decodeFrame(packet.payload.mid(1), &frame))
+ if (d->decodeFrame(payload.mid(1), &frame))
frames << frame;
sequence = packet.sequence + 1;
@@ -1229,9 +1230,9 @@ QList<QXmppVideoFrame> QXmppVpxDecoder::handlePacket(const QXmppRtpPacket &packe
// fragments
if (frag_type == StartFragment) {
// start fragment
- if ((packet.payload[1] & 0x1) == 0 // is key frame
+ if ((payload[1] & 0x1) == 0 // is key frame
|| packet.sequence == sequence) {
- d->packetBuffer = packet.payload.mid(1);
+ d->packetBuffer = payload.mid(1);
sequence = packet.sequence + 1;
}
} else {
diff --git a/src/base/QXmppRtpChannel.cpp b/src/base/QXmppRtpChannel.cpp
index ca498a63..55dad68c 100644
--- a/src/base/QXmppRtpChannel.cpp
+++ b/src/base/QXmppRtpChannel.cpp
@@ -345,28 +345,29 @@ void QXmppRtpAudioChannel::datagramReceived(const QByteArray &ba)
// check sequence number
#if 0
- if (d->incomingSequence && packet.sequence != d->incomingSequence + 1)
+ if (d->incomingSequence && packet.sequence() != d->incomingSequence + 1)
warning(QString("RTP packet seq %1 is out of order, previous was %2")
- .arg(QString::number(packet.sequence))
+ .arg(QString::number(packet.sequence()))
.arg(QString::number(d->incomingSequence)));
#endif
- d->incomingSequence = packet.sequence;
+ d->incomingSequence = packet.sequence();
// get or create codec
QXmppCodec *codec = 0;
- if (!d->incomingCodecs.contains(packet.type)) {
+ const quint8 packetType = packet.type();
+ if (!d->incomingCodecs.contains(packetType)) {
foreach (const QXmppJinglePayloadType &payload, m_incomingPayloadTypes) {
- if (packet.type == payload.id()) {
+ if (packetType == payload.id()) {
codec = d->codecForPayloadType(payload);
break;
}
}
if (codec)
- d->incomingCodecs.insert(packet.type, codec);
+ d->incomingCodecs.insert(packetType, codec);
else
- warning(QString("Could not find codec for RTP type %1").arg(QString::number(packet.type)));
+ warning(QString("Could not find codec for RTP type %1").arg(QString::number(packetType)));
} else {
- codec = d->incomingCodecs.value(packet.type);
+ codec = d->incomingCodecs.value(packetType);
}
if (!codec)
return;
@@ -374,25 +375,25 @@ void QXmppRtpAudioChannel::datagramReceived(const QByteArray &ba)
// determine packet's position in the buffer (in bytes)
qint64 packetOffset = 0;
if (!d->incomingBuffer.isEmpty()) {
- packetOffset = packet.stamp * SAMPLE_BYTES - d->incomingPos;
+ packetOffset = packet.stamp() * SAMPLE_BYTES - d->incomingPos;
if (packetOffset < 0) {
#ifdef QXMPP_DEBUG_RTP_BUFFER
warning(QString("RTP packet stamp %1 is too old, buffer start is %2")
- .arg(QString::number(packet.stamp))
+ .arg(QString::number(packet.stamp()))
.arg(QString::number(d->incomingPos)));
#endif
return;
}
} else {
- d->incomingPos = packet.stamp * SAMPLE_BYTES + (d->incomingPos % SAMPLE_BYTES);
+ d->incomingPos = packet.stamp() * SAMPLE_BYTES + (d->incomingPos % SAMPLE_BYTES);
}
// allocate space for new packet
// FIXME: this is wrong, we want the decoded data size!
- qint64 packetLength = packet.payload.size();
+ const qint64 packetLength = packet.payload().size();
if (packetOffset + packetLength > d->incomingBuffer.size())
d->incomingBuffer += QByteArray(packetOffset + packetLength - d->incomingBuffer.size(), 0);
- QDataStream input(packet.payload);
+ QDataStream input(packet.payload());
QDataStream output(&d->incomingBuffer, QIODevice::WriteOnly);
output.device()->seek(packetOffset);
output.setByteOrder(QDataStream::LittleEndian);
@@ -622,16 +623,18 @@ void QXmppRtpAudioChannel::writeDatagram()
if (d->outgoingTonesType.id()) {
// send RFC 2833 DTMF
QXmppRtpPacket packet;
- packet.marker = (info.outgoingStart == d->outgoingStamp);
- packet.type = d->outgoingTonesType.id();
- packet.sequence = d->outgoingSequence;
- packet.stamp = info.outgoingStart;
- packet.ssrc = localSsrc();
-
- QDataStream output(&packet.payload, QIODevice::WriteOnly);
+ packet.setMarker(info.outgoingStart == d->outgoingStamp);
+ packet.setType(d->outgoingTonesType.id());
+ packet.setSequence(d->outgoingSequence);
+ packet.setStamp(info.outgoingStart);
+ packet.setSsrc(localSsrc());
+
+ QByteArray payload;
+ QDataStream output(&payload, QIODevice::WriteOnly);
output << quint8(info.tone);
output << quint8(info.finished ? 0x80 : 0x00);
output << quint16(d->outgoingStamp + packetTicks - info.outgoingStart);
+ packet.setPayload(payload);
#ifdef QXMPP_DEBUG_RTP
logSent(packet.toString());
#endif
@@ -655,21 +658,23 @@ void QXmppRtpAudioChannel::writeDatagram()
QXmppRtpPacket packet;
if (d->outgoingMarker)
{
- packet.marker = true;
+ packet.setMarker(true);
d->outgoingMarker = false;
} else {
- packet.marker = false;
+ packet.setMarker(false);
}
- packet.type = d->payloadType.id();
- packet.sequence = d->outgoingSequence;
- packet.stamp = d->outgoingStamp;
- packet.ssrc = localSsrc();
+ packet.setType(d->payloadType.id());
+ packet.setSequence(d->outgoingSequence);
+ packet.setStamp(d->outgoingStamp);
+ packet.setSsrc(localSsrc());
// encode audio chunk
QDataStream input(chunk);
input.setByteOrder(QDataStream::LittleEndian);
- QDataStream output(&packet.payload, QIODevice::WriteOnly);
+ QByteArray payload;
+ QDataStream output(&payload, QIODevice::WriteOnly);
const qint64 packetTicks = d->outgoingCodec->encode(input, output);
+ packet.setPayload(payload);
#ifdef QXMPP_DEBUG_RTP
logSent(packet.toString());
@@ -872,7 +877,7 @@ void QXmppRtpVideoChannel::datagramReceived(const QByteArray &ba)
#endif
// get codec
- QXmppVideoDecoder *decoder = d->decoders.value(packet.type);
+ QXmppVideoDecoder *decoder = d->decoders.value(packet.type());
if (!decoder)
return;
d->frames << decoder->handlePacket(packet);
@@ -988,13 +993,13 @@ void QXmppRtpVideoChannel::writeFrame(const QXmppVideoFrame &frame)
}
QXmppRtpPacket packet;
- packet.marker = false;
- packet.type = d->outgoingId;
- packet.ssrc = localSsrc();
+ packet.setMarker(false);
+ packet.setType(d->outgoingId);
+ packet.setSsrc(localSsrc());
foreach (const QByteArray &payload, d->encoder->handleFrame(frame)) {
- packet.sequence = d->outgoingSequence++;
- packet.stamp = d->outgoingStamp;
- packet.payload = payload;
+ packet.setSequence(d->outgoingSequence++);
+ packet.setStamp(d->outgoingStamp);
+ packet.setPayload(payload);
#ifdef QXMPP_DEBUG_RTP
logSent(packet.toString());
#endif
diff --git a/src/base/QXmppRtpPacket.cpp b/src/base/QXmppRtpPacket.cpp
index 37d4eb7b..4f1ed17b 100644
--- a/src/base/QXmppRtpPacket.cpp
+++ b/src/base/QXmppRtpPacket.cpp
@@ -22,12 +22,34 @@
*/
#include <QDataStream>
+#include <QSharedData>
#include "QXmppRtpPacket.h"
#define RTP_VERSION 2
-QXmppRtpPacket::QXmppRtpPacket()
+class QXmppRtpPacketPrivate : public QSharedData
+{
+public:
+ QXmppRtpPacketPrivate();
+
+ /// Marker flag.
+ bool marker;
+ /// Payload type.
+ quint8 type;
+ /// Synchronization source.
+ quint32 ssrc;
+ /// Contributing sources.
+ QList<quint32> csrc;
+ /// Sequence number.
+ quint16 sequence;
+ /// Timestamp.
+ quint32 stamp;
+ /// Raw payload data.
+ QByteArray payload;
+};
+
+QXmppRtpPacketPrivate::QXmppRtpPacketPrivate()
: marker(false)
, type(0)
, ssrc(0)
@@ -36,10 +58,36 @@ QXmppRtpPacket::QXmppRtpPacket()
{
}
+/// Constructs an empty RTP packet
+
+QXmppRtpPacket::QXmppRtpPacket()
+ : d(new QXmppRtpPacketPrivate())
+{
+}
+
+/// Constructs a copy of other.
+///
+/// \param other
+///
+QXmppRtpPacket::QXmppRtpPacket(const QXmppRtpPacket &other)
+ : d(other.d)
+{
+}
+
QXmppRtpPacket::~QXmppRtpPacket()
{
}
+/// Assigns the other packet to this one.
+///
+/// \param other
+///
+QXmppRtpPacket& QXmppRtpPacket::operator=(const QXmppRtpPacket& other)
+{
+ d = other.d;
+ return *this;
+}
+
/// Parses an RTP packet.
///
/// \param ba
@@ -58,22 +106,22 @@ bool QXmppRtpPacket::decode(const QByteArray &ba)
if ((tmp >> 6) != RTP_VERSION || ba.size() < hlen)
return false;
stream >> tmp;
- marker = (tmp >> 7);
- type = tmp & 0x7f;
- stream >> sequence;
- stream >> stamp;
- stream >> ssrc;
+ d->marker = (tmp >> 7);
+ d->type = tmp & 0x7f;
+ stream >> d->sequence;
+ stream >> d->stamp;
+ stream >> d->ssrc;
// contributing source IDs
- csrc.clear();
+ d->csrc.clear();
quint32 src;
for (int i = 0; i < cc; ++i) {
stream >> src;
- csrc << src;
+ d->csrc << src;
}
// retrieve payload
- payload = ba.right(ba.size() - hlen);
+ d->payload = ba.right(ba.size() - hlen);
return true;
}
@@ -81,35 +129,105 @@ bool QXmppRtpPacket::decode(const QByteArray &ba)
QByteArray QXmppRtpPacket::encode() const
{
- Q_ASSERT(csrc.size() < 16);
+ Q_ASSERT(d->csrc.size() < 16);
// fixed header
QByteArray ba;
- ba.resize(payload.size() + 12 + 4 * csrc.size());
+ ba.resize(d->payload.size() + 12 + 4 * d->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;
+ ((d->csrc.size() & 0xf) << 1));
+ stream << quint8((d->type & 0x7f) | (d->marker << 7));
+ stream << d->sequence;
+ stream << d->stamp;
+ stream << d->ssrc;
// contributing source ids
- foreach (const quint32 &src, csrc)
+ foreach (const quint32 &src, d->csrc)
stream << src;
- stream.writeRawData(payload.constData(), payload.size());
+ stream.writeRawData(d->payload.constData(), d->payload.size());
return ba;
}
+QList<quint32> QXmppRtpPacket::csrc() const
+{
+ return d->csrc;
+}
+
+void QXmppRtpPacket::setCsrc(const QList<quint32> &csrc)
+{
+ d->csrc = csrc;
+}
+
+bool QXmppRtpPacket::marker() const
+{
+ return d->marker;
+}
+
+void QXmppRtpPacket::setMarker(bool marker)
+{
+ d->marker = marker;
+}
+
+QByteArray QXmppRtpPacket::payload() const
+{
+ return d->payload;
+}
+
+void QXmppRtpPacket::setPayload(const QByteArray &payload)
+{
+ d->payload = payload;
+}
+
+quint32 QXmppRtpPacket::ssrc() const
+{
+ return d->ssrc;
+}
+
+void QXmppRtpPacket::setSsrc(quint32 ssrc)
+{
+ d->ssrc = ssrc;
+}
+
+quint16 QXmppRtpPacket::sequence() const
+{
+ return d->sequence;
+}
+
+void QXmppRtpPacket::setSequence(quint16 sequence)
+{
+ d->sequence = sequence;
+}
+
+quint32 QXmppRtpPacket::stamp() const
+{
+ return d->stamp;
+}
+
+void QXmppRtpPacket::setStamp(quint32 stamp)
+{
+ d->stamp = stamp;
+}
+
+quint8 QXmppRtpPacket::type() const
+{
+ return d->type;
+}
+
+void QXmppRtpPacket::setType(quint8 type)
+{
+ d->type = type;
+}
+
/// 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()));
+ QString::number(d->sequence),
+ QString::number(d->stamp),
+ QString::number(d->marker),
+ QString::number(d->type),
+ QString::number(d->payload.size()));
}
diff --git a/src/base/QXmppRtpPacket.h b/src/base/QXmppRtpPacket.h
index d4ef590a..519769b6 100644
--- a/src/base/QXmppRtpPacket.h
+++ b/src/base/QXmppRtpPacket.h
@@ -37,26 +37,38 @@ class QXMPP_EXPORT QXmppRtpPacket
{
public:
QXmppRtpPacket();
+ QXmppRtpPacket(const QXmppRtpPacket &other);
~QXmppRtpPacket();
+ QXmppRtpPacket& operator=(const QXmppRtpPacket &other);
+
bool decode(const QByteArray &ba);
QByteArray encode() const;
QString toString() const;
- /// Marker flag.
- bool marker;
- /// Payload type.
- quint8 type;
- /// Synchronization source.
- quint32 ssrc;
- /// Contributing sources.
- QList<quint32> csrc;
- /// Sequence number.
- quint16 sequence;
- /// Timestamp.
- quint32 stamp;
- /// Raw payload data.
- QByteArray payload;
+ QList<quint32> csrc() const;
+ void setCsrc(const QList<quint32> &csrc);
+
+ bool marker() const;
+ void setMarker(bool marker);
+
+ QByteArray payload() const;
+ void setPayload(const QByteArray &payload);
+
+ quint16 sequence() const;
+ void setSequence(quint16 sequence);
+
+ quint32 ssrc() const;
+ void setSsrc(quint32 ssrc);
+
+ quint32 stamp() const;
+ void setStamp(quint32 stamp);
+
+ quint8 type() const;
+ void setType(quint8 type);
+
+private:
+ QSharedDataPointer<QXmppRtpPacketPrivate> d;
};
#endif