Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 242 static void BuildRtpMap(const MediaContentDescription* media_desc, | 242 static void BuildRtpMap(const MediaContentDescription* media_desc, |
| 243 const MediaType media_type, | 243 const MediaType media_type, |
| 244 std::string* message); | 244 std::string* message); |
| 245 static void BuildCandidate(const std::vector<Candidate>& candidates, | 245 static void BuildCandidate(const std::vector<Candidate>& candidates, |
| 246 bool include_ufrag, | 246 bool include_ufrag, |
| 247 std::string* message); | 247 std::string* message); |
| 248 static void BuildIceOptions(const std::vector<std::string>& transport_options, | 248 static void BuildIceOptions(const std::vector<std::string>& transport_options, |
| 249 std::string* message); | 249 std::string* message); |
| 250 static bool IsRtp(const std::string& protocol); | 250 static bool IsRtp(const std::string& protocol); |
| 251 static bool IsDtlsSctp(const std::string& protocol); | 251 static bool IsDtlsSctp(const std::string& protocol); |
| 252 static bool ParseSessionDescription(const std::string& message, size_t* pos, | 252 static bool ParseSessionDescription(const std::string& message, |
| 253 size_t* pos, | |
| 253 std::string* session_id, | 254 std::string* session_id, |
| 254 std::string* session_version, | 255 std::string* session_version, |
| 255 TransportDescription* session_td, | 256 TransportDescription* session_td, |
| 256 RtpHeaderExtensions* session_extmaps, | 257 RtpHeaderExtensions* session_extmaps, |
| 258 rtc::SocketAddress* connection_addr, | |
| 257 cricket::SessionDescription* desc, | 259 cricket::SessionDescription* desc, |
| 258 SdpParseError* error); | 260 SdpParseError* error); |
| 259 static bool ParseGroupAttribute(const std::string& line, | 261 static bool ParseGroupAttribute(const std::string& line, |
| 260 cricket::SessionDescription* desc, | 262 cricket::SessionDescription* desc, |
| 261 SdpParseError* error); | 263 SdpParseError* error); |
| 262 static bool ParseMediaDescription( | 264 static bool ParseMediaDescription( |
| 263 const std::string& message, | 265 const std::string& message, |
| 264 const TransportDescription& session_td, | 266 const TransportDescription& session_td, |
| 265 const RtpHeaderExtensions& session_extmaps, | 267 const RtpHeaderExtensions& session_extmaps, |
| 266 size_t* pos, cricket::SessionDescription* desc, | 268 size_t* pos, |
| 269 const rtc::SocketAddress& session_connection_addr, | |
| 270 cricket::SessionDescription* desc, | |
| 267 std::vector<JsepIceCandidate*>* candidates, | 271 std::vector<JsepIceCandidate*>* candidates, |
| 268 SdpParseError* error); | 272 SdpParseError* error); |
| 269 static bool ParseContent(const std::string& message, | 273 static bool ParseContent(const std::string& message, |
| 270 const MediaType media_type, | 274 const MediaType media_type, |
| 271 int mline_index, | 275 int mline_index, |
| 272 const std::string& protocol, | 276 const std::string& protocol, |
| 273 const std::vector<int>& payload_types, | 277 const std::vector<int>& payload_types, |
| 274 size_t* pos, | 278 size_t* pos, |
| 275 std::string* content_name, | 279 std::string* content_name, |
| 276 bool* bundle_only, | 280 bool* bundle_only, |
| (...skipping 429 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 706 } else if (family == AF_INET6) { | 710 } else if (family == AF_INET6) { |
| 707 addr_type->assign(kConnectionIpv6Addrtype); | 711 addr_type->assign(kConnectionIpv6Addrtype); |
| 708 } | 712 } |
| 709 current_preference = preference; | 713 current_preference = preference; |
| 710 current_family = family; | 714 current_family = family; |
| 711 *port = it->address().PortAsString(); | 715 *port = it->address().PortAsString(); |
| 712 *ip = it->address().ipaddr().ToString(); | 716 *ip = it->address().ipaddr().ToString(); |
| 713 } | 717 } |
| 714 } | 718 } |
| 715 | 719 |
| 716 // Update |mline|'s default destination and append a c line after it. | 720 // Update |mline|'s default destination. |
| 717 static void UpdateMediaDefaultDestination( | 721 static void UpdateMediaDefaultDestination( |
| 718 const std::vector<Candidate>& candidates, | 722 const std::vector<Candidate>& candidates, |
| 719 const std::string& mline, | 723 const std::string& mline, |
| 720 std::string* message) { | 724 std::string* message) { |
| 721 std::string new_lines; | 725 std::string new_lines; |
| 722 AddLine(mline, &new_lines); | 726 AddLine(mline, &new_lines); |
| 723 // RFC 4566 | 727 // RFC 4566 |
| 724 // m=<media> <port> <proto> <fmt> ... | 728 // m=<media> <port> <proto> <fmt> ... |
| 725 std::vector<std::string> fields; | 729 std::vector<std::string> fields; |
| 726 rtc::split(mline, kSdpDelimiterSpace, &fields); | 730 rtc::split(mline, kSdpDelimiterSpace, &fields); |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 738 // destination for media. For streams based on RTP, this is done by | 742 // destination for media. For streams based on RTP, this is done by |
| 739 // placing the IP address and port of the RTP candidate into the c and m | 743 // placing the IP address and port of the RTP candidate into the c and m |
| 740 // lines, respectively. | 744 // lines, respectively. |
| 741 // Update the port in the m line. | 745 // Update the port in the m line. |
| 742 // If this is a m-line with port equal to 0, we don't change it. | 746 // If this is a m-line with port equal to 0, we don't change it. |
| 743 if (fields[1] != kMediaPortRejected) { | 747 if (fields[1] != kMediaPortRejected) { |
| 744 new_lines.replace(fields[0].size() + 1, | 748 new_lines.replace(fields[0].size() + 1, |
| 745 fields[1].size(), | 749 fields[1].size(), |
| 746 rtp_port); | 750 rtp_port); |
| 747 } | 751 } |
| 748 // Add the c line. | |
| 749 // RFC 4566 | |
| 750 // c=<nettype> <addrtype> <connection-address> | |
| 751 InitLine(kLineTypeConnection, kConnectionNettype, &os); | |
| 752 os << " " << addr_type << " " << rtp_ip; | |
| 753 AddLine(os.str(), &new_lines); | |
|
Taylor Brandstetter
2017/03/15 17:57:20
We shouldn't remove this "default destination" log
| |
| 754 message->append(new_lines); | 752 message->append(new_lines); |
| 755 } | 753 } |
| 756 | 754 |
| 757 // Gets "a=rtcp" line if found default RTCP candidate from |candidates|. | 755 // Gets "a=rtcp" line if found default RTCP candidate from |candidates|. |
| 758 static std::string GetRtcpLine(const std::vector<Candidate>& candidates) { | 756 static std::string GetRtcpLine(const std::vector<Candidate>& candidates) { |
| 759 std::string rtcp_line, rtcp_port, rtcp_ip, addr_type; | 757 std::string rtcp_line, rtcp_port, rtcp_ip, addr_type; |
| 760 GetDefaultDestination(candidates, ICE_CANDIDATE_COMPONENT_RTCP, | 758 GetDefaultDestination(candidates, ICE_CANDIDATE_COMPONENT_RTCP, |
| 761 &rtcp_port, &rtcp_ip, &addr_type); | 759 &rtcp_port, &rtcp_ip, &addr_type); |
| 762 // Found default RTCP candidate. | 760 // Found default RTCP candidate. |
| 763 // RFC 5245 | 761 // RFC 5245 |
| (...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 895 return message; | 893 return message; |
| 896 } | 894 } |
| 897 | 895 |
| 898 bool SdpDeserialize(const std::string& message, | 896 bool SdpDeserialize(const std::string& message, |
| 899 JsepSessionDescription* jdesc, | 897 JsepSessionDescription* jdesc, |
| 900 SdpParseError* error) { | 898 SdpParseError* error) { |
| 901 std::string session_id; | 899 std::string session_id; |
| 902 std::string session_version; | 900 std::string session_version; |
| 903 TransportDescription session_td("", ""); | 901 TransportDescription session_td("", ""); |
| 904 RtpHeaderExtensions session_extmaps; | 902 RtpHeaderExtensions session_extmaps; |
| 903 rtc::SocketAddress session_connection_addr; | |
| 905 cricket::SessionDescription* desc = new cricket::SessionDescription(); | 904 cricket::SessionDescription* desc = new cricket::SessionDescription(); |
| 906 std::vector<JsepIceCandidate*> candidates; | 905 std::vector<JsepIceCandidate*> candidates; |
| 907 size_t current_pos = 0; | 906 size_t current_pos = 0; |
| 908 | 907 |
| 909 // Session Description | 908 // Session Description |
| 910 if (!ParseSessionDescription(message, ¤t_pos, &session_id, | 909 if (!ParseSessionDescription(message, ¤t_pos, &session_id, |
| 911 &session_version, &session_td, &session_extmaps, | 910 &session_version, &session_td, &session_extmaps, |
| 912 desc, error)) { | 911 &session_connection_addr, desc, error)) { |
| 913 delete desc; | 912 delete desc; |
| 914 return false; | 913 return false; |
| 915 } | 914 } |
| 916 | 915 |
| 917 // Media Description | 916 // Media Description |
| 918 if (!ParseMediaDescription(message, session_td, session_extmaps, ¤t_pos, | 917 if (!ParseMediaDescription(message, session_td, session_extmaps, ¤t_pos, |
| 919 desc, &candidates, error)) { | 918 session_connection_addr, desc, &candidates, |
| 919 error)) { | |
| 920 delete desc; | 920 delete desc; |
| 921 for (std::vector<JsepIceCandidate*>::const_iterator | 921 for (std::vector<JsepIceCandidate*>::const_iterator |
| 922 it = candidates.begin(); it != candidates.end(); ++it) { | 922 it = candidates.begin(); it != candidates.end(); ++it) { |
| 923 delete *it; | 923 delete *it; |
| 924 } | 924 } |
| 925 return false; | 925 return false; |
| 926 } | 926 } |
| 927 | 927 |
| 928 jdesc->Initialize(desc, session_id, session_version); | 928 jdesc->Initialize(desc, session_id, session_version); |
| 929 | 929 |
| (...skipping 391 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1321 | 1321 |
| 1322 rtc::SSLFingerprint* fp = (transport_info) ? | 1322 rtc::SSLFingerprint* fp = (transport_info) ? |
| 1323 transport_info->description.identity_fingerprint.get() : NULL; | 1323 transport_info->description.identity_fingerprint.get() : NULL; |
| 1324 | 1324 |
| 1325 // Add the m and c lines. | 1325 // Add the m and c lines. |
| 1326 InitLine(kLineTypeMedia, type, &os); | 1326 InitLine(kLineTypeMedia, type, &os); |
| 1327 os << " " << port << " " << media_desc->protocol() << fmt; | 1327 os << " " << port << " " << media_desc->protocol() << fmt; |
| 1328 std::string mline = os.str(); | 1328 std::string mline = os.str(); |
| 1329 UpdateMediaDefaultDestination(candidates, mline, message); | 1329 UpdateMediaDefaultDestination(candidates, mline, message); |
| 1330 | 1330 |
| 1331 InitLine(kLineTypeConnection, kConnectionNettype, &os); | |
| 1332 if (media_desc->connection_addr().family() == AF_INET) { | |
| 1333 os << " " | |
| 1334 << "IP4" | |
| 1335 << " " << media_desc->connection_addr().ipaddr().ToString(); | |
| 1336 } else { | |
| 1337 os << " " | |
| 1338 << "IP6" | |
| 1339 << " " << media_desc->connection_addr().ipaddr().ToString(); | |
| 1340 } | |
| 1341 AddLine(os.str(), message); | |
| 1342 | |
| 1331 // RFC 4566 | 1343 // RFC 4566 |
| 1332 // b=AS:<bandwidth> | 1344 // b=AS:<bandwidth> |
| 1333 if (media_desc->bandwidth() >= 1000) { | 1345 if (media_desc->bandwidth() >= 1000) { |
| 1334 InitLine(kLineTypeSessionBandwidth, kApplicationSpecificMaximum, &os); | 1346 InitLine(kLineTypeSessionBandwidth, kApplicationSpecificMaximum, &os); |
| 1335 os << kSdpDelimiterColon << (media_desc->bandwidth() / 1000); | 1347 os << kSdpDelimiterColon << (media_desc->bandwidth() / 1000); |
| 1336 AddLine(os.str(), message); | 1348 AddLine(os.str(), message); |
| 1337 } | 1349 } |
| 1338 | 1350 |
| 1339 // Add the a=bundle-only line. | 1351 // Add the a=bundle-only line. |
| 1340 if (content_info->bundle_only) { | 1352 if (content_info->bundle_only) { |
| (...skipping 552 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1893 bool IsRtp(const std::string& protocol) { | 1905 bool IsRtp(const std::string& protocol) { |
| 1894 return protocol.empty() || | 1906 return protocol.empty() || |
| 1895 (protocol.find(cricket::kMediaProtocolRtpPrefix) != std::string::npos); | 1907 (protocol.find(cricket::kMediaProtocolRtpPrefix) != std::string::npos); |
| 1896 } | 1908 } |
| 1897 | 1909 |
| 1898 bool IsDtlsSctp(const std::string& protocol) { | 1910 bool IsDtlsSctp(const std::string& protocol) { |
| 1899 // This intentionally excludes "SCTP" and "SCTP/DTLS". | 1911 // This intentionally excludes "SCTP" and "SCTP/DTLS". |
| 1900 return protocol.find(cricket::kMediaProtocolDtlsSctp) != std::string::npos; | 1912 return protocol.find(cricket::kMediaProtocolDtlsSctp) != std::string::npos; |
| 1901 } | 1913 } |
| 1902 | 1914 |
| 1903 bool ParseSessionDescription(const std::string& message, size_t* pos, | 1915 bool ParseConnectionData(const std::string& line, |
| 1916 rtc::SocketAddress* addr, | |
| 1917 SdpParseError* error) { | |
| 1918 // Parse the line from left to right. | |
| 1919 std::string token; | |
| 1920 std::string rightpart; | |
| 1921 // RFC 4566 | |
| 1922 // c=<nettype> <addrtype> <connection-address> | |
| 1923 // Skip the "c=" | |
| 1924 if (!rtc::tokenize_first(line, kSdpDelimiterEqual, &token, &rightpart)) { | |
| 1925 return ParseFailed(line, "Failed to parse the network type.", error); | |
| 1926 } | |
| 1927 | |
| 1928 // Extract and verify the <nettype> | |
| 1929 if (!rtc::tokenize_first(rightpart, kSdpDelimiterSpace, &token, &rightpart) || | |
| 1930 token != kConnectionNettype) { | |
| 1931 return ParseFailed(line, | |
| 1932 "Failed to parse the connection data. The network type " | |
| 1933 "is not currently supported.", | |
| 1934 error); | |
| 1935 } | |
| 1936 | |
| 1937 // Extract the "<addrtype>" and "<connection-address>". | |
| 1938 if (!rtc::tokenize_first(rightpart, kSdpDelimiterSpace, &token, &rightpart)) { | |
| 1939 return ParseFailed(line, "Failed to parse the address type.", error); | |
| 1940 } | |
| 1941 | |
| 1942 // The rightpart part should be the IP address without the slash which is used | |
| 1943 // for multicast. | |
| 1944 if (rightpart.find('/') != std::string::npos) { | |
| 1945 return ParseFailed(line, | |
| 1946 "Failed to parse the connection data. Multicast is not " | |
| 1947 "currently supported.", | |
| 1948 error); | |
| 1949 } | |
| 1950 addr->SetIP(rightpart); | |
| 1951 | |
| 1952 // Verify that the addrtype matches the type of the parsed address. | |
| 1953 if ((addr->family() == AF_INET && token != "IP4") || | |
| 1954 (addr->family() == AF_INET6 && token != "IP6")) { | |
| 1955 addr->Clear(); | |
| 1956 return ParseFailed( | |
| 1957 line, | |
| 1958 "Failed to parse the connection data. The address type is mismatching.", | |
| 1959 error); | |
| 1960 } | |
| 1961 return true; | |
| 1962 } | |
| 1963 | |
| 1964 bool ParseSessionDescription(const std::string& message, | |
| 1965 size_t* pos, | |
| 1904 std::string* session_id, | 1966 std::string* session_id, |
| 1905 std::string* session_version, | 1967 std::string* session_version, |
| 1906 TransportDescription* session_td, | 1968 TransportDescription* session_td, |
| 1907 RtpHeaderExtensions* session_extmaps, | 1969 RtpHeaderExtensions* session_extmaps, |
| 1970 rtc::SocketAddress* connection_addr, | |
| 1908 cricket::SessionDescription* desc, | 1971 cricket::SessionDescription* desc, |
| 1909 SdpParseError* error) { | 1972 SdpParseError* error) { |
| 1910 std::string line; | 1973 std::string line; |
| 1911 | 1974 |
| 1912 desc->set_msid_supported(false); | 1975 desc->set_msid_supported(false); |
| 1913 | 1976 |
| 1914 // RFC 4566 | 1977 // RFC 4566 |
| 1915 // v= (protocol version) | 1978 // v= (protocol version) |
| 1916 if (!GetLineWithType(message, pos, &line, kLineTypeVersion)) { | 1979 if (!GetLineWithType(message, pos, &line, kLineTypeVersion)) { |
| 1917 return ParseFailedExpectLine(message, *pos, kLineTypeVersion, | 1980 return ParseFailedExpectLine(message, *pos, kLineTypeVersion, |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1955 // e=* (email address) | 2018 // e=* (email address) |
| 1956 GetLineWithType(message, pos, &line, kLineTypeSessionEmail); | 2019 GetLineWithType(message, pos, &line, kLineTypeSessionEmail); |
| 1957 | 2020 |
| 1958 // RFC 4566 | 2021 // RFC 4566 |
| 1959 // p=* (phone number) | 2022 // p=* (phone number) |
| 1960 GetLineWithType(message, pos, &line, kLineTypeSessionPhone); | 2023 GetLineWithType(message, pos, &line, kLineTypeSessionPhone); |
| 1961 | 2024 |
| 1962 // RFC 4566 | 2025 // RFC 4566 |
| 1963 // c=* (connection information -- not required if included in | 2026 // c=* (connection information -- not required if included in |
| 1964 // all media) | 2027 // all media) |
| 1965 GetLineWithType(message, pos, &line, kLineTypeConnection); | 2028 if (GetLineWithType(message, pos, &line, kLineTypeConnection)) { |
| 2029 if (!ParseConnectionData(line, connection_addr, error)) { | |
| 2030 return false; | |
| 2031 } | |
| 2032 } | |
| 1966 | 2033 |
| 1967 // RFC 4566 | 2034 // RFC 4566 |
| 1968 // b=* (zero or more bandwidth information lines) | 2035 // b=* (zero or more bandwidth information lines) |
| 1969 while (GetLineWithType(message, pos, &line, kLineTypeSessionBandwidth)) { | 2036 while (GetLineWithType(message, pos, &line, kLineTypeSessionBandwidth)) { |
| 1970 // By pass zero or more b lines. | 2037 // By pass zero or more b lines. |
| 1971 } | 2038 } |
| 1972 | 2039 |
| 1973 // RFC 4566 | 2040 // RFC 4566 |
| 1974 // One or more time descriptions ("t=" and "r=" lines; see below) | 2041 // One or more time descriptions ("t=" and "r=" lines; see below) |
| 1975 // t= (time the session is active) | 2042 // t= (time the session is active) |
| (...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2259 *content_name = cricket::CN_DATA; | 2326 *content_name = cricket::CN_DATA; |
| 2260 break; | 2327 break; |
| 2261 default: | 2328 default: |
| 2262 RTC_NOTREACHED(); | 2329 RTC_NOTREACHED(); |
| 2263 break; | 2330 break; |
| 2264 } | 2331 } |
| 2265 if (!ParseContent(message, media_type, mline_index, protocol, payload_types, | 2332 if (!ParseContent(message, media_type, mline_index, protocol, payload_types, |
| 2266 pos, content_name, bundle_only, media_desc, transport, | 2333 pos, content_name, bundle_only, media_desc, transport, |
| 2267 candidates, error)) { | 2334 candidates, error)) { |
| 2268 delete media_desc; | 2335 delete media_desc; |
| 2269 return NULL; | 2336 return nullptr; |
| 2270 } | 2337 } |
| 2271 // Sort the codecs according to the m-line fmt list. | 2338 // Sort the codecs according to the m-line fmt list. |
| 2272 std::unordered_map<int, int> payload_type_preferences; | 2339 std::unordered_map<int, int> payload_type_preferences; |
| 2273 // "size + 1" so that the lowest preference payload type has a preference of | 2340 // "size + 1" so that the lowest preference payload type has a preference of |
| 2274 // 1, which is greater than the default (0) for payload types not in the fmt | 2341 // 1, which is greater than the default (0) for payload types not in the fmt |
| 2275 // list. | 2342 // list. |
| 2276 int preference = static_cast<int>(payload_types.size() + 1); | 2343 int preference = static_cast<int>(payload_types.size() + 1); |
| 2277 for (int pt : payload_types) { | 2344 for (int pt : payload_types) { |
| 2278 payload_type_preferences[pt] = preference--; | 2345 payload_type_preferences[pt] = preference--; |
| 2279 } | 2346 } |
| 2280 std::vector<typename C::CodecType> codecs = media_desc->codecs(); | 2347 std::vector<typename C::CodecType> codecs = media_desc->codecs(); |
| 2281 std::sort(codecs.begin(), codecs.end(), [&payload_type_preferences]( | 2348 std::sort(codecs.begin(), codecs.end(), [&payload_type_preferences]( |
| 2282 const typename C::CodecType& a, | 2349 const typename C::CodecType& a, |
| 2283 const typename C::CodecType& b) { | 2350 const typename C::CodecType& b) { |
| 2284 return payload_type_preferences[a.id] > payload_type_preferences[b.id]; | 2351 return payload_type_preferences[a.id] > payload_type_preferences[b.id]; |
| 2285 }); | 2352 }); |
| 2286 media_desc->set_codecs(codecs); | 2353 media_desc->set_codecs(codecs); |
| 2287 return media_desc; | 2354 return media_desc; |
| 2288 } | 2355 } |
| 2289 | 2356 |
| 2290 bool ParseMediaDescription(const std::string& message, | 2357 bool ParseMediaDescription(const std::string& message, |
| 2291 const TransportDescription& session_td, | 2358 const TransportDescription& session_td, |
| 2292 const RtpHeaderExtensions& session_extmaps, | 2359 const RtpHeaderExtensions& session_extmaps, |
| 2293 size_t* pos, | 2360 size_t* pos, |
| 2361 const rtc::SocketAddress& session_connection_addr, | |
| 2294 cricket::SessionDescription* desc, | 2362 cricket::SessionDescription* desc, |
| 2295 std::vector<JsepIceCandidate*>* candidates, | 2363 std::vector<JsepIceCandidate*>* candidates, |
| 2296 SdpParseError* error) { | 2364 SdpParseError* error) { |
| 2297 RTC_DCHECK(desc != NULL); | 2365 RTC_DCHECK(desc != NULL); |
| 2298 std::string line; | 2366 std::string line; |
| 2299 int mline_index = -1; | 2367 int mline_index = -1; |
| 2300 | 2368 |
| 2301 // Zero or more media descriptions | 2369 // Zero or more media descriptions |
| 2302 // RFC 4566 | 2370 // RFC 4566 |
| 2303 // m=<media> <port> <proto> <fmt> | 2371 // m=<media> <port> <proto> <fmt> |
| 2304 while (GetLineWithType(message, pos, &line, kLineTypeMedia)) { | 2372 while (GetLineWithType(message, pos, &line, kLineTypeMedia)) { |
| 2305 ++mline_index; | 2373 ++mline_index; |
| 2306 | 2374 |
| 2307 std::vector<std::string> fields; | 2375 std::vector<std::string> fields; |
| 2308 rtc::split(line.substr(kLinePrefixLength), | 2376 rtc::split(line.substr(kLinePrefixLength), |
| 2309 kSdpDelimiterSpace, &fields); | 2377 kSdpDelimiterSpace, &fields); |
| 2310 | 2378 |
| 2311 const size_t expected_min_fields = 4; | 2379 const size_t expected_min_fields = 4; |
| 2312 if (fields.size() < expected_min_fields) { | 2380 if (fields.size() < expected_min_fields) { |
| 2313 return ParseFailedExpectMinFieldNum(line, expected_min_fields, error); | 2381 return ParseFailedExpectMinFieldNum(line, expected_min_fields, error); |
| 2314 } | 2382 } |
| 2315 bool port_rejected = false; | 2383 bool port_rejected = false; |
| 2316 // RFC 3264 | 2384 // RFC 3264 |
| 2317 // To reject an offered stream, the port number in the corresponding stream | 2385 // To reject an offered stream, the port number in the corresponding stream |
| 2318 // in the answer MUST be set to zero. | 2386 // in the answer MUST be set to zero. |
| 2319 if (fields[1] == kMediaPortRejected) { | 2387 if (fields[1] == kMediaPortRejected) { |
|
Taylor Brandstetter
2017/03/15 17:57:20
Something I just realized: the port on the m= line
Zhi Huang
2017/03/16 19:47:26
Done.
| |
| 2320 port_rejected = true; | 2388 port_rejected = true; |
| 2321 } | 2389 } |
| 2322 | 2390 |
| 2323 std::string protocol = fields[2]; | 2391 std::string protocol = fields[2]; |
| 2324 | 2392 |
| 2325 // <fmt> | 2393 // <fmt> |
| 2326 std::vector<int> payload_types; | 2394 std::vector<int> payload_types; |
| 2327 if (IsRtp(protocol)) { | 2395 if (IsRtp(protocol)) { |
| 2328 for (size_t j = 3 ; j < fields.size(); ++j) { | 2396 for (size_t j = 3 ; j < fields.size(); ++j) { |
| 2329 // TODO(wu): Remove when below bug is fixed. | 2397 // TODO(wu): Remove when below bug is fixed. |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2413 return ParseFailed("", | 2481 return ParseFailed("", |
| 2414 "The a=extmap MUST be either all session level or " | 2482 "The a=extmap MUST be either all session level or " |
| 2415 "all media level.", | 2483 "all media level.", |
| 2416 error); | 2484 error); |
| 2417 } | 2485 } |
| 2418 for (size_t i = 0; i < session_extmaps.size(); ++i) { | 2486 for (size_t i = 0; i < session_extmaps.size(); ++i) { |
| 2419 content->AddRtpHeaderExtension(session_extmaps[i]); | 2487 content->AddRtpHeaderExtension(session_extmaps[i]); |
| 2420 } | 2488 } |
| 2421 } | 2489 } |
| 2422 content->set_protocol(protocol); | 2490 content->set_protocol(protocol); |
| 2491 | |
| 2492 // Use the session level connection address if the media level addresses are | |
| 2493 // not specified. | |
| 2494 if (content->connection_addr().IsNil()) { | |
| 2495 content->set_connection_addr(session_connection_addr); | |
| 2496 } | |
| 2497 | |
| 2423 desc->AddContent(content_name, | 2498 desc->AddContent(content_name, |
| 2424 IsDtlsSctp(protocol) ? cricket::NS_JINGLE_DRAFT_SCTP | 2499 IsDtlsSctp(protocol) ? cricket::NS_JINGLE_DRAFT_SCTP |
| 2425 : cricket::NS_JINGLE_RTP, | 2500 : cricket::NS_JINGLE_RTP, |
| 2426 content_rejected, bundle_only, content.release()); | 2501 content_rejected, bundle_only, content.release()); |
| 2427 // Create TransportInfo with the media level "ice-pwd" and "ice-ufrag". | 2502 // Create TransportInfo with the media level "ice-pwd" and "ice-ufrag". |
| 2428 TransportInfo transport_info(content_name, transport); | 2503 TransportInfo transport_info(content_name, transport); |
| 2429 | 2504 |
| 2430 if (!desc->AddTransportInfo(transport_info)) { | 2505 if (!desc->AddTransportInfo(transport_info)) { |
| 2431 std::ostringstream description; | 2506 std::ostringstream description; |
| 2432 description << "Failed to AddTransportInfo with content name: " | 2507 description << "Failed to AddTransportInfo with content name: " |
| (...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2661 return ParseFailed(line, description.str(), error); | 2736 return ParseFailed(line, description.str(), error); |
| 2662 } | 2737 } |
| 2663 // Prevent integer overflow. | 2738 // Prevent integer overflow. |
| 2664 b = std::min(b, INT_MAX / 1000); | 2739 b = std::min(b, INT_MAX / 1000); |
| 2665 media_desc->set_bandwidth(b * 1000); | 2740 media_desc->set_bandwidth(b * 1000); |
| 2666 } | 2741 } |
| 2667 } | 2742 } |
| 2668 continue; | 2743 continue; |
| 2669 } | 2744 } |
| 2670 | 2745 |
| 2746 // Parse the media level connection data. | |
| 2747 if (IsLineType(line, kLineTypeConnection)) { | |
| 2748 rtc::SocketAddress addr; | |
| 2749 if (!ParseConnectionData(line, &addr, error)) { | |
| 2750 return false; | |
| 2751 } | |
| 2752 media_desc->set_connection_addr(addr); | |
| 2753 continue; | |
| 2754 } | |
| 2755 | |
| 2671 if (!IsLineType(line, kLineTypeAttributes)) { | 2756 if (!IsLineType(line, kLineTypeAttributes)) { |
| 2672 // TODO: Handle other lines if needed. | 2757 // TODO: Handle other lines if needed. |
| 2673 LOG(LS_INFO) << "Ignored line: " << line; | 2758 LOG(LS_INFO) << "Ignored line: " << line; |
| 2674 continue; | 2759 continue; |
| 2675 } | 2760 } |
| 2676 | 2761 |
| 2677 // Handle attributes common to SCTP and RTP. | 2762 // Handle attributes common to SCTP and RTP. |
| 2678 if (HasAttribute(line, kAttributeMid)) { | 2763 if (HasAttribute(line, kAttributeMid)) { |
| 2679 // RFC 3388 | 2764 // RFC 3388 |
| 2680 // mid-attribute = "a=mid:" identification-tag | 2765 // mid-attribute = "a=mid:" identification-tag |
| (...skipping 553 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3234 UpdateCodec<AudioContentDescription, cricket::AudioCodec>( | 3319 UpdateCodec<AudioContentDescription, cricket::AudioCodec>( |
| 3235 media_desc, payload_type, feedback_param); | 3320 media_desc, payload_type, feedback_param); |
| 3236 } else if (media_type == cricket::MEDIA_TYPE_VIDEO) { | 3321 } else if (media_type == cricket::MEDIA_TYPE_VIDEO) { |
| 3237 UpdateCodec<VideoContentDescription, cricket::VideoCodec>( | 3322 UpdateCodec<VideoContentDescription, cricket::VideoCodec>( |
| 3238 media_desc, payload_type, feedback_param); | 3323 media_desc, payload_type, feedback_param); |
| 3239 } | 3324 } |
| 3240 return true; | 3325 return true; |
| 3241 } | 3326 } |
| 3242 | 3327 |
| 3243 } // namespace webrtc | 3328 } // namespace webrtc |
| OLD | NEW |