Add MSID signaling compatibility for Unified Plan endpoints
This is intended to ensure compatibility between Plan B and
Unified Plan endpoints for the single audio - single video case.
If Unified Plan is the offerer, it will add a=msid and a=ssrc MSID
entries to its offer.
If Unified Plan is the answerer, it will use whatever MSID
signaling mechanism was used in the offer (either a=msid or
a=ssrc).
Bug: webrtc:7600
Change-Id: I6192dec19123fbb56f5d04540d2175c7fb30b9b6
Reviewed-on: https://webrtc-review.googlesource.com/44162
Commit-Queue: Steve Anton <steveanton@webrtc.org>
Reviewed-by: Taylor Brandstetter <deadbeef@webrtc.org>
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#21859}
diff --git a/pc/webrtcsdp.cc b/pc/webrtcsdp.cc
index 56f4c99..535ed23 100644
--- a/pc/webrtcsdp.cc
+++ b/pc/webrtcsdp.cc
@@ -232,14 +232,14 @@
const TransportInfo* transport_info,
const MediaType media_type,
const std::vector<Candidate>& candidates,
- bool unified_plan_sdp,
+ int msid_signaling,
std::string* message);
static void BuildSctpContentAttributes(std::string* message,
int sctp_port,
bool use_sctpmap);
static void BuildRtpContentAttributes(const MediaContentDescription* media_desc,
const MediaType media_type,
- bool unified_plan_sdp,
+ int msid_signaling,
std::string* message);
static void BuildRtpMap(const MediaContentDescription* media_desc,
const MediaType media_type,
@@ -280,12 +280,14 @@
size_t* pos,
std::string* content_name,
bool* bundle_only,
+ int* msid_signaling,
MediaContentDescription* media_desc,
TransportDescription* transport,
std::vector<JsepIceCandidate*>* candidates,
SdpParseError* error);
static bool ParseSsrcAttribute(const std::string& line,
SsrcInfoVec* ssrc_infos,
+ int* msid_signaling,
SdpParseError* error);
static bool ParseSsrcGroupAttribute(const std::string& line,
SsrcGroupVec* ssrc_groups,
@@ -601,7 +603,7 @@
track_id = ssrc_info->label;
} else if (ssrc_info->stream_id.empty() && !msid_stream_id.empty()) {
// If there's no msid in the SSRC attributes, but there's a global one
- // (from a=msid), use that. This is the case with unified plan SDP.
+ // (from a=msid), use that. This is the case with Unified Plan SDP.
stream_id = msid_stream_id;
track_id = msid_track_id;
} else {
@@ -757,8 +759,7 @@
return port >= 0 && port <= 65535;
}
-std::string SdpSerialize(const JsepSessionDescription& jdesc,
- bool unified_plan_sdp) {
+std::string SdpSerialize(const JsepSessionDescription& jdesc) {
const cricket::SessionDescription* desc = jdesc.description();
if (!desc) {
return "";
@@ -829,7 +830,7 @@
std::vector<Candidate> candidates;
GetCandidatesByMindex(jdesc, ++mline_index, &candidates);
BuildMediaDescription(&*it, desc->GetTransportInfoByName(it->name),
- mdesc->type(), candidates, unified_plan_sdp,
+ mdesc->type(), candidates, desc->msid_signaling(),
&message);
}
return message;
@@ -1199,7 +1200,7 @@
const TransportInfo* transport_info,
const MediaType media_type,
const std::vector<Candidate>& candidates,
- bool unified_plan_sdp,
+ int msid_signaling,
std::string* message) {
RTC_DCHECK(message != NULL);
if (content_info == NULL || message == NULL) {
@@ -1405,8 +1406,7 @@
bool use_sctpmap = data_desc->use_sctpmap();
BuildSctpContentAttributes(message, sctp_port, use_sctpmap);
} else if (IsRtp(media_desc->protocol())) {
- BuildRtpContentAttributes(media_desc, media_type, unified_plan_sdp,
- message);
+ BuildRtpContentAttributes(media_desc, media_type, msid_signaling, message);
}
}
@@ -1431,10 +1431,9 @@
AddLine(os.str(), message);
}
-// If unified_plan_sdp is true, will use "a=msid".
void BuildRtpContentAttributes(const MediaContentDescription* media_desc,
const MediaType media_type,
- bool unified_plan_sdp,
+ int msid_signaling,
std::string* message) {
std::ostringstream os;
// RFC 5285
@@ -1471,19 +1470,20 @@
}
AddLine(os.str(), message);
- // draft-ietf-mmusic-msid-11
+ // Specified in https://tools.ietf.org/html/draft-ietf-mmusic-msid-16
// a=msid:<stream id> <track id>
- if (unified_plan_sdp && !media_desc->streams().empty()) {
- if (media_desc->streams().size() > 1u) {
- RTC_LOG(LS_WARNING)
- << "Trying to serialize unified plan SDP with more than "
- << "one track in a media section. Omitting 'a=msid'.";
- } else {
- auto track = media_desc->streams().begin();
- const std::string& stream_id = track->sync_label;
+ if (msid_signaling & cricket::kMsidSignalingMediaSection) {
+ const StreamParamsVec& streams = media_desc->streams();
+ if (streams.size() == 1u) {
+ const StreamParams& track = streams[0];
+ const std::string& stream_id = track.sync_label;
InitAttrLine(kAttributeMsid, &os);
- os << kSdpDelimiterColon << stream_id << kSdpDelimiterSpace << track->id;
+ os << kSdpDelimiterColon << stream_id << kSdpDelimiterSpace << track.id;
AddLine(os.str(), message);
+ } else if (streams.size() > 1u) {
+ RTC_LOG(LS_WARNING)
+ << "Trying to serialize Unified Plan SDP with more than "
+ << "one track in a media section. Omitting 'a=msid'.";
}
}
@@ -1558,25 +1558,27 @@
AddSsrcLine(ssrc, kSsrcAttributeCname,
track->cname, message);
- // draft-alvestrand-mmusic-msid-00
- // a=ssrc:<ssrc-id> msid:identifier [appdata]
- // The appdata consists of the "id" attribute of a MediaStreamTrack,
- // which corresponds to the "id" attribute of StreamParams.
- const std::string& stream_id = track->sync_label;
- InitAttrLine(kAttributeSsrc, &os);
- os << kSdpDelimiterColon << ssrc << kSdpDelimiterSpace
- << kSsrcAttributeMsid << kSdpDelimiterColon << stream_id
- << kSdpDelimiterSpace << track->id;
- AddLine(os.str(), message);
+ if (msid_signaling & cricket::kMsidSignalingSsrcAttribute) {
+ // draft-alvestrand-mmusic-msid-00
+ // a=ssrc:<ssrc-id> msid:identifier [appdata]
+ // The appdata consists of the "id" attribute of a MediaStreamTrack,
+ // which corresponds to the "id" attribute of StreamParams.
+ const std::string& stream_id = track->sync_label;
+ InitAttrLine(kAttributeSsrc, &os);
+ os << kSdpDelimiterColon << ssrc << kSdpDelimiterSpace
+ << kSsrcAttributeMsid << kSdpDelimiterColon << stream_id
+ << kSdpDelimiterSpace << track->id;
+ AddLine(os.str(), message);
- // TODO(ronghuawu): Remove below code which is for backward
- // compatibility.
- // draft-alvestrand-rtcweb-mid-01
- // a=ssrc:<ssrc-id> mslabel:<value>
- // The label isn't yet defined.
- // a=ssrc:<ssrc-id> label:<value>
- AddSsrcLine(ssrc, kSsrcAttributeMslabel, track->sync_label, message);
- AddSsrcLine(ssrc, kSSrcAttributeLabel, track->id, message);
+ // TODO(ronghuawu): Remove below code which is for backward
+ // compatibility.
+ // draft-alvestrand-rtcweb-mid-01
+ // a=ssrc:<ssrc-id> mslabel:<value>
+ // The label isn't yet defined.
+ // a=ssrc:<ssrc-id> label:<value>
+ AddSsrcLine(ssrc, kSsrcAttributeMslabel, track->sync_label, message);
+ AddSsrcLine(ssrc, kSSrcAttributeLabel, track->id, message);
+ }
}
}
}
@@ -2294,6 +2296,7 @@
size_t* pos,
std::string* content_name,
bool* bundle_only,
+ int* msid_signaling,
TransportDescription* transport,
std::vector<JsepIceCandidate*>* candidates,
webrtc::SdpParseError* error) {
@@ -2313,8 +2316,8 @@
break;
}
if (!ParseContent(message, media_type, mline_index, protocol, payload_types,
- pos, content_name, bundle_only, media_desc, transport,
- candidates, error)) {
+ pos, content_name, bundle_only, msid_signaling, media_desc,
+ transport, candidates, error)) {
delete media_desc;
return nullptr;
}
@@ -2348,6 +2351,7 @@
RTC_DCHECK(desc != NULL);
std::string line;
int mline_index = -1;
+ int msid_signaling = 0;
// Zero or more media descriptions
// RFC 4566
@@ -2405,22 +2409,23 @@
std::unique_ptr<MediaContentDescription> content;
std::string content_name;
bool bundle_only = false;
+ int section_msid_signaling = 0;
if (HasAttribute(line, kMediaTypeVideo)) {
content.reset(ParseContentDescription<VideoContentDescription>(
message, cricket::MEDIA_TYPE_VIDEO, mline_index, protocol,
- payload_types, pos, &content_name, &bundle_only, &transport,
- candidates, error));
+ payload_types, pos, &content_name, &bundle_only,
+ §ion_msid_signaling, &transport, candidates, error));
} else if (HasAttribute(line, kMediaTypeAudio)) {
content.reset(ParseContentDescription<AudioContentDescription>(
message, cricket::MEDIA_TYPE_AUDIO, mline_index, protocol,
- payload_types, pos, &content_name, &bundle_only, &transport,
- candidates, error));
+ payload_types, pos, &content_name, &bundle_only,
+ §ion_msid_signaling, &transport, candidates, error));
} else if (HasAttribute(line, kMediaTypeData)) {
DataContentDescription* data_desc =
ParseContentDescription<DataContentDescription>(
message, cricket::MEDIA_TYPE_DATA, mline_index, protocol,
- payload_types, pos, &content_name, &bundle_only, &transport,
- candidates, error);
+ payload_types, pos, &content_name, &bundle_only,
+ §ion_msid_signaling, &transport, candidates, error);
content.reset(data_desc);
if (data_desc && IsDtlsSctp(protocol)) {
@@ -2442,6 +2447,8 @@
return false;
}
+ msid_signaling |= section_msid_signaling;
+
bool content_rejected = false;
// A port of 0 is not interpreted as a rejected m= section when it's
// used along with a=bundle-only.
@@ -2500,6 +2507,8 @@
}
}
+ desc->set_msid_signaling(msid_signaling);
+
size_t end_of_message = message.size();
if (mline_index == -1 && *pos != end_of_message) {
ParseFailed(message, *pos, "Expects m line.", error);
@@ -2665,6 +2674,7 @@
size_t* pos,
std::string* content_name,
bool* bundle_only,
+ int* msid_signaling,
MediaContentDescription* media_desc,
TransportDescription* transport,
std::vector<JsepIceCandidate*>* candidates,
@@ -2839,7 +2849,7 @@
return false;
}
} else if (HasAttribute(line, kAttributeSsrc)) {
- if (!ParseSsrcAttribute(line, &ssrc_infos, error)) {
+ if (!ParseSsrcAttribute(line, &ssrc_infos, msid_signaling, error)) {
return false;
}
} else if (HasAttribute(line, kAttributeCrypto)) {
@@ -2891,6 +2901,7 @@
if (!ParseMsidAttribute(line, &stream_id, &track_id, error)) {
return false;
}
+ *msid_signaling |= cricket::kMsidSignalingMediaSection;
}
} else {
// Only parse lines that we are interested of.
@@ -2963,7 +2974,9 @@
return true;
}
-bool ParseSsrcAttribute(const std::string& line, SsrcInfoVec* ssrc_infos,
+bool ParseSsrcAttribute(const std::string& line,
+ SsrcInfoVec* ssrc_infos,
+ int* msid_signaling,
SdpParseError* error) {
RTC_DCHECK(ssrc_infos != NULL);
// RFC 5576
@@ -3029,6 +3042,7 @@
if (fields.size() == 2) {
ssrc_info->track_id = fields[1];
}
+ *msid_signaling |= cricket::kMsidSignalingSsrcAttribute;
} else if (attribute == kSsrcAttributeMslabel) {
// draft-alvestrand-rtcweb-mid-01
// mslabel:<value>