blob: 489983e7edc1a353dda18eea4c02608e147267f8 [file] [log] [blame]
pbos@webrtc.org29d58392013-05-16 12:08:03 +00001/*
2 * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
3 *
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
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
pbos@webrtc.org12dc1a32013-08-05 16:22:53 +000011#include <string.h>
mflodman101f2502016-06-09 17:21:19 +020012#include <algorithm>
pbos@webrtc.org29d58392013-05-16 12:08:03 +000013#include <map>
kwibergb25345e2016-03-12 06:10:44 -080014#include <memory>
pbos@webrtc.org29d58392013-05-16 12:08:03 +000015#include <vector>
16
Peter Boström5c389d32015-09-25 13:58:30 +020017#include "webrtc/audio/audio_receive_stream.h"
solenbergc7a8b082015-10-16 14:35:07 -070018#include "webrtc/audio/audio_send_stream.h"
solenberg566ef242015-11-06 15:34:49 -080019#include "webrtc/audio/audio_state.h"
20#include "webrtc/audio/scoped_voe_interface.h"
brandtr4e523862016-10-18 23:50:45 -070021#include "webrtc/base/basictypes.h"
pbos@webrtc.org2b4ce3a2015-03-23 13:12:24 +000022#include "webrtc/base/checks.h"
kwiberg4485ffb2016-04-26 08:14:39 -070023#include "webrtc/base/constructormagic.h"
Peter Boström7c704b82015-12-04 16:13:05 +010024#include "webrtc/base/logging.h"
perkj26091b12016-09-01 01:17:40 -070025#include "webrtc/base/task_queue.h"
pbos@webrtc.org38344ed2014-09-24 06:05:00 +000026#include "webrtc/base/thread_annotations.h"
solenberg5a289392015-10-19 03:39:20 -070027#include "webrtc/base/thread_checker.h"
tommie4f96502015-10-20 23:00:48 -070028#include "webrtc/base/trace_event.h"
pbos@webrtc.org16e03b72013-10-28 16:32:01 +000029#include "webrtc/call.h"
mflodman0e7e2592015-11-12 21:02:42 -080030#include "webrtc/call/bitrate_allocator.h"
pbos@webrtc.orgc49d5b72013-12-05 12:11:47 +000031#include "webrtc/config.h"
skvladcc91d282016-10-03 18:31:22 -070032#include "webrtc/logging/rtc_event_log/rtc_event_log.h"
mflodman0e7e2592015-11-12 21:02:42 -080033#include "webrtc/modules/bitrate_controller/include/bitrate_controller.h"
Stefan Holmer80e12072016-02-23 13:30:42 +010034#include "webrtc/modules/congestion_controller/include/congestion_controller.h"
Henrik Kjellander0b9e29c2015-11-16 11:12:24 +010035#include "webrtc/modules/pacing/paced_sender.h"
brandtr4e523862016-10-18 23:50:45 -070036#include "webrtc/modules/rtp_rtcp/include/flexfec_receiver.h"
Henrik Kjellanderff761fb2015-11-04 08:31:52 +010037#include "webrtc/modules/rtp_rtcp/include/rtp_header_parser.h"
sprang@webrtc.org2a6558c2015-01-28 12:37:36 +000038#include "webrtc/modules/rtp_rtcp/source/byte_io.h"
Henrik Kjellanderff761fb2015-11-04 08:31:52 +010039#include "webrtc/modules/utility/include/process_thread.h"
ivoc14d5dbe2016-07-04 07:06:55 -070040#include "webrtc/system_wrappers/include/clock.h"
Henrik Kjellander98f53512015-10-28 18:17:40 +010041#include "webrtc/system_wrappers/include/cpu_info.h"
42#include "webrtc/system_wrappers/include/critical_section_wrapper.h"
stefan91d92602015-11-11 10:13:02 -080043#include "webrtc/system_wrappers/include/metrics.h"
Henrik Kjellander98f53512015-10-28 18:17:40 +010044#include "webrtc/system_wrappers/include/rw_lock_wrapper.h"
45#include "webrtc/system_wrappers/include/trace.h"
Peter Boström7623ce42015-12-09 12:13:30 +010046#include "webrtc/video/call_stats.h"
asapersson35151f32016-05-02 23:44:01 -070047#include "webrtc/video/send_delay_stats.h"
asapersson250fd972016-09-08 00:07:21 -070048#include "webrtc/video/stats_counter.h"
pbos@webrtc.org16e03b72013-10-28 16:32:01 +000049#include "webrtc/video/video_receive_stream.h"
50#include "webrtc/video/video_send_stream.h"
Stefan Holmer58c664c2016-02-08 14:31:30 +010051#include "webrtc/video/vie_remb.h"
ivocb04965c2015-09-09 00:09:43 -070052#include "webrtc/voice_engine/include/voe_codec.h"
pbos@webrtc.org29d58392013-05-16 12:08:03 +000053
54namespace webrtc {
pbos@webrtc.orgab990ae2014-09-17 09:02:25 +000055
pbos@webrtc.orga73a6782014-10-14 11:52:10 +000056const int Call::Config::kDefaultStartBitrateBps = 300000;
57
pbos@webrtc.org16e03b72013-10-28 16:32:01 +000058namespace internal {
asapersson@webrtc.orgbdc5ed22014-01-31 10:05:07 +000059
perkjec81bcd2016-05-11 06:01:13 -070060class Call : public webrtc::Call,
61 public PacketReceiver,
brandtr4e523862016-10-18 23:50:45 -070062 public RecoveredPacketReceiver,
perkj71ee44c2016-06-15 00:47:53 -070063 public CongestionController::Observer,
64 public BitrateAllocator::LimitObserver {
pbos@webrtc.org16e03b72013-10-28 16:32:01 +000065 public:
Peter Boström45553ae2015-05-08 13:54:38 +020066 explicit Call(const Call::Config& config);
pbos@webrtc.org16e03b72013-10-28 16:32:01 +000067 virtual ~Call();
68
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +000069 PacketReceiver* Receiver() override;
pbos@webrtc.org16e03b72013-10-28 16:32:01 +000070
Fredrik Solenberg04f49312015-06-08 13:04:56 +020071 webrtc::AudioSendStream* CreateAudioSendStream(
72 const webrtc::AudioSendStream::Config& config) override;
73 void DestroyAudioSendStream(webrtc::AudioSendStream* send_stream) override;
74
Fredrik Solenberg23fba1f2015-04-29 15:24:01 +020075 webrtc::AudioReceiveStream* CreateAudioReceiveStream(
76 const webrtc::AudioReceiveStream::Config& config) override;
77 void DestroyAudioReceiveStream(
78 webrtc::AudioReceiveStream* receive_stream) override;
pbos@webrtc.org16e03b72013-10-28 16:32:01 +000079
Fredrik Solenberg23fba1f2015-04-29 15:24:01 +020080 webrtc::VideoSendStream* CreateVideoSendStream(
perkj26091b12016-09-01 01:17:40 -070081 webrtc::VideoSendStream::Config config,
82 VideoEncoderConfig encoder_config) override;
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +000083 void DestroyVideoSendStream(webrtc::VideoSendStream* send_stream) override;
pbos@webrtc.org16e03b72013-10-28 16:32:01 +000084
Fredrik Solenberg23fba1f2015-04-29 15:24:01 +020085 webrtc::VideoReceiveStream* CreateVideoReceiveStream(
Tommi733b5472016-06-10 17:58:01 +020086 webrtc::VideoReceiveStream::Config configuration) override;
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +000087 void DestroyVideoReceiveStream(
88 webrtc::VideoReceiveStream* receive_stream) override;
pbos@webrtc.org16e03b72013-10-28 16:32:01 +000089
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +000090 Stats GetStats() const override;
pbos@webrtc.org16e03b72013-10-28 16:32:01 +000091
stefan68786d22015-09-08 05:36:15 -070092 DeliveryStatus DeliverPacket(MediaType media_type,
93 const uint8_t* packet,
94 size_t length,
95 const PacketTime& packet_time) override;
pbos@webrtc.org16e03b72013-10-28 16:32:01 +000096
brandtr4e523862016-10-18 23:50:45 -070097 // Implements RecoveredPacketReceiver.
98 bool OnRecoveredPacket(const uint8_t* packet, size_t length) override;
99
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000100 void SetBitrateConfig(
101 const webrtc::Call::Config::BitrateConfig& bitrate_config) override;
skvlad7a43d252016-03-22 15:32:27 -0700102
103 void SignalChannelNetworkState(MediaType media, NetworkState state) override;
pbos@webrtc.org26c0c412014-09-03 16:17:12 +0000104
Honghai Zhang0e533ef2016-04-19 15:41:36 -0700105 void OnNetworkRouteChanged(const std::string& transport_name,
106 const rtc::NetworkRoute& network_route) override;
107
stefanc1aeaf02015-10-15 07:26:07 -0700108 void OnSentPacket(const rtc::SentPacket& sent_packet) override;
109
mflodman0e7e2592015-11-12 21:02:42 -0800110 // Implements BitrateObserver.
111 void OnNetworkChanged(uint32_t bitrate_bps, uint8_t fraction_loss,
112 int64_t rtt_ms) override;
113
perkj71ee44c2016-06-15 00:47:53 -0700114 // Implements BitrateAllocator::LimitObserver.
115 void OnAllocationLimitsChanged(uint32_t min_send_bitrate_bps,
116 uint32_t max_padding_bitrate_bps) override;
117
pbos@webrtc.org16e03b72013-10-28 16:32:01 +0000118 private:
Fredrik Solenberg23fba1f2015-04-29 15:24:01 +0200119 DeliveryStatus DeliverRtcp(MediaType media_type, const uint8_t* packet,
120 size_t length);
stefan68786d22015-09-08 05:36:15 -0700121 DeliveryStatus DeliverRtp(MediaType media_type,
122 const uint8_t* packet,
123 size_t length,
124 const PacketTime& packet_time);
pbos8fc7fa72015-07-15 08:02:58 -0700125 void ConfigureSync(const std::string& sync_group)
126 EXCLUSIVE_LOCKS_REQUIRED(receive_crit_);
127
solenberg566ef242015-11-06 15:34:49 -0800128 VoiceEngine* voice_engine() {
129 internal::AudioState* audio_state =
130 static_cast<internal::AudioState*>(config_.audio_state.get());
131 if (audio_state)
132 return audio_state->voice_engine();
133 else
134 return nullptr;
135 }
136
Stefan Holmer226befe2015-11-26 15:36:48 +0100137 void UpdateSendHistograms() EXCLUSIVE_LOCKS_REQUIRED(&bitrate_crit_);
stefan18adf0a2015-11-17 06:24:56 -0800138 void UpdateReceiveHistograms();
asapersson4374a092016-07-27 00:39:09 -0700139 void UpdateHistograms();
skvlad7a43d252016-03-22 15:32:27 -0700140 void UpdateAggregateNetworkState();
stefan91d92602015-11-11 10:13:02 -0800141
Peter Boströmd3c94472015-12-09 11:20:58 +0100142 Clock* const clock_;
stefan91d92602015-11-11 10:13:02 -0800143
Peter Boström45553ae2015-05-08 13:54:38 +0200144 const int num_cpu_cores_;
kwibergb25345e2016-03-12 06:10:44 -0800145 const std::unique_ptr<ProcessThread> module_process_thread_;
146 const std::unique_ptr<ProcessThread> pacer_thread_;
147 const std::unique_ptr<CallStats> call_stats_;
148 const std::unique_ptr<BitrateAllocator> bitrate_allocator_;
pbos@webrtc.org16e03b72013-10-28 16:32:01 +0000149 Call::Config config_;
solenberg5a289392015-10-19 03:39:20 -0700150 rtc::ThreadChecker configuration_thread_checker_;
pbos@webrtc.org16e03b72013-10-28 16:32:01 +0000151
skvlad7a43d252016-03-22 15:32:27 -0700152 NetworkState audio_network_state_;
153 NetworkState video_network_state_;
pbos@webrtc.org16e03b72013-10-28 16:32:01 +0000154
kwibergb25345e2016-03-12 06:10:44 -0800155 std::unique_ptr<RWLockWrapper> receive_crit_;
solenbergc7a8b082015-10-16 14:35:07 -0700156 // Audio and Video receive streams are owned by the client that creates them.
Fredrik Solenberg23fba1f2015-04-29 15:24:01 +0200157 std::map<uint32_t, AudioReceiveStream*> audio_receive_ssrcs_
pbos@webrtc.org26c0c412014-09-03 16:17:12 +0000158 GUARDED_BY(receive_crit_);
Fredrik Solenberg23fba1f2015-04-29 15:24:01 +0200159 std::map<uint32_t, VideoReceiveStream*> video_receive_ssrcs_
160 GUARDED_BY(receive_crit_);
161 std::set<VideoReceiveStream*> video_receive_streams_
162 GUARDED_BY(receive_crit_);
pbos8fc7fa72015-07-15 08:02:58 -0700163 std::map<std::string, AudioReceiveStream*> sync_stream_mapping_
164 GUARDED_BY(receive_crit_);
pbos@webrtc.org26c0c412014-09-03 16:17:12 +0000165
kwibergb25345e2016-03-12 06:10:44 -0800166 std::unique_ptr<RWLockWrapper> send_crit_;
solenbergc7a8b082015-10-16 14:35:07 -0700167 // Audio and Video send streams are owned by the client that creates them.
168 std::map<uint32_t, AudioSendStream*> audio_send_ssrcs_ GUARDED_BY(send_crit_);
Fredrik Solenberg23fba1f2015-04-29 15:24:01 +0200169 std::map<uint32_t, VideoSendStream*> video_send_ssrcs_ GUARDED_BY(send_crit_);
170 std::set<VideoSendStream*> video_send_streams_ GUARDED_BY(send_crit_);
pbos@webrtc.org16e03b72013-10-28 16:32:01 +0000171
Fredrik Solenberg23fba1f2015-04-29 15:24:01 +0200172 VideoSendStream::RtpStateMap suspended_video_send_ssrcs_;
skvlad11a9cbf2016-10-07 11:53:05 -0700173 webrtc::RtcEventLog* event_log_;
ivocb04965c2015-09-09 00:09:43 -0700174
stefan18adf0a2015-11-17 06:24:56 -0800175 // The following members are only accessed (exclusively) from one thread and
176 // from the destructor, and therefore doesn't need any explicit
177 // synchronization.
Stefan Holmer226befe2015-11-26 15:36:48 +0100178 int64_t first_packet_sent_ms_;
asapersson250fd972016-09-08 00:07:21 -0700179 RateCounter received_bytes_per_second_counter_;
180 RateCounter received_audio_bytes_per_second_counter_;
181 RateCounter received_video_bytes_per_second_counter_;
182 RateCounter received_rtcp_bytes_per_second_counter_;
stefan91d92602015-11-11 10:13:02 -0800183
stefan18adf0a2015-11-17 06:24:56 -0800184 // TODO(holmer): Remove this lock once BitrateController no longer calls
185 // OnNetworkChanged from multiple threads.
186 rtc::CriticalSection bitrate_crit_;
perkj71ee44c2016-06-15 00:47:53 -0700187 uint32_t min_allocated_send_bitrate_bps_ GUARDED_BY(&bitrate_crit_);
sprang9c0b5512016-07-06 00:54:28 -0700188 uint32_t configured_max_padding_bitrate_bps_ GUARDED_BY(&bitrate_crit_);
asaperssonce2e1362016-09-09 00:13:35 -0700189 AvgCounter estimated_send_bitrate_kbps_counter_ GUARDED_BY(&bitrate_crit_);
190 AvgCounter pacer_bitrate_kbps_counter_ GUARDED_BY(&bitrate_crit_);
stefan18adf0a2015-11-17 06:24:56 -0800191
Honghai Zhang0e533ef2016-04-19 15:41:36 -0700192 std::map<std::string, rtc::NetworkRoute> network_routes_;
193
Stefan Holmer58c664c2016-02-08 14:31:30 +0100194 VieRemb remb_;
kwibergb25345e2016-03-12 06:10:44 -0800195 const std::unique_ptr<CongestionController> congestion_controller_;
asapersson35151f32016-05-02 23:44:01 -0700196 const std::unique_ptr<SendDelayStats> video_send_delay_stats_;
asapersson4374a092016-07-27 00:39:09 -0700197 const int64_t start_ms_;
perkj26091b12016-09-01 01:17:40 -0700198 // TODO(perkj): |worker_queue_| is supposed to replace
199 // |module_process_thread_|.
200 // |worker_queue| is defined last to ensure all pending tasks are cancelled
201 // and deleted before any other members.
202 rtc::TaskQueue worker_queue_;
mflodman0e7e2592015-11-12 21:02:42 -0800203
henrikg3c089d72015-09-16 05:37:44 -0700204 RTC_DISALLOW_COPY_AND_ASSIGN(Call);
pbos@webrtc.org16e03b72013-10-28 16:32:01 +0000205};
pbos@webrtc.orgc49d5b72013-12-05 12:11:47 +0000206} // namespace internal
pbos@webrtc.orgfd39e132013-08-14 13:52:52 +0000207
asapersson2e5cfcd2016-08-11 08:41:18 -0700208std::string Call::Stats::ToString(int64_t time_ms) const {
209 std::stringstream ss;
210 ss << "Call stats: " << time_ms << ", {";
211 ss << "send_bw_bps: " << send_bandwidth_bps << ", ";
212 ss << "recv_bw_bps: " << recv_bandwidth_bps << ", ";
213 ss << "max_pad_bps: " << max_padding_bitrate_bps << ", ";
214 ss << "pacer_delay_ms: " << pacer_delay_ms << ", ";
215 ss << "rtt_ms: " << rtt_ms;
216 ss << '}';
217 return ss.str();
218}
219
stefan@webrtc.org7e9315b2013-12-04 10:24:26 +0000220Call* Call::Create(const Call::Config& config) {
Peter Boström45553ae2015-05-08 13:54:38 +0200221 return new internal::Call(config);
pbos@webrtc.orgfd39e132013-08-14 13:52:52 +0000222}
pbos@webrtc.orgfd39e132013-08-14 13:52:52 +0000223
pbos@webrtc.org29d58392013-05-16 12:08:03 +0000224namespace internal {
225
Peter Boström45553ae2015-05-08 13:54:38 +0200226Call::Call(const Call::Config& config)
stefan91d92602015-11-11 10:13:02 -0800227 : clock_(Clock::GetRealTimeClock()),
228 num_cpu_cores_(CpuInfo::DetectNumberOfCores()),
kwiberg1c7fdd82016-04-26 08:18:04 -0700229 module_process_thread_(ProcessThread::Create("ModuleProcessThread")),
230 pacer_thread_(ProcessThread::Create("PacerThread")),
Peter Boströmd3c94472015-12-09 11:20:58 +0100231 call_stats_(new CallStats(clock_)),
perkj71ee44c2016-06-15 00:47:53 -0700232 bitrate_allocator_(new BitrateAllocator(this)),
Peter Boström45553ae2015-05-08 13:54:38 +0200233 config_(config),
skvlad7a43d252016-03-22 15:32:27 -0700234 audio_network_state_(kNetworkUp),
235 video_network_state_(kNetworkUp),
pbos@webrtc.org26c0c412014-09-03 16:17:12 +0000236 receive_crit_(RWLockWrapper::CreateRWLock()),
stefan91d92602015-11-11 10:13:02 -0800237 send_crit_(RWLockWrapper::CreateRWLock()),
skvlad11a9cbf2016-10-07 11:53:05 -0700238 event_log_(config.event_log),
Stefan Holmer226befe2015-11-26 15:36:48 +0100239 first_packet_sent_ms_(-1),
asapersson250fd972016-09-08 00:07:21 -0700240 received_bytes_per_second_counter_(clock_, nullptr, true),
241 received_audio_bytes_per_second_counter_(clock_, nullptr, true),
242 received_video_bytes_per_second_counter_(clock_, nullptr, true),
243 received_rtcp_bytes_per_second_counter_(clock_, nullptr, true),
perkj71ee44c2016-06-15 00:47:53 -0700244 min_allocated_send_bitrate_bps_(0),
sprang9c0b5512016-07-06 00:54:28 -0700245 configured_max_padding_bitrate_bps_(0),
asaperssonce2e1362016-09-09 00:13:35 -0700246 estimated_send_bitrate_kbps_counter_(clock_, nullptr, true),
247 pacer_bitrate_kbps_counter_(clock_, nullptr, true),
Stefan Holmer58c664c2016-02-08 14:31:30 +0100248 remb_(clock_),
ivoc14d5dbe2016-07-04 07:06:55 -0700249 congestion_controller_(
skvlad11a9cbf2016-10-07 11:53:05 -0700250 new CongestionController(clock_, this, &remb_, event_log_)),
asapersson4374a092016-07-27 00:39:09 -0700251 video_send_delay_stats_(new SendDelayStats(clock_)),
perkj26091b12016-09-01 01:17:40 -0700252 start_ms_(clock_->TimeInMilliseconds()),
253 worker_queue_("call_worker_queue") {
solenberg56a34df2015-11-12 08:24:41 -0800254 RTC_DCHECK(configuration_thread_checker_.CalledOnValidThread());
skvlad11a9cbf2016-10-07 11:53:05 -0700255 RTC_DCHECK(config.event_log != nullptr);
henrikg91d6ede2015-09-17 00:24:34 -0700256 RTC_DCHECK_GE(config.bitrate_config.min_bitrate_bps, 0);
257 RTC_DCHECK_GE(config.bitrate_config.start_bitrate_bps,
258 config.bitrate_config.min_bitrate_bps);
Stefan Holmere5904162015-03-26 11:11:06 +0100259 if (config.bitrate_config.max_bitrate_bps != -1) {
henrikg91d6ede2015-09-17 00:24:34 -0700260 RTC_DCHECK_GE(config.bitrate_config.max_bitrate_bps,
261 config.bitrate_config.start_bitrate_bps);
pbos@webrtc.org00873182014-11-25 14:03:34 +0000262 }
Peter Boström45553ae2015-05-08 13:54:38 +0200263 Trace::CreateTrace();
Stefan Holmer789ba922016-02-17 15:52:17 +0100264 call_stats_->RegisterStatsObserver(congestion_controller_.get());
Peter Boström45553ae2015-05-08 13:54:38 +0200265
mflodman0c478b32015-10-21 15:52:16 +0200266 congestion_controller_->SetBweBitrates(
267 config_.bitrate_config.min_bitrate_bps,
268 config_.bitrate_config.start_bitrate_bps,
269 config_.bitrate_config.max_bitrate_bps);
Stefan Holmerc379fcb2016-02-24 16:02:55 +0100270
271 module_process_thread_->Start();
272 module_process_thread_->RegisterModule(call_stats_.get());
273 module_process_thread_->RegisterModule(congestion_controller_.get());
274 pacer_thread_->RegisterModule(congestion_controller_->pacer());
275 pacer_thread_->RegisterModule(
276 congestion_controller_->GetRemoteBitrateEstimator(true));
277 pacer_thread_->Start();
pbos@webrtc.org29d58392013-05-16 12:08:03 +0000278}
279
pbos@webrtc.org841c8a42013-09-09 15:04:25 +0000280Call::~Call() {
Stefan Holmer58c664c2016-02-08 14:31:30 +0100281 RTC_DCHECK(!remb_.InUse());
solenberg5a289392015-10-19 03:39:20 -0700282 RTC_DCHECK(configuration_thread_checker_.CalledOnValidThread());
perkj26091b12016-09-01 01:17:40 -0700283
solenbergc7a8b082015-10-16 14:35:07 -0700284 RTC_CHECK(audio_send_ssrcs_.empty());
285 RTC_CHECK(video_send_ssrcs_.empty());
286 RTC_CHECK(video_send_streams_.empty());
287 RTC_CHECK(audio_receive_ssrcs_.empty());
288 RTC_CHECK(video_receive_ssrcs_.empty());
289 RTC_CHECK(video_receive_streams_.empty());
pbos@webrtc.org9e4e5242015-02-12 10:48:23 +0000290
Stefan Holmerc379fcb2016-02-24 16:02:55 +0100291 pacer_thread_->Stop();
292 pacer_thread_->DeRegisterModule(congestion_controller_->pacer());
293 pacer_thread_->DeRegisterModule(
294 congestion_controller_->GetRemoteBitrateEstimator(true));
Stefan Holmer789ba922016-02-17 15:52:17 +0100295 module_process_thread_->DeRegisterModule(congestion_controller_.get());
mflodmane3787022015-10-21 13:24:28 +0200296 module_process_thread_->DeRegisterModule(call_stats_.get());
Peter Boström45553ae2015-05-08 13:54:38 +0200297 module_process_thread_->Stop();
Stefan Holmerc379fcb2016-02-24 16:02:55 +0100298 call_stats_->DeregisterStatsObserver(congestion_controller_.get());
sprang6d6122b2016-07-13 06:37:09 -0700299
300 // Only update histograms after process threads have been shut down, so that
301 // they won't try to concurrently update stats.
perkj26091b12016-09-01 01:17:40 -0700302 {
303 rtc::CritScope lock(&bitrate_crit_);
304 UpdateSendHistograms();
305 }
sprang6d6122b2016-07-13 06:37:09 -0700306 UpdateReceiveHistograms();
asapersson4374a092016-07-27 00:39:09 -0700307 UpdateHistograms();
sprang6d6122b2016-07-13 06:37:09 -0700308
Peter Boström45553ae2015-05-08 13:54:38 +0200309 Trace::ReturnTrace();
pbos@webrtc.org29d58392013-05-16 12:08:03 +0000310}
311
asapersson4374a092016-07-27 00:39:09 -0700312void Call::UpdateHistograms() {
asapersson1d02d3e2016-09-09 22:40:25 -0700313 RTC_HISTOGRAM_COUNTS_100000(
asapersson4374a092016-07-27 00:39:09 -0700314 "WebRTC.Call.LifetimeInSeconds",
315 (clock_->TimeInMilliseconds() - start_ms_) / 1000);
316}
317
stefan18adf0a2015-11-17 06:24:56 -0800318void Call::UpdateSendHistograms() {
asaperssonce2e1362016-09-09 00:13:35 -0700319 if (first_packet_sent_ms_ == -1)
stefan18adf0a2015-11-17 06:24:56 -0800320 return;
321 int64_t elapsed_sec =
322 (clock_->TimeInMilliseconds() - first_packet_sent_ms_) / 1000;
323 if (elapsed_sec < metrics::kMinRunTimeInSeconds)
324 return;
asaperssonce2e1362016-09-09 00:13:35 -0700325 const int kMinRequiredPeriodicSamples = 5;
326 AggregatedStats send_bitrate_stats =
327 estimated_send_bitrate_kbps_counter_.ProcessAndGetStats();
328 if (send_bitrate_stats.num_samples > kMinRequiredPeriodicSamples) {
asapersson1d02d3e2016-09-09 22:40:25 -0700329 RTC_HISTOGRAM_COUNTS_100000("WebRTC.Call.EstimatedSendBitrateInKbps",
330 send_bitrate_stats.average);
stefan18adf0a2015-11-17 06:24:56 -0800331 }
asaperssonce2e1362016-09-09 00:13:35 -0700332 AggregatedStats pacer_bitrate_stats =
333 pacer_bitrate_kbps_counter_.ProcessAndGetStats();
334 if (pacer_bitrate_stats.num_samples > kMinRequiredPeriodicSamples) {
asapersson1d02d3e2016-09-09 22:40:25 -0700335 RTC_HISTOGRAM_COUNTS_100000("WebRTC.Call.PacerBitrateInKbps",
336 pacer_bitrate_stats.average);
stefan18adf0a2015-11-17 06:24:56 -0800337 }
338}
339
340void Call::UpdateReceiveHistograms() {
asapersson250fd972016-09-08 00:07:21 -0700341 const int kMinRequiredPeriodicSamples = 5;
342 AggregatedStats video_bytes_per_sec =
343 received_video_bytes_per_second_counter_.GetStats();
344 if (video_bytes_per_sec.num_samples > kMinRequiredPeriodicSamples) {
asapersson1d02d3e2016-09-09 22:40:25 -0700345 RTC_HISTOGRAM_COUNTS_100000("WebRTC.Call.VideoBitrateReceivedInKbps",
346 video_bytes_per_sec.average * 8 / 1000);
stefan91d92602015-11-11 10:13:02 -0800347 }
asapersson250fd972016-09-08 00:07:21 -0700348 AggregatedStats audio_bytes_per_sec =
349 received_audio_bytes_per_second_counter_.GetStats();
350 if (audio_bytes_per_sec.num_samples > kMinRequiredPeriodicSamples) {
asapersson1d02d3e2016-09-09 22:40:25 -0700351 RTC_HISTOGRAM_COUNTS_100000("WebRTC.Call.AudioBitrateReceivedInKbps",
352 audio_bytes_per_sec.average * 8 / 1000);
stefan91d92602015-11-11 10:13:02 -0800353 }
asapersson250fd972016-09-08 00:07:21 -0700354 AggregatedStats rtcp_bytes_per_sec =
355 received_rtcp_bytes_per_second_counter_.GetStats();
356 if (rtcp_bytes_per_sec.num_samples > kMinRequiredPeriodicSamples) {
asapersson1d02d3e2016-09-09 22:40:25 -0700357 RTC_HISTOGRAM_COUNTS_100000("WebRTC.Call.RtcpBitrateReceivedInBps",
358 rtcp_bytes_per_sec.average * 8);
stefan91d92602015-11-11 10:13:02 -0800359 }
asapersson250fd972016-09-08 00:07:21 -0700360 AggregatedStats recv_bytes_per_sec =
361 received_bytes_per_second_counter_.GetStats();
362 if (recv_bytes_per_sec.num_samples > kMinRequiredPeriodicSamples) {
asapersson1d02d3e2016-09-09 22:40:25 -0700363 RTC_HISTOGRAM_COUNTS_100000("WebRTC.Call.BitrateReceivedInKbps",
364 recv_bytes_per_sec.average * 8 / 1000);
asapersson250fd972016-09-08 00:07:21 -0700365 }
stefan91d92602015-11-11 10:13:02 -0800366}
367
solenberg5a289392015-10-19 03:39:20 -0700368PacketReceiver* Call::Receiver() {
369 // TODO(solenberg): Some test cases in EndToEndTest use this from a different
370 // thread. Re-enable once that is fixed.
371 // RTC_DCHECK(configuration_thread_checker_.CalledOnValidThread());
372 return this;
373}
pbos@webrtc.org29d58392013-05-16 12:08:03 +0000374
Fredrik Solenberg04f49312015-06-08 13:04:56 +0200375webrtc::AudioSendStream* Call::CreateAudioSendStream(
376 const webrtc::AudioSendStream::Config& config) {
solenbergc7a8b082015-10-16 14:35:07 -0700377 TRACE_EVENT0("webrtc", "Call::CreateAudioSendStream");
solenberg5a289392015-10-19 03:39:20 -0700378 RTC_DCHECK(configuration_thread_checker_.CalledOnValidThread());
ivoce0928d82016-10-10 05:12:51 -0700379 event_log_->LogAudioSendStreamConfig(config);
Stefan Holmerb86d4e42015-12-07 10:26:18 +0100380 AudioSendStream* send_stream = new AudioSendStream(
perkj26091b12016-09-01 01:17:40 -0700381 config, config_.audio_state, &worker_queue_, congestion_controller_.get(),
sprang982bf892016-10-13 06:23:11 -0700382 bitrate_allocator_.get(), event_log_);
solenbergc7a8b082015-10-16 14:35:07 -0700383 {
solenbergc7a8b082015-10-16 14:35:07 -0700384 WriteLockScoped write_lock(*send_crit_);
385 RTC_DCHECK(audio_send_ssrcs_.find(config.rtp.ssrc) ==
386 audio_send_ssrcs_.end());
387 audio_send_ssrcs_[config.rtp.ssrc] = send_stream;
solenbergc7a8b082015-10-16 14:35:07 -0700388 }
skvlad7a43d252016-03-22 15:32:27 -0700389 send_stream->SignalNetworkState(audio_network_state_);
390 UpdateAggregateNetworkState();
solenbergc7a8b082015-10-16 14:35:07 -0700391 return send_stream;
Fredrik Solenberg04f49312015-06-08 13:04:56 +0200392}
393
394void Call::DestroyAudioSendStream(webrtc::AudioSendStream* send_stream) {
solenbergc7a8b082015-10-16 14:35:07 -0700395 TRACE_EVENT0("webrtc", "Call::DestroyAudioSendStream");
solenberg5a289392015-10-19 03:39:20 -0700396 RTC_DCHECK(configuration_thread_checker_.CalledOnValidThread());
solenbergc7a8b082015-10-16 14:35:07 -0700397 RTC_DCHECK(send_stream != nullptr);
398
399 send_stream->Stop();
400
401 webrtc::internal::AudioSendStream* audio_send_stream =
402 static_cast<webrtc::internal::AudioSendStream*>(send_stream);
403 {
404 WriteLockScoped write_lock(*send_crit_);
405 size_t num_deleted = audio_send_ssrcs_.erase(
406 audio_send_stream->config().rtp.ssrc);
407 RTC_DCHECK(num_deleted == 1);
408 }
skvlad7a43d252016-03-22 15:32:27 -0700409 UpdateAggregateNetworkState();
solenbergc7a8b082015-10-16 14:35:07 -0700410 delete audio_send_stream;
Fredrik Solenberg04f49312015-06-08 13:04:56 +0200411}
412
Fredrik Solenberg23fba1f2015-04-29 15:24:01 +0200413webrtc::AudioReceiveStream* Call::CreateAudioReceiveStream(
414 const webrtc::AudioReceiveStream::Config& config) {
415 TRACE_EVENT0("webrtc", "Call::CreateAudioReceiveStream");
solenberg5a289392015-10-19 03:39:20 -0700416 RTC_DCHECK(configuration_thread_checker_.CalledOnValidThread());
ivoce0928d82016-10-10 05:12:51 -0700417 event_log_->LogAudioReceiveStreamConfig(config);
skvlad11a9cbf2016-10-07 11:53:05 -0700418 AudioReceiveStream* receive_stream = new AudioReceiveStream(
419 congestion_controller_.get(), config, config_.audio_state, event_log_);
Fredrik Solenberg23fba1f2015-04-29 15:24:01 +0200420 {
421 WriteLockScoped write_lock(*receive_crit_);
henrikg91d6ede2015-09-17 00:24:34 -0700422 RTC_DCHECK(audio_receive_ssrcs_.find(config.rtp.remote_ssrc) ==
423 audio_receive_ssrcs_.end());
Fredrik Solenberg23fba1f2015-04-29 15:24:01 +0200424 audio_receive_ssrcs_[config.rtp.remote_ssrc] = receive_stream;
pbos8fc7fa72015-07-15 08:02:58 -0700425 ConfigureSync(config.sync_group);
Fredrik Solenberg23fba1f2015-04-29 15:24:01 +0200426 }
skvlad7a43d252016-03-22 15:32:27 -0700427 receive_stream->SignalNetworkState(audio_network_state_);
428 UpdateAggregateNetworkState();
Fredrik Solenberg23fba1f2015-04-29 15:24:01 +0200429 return receive_stream;
430}
431
432void Call::DestroyAudioReceiveStream(
433 webrtc::AudioReceiveStream* receive_stream) {
434 TRACE_EVENT0("webrtc", "Call::DestroyAudioReceiveStream");
solenberg5a289392015-10-19 03:39:20 -0700435 RTC_DCHECK(configuration_thread_checker_.CalledOnValidThread());
henrikg91d6ede2015-09-17 00:24:34 -0700436 RTC_DCHECK(receive_stream != nullptr);
solenbergc7a8b082015-10-16 14:35:07 -0700437 webrtc::internal::AudioReceiveStream* audio_receive_stream =
438 static_cast<webrtc::internal::AudioReceiveStream*>(receive_stream);
Fredrik Solenberg23fba1f2015-04-29 15:24:01 +0200439 {
440 WriteLockScoped write_lock(*receive_crit_);
441 size_t num_deleted = audio_receive_ssrcs_.erase(
442 audio_receive_stream->config().rtp.remote_ssrc);
henrikg91d6ede2015-09-17 00:24:34 -0700443 RTC_DCHECK(num_deleted == 1);
pbos8fc7fa72015-07-15 08:02:58 -0700444 const std::string& sync_group = audio_receive_stream->config().sync_group;
445 const auto it = sync_stream_mapping_.find(sync_group);
446 if (it != sync_stream_mapping_.end() &&
447 it->second == audio_receive_stream) {
448 sync_stream_mapping_.erase(it);
449 ConfigureSync(sync_group);
450 }
Fredrik Solenberg23fba1f2015-04-29 15:24:01 +0200451 }
skvlad7a43d252016-03-22 15:32:27 -0700452 UpdateAggregateNetworkState();
Fredrik Solenberg23fba1f2015-04-29 15:24:01 +0200453 delete audio_receive_stream;
454}
455
456webrtc::VideoSendStream* Call::CreateVideoSendStream(
perkj26091b12016-09-01 01:17:40 -0700457 webrtc::VideoSendStream::Config config,
458 VideoEncoderConfig encoder_config) {
pbos@webrtc.org50fe3592015-01-29 12:33:07 +0000459 TRACE_EVENT0("webrtc", "Call::CreateVideoSendStream");
solenberg5a289392015-10-19 03:39:20 -0700460 RTC_DCHECK(configuration_thread_checker_.CalledOnValidThread());
pbos@webrtc.org1819fd72013-06-10 13:48:26 +0000461
asapersson35151f32016-05-02 23:44:01 -0700462 video_send_delay_stats_->AddSsrcs(config);
perkj26091b12016-09-01 01:17:40 -0700463 event_log_->LogVideoSendStreamConfig(config);
464
mflodman@webrtc.orgeb16b812014-06-16 08:57:39 +0000465 // TODO(mflodman): Base the start bitrate on a current bandwidth estimate, if
466 // the call has already started.
perkj26091b12016-09-01 01:17:40 -0700467 // Copy ssrcs from |config| since |config| is moved.
468 std::vector<uint32_t> ssrcs = config.rtp.ssrcs;
mflodman0c478b32015-10-21 15:52:16 +0200469 VideoSendStream* send_stream = new VideoSendStream(
perkj26091b12016-09-01 01:17:40 -0700470 num_cpu_cores_, module_process_thread_.get(), &worker_queue_,
471 call_stats_.get(), congestion_controller_.get(), bitrate_allocator_.get(),
skvlad11a9cbf2016-10-07 11:53:05 -0700472 video_send_delay_stats_.get(), &remb_, event_log_, std::move(config),
473 std::move(encoder_config), suspended_video_send_ssrcs_);
perkj26091b12016-09-01 01:17:40 -0700474
skvlad7a43d252016-03-22 15:32:27 -0700475 {
476 WriteLockScoped write_lock(*send_crit_);
perkj26091b12016-09-01 01:17:40 -0700477 for (uint32_t ssrc : ssrcs) {
skvlad7a43d252016-03-22 15:32:27 -0700478 RTC_DCHECK(video_send_ssrcs_.find(ssrc) == video_send_ssrcs_.end());
479 video_send_ssrcs_[ssrc] = send_stream;
480 }
481 video_send_streams_.insert(send_stream);
pbos@webrtc.org29d58392013-05-16 12:08:03 +0000482 }
skvlad7a43d252016-03-22 15:32:27 -0700483 send_stream->SignalNetworkState(video_network_state_);
484 UpdateAggregateNetworkState();
perkj26091b12016-09-01 01:17:40 -0700485
pbos@webrtc.org29d58392013-05-16 12:08:03 +0000486 return send_stream;
487}
488
pbos@webrtc.org2c46f8d2013-11-21 13:49:43 +0000489void Call::DestroyVideoSendStream(webrtc::VideoSendStream* send_stream) {
pbos@webrtc.org50fe3592015-01-29 12:33:07 +0000490 TRACE_EVENT0("webrtc", "Call::DestroyVideoSendStream");
henrikg91d6ede2015-09-17 00:24:34 -0700491 RTC_DCHECK(send_stream != nullptr);
solenberg5a289392015-10-19 03:39:20 -0700492 RTC_DCHECK(configuration_thread_checker_.CalledOnValidThread());
pbos@webrtc.org95e51f52013-09-05 12:38:54 +0000493
pbos@webrtc.org2bb1bda2014-07-07 13:06:48 +0000494 send_stream->Stop();
495
pbos@webrtc.org2b4ce3a2015-03-23 13:12:24 +0000496 VideoSendStream* send_stream_impl = nullptr;
pbos@webrtc.org95e51f52013-09-05 12:38:54 +0000497 {
pbos@webrtc.org26c0c412014-09-03 16:17:12 +0000498 WriteLockScoped write_lock(*send_crit_);
Fredrik Solenberg23fba1f2015-04-29 15:24:01 +0200499 auto it = video_send_ssrcs_.begin();
500 while (it != video_send_ssrcs_.end()) {
pbos@webrtc.org95e51f52013-09-05 12:38:54 +0000501 if (it->second == static_cast<VideoSendStream*>(send_stream)) {
502 send_stream_impl = it->second;
Fredrik Solenberg23fba1f2015-04-29 15:24:01 +0200503 video_send_ssrcs_.erase(it++);
pbos@webrtc.org2bb1bda2014-07-07 13:06:48 +0000504 } else {
505 ++it;
pbos@webrtc.org95e51f52013-09-05 12:38:54 +0000506 }
507 }
Fredrik Solenberg23fba1f2015-04-29 15:24:01 +0200508 video_send_streams_.erase(send_stream_impl);
pbos@webrtc.org29d58392013-05-16 12:08:03 +0000509 }
henrikg91d6ede2015-09-17 00:24:34 -0700510 RTC_CHECK(send_stream_impl != nullptr);
pbos@webrtc.org95e51f52013-09-05 12:38:54 +0000511
perkj26091b12016-09-01 01:17:40 -0700512 VideoSendStream::RtpStateMap rtp_state =
513 send_stream_impl->StopPermanentlyAndGetRtpStates();
pbos@webrtc.org2bb1bda2014-07-07 13:06:48 +0000514
515 for (VideoSendStream::RtpStateMap::iterator it = rtp_state.begin();
perkj26091b12016-09-01 01:17:40 -0700516 it != rtp_state.end(); ++it) {
Fredrik Solenberg23fba1f2015-04-29 15:24:01 +0200517 suspended_video_send_ssrcs_[it->first] = it->second;
pbos@webrtc.org2bb1bda2014-07-07 13:06:48 +0000518 }
519
skvlad7a43d252016-03-22 15:32:27 -0700520 UpdateAggregateNetworkState();
pbos@webrtc.org95e51f52013-09-05 12:38:54 +0000521 delete send_stream_impl;
pbos@webrtc.org29d58392013-05-16 12:08:03 +0000522}
523
Fredrik Solenberg23fba1f2015-04-29 15:24:01 +0200524webrtc::VideoReceiveStream* Call::CreateVideoReceiveStream(
Tommi733b5472016-06-10 17:58:01 +0200525 webrtc::VideoReceiveStream::Config configuration) {
pbos@webrtc.org50fe3592015-01-29 12:33:07 +0000526 TRACE_EVENT0("webrtc", "Call::CreateVideoReceiveStream");
solenberg5a289392015-10-19 03:39:20 -0700527 RTC_DCHECK(configuration_thread_checker_.CalledOnValidThread());
Peter Boströmc4188fd2015-04-24 15:16:03 +0200528 VideoReceiveStream* receive_stream = new VideoReceiveStream(
Tommi733b5472016-06-10 17:58:01 +0200529 num_cpu_cores_, congestion_controller_.get(), std::move(configuration),
530 voice_engine(), module_process_thread_.get(), call_stats_.get(), &remb_);
531
532 const webrtc::VideoReceiveStream::Config& config = receive_stream->config();
skvlad7a43d252016-03-22 15:32:27 -0700533 {
534 WriteLockScoped write_lock(*receive_crit_);
535 RTC_DCHECK(video_receive_ssrcs_.find(config.rtp.remote_ssrc) ==
536 video_receive_ssrcs_.end());
537 video_receive_ssrcs_[config.rtp.remote_ssrc] = receive_stream;
538 // TODO(pbos): Configure different RTX payloads per receive payload.
539 VideoReceiveStream::Config::Rtp::RtxMap::const_iterator it =
540 config.rtp.rtx.begin();
541 if (it != config.rtp.rtx.end())
542 video_receive_ssrcs_[it->second.ssrc] = receive_stream;
543 video_receive_streams_.insert(receive_stream);
skvlad7a43d252016-03-22 15:32:27 -0700544 ConfigureSync(config.sync_group);
545 }
546 receive_stream->SignalNetworkState(video_network_state_);
547 UpdateAggregateNetworkState();
ivoc14d5dbe2016-07-04 07:06:55 -0700548 event_log_->LogVideoReceiveStreamConfig(config);
pbos@webrtc.org29d58392013-05-16 12:08:03 +0000549 return receive_stream;
550}
551
pbos@webrtc.org2c46f8d2013-11-21 13:49:43 +0000552void Call::DestroyVideoReceiveStream(
553 webrtc::VideoReceiveStream* receive_stream) {
pbos@webrtc.org50fe3592015-01-29 12:33:07 +0000554 TRACE_EVENT0("webrtc", "Call::DestroyVideoReceiveStream");
solenberg5a289392015-10-19 03:39:20 -0700555 RTC_DCHECK(configuration_thread_checker_.CalledOnValidThread());
henrikg91d6ede2015-09-17 00:24:34 -0700556 RTC_DCHECK(receive_stream != nullptr);
pbos@webrtc.org2b4ce3a2015-03-23 13:12:24 +0000557 VideoReceiveStream* receive_stream_impl = nullptr;
pbos@webrtc.org95e51f52013-09-05 12:38:54 +0000558 {
pbos@webrtc.org26c0c412014-09-03 16:17:12 +0000559 WriteLockScoped write_lock(*receive_crit_);
pbos@webrtc.orgc279a5d2014-01-24 09:30:53 +0000560 // Remove all ssrcs pointing to a receive stream. As RTX retransmits on a
561 // separate SSRC there can be either one or two.
Fredrik Solenberg23fba1f2015-04-29 15:24:01 +0200562 auto it = video_receive_ssrcs_.begin();
563 while (it != video_receive_ssrcs_.end()) {
pbos@webrtc.org95e51f52013-09-05 12:38:54 +0000564 if (it->second == static_cast<VideoReceiveStream*>(receive_stream)) {
pbos@webrtc.org2b4ce3a2015-03-23 13:12:24 +0000565 if (receive_stream_impl != nullptr)
henrikg91d6ede2015-09-17 00:24:34 -0700566 RTC_DCHECK(receive_stream_impl == it->second);
pbos@webrtc.org95e51f52013-09-05 12:38:54 +0000567 receive_stream_impl = it->second;
Fredrik Solenberg23fba1f2015-04-29 15:24:01 +0200568 video_receive_ssrcs_.erase(it++);
pbos@webrtc.orgc279a5d2014-01-24 09:30:53 +0000569 } else {
570 ++it;
pbos@webrtc.org95e51f52013-09-05 12:38:54 +0000571 }
572 }
Fredrik Solenberg23fba1f2015-04-29 15:24:01 +0200573 video_receive_streams_.erase(receive_stream_impl);
henrikg91d6ede2015-09-17 00:24:34 -0700574 RTC_CHECK(receive_stream_impl != nullptr);
pbos8fc7fa72015-07-15 08:02:58 -0700575 ConfigureSync(receive_stream_impl->config().sync_group);
pbos@webrtc.org29d58392013-05-16 12:08:03 +0000576 }
skvlad7a43d252016-03-22 15:32:27 -0700577 UpdateAggregateNetworkState();
pbos@webrtc.org95e51f52013-09-05 12:38:54 +0000578 delete receive_stream_impl;
pbos@webrtc.org29d58392013-05-16 12:08:03 +0000579}
580
stefan@webrtc.org0bae1fa2014-11-05 14:05:29 +0000581Call::Stats Call::GetStats() const {
solenberg5a289392015-10-19 03:39:20 -0700582 // TODO(solenberg): Some test cases in EndToEndTest use this from a different
583 // thread. Re-enable once that is fixed.
584 // RTC_DCHECK(configuration_thread_checker_.CalledOnValidThread());
stefan@webrtc.org0bae1fa2014-11-05 14:05:29 +0000585 Stats stats;
Peter Boström45553ae2015-05-08 13:54:38 +0200586 // Fetch available send/receive bitrates.
stefan@webrtc.org0bae1fa2014-11-05 14:05:29 +0000587 uint32_t send_bandwidth = 0;
mflodman0c478b32015-10-21 15:52:16 +0200588 congestion_controller_->GetBitrateController()->AvailableBandwidth(
589 &send_bandwidth);
Peter Boström45553ae2015-05-08 13:54:38 +0200590 std::vector<unsigned int> ssrcs;
stefan@webrtc.org0bae1fa2014-11-05 14:05:29 +0000591 uint32_t recv_bandwidth = 0;
mflodman0c478b32015-10-21 15:52:16 +0200592 congestion_controller_->GetRemoteBitrateEstimator(false)->LatestEstimate(
mflodmana20de202015-10-18 22:08:19 -0700593 &ssrcs, &recv_bandwidth);
Peter Boström45553ae2015-05-08 13:54:38 +0200594 stats.send_bandwidth_bps = send_bandwidth;
stefan@webrtc.org0bae1fa2014-11-05 14:05:29 +0000595 stats.recv_bandwidth_bps = recv_bandwidth;
mflodman0c478b32015-10-21 15:52:16 +0200596 stats.pacer_delay_ms = congestion_controller_->GetPacerQueuingDelayMs();
sprange2d83d62016-02-19 09:03:26 -0800597 stats.rtt_ms = call_stats_->rtcp_rtt_stats()->LastProcessedRtt();
sprang9c0b5512016-07-06 00:54:28 -0700598 {
599 rtc::CritScope cs(&bitrate_crit_);
600 stats.max_padding_bitrate_bps = configured_max_padding_bitrate_bps_;
601 }
stefan@webrtc.org0bae1fa2014-11-05 14:05:29 +0000602 return stats;
pbos@webrtc.org29d58392013-05-16 12:08:03 +0000603}
604
pbos@webrtc.org00873182014-11-25 14:03:34 +0000605void Call::SetBitrateConfig(
606 const webrtc::Call::Config::BitrateConfig& bitrate_config) {
pbos@webrtc.org50fe3592015-01-29 12:33:07 +0000607 TRACE_EVENT0("webrtc", "Call::SetBitrateConfig");
solenberg5a289392015-10-19 03:39:20 -0700608 RTC_DCHECK(configuration_thread_checker_.CalledOnValidThread());
henrikg91d6ede2015-09-17 00:24:34 -0700609 RTC_DCHECK_GE(bitrate_config.min_bitrate_bps, 0);
pbos@webrtc.org2b4ce3a2015-03-23 13:12:24 +0000610 if (bitrate_config.max_bitrate_bps != -1)
henrikg91d6ede2015-09-17 00:24:34 -0700611 RTC_DCHECK_GT(bitrate_config.max_bitrate_bps, 0);
Stefan Holmere5904162015-03-26 11:11:06 +0100612 if (config_.bitrate_config.min_bitrate_bps ==
pbos@webrtc.org00873182014-11-25 14:03:34 +0000613 bitrate_config.min_bitrate_bps &&
614 (bitrate_config.start_bitrate_bps <= 0 ||
Stefan Holmere5904162015-03-26 11:11:06 +0100615 config_.bitrate_config.start_bitrate_bps ==
pbos@webrtc.org00873182014-11-25 14:03:34 +0000616 bitrate_config.start_bitrate_bps) &&
Stefan Holmere5904162015-03-26 11:11:06 +0100617 config_.bitrate_config.max_bitrate_bps ==
pbos@webrtc.org00873182014-11-25 14:03:34 +0000618 bitrate_config.max_bitrate_bps) {
619 // Nothing new to set, early abort to avoid encoder reconfigurations.
620 return;
621 }
Stefan Holmerbe402962016-07-08 16:16:41 +0200622 config_.bitrate_config.min_bitrate_bps = bitrate_config.min_bitrate_bps;
623 // Start bitrate of -1 means we should keep the old bitrate, which there is
624 // no point in remembering for the future.
625 if (bitrate_config.start_bitrate_bps > 0)
626 config_.bitrate_config.start_bitrate_bps = bitrate_config.start_bitrate_bps;
627 config_.bitrate_config.max_bitrate_bps = bitrate_config.max_bitrate_bps;
mflodman0c478b32015-10-21 15:52:16 +0200628 congestion_controller_->SetBweBitrates(bitrate_config.min_bitrate_bps,
629 bitrate_config.start_bitrate_bps,
630 bitrate_config.max_bitrate_bps);
pbos@webrtc.org00873182014-11-25 14:03:34 +0000631}
632
skvlad7a43d252016-03-22 15:32:27 -0700633void Call::SignalChannelNetworkState(MediaType media, NetworkState state) {
solenberg5a289392015-10-19 03:39:20 -0700634 RTC_DCHECK(configuration_thread_checker_.CalledOnValidThread());
skvlad7a43d252016-03-22 15:32:27 -0700635 switch (media) {
636 case MediaType::AUDIO:
637 audio_network_state_ = state;
638 break;
639 case MediaType::VIDEO:
640 video_network_state_ = state;
641 break;
642 case MediaType::ANY:
643 case MediaType::DATA:
644 RTC_NOTREACHED();
645 break;
646 }
647
648 UpdateAggregateNetworkState();
pbos@webrtc.org26c0c412014-09-03 16:17:12 +0000649 {
skvlad7a43d252016-03-22 15:32:27 -0700650 ReadLockScoped read_lock(*send_crit_);
solenbergc7a8b082015-10-16 14:35:07 -0700651 for (auto& kv : audio_send_ssrcs_) {
skvlad7a43d252016-03-22 15:32:27 -0700652 kv.second->SignalNetworkState(audio_network_state_);
solenbergc7a8b082015-10-16 14:35:07 -0700653 }
Fredrik Solenberg23fba1f2015-04-29 15:24:01 +0200654 for (auto& kv : video_send_ssrcs_) {
skvlad7a43d252016-03-22 15:32:27 -0700655 kv.second->SignalNetworkState(video_network_state_);
pbos@webrtc.org26c0c412014-09-03 16:17:12 +0000656 }
657 }
658 {
skvlad7a43d252016-03-22 15:32:27 -0700659 ReadLockScoped read_lock(*receive_crit_);
660 for (auto& kv : audio_receive_ssrcs_) {
661 kv.second->SignalNetworkState(audio_network_state_);
662 }
Fredrik Solenberg23fba1f2015-04-29 15:24:01 +0200663 for (auto& kv : video_receive_ssrcs_) {
skvlad7a43d252016-03-22 15:32:27 -0700664 kv.second->SignalNetworkState(video_network_state_);
pbos@webrtc.org26c0c412014-09-03 16:17:12 +0000665 }
666 }
667}
668
Honghai Zhang0e533ef2016-04-19 15:41:36 -0700669// TODO(honghaiz): Add tests for this method.
670void Call::OnNetworkRouteChanged(const std::string& transport_name,
671 const rtc::NetworkRoute& network_route) {
672 RTC_DCHECK(configuration_thread_checker_.CalledOnValidThread());
673 // Check if the network route is connected.
674 if (!network_route.connected) {
675 LOG(LS_INFO) << "Transport " << transport_name << " is disconnected";
676 // TODO(honghaiz): Perhaps handle this in SignalChannelNetworkState and
677 // consider merging these two methods.
678 return;
679 }
680
681 // Check whether the network route has changed on each transport.
682 auto result =
683 network_routes_.insert(std::make_pair(transport_name, network_route));
684 auto kv = result.first;
685 bool inserted = result.second;
686 if (inserted) {
687 // No need to reset BWE if this is the first time the network connects.
688 return;
689 }
690 if (kv->second != network_route) {
691 kv->second = network_route;
692 LOG(LS_INFO) << "Network route changed on transport " << transport_name
693 << ": new local network id " << network_route.local_network_id
honghaiz059e1832016-06-24 11:03:55 -0700694 << " new remote network id " << network_route.remote_network_id
Stefan Holmer52200d02016-09-20 14:14:23 +0200695 << " Reset bitrates to min: "
696 << config_.bitrate_config.min_bitrate_bps
697 << " bps, start: " << config_.bitrate_config.start_bitrate_bps
698 << " bps, max: " << config_.bitrate_config.start_bitrate_bps
699 << " bps.";
honghaiz059e1832016-06-24 11:03:55 -0700700 congestion_controller_->ResetBweAndBitrates(
701 config_.bitrate_config.start_bitrate_bps,
702 config_.bitrate_config.min_bitrate_bps,
703 config_.bitrate_config.max_bitrate_bps);
Honghai Zhang0e533ef2016-04-19 15:41:36 -0700704 }
705}
706
skvlad7a43d252016-03-22 15:32:27 -0700707void Call::UpdateAggregateNetworkState() {
708 RTC_DCHECK(configuration_thread_checker_.CalledOnValidThread());
709
710 bool have_audio = false;
711 bool have_video = false;
712 {
713 ReadLockScoped read_lock(*send_crit_);
714 if (audio_send_ssrcs_.size() > 0)
715 have_audio = true;
716 if (video_send_ssrcs_.size() > 0)
717 have_video = true;
718 }
719 {
720 ReadLockScoped read_lock(*receive_crit_);
721 if (audio_receive_ssrcs_.size() > 0)
722 have_audio = true;
723 if (video_receive_ssrcs_.size() > 0)
724 have_video = true;
725 }
726
727 NetworkState aggregate_state = kNetworkDown;
728 if ((have_video && video_network_state_ == kNetworkUp) ||
729 (have_audio && audio_network_state_ == kNetworkUp)) {
730 aggregate_state = kNetworkUp;
731 }
732
733 LOG(LS_INFO) << "UpdateAggregateNetworkState: aggregate_state="
734 << (aggregate_state == kNetworkUp ? "up" : "down");
735
736 congestion_controller_->SignalNetworkState(aggregate_state);
737}
738
stefanc1aeaf02015-10-15 07:26:07 -0700739void Call::OnSentPacket(const rtc::SentPacket& sent_packet) {
stefan18adf0a2015-11-17 06:24:56 -0800740 if (first_packet_sent_ms_ == -1)
741 first_packet_sent_ms_ = clock_->TimeInMilliseconds();
asapersson35151f32016-05-02 23:44:01 -0700742 video_send_delay_stats_->OnSentPacket(sent_packet.packet_id,
743 clock_->TimeInMilliseconds());
mflodman0c478b32015-10-21 15:52:16 +0200744 congestion_controller_->OnSentPacket(sent_packet);
stefanc1aeaf02015-10-15 07:26:07 -0700745}
746
mflodman0e7e2592015-11-12 21:02:42 -0800747void Call::OnNetworkChanged(uint32_t target_bitrate_bps, uint8_t fraction_loss,
748 int64_t rtt_ms) {
perkj26091b12016-09-01 01:17:40 -0700749 // TODO(perkj): Consider making sure CongestionController operates on
750 // |worker_queue_|.
751 if (!worker_queue_.IsCurrent()) {
752 worker_queue_.PostTask([this, target_bitrate_bps, fraction_loss, rtt_ms] {
753 OnNetworkChanged(target_bitrate_bps, fraction_loss, rtt_ms);
754 });
755 return;
756 }
757 RTC_DCHECK_RUN_ON(&worker_queue_);
perkj71ee44c2016-06-15 00:47:53 -0700758 bitrate_allocator_->OnNetworkChanged(target_bitrate_bps, fraction_loss,
759 rtt_ms);
mflodman0e7e2592015-11-12 21:02:42 -0800760
asaperssonce2e1362016-09-09 00:13:35 -0700761 // Ignore updates if bitrate is zero (the aggregate network state is down).
762 if (target_bitrate_bps == 0) {
stefan18adf0a2015-11-17 06:24:56 -0800763 rtc::CritScope lock(&bitrate_crit_);
asaperssonce2e1362016-09-09 00:13:35 -0700764 estimated_send_bitrate_kbps_counter_.ProcessAndPause();
765 pacer_bitrate_kbps_counter_.ProcessAndPause();
766 return;
stefan18adf0a2015-11-17 06:24:56 -0800767 }
asaperssonce2e1362016-09-09 00:13:35 -0700768
769 bool sending_video;
770 {
771 ReadLockScoped read_lock(*send_crit_);
772 sending_video = !video_send_streams_.empty();
773 }
774
775 rtc::CritScope lock(&bitrate_crit_);
776 if (!sending_video) {
777 // Do not update the stats if we are not sending video.
778 estimated_send_bitrate_kbps_counter_.ProcessAndPause();
779 pacer_bitrate_kbps_counter_.ProcessAndPause();
780 return;
781 }
782 estimated_send_bitrate_kbps_counter_.Add(target_bitrate_bps / 1000);
783 // Pacer bitrate may be higher than bitrate estimate if enforcing min bitrate.
784 uint32_t pacer_bitrate_bps =
785 std::max(target_bitrate_bps, min_allocated_send_bitrate_bps_);
786 pacer_bitrate_kbps_counter_.Add(pacer_bitrate_bps / 1000);
perkj71ee44c2016-06-15 00:47:53 -0700787}
mflodman101f2502016-06-09 17:21:19 +0200788
perkj71ee44c2016-06-15 00:47:53 -0700789void Call::OnAllocationLimitsChanged(uint32_t min_send_bitrate_bps,
790 uint32_t max_padding_bitrate_bps) {
791 congestion_controller_->SetAllocatedSendBitrateLimits(
792 min_send_bitrate_bps, max_padding_bitrate_bps);
793 rtc::CritScope lock(&bitrate_crit_);
794 min_allocated_send_bitrate_bps_ = min_send_bitrate_bps;
sprang9c0b5512016-07-06 00:54:28 -0700795 configured_max_padding_bitrate_bps_ = max_padding_bitrate_bps;
mflodman0e7e2592015-11-12 21:02:42 -0800796}
797
pbos8fc7fa72015-07-15 08:02:58 -0700798void Call::ConfigureSync(const std::string& sync_group) {
799 // Set sync only if there was no previous one.
solenberg566ef242015-11-06 15:34:49 -0800800 if (voice_engine() == nullptr || sync_group.empty())
pbos8fc7fa72015-07-15 08:02:58 -0700801 return;
802
803 AudioReceiveStream* sync_audio_stream = nullptr;
804 // Find existing audio stream.
805 const auto it = sync_stream_mapping_.find(sync_group);
806 if (it != sync_stream_mapping_.end()) {
807 sync_audio_stream = it->second;
808 } else {
809 // No configured audio stream, see if we can find one.
810 for (const auto& kv : audio_receive_ssrcs_) {
811 if (kv.second->config().sync_group == sync_group) {
812 if (sync_audio_stream != nullptr) {
813 LOG(LS_WARNING) << "Attempting to sync more than one audio stream "
814 "within the same sync group. This is not "
815 "supported in the current implementation.";
816 break;
817 }
818 sync_audio_stream = kv.second;
819 }
820 }
821 }
822 if (sync_audio_stream)
823 sync_stream_mapping_[sync_group] = sync_audio_stream;
824 size_t num_synced_streams = 0;
825 for (VideoReceiveStream* video_stream : video_receive_streams_) {
826 if (video_stream->config().sync_group != sync_group)
827 continue;
828 ++num_synced_streams;
829 if (num_synced_streams > 1) {
830 // TODO(pbos): Support synchronizing more than one A/V pair.
831 // https://code.google.com/p/webrtc/issues/detail?id=4762
832 LOG(LS_WARNING) << "Attempting to sync more than one audio/video pair "
833 "within the same sync group. This is not supported in "
834 "the current implementation.";
835 }
836 // Only sync the first A/V pair within this sync group.
837 if (sync_audio_stream != nullptr && num_synced_streams == 1) {
solenberg566ef242015-11-06 15:34:49 -0800838 video_stream->SetSyncChannel(voice_engine(),
pbos8fc7fa72015-07-15 08:02:58 -0700839 sync_audio_stream->config().voe_channel_id);
840 } else {
solenberg566ef242015-11-06 15:34:49 -0800841 video_stream->SetSyncChannel(voice_engine(), -1);
pbos8fc7fa72015-07-15 08:02:58 -0700842 }
843 }
844}
845
Fredrik Solenberg23fba1f2015-04-29 15:24:01 +0200846PacketReceiver::DeliveryStatus Call::DeliverRtcp(MediaType media_type,
847 const uint8_t* packet,
848 size_t length) {
Peter Boström6f28cf02015-12-07 23:17:15 +0100849 TRACE_EVENT0("webrtc", "Call::DeliverRtcp");
mflodman3d7db262016-04-29 00:57:13 -0700850 // TODO(pbos): Make sure it's a valid packet.
pbos@webrtc.orgcaba2d22014-05-14 13:57:12 +0000851 // Return DELIVERY_UNKNOWN_SSRC if it can be determined that
852 // there's no receiver of the packet.
asapersson250fd972016-09-08 00:07:21 -0700853 if (received_bytes_per_second_counter_.HasSample()) {
854 // First RTP packet has been received.
855 received_bytes_per_second_counter_.Add(static_cast<int>(length));
856 received_rtcp_bytes_per_second_counter_.Add(static_cast<int>(length));
857 }
pbos@webrtc.org29d58392013-05-16 12:08:03 +0000858 bool rtcp_delivered = false;
Fredrik Solenberg23fba1f2015-04-29 15:24:01 +0200859 if (media_type == MediaType::ANY || media_type == MediaType::VIDEO) {
pbos@webrtc.org26c0c412014-09-03 16:17:12 +0000860 ReadLockScoped read_lock(*receive_crit_);
Fredrik Solenberg23fba1f2015-04-29 15:24:01 +0200861 for (VideoReceiveStream* stream : video_receive_streams_) {
mflodman3d7db262016-04-29 00:57:13 -0700862 if (stream->DeliverRtcp(packet, length))
pbos@webrtc.org40523702013-08-05 12:49:22 +0000863 rtcp_delivered = true;
mflodman3d7db262016-04-29 00:57:13 -0700864 }
865 }
866 if (media_type == MediaType::ANY || media_type == MediaType::AUDIO) {
867 ReadLockScoped read_lock(*receive_crit_);
868 for (auto& kv : audio_receive_ssrcs_) {
869 if (kv.second->DeliverRtcp(packet, length))
870 rtcp_delivered = true;
pbos@webrtc.orgbbb07e62013-08-05 12:01:36 +0000871 }
872 }
Fredrik Solenberg23fba1f2015-04-29 15:24:01 +0200873 if (media_type == MediaType::ANY || media_type == MediaType::VIDEO) {
pbos@webrtc.org26c0c412014-09-03 16:17:12 +0000874 ReadLockScoped read_lock(*send_crit_);
Fredrik Solenberg23fba1f2015-04-29 15:24:01 +0200875 for (VideoSendStream* stream : video_send_streams_) {
mflodman3d7db262016-04-29 00:57:13 -0700876 if (stream->DeliverRtcp(packet, length))
pbos@webrtc.org40523702013-08-05 12:49:22 +0000877 rtcp_delivered = true;
pbos@webrtc.org29d58392013-05-16 12:08:03 +0000878 }
879 }
mflodman3d7db262016-04-29 00:57:13 -0700880 if (media_type == MediaType::ANY || media_type == MediaType::AUDIO) {
881 ReadLockScoped read_lock(*send_crit_);
882 for (auto& kv : audio_send_ssrcs_) {
883 if (kv.second->DeliverRtcp(packet, length))
884 rtcp_delivered = true;
885 }
886 }
887
skvlad11a9cbf2016-10-07 11:53:05 -0700888 if (rtcp_delivered)
mflodman3d7db262016-04-29 00:57:13 -0700889 event_log_->LogRtcpPacket(kIncomingPacket, media_type, packet, length);
890
pbos@webrtc.orgcaba2d22014-05-14 13:57:12 +0000891 return rtcp_delivered ? DELIVERY_OK : DELIVERY_PACKET_ERROR;
pbos@webrtc.org29d58392013-05-16 12:08:03 +0000892}
893
Fredrik Solenberg23fba1f2015-04-29 15:24:01 +0200894PacketReceiver::DeliveryStatus Call::DeliverRtp(MediaType media_type,
895 const uint8_t* packet,
stefan68786d22015-09-08 05:36:15 -0700896 size_t length,
897 const PacketTime& packet_time) {
Peter Boström6f28cf02015-12-07 23:17:15 +0100898 TRACE_EVENT0("webrtc", "Call::DeliverRtp");
pbos@webrtc.orgaf38f4e2014-07-08 07:38:12 +0000899 // Minimum RTP header size.
900 if (length < 12)
901 return DELIVERY_PACKET_ERROR;
902
stefan91d92602015-11-11 10:13:02 -0800903 uint32_t ssrc = ByteReader<uint32_t>::ReadBigEndian(&packet[8]);
pbos@webrtc.org26c0c412014-09-03 16:17:12 +0000904 ReadLockScoped read_lock(*receive_crit_);
Fredrik Solenberg23fba1f2015-04-29 15:24:01 +0200905 if (media_type == MediaType::ANY || media_type == MediaType::AUDIO) {
906 auto it = audio_receive_ssrcs_.find(ssrc);
907 if (it != audio_receive_ssrcs_.end()) {
asapersson250fd972016-09-08 00:07:21 -0700908 received_bytes_per_second_counter_.Add(static_cast<int>(length));
909 received_audio_bytes_per_second_counter_.Add(static_cast<int>(length));
ivocb04965c2015-09-09 00:09:43 -0700910 auto status = it->second->DeliverRtp(packet, length, packet_time)
911 ? DELIVERY_OK
912 : DELIVERY_PACKET_ERROR;
ivoc14d5dbe2016-07-04 07:06:55 -0700913 if (status == DELIVERY_OK)
terelius429c3452016-01-21 05:42:04 -0800914 event_log_->LogRtpHeader(kIncomingPacket, media_type, packet, length);
ivocb04965c2015-09-09 00:09:43 -0700915 return status;
Fredrik Solenberg23fba1f2015-04-29 15:24:01 +0200916 }
917 }
918 if (media_type == MediaType::ANY || media_type == MediaType::VIDEO) {
919 auto it = video_receive_ssrcs_.find(ssrc);
920 if (it != video_receive_ssrcs_.end()) {
asapersson250fd972016-09-08 00:07:21 -0700921 received_bytes_per_second_counter_.Add(static_cast<int>(length));
922 received_video_bytes_per_second_counter_.Add(static_cast<int>(length));
ivocb04965c2015-09-09 00:09:43 -0700923 auto status = it->second->DeliverRtp(packet, length, packet_time)
924 ? DELIVERY_OK
925 : DELIVERY_PACKET_ERROR;
ivoc14d5dbe2016-07-04 07:06:55 -0700926 if (status == DELIVERY_OK)
terelius429c3452016-01-21 05:42:04 -0800927 event_log_->LogRtpHeader(kIncomingPacket, media_type, packet, length);
ivocb04965c2015-09-09 00:09:43 -0700928 return status;
Fredrik Solenberg23fba1f2015-04-29 15:24:01 +0200929 }
930 }
931 return DELIVERY_UNKNOWN_SSRC;
pbos@webrtc.org29d58392013-05-16 12:08:03 +0000932}
933
stefan68786d22015-09-08 05:36:15 -0700934PacketReceiver::DeliveryStatus Call::DeliverPacket(
935 MediaType media_type,
936 const uint8_t* packet,
937 size_t length,
938 const PacketTime& packet_time) {
solenberg5a289392015-10-19 03:39:20 -0700939 // TODO(solenberg): Tests call this function on a network thread, libjingle
940 // calls on the worker thread. We should move towards always using a network
941 // thread. Then this check can be enabled.
942 // RTC_DCHECK(!configuration_thread_checker_.CalledOnValidThread());
pbos@webrtc.org62bafae2014-07-08 12:10:51 +0000943 if (RtpHeaderParser::IsRtcp(packet, length))
Fredrik Solenberg23fba1f2015-04-29 15:24:01 +0200944 return DeliverRtcp(media_type, packet, length);
pbos@webrtc.org29d58392013-05-16 12:08:03 +0000945
stefan68786d22015-09-08 05:36:15 -0700946 return DeliverRtp(media_type, packet, length, packet_time);
pbos@webrtc.org29d58392013-05-16 12:08:03 +0000947}
948
brandtr4e523862016-10-18 23:50:45 -0700949// TODO(brandtr): Update this member function when we support protecting
950// audio packets with FlexFEC.
951bool Call::OnRecoveredPacket(const uint8_t* packet, size_t length) {
952 uint32_t ssrc = ByteReader<uint32_t>::ReadBigEndian(&packet[8]);
953 ReadLockScoped read_lock(*receive_crit_);
954 auto it = video_receive_ssrcs_.find(ssrc);
955 if (it == video_receive_ssrcs_.end())
956 return false;
957 return it->second->OnRecoveredPacket(packet, length);
958}
959
pbos@webrtc.org29d58392013-05-16 12:08:03 +0000960} // namespace internal
961} // namespace webrtc