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

Side by Side Diff: talk/app/webrtc/webrtcsdp.cc

Issue 1688383002: Implementing unified plan encoding of msid. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Fixing a comment. 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
OLDNEW
1 /* 1 /*
2 * libjingle 2 * libjingle
3 * Copyright 2011 Google Inc. 3 * Copyright 2011 Google Inc.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met: 6 * modification, are permitted provided that the following conditions are met:
7 * 7 *
8 * 1. Redistributions of source code must retain the above copyright notice, 8 * 1. Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer. 9 * this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright notice, 10 * 2. Redistributions in binary form must reproduce the above copyright notice,
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
94 } 94 }
95 95
96 namespace webrtc { 96 namespace webrtc {
97 97
98 // Line type 98 // Line type
99 // RFC 4566 99 // RFC 4566
100 // An SDP session description consists of a number of lines of text of 100 // An SDP session description consists of a number of lines of text of
101 // the form: 101 // the form:
102 // <type>=<value> 102 // <type>=<value>
103 // where <type> MUST be exactly one case-significant character. 103 // where <type> MUST be exactly one case-significant character.
104 static const int kLinePrefixLength = 2; // Lenght of <type>= 104 static const int kLinePrefixLength = 2; // Length of <type>=
105 static const char kLineTypeVersion = 'v'; 105 static const char kLineTypeVersion = 'v';
106 static const char kLineTypeOrigin = 'o'; 106 static const char kLineTypeOrigin = 'o';
107 static const char kLineTypeSessionName = 's'; 107 static const char kLineTypeSessionName = 's';
108 static const char kLineTypeSessionInfo = 'i'; 108 static const char kLineTypeSessionInfo = 'i';
109 static const char kLineTypeSessionUri = 'u'; 109 static const char kLineTypeSessionUri = 'u';
110 static const char kLineTypeSessionEmail = 'e'; 110 static const char kLineTypeSessionEmail = 'e';
111 static const char kLineTypeSessionPhone = 'p'; 111 static const char kLineTypeSessionPhone = 'p';
112 static const char kLineTypeSessionBandwidth = 'b'; 112 static const char kLineTypeSessionBandwidth = 'b';
113 static const char kLineTypeTiming = 't'; 113 static const char kLineTypeTiming = 't';
114 static const char kLineTypeRepeatTimes = 'r'; 114 static const char kLineTypeRepeatTimes = 'r';
115 static const char kLineTypeTimeZone = 'z'; 115 static const char kLineTypeTimeZone = 'z';
116 static const char kLineTypeEncryptionKey = 'k'; 116 static const char kLineTypeEncryptionKey = 'k';
117 static const char kLineTypeMedia = 'm'; 117 static const char kLineTypeMedia = 'm';
118 static const char kLineTypeConnection = 'c'; 118 static const char kLineTypeConnection = 'c';
119 static const char kLineTypeAttributes = 'a'; 119 static const char kLineTypeAttributes = 'a';
120 120
121 // Attributes 121 // Attributes
122 static const char kAttributeGroup[] = "group"; 122 static const char kAttributeGroup[] = "group";
123 static const char kAttributeMid[] = "mid"; 123 static const char kAttributeMid[] = "mid";
124 static const char kAttributeMsid[] = "msid";
124 static const char kAttributeRtcpMux[] = "rtcp-mux"; 125 static const char kAttributeRtcpMux[] = "rtcp-mux";
125 static const char kAttributeRtcpReducedSize[] = "rtcp-rsize"; 126 static const char kAttributeRtcpReducedSize[] = "rtcp-rsize";
126 static const char kAttributeSsrc[] = "ssrc"; 127 static const char kAttributeSsrc[] = "ssrc";
127 static const char kSsrcAttributeCname[] = "cname"; 128 static const char kSsrcAttributeCname[] = "cname";
128 static const char kAttributeExtmap[] = "extmap"; 129 static const char kAttributeExtmap[] = "extmap";
129 // draft-alvestrand-mmusic-msid-01 130 // draft-alvestrand-mmusic-msid-01
130 // a=msid-semantic: WMS 131 // a=msid-semantic: WMS
131 static const char kAttributeMsidSemantics[] = "msid-semantic"; 132 static const char kAttributeMsidSemantics[] = "msid-semantic";
132 static const char kMediaStreamSemantic[] = "WMS"; 133 static const char kMediaStreamSemantic[] = "WMS";
133 static const char kSsrcAttributeMsid[] = "msid"; 134 static const char kSsrcAttributeMsid[] = "msid";
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
245 }; 246 };
246 typedef std::vector<SsrcInfo> SsrcInfoVec; 247 typedef std::vector<SsrcInfo> SsrcInfoVec;
247 typedef std::vector<SsrcGroup> SsrcGroupVec; 248 typedef std::vector<SsrcGroup> SsrcGroupVec;
248 249
249 template <class T> 250 template <class T>
250 static void AddFmtpLine(const T& codec, std::string* message); 251 static void AddFmtpLine(const T& codec, std::string* message);
251 static void BuildMediaDescription(const ContentInfo* content_info, 252 static void BuildMediaDescription(const ContentInfo* content_info,
252 const TransportInfo* transport_info, 253 const TransportInfo* transport_info,
253 const MediaType media_type, 254 const MediaType media_type,
254 const std::vector<Candidate>& candidates, 255 const std::vector<Candidate>& candidates,
256 bool unified_plan_sdp,
255 std::string* message); 257 std::string* message);
256 static void BuildSctpContentAttributes(std::string* message, int sctp_port); 258 static void BuildSctpContentAttributes(std::string* message, int sctp_port);
257 static void BuildRtpContentAttributes( 259 static void BuildRtpContentAttributes(const MediaContentDescription* media_desc,
258 const MediaContentDescription* media_desc, 260 const MediaType media_type,
259 const MediaType media_type, 261 bool unified_plan_sdp,
260 std::string* message); 262 std::string* message);
261 static void BuildRtpMap(const MediaContentDescription* media_desc, 263 static void BuildRtpMap(const MediaContentDescription* media_desc,
262 const MediaType media_type, 264 const MediaType media_type,
263 std::string* message); 265 std::string* message);
264 static void BuildCandidate(const std::vector<Candidate>& candidates, 266 static void BuildCandidate(const std::vector<Candidate>& candidates,
265 bool include_ufrag, 267 bool include_ufrag,
266 std::string* message); 268 std::string* message);
267 static void BuildIceOptions(const std::vector<std::string>& transport_options, 269 static void BuildIceOptions(const std::vector<std::string>& transport_options,
268 std::string* message); 270 std::string* message);
269 static bool IsRtp(const std::string& protocol); 271 static bool IsRtp(const std::string& protocol);
270 static bool IsDtlsSctp(const std::string& protocol); 272 static bool IsDtlsSctp(const std::string& protocol);
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
327 SdpParseError* error); 329 SdpParseError* error);
328 static bool ParseExtmap(const std::string& line, 330 static bool ParseExtmap(const std::string& line,
329 RtpHeaderExtension* extmap, 331 RtpHeaderExtension* extmap,
330 SdpParseError* error); 332 SdpParseError* error);
331 static bool ParseFingerprintAttribute(const std::string& line, 333 static bool ParseFingerprintAttribute(const std::string& line,
332 rtc::SSLFingerprint** fingerprint, 334 rtc::SSLFingerprint** fingerprint,
333 SdpParseError* error); 335 SdpParseError* error);
334 static bool ParseDtlsSetup(const std::string& line, 336 static bool ParseDtlsSetup(const std::string& line,
335 cricket::ConnectionRole* role, 337 cricket::ConnectionRole* role,
336 SdpParseError* error); 338 SdpParseError* error);
339 static bool ParseMsidAttribute(const std::string& line,
340 std::string* stream_id,
341 std::string* track_id,
342 SdpParseError* error);
337 343
338 // Helper functions 344 // Helper functions
339 345
340 // Below ParseFailed*** functions output the line that caused the parsing 346 // Below ParseFailed*** functions output the line that caused the parsing
341 // failure and the detailed reason (|description|) of the failure to |error|. 347 // failure and the detailed reason (|description|) of the failure to |error|.
342 // The functions always return false so that they can be used directly in the 348 // The functions always return false so that they can be used directly in the
343 // following way when error happens: 349 // following way when error happens:
344 // "return ParseFailed***(...);" 350 // "return ParseFailed***(...);"
345 351
346 // The line starting at |line_start| of |message| is the failing line. 352 // The line starting at |line_start| of |message| is the failing line.
(...skipping 438 matching lines...) Expand 10 before | Expand all | Expand 10 after
785 if (!candidates) { 791 if (!candidates) {
786 return; 792 return;
787 } 793 }
788 const IceCandidateCollection* cc = desci.candidates(mline_index); 794 const IceCandidateCollection* cc = desci.candidates(mline_index);
789 for (size_t i = 0; i < cc->count(); ++i) { 795 for (size_t i = 0; i < cc->count(); ++i) {
790 const IceCandidateInterface* candidate = cc->at(i); 796 const IceCandidateInterface* candidate = cc->at(i);
791 candidates->push_back(candidate->candidate()); 797 candidates->push_back(candidate->candidate());
792 } 798 }
793 } 799 }
794 800
795 std::string SdpSerialize(const JsepSessionDescription& jdesc) { 801 std::string SdpSerialize(const JsepSessionDescription& jdesc,
802 bool unified_plan_sdp) {
796 const cricket::SessionDescription* desc = jdesc.description(); 803 const cricket::SessionDescription* desc = jdesc.description();
797 if (!desc) { 804 if (!desc) {
798 return ""; 805 return "";
799 } 806 }
800 807
801 std::string message; 808 std::string message;
802 809
803 // Session Description. 810 // Session Description.
804 AddLine(kSessionVersion, &message); 811 AddLine(kSessionVersion, &message);
805 // Session Origin 812 // Session Origin
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
856 AddLine(os.str(), &message); 863 AddLine(os.str(), &message);
857 864
858 // Preserve the order of the media contents. 865 // Preserve the order of the media contents.
859 int mline_index = -1; 866 int mline_index = -1;
860 for (cricket::ContentInfos::const_iterator it = desc->contents().begin(); 867 for (cricket::ContentInfos::const_iterator it = desc->contents().begin();
861 it != desc->contents().end(); ++it) { 868 it != desc->contents().end(); ++it) {
862 const MediaContentDescription* mdesc = 869 const MediaContentDescription* mdesc =
863 static_cast<const MediaContentDescription*>(it->description); 870 static_cast<const MediaContentDescription*>(it->description);
864 std::vector<Candidate> candidates; 871 std::vector<Candidate> candidates;
865 GetCandidatesByMindex(jdesc, ++mline_index, &candidates); 872 GetCandidatesByMindex(jdesc, ++mline_index, &candidates);
866 BuildMediaDescription(&*it, 873 BuildMediaDescription(&*it, desc->GetTransportInfoByName(it->name),
867 desc->GetTransportInfoByName(it->name), 874 mdesc->type(), candidates, unified_plan_sdp,
868 mdesc->type(),
869 candidates,
870 &message); 875 &message);
871 } 876 }
872 return message; 877 return message;
873 } 878 }
874 879
875 // Serializes the passed in IceCandidateInterface to a SDP string. 880 // Serializes the passed in IceCandidateInterface to a SDP string.
876 // candidate - The candidate to be serialized. 881 // candidate - The candidate to be serialized.
877 std::string SdpSerializeCandidate( 882 std::string SdpSerializeCandidate(
878 const IceCandidateInterface& candidate) { 883 const IceCandidateInterface& candidate) {
879 std::string message; 884 std::string message;
(...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after
1165 } 1170 }
1166 1171
1167 *extmap = RtpHeaderExtension(uri, value); 1172 *extmap = RtpHeaderExtension(uri, value);
1168 return true; 1173 return true;
1169 } 1174 }
1170 1175
1171 void BuildMediaDescription(const ContentInfo* content_info, 1176 void BuildMediaDescription(const ContentInfo* content_info,
1172 const TransportInfo* transport_info, 1177 const TransportInfo* transport_info,
1173 const MediaType media_type, 1178 const MediaType media_type,
1174 const std::vector<Candidate>& candidates, 1179 const std::vector<Candidate>& candidates,
1180 bool unified_plan_sdp,
1175 std::string* message) { 1181 std::string* message) {
1176 ASSERT(message != NULL); 1182 ASSERT(message != NULL);
1177 if (content_info == NULL || message == NULL) { 1183 if (content_info == NULL || message == NULL) {
1178 return; 1184 return;
1179 } 1185 }
1180 // TODO: Rethink if we should use sprintfn instead of stringstream. 1186 // TODO: Rethink if we should use sprintfn instead of stringstream.
1181 // According to the style guide, streams should only be used for logging. 1187 // According to the style guide, streams should only be used for logging.
1182 // http://google-styleguide.googlecode.com/svn/ 1188 // http://google-styleguide.googlecode.com/svn/
1183 // trunk/cppguide.xml?showone=Streams#Streams 1189 // trunk/cppguide.xml?showone=Streams#Streams
1184 std::ostringstream os; 1190 std::ostringstream os;
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after
1340 // mid-attribute = "a=mid:" identification-tag 1346 // mid-attribute = "a=mid:" identification-tag
1341 // identification-tag = token 1347 // identification-tag = token
1342 // Use the content name as the mid identification-tag. 1348 // Use the content name as the mid identification-tag.
1343 InitAttrLine(kAttributeMid, &os); 1349 InitAttrLine(kAttributeMid, &os);
1344 os << kSdpDelimiterColon << content_info->name; 1350 os << kSdpDelimiterColon << content_info->name;
1345 AddLine(os.str(), message); 1351 AddLine(os.str(), message);
1346 1352
1347 if (IsDtlsSctp(media_desc->protocol())) { 1353 if (IsDtlsSctp(media_desc->protocol())) {
1348 BuildSctpContentAttributes(message, sctp_port); 1354 BuildSctpContentAttributes(message, sctp_port);
1349 } else if (IsRtp(media_desc->protocol())) { 1355 } else if (IsRtp(media_desc->protocol())) {
1350 BuildRtpContentAttributes(media_desc, media_type, message); 1356 BuildRtpContentAttributes(media_desc, media_type, unified_plan_sdp,
1357 message);
1351 } 1358 }
1352 } 1359 }
1353 1360
1354 void BuildSctpContentAttributes(std::string* message, int sctp_port) { 1361 void BuildSctpContentAttributes(std::string* message, int sctp_port) {
1355 // draft-ietf-mmusic-sctp-sdp-04 1362 // draft-ietf-mmusic-sctp-sdp-04
1356 // a=sctpmap:sctpmap-number protocol [streams] 1363 // a=sctpmap:sctpmap-number protocol [streams]
1357 // TODO(lally): switch this over to mmusic-sctp-sdp-12 (or later), with 1364 // TODO(lally): switch this over to mmusic-sctp-sdp-12 (or later), with
1358 // 'a=sctp-port:' 1365 // 'a=sctp-port:'
1359 std::ostringstream os; 1366 std::ostringstream os;
1360 InitAttrLine(kAttributeSctpmap, &os); 1367 InitAttrLine(kAttributeSctpmap, &os);
1361 os << kSdpDelimiterColon << sctp_port << kSdpDelimiterSpace 1368 os << kSdpDelimiterColon << sctp_port << kSdpDelimiterSpace
1362 << kDefaultSctpmapProtocol << kSdpDelimiterSpace 1369 << kDefaultSctpmapProtocol << kSdpDelimiterSpace
1363 << (cricket::kMaxSctpSid + 1); 1370 << (cricket::kMaxSctpSid + 1);
1364 AddLine(os.str(), message); 1371 AddLine(os.str(), message);
1365 } 1372 }
1366 1373
1367 void BuildRtpContentAttributes( 1374 // If unified_plan_sdp is true, will use "a=msid".
1368 const MediaContentDescription* media_desc, 1375 void BuildRtpContentAttributes(const MediaContentDescription* media_desc,
1369 const MediaType media_type, 1376 const MediaType media_type,
1370 std::string* message) { 1377 bool unified_plan_sdp,
1378 std::string* message) {
1371 std::ostringstream os; 1379 std::ostringstream os;
1372 // RFC 5285 1380 // RFC 5285
1373 // a=extmap:<value>["/"<direction>] <URI> <extensionattributes> 1381 // a=extmap:<value>["/"<direction>] <URI> <extensionattributes>
1374 // The definitions MUST be either all session level or all media level. This 1382 // The definitions MUST be either all session level or all media level. This
1375 // implementation uses all media level. 1383 // implementation uses all media level.
1376 for (size_t i = 0; i < media_desc->rtp_header_extensions().size(); ++i) { 1384 for (size_t i = 0; i < media_desc->rtp_header_extensions().size(); ++i) {
1377 InitAttrLine(kAttributeExtmap, &os); 1385 InitAttrLine(kAttributeExtmap, &os);
1378 os << kSdpDelimiterColon << media_desc->rtp_header_extensions()[i].id 1386 os << kSdpDelimiterColon << media_desc->rtp_header_extensions()[i].id
1379 << kSdpDelimiterSpace << media_desc->rtp_header_extensions()[i].uri; 1387 << kSdpDelimiterSpace << media_desc->rtp_header_extensions()[i].uri;
1380 AddLine(os.str(), message); 1388 AddLine(os.str(), message);
(...skipping 11 matching lines...) Expand all
1392 case cricket::MD_RECVONLY: 1400 case cricket::MD_RECVONLY:
1393 InitAttrLine(kAttributeRecvOnly, &os); 1401 InitAttrLine(kAttributeRecvOnly, &os);
1394 break; 1402 break;
1395 case cricket::MD_SENDRECV: 1403 case cricket::MD_SENDRECV:
1396 default: 1404 default:
1397 InitAttrLine(kAttributeSendRecv, &os); 1405 InitAttrLine(kAttributeSendRecv, &os);
1398 break; 1406 break;
1399 } 1407 }
1400 AddLine(os.str(), message); 1408 AddLine(os.str(), message);
1401 1409
1410 // draft-ietf-mmusic-msid-11
1411 // a=msid:<stream id> <track id>
1412 if (unified_plan_sdp && !media_desc->streams().empty()) {
1413 if (media_desc->streams().size() > 1u) {
1414 LOG(LS_WARNING) << "Trying to serialize unified plan SDP with more than "
1415 << "one track in a media section. Omitting 'a=msid'.";
Taylor Brandstetter 2016/02/12 02:20:10 You may ask "why not throw an exception/return a w
pthatcher1 2016/02/12 03:54:35 Should we at least serialize the first media descr
Taylor Brandstetter 2016/02/12 20:44:57 We do.
1416 } else {
1417 auto track = media_desc->streams().begin();
1418 std::string appdata = track->id;
pthatcher1 2016/02/12 03:54:34 1. Why is this "appdata" instead of track_id? 2.
Taylor Brandstetter 2016/02/12 20:44:57 1. That's what the code below does for the SSRC li
1419 std::ostringstream os;
1420 InitAttrLine(kAttributeMsid, &os);
1421 os << kSdpDelimiterColon << track->sync_label << kSdpDelimiterSpace
1422 << appdata;
1423 AddLine(os.str(), message);
1424 }
1425 }
1426
1402 // RFC 5761 1427 // RFC 5761
1403 // a=rtcp-mux 1428 // a=rtcp-mux
1404 if (media_desc->rtcp_mux()) { 1429 if (media_desc->rtcp_mux()) {
1405 InitAttrLine(kAttributeRtcpMux, &os); 1430 InitAttrLine(kAttributeRtcpMux, &os);
1406 AddLine(os.str(), message); 1431 AddLine(os.str(), message);
1407 } 1432 }
1408 1433
1409 // RFC 5506 1434 // RFC 5506
1410 // a=rtcp-rsize 1435 // a=rtcp-rsize
1411 if (media_desc->rtcp_reduced_size()) { 1436 if (media_desc->rtcp_reduced_size()) {
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
1460 // Build the ssrc lines for each ssrc. 1485 // Build the ssrc lines for each ssrc.
1461 for (size_t i = 0; i < track->ssrcs.size(); ++i) { 1486 for (size_t i = 0; i < track->ssrcs.size(); ++i) {
1462 uint32_t ssrc = track->ssrcs[i]; 1487 uint32_t ssrc = track->ssrcs[i];
1463 // RFC 5576 1488 // RFC 5576
1464 // a=ssrc:<ssrc-id> cname:<value> 1489 // a=ssrc:<ssrc-id> cname:<value>
1465 AddSsrcLine(ssrc, kSsrcAttributeCname, 1490 AddSsrcLine(ssrc, kSsrcAttributeCname,
1466 track->cname, message); 1491 track->cname, message);
1467 1492
1468 // draft-alvestrand-mmusic-msid-00 1493 // draft-alvestrand-mmusic-msid-00
1469 // a=ssrc:<ssrc-id> msid:identifier [appdata] 1494 // a=ssrc:<ssrc-id> msid:identifier [appdata]
1470 // The appdata consists of the "id" attribute of a MediaStreamTrack, which 1495 // The appdata consists of the "id" attribute of a MediaStreamTrack,
1471 // is corresponding to the "name" attribute of StreamParams. 1496 // which corresponds to the "id" attribute of StreamParams.
1472 std::string appdata = track->id; 1497 std::string appdata = track->id;
1473 std::ostringstream os; 1498 std::ostringstream os;
1474 InitAttrLine(kAttributeSsrc, &os); 1499 InitAttrLine(kAttributeSsrc, &os);
1475 os << kSdpDelimiterColon << ssrc << kSdpDelimiterSpace 1500 os << kSdpDelimiterColon << ssrc << kSdpDelimiterSpace
1476 << kSsrcAttributeMsid << kSdpDelimiterColon << track->sync_label 1501 << kSsrcAttributeMsid << kSdpDelimiterColon << track->sync_label
1477 << kSdpDelimiterSpace << appdata; 1502 << kSdpDelimiterSpace << appdata;
1478 AddLine(os.str(), message); 1503 AddLine(os.str(), message);
1479 1504
1480 // TODO(ronghuawu): Remove below code which is for backward compatibility. 1505 // TODO(ronghuawu): Remove below code which is for backward
1506 // compatibility.
1481 // draft-alvestrand-rtcweb-mid-01 1507 // draft-alvestrand-rtcweb-mid-01
1482 // a=ssrc:<ssrc-id> mslabel:<value> 1508 // a=ssrc:<ssrc-id> mslabel:<value>
1483 // The label isn't yet defined. 1509 // The label isn't yet defined.
1484 // a=ssrc:<ssrc-id> label:<value> 1510 // a=ssrc:<ssrc-id> label:<value>
1485 AddSsrcLine(ssrc, kSsrcAttributeMslabel, track->sync_label, message); 1511 AddSsrcLine(ssrc, kSsrcAttributeMslabel, track->sync_label, message);
1486 AddSsrcLine(ssrc, kSSrcAttributeLabel, track->id, message); 1512 AddSsrcLine(ssrc, kSSrcAttributeLabel, track->id, message);
1487 } 1513 }
1488 } 1514 }
1489 } 1515 }
1490 1516
(...skipping 541 matching lines...) Expand 10 before | Expand all | Expand 10 after
2032 if (fields.size() != expected_fields) { 2058 if (fields.size() != expected_fields) {
2033 return ParseFailedExpectFieldNum(line, expected_fields, error); 2059 return ParseFailedExpectFieldNum(line, expected_fields, error);
2034 } 2060 }
2035 std::string role_str = fields[1]; 2061 std::string role_str = fields[1];
2036 if (!cricket::StringToConnectionRole(role_str, role)) { 2062 if (!cricket::StringToConnectionRole(role_str, role)) {
2037 return ParseFailed(line, "Invalid attribute value.", error); 2063 return ParseFailed(line, "Invalid attribute value.", error);
2038 } 2064 }
2039 return true; 2065 return true;
2040 } 2066 }
2041 2067
2068 static bool ParseMsidAttribute(const std::string& line,
2069 std::string* stream_id,
2070 std::string* track_id,
2071 SdpParseError* error) {
2072 // msid-value = msid-id [ SP msid-appdata ]
2073 // msid-id = 1*64token-char ; see RFC 4566
2074 // msid-appdata = 1*64token-char ; see RFC 4566
pthatcher1 2016/02/12 03:54:34 The parsing code and the serializing code don't se
Taylor Brandstetter 2016/02/12 20:44:56 Again, was just copying the way it was done elsewh
2075 std::string field1;
2076 if (!rtc::tokenize_first(line.substr(kLinePrefixLength), kSdpDelimiterSpace,
2077 &field1, track_id)) {
2078 const size_t expected_fields = 2;
2079 return ParseFailedExpectFieldNum(line, expected_fields, error);
2080 }
2081
2082 // msid:<msid-id>
2083 if (!GetValue(field1, kAttributeMsid, stream_id, error)) {
2084 return false;
2085 }
2086 return true;
2087 }
2088
2042 // RFC 3551 2089 // RFC 3551
2043 // PT encoding media type clock rate channels 2090 // PT encoding media type clock rate channels
2044 // name (Hz) 2091 // name (Hz)
2045 // 0 PCMU A 8,000 1 2092 // 0 PCMU A 8,000 1
2046 // 1 reserved A 2093 // 1 reserved A
2047 // 2 reserved A 2094 // 2 reserved A
2048 // 3 GSM A 8,000 1 2095 // 3 GSM A 8,000 1
2049 // 4 G723 A 8,000 1 2096 // 4 G723 A 8,000 1
2050 // 5 DVI4 A 8,000 1 2097 // 5 DVI4 A 8,000 1
2051 // 6 DVI4 A 16,000 1 2098 // 6 DVI4 A 16,000 1
(...skipping 404 matching lines...) Expand 10 before | Expand all | Expand 10 after
2456 // The candidates before update the media level "ice-pwd" and "ice-ufrag". 2503 // The candidates before update the media level "ice-pwd" and "ice-ufrag".
2457 Candidates candidates_orig; 2504 Candidates candidates_orig;
2458 std::string line; 2505 std::string line;
2459 std::string mline_id; 2506 std::string mline_id;
2460 // Tracks created out of the ssrc attributes. 2507 // Tracks created out of the ssrc attributes.
2461 StreamParamsVec tracks; 2508 StreamParamsVec tracks;
2462 SsrcInfoVec ssrc_infos; 2509 SsrcInfoVec ssrc_infos;
2463 SsrcGroupVec ssrc_groups; 2510 SsrcGroupVec ssrc_groups;
2464 std::string maxptime_as_string; 2511 std::string maxptime_as_string;
2465 std::string ptime_as_string; 2512 std::string ptime_as_string;
2513 std::string stream_id;
2514 std::string track_id;
2466 2515
2467 // Loop until the next m line 2516 // Loop until the next m line
2468 while (!IsLineType(message, kLineTypeMedia, *pos)) { 2517 while (!IsLineType(message, kLineTypeMedia, *pos)) {
2469 if (!GetLine(message, pos, &line)) { 2518 if (!GetLine(message, pos, &line)) {
2470 if (*pos >= message.size()) { 2519 if (*pos >= message.size()) {
2471 break; // Done parsing 2520 break; // Done parsing
2472 } else { 2521 } else {
2473 return ParseFailed(message, *pos, "Invalid SDP line.", error); 2522 return ParseFailed(message, *pos, "Invalid SDP line.", error);
2474 } 2523 }
2475 } 2524 }
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
2615 } else if (HasAttribute(line, kAttributeXGoogleFlag)) { 2664 } else if (HasAttribute(line, kAttributeXGoogleFlag)) {
2616 // Experimental attribute. Conference mode activates more aggressive 2665 // Experimental attribute. Conference mode activates more aggressive
2617 // AEC and NS settings. 2666 // AEC and NS settings.
2618 // TODO: expose API to set these directly. 2667 // TODO: expose API to set these directly.
2619 std::string flag_value; 2668 std::string flag_value;
2620 if (!GetValue(line, kAttributeXGoogleFlag, &flag_value, error)) { 2669 if (!GetValue(line, kAttributeXGoogleFlag, &flag_value, error)) {
2621 return false; 2670 return false;
2622 } 2671 }
2623 if (flag_value.compare(kValueConference) == 0) 2672 if (flag_value.compare(kValueConference) == 0)
2624 media_desc->set_conference_mode(true); 2673 media_desc->set_conference_mode(true);
2674 } else if (HasAttribute(line, kAttributeMsid)) {
2675 if (!ParseMsidAttribute(line, &stream_id, &track_id, error)) {
2676 return false;
2677 }
2625 } 2678 }
2626 } else { 2679 } else {
2627 // Only parse lines that we are interested of. 2680 // Only parse lines that we are interested of.
2628 LOG(LS_INFO) << "Ignored line: " << line; 2681 LOG(LS_INFO) << "Ignored line: " << line;
2629 continue; 2682 continue;
2630 } 2683 }
2631 } 2684 }
2632 2685
2686 // Found an msid attribute.
2687 // Setting the msid_identifier/msid_appdata will cause only one StreamParams
2688 // to be created, containing all the SSRCs from the m= section.
2689 if (!stream_id.empty() && !track_id.empty()) {
2690 for (SsrcInfo& ssrc_info : ssrc_infos) {
2691 ssrc_info.msid_identifier = stream_id;
2692 ssrc_info.msid_appdata = track_id;
pthatcher1 2016/02/12 03:54:34 Can we rename ssrc_info.msid_identifier and .msid_
Taylor Brandstetter 2016/02/12 20:44:56 Done.
2693 }
pthatcher1 2016/02/12 03:54:35 Do we need to merge all of the ssrc_infos into one
Taylor Brandstetter 2016/02/12 20:44:56 Yes, CreateTracksFromSsrcInfos does that. I meant
2694 }
2695
2633 // Create tracks from the |ssrc_infos|. 2696 // Create tracks from the |ssrc_infos|.
2634 CreateTracksFromSsrcInfos(ssrc_infos, &tracks); 2697 CreateTracksFromSsrcInfos(ssrc_infos, &tracks);
2635 2698
2636 // Add the ssrc group to the track. 2699 // Add the ssrc group to the track.
2637 for (SsrcGroupVec::iterator ssrc_group = ssrc_groups.begin(); 2700 for (SsrcGroupVec::iterator ssrc_group = ssrc_groups.begin();
2638 ssrc_group != ssrc_groups.end(); ++ssrc_group) { 2701 ssrc_group != ssrc_groups.end(); ++ssrc_group) {
2639 if (ssrc_group->ssrcs.empty()) { 2702 if (ssrc_group->ssrcs.empty()) {
2640 continue; 2703 continue;
2641 } 2704 }
2642 uint32_t ssrc = ssrc_group->ssrcs.front(); 2705 uint32_t ssrc = ssrc_group->ssrcs.front();
2643 for (StreamParamsVec::iterator track = tracks.begin(); 2706 for (StreamParamsVec::iterator track = tracks.begin();
2644 track != tracks.end(); ++track) { 2707 track != tracks.end(); ++track) {
2645 if (track->has_ssrc(ssrc)) { 2708 if (track->has_ssrc(ssrc)) {
2646 track->ssrc_groups.push_back(*ssrc_group); 2709 track->ssrc_groups.push_back(*ssrc_group);
2647 } 2710 }
2648 } 2711 }
2649 } 2712 }
2650 2713
2651 // Add the new tracks to the |media_desc|. 2714 // Add the new tracks to the |media_desc|.
2652 for (StreamParamsVec::iterator track = tracks.begin(); 2715 for (StreamParams& track : tracks) {
2653 track != tracks.end(); ++track) { 2716 media_desc->AddStream(track);
2654 media_desc->AddStream(*track);
2655 } 2717 }
2656 2718
2657 if (media_type == cricket::MEDIA_TYPE_AUDIO) { 2719 if (media_type == cricket::MEDIA_TYPE_AUDIO) {
2658 AudioContentDescription* audio_desc = 2720 AudioContentDescription* audio_desc =
2659 static_cast<AudioContentDescription*>(media_desc); 2721 static_cast<AudioContentDescription*>(media_desc);
2660 UpdateFromWildcardCodecs(audio_desc); 2722 UpdateFromWildcardCodecs(audio_desc);
2661 2723
2662 // Verify audio codec ensures that no audio codec has been populated with 2724 // Verify audio codec ensures that no audio codec has been populated with
2663 // only fmtp. 2725 // only fmtp.
2664 if (!VerifyAudioCodecs(audio_desc)) { 2726 if (!VerifyAudioCodecs(audio_desc)) {
(...skipping 409 matching lines...) Expand 10 before | Expand all | Expand 10 after
3074 UpdateCodec<AudioContentDescription, cricket::AudioCodec>( 3136 UpdateCodec<AudioContentDescription, cricket::AudioCodec>(
3075 media_desc, payload_type, feedback_param); 3137 media_desc, payload_type, feedback_param);
3076 } else if (media_type == cricket::MEDIA_TYPE_VIDEO) { 3138 } else if (media_type == cricket::MEDIA_TYPE_VIDEO) {
3077 UpdateCodec<VideoContentDescription, cricket::VideoCodec>( 3139 UpdateCodec<VideoContentDescription, cricket::VideoCodec>(
3078 media_desc, payload_type, feedback_param); 3140 media_desc, payload_type, feedback_param);
3079 } 3141 }
3080 return true; 3142 return true;
3081 } 3143 }
3082 3144
3083 } // namespace webrtc 3145 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698