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

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

Issue 1956343002: Initial asymmetric codec support in MediaSessionDescription (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Added RtpTranscieverDirection; removed old set_audio_codecs. Created 4 years, 6 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
« no previous file with comments | « webrtc/pc/mediasession.h ('k') | webrtc/pc/mediasession_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
43 func(&crypto_suites); 43 func(&crypto_suites);
44 for (const auto crypto : crypto_suites) { 44 for (const auto crypto : crypto_suites) {
45 names->push_back(rtc::SrtpCryptoSuiteToName(crypto)); 45 names->push_back(rtc::SrtpCryptoSuiteToName(crypto));
46 } 46 }
47 #endif 47 #endif
48 } 48 }
49 } // namespace 49 } // namespace
50 50
51 namespace cricket { 51 namespace cricket {
52 52
53
54 // RTP Profile names 53 // RTP Profile names
55 // http://www.iana.org/assignments/rtp-parameters/rtp-parameters.xml 54 // http://www.iana.org/assignments/rtp-parameters/rtp-parameters.xml
56 // RFC4585 55 // RFC4585
57 const char kMediaProtocolAvpf[] = "RTP/AVPF"; 56 const char kMediaProtocolAvpf[] = "RTP/AVPF";
58 // RFC5124 57 // RFC5124
59 const char kMediaProtocolDtlsSavpf[] = "UDP/TLS/RTP/SAVPF"; 58 const char kMediaProtocolDtlsSavpf[] = "UDP/TLS/RTP/SAVPF";
60 59
61 // We always generate offers with "UDP/TLS/RTP/SAVPF" when using DTLS-SRTP, 60 // We always generate offers with "UDP/TLS/RTP/SAVPF" when using DTLS-SRTP,
62 // but we tolerate "RTP/SAVPF" in offers we receive, for compatibility. 61 // but we tolerate "RTP/SAVPF" in offers we receive, for compatibility.
63 const char kMediaProtocolSavpf[] = "RTP/SAVPF"; 62 const char kMediaProtocolSavpf[] = "RTP/SAVPF";
64 63
65 const char kMediaProtocolRtpPrefix[] = "RTP/"; 64 const char kMediaProtocolRtpPrefix[] = "RTP/";
66 65
67 const char kMediaProtocolSctp[] = "SCTP"; 66 const char kMediaProtocolSctp[] = "SCTP";
68 const char kMediaProtocolDtlsSctp[] = "DTLS/SCTP"; 67 const char kMediaProtocolDtlsSctp[] = "DTLS/SCTP";
69 const char kMediaProtocolUdpDtlsSctp[] = "UDP/DTLS/SCTP"; 68 const char kMediaProtocolUdpDtlsSctp[] = "UDP/DTLS/SCTP";
70 const char kMediaProtocolTcpDtlsSctp[] = "TCP/DTLS/SCTP"; 69 const char kMediaProtocolTcpDtlsSctp[] = "TCP/DTLS/SCTP";
71 70
71 RtpTransceiverDirection RtpTransceiverDirection::FromMediaContentDirection(
72 MediaContentDirection md) {
73 const bool send = (md == MD_SENDRECV || md == MD_SENDONLY);
74 const bool recv = (md == MD_SENDRECV || md == MD_RECVONLY);
75 return RtpTransceiverDirection(send, recv);
76 }
77
78 MediaContentDirection RtpTransceiverDirection::ToMediaContentDirection() const {
79 if (send && recv)
80 return MD_SENDRECV;
81 if (send)
82 return MD_SENDONLY;
83 if (recv)
84 return MD_RECVONLY;
85
86 return MD_INACTIVE;
87 }
88
89 RtpTransceiverDirection
90 NegotiateRtpTransceiverDirection(RtpTransceiverDirection offer,
91 RtpTransceiverDirection wants) {
92 return RtpTransceiverDirection(offer.recv && wants.send,
ossu 2016/06/02 13:28:02 offer and wants mirror each other here: if the off
pthatcher1 2016/06/02 22:29:17 Ah, yes. You are correct. I forgot about that.
93 offer.send && wants.recv);
94 }
95
72 static bool IsMediaContentOfType(const ContentInfo* content, 96 static bool IsMediaContentOfType(const ContentInfo* content,
73 MediaType media_type) { 97 MediaType media_type) {
74 if (!IsMediaContent(content)) { 98 if (!IsMediaContent(content)) {
75 return false; 99 return false;
76 } 100 }
77 101
78 const MediaContentDescription* mdesc = 102 const MediaContentDescription* mdesc =
79 static_cast<const MediaContentDescription*>(content->description); 103 static_cast<const MediaContentDescription*>(content->description);
80 return mdesc && mdesc->type() == media_type; 104 return mdesc && mdesc->type() == media_type;
81 } 105 }
(...skipping 941 matching lines...) Expand 10 before | Expand all | Expand 10 after
1023 return false; 1047 return false;
1024 } 1048 }
1025 1049
1026 if (!AddStreamParams(answer->type(), options, current_streams, answer, 1050 if (!AddStreamParams(answer->type(), options, current_streams, answer,
1027 add_legacy_stream)) { 1051 add_legacy_stream)) {
1028 return false; // Something went seriously wrong. 1052 return false; // Something went seriously wrong.
1029 } 1053 }
1030 1054
1031 // Make sure the answer media content direction is per default set as 1055 // Make sure the answer media content direction is per default set as
1032 // described in RFC3264 section 6.1. 1056 // described in RFC3264 section 6.1.
1033 switch (offer->direction()) { 1057 const bool is_data = !IsRtpProtocol(answer->protocol());
1034 case MD_INACTIVE: 1058 const bool has_send_streams = !answer->streams().empty();
1035 answer->set_direction(MD_INACTIVE); 1059 const bool wants_send = has_send_streams || is_data;
1036 break; 1060 const bool recv_audio =
1037 case MD_SENDONLY: 1061 answer->type() == cricket::MEDIA_TYPE_AUDIO && options.recv_audio;
1038 answer->set_direction(MD_RECVONLY); 1062 const bool recv_video =
1039 break; 1063 answer->type() == cricket::MEDIA_TYPE_VIDEO && options.recv_video;
1040 case MD_RECVONLY: 1064 const bool recv_data =
1041 answer->set_direction(IsRtpProtocol(answer->protocol()) && 1065 answer->type() == cricket::MEDIA_TYPE_DATA;
1042 answer->streams().empty() 1066 const bool wants_receive = recv_audio || recv_video || recv_data;
1043 ? MD_INACTIVE
1044 : MD_SENDONLY);
1045 break;
1046 case MD_SENDRECV:
1047 answer->set_direction(IsRtpProtocol(answer->protocol()) &&
1048 answer->streams().empty()
1049 ? MD_RECVONLY
1050 : MD_SENDRECV);
1051 break;
1052 default:
1053 RTC_DCHECK(false && "MediaContentDescription has unexpected direction.");
1054 break;
1055 }
1056 1067
1068 auto offer_rtd =
1069 RtpTransceiverDirection::FromMediaContentDirection(offer->direction());
1070 auto wants_rtd = RtpTransceiverDirection(wants_send, wants_receive);
1071 answer->set_direction(NegotiateRtpTransceiverDirection(offer_rtd, wants_rtd)
1072 .ToMediaContentDirection());
1057 return true; 1073 return true;
1058 } 1074 }
1059 1075
1060 static bool IsDtlsRtp(const std::string& protocol) { 1076 static bool IsDtlsRtp(const std::string& protocol) {
1061 // Most-likely values first. 1077 // Most-likely values first.
1062 return protocol == "UDP/TLS/RTP/SAVPF" || protocol == "TCP/TLS/RTP/SAVPF" || 1078 return protocol == "UDP/TLS/RTP/SAVPF" || protocol == "TCP/TLS/RTP/SAVPF" ||
1063 protocol == "UDP/TLS/RTP/SAVP" || protocol == "TCP/TLS/RTP/SAVP"; 1079 protocol == "UDP/TLS/RTP/SAVP" || protocol == "TCP/TLS/RTP/SAVP";
1064 } 1080 }
1065 1081
1066 static bool IsPlainRtp(const std::string& protocol) { 1082 static bool IsPlainRtp(const std::string& protocol) {
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
1166 case MEDIA_TYPE_DATA: 1182 case MEDIA_TYPE_DATA:
1167 type_str = "data"; 1183 type_str = "data";
1168 break; 1184 break;
1169 default: 1185 default:
1170 ASSERT(false); 1186 ASSERT(false);
1171 break; 1187 break;
1172 } 1188 }
1173 return type_str; 1189 return type_str;
1174 } 1190 }
1175 1191
1192 std::string MediaContentDirectionToString(MediaContentDirection direction) {
1193 switch (direction) {
1194 case MD_INACTIVE:
1195 return "inactive";
1196 case MD_SENDONLY:
1197 return "sendonly";
1198 case MD_RECVONLY:
1199 return "recvonly";
1200 case MD_SENDRECV:
1201 return "sendrecv";
1202 default:
1203 ASSERT(false);
1204 break;
1205 }
1206 }
1207
1176 void MediaSessionOptions::AddSendStream(MediaType type, 1208 void MediaSessionOptions::AddSendStream(MediaType type,
1177 const std::string& id, 1209 const std::string& id,
1178 const std::string& sync_label) { 1210 const std::string& sync_label) {
1179 AddSendStreamInternal(type, id, sync_label, 1); 1211 AddSendStreamInternal(type, id, sync_label, 1);
1180 } 1212 }
1181 1213
1182 void MediaSessionOptions::AddSendVideoStream( 1214 void MediaSessionOptions::AddSendVideoStream(
1183 const std::string& id, 1215 const std::string& id,
1184 const std::string& sync_label, 1216 const std::string& sync_label,
1185 int num_sim_layers) { 1217 int num_sim_layers) {
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
1227 add_legacy_(true), 1259 add_legacy_(true),
1228 transport_desc_factory_(transport_desc_factory) { 1260 transport_desc_factory_(transport_desc_factory) {
1229 } 1261 }
1230 1262
1231 MediaSessionDescriptionFactory::MediaSessionDescriptionFactory( 1263 MediaSessionDescriptionFactory::MediaSessionDescriptionFactory(
1232 ChannelManager* channel_manager, 1264 ChannelManager* channel_manager,
1233 const TransportDescriptionFactory* transport_desc_factory) 1265 const TransportDescriptionFactory* transport_desc_factory)
1234 : secure_(SEC_DISABLED), 1266 : secure_(SEC_DISABLED),
1235 add_legacy_(true), 1267 add_legacy_(true),
1236 transport_desc_factory_(transport_desc_factory) { 1268 transport_desc_factory_(transport_desc_factory) {
1237 channel_manager->GetSupportedAudioCodecs(&audio_codecs_); 1269 channel_manager->GetSupportedAudioCodecs(&audio_sendrecv_codecs_);
1238 channel_manager->GetSupportedAudioRtpHeaderExtensions(&audio_rtp_extensions_); 1270 channel_manager->GetSupportedAudioRtpHeaderExtensions(&audio_rtp_extensions_);
1239 channel_manager->GetSupportedVideoCodecs(&video_codecs_); 1271 channel_manager->GetSupportedVideoCodecs(&video_codecs_);
1240 channel_manager->GetSupportedVideoRtpHeaderExtensions(&video_rtp_extensions_); 1272 channel_manager->GetSupportedVideoRtpHeaderExtensions(&video_rtp_extensions_);
1241 channel_manager->GetSupportedDataCodecs(&data_codecs_); 1273 channel_manager->GetSupportedDataCodecs(&data_codecs_);
1274 audio_send_codecs_ = audio_sendrecv_codecs_;
1275 audio_recv_codecs_ = audio_sendrecv_codecs_;
1276 }
1277
1278 const AudioCodecs& MediaSessionDescriptionFactory::audio_codecs() const {
1279 return audio_sendrecv_codecs_;
1280 }
1281
1282 const AudioCodecs& MediaSessionDescriptionFactory::audio_send_codecs() const {
1283 return audio_send_codecs_;
1284 }
1285
1286 const AudioCodecs& MediaSessionDescriptionFactory::audio_recv_codecs() const {
1287 return audio_recv_codecs_;
1288 }
1289
1290 void MediaSessionDescriptionFactory::set_audio_codecs(
1291 const AudioCodecs& send_codecs, const AudioCodecs& recv_codecs) {
1292 audio_send_codecs_ = send_codecs;
1293 audio_recv_codecs_ = recv_codecs;
1294 audio_sendrecv_codecs_.clear();
1295
1296 // Intersect the two lists of codecs, preserving the order of the send codecs.
1297 // If there's any difference in priorities, chances are encoding is more
1298 // expensive than decoding, and high-priority send codecs are likely handled
1299 // better (e.g. through hardware encoder support) than low-priority ones.
1300 // TODO(ossu): This is O(n^2). However, each list should generally be small
1301 // enough for this to not be a problem. They are also nicely local in memory
1302 // like this.
1303 for (const auto& sc : audio_send_codecs_) {
1304 for (const auto& rc : audio_recv_codecs_) {
1305 const size_t send_channels = (sc.channels == 0) ? 1 : sc.channels;
1306 const size_t recv_channels = (rc.channels == 0) ? 1 : rc.channels;
1307 if (sc.clockrate == rc.clockrate &&
1308 sc.bitrate == rc.bitrate &&
1309 send_channels == recv_channels &&
1310 (_stricmp(sc.name.c_str(), rc.name.c_str()) == 0) &&
1311 sc.params == rc.params &&
1312 sc.feedback_params == rc.feedback_params) {
1313 AudioCodec out_codec = sc;
1314 out_codec.channels = send_channels;
1315 audio_sendrecv_codecs_.push_back(out_codec);
1316 break;
1317 }
1318 }
1319 }
1242 } 1320 }
1243 1321
1244 SessionDescription* MediaSessionDescriptionFactory::CreateOffer( 1322 SessionDescription* MediaSessionDescriptionFactory::CreateOffer(
1245 const MediaSessionOptions& options, 1323 const MediaSessionOptions& options,
1246 const SessionDescription* current_description) const { 1324 const SessionDescription* current_description) const {
1247 std::unique_ptr<SessionDescription> offer(new SessionDescription()); 1325 std::unique_ptr<SessionDescription> offer(new SessionDescription());
1248 1326
1249 StreamParamsVec current_streams; 1327 StreamParamsVec current_streams;
1250 GetCurrentStreamParams(current_description, &current_streams); 1328 GetCurrentStreamParams(current_description, &current_streams);
1251 1329
1330 const bool wants_send =
1331 options.HasSendMediaStream(MEDIA_TYPE_AUDIO) || add_legacy_;
1332 const AudioCodecs& supported_audio_codecs =
1333 GetAudioCodecsForDirection({wants_send, options.recv_audio});
1334
1252 AudioCodecs audio_codecs; 1335 AudioCodecs audio_codecs;
1253 VideoCodecs video_codecs; 1336 VideoCodecs video_codecs;
1254 DataCodecs data_codecs; 1337 DataCodecs data_codecs;
1255 GetCodecsToOffer(current_description, &audio_codecs, &video_codecs, 1338 GetCodecsToOffer(current_description, supported_audio_codecs,
1256 &data_codecs); 1339 video_codecs_, data_codecs_,
1340 &audio_codecs, &video_codecs, &data_codecs);
1257 1341
1258 if (!options.vad_enabled) { 1342 if (!options.vad_enabled) {
1259 // If application doesn't want CN codecs in offer. 1343 // If application doesn't want CN codecs in offer.
1260 StripCNCodecs(&audio_codecs); 1344 StripCNCodecs(&audio_codecs);
1261 } 1345 }
1262 1346
1263 RtpHeaderExtensions audio_rtp_extensions; 1347 RtpHeaderExtensions audio_rtp_extensions;
1264 RtpHeaderExtensions video_rtp_extensions; 1348 RtpHeaderExtensions video_rtp_extensions;
1265 GetRtpHdrExtsToOffer(current_description, &audio_rtp_extensions, 1349 GetRtpHdrExtsToOffer(current_description, &audio_rtp_extensions,
1266 &video_rtp_extensions); 1350 &video_rtp_extensions);
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after
1405 if (!UpdateCryptoParamsForBundle(answer_bundle, answer.get())) { 1489 if (!UpdateCryptoParamsForBundle(answer_bundle, answer.get())) {
1406 LOG(LS_ERROR) << "CreateAnswer failed to UpdateCryptoParamsForBundle."; 1490 LOG(LS_ERROR) << "CreateAnswer failed to UpdateCryptoParamsForBundle.";
1407 return NULL; 1491 return NULL;
1408 } 1492 }
1409 } 1493 }
1410 } 1494 }
1411 1495
1412 return answer.release(); 1496 return answer.release();
1413 } 1497 }
1414 1498
1499 const AudioCodecs& MediaSessionDescriptionFactory::GetAudioCodecsForDirection(
1500 const RtpTransceiverDirection& direction) const {
1501 // If stream is inactive - generate list as if sendrecv.
1502 // See RFC 3264 Section 6.1.
1503 if (direction.send == direction.recv)
1504 return audio_sendrecv_codecs_;
1505 else if (direction.send)
1506 return audio_send_codecs_;
1507 else
1508 return audio_recv_codecs_;
1509 }
1510
1415 void MediaSessionDescriptionFactory::GetCodecsToOffer( 1511 void MediaSessionDescriptionFactory::GetCodecsToOffer(
1416 const SessionDescription* current_description, 1512 const SessionDescription* current_description,
1513 const AudioCodecs& supported_audio_codecs,
1514 const VideoCodecs& supported_video_codecs,
1515 const DataCodecs& supported_data_codecs,
1417 AudioCodecs* audio_codecs, 1516 AudioCodecs* audio_codecs,
1418 VideoCodecs* video_codecs, 1517 VideoCodecs* video_codecs,
1419 DataCodecs* data_codecs) const { 1518 DataCodecs* data_codecs) const {
1420 UsedPayloadTypes used_pltypes; 1519 UsedPayloadTypes used_pltypes;
1421 audio_codecs->clear(); 1520 audio_codecs->clear();
1422 video_codecs->clear(); 1521 video_codecs->clear();
1423 data_codecs->clear(); 1522 data_codecs->clear();
1424 1523
1425 1524
1426 // First - get all codecs from the current description if the media type 1525 // First - get all codecs from the current description if the media type
(...skipping 15 matching lines...) Expand all
1442 } 1541 }
1443 const DataContentDescription* data = 1542 const DataContentDescription* data =
1444 GetFirstDataContentDescription(current_description); 1543 GetFirstDataContentDescription(current_description);
1445 if (data) { 1544 if (data) {
1446 *data_codecs = data->codecs(); 1545 *data_codecs = data->codecs();
1447 used_pltypes.FindAndSetIdUsed<DataCodec>(data_codecs); 1546 used_pltypes.FindAndSetIdUsed<DataCodec>(data_codecs);
1448 } 1547 }
1449 } 1548 }
1450 1549
1451 // Add our codecs that are not in |current_description|. 1550 // Add our codecs that are not in |current_description|.
1452 FindCodecsToOffer<AudioCodec>(audio_codecs_, audio_codecs, &used_pltypes); 1551 FindCodecsToOffer<AudioCodec>(supported_audio_codecs, audio_codecs,
1453 FindCodecsToOffer<VideoCodec>(video_codecs_, video_codecs, &used_pltypes); 1552 &used_pltypes);
1454 FindCodecsToOffer<DataCodec>(data_codecs_, data_codecs, &used_pltypes); 1553 FindCodecsToOffer<VideoCodec>(supported_video_codecs, video_codecs,
1554 &used_pltypes);
1555 FindCodecsToOffer<DataCodec>(supported_data_codecs, data_codecs,
1556 &used_pltypes);
1455 } 1557 }
1456 1558
1457 void MediaSessionDescriptionFactory::GetRtpHdrExtsToOffer( 1559 void MediaSessionDescriptionFactory::GetRtpHdrExtsToOffer(
1458 const SessionDescription* current_description, 1560 const SessionDescription* current_description,
1459 RtpHeaderExtensions* audio_extensions, 1561 RtpHeaderExtensions* audio_extensions,
1460 RtpHeaderExtensions* video_extensions) const { 1562 RtpHeaderExtensions* video_extensions) const {
1461 // All header extensions allocated from the same range to avoid potential 1563 // All header extensions allocated from the same range to avoid potential
1462 // issues when using BUNDLE. 1564 // issues when using BUNDLE.
1463 UsedRtpHeaderExtensionIds used_ids; 1565 UsedRtpHeaderExtensionIds used_ids;
1464 RtpHeaderExtensions all_extensions; 1566 RtpHeaderExtensions all_extensions;
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
1570 add_legacy_, 1672 add_legacy_,
1571 current_streams, 1673 current_streams,
1572 audio.get())) { 1674 audio.get())) {
1573 return false; 1675 return false;
1574 } 1676 }
1575 audio->set_lang(lang_); 1677 audio->set_lang(lang_);
1576 1678
1577 bool secure_transport = (transport_desc_factory_->secure() != SEC_DISABLED); 1679 bool secure_transport = (transport_desc_factory_->secure() != SEC_DISABLED);
1578 SetMediaProtocol(secure_transport, audio.get()); 1680 SetMediaProtocol(secure_transport, audio.get());
1579 1681
1580 if (!audio->streams().empty()) { 1682 auto offer_rtd =
1581 if (options.recv_audio) { 1683 RtpTransceiverDirection(!audio->streams().empty(), options.recv_audio);
1582 audio->set_direction(MD_SENDRECV); 1684 audio->set_direction(offer_rtd.ToMediaContentDirection());
1583 } else {
1584 audio->set_direction(MD_SENDONLY);
1585 }
1586 } else {
1587 if (options.recv_audio) {
1588 audio->set_direction(MD_RECVONLY);
1589 } else {
1590 audio->set_direction(MD_INACTIVE);
1591 }
1592 }
1593 1685
1594 desc->AddContent(content_name, NS_JINGLE_RTP, audio.release()); 1686 desc->AddContent(content_name, NS_JINGLE_RTP, audio.release());
1595 if (!AddTransportOffer(content_name, 1687 if (!AddTransportOffer(content_name,
1596 GetTransportOptions(options, content_name), 1688 GetTransportOptions(options, content_name),
1597 current_description, desc)) { 1689 current_description, desc)) {
1598 return false; 1690 return false;
1599 } 1691 }
1600 1692
1601 return true; 1693 return true;
1602 } 1694 }
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
1726 return true; 1818 return true;
1727 } 1819 }
1728 1820
1729 bool MediaSessionDescriptionFactory::AddAudioContentForAnswer( 1821 bool MediaSessionDescriptionFactory::AddAudioContentForAnswer(
1730 const SessionDescription* offer, 1822 const SessionDescription* offer,
1731 const MediaSessionOptions& options, 1823 const MediaSessionOptions& options,
1732 const SessionDescription* current_description, 1824 const SessionDescription* current_description,
1733 StreamParamsVec* current_streams, 1825 StreamParamsVec* current_streams,
1734 SessionDescription* answer) const { 1826 SessionDescription* answer) const {
1735 const ContentInfo* audio_content = GetFirstAudioContent(offer); 1827 const ContentInfo* audio_content = GetFirstAudioContent(offer);
1828 const AudioContentDescription* offer_audio =
1829 static_cast<const AudioContentDescription*>(audio_content->description);
1736 1830
1737 std::unique_ptr<TransportDescription> audio_transport(CreateTransportAnswer( 1831 std::unique_ptr<TransportDescription> audio_transport(CreateTransportAnswer(
1738 audio_content->name, offer, 1832 audio_content->name, offer,
1739 GetTransportOptions(options, audio_content->name), current_description)); 1833 GetTransportOptions(options, audio_content->name), current_description));
1740 if (!audio_transport) { 1834 if (!audio_transport) {
1741 return false; 1835 return false;
1742 } 1836 }
1743 1837
1744 AudioCodecs audio_codecs = audio_codecs_; 1838 // Pick codecs based on the requested communications direction in the offer.
1839 const bool wants_send =
1840 options.HasSendMediaStream(MEDIA_TYPE_AUDIO) || add_legacy_;
1841 auto wants_rtd = RtpTransceiverDirection(wants_send, options.recv_audio);
1842 auto offer_rtd =
1843 RtpTransceiverDirection::FromMediaContentDirection(
1844 offer_audio->direction());
1845 auto answer_rtd = NegotiateRtpTransceiverDirection(offer_rtd, wants_rtd);
1846 AudioCodecs audio_codecs = GetAudioCodecsForDirection(answer_rtd);
1745 if (!options.vad_enabled) { 1847 if (!options.vad_enabled) {
1746 StripCNCodecs(&audio_codecs); 1848 StripCNCodecs(&audio_codecs);
1747 } 1849 }
1748 1850
1749 bool bundle_enabled = 1851 bool bundle_enabled =
1750 offer->HasGroup(GROUP_TYPE_BUNDLE) && options.bundle_enabled; 1852 offer->HasGroup(GROUP_TYPE_BUNDLE) && options.bundle_enabled;
1751 std::unique_ptr<AudioContentDescription> audio_answer( 1853 std::unique_ptr<AudioContentDescription> audio_answer(
1752 new AudioContentDescription()); 1854 new AudioContentDescription());
1753 // Do not require or create SDES cryptos if DTLS is used. 1855 // Do not require or create SDES cryptos if DTLS is used.
1754 cricket::SecurePolicy sdes_policy = 1856 cricket::SecurePolicy sdes_policy =
1755 audio_transport->secure() ? cricket::SEC_DISABLED : secure(); 1857 audio_transport->secure() ? cricket::SEC_DISABLED : secure();
1756 if (!CreateMediaContentAnswer( 1858 if (!CreateMediaContentAnswer(
1757 static_cast<const AudioContentDescription*>( 1859 offer_audio,
1758 audio_content->description),
1759 options, 1860 options,
1760 audio_codecs, 1861 audio_codecs,
1761 sdes_policy, 1862 sdes_policy,
1762 GetCryptos(GetFirstAudioContentDescription(current_description)), 1863 GetCryptos(GetFirstAudioContentDescription(current_description)),
1763 audio_rtp_extensions_, 1864 audio_rtp_extensions_,
1764 current_streams, 1865 current_streams,
1765 add_legacy_, 1866 add_legacy_,
1766 bundle_enabled, 1867 bundle_enabled,
1767 audio_answer.get())) { 1868 audio_answer.get())) {
1768 return false; // Fails the session setup. 1869 return false; // Fails the session setup.
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after
1980 GetFirstMediaContentDescription(sdesc, MEDIA_TYPE_VIDEO)); 2081 GetFirstMediaContentDescription(sdesc, MEDIA_TYPE_VIDEO));
1981 } 2082 }
1982 2083
1983 const DataContentDescription* GetFirstDataContentDescription( 2084 const DataContentDescription* GetFirstDataContentDescription(
1984 const SessionDescription* sdesc) { 2085 const SessionDescription* sdesc) {
1985 return static_cast<const DataContentDescription*>( 2086 return static_cast<const DataContentDescription*>(
1986 GetFirstMediaContentDescription(sdesc, MEDIA_TYPE_DATA)); 2087 GetFirstMediaContentDescription(sdesc, MEDIA_TYPE_DATA));
1987 } 2088 }
1988 2089
1989 } // namespace cricket 2090 } // namespace cricket
OLDNEW
« no previous file with comments | « webrtc/pc/mediasession.h ('k') | webrtc/pc/mediasession_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698