OLD | NEW |
1 /* | 1 /* |
2 * libjingle | 2 * libjingle |
3 * Copyright 2004 Google Inc. | 3 * Copyright 2004 Google Inc. |
4 * | 4 * |
5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
6 * modification, are permitted provided that the following conditions are met: | 6 * modification, are permitted provided that the following conditions are met: |
7 * | 7 * |
8 * 1. Redistributions of source code must retain the above copyright notice, | 8 * 1. Redistributions of source code must retain the above copyright notice, |
9 * this list of conditions and the following disclaimer. | 9 * this list of conditions and the following disclaimer. |
10 * 2. Redistributions in binary form must reproduce the above copyright notice, | 10 * 2. Redistributions in binary form must reproduce the above copyright notice, |
(...skipping 1117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1128 voe_codec.rate = (in.bitrate > 0) ? in.bitrate : -1; | 1128 voe_codec.rate = (in.bitrate > 0) ? in.bitrate : -1; |
1129 } | 1129 } |
1130 *out = voe_codec; | 1130 *out = voe_codec; |
1131 } | 1131 } |
1132 return true; | 1132 return true; |
1133 } | 1133 } |
1134 } | 1134 } |
1135 } | 1135 } |
1136 return false; | 1136 return false; |
1137 } | 1137 } |
| 1138 |
1138 const std::vector<RtpHeaderExtension>& | 1139 const std::vector<RtpHeaderExtension>& |
1139 WebRtcVoiceEngine::rtp_header_extensions() const { | 1140 WebRtcVoiceEngine::rtp_header_extensions() const { |
1140 RTC_DCHECK(signal_thread_checker_.CalledOnValidThread()); | 1141 RTC_DCHECK(signal_thread_checker_.CalledOnValidThread()); |
1141 return rtp_header_extensions_; | 1142 return rtp_header_extensions_; |
1142 } | 1143 } |
1143 | 1144 |
1144 void WebRtcVoiceEngine::SetLogging(int min_sev, const char* filter) { | 1145 void WebRtcVoiceEngine::SetLogging(int min_sev, const char* filter) { |
1145 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 1146 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
1146 // if min_sev == -1, we keep the current log level. | 1147 // if min_sev == -1, we keep the current log level. |
1147 if (min_sev >= 0) { | 1148 if (min_sev >= 0) { |
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1346 return voe_wrapper_->base()->CreateChannel(voe_config_); | 1347 return voe_wrapper_->base()->CreateChannel(voe_config_); |
1347 } | 1348 } |
1348 | 1349 |
1349 class WebRtcVoiceMediaChannel::WebRtcAudioSendStream | 1350 class WebRtcVoiceMediaChannel::WebRtcAudioSendStream |
1350 : public AudioRenderer::Sink { | 1351 : public AudioRenderer::Sink { |
1351 public: | 1352 public: |
1352 WebRtcAudioSendStream(int ch, webrtc::AudioTransport* voe_audio_transport, | 1353 WebRtcAudioSendStream(int ch, webrtc::AudioTransport* voe_audio_transport, |
1353 uint32_t ssrc, const std::string& c_name, | 1354 uint32_t ssrc, const std::string& c_name, |
1354 const std::vector<webrtc::RtpExtension>& extensions, | 1355 const std::vector<webrtc::RtpExtension>& extensions, |
1355 webrtc::Call* call) | 1356 webrtc::Call* call) |
1356 : channel_(ch), | 1357 : voe_audio_transport_(voe_audio_transport), |
1357 voe_audio_transport_(voe_audio_transport), | |
1358 call_(call), | 1358 call_(call), |
1359 config_(nullptr) { | 1359 config_(nullptr) { |
1360 RTC_DCHECK_GE(ch, 0); | 1360 RTC_DCHECK_GE(ch, 0); |
1361 // TODO(solenberg): Once we're not using FakeWebRtcVoiceEngine anymore: | 1361 // TODO(solenberg): Once we're not using FakeWebRtcVoiceEngine anymore: |
1362 // RTC_DCHECK(voe_audio_transport); | 1362 // RTC_DCHECK(voe_audio_transport); |
1363 RTC_DCHECK(call); | 1363 RTC_DCHECK(call); |
1364 audio_capture_thread_checker_.DetachFromThread(); | 1364 audio_capture_thread_checker_.DetachFromThread(); |
1365 config_.rtp.ssrc = ssrc; | 1365 config_.rtp.ssrc = ssrc; |
1366 config_.rtp.c_name = c_name; | 1366 config_.rtp.c_name = c_name; |
1367 config_.voe_channel_id = ch; | 1367 config_.voe_channel_id = ch; |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1422 // AudioRenderer::Sink implementation. | 1422 // AudioRenderer::Sink implementation. |
1423 // This method is called on the audio thread. | 1423 // This method is called on the audio thread. |
1424 void OnData(const void* audio_data, | 1424 void OnData(const void* audio_data, |
1425 int bits_per_sample, | 1425 int bits_per_sample, |
1426 int sample_rate, | 1426 int sample_rate, |
1427 int number_of_channels, | 1427 int number_of_channels, |
1428 size_t number_of_frames) override { | 1428 size_t number_of_frames) override { |
1429 RTC_DCHECK(!worker_thread_checker_.CalledOnValidThread()); | 1429 RTC_DCHECK(!worker_thread_checker_.CalledOnValidThread()); |
1430 RTC_DCHECK(audio_capture_thread_checker_.CalledOnValidThread()); | 1430 RTC_DCHECK(audio_capture_thread_checker_.CalledOnValidThread()); |
1431 RTC_DCHECK(voe_audio_transport_); | 1431 RTC_DCHECK(voe_audio_transport_); |
1432 voe_audio_transport_->OnData(channel_, | 1432 voe_audio_transport_->OnData(config_.voe_channel_id, |
1433 audio_data, | 1433 audio_data, |
1434 bits_per_sample, | 1434 bits_per_sample, |
1435 sample_rate, | 1435 sample_rate, |
1436 number_of_channels, | 1436 number_of_channels, |
1437 number_of_frames); | 1437 number_of_frames); |
1438 } | 1438 } |
1439 | 1439 |
1440 // Callback from the |renderer_| when it is going away. In case Start() has | 1440 // Callback from the |renderer_| when it is going away. In case Start() has |
1441 // never been called, this callback won't be triggered. | 1441 // never been called, this callback won't be triggered. |
1442 void OnClose() override { | 1442 void OnClose() override { |
1443 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 1443 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
1444 // Set |renderer_| to nullptr to make sure no more callback will get into | 1444 // Set |renderer_| to nullptr to make sure no more callback will get into |
1445 // the renderer. | 1445 // the renderer. |
1446 renderer_ = nullptr; | 1446 renderer_ = nullptr; |
1447 } | 1447 } |
1448 | 1448 |
1449 // Accessor to the VoE channel ID. | 1449 // Accessor to the VoE channel ID. |
1450 int channel() const { | 1450 int channel() const { |
1451 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 1451 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
1452 return channel_; | 1452 return config_.voe_channel_id; |
1453 } | 1453 } |
1454 | 1454 |
1455 private: | 1455 private: |
1456 rtc::ThreadChecker worker_thread_checker_; | 1456 rtc::ThreadChecker worker_thread_checker_; |
1457 rtc::ThreadChecker audio_capture_thread_checker_; | 1457 rtc::ThreadChecker audio_capture_thread_checker_; |
1458 const int channel_ = -1; | |
1459 webrtc::AudioTransport* const voe_audio_transport_ = nullptr; | 1458 webrtc::AudioTransport* const voe_audio_transport_ = nullptr; |
1460 webrtc::Call* call_ = nullptr; | 1459 webrtc::Call* call_ = nullptr; |
1461 webrtc::AudioSendStream::Config config_; | 1460 webrtc::AudioSendStream::Config config_; |
1462 // The stream is owned by WebRtcAudioSendStream and may be reallocated if | 1461 // The stream is owned by WebRtcAudioSendStream and may be reallocated if |
1463 // configuration changes. | 1462 // configuration changes. |
1464 webrtc::AudioSendStream* stream_ = nullptr; | 1463 webrtc::AudioSendStream* stream_ = nullptr; |
1465 | 1464 |
1466 // Raw pointer to AudioRenderer owned by LocalAudioTrackHandler. | 1465 // Raw pointer to AudioRenderer owned by LocalAudioTrackHandler. |
1467 // PeerConnection will make sure invalidating the pointer before the object | 1466 // PeerConnection will make sure invalidating the pointer before the object |
1468 // goes away. | 1467 // goes away. |
1469 AudioRenderer* renderer_ = nullptr; | 1468 AudioRenderer* renderer_ = nullptr; |
1470 | 1469 |
1471 RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(WebRtcAudioSendStream); | 1470 RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(WebRtcAudioSendStream); |
1472 }; | 1471 }; |
1473 | 1472 |
1474 class WebRtcVoiceMediaChannel::WebRtcAudioReceiveStream { | 1473 class WebRtcVoiceMediaChannel::WebRtcAudioReceiveStream { |
1475 public: | 1474 public: |
1476 explicit WebRtcAudioReceiveStream(int voe_channel_id) | 1475 WebRtcAudioReceiveStream(int ch, uint32_t remote_ssrc, uint32_t local_ssrc, |
1477 : channel_(voe_channel_id) {} | 1476 bool use_combined_bwe, const std::string& sync_group, |
| 1477 const std::vector<webrtc::RtpExtension>& extensions, |
| 1478 webrtc::Call* call) |
| 1479 : call_(call), |
| 1480 config_() { |
| 1481 RTC_DCHECK_GE(ch, 0); |
| 1482 RTC_DCHECK(call); |
| 1483 config_.rtp.remote_ssrc = remote_ssrc; |
| 1484 config_.rtp.local_ssrc = local_ssrc; |
| 1485 config_.voe_channel_id = ch; |
| 1486 config_.sync_group = sync_group; |
| 1487 RecreateAudioReceiveStream(use_combined_bwe, extensions); |
| 1488 } |
1478 | 1489 |
1479 int channel() { return channel_; } | 1490 ~WebRtcAudioReceiveStream() { |
| 1491 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
| 1492 call_->DestroyAudioReceiveStream(stream_); |
| 1493 } |
| 1494 |
| 1495 void RecreateAudioReceiveStream( |
| 1496 const std::vector<webrtc::RtpExtension>& extensions) { |
| 1497 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
| 1498 RecreateAudioReceiveStream(config_.combined_audio_video_bwe, extensions); |
| 1499 } |
| 1500 void RecreateAudioReceiveStream(bool use_combined_bwe) { |
| 1501 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
| 1502 RecreateAudioReceiveStream(use_combined_bwe, config_.rtp.extensions); |
| 1503 } |
| 1504 |
| 1505 webrtc::AudioReceiveStream::Stats GetStats() const { |
| 1506 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
| 1507 RTC_DCHECK(stream_); |
| 1508 return stream_->GetStats(); |
| 1509 } |
| 1510 |
| 1511 int channel() const { |
| 1512 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
| 1513 return config_.voe_channel_id; |
| 1514 } |
1480 | 1515 |
1481 private: | 1516 private: |
1482 int channel_; | 1517 void RecreateAudioReceiveStream(bool use_combined_bwe, |
| 1518 const std::vector<webrtc::RtpExtension>& extensions) { |
| 1519 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
| 1520 if (stream_) { |
| 1521 call_->DestroyAudioReceiveStream(stream_); |
| 1522 stream_ = nullptr; |
| 1523 } |
| 1524 config_.rtp.extensions = extensions; |
| 1525 config_.combined_audio_video_bwe = use_combined_bwe; |
| 1526 RTC_DCHECK(!stream_); |
| 1527 stream_ = call_->CreateAudioReceiveStream(config_); |
| 1528 RTC_CHECK(stream_); |
| 1529 } |
| 1530 |
| 1531 rtc::ThreadChecker worker_thread_checker_; |
| 1532 webrtc::Call* call_ = nullptr; |
| 1533 webrtc::AudioReceiveStream::Config config_; |
| 1534 // The stream is owned by WebRtcAudioReceiveStream and may be reallocated if |
| 1535 // configuration changes. |
| 1536 webrtc::AudioReceiveStream* stream_ = nullptr; |
1483 | 1537 |
1484 RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(WebRtcAudioReceiveStream); | 1538 RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(WebRtcAudioReceiveStream); |
1485 }; | 1539 }; |
1486 | 1540 |
1487 // WebRtcVoiceMediaChannel | |
1488 WebRtcVoiceMediaChannel::WebRtcVoiceMediaChannel(WebRtcVoiceEngine* engine, | 1541 WebRtcVoiceMediaChannel::WebRtcVoiceMediaChannel(WebRtcVoiceEngine* engine, |
1489 const AudioOptions& options, | 1542 const AudioOptions& options, |
1490 webrtc::Call* call) | 1543 webrtc::Call* call) |
1491 : engine_(engine), call_(call) { | 1544 : engine_(engine), call_(call) { |
1492 LOG(LS_VERBOSE) << "WebRtcVoiceMediaChannel::WebRtcVoiceMediaChannel"; | 1545 LOG(LS_VERBOSE) << "WebRtcVoiceMediaChannel::WebRtcVoiceMediaChannel"; |
1493 RTC_DCHECK(call); | 1546 RTC_DCHECK(call); |
1494 engine->RegisterChannel(this); | 1547 engine->RegisterChannel(this); |
1495 SetOptions(options); | 1548 SetOptions(options); |
1496 } | 1549 } |
1497 | 1550 |
1498 WebRtcVoiceMediaChannel::~WebRtcVoiceMediaChannel() { | 1551 WebRtcVoiceMediaChannel::~WebRtcVoiceMediaChannel() { |
1499 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 1552 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
1500 LOG(LS_VERBOSE) << "WebRtcVoiceMediaChannel::~WebRtcVoiceMediaChannel"; | 1553 LOG(LS_VERBOSE) << "WebRtcVoiceMediaChannel::~WebRtcVoiceMediaChannel"; |
1501 | 1554 // TODO(solenberg): Should be able to delete the streams directly, without |
1502 // Remove any remaining send streams. | 1555 // going through RemoveNnStream(), once stream objects handle |
| 1556 // all (de)configuration. |
1503 while (!send_streams_.empty()) { | 1557 while (!send_streams_.empty()) { |
1504 RemoveSendStream(send_streams_.begin()->first); | 1558 RemoveSendStream(send_streams_.begin()->first); |
1505 } | 1559 } |
1506 | 1560 while (!recv_streams_.empty()) { |
1507 // Remove any remaining receive streams. | 1561 RemoveRecvStream(recv_streams_.begin()->first); |
1508 while (!receive_channels_.empty()) { | |
1509 RemoveRecvStream(receive_channels_.begin()->first); | |
1510 } | 1562 } |
1511 RTC_DCHECK(receive_streams_.empty()); | |
1512 | |
1513 // Unregister ourselves from the engine. | |
1514 engine()->UnregisterChannel(this); | 1563 engine()->UnregisterChannel(this); |
1515 } | 1564 } |
1516 | 1565 |
1517 bool WebRtcVoiceMediaChannel::SetSendParameters( | 1566 bool WebRtcVoiceMediaChannel::SetSendParameters( |
1518 const AudioSendParameters& params) { | 1567 const AudioSendParameters& params) { |
1519 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 1568 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
1520 // TODO(pthatcher): Refactor this to be more clean now that we have | 1569 // TODO(pthatcher): Refactor this to be more clean now that we have |
1521 // all the information at once. | 1570 // all the information at once. |
1522 | 1571 |
1523 if (!SetSendCodecs(params.codecs)) { | 1572 if (!SetSendCodecs(params.codecs)) { |
(...skipping 13 matching lines...) Expand all Loading... |
1537 return false; | 1586 return false; |
1538 } | 1587 } |
1539 return SetOptions(params.options); | 1588 return SetOptions(params.options); |
1540 } | 1589 } |
1541 | 1590 |
1542 bool WebRtcVoiceMediaChannel::SetRecvParameters( | 1591 bool WebRtcVoiceMediaChannel::SetRecvParameters( |
1543 const AudioRecvParameters& params) { | 1592 const AudioRecvParameters& params) { |
1544 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 1593 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
1545 // TODO(pthatcher): Refactor this to be more clean now that we have | 1594 // TODO(pthatcher): Refactor this to be more clean now that we have |
1546 // all the information at once. | 1595 // all the information at once. |
1547 return (SetRecvCodecs(params.codecs) && | 1596 |
1548 SetRecvRtpHeaderExtensions(params.extensions)); | 1597 if (!SetRecvCodecs(params.codecs)) { |
| 1598 return false; |
| 1599 } |
| 1600 |
| 1601 std::vector<webrtc::RtpExtension> recv_rtp_extensions = |
| 1602 FindAudioRtpHeaderExtensions(params.extensions); |
| 1603 if (recv_rtp_extensions_ != recv_rtp_extensions) { |
| 1604 recv_rtp_extensions_.swap(recv_rtp_extensions); |
| 1605 for (auto& it : recv_streams_) { |
| 1606 it.second->RecreateAudioReceiveStream(recv_rtp_extensions_); |
| 1607 } |
| 1608 } |
| 1609 |
| 1610 return true; |
1549 } | 1611 } |
1550 | 1612 |
1551 bool WebRtcVoiceMediaChannel::SetOptions(const AudioOptions& options) { | 1613 bool WebRtcVoiceMediaChannel::SetOptions(const AudioOptions& options) { |
1552 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 1614 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
1553 LOG(LS_INFO) << "Setting voice channel options: " | 1615 LOG(LS_INFO) << "Setting voice channel options: " |
1554 << options.ToString(); | 1616 << options.ToString(); |
1555 | 1617 |
1556 // Check if DSCP value is changed from previous. | 1618 // Check if DSCP value is changed from previous. |
1557 bool dscp_option_changed = (options_.dscp != options.dscp); | 1619 bool dscp_option_changed = (options_.dscp != options.dscp); |
1558 | 1620 |
(...skipping 13 matching lines...) Expand all Loading... |
1572 if (dscp_option_changed) { | 1634 if (dscp_option_changed) { |
1573 rtc::DiffServCodePoint dscp = rtc::DSCP_DEFAULT; | 1635 rtc::DiffServCodePoint dscp = rtc::DSCP_DEFAULT; |
1574 if (options_.dscp.value_or(false)) | 1636 if (options_.dscp.value_or(false)) |
1575 dscp = kAudioDscpValue; | 1637 dscp = kAudioDscpValue; |
1576 if (MediaChannel::SetDscp(dscp) != 0) { | 1638 if (MediaChannel::SetDscp(dscp) != 0) { |
1577 LOG(LS_WARNING) << "Failed to set DSCP settings for audio channel"; | 1639 LOG(LS_WARNING) << "Failed to set DSCP settings for audio channel"; |
1578 } | 1640 } |
1579 } | 1641 } |
1580 | 1642 |
1581 // TODO(solenberg): Don't recreate unless options changed. | 1643 // TODO(solenberg): Don't recreate unless options changed. |
1582 RecreateAudioReceiveStreams(); | 1644 for (auto& it : recv_streams_) { |
| 1645 it.second->RecreateAudioReceiveStream( |
| 1646 options_.combined_audio_video_bwe.value_or(false)); |
| 1647 } |
1583 | 1648 |
1584 LOG(LS_INFO) << "Set voice channel options. Current options: " | 1649 LOG(LS_INFO) << "Set voice channel options. Current options: " |
1585 << options_.ToString(); | 1650 << options_.ToString(); |
1586 return true; | 1651 return true; |
1587 } | 1652 } |
1588 | 1653 |
1589 bool WebRtcVoiceMediaChannel::SetRecvCodecs( | 1654 bool WebRtcVoiceMediaChannel::SetRecvCodecs( |
1590 const std::vector<AudioCodec>& codecs) { | 1655 const std::vector<AudioCodec>& codecs) { |
1591 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 1656 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
1592 | 1657 |
(...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1858 | 1923 |
1859 // Cache the codecs in order to configure the channel created later. | 1924 // Cache the codecs in order to configure the channel created later. |
1860 send_codecs_ = codecs; | 1925 send_codecs_ = codecs; |
1861 for (const auto& ch : send_streams_) { | 1926 for (const auto& ch : send_streams_) { |
1862 if (!SetSendCodecs(ch.second->channel(), codecs)) { | 1927 if (!SetSendCodecs(ch.second->channel(), codecs)) { |
1863 return false; | 1928 return false; |
1864 } | 1929 } |
1865 } | 1930 } |
1866 | 1931 |
1867 // Set nack status on receive channels and update |nack_enabled_|. | 1932 // Set nack status on receive channels and update |nack_enabled_|. |
1868 for (const auto& ch : receive_channels_) { | 1933 for (const auto& ch : recv_streams_) { |
1869 SetNack(ch.second->channel(), nack_enabled_); | 1934 SetNack(ch.second->channel(), nack_enabled_); |
1870 } | 1935 } |
1871 | 1936 |
1872 return true; | 1937 return true; |
1873 } | 1938 } |
1874 | 1939 |
1875 void WebRtcVoiceMediaChannel::SetNack(int channel, bool nack_enabled) { | 1940 void WebRtcVoiceMediaChannel::SetNack(int channel, bool nack_enabled) { |
1876 if (nack_enabled) { | 1941 if (nack_enabled) { |
1877 LOG(LS_INFO) << "Enabling NACK for channel " << channel; | 1942 LOG(LS_INFO) << "Enabling NACK for channel " << channel; |
1878 engine()->voe()->rtp()->SetNACKStatus(channel, true, kNackMaxPackets); | 1943 engine()->voe()->rtp()->SetNACKStatus(channel, true, kNackMaxPackets); |
(...skipping 15 matching lines...) Expand all Loading... |
1894 return true; | 1959 return true; |
1895 } | 1960 } |
1896 | 1961 |
1897 if (engine()->voe()->codec()->SetSendCodec(channel, send_codec) == -1) { | 1962 if (engine()->voe()->codec()->SetSendCodec(channel, send_codec) == -1) { |
1898 LOG_RTCERR2(SetSendCodec, channel, ToString(send_codec)); | 1963 LOG_RTCERR2(SetSendCodec, channel, ToString(send_codec)); |
1899 return false; | 1964 return false; |
1900 } | 1965 } |
1901 return true; | 1966 return true; |
1902 } | 1967 } |
1903 | 1968 |
1904 bool WebRtcVoiceMediaChannel::SetRecvRtpHeaderExtensions( | |
1905 const std::vector<RtpHeaderExtension>& extensions) { | |
1906 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | |
1907 if (receive_extensions_ == extensions) { | |
1908 return true; | |
1909 } | |
1910 | |
1911 for (const auto& ch : receive_channels_) { | |
1912 if (!SetChannelRecvRtpHeaderExtensions(ch.second->channel(), extensions)) { | |
1913 return false; | |
1914 } | |
1915 } | |
1916 | |
1917 receive_extensions_ = extensions; | |
1918 | |
1919 // Recreate AudioReceiveStream:s. | |
1920 recv_rtp_extensions_ = FindAudioRtpHeaderExtensions(extensions); | |
1921 RecreateAudioReceiveStreams(); | |
1922 | |
1923 return true; | |
1924 } | |
1925 | |
1926 bool WebRtcVoiceMediaChannel::SetChannelRecvRtpHeaderExtensions( | |
1927 int channel_id, const std::vector<RtpHeaderExtension>& extensions) { | |
1928 const RtpHeaderExtension* audio_level_extension = | |
1929 FindHeaderExtension(extensions, kRtpAudioLevelHeaderExtension); | |
1930 if (!SetHeaderExtension( | |
1931 &webrtc::VoERTP_RTCP::SetReceiveAudioLevelIndicationStatus, channel_id, | |
1932 audio_level_extension)) { | |
1933 return false; | |
1934 } | |
1935 | |
1936 const RtpHeaderExtension* send_time_extension = | |
1937 FindHeaderExtension(extensions, kRtpAbsoluteSenderTimeHeaderExtension); | |
1938 if (!SetHeaderExtension( | |
1939 &webrtc::VoERTP_RTCP::SetReceiveAbsoluteSenderTimeStatus, channel_id, | |
1940 send_time_extension)) { | |
1941 return false; | |
1942 } | |
1943 | |
1944 return true; | |
1945 } | |
1946 | |
1947 bool WebRtcVoiceMediaChannel::SetPlayout(bool playout) { | 1969 bool WebRtcVoiceMediaChannel::SetPlayout(bool playout) { |
1948 desired_playout_ = playout; | 1970 desired_playout_ = playout; |
1949 return ChangePlayout(desired_playout_); | 1971 return ChangePlayout(desired_playout_); |
1950 } | 1972 } |
1951 | 1973 |
1952 bool WebRtcVoiceMediaChannel::PausePlayout() { | 1974 bool WebRtcVoiceMediaChannel::PausePlayout() { |
1953 return ChangePlayout(false); | 1975 return ChangePlayout(false); |
1954 } | 1976 } |
1955 | 1977 |
1956 bool WebRtcVoiceMediaChannel::ResumePlayout() { | 1978 bool WebRtcVoiceMediaChannel::ResumePlayout() { |
1957 return ChangePlayout(desired_playout_); | 1979 return ChangePlayout(desired_playout_); |
1958 } | 1980 } |
1959 | 1981 |
1960 bool WebRtcVoiceMediaChannel::ChangePlayout(bool playout) { | 1982 bool WebRtcVoiceMediaChannel::ChangePlayout(bool playout) { |
1961 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 1983 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
1962 if (playout_ == playout) { | 1984 if (playout_ == playout) { |
1963 return true; | 1985 return true; |
1964 } | 1986 } |
1965 | 1987 |
1966 for (const auto& ch : receive_channels_) { | 1988 for (const auto& ch : recv_streams_) { |
1967 if (!SetPlayout(ch.second->channel(), playout)) { | 1989 if (!SetPlayout(ch.second->channel(), playout)) { |
1968 LOG(LS_ERROR) << "SetPlayout " << playout << " on channel " | 1990 LOG(LS_ERROR) << "SetPlayout " << playout << " on channel " |
1969 << ch.second->channel() << " failed"; | 1991 << ch.second->channel() << " failed"; |
1970 return false; | 1992 return false; |
1971 } | 1993 } |
1972 } | 1994 } |
1973 playout_ = playout; | 1995 playout_ = playout; |
1974 return true; | 1996 return true; |
1975 } | 1997 } |
1976 | 1998 |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2061 return -1; | 2083 return -1; |
2062 } | 2084 } |
2063 if (engine()->voe()->network()->RegisterExternalTransport(id, *this) == -1) { | 2085 if (engine()->voe()->network()->RegisterExternalTransport(id, *this) == -1) { |
2064 LOG_RTCERR2(RegisterExternalTransport, id, this); | 2086 LOG_RTCERR2(RegisterExternalTransport, id, this); |
2065 engine()->voe()->base()->DeleteChannel(id); | 2087 engine()->voe()->base()->DeleteChannel(id); |
2066 return -1; | 2088 return -1; |
2067 } | 2089 } |
2068 return id; | 2090 return id; |
2069 } | 2091 } |
2070 | 2092 |
2071 bool WebRtcVoiceMediaChannel::DeleteChannel(int channel) { | 2093 bool WebRtcVoiceMediaChannel::DeleteVoEChannel(int channel) { |
2072 if (engine()->voe()->network()->DeRegisterExternalTransport(channel) == -1) { | 2094 if (engine()->voe()->network()->DeRegisterExternalTransport(channel) == -1) { |
2073 LOG_RTCERR1(DeRegisterExternalTransport, channel); | 2095 LOG_RTCERR1(DeRegisterExternalTransport, channel); |
2074 } | 2096 } |
2075 if (engine()->voe()->base()->DeleteChannel(channel) == -1) { | 2097 if (engine()->voe()->base()->DeleteChannel(channel) == -1) { |
2076 LOG_RTCERR1(DeleteChannel, channel); | 2098 LOG_RTCERR1(DeleteChannel, channel); |
2077 return false; | 2099 return false; |
2078 } | 2100 } |
2079 return true; | 2101 return true; |
2080 } | 2102 } |
2081 | 2103 |
(...skipping 28 matching lines...) Expand all Loading... |
2110 if (!send_codecs_.empty() && !SetSendCodecs(channel, send_codecs_)) { | 2132 if (!send_codecs_.empty() && !SetSendCodecs(channel, send_codecs_)) { |
2111 RemoveSendStream(ssrc); | 2133 RemoveSendStream(ssrc); |
2112 return false; | 2134 return false; |
2113 } | 2135 } |
2114 | 2136 |
2115 // At this point the channel's local SSRC has been updated. If the channel is | 2137 // At this point the channel's local SSRC has been updated. If the channel is |
2116 // the first send channel make sure that all the receive channels are updated | 2138 // the first send channel make sure that all the receive channels are updated |
2117 // with the same SSRC in order to send receiver reports. | 2139 // with the same SSRC in order to send receiver reports. |
2118 if (send_streams_.size() == 1) { | 2140 if (send_streams_.size() == 1) { |
2119 receiver_reports_ssrc_ = ssrc; | 2141 receiver_reports_ssrc_ = ssrc; |
2120 for (const auto& ch : receive_channels_) { | 2142 for (const auto& stream : recv_streams_) { |
2121 int recv_channel = ch.second->channel(); | 2143 int recv_channel = stream.second->channel(); |
2122 if (engine()->voe()->rtp()->SetLocalSSRC(recv_channel, ssrc) != 0) { | 2144 if (engine()->voe()->rtp()->SetLocalSSRC(recv_channel, ssrc) != 0) { |
2123 LOG_RTCERR2(SetLocalSSRC, ch.second->channel(), ssrc); | 2145 LOG_RTCERR2(SetLocalSSRC, recv_channel, ssrc); |
2124 return false; | 2146 return false; |
2125 } | 2147 } |
2126 engine()->voe()->base()->AssociateSendChannel(recv_channel, channel); | 2148 engine()->voe()->base()->AssociateSendChannel(recv_channel, channel); |
2127 LOG(LS_INFO) << "VoiceEngine channel #" << recv_channel | 2149 LOG(LS_INFO) << "VoiceEngine channel #" << recv_channel |
2128 << " is associated with channel #" << channel << "."; | 2150 << " is associated with channel #" << channel << "."; |
2129 } | 2151 } |
2130 } | 2152 } |
2131 | 2153 |
2132 return ChangeSend(channel, desired_send_); | 2154 return ChangeSend(channel, desired_send_); |
2133 } | 2155 } |
2134 | 2156 |
2135 bool WebRtcVoiceMediaChannel::RemoveSendStream(uint32_t ssrc) { | 2157 bool WebRtcVoiceMediaChannel::RemoveSendStream(uint32_t ssrc) { |
2136 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 2158 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
2137 LOG(LS_INFO) << "RemoveSendStream: " << ssrc; | 2159 LOG(LS_INFO) << "RemoveSendStream: " << ssrc; |
2138 | 2160 |
2139 auto it = send_streams_.find(ssrc); | 2161 auto it = send_streams_.find(ssrc); |
2140 if (it == send_streams_.end()) { | 2162 if (it == send_streams_.end()) { |
2141 LOG(LS_WARNING) << "Try to remove stream with ssrc " << ssrc | 2163 LOG(LS_WARNING) << "Try to remove stream with ssrc " << ssrc |
2142 << " which doesn't exist."; | 2164 << " which doesn't exist."; |
2143 return false; | 2165 return false; |
2144 } | 2166 } |
2145 | 2167 |
2146 int channel = it->second->channel(); | 2168 int channel = it->second->channel(); |
2147 ChangeSend(channel, SEND_NOTHING); | 2169 ChangeSend(channel, SEND_NOTHING); |
2148 | 2170 |
2149 // Delete the WebRtcVoiceChannelRenderer object connected to the channel, | 2171 // Clean up and delete the send stream+channel. |
2150 // this will disconnect the audio renderer with the send channel. | 2172 LOG(LS_INFO) << "Removing audio send stream " << ssrc |
| 2173 << " with VoiceEngine channel #" << channel << "."; |
2151 delete it->second; | 2174 delete it->second; |
2152 send_streams_.erase(it); | 2175 send_streams_.erase(it); |
2153 | 2176 if (!DeleteVoEChannel(channel)) { |
2154 // Clean up and delete the send channel. | |
2155 LOG(LS_INFO) << "Removing audio send stream " << ssrc | |
2156 << " with VoiceEngine channel #" << channel << "."; | |
2157 if (!DeleteChannel(channel)) { | |
2158 return false; | 2177 return false; |
2159 } | 2178 } |
2160 if (send_streams_.empty()) { | 2179 if (send_streams_.empty()) { |
2161 ChangeSend(SEND_NOTHING); | 2180 ChangeSend(SEND_NOTHING); |
2162 } | 2181 } |
2163 return true; | 2182 return true; |
2164 } | 2183 } |
2165 | 2184 |
2166 bool WebRtcVoiceMediaChannel::AddRecvStream(const StreamParams& sp) { | 2185 bool WebRtcVoiceMediaChannel::AddRecvStream(const StreamParams& sp) { |
2167 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 2186 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
2168 LOG(LS_INFO) << "AddRecvStream: " << sp.ToString(); | 2187 LOG(LS_INFO) << "AddRecvStream: " << sp.ToString(); |
2169 | 2188 |
2170 if (!ValidateStreamParams(sp)) { | 2189 if (!ValidateStreamParams(sp)) { |
2171 return false; | 2190 return false; |
2172 } | 2191 } |
2173 | 2192 |
2174 uint32_t ssrc = sp.first_ssrc(); | 2193 const uint32_t ssrc = sp.first_ssrc(); |
2175 if (ssrc == 0) { | 2194 if (ssrc == 0) { |
2176 LOG(LS_WARNING) << "AddRecvStream with ssrc==0 is not supported."; | 2195 LOG(LS_WARNING) << "AddRecvStream with ssrc==0 is not supported."; |
2177 return false; | 2196 return false; |
2178 } | 2197 } |
2179 | 2198 |
2180 // Remove the default receive stream if one had been created with this ssrc; | 2199 // Remove the default receive stream if one had been created with this ssrc; |
2181 // we'll recreate it then. | 2200 // we'll recreate it then. |
2182 if (IsDefaultRecvStream(ssrc)) { | 2201 if (IsDefaultRecvStream(ssrc)) { |
2183 RemoveRecvStream(ssrc); | 2202 RemoveRecvStream(ssrc); |
2184 } | 2203 } |
2185 | 2204 |
2186 if (receive_channels_.find(ssrc) != receive_channels_.end()) { | 2205 if (GetReceiveChannelId(ssrc) != -1) { |
2187 LOG(LS_ERROR) << "Stream already exists with ssrc " << ssrc; | 2206 LOG(LS_ERROR) << "Stream already exists with ssrc " << ssrc; |
2188 return false; | 2207 return false; |
2189 } | 2208 } |
2190 RTC_DCHECK(receive_stream_params_.find(ssrc) == receive_stream_params_.end()); | |
2191 | 2209 |
2192 // Create a new channel for receiving audio data. | 2210 // Create a new channel for receiving audio data. |
2193 int channel = CreateVoEChannel(); | 2211 const int channel = CreateVoEChannel(); |
2194 if (channel == -1) { | 2212 if (channel == -1) { |
2195 return false; | 2213 return false; |
2196 } | 2214 } |
2197 if (!ConfigureRecvChannel(channel)) { | |
2198 DeleteChannel(channel); | |
2199 return false; | |
2200 } | |
2201 | |
2202 WebRtcAudioReceiveStream* stream = new WebRtcAudioReceiveStream(channel); | |
2203 receive_channels_.insert(std::make_pair(ssrc, stream)); | |
2204 receive_stream_params_[ssrc] = sp; | |
2205 AddAudioReceiveStream(ssrc); | |
2206 | |
2207 LOG(LS_INFO) << "New audio stream " << ssrc | |
2208 << " registered to VoiceEngine channel #" | |
2209 << channel << "."; | |
2210 return true; | |
2211 } | |
2212 | |
2213 bool WebRtcVoiceMediaChannel::ConfigureRecvChannel(int channel) { | |
2214 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | |
2215 | |
2216 int send_channel = GetSendChannelId(receiver_reports_ssrc_); | |
2217 if (send_channel != -1) { | |
2218 // Associate receive channel with first send channel (so the receive channel | |
2219 // can obtain RTT from the send channel) | |
2220 engine()->voe()->base()->AssociateSendChannel(channel, send_channel); | |
2221 LOG(LS_INFO) << "VoiceEngine channel #" << channel | |
2222 << " is associated with channel #" << send_channel << "."; | |
2223 } | |
2224 if (engine()->voe()->rtp()->SetLocalSSRC(channel, | |
2225 receiver_reports_ssrc_) == -1) { | |
2226 LOG_RTCERR1(SetLocalSSRC, channel); | |
2227 return false; | |
2228 } | |
2229 | 2215 |
2230 // Turn off all supported codecs. | 2216 // Turn off all supported codecs. |
2231 int ncodecs = engine()->voe()->codec()->NumOfCodecs(); | 2217 const int ncodecs = engine()->voe()->codec()->NumOfCodecs(); |
2232 for (int i = 0; i < ncodecs; ++i) { | 2218 for (int i = 0; i < ncodecs; ++i) { |
2233 webrtc::CodecInst voe_codec; | 2219 webrtc::CodecInst voe_codec; |
2234 if (engine()->voe()->codec()->GetCodec(i, voe_codec) != -1) { | 2220 if (engine()->voe()->codec()->GetCodec(i, voe_codec) != -1) { |
2235 voe_codec.pltype = -1; | 2221 voe_codec.pltype = -1; |
2236 if (engine()->voe()->codec()->SetRecPayloadType( | 2222 if (engine()->voe()->codec()->SetRecPayloadType( |
2237 channel, voe_codec) == -1) { | 2223 channel, voe_codec) == -1) { |
2238 LOG_RTCERR2(SetRecPayloadType, channel, ToString(voe_codec)); | 2224 LOG_RTCERR2(SetRecPayloadType, channel, ToString(voe_codec)); |
| 2225 DeleteVoEChannel(channel); |
2239 return false; | 2226 return false; |
2240 } | 2227 } |
2241 } | 2228 } |
2242 } | 2229 } |
2243 | 2230 |
2244 // Only enable those configured for this channel. | 2231 // Only enable those configured for this channel. |
2245 for (const auto& codec : recv_codecs_) { | 2232 for (const auto& codec : recv_codecs_) { |
2246 webrtc::CodecInst voe_codec; | 2233 webrtc::CodecInst voe_codec; |
2247 if (engine()->FindWebRtcCodec(codec, &voe_codec)) { | 2234 if (engine()->FindWebRtcCodec(codec, &voe_codec)) { |
2248 voe_codec.pltype = codec.id; | 2235 voe_codec.pltype = codec.id; |
2249 if (engine()->voe()->codec()->SetRecPayloadType( | 2236 if (engine()->voe()->codec()->SetRecPayloadType( |
2250 channel, voe_codec) == -1) { | 2237 channel, voe_codec) == -1) { |
2251 LOG_RTCERR2(SetRecPayloadType, channel, ToString(voe_codec)); | 2238 LOG_RTCERR2(SetRecPayloadType, channel, ToString(voe_codec)); |
| 2239 DeleteVoEChannel(channel); |
2252 return false; | 2240 return false; |
2253 } | 2241 } |
2254 } | 2242 } |
2255 } | 2243 } |
2256 | 2244 |
2257 SetNack(channel, nack_enabled_); | 2245 const int send_channel = GetSendChannelId(receiver_reports_ssrc_); |
2258 | 2246 if (send_channel != -1) { |
2259 // Set RTP header extension for the new channel. | 2247 // Associate receive channel with first send channel (so the receive channel |
2260 if (!SetChannelRecvRtpHeaderExtensions(channel, receive_extensions_)) { | 2248 // can obtain RTT from the send channel) |
2261 return false; | 2249 engine()->voe()->base()->AssociateSendChannel(channel, send_channel); |
| 2250 LOG(LS_INFO) << "VoiceEngine channel #" << channel |
| 2251 << " is associated with channel #" << send_channel << "."; |
2262 } | 2252 } |
2263 | 2253 |
| 2254 recv_streams_.insert(std::make_pair(ssrc, new WebRtcAudioReceiveStream( |
| 2255 channel, ssrc, receiver_reports_ssrc_, |
| 2256 options_.combined_audio_video_bwe.value_or(false), sp.sync_label, |
| 2257 recv_rtp_extensions_, call_))); |
| 2258 |
| 2259 SetNack(channel, nack_enabled_); |
2264 SetPlayout(channel, playout_); | 2260 SetPlayout(channel, playout_); |
| 2261 |
2265 return true; | 2262 return true; |
2266 } | 2263 } |
2267 | 2264 |
2268 bool WebRtcVoiceMediaChannel::RemoveRecvStream(uint32_t ssrc) { | 2265 bool WebRtcVoiceMediaChannel::RemoveRecvStream(uint32_t ssrc) { |
2269 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 2266 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
2270 LOG(LS_INFO) << "RemoveRecvStream: " << ssrc; | 2267 LOG(LS_INFO) << "RemoveRecvStream: " << ssrc; |
2271 | 2268 |
2272 auto it = receive_channels_.find(ssrc); | 2269 const auto it = recv_streams_.find(ssrc); |
2273 if (it == receive_channels_.end()) { | 2270 if (it == recv_streams_.end()) { |
2274 LOG(LS_WARNING) << "Try to remove stream with ssrc " << ssrc | 2271 LOG(LS_WARNING) << "Try to remove stream with ssrc " << ssrc |
2275 << " which doesn't exist."; | 2272 << " which doesn't exist."; |
2276 return false; | 2273 return false; |
2277 } | 2274 } |
2278 | 2275 |
2279 RemoveAudioReceiveStream(ssrc); | |
2280 receive_stream_params_.erase(ssrc); | |
2281 | |
2282 const int channel = it->second->channel(); | |
2283 delete it->second; | |
2284 receive_channels_.erase(it); | |
2285 | |
2286 // Deregister default channel, if that's the one being destroyed. | 2276 // Deregister default channel, if that's the one being destroyed. |
2287 if (IsDefaultRecvStream(ssrc)) { | 2277 if (IsDefaultRecvStream(ssrc)) { |
2288 default_recv_ssrc_ = -1; | 2278 default_recv_ssrc_ = -1; |
2289 } | 2279 } |
2290 | 2280 |
2291 LOG(LS_INFO) << "Removing audio stream " << ssrc | 2281 const int channel = it->second->channel(); |
| 2282 |
| 2283 // Clean up and delete the receive stream+channel. |
| 2284 LOG(LS_INFO) << "Removing audio receive stream " << ssrc |
2292 << " with VoiceEngine channel #" << channel << "."; | 2285 << " with VoiceEngine channel #" << channel << "."; |
2293 return DeleteChannel(channel); | 2286 delete it->second; |
| 2287 recv_streams_.erase(it); |
| 2288 return DeleteVoEChannel(channel); |
2294 } | 2289 } |
2295 | 2290 |
2296 bool WebRtcVoiceMediaChannel::SetLocalRenderer(uint32_t ssrc, | 2291 bool WebRtcVoiceMediaChannel::SetLocalRenderer(uint32_t ssrc, |
2297 AudioRenderer* renderer) { | 2292 AudioRenderer* renderer) { |
2298 auto it = send_streams_.find(ssrc); | 2293 auto it = send_streams_.find(ssrc); |
2299 if (it == send_streams_.end()) { | 2294 if (it == send_streams_.end()) { |
2300 if (renderer) { | 2295 if (renderer) { |
2301 // Return an error if trying to set a valid renderer with an invalid ssrc. | 2296 // Return an error if trying to set a valid renderer with an invalid ssrc. |
2302 LOG(LS_ERROR) << "SetLocalRenderer failed with ssrc "<< ssrc; | 2297 LOG(LS_ERROR) << "SetLocalRenderer failed with ssrc "<< ssrc; |
2303 return false; | 2298 return false; |
2304 } | 2299 } |
2305 | 2300 |
2306 // The channel likely has gone away, do nothing. | 2301 // The channel likely has gone away, do nothing. |
2307 return true; | 2302 return true; |
2308 } | 2303 } |
2309 | 2304 |
2310 if (renderer) { | 2305 if (renderer) { |
2311 it->second->Start(renderer); | 2306 it->second->Start(renderer); |
2312 } else { | 2307 } else { |
2313 it->second->Stop(); | 2308 it->second->Stop(); |
2314 } | 2309 } |
2315 | 2310 |
2316 return true; | 2311 return true; |
2317 } | 2312 } |
2318 | 2313 |
2319 bool WebRtcVoiceMediaChannel::GetActiveStreams( | 2314 bool WebRtcVoiceMediaChannel::GetActiveStreams( |
2320 AudioInfo::StreamList* actives) { | 2315 AudioInfo::StreamList* actives) { |
2321 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 2316 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
2322 actives->clear(); | 2317 actives->clear(); |
2323 for (const auto& ch : receive_channels_) { | 2318 for (const auto& ch : recv_streams_) { |
2324 int level = GetOutputLevel(ch.second->channel()); | 2319 int level = GetOutputLevel(ch.second->channel()); |
2325 if (level > 0) { | 2320 if (level > 0) { |
2326 actives->push_back(std::make_pair(ch.first, level)); | 2321 actives->push_back(std::make_pair(ch.first, level)); |
2327 } | 2322 } |
2328 } | 2323 } |
2329 return true; | 2324 return true; |
2330 } | 2325 } |
2331 | 2326 |
2332 int WebRtcVoiceMediaChannel::GetOutputLevel() { | 2327 int WebRtcVoiceMediaChannel::GetOutputLevel() { |
2333 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 2328 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
2334 int highest = 0; | 2329 int highest = 0; |
2335 for (const auto& ch : receive_channels_) { | 2330 for (const auto& ch : recv_streams_) { |
2336 highest = std::max(GetOutputLevel(ch.second->channel()), highest); | 2331 highest = std::max(GetOutputLevel(ch.second->channel()), highest); |
2337 } | 2332 } |
2338 return highest; | 2333 return highest; |
2339 } | 2334 } |
2340 | 2335 |
2341 int WebRtcVoiceMediaChannel::GetTimeSinceLastTyping() { | 2336 int WebRtcVoiceMediaChannel::GetTimeSinceLastTyping() { |
2342 int ret; | 2337 int ret; |
2343 if (engine()->voe()->processing()->TimeSinceLastTyping(ret) == -1) { | 2338 if (engine()->voe()->processing()->TimeSinceLastTyping(ret) == -1) { |
2344 // In case of error, log the info and continue | 2339 // In case of error, log the info and continue |
2345 LOG_RTCERR0(TimeSinceLastTyping); | 2340 LOG_RTCERR0(TimeSinceLastTyping); |
(...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2640 sinfo.echo_delay_std_ms = stats.echo_delay_std_ms; | 2635 sinfo.echo_delay_std_ms = stats.echo_delay_std_ms; |
2641 sinfo.echo_return_loss = stats.echo_return_loss; | 2636 sinfo.echo_return_loss = stats.echo_return_loss; |
2642 sinfo.echo_return_loss_enhancement = stats.echo_return_loss_enhancement; | 2637 sinfo.echo_return_loss_enhancement = stats.echo_return_loss_enhancement; |
2643 sinfo.typing_noise_detected = | 2638 sinfo.typing_noise_detected = |
2644 (send_ == SEND_NOTHING ? false : stats.typing_noise_detected); | 2639 (send_ == SEND_NOTHING ? false : stats.typing_noise_detected); |
2645 info->senders.push_back(sinfo); | 2640 info->senders.push_back(sinfo); |
2646 } | 2641 } |
2647 | 2642 |
2648 // Get SSRC and stats for each receiver. | 2643 // Get SSRC and stats for each receiver. |
2649 RTC_DCHECK(info->receivers.size() == 0); | 2644 RTC_DCHECK(info->receivers.size() == 0); |
2650 for (const auto& stream : receive_streams_) { | 2645 for (const auto& stream : recv_streams_) { |
2651 webrtc::AudioReceiveStream::Stats stats = stream.second->GetStats(); | 2646 webrtc::AudioReceiveStream::Stats stats = stream.second->GetStats(); |
2652 VoiceReceiverInfo rinfo; | 2647 VoiceReceiverInfo rinfo; |
2653 rinfo.add_ssrc(stats.remote_ssrc); | 2648 rinfo.add_ssrc(stats.remote_ssrc); |
2654 rinfo.bytes_rcvd = stats.bytes_rcvd; | 2649 rinfo.bytes_rcvd = stats.bytes_rcvd; |
2655 rinfo.packets_rcvd = stats.packets_rcvd; | 2650 rinfo.packets_rcvd = stats.packets_rcvd; |
2656 rinfo.packets_lost = stats.packets_lost; | 2651 rinfo.packets_lost = stats.packets_lost; |
2657 rinfo.fraction_lost = stats.fraction_lost; | 2652 rinfo.fraction_lost = stats.fraction_lost; |
2658 rinfo.codec_name = stats.codec_name; | 2653 rinfo.codec_name = stats.codec_name; |
2659 rinfo.ext_seqnum = stats.ext_seqnum; | 2654 rinfo.ext_seqnum = stats.ext_seqnum; |
2660 rinfo.jitter_ms = stats.jitter_ms; | 2655 rinfo.jitter_ms = stats.jitter_ms; |
(...skipping 21 matching lines...) Expand all Loading... |
2682 } | 2677 } |
2683 | 2678 |
2684 int WebRtcVoiceMediaChannel::GetOutputLevel(int channel) { | 2679 int WebRtcVoiceMediaChannel::GetOutputLevel(int channel) { |
2685 unsigned int ulevel = 0; | 2680 unsigned int ulevel = 0; |
2686 int ret = engine()->voe()->volume()->GetSpeechOutputLevel(channel, ulevel); | 2681 int ret = engine()->voe()->volume()->GetSpeechOutputLevel(channel, ulevel); |
2687 return (ret == 0) ? static_cast<int>(ulevel) : -1; | 2682 return (ret == 0) ? static_cast<int>(ulevel) : -1; |
2688 } | 2683 } |
2689 | 2684 |
2690 int WebRtcVoiceMediaChannel::GetReceiveChannelId(uint32_t ssrc) const { | 2685 int WebRtcVoiceMediaChannel::GetReceiveChannelId(uint32_t ssrc) const { |
2691 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 2686 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
2692 const auto it = receive_channels_.find(ssrc); | 2687 const auto it = recv_streams_.find(ssrc); |
2693 if (it != receive_channels_.end()) { | 2688 if (it != recv_streams_.end()) { |
2694 return it->second->channel(); | 2689 return it->second->channel(); |
2695 } | 2690 } |
2696 return -1; | 2691 return -1; |
2697 } | 2692 } |
2698 | 2693 |
2699 int WebRtcVoiceMediaChannel::GetSendChannelId(uint32_t ssrc) const { | 2694 int WebRtcVoiceMediaChannel::GetSendChannelId(uint32_t ssrc) const { |
2700 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 2695 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
2701 const auto it = send_streams_.find(ssrc); | 2696 const auto it = send_streams_.find(ssrc); |
2702 if (it != send_streams_.end()) { | 2697 if (it != send_streams_.end()) { |
2703 return it->second->channel(); | 2698 return it->second->channel(); |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2756 LOG_RTCERR1(StartPlayout, channel); | 2751 LOG_RTCERR1(StartPlayout, channel); |
2757 return false; | 2752 return false; |
2758 } | 2753 } |
2759 } else { | 2754 } else { |
2760 LOG(LS_INFO) << "Stopping playout for channel #" << channel; | 2755 LOG(LS_INFO) << "Stopping playout for channel #" << channel; |
2761 engine()->voe()->base()->StopPlayout(channel); | 2756 engine()->voe()->base()->StopPlayout(channel); |
2762 } | 2757 } |
2763 return true; | 2758 return true; |
2764 } | 2759 } |
2765 | 2760 |
2766 bool WebRtcVoiceMediaChannel::SetHeaderExtension(ExtensionSetterFunction setter, | |
2767 int channel_id, const RtpHeaderExtension* extension) { | |
2768 bool enable = false; | |
2769 int id = 0; | |
2770 std::string uri; | |
2771 if (extension) { | |
2772 enable = true; | |
2773 id = extension->id; | |
2774 uri = extension->uri; | |
2775 } | |
2776 if ((engine()->voe()->rtp()->*setter)(channel_id, enable, id) != 0) { | |
2777 LOG_RTCERR4(*setter, uri, channel_id, enable, id); | |
2778 return false; | |
2779 } | |
2780 return true; | |
2781 } | |
2782 | |
2783 void WebRtcVoiceMediaChannel::RecreateAudioReceiveStreams() { | |
2784 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | |
2785 for (const auto& it : receive_channels_) { | |
2786 RemoveAudioReceiveStream(it.first); | |
2787 } | |
2788 for (const auto& it : receive_channels_) { | |
2789 AddAudioReceiveStream(it.first); | |
2790 } | |
2791 } | |
2792 | |
2793 void WebRtcVoiceMediaChannel::AddAudioReceiveStream(uint32_t ssrc) { | |
2794 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | |
2795 WebRtcAudioReceiveStream* stream = receive_channels_[ssrc]; | |
2796 RTC_DCHECK(stream != nullptr); | |
2797 RTC_DCHECK(receive_streams_.find(ssrc) == receive_streams_.end()); | |
2798 webrtc::AudioReceiveStream::Config config; | |
2799 config.rtp.remote_ssrc = ssrc; | |
2800 // Only add RTP extensions if we support combined A/V BWE. | |
2801 config.rtp.extensions = recv_rtp_extensions_; | |
2802 config.combined_audio_video_bwe = | |
2803 options_.combined_audio_video_bwe.value_or(false); | |
2804 config.voe_channel_id = stream->channel(); | |
2805 config.sync_group = receive_stream_params_[ssrc].sync_label; | |
2806 webrtc::AudioReceiveStream* s = call_->CreateAudioReceiveStream(config); | |
2807 receive_streams_.insert(std::make_pair(ssrc, s)); | |
2808 } | |
2809 | |
2810 void WebRtcVoiceMediaChannel::RemoveAudioReceiveStream(uint32_t ssrc) { | |
2811 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | |
2812 auto stream_it = receive_streams_.find(ssrc); | |
2813 if (stream_it != receive_streams_.end()) { | |
2814 call_->DestroyAudioReceiveStream(stream_it->second); | |
2815 receive_streams_.erase(stream_it); | |
2816 } | |
2817 } | |
2818 | |
2819 bool WebRtcVoiceMediaChannel::SetRecvCodecsInternal( | 2761 bool WebRtcVoiceMediaChannel::SetRecvCodecsInternal( |
2820 const std::vector<AudioCodec>& new_codecs) { | 2762 const std::vector<AudioCodec>& new_codecs) { |
2821 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 2763 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
2822 for (const AudioCodec& codec : new_codecs) { | 2764 for (const AudioCodec& codec : new_codecs) { |
2823 webrtc::CodecInst voe_codec; | 2765 webrtc::CodecInst voe_codec; |
2824 if (engine()->FindWebRtcCodec(codec, &voe_codec)) { | 2766 if (engine()->FindWebRtcCodec(codec, &voe_codec)) { |
2825 LOG(LS_INFO) << ToString(codec); | 2767 LOG(LS_INFO) << ToString(codec); |
2826 voe_codec.pltype = codec.id; | 2768 voe_codec.pltype = codec.id; |
2827 for (const auto& ch : receive_channels_) { | 2769 for (const auto& ch : recv_streams_) { |
2828 if (engine()->voe()->codec()->SetRecPayloadType( | 2770 if (engine()->voe()->codec()->SetRecPayloadType( |
2829 ch.second->channel(), voe_codec) == -1) { | 2771 ch.second->channel(), voe_codec) == -1) { |
2830 LOG_RTCERR2(SetRecPayloadType, ch.second->channel(), | 2772 LOG_RTCERR2(SetRecPayloadType, ch.second->channel(), |
2831 ToString(voe_codec)); | 2773 ToString(voe_codec)); |
2832 return false; | 2774 return false; |
2833 } | 2775 } |
2834 } | 2776 } |
2835 } else { | 2777 } else { |
2836 LOG(LS_WARNING) << "Unknown codec " << ToString(codec); | 2778 LOG(LS_WARNING) << "Unknown codec " << ToString(codec); |
2837 return false; | 2779 return false; |
2838 } | 2780 } |
2839 } | 2781 } |
2840 return true; | 2782 return true; |
2841 } | 2783 } |
2842 | |
2843 } // namespace cricket | 2784 } // namespace cricket |
2844 | 2785 |
2845 #endif // HAVE_WEBRTC_VOICE | 2786 #endif // HAVE_WEBRTC_VOICE |
OLD | NEW |