Add support for enabling and negotiating raw RTP packetization.
Raw RTP packetization is done using the existing RtpPacketizerGeneric
without adding the generic payload header. It is intended to be used
together with generic frame descriptor RTP header extension.
Bug: webrtc:10625
Change-Id: I2e3d0a766e4933ddc4ad4abc1449b9b91ba6cd35
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/138061
Commit-Queue: Mirta Dvornicic <mirtad@webrtc.org>
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Reviewed-by: Magnus Jedvert <magjed@webrtc.org>
Reviewed-by: Karl Wiberg <kwiberg@webrtc.org>
Reviewed-by: Rasmus Brandt <brandtr@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#28154}
diff --git a/pc/webrtc_sdp.cc b/pc/webrtc_sdp.cc
index af8a527..83bd378 100644
--- a/pc/webrtc_sdp.cc
+++ b/pc/webrtc_sdp.cc
@@ -180,6 +180,7 @@
// draft-ietf-mmusic-rid-15
// a=rid
static const char kAttributeRid[] = "rid";
+static const char kAttributePacketization[] = "packetization";
// Experimental flags
static const char kAttributeXGoogleFlag[] = "x-google-flag";
@@ -344,6 +345,10 @@
std::string* parameter,
std::string* value,
SdpParseError* error);
+static bool ParsePacketizationAttribute(const std::string& line,
+ const cricket::MediaType media_type,
+ MediaContentDescription* media_desc,
+ SdpParseError* error);
static bool ParseRtcpFbAttribute(const std::string& line,
const cricket::MediaType media_type,
MediaContentDescription* media_desc,
@@ -1744,6 +1749,14 @@
*os << kSdpDelimiterColon << payload_type;
}
+void WritePacketizationHeader(int payload_type, rtc::StringBuilder* os) {
+ // packetization header: a=packetization:|payload_type| <packetization_format>
+ // Add a=packetization
+ InitAttrLine(kAttributePacketization, os);
+ // Add :|payload_type|
+ *os << kSdpDelimiterColon << payload_type;
+}
+
void WriteRtcpFbHeader(int payload_type, rtc::StringBuilder* os) {
// rtcp-fb header: a=rtcp-fb:|payload_type|
// <parameters>/<ccm <ccm_parameters>>
@@ -1820,6 +1833,17 @@
}
template <class T>
+void AddPacketizationLine(const T& codec, std::string* message) {
+ if (!codec.packetization) {
+ return;
+ }
+ rtc::StringBuilder os;
+ WritePacketizationHeader(codec.id, &os);
+ os << " " << *codec.packetization;
+ AddLine(os.str(), message);
+}
+
+template <class T>
void AddRtcpFbLines(const T& codec, std::string* message) {
for (const cricket::FeedbackParam& param : codec.feedback_params.params()) {
rtc::StringBuilder os;
@@ -1871,6 +1895,7 @@
<< cricket::kVideoCodecClockrate;
AddLine(os.str(), message);
}
+ AddPacketizationLine(codec, message);
AddRtcpFbLines(codec, message);
AddFmtpLine(codec, message);
}
@@ -2910,6 +2935,24 @@
AddOrReplaceCodec<T, U>(content_desc, new_codec);
}
+// Adds or updates existing video codec corresponding to |payload_type|
+// according to |packetization|.
+void UpdateVideoCodecPacketization(VideoContentDescription* video_desc,
+ int payload_type,
+ const std::string& packetization) {
+ if (packetization != cricket::kPacketizationParamRaw) {
+ // Ignore unsupported packetization attribute.
+ return;
+ }
+
+ // Codec might already have been populated (from rtpmap).
+ cricket::VideoCodec codec =
+ GetCodecWithPayloadType(video_desc->codecs(), payload_type);
+ codec.packetization = packetization;
+ AddOrReplaceCodec<VideoContentDescription, cricket::VideoCodec>(video_desc,
+ codec);
+}
+
template <class T>
bool PopWildcardCodec(std::vector<T>* codecs, T* wildcard_codec) {
for (auto iter = codecs->begin(); iter != codecs->end(); ++iter) {
@@ -3166,6 +3209,10 @@
if (!GetValue(line, kCodecParamMaxPTime, &maxptime_as_string, error)) {
return false;
}
+ } else if (HasAttribute(line, kAttributePacketization)) {
+ if (!ParsePacketizationAttribute(line, media_type, media_desc, error)) {
+ return false;
+ }
} else if (HasAttribute(line, kAttributeRtcpFb)) {
if (!ParseRtcpFbAttribute(line, media_type, media_desc, error)) {
return false;
@@ -3682,6 +3729,34 @@
return true;
}
+bool ParsePacketizationAttribute(const std::string& line,
+ const cricket::MediaType media_type,
+ MediaContentDescription* media_desc,
+ SdpParseError* error) {
+ if (media_type != cricket::MEDIA_TYPE_VIDEO) {
+ return true;
+ }
+ std::vector<std::string> packetization_fields;
+ rtc::split(line.c_str(), kSdpDelimiterSpaceChar, &packetization_fields);
+ if (packetization_fields.size() < 2) {
+ return ParseFailedGetValue(line, kAttributePacketization, error);
+ }
+ std::string payload_type_string;
+ if (!GetValue(packetization_fields[0], kAttributePacketization,
+ &payload_type_string, error)) {
+ return false;
+ }
+ int payload_type;
+ if (!GetPayloadTypeFromString(line, payload_type_string, &payload_type,
+ error)) {
+ return false;
+ }
+ std::string packetization = packetization_fields[1];
+ UpdateVideoCodecPacketization(media_desc->as_video(), payload_type,
+ packetization);
+ return true;
+}
+
bool ParseRtcpFbAttribute(const std::string& line,
const cricket::MediaType media_type,
MediaContentDescription* media_desc,