diff options
| author | Jeremy Lainé <jeremy.laine@m4x.org> | 2015-08-20 13:26:19 +0200 |
|---|---|---|
| committer | Jeremy Lainé <jeremy.laine@m4x.org> | 2015-08-24 08:32:00 +0200 |
| commit | 1c28cc6f1cca7c1cd941e6402027be2ee2c8c42b (patch) | |
| tree | 0a1f058bf4e4b5f88ae11d672ccf9666bbfea6e8 /src/base | |
| parent | f87d817c2f3390d80a038007dcfaf588375319dd (diff) | |
| download | qxmpp-1c28cc6f1cca7c1cd941e6402027be2ee2c8c42b.tar.gz | |
use PIMPL + accessors for QXmppRtpPacket
Diffstat (limited to 'src/base')
| -rw-r--r-- | src/base/QXmppCodec.cpp | 15 | ||||
| -rw-r--r-- | src/base/QXmppRtpChannel.cpp | 73 | ||||
| -rw-r--r-- | src/base/QXmppRtpPacket.cpp | 164 | ||||
| -rw-r--r-- | src/base/QXmppRtpPacket.h | 40 |
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 |
