| 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 |
| 11 #include "webrtc/api/webrtcsdp.h" | 11 #include "webrtc/api/webrtcsdp.h" |
| 12 | 12 |
| 13 #include <ctype.h> | 13 #include <ctype.h> |
| 14 #include <limits.h> | 14 #include <limits.h> |
| 15 #include <stdio.h> | 15 #include <stdio.h> |
| 16 | 16 |
| 17 #include <algorithm> | 17 #include <algorithm> |
| 18 #include <memory> | 18 #include <memory> |
| 19 #include <string> | 19 #include <string> |
| 20 #include <unordered_map> | 20 #include <unordered_map> |
| 21 #include <vector> | 21 #include <vector> |
| 22 | 22 |
| 23 #include "webrtc/api/jsepicecandidate.h" | 23 #include "webrtc/api/jsepicecandidate.h" |
| 24 #include "webrtc/api/jsepsessiondescription.h" | 24 #include "webrtc/api/jsepsessiondescription.h" |
| 25 #include "webrtc/base/arraysize.h" | 25 #include "webrtc/base/arraysize.h" |
| 26 #include "webrtc/base/common.h" | 26 #include "webrtc/base/common.h" |
| 27 #include "webrtc/base/logging.h" | 27 #include "webrtc/base/logging.h" |
| 28 #include "webrtc/base/messagedigest.h" | 28 #include "webrtc/base/messagedigest.h" |
| 29 #include "webrtc/base/stringutils.h" | 29 #include "webrtc/base/stringutils.h" |
| 30 // for RtpExtension |
| 31 #include "webrtc/config.h" |
| 30 #include "webrtc/media/base/codec.h" | 32 #include "webrtc/media/base/codec.h" |
| 31 #include "webrtc/media/base/cryptoparams.h" | 33 #include "webrtc/media/base/cryptoparams.h" |
| 32 #include "webrtc/media/base/mediaconstants.h" | 34 #include "webrtc/media/base/mediaconstants.h" |
| 33 #include "webrtc/media/base/rtputils.h" | 35 #include "webrtc/media/base/rtputils.h" |
| 34 #include "webrtc/media/sctp/sctpdataengine.h" | 36 #include "webrtc/media/sctp/sctpdataengine.h" |
| 35 #include "webrtc/p2p/base/candidate.h" | 37 #include "webrtc/p2p/base/candidate.h" |
| 36 #include "webrtc/p2p/base/p2pconstants.h" | 38 #include "webrtc/p2p/base/p2pconstants.h" |
| 37 #include "webrtc/p2p/base/port.h" | 39 #include "webrtc/p2p/base/port.h" |
| 38 #include "webrtc/pc/mediasession.h" | 40 #include "webrtc/pc/mediasession.h" |
| 39 | 41 |
| (...skipping 17 matching lines...) Expand all Loading... |
| 57 using cricket::kCodecParamStereo; | 59 using cricket::kCodecParamStereo; |
| 58 using cricket::kCodecParamUseInbandFec; | 60 using cricket::kCodecParamUseInbandFec; |
| 59 using cricket::kCodecParamUseDtx; | 61 using cricket::kCodecParamUseDtx; |
| 60 using cricket::kCodecParamSctpProtocol; | 62 using cricket::kCodecParamSctpProtocol; |
| 61 using cricket::kCodecParamSctpStreams; | 63 using cricket::kCodecParamSctpStreams; |
| 62 using cricket::kCodecParamMaxAverageBitrate; | 64 using cricket::kCodecParamMaxAverageBitrate; |
| 63 using cricket::kCodecParamMaxPlaybackRate; | 65 using cricket::kCodecParamMaxPlaybackRate; |
| 64 using cricket::kCodecParamAssociatedPayloadType; | 66 using cricket::kCodecParamAssociatedPayloadType; |
| 65 using cricket::MediaContentDescription; | 67 using cricket::MediaContentDescription; |
| 66 using cricket::MediaType; | 68 using cricket::MediaType; |
| 67 using cricket::RtpHeaderExtension; | 69 using cricket::RtpHeaderExtensions; |
| 68 using cricket::SsrcGroup; | 70 using cricket::SsrcGroup; |
| 69 using cricket::StreamParams; | 71 using cricket::StreamParams; |
| 70 using cricket::StreamParamsVec; | 72 using cricket::StreamParamsVec; |
| 71 using cricket::TransportDescription; | 73 using cricket::TransportDescription; |
| 72 using cricket::TransportInfo; | 74 using cricket::TransportInfo; |
| 73 using cricket::VideoContentDescription; | 75 using cricket::VideoContentDescription; |
| 74 using rtc::SocketAddress; | 76 using rtc::SocketAddress; |
| 75 | 77 |
| 76 typedef std::vector<RtpHeaderExtension> RtpHeaderExtensions; | |
| 77 | |
| 78 namespace cricket { | 78 namespace cricket { |
| 79 class SessionDescription; | 79 class SessionDescription; |
| 80 } | 80 } |
| 81 | 81 |
| 82 namespace webrtc { | 82 namespace webrtc { |
| 83 | 83 |
| 84 // Line type | 84 // Line type |
| 85 // RFC 4566 | 85 // RFC 4566 |
| 86 // An SDP session description consists of a number of lines of text of | 86 // An SDP session description consists of a number of lines of text of |
| 87 // the form: | 87 // the form: |
| (...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 302 static bool ParseCandidate(const std::string& message, Candidate* candidate, | 302 static bool ParseCandidate(const std::string& message, Candidate* candidate, |
| 303 SdpParseError* error, bool is_raw); | 303 SdpParseError* error, bool is_raw); |
| 304 static bool ParseRtcpFbAttribute(const std::string& line, | 304 static bool ParseRtcpFbAttribute(const std::string& line, |
| 305 const MediaType media_type, | 305 const MediaType media_type, |
| 306 MediaContentDescription* media_desc, | 306 MediaContentDescription* media_desc, |
| 307 SdpParseError* error); | 307 SdpParseError* error); |
| 308 static bool ParseIceOptions(const std::string& line, | 308 static bool ParseIceOptions(const std::string& line, |
| 309 std::vector<std::string>* transport_options, | 309 std::vector<std::string>* transport_options, |
| 310 SdpParseError* error); | 310 SdpParseError* error); |
| 311 static bool ParseExtmap(const std::string& line, | 311 static bool ParseExtmap(const std::string& line, |
| 312 RtpHeaderExtension* extmap, | 312 RtpExtension* extmap, |
| 313 SdpParseError* error); | 313 SdpParseError* error); |
| 314 static bool ParseFingerprintAttribute(const std::string& line, | 314 static bool ParseFingerprintAttribute(const std::string& line, |
| 315 rtc::SSLFingerprint** fingerprint, | 315 rtc::SSLFingerprint** fingerprint, |
| 316 SdpParseError* error); | 316 SdpParseError* error); |
| 317 static bool ParseDtlsSetup(const std::string& line, | 317 static bool ParseDtlsSetup(const std::string& line, |
| 318 cricket::ConnectionRole* role, | 318 cricket::ConnectionRole* role, |
| 319 SdpParseError* error); | 319 SdpParseError* error); |
| 320 static bool ParseMsidAttribute(const std::string& line, | 320 static bool ParseMsidAttribute(const std::string& line, |
| 321 std::string* stream_id, | 321 std::string* stream_id, |
| 322 std::string* track_id, | 322 std::string* track_id, |
| (...skipping 838 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1161 } | 1161 } |
| 1162 if (fields.size() < expected_min_fields) { | 1162 if (fields.size() < expected_min_fields) { |
| 1163 return ParseFailedExpectMinFieldNum(line, expected_min_fields, error); | 1163 return ParseFailedExpectMinFieldNum(line, expected_min_fields, error); |
| 1164 } | 1164 } |
| 1165 if (!rtc::FromString(fields[1], sctp_port)) { | 1165 if (!rtc::FromString(fields[1], sctp_port)) { |
| 1166 return ParseFailed(line, "Invalid sctp port value.", error); | 1166 return ParseFailed(line, "Invalid sctp port value.", error); |
| 1167 } | 1167 } |
| 1168 return true; | 1168 return true; |
| 1169 } | 1169 } |
| 1170 | 1170 |
| 1171 bool ParseExtmap(const std::string& line, RtpHeaderExtension* extmap, | 1171 bool ParseExtmap(const std::string& line, |
| 1172 RtpExtension* extmap, |
| 1172 SdpParseError* error) { | 1173 SdpParseError* error) { |
| 1173 // RFC 5285 | 1174 // RFC 5285 |
| 1174 // a=extmap:<value>["/"<direction>] <URI> <extensionattributes> | 1175 // a=extmap:<value>["/"<direction>] <URI> <extensionattributes> |
| 1175 std::vector<std::string> fields; | 1176 std::vector<std::string> fields; |
| 1176 rtc::split(line.substr(kLinePrefixLength), | 1177 rtc::split(line.substr(kLinePrefixLength), |
| 1177 kSdpDelimiterSpace, &fields); | 1178 kSdpDelimiterSpace, &fields); |
| 1178 const size_t expected_min_fields = 2; | 1179 const size_t expected_min_fields = 2; |
| 1179 if (fields.size() < expected_min_fields) { | 1180 if (fields.size() < expected_min_fields) { |
| 1180 return ParseFailedExpectMinFieldNum(line, expected_min_fields, error); | 1181 return ParseFailedExpectMinFieldNum(line, expected_min_fields, error); |
| 1181 } | 1182 } |
| 1182 std::string uri = fields[1]; | 1183 std::string uri = fields[1]; |
| 1183 | 1184 |
| 1184 std::string value_direction; | 1185 std::string value_direction; |
| 1185 if (!GetValue(fields[0], kAttributeExtmap, &value_direction, error)) { | 1186 if (!GetValue(fields[0], kAttributeExtmap, &value_direction, error)) { |
| 1186 return false; | 1187 return false; |
| 1187 } | 1188 } |
| 1188 std::vector<std::string> sub_fields; | 1189 std::vector<std::string> sub_fields; |
| 1189 rtc::split(value_direction, kSdpDelimiterSlash, &sub_fields); | 1190 rtc::split(value_direction, kSdpDelimiterSlash, &sub_fields); |
| 1190 int value = 0; | 1191 int value = 0; |
| 1191 if (!GetValueFromString(line, sub_fields[0], &value, error)) { | 1192 if (!GetValueFromString(line, sub_fields[0], &value, error)) { |
| 1192 return false; | 1193 return false; |
| 1193 } | 1194 } |
| 1194 | 1195 |
| 1195 *extmap = RtpHeaderExtension(uri, value); | 1196 *extmap = RtpExtension(uri, value); |
| 1196 return true; | 1197 return true; |
| 1197 } | 1198 } |
| 1198 | 1199 |
| 1199 void BuildMediaDescription(const ContentInfo* content_info, | 1200 void BuildMediaDescription(const ContentInfo* content_info, |
| 1200 const TransportInfo* transport_info, | 1201 const TransportInfo* transport_info, |
| 1201 const MediaType media_type, | 1202 const MediaType media_type, |
| 1202 const std::vector<Candidate>& candidates, | 1203 const std::vector<Candidate>& candidates, |
| 1203 bool unified_plan_sdp, | 1204 bool unified_plan_sdp, |
| 1204 std::string* message) { | 1205 std::string* message) { |
| 1205 ASSERT(message != NULL); | 1206 ASSERT(message != NULL); |
| (...skipping 802 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2008 return false; | 2009 return false; |
| 2009 } | 2010 } |
| 2010 } else if (HasAttribute(line, kAttributeMsidSemantics)) { | 2011 } else if (HasAttribute(line, kAttributeMsidSemantics)) { |
| 2011 std::string semantics; | 2012 std::string semantics; |
| 2012 if (!GetValue(line, kAttributeMsidSemantics, &semantics, error)) { | 2013 if (!GetValue(line, kAttributeMsidSemantics, &semantics, error)) { |
| 2013 return false; | 2014 return false; |
| 2014 } | 2015 } |
| 2015 desc->set_msid_supported( | 2016 desc->set_msid_supported( |
| 2016 CaseInsensitiveFind(semantics, kMediaStreamSemantic)); | 2017 CaseInsensitiveFind(semantics, kMediaStreamSemantic)); |
| 2017 } else if (HasAttribute(line, kAttributeExtmap)) { | 2018 } else if (HasAttribute(line, kAttributeExtmap)) { |
| 2018 RtpHeaderExtension extmap; | 2019 RtpExtension extmap; |
| 2019 if (!ParseExtmap(line, &extmap, error)) { | 2020 if (!ParseExtmap(line, &extmap, error)) { |
| 2020 return false; | 2021 return false; |
| 2021 } | 2022 } |
| 2022 session_extmaps->push_back(extmap); | 2023 session_extmaps->push_back(extmap); |
| 2023 } | 2024 } |
| 2024 } | 2025 } |
| 2025 | 2026 |
| 2026 return true; | 2027 return true; |
| 2027 } | 2028 } |
| 2028 | 2029 |
| (...skipping 667 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2696 } | 2697 } |
| 2697 } else if (HasAttribute(line, kAttributeSendOnly)) { | 2698 } else if (HasAttribute(line, kAttributeSendOnly)) { |
| 2698 media_desc->set_direction(cricket::MD_SENDONLY); | 2699 media_desc->set_direction(cricket::MD_SENDONLY); |
| 2699 } else if (HasAttribute(line, kAttributeRecvOnly)) { | 2700 } else if (HasAttribute(line, kAttributeRecvOnly)) { |
| 2700 media_desc->set_direction(cricket::MD_RECVONLY); | 2701 media_desc->set_direction(cricket::MD_RECVONLY); |
| 2701 } else if (HasAttribute(line, kAttributeInactive)) { | 2702 } else if (HasAttribute(line, kAttributeInactive)) { |
| 2702 media_desc->set_direction(cricket::MD_INACTIVE); | 2703 media_desc->set_direction(cricket::MD_INACTIVE); |
| 2703 } else if (HasAttribute(line, kAttributeSendRecv)) { | 2704 } else if (HasAttribute(line, kAttributeSendRecv)) { |
| 2704 media_desc->set_direction(cricket::MD_SENDRECV); | 2705 media_desc->set_direction(cricket::MD_SENDRECV); |
| 2705 } else if (HasAttribute(line, kAttributeExtmap)) { | 2706 } else if (HasAttribute(line, kAttributeExtmap)) { |
| 2706 RtpHeaderExtension extmap; | 2707 RtpExtension extmap; |
| 2707 if (!ParseExtmap(line, &extmap, error)) { | 2708 if (!ParseExtmap(line, &extmap, error)) { |
| 2708 return false; | 2709 return false; |
| 2709 } | 2710 } |
| 2710 media_desc->AddRtpHeaderExtension(extmap); | 2711 media_desc->AddRtpHeaderExtension(extmap); |
| 2711 } else if (HasAttribute(line, kAttributeXGoogleFlag)) { | 2712 } else if (HasAttribute(line, kAttributeXGoogleFlag)) { |
| 2712 // Experimental attribute. Conference mode activates more aggressive | 2713 // Experimental attribute. Conference mode activates more aggressive |
| 2713 // AEC and NS settings. | 2714 // AEC and NS settings. |
| 2714 // TODO: expose API to set these directly. | 2715 // TODO: expose API to set these directly. |
| 2715 std::string flag_value; | 2716 std::string flag_value; |
| 2716 if (!GetValue(line, kAttributeXGoogleFlag, &flag_value, error)) { | 2717 if (!GetValue(line, kAttributeXGoogleFlag, &flag_value, error)) { |
| (...skipping 458 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3175 UpdateCodec<AudioContentDescription, cricket::AudioCodec>( | 3176 UpdateCodec<AudioContentDescription, cricket::AudioCodec>( |
| 3176 media_desc, payload_type, feedback_param); | 3177 media_desc, payload_type, feedback_param); |
| 3177 } else if (media_type == cricket::MEDIA_TYPE_VIDEO) { | 3178 } else if (media_type == cricket::MEDIA_TYPE_VIDEO) { |
| 3178 UpdateCodec<VideoContentDescription, cricket::VideoCodec>( | 3179 UpdateCodec<VideoContentDescription, cricket::VideoCodec>( |
| 3179 media_desc, payload_type, feedback_param); | 3180 media_desc, payload_type, feedback_param); |
| 3180 } | 3181 } |
| 3181 return true; | 3182 return true; |
| 3182 } | 3183 } |
| 3183 | 3184 |
| 3184 } // namespace webrtc | 3185 } // namespace webrtc |
| OLD | NEW |