Bläddra i källkod

Merge pull request #615 from paullouisageneau/enhance-rtp-demux

Enhance RTP and RTCP demultiplexing
Paul-Louis Ageneau 3 år sedan
förälder
incheckning
8339526e6a
4 ändrade filer med 35 tillägg och 18 borttagningar
  1. 2 0
      include/rtc/rtp.hpp
  2. 3 14
      src/impl/dtlssrtptransport.cpp
  3. 13 4
      src/impl/track.cpp
  4. 17 0
      src/rtp.cpp

+ 2 - 0
include/rtc/rtp.hpp

@@ -29,6 +29,8 @@ namespace rtc {
 
 typedef uint32_t SSRC;
 
+RTC_CPP_EXPORT bool IsRtcp(const binary &data);
+
 #pragma pack(push, 1)
 
 struct RTC_CPP_EXPORT RtpExtensionHeader {

+ 3 - 14
src/impl/dtlssrtptransport.cpp

@@ -104,18 +104,7 @@ bool DtlsSrtpTransport::sendMedia(message_ptr message) {
 	// the authentication tag) into the location in memory immediately following the RTP packet.
 	message->resize(size + SRTP_MAX_TRAILER_LEN);
 
-	uint8_t value2 = to_integer<uint8_t>(*(message->begin() + 1)) & 0x7F;
-	PLOG_VERBOSE << "Demultiplexing SRTCP and SRTP with RTP payload type, value="
-	             << unsigned(value2);
-
-	// RFC 5761 Multiplexing RTP and RTCP 4. Distinguishable RTP and RTCP Packets
-	// https://www.rfc-editor.org/rfc/rfc5761.html#section-4
-	// It is RECOMMENDED to follow the guidelines in the RTP/AVP profile for the choice of RTP
-	// payload type values, with the additional restriction that payload type values in the
-	// range 64-95 MUST NOT be used. Specifically, dynamic RTP payload types SHOULD be chosen in
-	// the range 96-127 where possible. Values below 64 MAY be used if that is insufficient
-	// [...]
-	if (value2 >= 64 && value2 <= 95) { // Range 64-95 (inclusive) MUST be RTCP
+	if (IsRtcp(*message)) { // Demultiplex RTCP and RTP using payload type
 		if (srtp_err_status_t err = srtp_protect_rtcp(mSrtpOut, message->data(), &size)) {
 			if (err == srtp_err_status_replay_fail)
 				throw std::runtime_error("Outgoing SRTCP packet is a replay");
@@ -124,6 +113,7 @@ bool DtlsSrtpTransport::sendMedia(message_ptr message) {
 				                         to_string(static_cast<int>(err)));
 		}
 		PLOG_VERBOSE << "Protected SRTCP packet, size=" << size;
+
 	} else {
 		if (srtp_err_status_t err = srtp_protect(mSrtpOut, message->data(), &size)) {
 			if (err == srtp_err_status_replay_fail)
@@ -160,8 +150,7 @@ void DtlsSrtpTransport::recvMedia(message_ptr message) {
 	PLOG_VERBOSE << "Demultiplexing SRTCP and SRTP with RTP payload type, value="
 	             << unsigned(value2);
 
-	// See RFC 5761 reference above
-	if (value2 >= 64 && value2 <= 95) { // Range 64-95 (inclusive) MUST be RTCP
+	if (IsRtcp(*message)) { // Demultiplex RTCP and RTP using payload type
 		PLOG_VERBOSE << "Incoming SRTCP packet, size=" << size;
 		if (srtp_err_status_t err = srtp_unprotect_rtcp(mSrtpIn, message->data(), &size)) {
 			if (err == srtp_err_status_replay_fail) {

+ 13 - 4
src/impl/track.cpp

@@ -20,6 +20,7 @@
 #include "internals.hpp"
 #include "logcounter.hpp"
 #include "peerconnection.hpp"
+#include "rtp.hpp"
 
 namespace rtc::impl {
 
@@ -122,7 +123,8 @@ void Track::incoming(message_ptr message) {
 	if (!message)
 		return;
 
-	// TODO
+	auto handler = getMediaHandler();
+
 	auto dir = direction();
 	if ((dir == Description::Direction::SendOnly || dir == Description::Direction::Inactive) &&
 	    message->type != Message::Control) {
@@ -130,7 +132,7 @@ void Track::incoming(message_ptr message) {
 		return;
 	}
 
-	if (auto handler = getMediaHandler()) {
+	if (handler) {
 		message = handler->incoming(message);
 		if (!message)
 			return;
@@ -150,13 +152,20 @@ bool Track::outgoing(message_ptr message) {
 	if (mIsClosed)
 		throw std::runtime_error("Track is closed");
 
+	auto handler = getMediaHandler();
+
+	// If there is no handler, the track expects RTP or RTCP packets
+	if (!handler && IsRtcp(*message))
+		message->type = Message::Control; // to allow sending RTCP packets irrelevant of direction
+
 	auto dir = direction();
-	if ((dir == Description::Direction::RecvOnly || dir == Description::Direction::Inactive)) {
+	if ((dir == Description::Direction::RecvOnly || dir == Description::Direction::Inactive) &&
+	    message->type != Message::Control) {
 		COUNTER_MEDIA_BAD_DIRECTION++;
 		return false;
 	}
 
-	if (auto handler = getMediaHandler()) {
+	if (handler) {
 		message = handler->outgoing(message);
 		if (!message)
 			return false;

+ 17 - 0
src/rtp.cpp

@@ -41,6 +41,23 @@
 
 namespace rtc {
 
+bool IsRtcp(const binary &data) {
+	if (data.size() < 8)
+		return false;
+
+	uint8_t payloadType = std::to_integer<uint8_t>(data[1]) & 0x7F;
+	PLOG_VERBOSE << "Demultiplexing RTCP and RTP with payload type, value=" << int(payloadType);
+
+	// RFC 5761 Multiplexing RTP and RTCP 4. Distinguishable RTP and RTCP Packets
+	// https://www.rfc-editor.org/rfc/rfc5761.html#section-4
+	// It is RECOMMENDED to follow the guidelines in the RTP/AVP profile for the choice of RTP
+	// payload type values, with the additional restriction that payload type values in the
+	// range 64-95 MUST NOT be used. Specifically, dynamic RTP payload types SHOULD be chosen in
+	// the range 96-127 where possible. Values below 64 MAY be used if that is insufficient
+	// [...]
+	return (payloadType >= 64 && payloadType <= 95); // Range 64-95 (inclusive) MUST be RTCP
+}
+
 uint8_t RtpHeader::version() const { return _first >> 6; }
 bool RtpHeader::padding() const { return (_first >> 5) & 0x01; }
 bool RtpHeader::extension() const { return (_first >> 4) & 0x01; }