Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(18)

Side by Side Diff: webrtc/api/webrtcsdp.cc

Issue 1688383002: Implementing unified plan encoding of msid. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Merging with master. Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « webrtc/api/webrtcsdp.h ('k') | webrtc/api/webrtcsdp_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2011 The WebRTC project authors. All Rights Reserved. 2 * Copyright 2011 The WebRTC project authors. All Rights Reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source 5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 10
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
77 } 77 }
78 78
79 namespace webrtc { 79 namespace webrtc {
80 80
81 // Line type 81 // Line type
82 // RFC 4566 82 // RFC 4566
83 // An SDP session description consists of a number of lines of text of 83 // An SDP session description consists of a number of lines of text of
84 // the form: 84 // the form:
85 // <type>=<value> 85 // <type>=<value>
86 // where <type> MUST be exactly one case-significant character. 86 // where <type> MUST be exactly one case-significant character.
87 static const int kLinePrefixLength = 2; // Lenght of <type>= 87 static const int kLinePrefixLength = 2; // Length of <type>=
88 static const char kLineTypeVersion = 'v'; 88 static const char kLineTypeVersion = 'v';
89 static const char kLineTypeOrigin = 'o'; 89 static const char kLineTypeOrigin = 'o';
90 static const char kLineTypeSessionName = 's'; 90 static const char kLineTypeSessionName = 's';
91 static const char kLineTypeSessionInfo = 'i'; 91 static const char kLineTypeSessionInfo = 'i';
92 static const char kLineTypeSessionUri = 'u'; 92 static const char kLineTypeSessionUri = 'u';
93 static const char kLineTypeSessionEmail = 'e'; 93 static const char kLineTypeSessionEmail = 'e';
94 static const char kLineTypeSessionPhone = 'p'; 94 static const char kLineTypeSessionPhone = 'p';
95 static const char kLineTypeSessionBandwidth = 'b'; 95 static const char kLineTypeSessionBandwidth = 'b';
96 static const char kLineTypeTiming = 't'; 96 static const char kLineTypeTiming = 't';
97 static const char kLineTypeRepeatTimes = 'r'; 97 static const char kLineTypeRepeatTimes = 'r';
98 static const char kLineTypeTimeZone = 'z'; 98 static const char kLineTypeTimeZone = 'z';
99 static const char kLineTypeEncryptionKey = 'k'; 99 static const char kLineTypeEncryptionKey = 'k';
100 static const char kLineTypeMedia = 'm'; 100 static const char kLineTypeMedia = 'm';
101 static const char kLineTypeConnection = 'c'; 101 static const char kLineTypeConnection = 'c';
102 static const char kLineTypeAttributes = 'a'; 102 static const char kLineTypeAttributes = 'a';
103 103
104 // Attributes 104 // Attributes
105 static const char kAttributeGroup[] = "group"; 105 static const char kAttributeGroup[] = "group";
106 static const char kAttributeMid[] = "mid"; 106 static const char kAttributeMid[] = "mid";
107 static const char kAttributeMsid[] = "msid";
107 static const char kAttributeRtcpMux[] = "rtcp-mux"; 108 static const char kAttributeRtcpMux[] = "rtcp-mux";
108 static const char kAttributeRtcpReducedSize[] = "rtcp-rsize"; 109 static const char kAttributeRtcpReducedSize[] = "rtcp-rsize";
109 static const char kAttributeSsrc[] = "ssrc"; 110 static const char kAttributeSsrc[] = "ssrc";
110 static const char kSsrcAttributeCname[] = "cname"; 111 static const char kSsrcAttributeCname[] = "cname";
111 static const char kAttributeExtmap[] = "extmap"; 112 static const char kAttributeExtmap[] = "extmap";
112 // draft-alvestrand-mmusic-msid-01 113 // draft-alvestrand-mmusic-msid-01
113 // a=msid-semantic: WMS 114 // a=msid-semantic: WMS
114 static const char kAttributeMsidSemantics[] = "msid-semantic"; 115 static const char kAttributeMsidSemantics[] = "msid-semantic";
115 static const char kMediaStreamSemantic[] = "WMS"; 116 static const char kMediaStreamSemantic[] = "WMS";
116 static const char kSsrcAttributeMsid[] = "msid"; 117 static const char kSsrcAttributeMsid[] = "msid";
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
204 static const int kIsacSwbDefaultRate = 56000; // From acm_common_defs.h 205 static const int kIsacSwbDefaultRate = 56000; // From acm_common_defs.h
205 206
206 static const char kDefaultSctpmapProtocol[] = "webrtc-datachannel"; 207 static const char kDefaultSctpmapProtocol[] = "webrtc-datachannel";
207 208
208 // RTP payload type is in the 0-127 range. Use -1 to indicate "all" payload 209 // RTP payload type is in the 0-127 range. Use -1 to indicate "all" payload
209 // types. 210 // types.
210 const int kWildcardPayloadType = -1; 211 const int kWildcardPayloadType = -1;
211 212
212 struct SsrcInfo { 213 struct SsrcInfo {
213 SsrcInfo() 214 SsrcInfo()
214 : msid_identifier(kDefaultMsid), 215 : stream_id(kDefaultMsid),
215 // TODO(ronghuawu): What should we do if the appdata doesn't appear? 216 // TODO(ronghuawu): What should we do if the track id doesn't appear?
216 // Create random string (which will be used as track label later)? 217 // Create random string (which will be used as track label later)?
217 msid_appdata(rtc::CreateRandomString(8)) { 218 track_id(rtc::CreateRandomString(8)) {}
218 }
219 uint32_t ssrc_id; 219 uint32_t ssrc_id;
220 std::string cname; 220 std::string cname;
221 std::string msid_identifier; 221 std::string stream_id;
222 std::string msid_appdata; 222 std::string track_id;
223 223
224 // For backward compatibility. 224 // For backward compatibility.
225 // TODO(ronghuawu): Remove below 2 fields once all the clients support msid. 225 // TODO(ronghuawu): Remove below 2 fields once all the clients support msid.
226 std::string label; 226 std::string label;
227 std::string mslabel; 227 std::string mslabel;
228 }; 228 };
229 typedef std::vector<SsrcInfo> SsrcInfoVec; 229 typedef std::vector<SsrcInfo> SsrcInfoVec;
230 typedef std::vector<SsrcGroup> SsrcGroupVec; 230 typedef std::vector<SsrcGroup> SsrcGroupVec;
231 231
232 template <class T> 232 template <class T>
233 static void AddFmtpLine(const T& codec, std::string* message); 233 static void AddFmtpLine(const T& codec, std::string* message);
234 static void BuildMediaDescription(const ContentInfo* content_info, 234 static void BuildMediaDescription(const ContentInfo* content_info,
235 const TransportInfo* transport_info, 235 const TransportInfo* transport_info,
236 const MediaType media_type, 236 const MediaType media_type,
237 const std::vector<Candidate>& candidates, 237 const std::vector<Candidate>& candidates,
238 bool unified_plan_sdp,
238 std::string* message); 239 std::string* message);
239 static void BuildSctpContentAttributes(std::string* message, int sctp_port); 240 static void BuildSctpContentAttributes(std::string* message, int sctp_port);
240 static void BuildRtpContentAttributes( 241 static void BuildRtpContentAttributes(const MediaContentDescription* media_desc,
241 const MediaContentDescription* media_desc, 242 const MediaType media_type,
242 const MediaType media_type, 243 bool unified_plan_sdp,
243 std::string* message); 244 std::string* message);
244 static void BuildRtpMap(const MediaContentDescription* media_desc, 245 static void BuildRtpMap(const MediaContentDescription* media_desc,
245 const MediaType media_type, 246 const MediaType media_type,
246 std::string* message); 247 std::string* message);
247 static void BuildCandidate(const std::vector<Candidate>& candidates, 248 static void BuildCandidate(const std::vector<Candidate>& candidates,
248 bool include_ufrag, 249 bool include_ufrag,
249 std::string* message); 250 std::string* message);
250 static void BuildIceOptions(const std::vector<std::string>& transport_options, 251 static void BuildIceOptions(const std::vector<std::string>& transport_options,
251 std::string* message); 252 std::string* message);
252 static bool IsRtp(const std::string& protocol); 253 static bool IsRtp(const std::string& protocol);
253 static bool IsDtlsSctp(const std::string& protocol); 254 static bool IsDtlsSctp(const std::string& protocol);
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
310 SdpParseError* error); 311 SdpParseError* error);
311 static bool ParseExtmap(const std::string& line, 312 static bool ParseExtmap(const std::string& line,
312 RtpHeaderExtension* extmap, 313 RtpHeaderExtension* extmap,
313 SdpParseError* error); 314 SdpParseError* error);
314 static bool ParseFingerprintAttribute(const std::string& line, 315 static bool ParseFingerprintAttribute(const std::string& line,
315 rtc::SSLFingerprint** fingerprint, 316 rtc::SSLFingerprint** fingerprint,
316 SdpParseError* error); 317 SdpParseError* error);
317 static bool ParseDtlsSetup(const std::string& line, 318 static bool ParseDtlsSetup(const std::string& line,
318 cricket::ConnectionRole* role, 319 cricket::ConnectionRole* role,
319 SdpParseError* error); 320 SdpParseError* error);
321 static bool ParseMsidAttribute(const std::string& line,
322 std::string* stream_id,
323 std::string* track_id,
324 SdpParseError* error);
320 325
321 // Helper functions 326 // Helper functions
322 327
323 // Below ParseFailed*** functions output the line that caused the parsing 328 // Below ParseFailed*** functions output the line that caused the parsing
324 // failure and the detailed reason (|description|) of the failure to |error|. 329 // failure and the detailed reason (|description|) of the failure to |error|.
325 // The functions always return false so that they can be used directly in the 330 // The functions always return false so that they can be used directly in the
326 // following way when error happens: 331 // following way when error happens:
327 // "return ParseFailed***(...);" 332 // "return ParseFailed***(...);"
328 333
329 // The line starting at |line_start| of |message| is the failing line. 334 // The line starting at |line_start| of |message| is the failing line.
(...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after
571 StreamParamsVec* tracks) { 576 StreamParamsVec* tracks) {
572 ASSERT(tracks != NULL); 577 ASSERT(tracks != NULL);
573 for (SsrcInfoVec::const_iterator ssrc_info = ssrc_infos.begin(); 578 for (SsrcInfoVec::const_iterator ssrc_info = ssrc_infos.begin();
574 ssrc_info != ssrc_infos.end(); ++ssrc_info) { 579 ssrc_info != ssrc_infos.end(); ++ssrc_info) {
575 if (ssrc_info->cname.empty()) { 580 if (ssrc_info->cname.empty()) {
576 continue; 581 continue;
577 } 582 }
578 583
579 std::string sync_label; 584 std::string sync_label;
580 std::string track_id; 585 std::string track_id;
581 if (ssrc_info->msid_identifier == kDefaultMsid && 586 if (ssrc_info->stream_id == kDefaultMsid && !ssrc_info->mslabel.empty()) {
582 !ssrc_info->mslabel.empty()) {
583 // If there's no msid and there's mslabel, we consider this is a sdp from 587 // If there's no msid and there's mslabel, we consider this is a sdp from
584 // a older version of client that doesn't support msid. 588 // a older version of client that doesn't support msid.
585 // In that case, we use the mslabel and label to construct the track. 589 // In that case, we use the mslabel and label to construct the track.
586 sync_label = ssrc_info->mslabel; 590 sync_label = ssrc_info->mslabel;
587 track_id = ssrc_info->label; 591 track_id = ssrc_info->label;
588 } else { 592 } else {
589 sync_label = ssrc_info->msid_identifier; 593 sync_label = ssrc_info->stream_id;
590 // The appdata consists of the "id" attribute of a MediaStreamTrack, which 594 track_id = ssrc_info->track_id;
591 // is corresponding to the "id" attribute of StreamParams.
592 track_id = ssrc_info->msid_appdata;
593 } 595 }
594 if (sync_label.empty() || track_id.empty()) { 596 if (sync_label.empty() || track_id.empty()) {
595 ASSERT(false); 597 ASSERT(false);
596 continue; 598 continue;
597 } 599 }
598 600
599 StreamParamsVec::iterator track = tracks->begin(); 601 StreamParamsVec::iterator track = tracks->begin();
600 for (; track != tracks->end(); ++track) { 602 for (; track != tracks->end(); ++track) {
601 if (track->id == track_id) { 603 if (track->id == track_id) {
602 break; 604 break;
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after
768 if (!candidates) { 770 if (!candidates) {
769 return; 771 return;
770 } 772 }
771 const IceCandidateCollection* cc = desci.candidates(mline_index); 773 const IceCandidateCollection* cc = desci.candidates(mline_index);
772 for (size_t i = 0; i < cc->count(); ++i) { 774 for (size_t i = 0; i < cc->count(); ++i) {
773 const IceCandidateInterface* candidate = cc->at(i); 775 const IceCandidateInterface* candidate = cc->at(i);
774 candidates->push_back(candidate->candidate()); 776 candidates->push_back(candidate->candidate());
775 } 777 }
776 } 778 }
777 779
778 std::string SdpSerialize(const JsepSessionDescription& jdesc) { 780 std::string SdpSerialize(const JsepSessionDescription& jdesc,
781 bool unified_plan_sdp) {
779 const cricket::SessionDescription* desc = jdesc.description(); 782 const cricket::SessionDescription* desc = jdesc.description();
780 if (!desc) { 783 if (!desc) {
781 return ""; 784 return "";
782 } 785 }
783 786
784 std::string message; 787 std::string message;
785 788
786 // Session Description. 789 // Session Description.
787 AddLine(kSessionVersion, &message); 790 AddLine(kSessionVersion, &message);
788 // Session Origin 791 // Session Origin
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
839 AddLine(os.str(), &message); 842 AddLine(os.str(), &message);
840 843
841 // Preserve the order of the media contents. 844 // Preserve the order of the media contents.
842 int mline_index = -1; 845 int mline_index = -1;
843 for (cricket::ContentInfos::const_iterator it = desc->contents().begin(); 846 for (cricket::ContentInfos::const_iterator it = desc->contents().begin();
844 it != desc->contents().end(); ++it) { 847 it != desc->contents().end(); ++it) {
845 const MediaContentDescription* mdesc = 848 const MediaContentDescription* mdesc =
846 static_cast<const MediaContentDescription*>(it->description); 849 static_cast<const MediaContentDescription*>(it->description);
847 std::vector<Candidate> candidates; 850 std::vector<Candidate> candidates;
848 GetCandidatesByMindex(jdesc, ++mline_index, &candidates); 851 GetCandidatesByMindex(jdesc, ++mline_index, &candidates);
849 BuildMediaDescription(&*it, 852 BuildMediaDescription(&*it, desc->GetTransportInfoByName(it->name),
850 desc->GetTransportInfoByName(it->name), 853 mdesc->type(), candidates, unified_plan_sdp,
851 mdesc->type(),
852 candidates,
853 &message); 854 &message);
854 } 855 }
855 return message; 856 return message;
856 } 857 }
857 858
858 // Serializes the passed in IceCandidateInterface to a SDP string. 859 // Serializes the passed in IceCandidateInterface to a SDP string.
859 // candidate - The candidate to be serialized. 860 // candidate - The candidate to be serialized.
860 std::string SdpSerializeCandidate( 861 std::string SdpSerializeCandidate(
861 const IceCandidateInterface& candidate) { 862 const IceCandidateInterface& candidate) {
862 std::string message; 863 std::string message;
(...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after
1148 } 1149 }
1149 1150
1150 *extmap = RtpHeaderExtension(uri, value); 1151 *extmap = RtpHeaderExtension(uri, value);
1151 return true; 1152 return true;
1152 } 1153 }
1153 1154
1154 void BuildMediaDescription(const ContentInfo* content_info, 1155 void BuildMediaDescription(const ContentInfo* content_info,
1155 const TransportInfo* transport_info, 1156 const TransportInfo* transport_info,
1156 const MediaType media_type, 1157 const MediaType media_type,
1157 const std::vector<Candidate>& candidates, 1158 const std::vector<Candidate>& candidates,
1159 bool unified_plan_sdp,
1158 std::string* message) { 1160 std::string* message) {
1159 ASSERT(message != NULL); 1161 ASSERT(message != NULL);
1160 if (content_info == NULL || message == NULL) { 1162 if (content_info == NULL || message == NULL) {
1161 return; 1163 return;
1162 } 1164 }
1163 // TODO: Rethink if we should use sprintfn instead of stringstream. 1165 // TODO: Rethink if we should use sprintfn instead of stringstream.
1164 // According to the style guide, streams should only be used for logging. 1166 // According to the style guide, streams should only be used for logging.
1165 // http://google-styleguide.googlecode.com/svn/ 1167 // http://google-styleguide.googlecode.com/svn/
1166 // trunk/cppguide.xml?showone=Streams#Streams 1168 // trunk/cppguide.xml?showone=Streams#Streams
1167 std::ostringstream os; 1169 std::ostringstream os;
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after
1323 // mid-attribute = "a=mid:" identification-tag 1325 // mid-attribute = "a=mid:" identification-tag
1324 // identification-tag = token 1326 // identification-tag = token
1325 // Use the content name as the mid identification-tag. 1327 // Use the content name as the mid identification-tag.
1326 InitAttrLine(kAttributeMid, &os); 1328 InitAttrLine(kAttributeMid, &os);
1327 os << kSdpDelimiterColon << content_info->name; 1329 os << kSdpDelimiterColon << content_info->name;
1328 AddLine(os.str(), message); 1330 AddLine(os.str(), message);
1329 1331
1330 if (IsDtlsSctp(media_desc->protocol())) { 1332 if (IsDtlsSctp(media_desc->protocol())) {
1331 BuildSctpContentAttributes(message, sctp_port); 1333 BuildSctpContentAttributes(message, sctp_port);
1332 } else if (IsRtp(media_desc->protocol())) { 1334 } else if (IsRtp(media_desc->protocol())) {
1333 BuildRtpContentAttributes(media_desc, media_type, message); 1335 BuildRtpContentAttributes(media_desc, media_type, unified_plan_sdp,
1336 message);
1334 } 1337 }
1335 } 1338 }
1336 1339
1337 void BuildSctpContentAttributes(std::string* message, int sctp_port) { 1340 void BuildSctpContentAttributes(std::string* message, int sctp_port) {
1338 // draft-ietf-mmusic-sctp-sdp-04 1341 // draft-ietf-mmusic-sctp-sdp-04
1339 // a=sctpmap:sctpmap-number protocol [streams] 1342 // a=sctpmap:sctpmap-number protocol [streams]
1340 // TODO(lally): switch this over to mmusic-sctp-sdp-12 (or later), with 1343 // TODO(lally): switch this over to mmusic-sctp-sdp-12 (or later), with
1341 // 'a=sctp-port:' 1344 // 'a=sctp-port:'
1342 std::ostringstream os; 1345 std::ostringstream os;
1343 InitAttrLine(kAttributeSctpmap, &os); 1346 InitAttrLine(kAttributeSctpmap, &os);
1344 os << kSdpDelimiterColon << sctp_port << kSdpDelimiterSpace 1347 os << kSdpDelimiterColon << sctp_port << kSdpDelimiterSpace
1345 << kDefaultSctpmapProtocol << kSdpDelimiterSpace 1348 << kDefaultSctpmapProtocol << kSdpDelimiterSpace
1346 << (cricket::kMaxSctpSid + 1); 1349 << (cricket::kMaxSctpSid + 1);
1347 AddLine(os.str(), message); 1350 AddLine(os.str(), message);
1348 } 1351 }
1349 1352
1350 void BuildRtpContentAttributes( 1353 // If unified_plan_sdp is true, will use "a=msid".
1351 const MediaContentDescription* media_desc, 1354 void BuildRtpContentAttributes(const MediaContentDescription* media_desc,
1352 const MediaType media_type, 1355 const MediaType media_type,
1353 std::string* message) { 1356 bool unified_plan_sdp,
1357 std::string* message) {
1354 std::ostringstream os; 1358 std::ostringstream os;
1355 // RFC 5285 1359 // RFC 5285
1356 // a=extmap:<value>["/"<direction>] <URI> <extensionattributes> 1360 // a=extmap:<value>["/"<direction>] <URI> <extensionattributes>
1357 // The definitions MUST be either all session level or all media level. This 1361 // The definitions MUST be either all session level or all media level. This
1358 // implementation uses all media level. 1362 // implementation uses all media level.
1359 for (size_t i = 0; i < media_desc->rtp_header_extensions().size(); ++i) { 1363 for (size_t i = 0; i < media_desc->rtp_header_extensions().size(); ++i) {
1360 InitAttrLine(kAttributeExtmap, &os); 1364 InitAttrLine(kAttributeExtmap, &os);
1361 os << kSdpDelimiterColon << media_desc->rtp_header_extensions()[i].id 1365 os << kSdpDelimiterColon << media_desc->rtp_header_extensions()[i].id
1362 << kSdpDelimiterSpace << media_desc->rtp_header_extensions()[i].uri; 1366 << kSdpDelimiterSpace << media_desc->rtp_header_extensions()[i].uri;
1363 AddLine(os.str(), message); 1367 AddLine(os.str(), message);
(...skipping 11 matching lines...) Expand all
1375 case cricket::MD_RECVONLY: 1379 case cricket::MD_RECVONLY:
1376 InitAttrLine(kAttributeRecvOnly, &os); 1380 InitAttrLine(kAttributeRecvOnly, &os);
1377 break; 1381 break;
1378 case cricket::MD_SENDRECV: 1382 case cricket::MD_SENDRECV:
1379 default: 1383 default:
1380 InitAttrLine(kAttributeSendRecv, &os); 1384 InitAttrLine(kAttributeSendRecv, &os);
1381 break; 1385 break;
1382 } 1386 }
1383 AddLine(os.str(), message); 1387 AddLine(os.str(), message);
1384 1388
1389 // draft-ietf-mmusic-msid-11
1390 // a=msid:<stream id> <track id>
1391 if (unified_plan_sdp && !media_desc->streams().empty()) {
1392 if (media_desc->streams().size() > 1u) {
1393 LOG(LS_WARNING) << "Trying to serialize unified plan SDP with more than "
1394 << "one track in a media section. Omitting 'a=msid'.";
1395 } else {
1396 auto track = media_desc->streams().begin();
1397 const std::string& stream_id = track->sync_label;
1398 std::ostringstream os;
brucedawson 2016/02/19 19:23:39 Unnecessarily duplicated variable, also variable s
1399 InitAttrLine(kAttributeMsid, &os);
1400 os << kSdpDelimiterColon << stream_id << kSdpDelimiterSpace << track->id;
1401 AddLine(os.str(), message);
1402 }
1403 }
1404
1385 // RFC 5761 1405 // RFC 5761
1386 // a=rtcp-mux 1406 // a=rtcp-mux
1387 if (media_desc->rtcp_mux()) { 1407 if (media_desc->rtcp_mux()) {
1388 InitAttrLine(kAttributeRtcpMux, &os); 1408 InitAttrLine(kAttributeRtcpMux, &os);
1389 AddLine(os.str(), message); 1409 AddLine(os.str(), message);
1390 } 1410 }
1391 1411
1392 // RFC 5506 1412 // RFC 5506
1393 // a=rtcp-rsize 1413 // a=rtcp-rsize
1394 if (media_desc->rtcp_reduced_size()) { 1414 if (media_desc->rtcp_reduced_size()) {
(...skipping 28 matching lines...) Expand all
1423 // if no track or media stream have been created. 1443 // if no track or media stream have been created.
1424 if (track->sync_label.empty()) continue; 1444 if (track->sync_label.empty()) continue;
1425 1445
1426 // Build the ssrc-group lines. 1446 // Build the ssrc-group lines.
1427 for (size_t i = 0; i < track->ssrc_groups.size(); ++i) { 1447 for (size_t i = 0; i < track->ssrc_groups.size(); ++i) {
1428 // RFC 5576 1448 // RFC 5576
1429 // a=ssrc-group:<semantics> <ssrc-id> ... 1449 // a=ssrc-group:<semantics> <ssrc-id> ...
1430 if (track->ssrc_groups[i].ssrcs.empty()) { 1450 if (track->ssrc_groups[i].ssrcs.empty()) {
1431 continue; 1451 continue;
1432 } 1452 }
1433 std::ostringstream os; 1453 std::ostringstream os;
brucedawson 2016/02/19 19:23:39 Ditto (but not from this CL).
1434 InitAttrLine(kAttributeSsrcGroup, &os); 1454 InitAttrLine(kAttributeSsrcGroup, &os);
1435 os << kSdpDelimiterColon << track->ssrc_groups[i].semantics; 1455 os << kSdpDelimiterColon << track->ssrc_groups[i].semantics;
1436 std::vector<uint32_t>::const_iterator ssrc = 1456 std::vector<uint32_t>::const_iterator ssrc =
1437 track->ssrc_groups[i].ssrcs.begin(); 1457 track->ssrc_groups[i].ssrcs.begin();
1438 for (; ssrc != track->ssrc_groups[i].ssrcs.end(); ++ssrc) { 1458 for (; ssrc != track->ssrc_groups[i].ssrcs.end(); ++ssrc) {
1439 os << kSdpDelimiterSpace << rtc::ToString<uint32_t>(*ssrc); 1459 os << kSdpDelimiterSpace << rtc::ToString<uint32_t>(*ssrc);
1440 } 1460 }
1441 AddLine(os.str(), message); 1461 AddLine(os.str(), message);
1442 } 1462 }
1443 // Build the ssrc lines for each ssrc. 1463 // Build the ssrc lines for each ssrc.
1444 for (size_t i = 0; i < track->ssrcs.size(); ++i) { 1464 for (size_t i = 0; i < track->ssrcs.size(); ++i) {
1445 uint32_t ssrc = track->ssrcs[i]; 1465 uint32_t ssrc = track->ssrcs[i];
1446 // RFC 5576 1466 // RFC 5576
1447 // a=ssrc:<ssrc-id> cname:<value> 1467 // a=ssrc:<ssrc-id> cname:<value>
1448 AddSsrcLine(ssrc, kSsrcAttributeCname, 1468 AddSsrcLine(ssrc, kSsrcAttributeCname,
1449 track->cname, message); 1469 track->cname, message);
1450 1470
1451 // draft-alvestrand-mmusic-msid-00 1471 // draft-alvestrand-mmusic-msid-00
1452 // a=ssrc:<ssrc-id> msid:identifier [appdata] 1472 // a=ssrc:<ssrc-id> msid:identifier [appdata]
1453 // The appdata consists of the "id" attribute of a MediaStreamTrack, which 1473 // The appdata consists of the "id" attribute of a MediaStreamTrack,
1454 // is corresponding to the "name" attribute of StreamParams. 1474 // which corresponds to the "id" attribute of StreamParams.
1455 std::string appdata = track->id; 1475 const std::string& stream_id = track->sync_label;
1456 std::ostringstream os; 1476 std::ostringstream os;
brucedawson 2016/02/19 19:23:39 Ditto (but not from this CL).
1457 InitAttrLine(kAttributeSsrc, &os); 1477 InitAttrLine(kAttributeSsrc, &os);
1458 os << kSdpDelimiterColon << ssrc << kSdpDelimiterSpace 1478 os << kSdpDelimiterColon << ssrc << kSdpDelimiterSpace
1459 << kSsrcAttributeMsid << kSdpDelimiterColon << track->sync_label 1479 << kSsrcAttributeMsid << kSdpDelimiterColon << stream_id
1460 << kSdpDelimiterSpace << appdata; 1480 << kSdpDelimiterSpace << track->id;
1461 AddLine(os.str(), message); 1481 AddLine(os.str(), message);
1462 1482
1463 // TODO(ronghuawu): Remove below code which is for backward compatibility. 1483 // TODO(ronghuawu): Remove below code which is for backward
1484 // compatibility.
1464 // draft-alvestrand-rtcweb-mid-01 1485 // draft-alvestrand-rtcweb-mid-01
1465 // a=ssrc:<ssrc-id> mslabel:<value> 1486 // a=ssrc:<ssrc-id> mslabel:<value>
1466 // The label isn't yet defined. 1487 // The label isn't yet defined.
1467 // a=ssrc:<ssrc-id> label:<value> 1488 // a=ssrc:<ssrc-id> label:<value>
1468 AddSsrcLine(ssrc, kSsrcAttributeMslabel, track->sync_label, message); 1489 AddSsrcLine(ssrc, kSsrcAttributeMslabel, track->sync_label, message);
1469 AddSsrcLine(ssrc, kSSrcAttributeLabel, track->id, message); 1490 AddSsrcLine(ssrc, kSSrcAttributeLabel, track->id, message);
1470 } 1491 }
1471 } 1492 }
1472 } 1493 }
1473 1494
(...skipping 541 matching lines...) Expand 10 before | Expand all | Expand 10 after
2015 if (fields.size() != expected_fields) { 2036 if (fields.size() != expected_fields) {
2016 return ParseFailedExpectFieldNum(line, expected_fields, error); 2037 return ParseFailedExpectFieldNum(line, expected_fields, error);
2017 } 2038 }
2018 std::string role_str = fields[1]; 2039 std::string role_str = fields[1];
2019 if (!cricket::StringToConnectionRole(role_str, role)) { 2040 if (!cricket::StringToConnectionRole(role_str, role)) {
2020 return ParseFailed(line, "Invalid attribute value.", error); 2041 return ParseFailed(line, "Invalid attribute value.", error);
2021 } 2042 }
2022 return true; 2043 return true;
2023 } 2044 }
2024 2045
2046 static bool ParseMsidAttribute(const std::string& line,
2047 std::string* stream_id,
2048 std::string* track_id,
2049 SdpParseError* error) {
2050 // draft-ietf-mmusic-msid-11
2051 // a=msid:<stream id> <track id>
2052 // msid-value = msid-id [ SP msid-appdata ]
2053 // msid-id = 1*64token-char ; see RFC 4566
2054 // msid-appdata = 1*64token-char ; see RFC 4566
2055 std::string field1;
2056 if (!rtc::tokenize_first(line.substr(kLinePrefixLength), kSdpDelimiterSpace,
2057 &field1, track_id)) {
2058 const size_t expected_fields = 2;
2059 return ParseFailedExpectFieldNum(line, expected_fields, error);
2060 }
2061
2062 // msid:<msid-id>
2063 if (!GetValue(field1, kAttributeMsid, stream_id, error)) {
2064 return false;
2065 }
2066 return true;
2067 }
2068
2025 // RFC 3551 2069 // RFC 3551
2026 // PT encoding media type clock rate channels 2070 // PT encoding media type clock rate channels
2027 // name (Hz) 2071 // name (Hz)
2028 // 0 PCMU A 8,000 1 2072 // 0 PCMU A 8,000 1
2029 // 1 reserved A 2073 // 1 reserved A
2030 // 2 reserved A 2074 // 2 reserved A
2031 // 3 GSM A 8,000 1 2075 // 3 GSM A 8,000 1
2032 // 4 G723 A 8,000 1 2076 // 4 G723 A 8,000 1
2033 // 5 DVI4 A 8,000 1 2077 // 5 DVI4 A 8,000 1
2034 // 6 DVI4 A 16,000 1 2078 // 6 DVI4 A 16,000 1
(...skipping 404 matching lines...) Expand 10 before | Expand all | Expand 10 after
2439 // The candidates before update the media level "ice-pwd" and "ice-ufrag". 2483 // The candidates before update the media level "ice-pwd" and "ice-ufrag".
2440 Candidates candidates_orig; 2484 Candidates candidates_orig;
2441 std::string line; 2485 std::string line;
2442 std::string mline_id; 2486 std::string mline_id;
2443 // Tracks created out of the ssrc attributes. 2487 // Tracks created out of the ssrc attributes.
2444 StreamParamsVec tracks; 2488 StreamParamsVec tracks;
2445 SsrcInfoVec ssrc_infos; 2489 SsrcInfoVec ssrc_infos;
2446 SsrcGroupVec ssrc_groups; 2490 SsrcGroupVec ssrc_groups;
2447 std::string maxptime_as_string; 2491 std::string maxptime_as_string;
2448 std::string ptime_as_string; 2492 std::string ptime_as_string;
2493 std::string stream_id;
2494 std::string track_id;
2449 2495
2450 // Loop until the next m line 2496 // Loop until the next m line
2451 while (!IsLineType(message, kLineTypeMedia, *pos)) { 2497 while (!IsLineType(message, kLineTypeMedia, *pos)) {
2452 if (!GetLine(message, pos, &line)) { 2498 if (!GetLine(message, pos, &line)) {
2453 if (*pos >= message.size()) { 2499 if (*pos >= message.size()) {
2454 break; // Done parsing 2500 break; // Done parsing
2455 } else { 2501 } else {
2456 return ParseFailed(message, *pos, "Invalid SDP line.", error); 2502 return ParseFailed(message, *pos, "Invalid SDP line.", error);
2457 } 2503 }
2458 } 2504 }
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
2598 } else if (HasAttribute(line, kAttributeXGoogleFlag)) { 2644 } else if (HasAttribute(line, kAttributeXGoogleFlag)) {
2599 // Experimental attribute. Conference mode activates more aggressive 2645 // Experimental attribute. Conference mode activates more aggressive
2600 // AEC and NS settings. 2646 // AEC and NS settings.
2601 // TODO: expose API to set these directly. 2647 // TODO: expose API to set these directly.
2602 std::string flag_value; 2648 std::string flag_value;
2603 if (!GetValue(line, kAttributeXGoogleFlag, &flag_value, error)) { 2649 if (!GetValue(line, kAttributeXGoogleFlag, &flag_value, error)) {
2604 return false; 2650 return false;
2605 } 2651 }
2606 if (flag_value.compare(kValueConference) == 0) 2652 if (flag_value.compare(kValueConference) == 0)
2607 media_desc->set_conference_mode(true); 2653 media_desc->set_conference_mode(true);
2654 } else if (HasAttribute(line, kAttributeMsid)) {
2655 if (!ParseMsidAttribute(line, &stream_id, &track_id, error)) {
2656 return false;
2657 }
2608 } 2658 }
2609 } else { 2659 } else {
2610 // Only parse lines that we are interested of. 2660 // Only parse lines that we are interested of.
2611 LOG(LS_INFO) << "Ignored line: " << line; 2661 LOG(LS_INFO) << "Ignored line: " << line;
2612 continue; 2662 continue;
2613 } 2663 }
2614 } 2664 }
2615 2665
2666 // Found an msid attribute.
2667 // Setting the stream_id/track_id will cause only one StreamParams
2668 // to be created in CreateTracksFromSsrcInfos, containing all the SSRCs from
2669 // the m= section.
2670 if (!stream_id.empty() && !track_id.empty()) {
2671 for (SsrcInfo& ssrc_info : ssrc_infos) {
2672 ssrc_info.stream_id = stream_id;
2673 ssrc_info.track_id = track_id;
2674 }
2675 }
2676
2616 // Create tracks from the |ssrc_infos|. 2677 // Create tracks from the |ssrc_infos|.
2617 CreateTracksFromSsrcInfos(ssrc_infos, &tracks); 2678 CreateTracksFromSsrcInfos(ssrc_infos, &tracks);
2618 2679
2619 // Add the ssrc group to the track. 2680 // Add the ssrc group to the track.
2620 for (SsrcGroupVec::iterator ssrc_group = ssrc_groups.begin(); 2681 for (SsrcGroupVec::iterator ssrc_group = ssrc_groups.begin();
2621 ssrc_group != ssrc_groups.end(); ++ssrc_group) { 2682 ssrc_group != ssrc_groups.end(); ++ssrc_group) {
2622 if (ssrc_group->ssrcs.empty()) { 2683 if (ssrc_group->ssrcs.empty()) {
2623 continue; 2684 continue;
2624 } 2685 }
2625 uint32_t ssrc = ssrc_group->ssrcs.front(); 2686 uint32_t ssrc = ssrc_group->ssrcs.front();
2626 for (StreamParamsVec::iterator track = tracks.begin(); 2687 for (StreamParamsVec::iterator track = tracks.begin();
2627 track != tracks.end(); ++track) { 2688 track != tracks.end(); ++track) {
2628 if (track->has_ssrc(ssrc)) { 2689 if (track->has_ssrc(ssrc)) {
2629 track->ssrc_groups.push_back(*ssrc_group); 2690 track->ssrc_groups.push_back(*ssrc_group);
2630 } 2691 }
2631 } 2692 }
2632 } 2693 }
2633 2694
2634 // Add the new tracks to the |media_desc|. 2695 // Add the new tracks to the |media_desc|.
2635 for (StreamParamsVec::iterator track = tracks.begin(); 2696 for (StreamParams& track : tracks) {
2636 track != tracks.end(); ++track) { 2697 media_desc->AddStream(track);
2637 media_desc->AddStream(*track);
2638 } 2698 }
2639 2699
2640 if (media_type == cricket::MEDIA_TYPE_AUDIO) { 2700 if (media_type == cricket::MEDIA_TYPE_AUDIO) {
2641 AudioContentDescription* audio_desc = 2701 AudioContentDescription* audio_desc =
2642 static_cast<AudioContentDescription*>(media_desc); 2702 static_cast<AudioContentDescription*>(media_desc);
2643 UpdateFromWildcardCodecs(audio_desc); 2703 UpdateFromWildcardCodecs(audio_desc);
2644 2704
2645 // Verify audio codec ensures that no audio codec has been populated with 2705 // Verify audio codec ensures that no audio codec has been populated with
2646 // only fmtp. 2706 // only fmtp.
2647 if (!VerifyAudioCodecs(audio_desc)) { 2707 if (!VerifyAudioCodecs(audio_desc)) {
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
2732 } else if (attribute == kSsrcAttributeMsid) { 2792 } else if (attribute == kSsrcAttributeMsid) {
2733 // draft-alvestrand-mmusic-msid-00 2793 // draft-alvestrand-mmusic-msid-00
2734 // "msid:" identifier [ " " appdata ] 2794 // "msid:" identifier [ " " appdata ]
2735 std::vector<std::string> fields; 2795 std::vector<std::string> fields;
2736 rtc::split(value, kSdpDelimiterSpace, &fields); 2796 rtc::split(value, kSdpDelimiterSpace, &fields);
2737 if (fields.size() < 1 || fields.size() > 2) { 2797 if (fields.size() < 1 || fields.size() > 2) {
2738 return ParseFailed(line, 2798 return ParseFailed(line,
2739 "Expected format \"msid:<identifier>[ <appdata>]\".", 2799 "Expected format \"msid:<identifier>[ <appdata>]\".",
2740 error); 2800 error);
2741 } 2801 }
2742 ssrc_info->msid_identifier = fields[0]; 2802 ssrc_info->stream_id = fields[0];
2743 if (fields.size() == 2) { 2803 if (fields.size() == 2) {
2744 ssrc_info->msid_appdata = fields[1]; 2804 ssrc_info->track_id = fields[1];
2745 } 2805 }
2746 } else if (attribute == kSsrcAttributeMslabel) { 2806 } else if (attribute == kSsrcAttributeMslabel) {
2747 // draft-alvestrand-rtcweb-mid-01 2807 // draft-alvestrand-rtcweb-mid-01
2748 // mslabel:<value> 2808 // mslabel:<value>
2749 ssrc_info->mslabel = value; 2809 ssrc_info->mslabel = value;
2750 } else if (attribute == kSSrcAttributeLabel) { 2810 } else if (attribute == kSSrcAttributeLabel) {
2751 // The label isn't defined. 2811 // The label isn't defined.
2752 // label:<value> 2812 // label:<value>
2753 ssrc_info->label = value; 2813 ssrc_info->label = value;
2754 } 2814 }
(...skipping 302 matching lines...) Expand 10 before | Expand all | Expand 10 after
3057 UpdateCodec<AudioContentDescription, cricket::AudioCodec>( 3117 UpdateCodec<AudioContentDescription, cricket::AudioCodec>(
3058 media_desc, payload_type, feedback_param); 3118 media_desc, payload_type, feedback_param);
3059 } else if (media_type == cricket::MEDIA_TYPE_VIDEO) { 3119 } else if (media_type == cricket::MEDIA_TYPE_VIDEO) {
3060 UpdateCodec<VideoContentDescription, cricket::VideoCodec>( 3120 UpdateCodec<VideoContentDescription, cricket::VideoCodec>(
3061 media_desc, payload_type, feedback_param); 3121 media_desc, payload_type, feedback_param);
3062 } 3122 }
3063 return true; 3123 return true;
3064 } 3124 }
3065 3125
3066 } // namespace webrtc 3126 } // namespace webrtc
OLDNEW
« no previous file with comments | « webrtc/api/webrtcsdp.h ('k') | webrtc/api/webrtcsdp_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698