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

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: More intense testing! 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 1012 matching lines...) Expand 10 before | Expand all | Expand 10 after
1023 return false; 1023 return false;
1024 } 1024 }
1025 1025
1026 if (!AddStreamParams(answer->type(), options, current_streams, answer, 1026 if (!AddStreamParams(answer->type(), options, current_streams, answer,
1027 add_legacy_stream)) { 1027 add_legacy_stream)) {
1028 return false; // Something went seriously wrong. 1028 return false; // Something went seriously wrong.
1029 } 1029 }
1030 1030
1031 // Make sure the answer media content direction is per default set as 1031 // Make sure the answer media content direction is per default set as
1032 // described in RFC3264 section 6.1. 1032 // described in RFC3264 section 6.1.
1033 const bool should_send =
1034 !IsRtpProtocol(answer->protocol()) || !answer->streams().empty();
1035
1033 switch (offer->direction()) { 1036 switch (offer->direction()) {
1034 case MD_INACTIVE: 1037 case MD_INACTIVE:
1035 answer->set_direction(MD_INACTIVE); 1038 answer->set_direction(MD_INACTIVE);
1036 break; 1039 break;
1037 case MD_SENDONLY: 1040 case MD_SENDONLY:
1038 answer->set_direction(MD_RECVONLY); 1041 answer->set_direction(options.recv_audio ? MD_RECVONLY : MD_INACTIVE);
ossu 2016/05/25 11:15:06 This is clearly wrong: it should only check recv_a
1039 break; 1042 break;
1040 case MD_RECVONLY: 1043 case MD_RECVONLY:
1041 answer->set_direction(IsRtpProtocol(answer->protocol()) && 1044 answer->set_direction(should_send ? MD_SENDONLY : MD_INACTIVE);
1042 answer->streams().empty()
1043 ? MD_INACTIVE
1044 : MD_SENDONLY);
1045 break; 1045 break;
1046 case MD_SENDRECV: 1046 case MD_SENDRECV:
1047 answer->set_direction(IsRtpProtocol(answer->protocol()) && 1047 answer->set_direction(should_send
1048 answer->streams().empty() 1048 ? (options.recv_audio ? MD_SENDRECV : MD_SENDONLY)
1049 ? MD_RECVONLY 1049 : (options.recv_audio ? MD_RECVONLY : MD_INACTIVE));
1050 : MD_SENDRECV);
1051 break; 1050 break;
1052 default: 1051 default:
1053 RTC_DCHECK(false && "MediaContentDescription has unexpected direction."); 1052 RTC_DCHECK(false && "MediaContentDescription has unexpected direction.");
1054 break; 1053 break;
1055 } 1054 }
1056 1055
1057 return true; 1056 return true;
1058 } 1057 }
1059 1058
1060 static bool IsDtlsRtp(const std::string& protocol) { 1059 static bool IsDtlsRtp(const std::string& protocol) {
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
1166 case MEDIA_TYPE_DATA: 1165 case MEDIA_TYPE_DATA:
1167 type_str = "data"; 1166 type_str = "data";
1168 break; 1167 break;
1169 default: 1168 default:
1170 ASSERT(false); 1169 ASSERT(false);
1171 break; 1170 break;
1172 } 1171 }
1173 return type_str; 1172 return type_str;
1174 } 1173 }
1175 1174
1175 std::string MediaContentDirectionToString(MediaContentDirection direction) {
1176 switch (direction) {
1177 case MD_INACTIVE:
1178 return "inactive";
1179 case MD_SENDONLY:
1180 return "sendonly";
1181 case MD_RECVONLY:
1182 return "recvonly";
1183 case MD_SENDRECV:
1184 return "sendrecv";
1185 default:
1186 ASSERT(false);
1187 break;
1188 }
1189 }
1190
1176 void MediaSessionOptions::AddSendStream(MediaType type, 1191 void MediaSessionOptions::AddSendStream(MediaType type,
1177 const std::string& id, 1192 const std::string& id,
1178 const std::string& sync_label) { 1193 const std::string& sync_label) {
1179 AddSendStreamInternal(type, id, sync_label, 1); 1194 AddSendStreamInternal(type, id, sync_label, 1);
1180 } 1195 }
1181 1196
1182 void MediaSessionOptions::AddSendVideoStream( 1197 void MediaSessionOptions::AddSendVideoStream(
1183 const std::string& id, 1198 const std::string& id,
1184 const std::string& sync_label, 1199 const std::string& sync_label,
1185 int num_sim_layers) { 1200 int num_sim_layers) {
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
1227 add_legacy_(true), 1242 add_legacy_(true),
1228 transport_desc_factory_(transport_desc_factory) { 1243 transport_desc_factory_(transport_desc_factory) {
1229 } 1244 }
1230 1245
1231 MediaSessionDescriptionFactory::MediaSessionDescriptionFactory( 1246 MediaSessionDescriptionFactory::MediaSessionDescriptionFactory(
1232 ChannelManager* channel_manager, 1247 ChannelManager* channel_manager,
1233 const TransportDescriptionFactory* transport_desc_factory) 1248 const TransportDescriptionFactory* transport_desc_factory)
1234 : secure_(SEC_DISABLED), 1249 : secure_(SEC_DISABLED),
1235 add_legacy_(true), 1250 add_legacy_(true),
1236 transport_desc_factory_(transport_desc_factory) { 1251 transport_desc_factory_(transport_desc_factory) {
1237 channel_manager->GetSupportedAudioCodecs(&audio_codecs_); 1252 channel_manager->GetSupportedAudioCodecs(&audio_sendrecv_codecs_);
1238 channel_manager->GetSupportedAudioRtpHeaderExtensions(&audio_rtp_extensions_); 1253 channel_manager->GetSupportedAudioRtpHeaderExtensions(&audio_rtp_extensions_);
1239 channel_manager->GetSupportedVideoCodecs(&video_codecs_); 1254 channel_manager->GetSupportedVideoCodecs(&video_codecs_);
1240 channel_manager->GetSupportedVideoRtpHeaderExtensions(&video_rtp_extensions_); 1255 channel_manager->GetSupportedVideoRtpHeaderExtensions(&video_rtp_extensions_);
1241 channel_manager->GetSupportedDataCodecs(&data_codecs_); 1256 channel_manager->GetSupportedDataCodecs(&data_codecs_);
1257 audio_send_codecs_ = audio_sendrecv_codecs_;
1258 audio_recv_codecs_ = audio_sendrecv_codecs_;
1259 }
1260
1261 const AudioCodecs& MediaSessionDescriptionFactory::audio_codecs() const {
1262 return audio_sendrecv_codecs_;
1263 }
1264
1265 const AudioCodecs& MediaSessionDescriptionFactory::audio_send_codecs() const {
1266 return audio_send_codecs_;
1267 }
1268
1269 const AudioCodecs& MediaSessionDescriptionFactory::audio_recv_codecs() const {
1270 return audio_recv_codecs_;
1271 }
1272
1273 void MediaSessionDescriptionFactory::set_audio_codecs(
1274 const AudioCodecs& send_and_recv_codecs) {
1275 audio_send_codecs_ = send_and_recv_codecs;
1276 audio_recv_codecs_ = send_and_recv_codecs;
1277 audio_sendrecv_codecs_ = send_and_recv_codecs;
1278 }
1279
1280 void MediaSessionDescriptionFactory::set_audio_codecs(
1281 const AudioCodecs& send_codecs, const AudioCodecs& recv_codecs) {
1282 audio_send_codecs_ = send_codecs;
1283 audio_recv_codecs_ = recv_codecs;
1284 audio_sendrecv_codecs_.clear();
1285
1286 // Intersect the two lists of codecs, preserving the order of the send codecs.
1287 // If there's any difference in priorities, chances are encoding is more
1288 // expensive than decoding, and high-priority send codecs are likely handled
1289 // better (e.g. through hardware encoder support) than low-priority ones.
1290 // TODO(ossu): This is O(n^2). However, each list should generally be small
1291 // enough for this to not be a problem. They are also nicely local in memory
1292 // like this.
1293 for (const auto& sc : audio_send_codecs_) {
1294 for (const auto& rc : audio_recv_codecs_) {
1295 const size_t send_channels = (sc.channels == 0) ? 1 : sc.channels;
1296 const size_t recv_channels = (rc.channels == 0) ? 1 : rc.channels;
1297 if (sc.clockrate == rc.clockrate &&
1298 sc.bitrate == rc.bitrate &&
1299 send_channels == recv_channels &&
1300 (_stricmp(sc.name.c_str(), rc.name.c_str()) == 0) &&
1301 sc.params == rc.params &&
1302 sc.feedback_params == rc.feedback_params) {
1303 AudioCodec out_codec = sc;
1304 out_codec.channels = send_channels;
1305 audio_sendrecv_codecs_.push_back(out_codec);
1306 break;
1307 }
1308 }
1309 }
1242 } 1310 }
1243 1311
1244 SessionDescription* MediaSessionDescriptionFactory::CreateOffer( 1312 SessionDescription* MediaSessionDescriptionFactory::CreateOffer(
1245 const MediaSessionOptions& options, 1313 const MediaSessionOptions& options,
1246 const SessionDescription* current_description) const { 1314 const SessionDescription* current_description) const {
1247 std::unique_ptr<SessionDescription> offer(new SessionDescription()); 1315 std::unique_ptr<SessionDescription> offer(new SessionDescription());
1248 1316
1249 StreamParamsVec current_streams; 1317 StreamParamsVec current_streams;
1250 GetCurrentStreamParams(current_description, &current_streams); 1318 GetCurrentStreamParams(current_description, &current_streams);
1251 1319
1320 const AudioCodecs *supported_audio_codecs;
1321 if (options.HasSendMediaStream(MEDIA_TYPE_AUDIO) || add_legacy_) {
1322 if (options.recv_audio) {
1323 // sendrecv
1324 supported_audio_codecs = &audio_sendrecv_codecs_;
1325 } else {
1326 // sendonly
1327 supported_audio_codecs = &audio_send_codecs_;
1328 }
1329 } else if (options.recv_audio) {
1330 // recvonly
1331 supported_audio_codecs = &audio_recv_codecs_;
1332 } else {
1333 // Stream is inactive - generate list as if sendrecv.
1334 // See RFC 3264 Section 6.1.
1335 supported_audio_codecs = &audio_sendrecv_codecs_;
1336 }
1337
1252 AudioCodecs audio_codecs; 1338 AudioCodecs audio_codecs;
1253 VideoCodecs video_codecs; 1339 VideoCodecs video_codecs;
1254 DataCodecs data_codecs; 1340 DataCodecs data_codecs;
1255 GetCodecsToOffer(current_description, &audio_codecs, &video_codecs, 1341 GetCodecsToOffer(current_description, *supported_audio_codecs,
1256 &data_codecs); 1342 video_codecs_, data_codecs_,
1343 &audio_codecs, &video_codecs, &data_codecs);
1257 1344
1258 if (!options.vad_enabled) { 1345 if (!options.vad_enabled) {
1259 // If application doesn't want CN codecs in offer. 1346 // If application doesn't want CN codecs in offer.
1260 StripCNCodecs(&audio_codecs); 1347 StripCNCodecs(&audio_codecs);
1261 } 1348 }
1262 1349
1263 RtpHeaderExtensions audio_rtp_extensions; 1350 RtpHeaderExtensions audio_rtp_extensions;
1264 RtpHeaderExtensions video_rtp_extensions; 1351 RtpHeaderExtensions video_rtp_extensions;
1265 GetRtpHdrExtsToOffer(current_description, &audio_rtp_extensions, 1352 GetRtpHdrExtsToOffer(current_description, &audio_rtp_extensions,
1266 &video_rtp_extensions); 1353 &video_rtp_extensions);
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after
1407 return NULL; 1494 return NULL;
1408 } 1495 }
1409 } 1496 }
1410 } 1497 }
1411 1498
1412 return answer.release(); 1499 return answer.release();
1413 } 1500 }
1414 1501
1415 void MediaSessionDescriptionFactory::GetCodecsToOffer( 1502 void MediaSessionDescriptionFactory::GetCodecsToOffer(
1416 const SessionDescription* current_description, 1503 const SessionDescription* current_description,
1504 const AudioCodecs& supported_audio_codecs,
1505 const VideoCodecs& supported_video_codecs,
1506 const DataCodecs& supported_data_codecs,
1417 AudioCodecs* audio_codecs, 1507 AudioCodecs* audio_codecs,
1418 VideoCodecs* video_codecs, 1508 VideoCodecs* video_codecs,
1419 DataCodecs* data_codecs) const { 1509 DataCodecs* data_codecs) const {
1420 UsedPayloadTypes used_pltypes; 1510 UsedPayloadTypes used_pltypes;
1421 audio_codecs->clear(); 1511 audio_codecs->clear();
1422 video_codecs->clear(); 1512 video_codecs->clear();
1423 data_codecs->clear(); 1513 data_codecs->clear();
1424 1514
1425 1515
1426 // First - get all codecs from the current description if the media type 1516 // First - get all codecs from the current description if the media type
(...skipping 15 matching lines...) Expand all
1442 } 1532 }
1443 const DataContentDescription* data = 1533 const DataContentDescription* data =
1444 GetFirstDataContentDescription(current_description); 1534 GetFirstDataContentDescription(current_description);
1445 if (data) { 1535 if (data) {
1446 *data_codecs = data->codecs(); 1536 *data_codecs = data->codecs();
1447 used_pltypes.FindAndSetIdUsed<DataCodec>(data_codecs); 1537 used_pltypes.FindAndSetIdUsed<DataCodec>(data_codecs);
1448 } 1538 }
1449 } 1539 }
1450 1540
1451 // Add our codecs that are not in |current_description|. 1541 // Add our codecs that are not in |current_description|.
1452 FindCodecsToOffer<AudioCodec>(audio_codecs_, audio_codecs, &used_pltypes); 1542 FindCodecsToOffer<AudioCodec>(supported_audio_codecs, audio_codecs,
1453 FindCodecsToOffer<VideoCodec>(video_codecs_, video_codecs, &used_pltypes); 1543 &used_pltypes);
1454 FindCodecsToOffer<DataCodec>(data_codecs_, data_codecs, &used_pltypes); 1544 FindCodecsToOffer<VideoCodec>(supported_video_codecs, video_codecs,
1545 &used_pltypes);
1546 FindCodecsToOffer<DataCodec>(supported_data_codecs, data_codecs,
1547 &used_pltypes);
1455 } 1548 }
1456 1549
1457 void MediaSessionDescriptionFactory::GetRtpHdrExtsToOffer( 1550 void MediaSessionDescriptionFactory::GetRtpHdrExtsToOffer(
1458 const SessionDescription* current_description, 1551 const SessionDescription* current_description,
1459 RtpHeaderExtensions* audio_extensions, 1552 RtpHeaderExtensions* audio_extensions,
1460 RtpHeaderExtensions* video_extensions) const { 1553 RtpHeaderExtensions* video_extensions) const {
1461 // All header extensions allocated from the same range to avoid potential 1554 // All header extensions allocated from the same range to avoid potential
1462 // issues when using BUNDLE. 1555 // issues when using BUNDLE.
1463 UsedRtpHeaderExtensionIds used_ids; 1556 UsedRtpHeaderExtensionIds used_ids;
1464 RtpHeaderExtensions all_extensions; 1557 RtpHeaderExtensions all_extensions;
(...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after
1726 return true; 1819 return true;
1727 } 1820 }
1728 1821
1729 bool MediaSessionDescriptionFactory::AddAudioContentForAnswer( 1822 bool MediaSessionDescriptionFactory::AddAudioContentForAnswer(
1730 const SessionDescription* offer, 1823 const SessionDescription* offer,
1731 const MediaSessionOptions& options, 1824 const MediaSessionOptions& options,
1732 const SessionDescription* current_description, 1825 const SessionDescription* current_description,
1733 StreamParamsVec* current_streams, 1826 StreamParamsVec* current_streams,
1734 SessionDescription* answer) const { 1827 SessionDescription* answer) const {
1735 const ContentInfo* audio_content = GetFirstAudioContent(offer); 1828 const ContentInfo* audio_content = GetFirstAudioContent(offer);
1829 const AudioContentDescription* audio_content_description =
1830 static_cast<const AudioContentDescription*>(audio_content->description);
1736 1831
1737 std::unique_ptr<TransportDescription> audio_transport(CreateTransportAnswer( 1832 std::unique_ptr<TransportDescription> audio_transport(CreateTransportAnswer(
1738 audio_content->name, offer, 1833 audio_content->name, offer,
1739 GetTransportOptions(options, audio_content->name), current_description)); 1834 GetTransportOptions(options, audio_content->name), current_description));
1740 if (!audio_transport) { 1835 if (!audio_transport) {
1741 return false; 1836 return false;
1742 } 1837 }
1743 1838
1744 AudioCodecs audio_codecs = audio_codecs_; 1839 // Pick codecs based on the requested communications direction in the offer.
1840 // According to RFC 3264 Section 6.1, inactive is to be treated as sendrecv
1841 // when constructing the list of supported formats.
1842 AudioCodecs audio_codecs;
1843 switch (audio_content_description->direction()) {
1844 case MD_INACTIVE:
1845 audio_codecs = audio_sendrecv_codecs_;
1846 break;
1847 case MD_SENDRECV:
1848 if (options.HasSendMediaStream(MEDIA_TYPE_AUDIO) || add_legacy_) {
1849 audio_codecs = options.recv_audio
1850 ? audio_sendrecv_codecs_
1851 : audio_send_codecs_;
1852 } else {
1853 audio_codecs = options.recv_audio
1854 ? audio_recv_codecs_
1855 : audio_sendrecv_codecs_; // inactive
1856 }
1857 break;
1858 case MD_RECVONLY:
1859 if (options.HasSendMediaStream(MEDIA_TYPE_AUDIO) || add_legacy_)
1860 audio_codecs = audio_send_codecs_;
1861 else
1862 audio_codecs = audio_sendrecv_codecs_; // inactive
1863 break;
1864 case MD_SENDONLY:
1865 if (options.recv_audio)
1866 audio_codecs = audio_recv_codecs_;
1867 else
1868 audio_codecs = audio_sendrecv_codecs_; // inactive
1869 break;
1870 }
1871
1745 if (!options.vad_enabled) { 1872 if (!options.vad_enabled) {
1746 StripCNCodecs(&audio_codecs); 1873 StripCNCodecs(&audio_codecs);
1747 } 1874 }
1748 1875
1749 bool bundle_enabled = 1876 bool bundle_enabled =
1750 offer->HasGroup(GROUP_TYPE_BUNDLE) && options.bundle_enabled; 1877 offer->HasGroup(GROUP_TYPE_BUNDLE) && options.bundle_enabled;
1751 std::unique_ptr<AudioContentDescription> audio_answer( 1878 std::unique_ptr<AudioContentDescription> audio_answer(
1752 new AudioContentDescription()); 1879 new AudioContentDescription());
1753 // Do not require or create SDES cryptos if DTLS is used. 1880 // Do not require or create SDES cryptos if DTLS is used.
1754 cricket::SecurePolicy sdes_policy = 1881 cricket::SecurePolicy sdes_policy =
1755 audio_transport->secure() ? cricket::SEC_DISABLED : secure(); 1882 audio_transport->secure() ? cricket::SEC_DISABLED : secure();
1756 if (!CreateMediaContentAnswer( 1883 if (!CreateMediaContentAnswer(
1757 static_cast<const AudioContentDescription*>( 1884 audio_content_description,
1758 audio_content->description),
1759 options, 1885 options,
1760 audio_codecs, 1886 audio_codecs,
1761 sdes_policy, 1887 sdes_policy,
1762 GetCryptos(GetFirstAudioContentDescription(current_description)), 1888 GetCryptos(GetFirstAudioContentDescription(current_description)),
1763 audio_rtp_extensions_, 1889 audio_rtp_extensions_,
1764 current_streams, 1890 current_streams,
1765 add_legacy_, 1891 add_legacy_,
1766 bundle_enabled, 1892 bundle_enabled,
1767 audio_answer.get())) { 1893 audio_answer.get())) {
1768 return false; // Fails the session setup. 1894 return false; // Fails the session setup.
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after
1980 GetFirstMediaContentDescription(sdesc, MEDIA_TYPE_VIDEO)); 2106 GetFirstMediaContentDescription(sdesc, MEDIA_TYPE_VIDEO));
1981 } 2107 }
1982 2108
1983 const DataContentDescription* GetFirstDataContentDescription( 2109 const DataContentDescription* GetFirstDataContentDescription(
1984 const SessionDescription* sdesc) { 2110 const SessionDescription* sdesc) {
1985 return static_cast<const DataContentDescription*>( 2111 return static_cast<const DataContentDescription*>(
1986 GetFirstMediaContentDescription(sdesc, MEDIA_TYPE_DATA)); 2112 GetFirstMediaContentDescription(sdesc, MEDIA_TYPE_DATA));
1987 } 2113 }
1988 2114
1989 } // namespace cricket 2115 } // 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