#include "pc/webrtc_sdp.h"
#include <ctype.h>
#include <limits.h>
#include <algorithm>
#include <cstddef>
#include <cstdint>
#include <map>
#include <memory>
#include <set>
#include <string>
#include <type_traits>
#include <unordered_map>
#include <utility>
#include <vector>
#include "absl/algorithm/container.h"
#include "absl/strings/ascii.h"
#include "absl/strings/match.h"
#include "api/candidate.h"
#include "api/jsep_ice_candidate.h"
#include "api/jsep_session_description.h"
#include "api/media_types.h"
#include "absl/strings/string_view.h"
#include "absl/types/optional.h"
#include "api/rtc_error.h"
#include "api/rtp_parameters.h"
#include "api/rtp_transceiver_direction.h"
#include "media/base/codec.h"
#include "media/base/media_constants.h"
#include "media/base/rid_description.h"
#include "media/base/rtp_utils.h"
#include "media/base/stream_params.h"
#include "media/sctp/sctp_transport_internal.h"
#include "p2p/base/candidate_pair_interface.h"
#include "p2p/base/ice_transport_internal.h"
#include "p2p/base/p2p_constants.h"
#include "p2p/base/port.h"
#include "p2p/base/port_interface.h"
#include "p2p/base/transport_description.h"
#include "p2p/base/transport_info.h"
#include "pc/media_protocol_names.h"
#include "pc/media_session.h"
#include "pc/session_description.h"
#include "pc/simulcast_description.h"
#include "pc/simulcast_sdp_serializer.h"
#include "rtc_base/arraysize.h"
#include "rtc_base/checks.h"
#include "rtc_base/crypto_random.h"
#include "rtc_base/ip_address.h"
#include "rtc_base/logging.h"
#include "rtc_base/net_helper.h"
#include "rtc_base/network_constants.h"
#include "rtc_base/socket_address.h"
#include "rtc_base/ssl_fingerprint.h"
#include "rtc_base/string_encode.h"
#include "rtc_base/string_utils.h"
#include "rtc_base/strings/string_builder.h"
AudioContentDescription;
Candidate;
Candidates;
ContentInfo;
ICE_CANDIDATE_COMPONENT_RTCP;
ICE_CANDIDATE_COMPONENT_RTP;
kApplicationSpecificBandwidth;
kCodecParamMaxPTime;
kCodecParamMinPTime;
kCodecParamPTime;
kTransportSpecificBandwidth;
MediaContentDescription;
MediaProtocolType;
MediaType;
RidDescription;
RtpHeaderExtensions;
SctpDataContentDescription;
SimulcastDescription;
SimulcastLayer;
SimulcastLayerList;
SsrcGroup;
StreamParams;
StreamParamsVec;
TransportDescription;
TransportInfo;
UnsupportedContentDescription;
VideoContentDescription;
SocketAddress;
namespace webrtc {
bool IsTokenChar(char ch) { … }
static const int kLinePrefixLength = …;
static const char kLineTypeVersion = …;
static const char kLineTypeOrigin = …;
static const char kLineTypeSessionName = …;
static const char kLineTypeSessionInfo = …;
static const char kLineTypeSessionUri = …;
static const char kLineTypeSessionEmail = …;
static const char kLineTypeSessionPhone = …;
static const char kLineTypeSessionBandwidth = …;
static const char kLineTypeTiming = …;
static const char kLineTypeRepeatTimes = …;
static const char kLineTypeTimeZone = …;
static const char kLineTypeEncryptionKey = …;
static const char kLineTypeMedia = …;
static const char kLineTypeConnection = …;
static const char kLineTypeAttributes = …;
static const char kAttributeGroup[] = …;
static const char kAttributeMid[] = …;
static const char kAttributeMsid[] = …;
static const char kAttributeBundleOnly[] = …;
static const char kAttributeRtcpMux[] = …;
static const char kAttributeRtcpReducedSize[] = …;
static const char kAttributeSsrc[] = …;
static const char kSsrcAttributeCname[] = …;
static const char kAttributeExtmapAllowMixed[] = …;
static const char kAttributeExtmap[] = …;
static const char kAttributeMsidSemantics[] = …;
static const char kMediaStreamSemantic[] = …;
static const char kSsrcAttributeMsid[] = …;
static const char kDefaultMsid[] = …;
static const char kNoStreamMsid[] = …;
static const char kAttributeSsrcGroup[] = …;
static const char kAttributeCandidate[] = …;
static const char kAttributeCandidateTyp[] = …;
static const char kAttributeCandidateRaddr[] = …;
static const char kAttributeCandidateRport[] = …;
static const char kAttributeCandidateUfrag[] = …;
static const char kAttributeCandidatePwd[] = …;
static const char kAttributeCandidateGeneration[] = …;
static const char kAttributeCandidateNetworkId[] = …;
static const char kAttributeCandidateNetworkCost[] = …;
static const char kAttributeFingerprint[] = …;
static const char kAttributeSetup[] = …;
static const char kAttributeFmtp[] = …;
static const char kAttributeRtpmap[] = …;
static const char kAttributeSctpmap[] = …;
static const char kAttributeRtcp[] = …;
static const char kAttributeIceUfrag[] = …;
static const char kAttributeIcePwd[] = …;
static const char kAttributeIceLite[] = …;
static const char kAttributeIceOption[] = …;
static const char kAttributeSendOnly[] = …;
static const char kAttributeRecvOnly[] = …;
static const char kAttributeRtcpFb[] = …;
static const char kAttributeSendRecv[] = …;
static const char kAttributeInactive[] = …;
static const char kAttributeSctpPort[] = …;
static const char kAttributeMaxMessageSize[] = …;
static const int kDefaultSctpMaxMessageSize = …;
static const char kAttributeSimulcast[] = …;
static const char kAttributeRid[] = …;
static const char kAttributePacketization[] = …;
static const char kAttributeXGoogleFlag[] = …;
static const char kValueConference[] = …;
static const char kAttributeRtcpRemoteEstimate[] = …;
static const char kCandidateHost[] = …;
static const char kCandidateSrflx[] = …;
static const char kCandidatePrflx[] = …;
static const char kCandidateRelay[] = …;
static const char kTcpCandidateType[] = …;
static const char kSdpDelimiterEqual[] = …;
static const char kSdpDelimiterEqualChar = …;
static const char kSdpDelimiterSpace[] = …;
static const char kSdpDelimiterSpaceChar = …;
static const char kSdpDelimiterColon[] = …;
static const char kSdpDelimiterColonChar = …;
static const char kSdpDelimiterSemicolon[] = …;
static const char kSdpDelimiterSemicolonChar = …;
static const char kSdpDelimiterSlashChar = …;
static const char kNewLineChar = …;
static const char kReturnChar = …;
static const char kLineBreak[] = …;
static const char kSessionVersion[] = …;
static const char kSessionOriginUsername[] = …;
static const char kSessionOriginSessionId[] = …;
static const char kSessionOriginSessionVersion[] = …;
static const char kSessionOriginNettype[] = …;
static const char kSessionOriginAddrtype[] = …;
static const char kSessionOriginAddress[] = …;
static const char kSessionName[] = …;
static const char kTimeDescription[] = …;
static const char kAttrGroup[] = …;
static const char kConnectionNettype[] = …;
static const char kConnectionIpv4Addrtype[] = …;
static const char kConnectionIpv6Addrtype[] = …;
static const char kMediaTypeVideo[] = …;
static const char kMediaTypeAudio[] = …;
static const char kMediaTypeData[] = …;
static const char kMediaPortRejected[] = …;
static const char kDummyAddress[] = …;
static const char kDummyPort[] = …;
static const char kDefaultSctpmapProtocol[] = …;
const int kWildcardPayloadType = …;
static const size_t kMaxNumberOfChannels = …;
struct SsrcInfo { … };
SsrcInfoVec;
SsrcGroupVec;
static void BuildMediaDescription(const ContentInfo* content_info,
const TransportInfo* transport_info,
const cricket::MediaType media_type,
const std::vector<Candidate>& candidates,
int msid_signaling,
std::string* message);
static void BuildMediaLine(const cricket::MediaType media_type,
const ContentInfo* content_info,
const MediaContentDescription* media_desc,
std::string* message);
static void BuildRtpContentAttributes(const MediaContentDescription* media_desc,
const cricket::MediaType media_type,
int msid_signaling,
std::string* message);
static void BuildRtpHeaderExtensions(const RtpHeaderExtensions& extensions,
std::string* message);
static void BuildRtpmap(const MediaContentDescription* media_desc,
const cricket::MediaType media_type,
std::string* message);
static void BuildCandidate(const std::vector<Candidate>& candidates,
bool include_ufrag,
std::string* message);
static void BuildIceUfragPwd(const TransportInfo* transport_info,
std::string* message);
static void BuildDtlsFingerprintSetup(const TransportInfo* transport_info,
std::string* message);
static void BuildIceOptions(const std::vector<std::string>& transport_options,
std::string* message);
static bool ParseSessionDescription(absl::string_view message,
size_t* pos,
std::string* session_id,
std::string* session_version,
TransportDescription* session_td,
RtpHeaderExtensions* session_extmaps,
rtc::SocketAddress* connection_addr,
cricket::SessionDescription* desc,
SdpParseError* error);
static bool ParseMediaDescription(
absl::string_view message,
const TransportDescription& session_td,
const RtpHeaderExtensions& session_extmaps,
size_t* pos,
const rtc::SocketAddress& session_connection_addr,
cricket::SessionDescription* desc,
std::vector<std::unique_ptr<JsepIceCandidate>>* candidates,
SdpParseError* error);
static bool ParseContent(
absl::string_view message,
const cricket::MediaType media_type,
int mline_index,
absl::string_view protocol,
const std::vector<int>& payload_types,
size_t* pos,
std::string* content_name,
bool* bundle_only,
int* msid_signaling,
MediaContentDescription* media_desc,
TransportDescription* transport,
std::vector<std::unique_ptr<JsepIceCandidate>>* candidates,
SdpParseError* error);
static bool ParseGroupAttribute(absl::string_view line,
cricket::SessionDescription* desc,
SdpParseError* error);
static bool ParseSsrcAttribute(absl::string_view line,
SsrcInfoVec* ssrc_infos,
int* msid_signaling,
SdpParseError* error);
static bool ParseSsrcGroupAttribute(absl::string_view line,
SsrcGroupVec* ssrc_groups,
SdpParseError* error);
static bool ParseRtpmapAttribute(absl::string_view line,
const cricket::MediaType media_type,
const std::vector<int>& payload_types,
MediaContentDescription* media_desc,
SdpParseError* error);
static bool ParseFmtpAttributes(absl::string_view line,
const cricket::MediaType media_type,
MediaContentDescription* media_desc,
SdpParseError* error);
static bool ParseFmtpParam(absl::string_view line,
std::string* parameter,
std::string* value,
SdpParseError* error);
static bool ParsePacketizationAttribute(absl::string_view line,
const cricket::MediaType media_type,
MediaContentDescription* media_desc,
SdpParseError* error);
static bool ParseRtcpFbAttribute(absl::string_view line,
const cricket::MediaType media_type,
MediaContentDescription* media_desc,
SdpParseError* error);
static bool ParseIceOptions(absl::string_view line,
std::vector<std::string>* transport_options,
SdpParseError* error);
static bool ParseExtmap(absl::string_view line,
RtpExtension* extmap,
SdpParseError* error);
static bool ParseFingerprintAttribute(
absl::string_view line,
std::unique_ptr<rtc::SSLFingerprint>* fingerprint,
SdpParseError* error);
static bool ParseDtlsSetup(absl::string_view line,
cricket::ConnectionRole* role,
SdpParseError* error);
static bool ParseMsidAttribute(absl::string_view line,
std::vector<std::string>* stream_ids,
std::string* track_id,
SdpParseError* error);
static void RemoveInvalidRidDescriptions(const std::vector<int>& payload_types,
std::vector<RidDescription>* rids);
static SimulcastLayerList RemoveRidsFromSimulcastLayerList(
const std::set<std::string>& to_remove,
const SimulcastLayerList& layers);
static void RemoveInvalidRidsFromSimulcast(
const std::vector<RidDescription>& rids,
SimulcastDescription* simulcast);
static bool ParseFailed(absl::string_view message,
size_t line_start,
std::string description,
SdpParseError* error) { … }
static bool ParseFailed(absl::string_view line,
std::string description,
SdpParseError* error) { … }
static bool ParseFailed(std::string description, SdpParseError* error) { … }
static bool ParseFailedExpectFieldNum(absl::string_view line,
int expected_fields,
SdpParseError* error) { … }
static bool ParseFailedExpectMinFieldNum(absl::string_view line,
int expected_min_fields,
SdpParseError* error) { … }
static bool ParseFailedGetValue(absl::string_view line,
absl::string_view attribute,
SdpParseError* error) { … }
static bool ParseFailedExpectLine(absl::string_view message,
size_t line_start,
const char line_type,
absl::string_view line_value,
SdpParseError* error) { … }
static bool AddLine(absl::string_view line, std::string* message) { … }
static absl::string_view TrimReturnChar(absl::string_view line) { … }
static absl::optional<absl::string_view> GetLine(absl::string_view message,
size_t* pos) { … }
static void InitLine(const char type,
absl::string_view value,
rtc::StringBuilder* os) { … }
static void InitAttrLine(absl::string_view attribute, rtc::StringBuilder* os) { … }
static void AddAttributeLine(absl::string_view attribute,
int value,
std::string* message) { … }
static bool IsLineType(absl::string_view message,
const char type,
size_t line_start) { … }
static bool IsLineType(absl::string_view line, const char type) { … }
static absl::optional<absl::string_view>
GetLineWithType(absl::string_view message, size_t* pos, const char type) { … }
static bool HasAttribute(absl::string_view line, absl::string_view attribute) { … }
static bool AddSsrcLine(uint32_t ssrc_id,
absl::string_view attribute,
absl::string_view value,
std::string* message) { … }
static bool GetValue(absl::string_view message,
absl::string_view attribute,
std::string* value,
SdpParseError* error) { … }
static bool GetSingleTokenValue(absl::string_view message,
absl::string_view attribute,
std::string* value,
SdpParseError* error) { … }
static bool CaseInsensitiveFind(std::string str1, std::string str2) { … }
template <class T>
static bool GetValueFromString(absl::string_view line,
absl::string_view s,
T* t,
SdpParseError* error) { … }
static bool GetPayloadTypeFromString(absl::string_view line,
absl::string_view s,
int* payload_type,
SdpParseError* error) { … }
void CreateTrackWithNoSsrcs(const std::vector<std::string>& msid_stream_ids,
absl::string_view msid_track_id,
const std::vector<RidDescription>& rids,
StreamParamsVec* tracks) { … }
void CreateTracksFromSsrcInfos(const SsrcInfoVec& ssrc_infos,
const std::vector<std::string>& msid_stream_ids,
absl::string_view msid_track_id,
StreamParamsVec* tracks,
int msid_signaling) { … }
void GetMediaStreamIds(const ContentInfo* content,
std::set<std::string>* labels) { … }
static void GetDefaultDestination(const std::vector<Candidate>& candidates,
int component_id,
std::string* port,
std::string* ip,
std::string* addr_type) { … }
static std::string GetRtcpLine(const std::vector<Candidate>& candidates) { … }
static void GetCandidatesByMindex(const SessionDescriptionInterface& desci,
int mline_index,
std::vector<Candidate>* candidates) { … }
static bool IsValidPort(int port) { … }
std::string SdpSerialize(const JsepSessionDescription& jdesc) { … }
std::string SdpSerializeCandidate(const IceCandidateInterface& candidate) { … }
std::string SdpSerializeCandidate(const cricket::Candidate& candidate) { … }
bool SdpDeserialize(absl::string_view message,
JsepSessionDescription* jdesc,
SdpParseError* error) { … }
bool SdpDeserializeCandidate(absl::string_view message,
JsepIceCandidate* jcandidate,
SdpParseError* error) { … }
bool SdpDeserializeCandidate(absl::string_view transport_name,
absl::string_view message,
cricket::Candidate* candidate,
SdpParseError* error) { … }
bool ParseCandidate(absl::string_view message,
Candidate* candidate,
SdpParseError* error,
bool is_raw) { … }
bool ParseIceOptions(absl::string_view line,
std::vector<std::string>* transport_options,
SdpParseError* error) { … }
bool ParseSctpPort(absl::string_view line,
int* sctp_port,
SdpParseError* error) { … }
bool ParseSctpMaxMessageSize(absl::string_view line,
int* max_message_size,
SdpParseError* error) { … }
bool ParseExtmap(absl::string_view line,
RtpExtension* extmap,
SdpParseError* error) { … }
static void BuildSctpContentAttributes(
std::string* message,
const cricket::SctpDataContentDescription* data_desc) { … }
void BuildIceUfragPwd(const TransportInfo* transport_info,
std::string* message) { … }
void BuildDtlsFingerprintSetup(const TransportInfo* transport_info,
std::string* message) { … }
void BuildMediaLine(const cricket::MediaType media_type,
const ContentInfo* content_info,
const MediaContentDescription* media_desc,
std::string* message) { … }
void BuildMediaDescription(const ContentInfo* content_info,
const TransportInfo* transport_info,
const cricket::MediaType media_type,
const std::vector<Candidate>& candidates,
int msid_signaling,
std::string* message) { … }
void BuildRtpContentAttributes(const MediaContentDescription* media_desc,
const cricket::MediaType media_type,
int msid_signaling,
std::string* message) { … }
void BuildRtpHeaderExtensions(const RtpHeaderExtensions& extensions,
std::string* message) { … }
void WriteFmtpHeader(int payload_type, rtc::StringBuilder* os) { … }
void WritePacketizationHeader(int payload_type, rtc::StringBuilder* os) { … }
void WriteRtcpFbHeader(int payload_type, rtc::StringBuilder* os) { … }
void WriteFmtpParameter(absl::string_view parameter_name,
absl::string_view parameter_value,
rtc::StringBuilder* os) { … }
bool IsFmtpParam(absl::string_view name) { … }
bool WriteFmtpParameters(const webrtc::CodecParameterMap& parameters,
rtc::StringBuilder* os) { … }
void AddFmtpLine(const cricket::Codec& codec, std::string* message) { … }
void AddPacketizationLine(const cricket::Codec& codec, std::string* message) { … }
void AddRtcpFbLines(const cricket::Codec& codec, std::string* message) { … }
bool GetMinValue(const std::vector<int>& values, int* value) { … }
bool GetParameter(const std::string& name,
const webrtc::CodecParameterMap& params,
int* value) { … }
void BuildRtpmap(const MediaContentDescription* media_desc,
const cricket::MediaType media_type,
std::string* message) { … }
void BuildCandidate(const std::vector<Candidate>& candidates,
bool include_ufrag,
std::string* message) { … }
void BuildIceOptions(const std::vector<std::string>& transport_options,
std::string* message) { … }
bool ParseConnectionData(absl::string_view line,
rtc::SocketAddress* addr,
SdpParseError* error) { … }
bool ParseSessionDescription(absl::string_view message,
size_t* pos,
std::string* session_id,
std::string* session_version,
TransportDescription* session_td,
RtpHeaderExtensions* session_extmaps,
rtc::SocketAddress* connection_addr,
cricket::SessionDescription* desc,
SdpParseError* error) { … }
bool ParseGroupAttribute(absl::string_view line,
cricket::SessionDescription* desc,
SdpParseError* error) { … }
static bool ParseFingerprintAttribute(
absl::string_view line,
std::unique_ptr<rtc::SSLFingerprint>* fingerprint,
SdpParseError* error) { … }
static bool ParseDtlsSetup(absl::string_view line,
cricket::ConnectionRole* role_ptr,
SdpParseError* error) { … }
static bool ParseMsidAttribute(absl::string_view line,
std::vector<std::string>* stream_ids,
std::string* track_id,
SdpParseError* error) { … }
static void RemoveInvalidRidDescriptions(const std::vector<int>& payload_types,
std::vector<RidDescription>* rids) { … }
static SimulcastLayerList RemoveRidsFromSimulcastLayerList(
const std::set<std::string>& to_remove,
const SimulcastLayerList& layers) { … }
static void RemoveInvalidRidsFromSimulcast(
const std::vector<RidDescription>& valid_rids,
SimulcastDescription* simulcast) { … }
struct StaticPayloadAudioCodec { … };
static const StaticPayloadAudioCodec kStaticPayloadAudioCodecs[] = …;
void MaybeCreateStaticPayloadAudioCodecs(const std::vector<int>& fmts,
MediaContentDescription* media_desc) { … }
static void BackfillCodecParameters(std::vector<cricket::Codec>& codecs) { … }
static std::unique_ptr<MediaContentDescription> ParseContentDescription(
absl::string_view message,
const cricket::MediaType media_type,
int mline_index,
absl::string_view protocol,
const std::vector<int>& payload_types,
size_t* pos,
std::string* content_name,
bool* bundle_only,
int* msid_signaling,
TransportDescription* transport,
std::vector<std::unique_ptr<JsepIceCandidate>>* candidates,
SdpParseError* error) { … }
bool HasDuplicateMsidLines(cricket::SessionDescription* desc) { … }
bool ParseMediaDescription(
absl::string_view message,
const TransportDescription& session_td,
const RtpHeaderExtensions& session_extmaps,
size_t* pos,
const rtc::SocketAddress& session_connection_addr,
cricket::SessionDescription* desc,
std::vector<std::unique_ptr<JsepIceCandidate>>* candidates,
SdpParseError* error) { … }
void AddParameters(const webrtc::CodecParameterMap& parameters,
cricket::Codec* codec) { … }
void AddFeedbackParameter(const cricket::FeedbackParam& feedback_param,
cricket::Codec* codec) { … }
void AddFeedbackParameters(const cricket::FeedbackParams& feedback_params,
cricket::Codec* codec) { … }
cricket::Codec GetCodecWithPayloadType(
cricket::MediaType type,
const std::vector<cricket::Codec>& codecs,
int payload_type) { … }
void AddOrReplaceCodec(MediaContentDescription* content_desc,
const cricket::Codec& codec) { … }
void UpdateCodec(MediaContentDescription* content_desc,
int payload_type,
const webrtc::CodecParameterMap& parameters) { … }
void UpdateCodec(MediaContentDescription* content_desc,
int payload_type,
const cricket::FeedbackParam& feedback_param) { … }
void UpdateVideoCodecPacketization(MediaContentDescription* desc,
int payload_type,
absl::string_view packetization) { … }
absl::optional<cricket::Codec> PopWildcardCodec(
std::vector<cricket::Codec>* codecs) { … }
void UpdateFromWildcardCodecs(cricket::MediaContentDescription* desc) { … }
void AddAudioAttribute(const std::string& name,
absl::string_view value,
MediaContentDescription* desc) { … }
bool ParseContent(absl::string_view message,
const cricket::MediaType media_type,
int mline_index,
absl::string_view protocol,
const std::vector<int>& payload_types,
size_t* pos,
std::string* content_name,
bool* bundle_only,
int* msid_signaling,
MediaContentDescription* media_desc,
TransportDescription* transport,
std::vector<std::unique_ptr<JsepIceCandidate>>* candidates,
SdpParseError* error) { … }
bool ParseSsrcAttribute(absl::string_view line,
SsrcInfoVec* ssrc_infos,
int* msid_signaling,
SdpParseError* error) { … }
bool ParseSsrcGroupAttribute(absl::string_view line,
SsrcGroupVec* ssrc_groups,
SdpParseError* error) { … }
void UpdateCodec(int payload_type,
absl::string_view name,
int clockrate,
int bitrate,
size_t channels,
MediaContentDescription* desc) { … }
void UpdateCodec(int payload_type,
absl::string_view name,
MediaContentDescription* desc) { … }
bool ParseRtpmapAttribute(absl::string_view line,
const cricket::MediaType media_type,
const std::vector<int>& payload_types,
MediaContentDescription* media_desc,
SdpParseError* error) { … }
bool ParseFmtpParam(absl::string_view line,
std::string* parameter,
std::string* value,
SdpParseError* error) { … }
bool ParseFmtpParameterSet(absl::string_view line_params,
webrtc::CodecParameterMap& codec_params,
SdpParseError* error) { … }
bool ParseFmtpAttributes(absl::string_view line,
const cricket::MediaType media_type,
MediaContentDescription* media_desc,
SdpParseError* error) { … }
bool ParsePacketizationAttribute(absl::string_view line,
const cricket::MediaType media_type,
MediaContentDescription* media_desc,
SdpParseError* error) { … }
bool ParseRtcpFbAttribute(absl::string_view line,
const cricket::MediaType media_type,
MediaContentDescription* media_desc,
SdpParseError* error) { … }
}