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

Side by Side Diff: webrtc/pc/mediasession.cc

Issue 2761143002: Support encrypted RTP extensions (RFC 6904) (Closed)
Patch Set: Updated comment. Created 3 years, 7 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 * Copyright 2004 The WebRTC project authors. All Rights Reserved. 2 * Copyright 2004 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 914 matching lines...) Expand 10 before | Expand all | Expand 10 after
925 rtc::ToString(matching_codec.id); 925 rtc::ToString(matching_codec.id);
926 used_pltypes->FindAndSetIdUsed(&rtx_codec); 926 used_pltypes->FindAndSetIdUsed(&rtx_codec);
927 offered_codecs->push_back(rtx_codec); 927 offered_codecs->push_back(rtx_codec);
928 } 928 }
929 } 929 }
930 } 930 }
931 931
932 static bool FindByUri(const RtpHeaderExtensions& extensions, 932 static bool FindByUri(const RtpHeaderExtensions& extensions,
933 const webrtc::RtpExtension& ext_to_match, 933 const webrtc::RtpExtension& ext_to_match,
934 webrtc::RtpExtension* found_extension) { 934 webrtc::RtpExtension* found_extension) {
935 // We assume that all URIs are given in a canonical format.
936 const webrtc::RtpExtension* found =
937 webrtc::RtpExtension::FindHeaderExtensionByUri(extensions,
938 ext_to_match.uri);
939 if (!found) {
940 return false;
941 }
942 if (found_extension) {
943 *found_extension = *found;
944 }
945 return true;
946 }
947
948 static bool FindByUriWithEncryptionPreference(
949 const RtpHeaderExtensions& extensions,
950 const webrtc::RtpExtension& ext_to_match, bool encryption_preference,
951 webrtc::RtpExtension* found_extension) {
952 const webrtc::RtpExtension* regular_extension = nullptr;
935 for (RtpHeaderExtensions::const_iterator it = extensions.begin(); 953 for (RtpHeaderExtensions::const_iterator it = extensions.begin();
936 it != extensions.end(); ++it) { 954 it != extensions.end(); ++it) {
937 // We assume that all URIs are given in a canonical format. 955 // We assume that all URIs are given in a canonical format.
938 if (it->uri == ext_to_match.uri) { 956 if (it->uri == ext_to_match.uri) {
939 if (found_extension != NULL) { 957 if (!found_extension) {
958 return true;
959 }
960 if (!encryption_preference || it->encrypt) {
940 *found_extension = *it; 961 *found_extension = *it;
962 return true;
941 } 963 }
pthatcher1 2017/05/05 21:26:38 This would be more clear the way you did it in the
joachim 2017/05/06 14:52:33 Done.
942 return true; 964 regular_extension = &(*it);
pthatcher1 2017/05/05 21:26:38 unencrypted_extension might be more clear
joachim 2017/05/06 14:52:33 Done.
943 } 965 }
944 } 966 }
967 if (regular_extension) {
968 *found_extension = *regular_extension;
969 return true;
pthatcher1 2017/05/05 21:26:38 I know you mixed it into the logic up above, but i
joachim 2017/05/06 14:52:33 Done.
970 }
945 return false; 971 return false;
946 } 972 }
947 973
948 // Iterates through |offered_extensions|, adding each one to |all_extensions| 974 // Iterates through |offered_extensions|, adding each one to
949 // and |used_ids|, and resolving ID conflicts. If an offered extension has the 975 // |regular_extensions| (or |encrypted_extensions| if encrypted) and |used_ids|,
950 // same URI as one in |all_extensions|, it will re-use the same ID and won't be 976 // and resolving ID conflicts.
951 // treated as a conflict. 977 // If an offered extension has the same URI as one in |regular_extensions| or
978 // |encrypted_extensions|, it will re-use the same ID and won't be treated as
979 // a conflict.
952 static void FindAndSetRtpHdrExtUsed(RtpHeaderExtensions* offered_extensions, 980 static void FindAndSetRtpHdrExtUsed(RtpHeaderExtensions* offered_extensions,
953 RtpHeaderExtensions* all_extensions, 981 RtpHeaderExtensions* regular_extensions,
982 RtpHeaderExtensions* encrypted_extensions,
954 UsedRtpHeaderExtensionIds* used_ids) { 983 UsedRtpHeaderExtensionIds* used_ids) {
955 for (auto& extension : *offered_extensions) { 984 for (auto& extension : *offered_extensions) {
956 webrtc::RtpExtension existing; 985 webrtc::RtpExtension existing;
957 if (FindByUri(*all_extensions, extension, &existing)) { 986 if ((extension.encrypt &&
987 FindByUri(*encrypted_extensions, extension, &existing)) ||
988 (!extension.encrypt &&
989 FindByUri(*regular_extensions, extension, &existing))) {
958 extension.id = existing.id; 990 extension.id = existing.id;
959 } else { 991 } else {
960 used_ids->FindAndSetIdUsed(&extension); 992 used_ids->FindAndSetIdUsed(&extension);
961 all_extensions->push_back(extension); 993 if (extension.encrypt) {
994 encrypted_extensions->push_back(extension);
995 } else {
996 regular_extensions->push_back(extension);
997 }
962 } 998 }
963 } 999 }
964 } 1000 }
965 1001
966 // Adds |reference_extensions| to |offered_extensions|, while updating 1002 // Adds |reference_extensions| to |offered_extensions|, while updating
967 // |all_extensions| and |used_ids|. 1003 // |all_extensions| and |used_ids|.
968 static void FindRtpHdrExtsToOffer( 1004 static void FindRtpHdrExtsToOffer(
969 const RtpHeaderExtensions& reference_extensions, 1005 const RtpHeaderExtensions& reference_extensions,
970 RtpHeaderExtensions* offered_extensions, 1006 RtpHeaderExtensions* offered_extensions,
971 RtpHeaderExtensions* all_extensions, 1007 RtpHeaderExtensions* all_extensions,
972 UsedRtpHeaderExtensionIds* used_ids) { 1008 UsedRtpHeaderExtensionIds* used_ids) {
973 for (auto reference_extension : reference_extensions) { 1009 for (auto reference_extension : reference_extensions) {
974 if (!FindByUri(*offered_extensions, reference_extension, NULL)) { 1010 if (!FindByUri(*offered_extensions, reference_extension, NULL)) {
975 webrtc::RtpExtension existing; 1011 webrtc::RtpExtension existing;
976 if (FindByUri(*all_extensions, reference_extension, &existing)) { 1012 if (FindByUri(*all_extensions, reference_extension, &existing)) {
977 offered_extensions->push_back(existing); 1013 offered_extensions->push_back(existing);
978 } else { 1014 } else {
979 used_ids->FindAndSetIdUsed(&reference_extension); 1015 used_ids->FindAndSetIdUsed(&reference_extension);
980 all_extensions->push_back(reference_extension); 1016 all_extensions->push_back(reference_extension);
981 offered_extensions->push_back(reference_extension); 1017 offered_extensions->push_back(reference_extension);
982 } 1018 }
983 } 1019 }
984 } 1020 }
985 } 1021 }
986 1022
1023 static void AddEncryptedVersionsOfHdrExts(RtpHeaderExtensions* extensions,
1024 RtpHeaderExtensions* all_extensions,
1025 UsedRtpHeaderExtensionIds* used_ids) {
1026 RtpHeaderExtensions encrypted_extensions;
1027 for (const webrtc::RtpExtension& extension : *extensions) {
1028 webrtc::RtpExtension existing;
1029 // Don't add encrypted extensions again that were already included in a
1030 // previous offer or regular extensions that are also included as encrypted
1031 // extensions.
1032 if (extension.encrypt ||
1033 !webrtc::RtpExtension::IsEncryptionSupported(extension.uri) ||
1034 (FindByUriWithEncryptionPreference(*extensions, extension, true,
1035 &existing) && existing.encrypt)) {
1036 continue;
1037 }
1038
1039 if (FindByUri(*all_extensions, extension, &existing)) {
1040 encrypted_extensions.push_back(existing);
1041 } else {
1042 webrtc::RtpExtension encrypted(extension);
1043 encrypted.encrypt = true;
1044 used_ids->FindAndSetIdUsed(&encrypted);
1045 all_extensions->push_back(encrypted);
1046 encrypted_extensions.push_back(encrypted);
1047 }
1048 }
1049 extensions->insert(extensions->end(), encrypted_extensions.begin(),
1050 encrypted_extensions.end());
1051 }
1052
987 static void NegotiateRtpHeaderExtensions( 1053 static void NegotiateRtpHeaderExtensions(
988 const RtpHeaderExtensions& local_extensions, 1054 const RtpHeaderExtensions& local_extensions,
989 const RtpHeaderExtensions& offered_extensions, 1055 const RtpHeaderExtensions& offered_extensions,
1056 bool enable_encrypted_rtp_header_extensions,
990 RtpHeaderExtensions* negotiated_extenstions) { 1057 RtpHeaderExtensions* negotiated_extenstions) {
991 RtpHeaderExtensions::const_iterator ours; 1058 RtpHeaderExtensions::const_iterator ours;
992 for (ours = local_extensions.begin(); 1059 for (ours = local_extensions.begin();
993 ours != local_extensions.end(); ++ours) { 1060 ours != local_extensions.end(); ++ours) {
994 webrtc::RtpExtension theirs; 1061 webrtc::RtpExtension theirs;
995 if (FindByUri(offered_extensions, *ours, &theirs)) { 1062 if (FindByUriWithEncryptionPreference(offered_extensions, *ours,
1063 enable_encrypted_rtp_header_extensions, &theirs)) {
996 // We respond with their RTP header extension id. 1064 // We respond with their RTP header extension id.
997 negotiated_extenstions->push_back(theirs); 1065 negotiated_extenstions->push_back(theirs);
998 } 1066 }
999 } 1067 }
1000 } 1068 }
1001 1069
1002 static void StripCNCodecs(AudioCodecs* audio_codecs) { 1070 static void StripCNCodecs(AudioCodecs* audio_codecs) {
1003 AudioCodecs::iterator iter = audio_codecs->begin(); 1071 AudioCodecs::iterator iter = audio_codecs->begin();
1004 while (iter != audio_codecs->end()) { 1072 while (iter != audio_codecs->end()) {
1005 if (STR_CASE_CMP(iter->name.c_str(), kComfortNoiseCodecName) == 0) { 1073 if (STR_CASE_CMP(iter->name.c_str(), kComfortNoiseCodecName) == 0) {
(...skipping 14 matching lines...) Expand all
1020 // from the incoming session-initiate. If the negotiation fails, this 1088 // from the incoming session-initiate. If the negotiation fails, this
1021 // method returns false. The created content is added to the offer. 1089 // method returns false. The created content is added to the offer.
1022 template <class C> 1090 template <class C>
1023 static bool CreateMediaContentAnswer( 1091 static bool CreateMediaContentAnswer(
1024 const MediaContentDescriptionImpl<C>* offer, 1092 const MediaContentDescriptionImpl<C>* offer,
1025 const MediaSessionOptions& options, 1093 const MediaSessionOptions& options,
1026 const std::vector<C>& local_codecs, 1094 const std::vector<C>& local_codecs,
1027 const SecurePolicy& sdes_policy, 1095 const SecurePolicy& sdes_policy,
1028 const CryptoParamsVec* current_cryptos, 1096 const CryptoParamsVec* current_cryptos,
1029 const RtpHeaderExtensions& local_rtp_extenstions, 1097 const RtpHeaderExtensions& local_rtp_extenstions,
1098 bool enable_encrypted_rtp_header_extensions,
1030 StreamParamsVec* current_streams, 1099 StreamParamsVec* current_streams,
1031 bool add_legacy_stream, 1100 bool add_legacy_stream,
1032 bool bundle_enabled, 1101 bool bundle_enabled,
1033 MediaContentDescriptionImpl<C>* answer) { 1102 MediaContentDescriptionImpl<C>* answer) {
1034 std::vector<C> negotiated_codecs; 1103 std::vector<C> negotiated_codecs;
1035 NegotiateCodecs(local_codecs, offer->codecs(), &negotiated_codecs); 1104 NegotiateCodecs(local_codecs, offer->codecs(), &negotiated_codecs);
1036 answer->AddCodecs(negotiated_codecs); 1105 answer->AddCodecs(negotiated_codecs);
1037 answer->set_protocol(offer->protocol()); 1106 answer->set_protocol(offer->protocol());
1038 RtpHeaderExtensions negotiated_rtp_extensions; 1107 RtpHeaderExtensions negotiated_rtp_extensions;
1039 NegotiateRtpHeaderExtensions(local_rtp_extenstions, 1108 NegotiateRtpHeaderExtensions(local_rtp_extenstions,
1040 offer->rtp_header_extensions(), 1109 offer->rtp_header_extensions(),
1110 enable_encrypted_rtp_header_extensions,
1041 &negotiated_rtp_extensions); 1111 &negotiated_rtp_extensions);
1042 answer->set_rtp_header_extensions(negotiated_rtp_extensions); 1112 answer->set_rtp_header_extensions(negotiated_rtp_extensions);
1043 1113
1044 answer->set_rtcp_mux(options.rtcp_mux_enabled && offer->rtcp_mux()); 1114 answer->set_rtcp_mux(options.rtcp_mux_enabled && offer->rtcp_mux());
1045 if (answer->type() == cricket::MEDIA_TYPE_VIDEO) { 1115 if (answer->type() == cricket::MEDIA_TYPE_VIDEO) {
1046 answer->set_rtcp_reduced_size(offer->rtcp_reduced_size()); 1116 answer->set_rtcp_reduced_size(offer->rtcp_reduced_size());
1047 } 1117 }
1048 1118
1049 if (sdes_policy != SEC_DISABLED) { 1119 if (sdes_policy != SEC_DISABLED) {
1050 CryptoParams crypto; 1120 CryptoParams crypto;
(...skipping 518 matching lines...) Expand 10 before | Expand all | Expand 10 after
1569 &used_pltypes); 1639 &used_pltypes);
1570 } 1640 }
1571 1641
1572 void MediaSessionDescriptionFactory::GetRtpHdrExtsToOffer( 1642 void MediaSessionDescriptionFactory::GetRtpHdrExtsToOffer(
1573 const SessionDescription* current_description, 1643 const SessionDescription* current_description,
1574 RtpHeaderExtensions* audio_extensions, 1644 RtpHeaderExtensions* audio_extensions,
1575 RtpHeaderExtensions* video_extensions) const { 1645 RtpHeaderExtensions* video_extensions) const {
1576 // All header extensions allocated from the same range to avoid potential 1646 // All header extensions allocated from the same range to avoid potential
1577 // issues when using BUNDLE. 1647 // issues when using BUNDLE.
1578 UsedRtpHeaderExtensionIds used_ids; 1648 UsedRtpHeaderExtensionIds used_ids;
1579 RtpHeaderExtensions all_extensions; 1649 RtpHeaderExtensions all_regular_extensions;
1650 RtpHeaderExtensions all_encrypted_extensions;
1580 audio_extensions->clear(); 1651 audio_extensions->clear();
1581 video_extensions->clear(); 1652 video_extensions->clear();
1582 1653
1583 // First - get all extensions from the current description if the media type 1654 // First - get all extensions from the current description if the media type
1584 // is used. 1655 // is used.
1585 // Add them to |used_ids| so the local ids are not reused if a new media 1656 // Add them to |used_ids| so the local ids are not reused if a new media
1586 // type is added. 1657 // type is added.
1587 if (current_description) { 1658 if (current_description) {
1588 const AudioContentDescription* audio = 1659 const AudioContentDescription* audio =
1589 GetFirstAudioContentDescription(current_description); 1660 GetFirstAudioContentDescription(current_description);
1590 if (audio) { 1661 if (audio) {
1591 *audio_extensions = audio->rtp_header_extensions(); 1662 *audio_extensions = audio->rtp_header_extensions();
1592 FindAndSetRtpHdrExtUsed(audio_extensions, &all_extensions, &used_ids); 1663 FindAndSetRtpHdrExtUsed(audio_extensions, &all_regular_extensions,
1664 &all_encrypted_extensions, &used_ids);
1593 } 1665 }
1594 const VideoContentDescription* video = 1666 const VideoContentDescription* video =
1595 GetFirstVideoContentDescription(current_description); 1667 GetFirstVideoContentDescription(current_description);
1596 if (video) { 1668 if (video) {
1597 *video_extensions = video->rtp_header_extensions(); 1669 *video_extensions = video->rtp_header_extensions();
1598 FindAndSetRtpHdrExtUsed(video_extensions, &all_extensions, &used_ids); 1670 FindAndSetRtpHdrExtUsed(video_extensions, &all_regular_extensions,
1671 &all_encrypted_extensions, &used_ids);
1599 } 1672 }
1600 } 1673 }
1601 1674
1602 // Add our default RTP header extensions that are not in 1675 // Add our default RTP header extensions that are not in
1603 // |current_description|. 1676 // |current_description|.
1604 FindRtpHdrExtsToOffer(audio_rtp_header_extensions(), audio_extensions, 1677 FindRtpHdrExtsToOffer(audio_rtp_header_extensions(), audio_extensions,
1605 &all_extensions, &used_ids); 1678 &all_regular_extensions, &used_ids);
1606 FindRtpHdrExtsToOffer(video_rtp_header_extensions(), video_extensions, 1679 FindRtpHdrExtsToOffer(video_rtp_header_extensions(), video_extensions,
1607 &all_extensions, &used_ids); 1680 &all_regular_extensions, &used_ids);
1681 // TODO(jbauch): Support adding encrypted header extensions to existing
1682 // sessions.
1683 if (enable_encrypted_rtp_header_extensions_ && !current_description) {
1684 AddEncryptedVersionsOfHdrExts(audio_extensions, &all_encrypted_extensions,
1685 &used_ids);
1686 AddEncryptedVersionsOfHdrExts(video_extensions, &all_encrypted_extensions,
1687 &used_ids);
1688 }
1608 } 1689 }
1609 1690
1610 bool MediaSessionDescriptionFactory::AddTransportOffer( 1691 bool MediaSessionDescriptionFactory::AddTransportOffer(
1611 const std::string& content_name, 1692 const std::string& content_name,
1612 const TransportOptions& transport_options, 1693 const TransportOptions& transport_options,
1613 const SessionDescription* current_desc, 1694 const SessionDescription* current_desc,
1614 SessionDescription* offer_desc) const { 1695 SessionDescription* offer_desc) const {
1615 if (!transport_desc_factory_) 1696 if (!transport_desc_factory_)
1616 return false; 1697 return false;
1617 const TransportDescription* current_tdesc = 1698 const TransportDescription* current_tdesc =
(...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after
1871 // Do not require or create SDES cryptos if DTLS is used. 1952 // Do not require or create SDES cryptos if DTLS is used.
1872 cricket::SecurePolicy sdes_policy = 1953 cricket::SecurePolicy sdes_policy =
1873 audio_transport->secure() ? cricket::SEC_DISABLED : secure(); 1954 audio_transport->secure() ? cricket::SEC_DISABLED : secure();
1874 if (!CreateMediaContentAnswer( 1955 if (!CreateMediaContentAnswer(
1875 offer_audio, 1956 offer_audio,
1876 options, 1957 options,
1877 audio_codecs, 1958 audio_codecs,
1878 sdes_policy, 1959 sdes_policy,
1879 GetCryptos(GetFirstAudioContentDescription(current_description)), 1960 GetCryptos(GetFirstAudioContentDescription(current_description)),
1880 audio_rtp_extensions_, 1961 audio_rtp_extensions_,
1962 enable_encrypted_rtp_header_extensions_,
1881 current_streams, 1963 current_streams,
1882 add_legacy_, 1964 add_legacy_,
1883 bundle_enabled, 1965 bundle_enabled,
1884 audio_answer.get())) { 1966 audio_answer.get())) {
1885 return false; // Fails the session setup. 1967 return false; // Fails the session setup.
1886 } 1968 }
1887 1969
1888 bool secure = bundle_transport ? bundle_transport->description.secure() 1970 bool secure = bundle_transport ? bundle_transport->description.secure()
1889 : audio_transport->secure(); 1971 : audio_transport->secure();
1890 bool rejected = !options.has_audio() || audio_content->rejected || 1972 bool rejected = !options.has_audio() || audio_content->rejected ||
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
1927 bool bundle_enabled = 2009 bool bundle_enabled =
1928 offer->HasGroup(GROUP_TYPE_BUNDLE) && options.bundle_enabled; 2010 offer->HasGroup(GROUP_TYPE_BUNDLE) && options.bundle_enabled;
1929 if (!CreateMediaContentAnswer( 2011 if (!CreateMediaContentAnswer(
1930 static_cast<const VideoContentDescription*>( 2012 static_cast<const VideoContentDescription*>(
1931 video_content->description), 2013 video_content->description),
1932 options, 2014 options,
1933 video_codecs_, 2015 video_codecs_,
1934 sdes_policy, 2016 sdes_policy,
1935 GetCryptos(GetFirstVideoContentDescription(current_description)), 2017 GetCryptos(GetFirstVideoContentDescription(current_description)),
1936 video_rtp_extensions_, 2018 video_rtp_extensions_,
2019 enable_encrypted_rtp_header_extensions_,
1937 current_streams, 2020 current_streams,
1938 add_legacy_, 2021 add_legacy_,
1939 bundle_enabled, 2022 bundle_enabled,
1940 video_answer.get())) { 2023 video_answer.get())) {
1941 return false; 2024 return false;
1942 } 2025 }
1943 bool secure = bundle_transport ? bundle_transport->description.secure() 2026 bool secure = bundle_transport ? bundle_transport->description.secure()
1944 : video_transport->secure(); 2027 : video_transport->secure();
1945 bool rejected = !options.has_video() || video_content->rejected || 2028 bool rejected = !options.has_video() || video_content->rejected ||
1946 !IsMediaProtocolSupported(MEDIA_TYPE_VIDEO, 2029 !IsMediaProtocolSupported(MEDIA_TYPE_VIDEO,
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
1988 bool bundle_enabled = 2071 bool bundle_enabled =
1989 offer->HasGroup(GROUP_TYPE_BUNDLE) && options.bundle_enabled; 2072 offer->HasGroup(GROUP_TYPE_BUNDLE) && options.bundle_enabled;
1990 if (!CreateMediaContentAnswer( 2073 if (!CreateMediaContentAnswer(
1991 static_cast<const DataContentDescription*>( 2074 static_cast<const DataContentDescription*>(
1992 data_content->description), 2075 data_content->description),
1993 options, 2076 options,
1994 data_codecs_, 2077 data_codecs_,
1995 sdes_policy, 2078 sdes_policy,
1996 GetCryptos(GetFirstDataContentDescription(current_description)), 2079 GetCryptos(GetFirstDataContentDescription(current_description)),
1997 RtpHeaderExtensions(), 2080 RtpHeaderExtensions(),
2081 enable_encrypted_rtp_header_extensions_,
1998 current_streams, 2082 current_streams,
1999 add_legacy_, 2083 add_legacy_,
2000 bundle_enabled, 2084 bundle_enabled,
2001 data_answer.get())) { 2085 data_answer.get())) {
2002 return false; // Fails the session setup. 2086 return false; // Fails the session setup.
2003 } 2087 }
2004 2088
2005 // Respond with sctpmap if the offer uses sctpmap. 2089 // Respond with sctpmap if the offer uses sctpmap.
2006 const DataContentDescription* offer_data_description = 2090 const DataContentDescription* offer_data_description =
2007 static_cast<const DataContentDescription*>(data_content->description); 2091 static_cast<const DataContentDescription*>(data_content->description);
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after
2183 GetFirstMediaContentDescription(sdesc, MEDIA_TYPE_VIDEO)); 2267 GetFirstMediaContentDescription(sdesc, MEDIA_TYPE_VIDEO));
2184 } 2268 }
2185 2269
2186 DataContentDescription* GetFirstDataContentDescription( 2270 DataContentDescription* GetFirstDataContentDescription(
2187 SessionDescription* sdesc) { 2271 SessionDescription* sdesc) {
2188 return static_cast<DataContentDescription*>( 2272 return static_cast<DataContentDescription*>(
2189 GetFirstMediaContentDescription(sdesc, MEDIA_TYPE_DATA)); 2273 GetFirstMediaContentDescription(sdesc, MEDIA_TYPE_DATA));
2190 } 2274 }
2191 2275
2192 } // namespace cricket 2276 } // namespace cricket
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698