Index: webrtc/api/webrtcsdp.cc |
diff --git a/webrtc/api/webrtcsdp.cc b/webrtc/api/webrtcsdp.cc |
index 5fd200a57652d4c0703e305a0c8c2e283a116ae5..502f8d802699f42255d3f1b7b261765ebd2646cc 100644 |
--- a/webrtc/api/webrtcsdp.cc |
+++ b/webrtc/api/webrtcsdp.cc |
@@ -84,7 +84,7 @@ namespace webrtc { |
// the form: |
// <type>=<value> |
// where <type> MUST be exactly one case-significant character. |
-static const int kLinePrefixLength = 2; // Lenght of <type>= |
+static const int kLinePrefixLength = 2; // Length of <type>= |
static const char kLineTypeVersion = 'v'; |
static const char kLineTypeOrigin = 'o'; |
static const char kLineTypeSessionName = 's'; |
@@ -104,6 +104,7 @@ static const char kLineTypeAttributes = 'a'; |
// Attributes |
static const char kAttributeGroup[] = "group"; |
static const char kAttributeMid[] = "mid"; |
+static const char kAttributeMsid[] = "msid"; |
static const char kAttributeRtcpMux[] = "rtcp-mux"; |
static const char kAttributeRtcpReducedSize[] = "rtcp-rsize"; |
static const char kAttributeSsrc[] = "ssrc"; |
@@ -211,15 +212,14 @@ const int kWildcardPayloadType = -1; |
struct SsrcInfo { |
SsrcInfo() |
- : msid_identifier(kDefaultMsid), |
- // TODO(ronghuawu): What should we do if the appdata doesn't appear? |
+ : stream_id(kDefaultMsid), |
+ // TODO(ronghuawu): What should we do if the track id doesn't appear? |
// Create random string (which will be used as track label later)? |
- msid_appdata(rtc::CreateRandomString(8)) { |
- } |
+ track_id(rtc::CreateRandomString(8)) {} |
uint32_t ssrc_id; |
std::string cname; |
- std::string msid_identifier; |
- std::string msid_appdata; |
+ std::string stream_id; |
+ std::string track_id; |
// For backward compatibility. |
// TODO(ronghuawu): Remove below 2 fields once all the clients support msid. |
@@ -235,12 +235,13 @@ static void BuildMediaDescription(const ContentInfo* content_info, |
const TransportInfo* transport_info, |
const MediaType media_type, |
const std::vector<Candidate>& candidates, |
+ bool unified_plan_sdp, |
std::string* message); |
static void BuildSctpContentAttributes(std::string* message, int sctp_port); |
-static void BuildRtpContentAttributes( |
- const MediaContentDescription* media_desc, |
- const MediaType media_type, |
- std::string* message); |
+static void BuildRtpContentAttributes(const MediaContentDescription* media_desc, |
+ const MediaType media_type, |
+ bool unified_plan_sdp, |
+ std::string* message); |
static void BuildRtpMap(const MediaContentDescription* media_desc, |
const MediaType media_type, |
std::string* message); |
@@ -317,6 +318,10 @@ static bool ParseFingerprintAttribute(const std::string& line, |
static bool ParseDtlsSetup(const std::string& line, |
cricket::ConnectionRole* role, |
SdpParseError* error); |
+static bool ParseMsidAttribute(const std::string& line, |
+ std::string* stream_id, |
+ std::string* track_id, |
+ SdpParseError* error); |
// Helper functions |
@@ -578,18 +583,15 @@ void CreateTracksFromSsrcInfos(const SsrcInfoVec& ssrc_infos, |
std::string sync_label; |
std::string track_id; |
- if (ssrc_info->msid_identifier == kDefaultMsid && |
- !ssrc_info->mslabel.empty()) { |
+ if (ssrc_info->stream_id == kDefaultMsid && !ssrc_info->mslabel.empty()) { |
// If there's no msid and there's mslabel, we consider this is a sdp from |
// a older version of client that doesn't support msid. |
// In that case, we use the mslabel and label to construct the track. |
sync_label = ssrc_info->mslabel; |
track_id = ssrc_info->label; |
} else { |
- sync_label = ssrc_info->msid_identifier; |
- // The appdata consists of the "id" attribute of a MediaStreamTrack, which |
- // is corresponding to the "id" attribute of StreamParams. |
- track_id = ssrc_info->msid_appdata; |
+ sync_label = ssrc_info->stream_id; |
+ track_id = ssrc_info->track_id; |
} |
if (sync_label.empty() || track_id.empty()) { |
ASSERT(false); |
@@ -775,7 +777,8 @@ static void GetCandidatesByMindex(const SessionDescriptionInterface& desci, |
} |
} |
-std::string SdpSerialize(const JsepSessionDescription& jdesc) { |
+std::string SdpSerialize(const JsepSessionDescription& jdesc, |
+ bool unified_plan_sdp) { |
const cricket::SessionDescription* desc = jdesc.description(); |
if (!desc) { |
return ""; |
@@ -846,10 +849,8 @@ std::string SdpSerialize(const JsepSessionDescription& jdesc) { |
static_cast<const MediaContentDescription*>(it->description); |
std::vector<Candidate> candidates; |
GetCandidatesByMindex(jdesc, ++mline_index, &candidates); |
- BuildMediaDescription(&*it, |
- desc->GetTransportInfoByName(it->name), |
- mdesc->type(), |
- candidates, |
+ BuildMediaDescription(&*it, desc->GetTransportInfoByName(it->name), |
+ mdesc->type(), candidates, unified_plan_sdp, |
&message); |
} |
return message; |
@@ -1155,6 +1156,7 @@ void BuildMediaDescription(const ContentInfo* content_info, |
const TransportInfo* transport_info, |
const MediaType media_type, |
const std::vector<Candidate>& candidates, |
+ bool unified_plan_sdp, |
std::string* message) { |
ASSERT(message != NULL); |
if (content_info == NULL || message == NULL) { |
@@ -1330,7 +1332,8 @@ void BuildMediaDescription(const ContentInfo* content_info, |
if (IsDtlsSctp(media_desc->protocol())) { |
BuildSctpContentAttributes(message, sctp_port); |
} else if (IsRtp(media_desc->protocol())) { |
- BuildRtpContentAttributes(media_desc, media_type, message); |
+ BuildRtpContentAttributes(media_desc, media_type, unified_plan_sdp, |
+ message); |
} |
} |
@@ -1347,10 +1350,11 @@ void BuildSctpContentAttributes(std::string* message, int sctp_port) { |
AddLine(os.str(), message); |
} |
-void BuildRtpContentAttributes( |
- const MediaContentDescription* media_desc, |
- const MediaType media_type, |
- std::string* 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, |
+ std::string* message) { |
std::ostringstream os; |
// RFC 5285 |
// a=extmap:<value>["/"<direction>] <URI> <extensionattributes> |
@@ -1382,6 +1386,22 @@ void BuildRtpContentAttributes( |
} |
AddLine(os.str(), message); |
+ // draft-ietf-mmusic-msid-11 |
+ // a=msid:<stream id> <track id> |
+ if (unified_plan_sdp && !media_desc->streams().empty()) { |
+ if (media_desc->streams().size() > 1u) { |
+ 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; |
+ std::ostringstream os; |
brucedawson
2016/02/19 19:23:39
Unnecessarily duplicated variable, also variable s
|
+ InitAttrLine(kAttributeMsid, &os); |
+ os << kSdpDelimiterColon << stream_id << kSdpDelimiterSpace << track->id; |
+ AddLine(os.str(), message); |
+ } |
+ } |
+ |
// RFC 5761 |
// a=rtcp-mux |
if (media_desc->rtcp_mux()) { |
@@ -1450,17 +1470,18 @@ void BuildRtpContentAttributes( |
// draft-alvestrand-mmusic-msid-00 |
// a=ssrc:<ssrc-id> msid:identifier [appdata] |
- // The appdata consists of the "id" attribute of a MediaStreamTrack, which |
- // is corresponding to the "name" attribute of StreamParams. |
- std::string appdata = track->id; |
+ // 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; |
std::ostringstream os; |
brucedawson
2016/02/19 19:23:39
Ditto (but not from this CL).
|
InitAttrLine(kAttributeSsrc, &os); |
os << kSdpDelimiterColon << ssrc << kSdpDelimiterSpace |
- << kSsrcAttributeMsid << kSdpDelimiterColon << track->sync_label |
- << kSdpDelimiterSpace << appdata; |
+ << kSsrcAttributeMsid << kSdpDelimiterColon << stream_id |
+ << kSdpDelimiterSpace << track->id; |
AddLine(os.str(), message); |
- // TODO(ronghuawu): Remove below code which is for backward compatibility. |
+ // 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. |
@@ -2022,6 +2043,29 @@ static bool ParseDtlsSetup(const std::string& line, |
return true; |
} |
+static bool ParseMsidAttribute(const std::string& line, |
+ std::string* stream_id, |
+ std::string* track_id, |
+ SdpParseError* error) { |
+ // draft-ietf-mmusic-msid-11 |
+ // a=msid:<stream id> <track id> |
+ // msid-value = msid-id [ SP msid-appdata ] |
+ // msid-id = 1*64token-char ; see RFC 4566 |
+ // msid-appdata = 1*64token-char ; see RFC 4566 |
+ std::string field1; |
+ if (!rtc::tokenize_first(line.substr(kLinePrefixLength), kSdpDelimiterSpace, |
+ &field1, track_id)) { |
+ const size_t expected_fields = 2; |
+ return ParseFailedExpectFieldNum(line, expected_fields, error); |
+ } |
+ |
+ // msid:<msid-id> |
+ if (!GetValue(field1, kAttributeMsid, stream_id, error)) { |
+ return false; |
+ } |
+ return true; |
+} |
+ |
// RFC 3551 |
// PT encoding media type clock rate channels |
// name (Hz) |
@@ -2446,6 +2490,8 @@ bool ParseContent(const std::string& message, |
SsrcGroupVec ssrc_groups; |
std::string maxptime_as_string; |
std::string ptime_as_string; |
+ std::string stream_id; |
+ std::string track_id; |
// Loop until the next m line |
while (!IsLineType(message, kLineTypeMedia, *pos)) { |
@@ -2605,6 +2651,10 @@ bool ParseContent(const std::string& message, |
} |
if (flag_value.compare(kValueConference) == 0) |
media_desc->set_conference_mode(true); |
+ } else if (HasAttribute(line, kAttributeMsid)) { |
+ if (!ParseMsidAttribute(line, &stream_id, &track_id, error)) { |
+ return false; |
+ } |
} |
} else { |
// Only parse lines that we are interested of. |
@@ -2613,6 +2663,17 @@ bool ParseContent(const std::string& message, |
} |
} |
+ // Found an msid attribute. |
+ // Setting the stream_id/track_id will cause only one StreamParams |
+ // to be created in CreateTracksFromSsrcInfos, containing all the SSRCs from |
+ // the m= section. |
+ if (!stream_id.empty() && !track_id.empty()) { |
+ for (SsrcInfo& ssrc_info : ssrc_infos) { |
+ ssrc_info.stream_id = stream_id; |
+ ssrc_info.track_id = track_id; |
+ } |
+ } |
+ |
// Create tracks from the |ssrc_infos|. |
CreateTracksFromSsrcInfos(ssrc_infos, &tracks); |
@@ -2632,9 +2693,8 @@ bool ParseContent(const std::string& message, |
} |
// Add the new tracks to the |media_desc|. |
- for (StreamParamsVec::iterator track = tracks.begin(); |
- track != tracks.end(); ++track) { |
- media_desc->AddStream(*track); |
+ for (StreamParams& track : tracks) { |
+ media_desc->AddStream(track); |
} |
if (media_type == cricket::MEDIA_TYPE_AUDIO) { |
@@ -2739,9 +2799,9 @@ bool ParseSsrcAttribute(const std::string& line, SsrcInfoVec* ssrc_infos, |
"Expected format \"msid:<identifier>[ <appdata>]\".", |
error); |
} |
- ssrc_info->msid_identifier = fields[0]; |
+ ssrc_info->stream_id = fields[0]; |
if (fields.size() == 2) { |
- ssrc_info->msid_appdata = fields[1]; |
+ ssrc_info->track_id = fields[1]; |
} |
} else if (attribute == kSsrcAttributeMslabel) { |
// draft-alvestrand-rtcweb-mid-01 |