summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'Swiften/ScreenSharing/RTPSessionImpl.cpp')
-rw-r--r--Swiften/ScreenSharing/RTPSessionImpl.cpp96
1 files changed, 87 insertions, 9 deletions
diff --git a/Swiften/ScreenSharing/RTPSessionImpl.cpp b/Swiften/ScreenSharing/RTPSessionImpl.cpp
index 922ffa2..33b9c2e 100644
--- a/Swiften/ScreenSharing/RTPSessionImpl.cpp
+++ b/Swiften/ScreenSharing/RTPSessionImpl.cpp
@@ -10,6 +10,7 @@
#include <Swiften/Network/BoostUDPSocket.h>
#include <Swiften/Base/boost_bsignals.h>
#include <Swiften/Network/UDPSocket.h>
+#include <Swiften/Base/Log.h>
#include <boost/algorithm/string/split.hpp>
#include <boost/algorithm/string/classification.hpp>
@@ -63,9 +64,9 @@ RTPSessionImpl::RTPSessionImpl(boost::shared_ptr<UDPSocket> udpSocket, const RTP
// IMPORTANT: The local timestamp unit MUST be set, otherwise RTCP Sender Report info will be calculated wrong
sessparams.SetOwnTimestampUnit(1.0 / payloadType.getClockrate());
- checkError(session.Create(sessparams, &transparams, jrtplib::RTPTransmitter::ExternalProto));
+ checkError(Create(sessparams, &transparams, jrtplib::RTPTransmitter::ExternalProto));
- packetInjecter = static_cast<jrtplib::RTPExternalTransmissionInfo*>(session.GetTransmissionInfo())->GetPacketInjector();
+ packetInjecter = static_cast<jrtplib::RTPExternalTransmissionInfo*>(GetTransmissionInfo())->GetPacketInjector();
udpSocket->onDataRead.connect(boost::bind(&RTPSessionImpl::handleDataRead, this, _1));
udpSocket->listen();
@@ -78,27 +79,27 @@ RTPSessionImpl::~RTPSessionImpl()
void RTPSessionImpl::poll()
{
- checkError(session.Poll()); // Required if threading disabled
+ checkError(Poll()); // Required if threading disabled
}
void RTPSessionImpl::checkIncomingPackets()
{
// session.BeginDataAccess(); // useless without threading
- if (session.GotoFirstSourceWithData() && session.GetCurrentSourceInfo()->GetRTPDataAddress()->IsSameAddress(jRTPRemotePeer)) {
+ if (GotoFirstSourceWithData() && GetCurrentSourceInfo()->GetRTPDataAddress()->IsSameAddress(jRTPRemotePeer)) {
do {
jrtplib::RTPPacket *pack;
- while ((pack = session.GetNextPacket()) != NULL) {
+ while ((pack = GetNextPacket()) != NULL) {
onIncomingPacket(pack->GetPayloadData(), pack->GetPayloadLength(), pack->HasMarker());
- session.DeletePacket(pack);
+ DeletePacket(pack);
}
- } while (session.GotoNextSourceWithData());
+ } while (GotoNextSourceWithData());
}
// session.EndDataAccess(); // useless without threading
}
void RTPSessionImpl::sendPacket(const SafeByteArray& data, int timestampinc, bool marker)
{
- checkError(session.SendPacket((void*)(data.data()), data.size(), payloadType.getID(), marker, timestampinc));
+ checkError(SendPacket((void*)(data.data()), data.size(), payloadType.getID(), marker, timestampinc));
poll();
}
@@ -111,16 +112,69 @@ void RTPSessionImpl::injectData(const SafeByteArray& data)
void RTPSessionImpl::stop(int maxWaitMs)
{
- session.BYEDestroy(jrtplib::RTPTime(0, maxWaitMs * 1000), "", 0);
+ BYEDestroy(jrtplib::RTPTime(0, maxWaitMs * 1000), "", 0);
udpSocket->close();
}
+void RTPSessionImpl::sendSLIFeedback(int pictureID)
+{
+ // Send an SLI as negative feedback. VP8: 0, total number of macroblocks, pictureID (6 bits)
+ int first = 0; // 13 bits
+ int number = 0; // 13 bits // TODO : Find the total number of macroblocks per frame
+
+ uint32_t data = 0;
+ data |= first << 19;
+ data |= (number & 2047) << 6;
+ data |= (pictureID & 63);
+
+ SendUnknownPacket(false, PSFB, PSFB_SLI, (void*)&data, sizeof(uint32_t));
+}
+
+void RTPSessionImpl::sendRPSIFeedback(int pictureID)
+{
+ // Send an RPSI as positive feedback. With VP8, it only contains the picture ID (7 bits)
+ int pb = 9; // trailing padding bits
+ int pt = payloadType.getID(); // payload type (7 bits)
+
+ uint32_t data = 0;
+ data |= pb << 24;
+ data |= (pt & 127) << 16;
+ data |= (pictureID & 127) << 9;
+
+ SendUnknownPacket(false, PSFB, PSFB_RPSI, (void*)&data, sizeof(uint32_t));
+}
+
size_t RTPSessionImpl::getMaxRTPPayloadSize() const
{
jrtplib::RTPSessionParams sessparams;
return sessparams.GetMaximumPacketSize();
}
+void RTPSessionImpl::OnUnknownPacketType(jrtplib::RTCPPacket* rtcpPack, const jrtplib::RTPTime& /*receivetime*/, const jrtplib::RTPAddress* senderAddress)
+{
+ if (!senderAddress->IsSameAddress(jRTPRemotePeer))
+ return;
+
+ uint8_t* data = rtcpPack->GetPacketData();
+ size_t len = rtcpPack->GetPacketLength();
+ jrtplib::RTCPCommonHeader* rtcpHdr = (jrtplib::RTCPCommonHeader*)data;
+ int type = rtcpHdr->packettype;
+ if (type != PSFB)
+ return;
+
+ int subtype = rtcpHdr->count;
+ switch (subtype) {
+ case PSFB_SLI:
+ parseSLIFeedBack(data + 8, len - 8);
+ break;
+ case PSFB_RPSI:
+ parseRPSIFeedBack(data + 8, len - 8);
+ break;
+ default:
+ break;
+ }
+}
+
void RTPSessionImpl::checkError(int rtperr) const
{
if (rtperr < 0)
@@ -132,6 +186,30 @@ void RTPSessionImpl::handleDataRead(boost::shared_ptr<SafeByteArray> data)
injectData(*data);
}
+void RTPSessionImpl::parseSLIFeedBack(uint8_t* data, size_t len)
+{
+ SWIFT_LOG(debug) << "Got SLI feedback (negative)" << std::endl;
+
+ if (len < 4)
+ return;
+ int pictureID = data[len - 1] & 63; // pictureID correspond to the 6 last bits
+ onSLIFeedback(pictureID);
+}
+
+void RTPSessionImpl::parseRPSIFeedBack(uint8_t* data, size_t len)
+{
+ SWIFT_LOG(debug) << "Got RPSI feedback (postive)" << std::endl;
+
+ if (len < 4)
+ return;
+ int pb = data[0]; // First byte : trailing padding bits
+ uint32_t intData = *((uint32_t*)(data));
+ intData >>= pb; // remove padding bits
+ int pictureID = (intData & 127); // pictureID correspond to the 7 last bits
+ onRPSIFeedback(pictureID);
+
+}
+
jrtplib::RTPAddress* RTPSessionImpl::nativeAddressToJRTPAddress(const HostAddressPort& hostAddressPort)
{
jrtplib::RTPAddress* jrtpAddress = 0;