129d5839233b19743286a89676bd748a6bd8623d6pbos@webrtc.org/*
229d5839233b19743286a89676bd748a6bd8623d6pbos@webrtc.org *  Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
329d5839233b19743286a89676bd748a6bd8623d6pbos@webrtc.org *
429d5839233b19743286a89676bd748a6bd8623d6pbos@webrtc.org *  Use of this source code is governed by a BSD-style license
529d5839233b19743286a89676bd748a6bd8623d6pbos@webrtc.org *  that can be found in the LICENSE file in the root of the source
629d5839233b19743286a89676bd748a6bd8623d6pbos@webrtc.org *  tree. An additional intellectual property rights grant can be found
729d5839233b19743286a89676bd748a6bd8623d6pbos@webrtc.org *  in the file PATENTS.  All contributing project authors may
829d5839233b19743286a89676bd748a6bd8623d6pbos@webrtc.org *  be found in the AUTHORS file in the root of the source tree.
929d5839233b19743286a89676bd748a6bd8623d6pbos@webrtc.org */
1029d5839233b19743286a89676bd748a6bd8623d6pbos@webrtc.org
1112dc1a38ca54a000e4fecfbc6d41138b895c9ca5pbos@webrtc.org#include <string.h>
1212dc1a38ca54a000e4fecfbc6d41138b895c9ca5pbos@webrtc.org
1329d5839233b19743286a89676bd748a6bd8623d6pbos@webrtc.org#include <map>
1429d5839233b19743286a89676bd748a6bd8623d6pbos@webrtc.org#include <vector>
1529d5839233b19743286a89676bd748a6bd8623d6pbos@webrtc.org
165c389d3e09646c0e2ed76d5ccb37a3419a09eb6aPeter Boström#include "webrtc/audio/audio_receive_stream.h"
17c7a8b08a7cd8d8f37d7f5fb9930d0cdc74baba35solenberg#include "webrtc/audio/audio_send_stream.h"
18566ef247b9779f6c9d0e7ec9eea6b037f4682c53solenberg#include "webrtc/audio/audio_state.h"
19566ef247b9779f6c9d0e7ec9eea6b037f4682c53solenberg#include "webrtc/audio/scoped_voe_interface.h"
202b4ce3a501b8d679f84c1ad10317dea5c78fa595pbos@webrtc.org#include "webrtc/base/checks.h"
217c704b82893bbe7fc206b004fb9dfe6e69a986efPeter Boström#include "webrtc/base/logging.h"
2200b8f6b3643332cce1ee711715f7fbb824d793cakwiberg@webrtc.org#include "webrtc/base/scoped_ptr.h"
2338344ed2806c8fed60d67d280ca44c32e36707c0pbos@webrtc.org#include "webrtc/base/thread_annotations.h"
245a289393928c18af580c6339ba77600fb67006e2solenberg#include "webrtc/base/thread_checker.h"
25e4f96501fc5b3e6de0d1ccd262372afcda1f5b4ftommi#include "webrtc/base/trace_event.h"
2616e03b7bd8b88ba569987e20a7f29061f91a3d0dpbos@webrtc.org#include "webrtc/call.h"
270e7e259ebd69993bb5670a991f43aa1b06c9bf9emflodman#include "webrtc/call/bitrate_allocator.h"
280c478b3d75be3c026e68f03a11cb558c3655c926mflodman#include "webrtc/call/congestion_controller.h"
295c389d3e09646c0e2ed76d5ccb37a3419a09eb6aPeter Boström#include "webrtc/call/rtc_event_log.h"
307e9315b42ebe8f7df860030af93618de81326503stefan@webrtc.org#include "webrtc/common.h"
31c49d5b7df8afb45816f2816610aa85a28a76c714pbos@webrtc.org#include "webrtc/config.h"
320e7e259ebd69993bb5670a991f43aa1b06c9bf9emflodman#include "webrtc/modules/bitrate_controller/include/bitrate_controller.h"
330b9e29c87da2d9c1a3792d2c87197b0688b68e4eHenrik Kjellander#include "webrtc/modules/pacing/paced_sender.h"
34ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander#include "webrtc/modules/rtp_rtcp/include/rtp_header_parser.h"
352a6558c2a51a0aa610e85455ea7a35cfaf39bec8sprang@webrtc.org#include "webrtc/modules/rtp_rtcp/source/byte_io.h"
36ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander#include "webrtc/modules/utility/include/process_thread.h"
3798f53510b222f71fdd8b799b2f33737ceeb28c61Henrik Kjellander#include "webrtc/system_wrappers/include/cpu_info.h"
3898f53510b222f71fdd8b799b2f33737ceeb28c61Henrik Kjellander#include "webrtc/system_wrappers/include/critical_section_wrapper.h"
3991d926038f7cebf889ef843f2f087d72bc8c60c2stefan#include "webrtc/system_wrappers/include/metrics.h"
4098f53510b222f71fdd8b799b2f33737ceeb28c61Henrik Kjellander#include "webrtc/system_wrappers/include/rw_lock_wrapper.h"
4198f53510b222f71fdd8b799b2f33737ceeb28c61Henrik Kjellander#include "webrtc/system_wrappers/include/trace.h"
427623ce4aeb9130c937ba5836490cbb3a35679e79Peter Boström#include "webrtc/video/call_stats.h"
4316e03b7bd8b88ba569987e20a7f29061f91a3d0dpbos@webrtc.org#include "webrtc/video/video_receive_stream.h"
4416e03b7bd8b88ba569987e20a7f29061f91a3d0dpbos@webrtc.org#include "webrtc/video/video_send_stream.h"
45b04965ccf83c2bc6e2758abab9bea0c18551a54civoc#include "webrtc/voice_engine/include/voe_codec.h"
4629d5839233b19743286a89676bd748a6bd8623d6pbos@webrtc.org
4729d5839233b19743286a89676bd748a6bd8623d6pbos@webrtc.orgnamespace webrtc {
48ab990ae43a2b84b103cb3c50bc38502375c13e68pbos@webrtc.org
49a73a678e25bfec7d89a1a241419897ee8a64f7b0pbos@webrtc.orgconst int Call::Config::kDefaultStartBitrateBps = 300000;
50a73a678e25bfec7d89a1a241419897ee8a64f7b0pbos@webrtc.org
5116e03b7bd8b88ba569987e20a7f29061f91a3d0dpbos@webrtc.orgnamespace internal {
52bdc5ed2e7d081de6597f0f993d54489eb3abd496asapersson@webrtc.org
530e7e259ebd69993bb5670a991f43aa1b06c9bf9emflodmanclass Call : public webrtc::Call, public PacketReceiver,
540e7e259ebd69993bb5670a991f43aa1b06c9bf9emflodman             public BitrateObserver {
5516e03b7bd8b88ba569987e20a7f29061f91a3d0dpbos@webrtc.org public:
5645553aefacb797818da83ccef1c3679a8aa0fc7fPeter Boström  explicit Call(const Call::Config& config);
5716e03b7bd8b88ba569987e20a7f29061f91a3d0dpbos@webrtc.org  virtual ~Call();
5816e03b7bd8b88ba569987e20a7f29061f91a3d0dpbos@webrtc.org
5914665ff7d4024d07e58622f498b23fd980001871kjellander@webrtc.org  PacketReceiver* Receiver() override;
6016e03b7bd8b88ba569987e20a7f29061f91a3d0dpbos@webrtc.org
6104f4931ef06273c2873e7816ed1f568d445117b8Fredrik Solenberg  webrtc::AudioSendStream* CreateAudioSendStream(
6204f4931ef06273c2873e7816ed1f568d445117b8Fredrik Solenberg      const webrtc::AudioSendStream::Config& config) override;
6304f4931ef06273c2873e7816ed1f568d445117b8Fredrik Solenberg  void DestroyAudioSendStream(webrtc::AudioSendStream* send_stream) override;
6404f4931ef06273c2873e7816ed1f568d445117b8Fredrik Solenberg
6523fba1ffa0079f70744a83bcf4e85501dc226013Fredrik Solenberg  webrtc::AudioReceiveStream* CreateAudioReceiveStream(
6623fba1ffa0079f70744a83bcf4e85501dc226013Fredrik Solenberg      const webrtc::AudioReceiveStream::Config& config) override;
6723fba1ffa0079f70744a83bcf4e85501dc226013Fredrik Solenberg  void DestroyAudioReceiveStream(
6823fba1ffa0079f70744a83bcf4e85501dc226013Fredrik Solenberg      webrtc::AudioReceiveStream* receive_stream) override;
6916e03b7bd8b88ba569987e20a7f29061f91a3d0dpbos@webrtc.org
7023fba1ffa0079f70744a83bcf4e85501dc226013Fredrik Solenberg  webrtc::VideoSendStream* CreateVideoSendStream(
7123fba1ffa0079f70744a83bcf4e85501dc226013Fredrik Solenberg      const webrtc::VideoSendStream::Config& config,
7223fba1ffa0079f70744a83bcf4e85501dc226013Fredrik Solenberg      const VideoEncoderConfig& encoder_config) override;
7314665ff7d4024d07e58622f498b23fd980001871kjellander@webrtc.org  void DestroyVideoSendStream(webrtc::VideoSendStream* send_stream) override;
7416e03b7bd8b88ba569987e20a7f29061f91a3d0dpbos@webrtc.org
7523fba1ffa0079f70744a83bcf4e85501dc226013Fredrik Solenberg  webrtc::VideoReceiveStream* CreateVideoReceiveStream(
7623fba1ffa0079f70744a83bcf4e85501dc226013Fredrik Solenberg      const webrtc::VideoReceiveStream::Config& config) override;
7714665ff7d4024d07e58622f498b23fd980001871kjellander@webrtc.org  void DestroyVideoReceiveStream(
7814665ff7d4024d07e58622f498b23fd980001871kjellander@webrtc.org      webrtc::VideoReceiveStream* receive_stream) override;
7916e03b7bd8b88ba569987e20a7f29061f91a3d0dpbos@webrtc.org
8014665ff7d4024d07e58622f498b23fd980001871kjellander@webrtc.org  Stats GetStats() const override;
8116e03b7bd8b88ba569987e20a7f29061f91a3d0dpbos@webrtc.org
8268786d20400f1f3744ad83549325665c18ea9e5bstefan  DeliveryStatus DeliverPacket(MediaType media_type,
8368786d20400f1f3744ad83549325665c18ea9e5bstefan                               const uint8_t* packet,
8468786d20400f1f3744ad83549325665c18ea9e5bstefan                               size_t length,
8568786d20400f1f3744ad83549325665c18ea9e5bstefan                               const PacketTime& packet_time) override;
8616e03b7bd8b88ba569987e20a7f29061f91a3d0dpbos@webrtc.org
8714665ff7d4024d07e58622f498b23fd980001871kjellander@webrtc.org  void SetBitrateConfig(
8814665ff7d4024d07e58622f498b23fd980001871kjellander@webrtc.org      const webrtc::Call::Config::BitrateConfig& bitrate_config) override;
8914665ff7d4024d07e58622f498b23fd980001871kjellander@webrtc.org  void SignalNetworkState(NetworkState state) override;
9026c0c41a06d77af54df547169d952a21319dea8cpbos@webrtc.org
91c1aeaf0dc37d96f31c92f893f4e30e7a5f7cc2b7stefan  void OnSentPacket(const rtc::SentPacket& sent_packet) override;
92c1aeaf0dc37d96f31c92f893f4e30e7a5f7cc2b7stefan
930e7e259ebd69993bb5670a991f43aa1b06c9bf9emflodman  // Implements BitrateObserver.
940e7e259ebd69993bb5670a991f43aa1b06c9bf9emflodman  void OnNetworkChanged(uint32_t bitrate_bps, uint8_t fraction_loss,
950e7e259ebd69993bb5670a991f43aa1b06c9bf9emflodman                        int64_t rtt_ms) override;
960e7e259ebd69993bb5670a991f43aa1b06c9bf9emflodman
9716e03b7bd8b88ba569987e20a7f29061f91a3d0dpbos@webrtc.org private:
9823fba1ffa0079f70744a83bcf4e85501dc226013Fredrik Solenberg  DeliveryStatus DeliverRtcp(MediaType media_type, const uint8_t* packet,
9923fba1ffa0079f70744a83bcf4e85501dc226013Fredrik Solenberg                             size_t length);
10068786d20400f1f3744ad83549325665c18ea9e5bstefan  DeliveryStatus DeliverRtp(MediaType media_type,
10168786d20400f1f3744ad83549325665c18ea9e5bstefan                            const uint8_t* packet,
10268786d20400f1f3744ad83549325665c18ea9e5bstefan                            size_t length,
10368786d20400f1f3744ad83549325665c18ea9e5bstefan                            const PacketTime& packet_time);
10416e03b7bd8b88ba569987e20a7f29061f91a3d0dpbos@webrtc.org
1058fc7fa798f7a36955f1b933980401afad2aff592pbos  void ConfigureSync(const std::string& sync_group)
1068fc7fa798f7a36955f1b933980401afad2aff592pbos      EXCLUSIVE_LOCKS_REQUIRED(receive_crit_);
1078fc7fa798f7a36955f1b933980401afad2aff592pbos
108566ef247b9779f6c9d0e7ec9eea6b037f4682c53solenberg  VoiceEngine* voice_engine() {
109566ef247b9779f6c9d0e7ec9eea6b037f4682c53solenberg    internal::AudioState* audio_state =
110566ef247b9779f6c9d0e7ec9eea6b037f4682c53solenberg        static_cast<internal::AudioState*>(config_.audio_state.get());
111566ef247b9779f6c9d0e7ec9eea6b037f4682c53solenberg    if (audio_state)
112566ef247b9779f6c9d0e7ec9eea6b037f4682c53solenberg      return audio_state->voice_engine();
113566ef247b9779f6c9d0e7ec9eea6b037f4682c53solenberg    else
114566ef247b9779f6c9d0e7ec9eea6b037f4682c53solenberg      return nullptr;
115566ef247b9779f6c9d0e7ec9eea6b037f4682c53solenberg  }
116566ef247b9779f6c9d0e7ec9eea6b037f4682c53solenberg
117226befecfb5e56287482a2d6250f01d019761884Stefan Holmer  void UpdateSendHistograms() EXCLUSIVE_LOCKS_REQUIRED(&bitrate_crit_);
11818adf0a79d4a0ea124c7f27fd553382d0b0cb7acstefan  void UpdateReceiveHistograms();
11991d926038f7cebf889ef843f2f087d72bc8c60c2stefan
120d3c944755ec546f46d5bdd84bff359fe6c4639e9Peter Boström  Clock* const clock_;
12191d926038f7cebf889ef843f2f087d72bc8c60c2stefan
12245553aefacb797818da83ccef1c3679a8aa0fc7fPeter Boström  const int num_cpu_cores_;
12345553aefacb797818da83ccef1c3679a8aa0fc7fPeter Boström  const rtc::scoped_ptr<ProcessThread> module_process_thread_;
124e37870297fc45f1253dff4b1c59c85a50d2a8a97mflodman  const rtc::scoped_ptr<CallStats> call_stats_;
1250e7e259ebd69993bb5670a991f43aa1b06c9bf9emflodman  const rtc::scoped_ptr<BitrateAllocator> bitrate_allocator_;
12616e03b7bd8b88ba569987e20a7f29061f91a3d0dpbos@webrtc.org  Call::Config config_;
1275a289393928c18af580c6339ba77600fb67006e2solenberg  rtc::ThreadChecker configuration_thread_checker_;
12816e03b7bd8b88ba569987e20a7f29061f91a3d0dpbos@webrtc.org
129ea07373a2eb46f2732a8b5acef06a9b5078f37f8Fredrik Solenberg  bool network_enabled_;
13026c0c41a06d77af54df547169d952a21319dea8cpbos@webrtc.org
13100b8f6b3643332cce1ee711715f7fbb824d793cakwiberg@webrtc.org  rtc::scoped_ptr<RWLockWrapper> receive_crit_;
132c7a8b08a7cd8d8f37d7f5fb9930d0cdc74baba35solenberg  // Audio and Video receive streams are owned by the client that creates them.
13323fba1ffa0079f70744a83bcf4e85501dc226013Fredrik Solenberg  std::map<uint32_t, AudioReceiveStream*> audio_receive_ssrcs_
13423fba1ffa0079f70744a83bcf4e85501dc226013Fredrik Solenberg      GUARDED_BY(receive_crit_);
13523fba1ffa0079f70744a83bcf4e85501dc226013Fredrik Solenberg  std::map<uint32_t, VideoReceiveStream*> video_receive_ssrcs_
13623fba1ffa0079f70744a83bcf4e85501dc226013Fredrik Solenberg      GUARDED_BY(receive_crit_);
13723fba1ffa0079f70744a83bcf4e85501dc226013Fredrik Solenberg  std::set<VideoReceiveStream*> video_receive_streams_
13826c0c41a06d77af54df547169d952a21319dea8cpbos@webrtc.org      GUARDED_BY(receive_crit_);
1398fc7fa798f7a36955f1b933980401afad2aff592pbos  std::map<std::string, AudioReceiveStream*> sync_stream_mapping_
1408fc7fa798f7a36955f1b933980401afad2aff592pbos      GUARDED_BY(receive_crit_);
14116e03b7bd8b88ba569987e20a7f29061f91a3d0dpbos@webrtc.org
14200b8f6b3643332cce1ee711715f7fbb824d793cakwiberg@webrtc.org  rtc::scoped_ptr<RWLockWrapper> send_crit_;
143c7a8b08a7cd8d8f37d7f5fb9930d0cdc74baba35solenberg  // Audio and Video send streams are owned by the client that creates them.
144c7a8b08a7cd8d8f37d7f5fb9930d0cdc74baba35solenberg  std::map<uint32_t, AudioSendStream*> audio_send_ssrcs_ GUARDED_BY(send_crit_);
14523fba1ffa0079f70744a83bcf4e85501dc226013Fredrik Solenberg  std::map<uint32_t, VideoSendStream*> video_send_ssrcs_ GUARDED_BY(send_crit_);
14623fba1ffa0079f70744a83bcf4e85501dc226013Fredrik Solenberg  std::set<VideoSendStream*> video_send_streams_ GUARDED_BY(send_crit_);
14716e03b7bd8b88ba569987e20a7f29061f91a3d0dpbos@webrtc.org
14823fba1ffa0079f70744a83bcf4e85501dc226013Fredrik Solenberg  VideoSendStream::RtpStateMap suspended_video_send_ssrcs_;
1492bb1bdab8d11f5445693c028335fb3ace631f636pbos@webrtc.org
1504f4ec0a9270a8cefadfa12e9fa3b979b58b15392Fredrik Solenberg  RtcEventLog* event_log_ = nullptr;
151b04965ccf83c2bc6e2758abab9bea0c18551a54civoc
15218adf0a79d4a0ea124c7f27fd553382d0b0cb7acstefan  // The following members are only accessed (exclusively) from one thread and
15318adf0a79d4a0ea124c7f27fd553382d0b0cb7acstefan  // from the destructor, and therefore doesn't need any explicit
15418adf0a79d4a0ea124c7f27fd553382d0b0cb7acstefan  // synchronization.
155226befecfb5e56287482a2d6250f01d019761884Stefan Holmer  int64_t received_video_bytes_;
156226befecfb5e56287482a2d6250f01d019761884Stefan Holmer  int64_t received_audio_bytes_;
157226befecfb5e56287482a2d6250f01d019761884Stefan Holmer  int64_t received_rtcp_bytes_;
15891d926038f7cebf889ef843f2f087d72bc8c60c2stefan  int64_t first_rtp_packet_received_ms_;
159226befecfb5e56287482a2d6250f01d019761884Stefan Holmer  int64_t last_rtp_packet_received_ms_;
160226befecfb5e56287482a2d6250f01d019761884Stefan Holmer  int64_t first_packet_sent_ms_;
16191d926038f7cebf889ef843f2f087d72bc8c60c2stefan
16218adf0a79d4a0ea124c7f27fd553382d0b0cb7acstefan  // TODO(holmer): Remove this lock once BitrateController no longer calls
16318adf0a79d4a0ea124c7f27fd553382d0b0cb7acstefan  // OnNetworkChanged from multiple threads.
16418adf0a79d4a0ea124c7f27fd553382d0b0cb7acstefan  rtc::CriticalSection bitrate_crit_;
165226befecfb5e56287482a2d6250f01d019761884Stefan Holmer  int64_t estimated_send_bitrate_sum_kbits_ GUARDED_BY(&bitrate_crit_);
166226befecfb5e56287482a2d6250f01d019761884Stefan Holmer  int64_t pacer_bitrate_sum_kbits_ GUARDED_BY(&bitrate_crit_);
167226befecfb5e56287482a2d6250f01d019761884Stefan Holmer  int64_t num_bitrate_updates_ GUARDED_BY(&bitrate_crit_);
16818adf0a79d4a0ea124c7f27fd553382d0b0cb7acstefan
1690e7e259ebd69993bb5670a991f43aa1b06c9bf9emflodman  const rtc::scoped_ptr<CongestionController> congestion_controller_;
1700e7e259ebd69993bb5670a991f43aa1b06c9bf9emflodman
1713c089d751ede283e21e186885eaf705c3257ccd2henrikg  RTC_DISALLOW_COPY_AND_ASSIGN(Call);
17216e03b7bd8b88ba569987e20a7f29061f91a3d0dpbos@webrtc.org};
173c49d5b7df8afb45816f2816610aa85a28a76c714pbos@webrtc.org}  // namespace internal
174fd39e13c8062cb47a93c6adcf2078c1d2a0f501bpbos@webrtc.org
1757e9315b42ebe8f7df860030af93618de81326503stefan@webrtc.orgCall* Call::Create(const Call::Config& config) {
17645553aefacb797818da83ccef1c3679a8aa0fc7fPeter Boström  return new internal::Call(config);
177fd39e13c8062cb47a93c6adcf2078c1d2a0f501bpbos@webrtc.org}
178fd39e13c8062cb47a93c6adcf2078c1d2a0f501bpbos@webrtc.org
17929d5839233b19743286a89676bd748a6bd8623d6pbos@webrtc.orgnamespace internal {
18029d5839233b19743286a89676bd748a6bd8623d6pbos@webrtc.org
18145553aefacb797818da83ccef1c3679a8aa0fc7fPeter BoströmCall::Call(const Call::Config& config)
18291d926038f7cebf889ef843f2f087d72bc8c60c2stefan    : clock_(Clock::GetRealTimeClock()),
18391d926038f7cebf889ef843f2f087d72bc8c60c2stefan      num_cpu_cores_(CpuInfo::DetectNumberOfCores()),
184847855b865987524be768c7771959f927db25808stefan      module_process_thread_(ProcessThread::Create("ModuleProcessThread")),
185d3c944755ec546f46d5bdd84bff359fe6c4639e9Peter Boström      call_stats_(new CallStats(clock_)),
1860e7e259ebd69993bb5670a991f43aa1b06c9bf9emflodman      bitrate_allocator_(new BitrateAllocator()),
18745553aefacb797818da83ccef1c3679a8aa0fc7fPeter Boström      config_(config),
18826c0c41a06d77af54df547169d952a21319dea8cpbos@webrtc.org      network_enabled_(true),
18926c0c41a06d77af54df547169d952a21319dea8cpbos@webrtc.org      receive_crit_(RWLockWrapper::CreateRWLock()),
19091d926038f7cebf889ef843f2f087d72bc8c60c2stefan      send_crit_(RWLockWrapper::CreateRWLock()),
191226befecfb5e56287482a2d6250f01d019761884Stefan Holmer      received_video_bytes_(0),
192226befecfb5e56287482a2d6250f01d019761884Stefan Holmer      received_audio_bytes_(0),
193226befecfb5e56287482a2d6250f01d019761884Stefan Holmer      received_rtcp_bytes_(0),
1940e7e259ebd69993bb5670a991f43aa1b06c9bf9emflodman      first_rtp_packet_received_ms_(-1),
195226befecfb5e56287482a2d6250f01d019761884Stefan Holmer      last_rtp_packet_received_ms_(-1),
196226befecfb5e56287482a2d6250f01d019761884Stefan Holmer      first_packet_sent_ms_(-1),
197226befecfb5e56287482a2d6250f01d019761884Stefan Holmer      estimated_send_bitrate_sum_kbits_(0),
198226befecfb5e56287482a2d6250f01d019761884Stefan Holmer      pacer_bitrate_sum_kbits_(0),
199226befecfb5e56287482a2d6250f01d019761884Stefan Holmer      num_bitrate_updates_(0),
20018adf0a79d4a0ea124c7f27fd553382d0b0cb7acstefan      congestion_controller_(
20118adf0a79d4a0ea124c7f27fd553382d0b0cb7acstefan          new CongestionController(module_process_thread_.get(),
20218adf0a79d4a0ea124c7f27fd553382d0b0cb7acstefan                                   call_stats_.get(),
20318adf0a79d4a0ea124c7f27fd553382d0b0cb7acstefan                                   this)) {
20456a34df92807d95a2660765be10abef7c779666fsolenberg  RTC_DCHECK(configuration_thread_checker_.CalledOnValidThread());
20591d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg  RTC_DCHECK_GE(config.bitrate_config.min_bitrate_bps, 0);
20691d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg  RTC_DCHECK_GE(config.bitrate_config.start_bitrate_bps,
20791d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg                config.bitrate_config.min_bitrate_bps);
208e59041672283a28bde0b043c0c2bc198272f82e1Stefan Holmer  if (config.bitrate_config.max_bitrate_bps != -1) {
20991d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg    RTC_DCHECK_GE(config.bitrate_config.max_bitrate_bps,
21091d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg                  config.bitrate_config.start_bitrate_bps);
211008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org  }
212566ef247b9779f6c9d0e7ec9eea6b037f4682c53solenberg  if (config.audio_state.get()) {
213566ef247b9779f6c9d0e7ec9eea6b037f4682c53solenberg    ScopedVoEInterface<VoECodec> voe_codec(voice_engine());
214566ef247b9779f6c9d0e7ec9eea6b037f4682c53solenberg    event_log_ = voe_codec->GetEventLog();
215b04965ccf83c2bc6e2758abab9bea0c18551a54civoc  }
216008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org
21745553aefacb797818da83ccef1c3679a8aa0fc7fPeter Boström  Trace::CreateTrace();
21845553aefacb797818da83ccef1c3679a8aa0fc7fPeter Boström  module_process_thread_->Start();
219e37870297fc45f1253dff4b1c59c85a50d2a8a97mflodman  module_process_thread_->RegisterModule(call_stats_.get());
22045553aefacb797818da83ccef1c3679a8aa0fc7fPeter Boström
2210c478b3d75be3c026e68f03a11cb558c3655c926mflodman  congestion_controller_->SetBweBitrates(
2220c478b3d75be3c026e68f03a11cb558c3655c926mflodman      config_.bitrate_config.min_bitrate_bps,
2230c478b3d75be3c026e68f03a11cb558c3655c926mflodman      config_.bitrate_config.start_bitrate_bps,
2240c478b3d75be3c026e68f03a11cb558c3655c926mflodman      config_.bitrate_config.max_bitrate_bps);
225006d93d3c679ffd15223c327d649066a72400639terelius
226006d93d3c679ffd15223c327d649066a72400639terelius  congestion_controller_->GetBitrateController()->SetEventLog(event_log_);
22729d5839233b19743286a89676bd748a6bd8623d6pbos@webrtc.org}
22829d5839233b19743286a89676bd748a6bd8623d6pbos@webrtc.org
229841c8a44bb6261e62a263edf60e7ae53d2f932efpbos@webrtc.orgCall::~Call() {
2305a289393928c18af580c6339ba77600fb67006e2solenberg  RTC_DCHECK(configuration_thread_checker_.CalledOnValidThread());
23118adf0a79d4a0ea124c7f27fd553382d0b0cb7acstefan  UpdateSendHistograms();
23218adf0a79d4a0ea124c7f27fd553382d0b0cb7acstefan  UpdateReceiveHistograms();
233c7a8b08a7cd8d8f37d7f5fb9930d0cdc74baba35solenberg  RTC_CHECK(audio_send_ssrcs_.empty());
234c7a8b08a7cd8d8f37d7f5fb9930d0cdc74baba35solenberg  RTC_CHECK(video_send_ssrcs_.empty());
235c7a8b08a7cd8d8f37d7f5fb9930d0cdc74baba35solenberg  RTC_CHECK(video_send_streams_.empty());
236c7a8b08a7cd8d8f37d7f5fb9930d0cdc74baba35solenberg  RTC_CHECK(audio_receive_ssrcs_.empty());
237c7a8b08a7cd8d8f37d7f5fb9930d0cdc74baba35solenberg  RTC_CHECK(video_receive_ssrcs_.empty());
238c7a8b08a7cd8d8f37d7f5fb9930d0cdc74baba35solenberg  RTC_CHECK(video_receive_streams_.empty());
2399e4e524f3894c7eeee8a53bd3cbf21d27b5efc8cpbos@webrtc.org
240e37870297fc45f1253dff4b1c59c85a50d2a8a97mflodman  module_process_thread_->DeRegisterModule(call_stats_.get());
24145553aefacb797818da83ccef1c3679a8aa0fc7fPeter Boström  module_process_thread_->Stop();
24245553aefacb797818da83ccef1c3679a8aa0fc7fPeter Boström  Trace::ReturnTrace();
24329d5839233b19743286a89676bd748a6bd8623d6pbos@webrtc.org}
24429d5839233b19743286a89676bd748a6bd8623d6pbos@webrtc.org
24518adf0a79d4a0ea124c7f27fd553382d0b0cb7acstefanvoid Call::UpdateSendHistograms() {
246226befecfb5e56287482a2d6250f01d019761884Stefan Holmer  if (num_bitrate_updates_ == 0 || first_packet_sent_ms_ == -1)
24718adf0a79d4a0ea124c7f27fd553382d0b0cb7acstefan    return;
24818adf0a79d4a0ea124c7f27fd553382d0b0cb7acstefan  int64_t elapsed_sec =
24918adf0a79d4a0ea124c7f27fd553382d0b0cb7acstefan      (clock_->TimeInMilliseconds() - first_packet_sent_ms_) / 1000;
25018adf0a79d4a0ea124c7f27fd553382d0b0cb7acstefan  if (elapsed_sec < metrics::kMinRunTimeInSeconds)
25118adf0a79d4a0ea124c7f27fd553382d0b0cb7acstefan    return;
252226befecfb5e56287482a2d6250f01d019761884Stefan Holmer  int send_bitrate_kbps =
253226befecfb5e56287482a2d6250f01d019761884Stefan Holmer      estimated_send_bitrate_sum_kbits_ / num_bitrate_updates_;
254226befecfb5e56287482a2d6250f01d019761884Stefan Holmer  int pacer_bitrate_kbps = pacer_bitrate_sum_kbits_ / num_bitrate_updates_;
25518adf0a79d4a0ea124c7f27fd553382d0b0cb7acstefan  if (send_bitrate_kbps > 0) {
25653805324c0fa904d796cc0b333868c591f2c5f2casapersson    RTC_HISTOGRAM_COUNTS_SPARSE_100000("WebRTC.Call.EstimatedSendBitrateInKbps",
25753805324c0fa904d796cc0b333868c591f2c5f2casapersson                                       send_bitrate_kbps);
25818adf0a79d4a0ea124c7f27fd553382d0b0cb7acstefan  }
25918adf0a79d4a0ea124c7f27fd553382d0b0cb7acstefan  if (pacer_bitrate_kbps > 0) {
26053805324c0fa904d796cc0b333868c591f2c5f2casapersson    RTC_HISTOGRAM_COUNTS_SPARSE_100000("WebRTC.Call.PacerBitrateInKbps",
26153805324c0fa904d796cc0b333868c591f2c5f2casapersson                                       pacer_bitrate_kbps);
26218adf0a79d4a0ea124c7f27fd553382d0b0cb7acstefan  }
26318adf0a79d4a0ea124c7f27fd553382d0b0cb7acstefan}
26418adf0a79d4a0ea124c7f27fd553382d0b0cb7acstefan
26518adf0a79d4a0ea124c7f27fd553382d0b0cb7acstefanvoid Call::UpdateReceiveHistograms() {
26691d926038f7cebf889ef843f2f087d72bc8c60c2stefan  if (first_rtp_packet_received_ms_ == -1)
26791d926038f7cebf889ef843f2f087d72bc8c60c2stefan    return;
26891d926038f7cebf889ef843f2f087d72bc8c60c2stefan  int64_t elapsed_sec =
269226befecfb5e56287482a2d6250f01d019761884Stefan Holmer      (last_rtp_packet_received_ms_ - first_rtp_packet_received_ms_) / 1000;
27091d926038f7cebf889ef843f2f087d72bc8c60c2stefan  if (elapsed_sec < metrics::kMinRunTimeInSeconds)
27191d926038f7cebf889ef843f2f087d72bc8c60c2stefan    return;
272226befecfb5e56287482a2d6250f01d019761884Stefan Holmer  int audio_bitrate_kbps = received_audio_bytes_ * 8 / elapsed_sec / 1000;
273226befecfb5e56287482a2d6250f01d019761884Stefan Holmer  int video_bitrate_kbps = received_video_bytes_ * 8 / elapsed_sec / 1000;
274226befecfb5e56287482a2d6250f01d019761884Stefan Holmer  int rtcp_bitrate_bps = received_rtcp_bytes_ * 8 / elapsed_sec;
27591d926038f7cebf889ef843f2f087d72bc8c60c2stefan  if (video_bitrate_kbps > 0) {
27653805324c0fa904d796cc0b333868c591f2c5f2casapersson    RTC_HISTOGRAM_COUNTS_SPARSE_100000("WebRTC.Call.VideoBitrateReceivedInKbps",
27753805324c0fa904d796cc0b333868c591f2c5f2casapersson                                       video_bitrate_kbps);
27891d926038f7cebf889ef843f2f087d72bc8c60c2stefan  }
27991d926038f7cebf889ef843f2f087d72bc8c60c2stefan  if (audio_bitrate_kbps > 0) {
28053805324c0fa904d796cc0b333868c591f2c5f2casapersson    RTC_HISTOGRAM_COUNTS_SPARSE_100000("WebRTC.Call.AudioBitrateReceivedInKbps",
28153805324c0fa904d796cc0b333868c591f2c5f2casapersson                                       audio_bitrate_kbps);
28291d926038f7cebf889ef843f2f087d72bc8c60c2stefan  }
28391d926038f7cebf889ef843f2f087d72bc8c60c2stefan  if (rtcp_bitrate_bps > 0) {
28453805324c0fa904d796cc0b333868c591f2c5f2casapersson    RTC_HISTOGRAM_COUNTS_SPARSE_100000("WebRTC.Call.RtcpBitrateReceivedInBps",
28553805324c0fa904d796cc0b333868c591f2c5f2casapersson                                       rtcp_bitrate_bps);
28691d926038f7cebf889ef843f2f087d72bc8c60c2stefan  }
28753805324c0fa904d796cc0b333868c591f2c5f2casapersson  RTC_HISTOGRAM_COUNTS_SPARSE_100000(
28891d926038f7cebf889ef843f2f087d72bc8c60c2stefan      "WebRTC.Call.BitrateReceivedInKbps",
28991d926038f7cebf889ef843f2f087d72bc8c60c2stefan      audio_bitrate_kbps + video_bitrate_kbps + rtcp_bitrate_bps / 1000);
29091d926038f7cebf889ef843f2f087d72bc8c60c2stefan}
29191d926038f7cebf889ef843f2f087d72bc8c60c2stefan
2925a289393928c18af580c6339ba77600fb67006e2solenbergPacketReceiver* Call::Receiver() {
2935a289393928c18af580c6339ba77600fb67006e2solenberg  // TODO(solenberg): Some test cases in EndToEndTest use this from a different
2945a289393928c18af580c6339ba77600fb67006e2solenberg  // thread. Re-enable once that is fixed.
2955a289393928c18af580c6339ba77600fb67006e2solenberg  // RTC_DCHECK(configuration_thread_checker_.CalledOnValidThread());
2965a289393928c18af580c6339ba77600fb67006e2solenberg  return this;
2975a289393928c18af580c6339ba77600fb67006e2solenberg}
29829d5839233b19743286a89676bd748a6bd8623d6pbos@webrtc.org
29904f4931ef06273c2873e7816ed1f568d445117b8Fredrik Solenbergwebrtc::AudioSendStream* Call::CreateAudioSendStream(
30004f4931ef06273c2873e7816ed1f568d445117b8Fredrik Solenberg    const webrtc::AudioSendStream::Config& config) {
301c7a8b08a7cd8d8f37d7f5fb9930d0cdc74baba35solenberg  TRACE_EVENT0("webrtc", "Call::CreateAudioSendStream");
3025a289393928c18af580c6339ba77600fb67006e2solenberg  RTC_DCHECK(configuration_thread_checker_.CalledOnValidThread());
303b86d4e4a8dec1eb1b801244a2a97cda66f561d8eStefan Holmer  AudioSendStream* send_stream = new AudioSendStream(
304b86d4e4a8dec1eb1b801244a2a97cda66f561d8eStefan Holmer      config, config_.audio_state, congestion_controller_.get());
305717432f13016d2668a584bfd864338ecffd106b2mflodman  if (!network_enabled_)
306717432f13016d2668a584bfd864338ecffd106b2mflodman    send_stream->SignalNetworkState(kNetworkDown);
307c7a8b08a7cd8d8f37d7f5fb9930d0cdc74baba35solenberg  {
308c7a8b08a7cd8d8f37d7f5fb9930d0cdc74baba35solenberg    WriteLockScoped write_lock(*send_crit_);
309c7a8b08a7cd8d8f37d7f5fb9930d0cdc74baba35solenberg    RTC_DCHECK(audio_send_ssrcs_.find(config.rtp.ssrc) ==
310c7a8b08a7cd8d8f37d7f5fb9930d0cdc74baba35solenberg               audio_send_ssrcs_.end());
311c7a8b08a7cd8d8f37d7f5fb9930d0cdc74baba35solenberg    audio_send_ssrcs_[config.rtp.ssrc] = send_stream;
312c7a8b08a7cd8d8f37d7f5fb9930d0cdc74baba35solenberg  }
313c7a8b08a7cd8d8f37d7f5fb9930d0cdc74baba35solenberg  return send_stream;
31404f4931ef06273c2873e7816ed1f568d445117b8Fredrik Solenberg}
31504f4931ef06273c2873e7816ed1f568d445117b8Fredrik Solenberg
31604f4931ef06273c2873e7816ed1f568d445117b8Fredrik Solenbergvoid Call::DestroyAudioSendStream(webrtc::AudioSendStream* send_stream) {
317c7a8b08a7cd8d8f37d7f5fb9930d0cdc74baba35solenberg  TRACE_EVENT0("webrtc", "Call::DestroyAudioSendStream");
3185a289393928c18af580c6339ba77600fb67006e2solenberg  RTC_DCHECK(configuration_thread_checker_.CalledOnValidThread());
319c7a8b08a7cd8d8f37d7f5fb9930d0cdc74baba35solenberg  RTC_DCHECK(send_stream != nullptr);
320c7a8b08a7cd8d8f37d7f5fb9930d0cdc74baba35solenberg
321c7a8b08a7cd8d8f37d7f5fb9930d0cdc74baba35solenberg  send_stream->Stop();
322c7a8b08a7cd8d8f37d7f5fb9930d0cdc74baba35solenberg
323c7a8b08a7cd8d8f37d7f5fb9930d0cdc74baba35solenberg  webrtc::internal::AudioSendStream* audio_send_stream =
324c7a8b08a7cd8d8f37d7f5fb9930d0cdc74baba35solenberg      static_cast<webrtc::internal::AudioSendStream*>(send_stream);
325c7a8b08a7cd8d8f37d7f5fb9930d0cdc74baba35solenberg  {
326c7a8b08a7cd8d8f37d7f5fb9930d0cdc74baba35solenberg    WriteLockScoped write_lock(*send_crit_);
327c7a8b08a7cd8d8f37d7f5fb9930d0cdc74baba35solenberg    size_t num_deleted = audio_send_ssrcs_.erase(
328c7a8b08a7cd8d8f37d7f5fb9930d0cdc74baba35solenberg        audio_send_stream->config().rtp.ssrc);
329c7a8b08a7cd8d8f37d7f5fb9930d0cdc74baba35solenberg    RTC_DCHECK(num_deleted == 1);
330c7a8b08a7cd8d8f37d7f5fb9930d0cdc74baba35solenberg  }
331c7a8b08a7cd8d8f37d7f5fb9930d0cdc74baba35solenberg  delete audio_send_stream;
33204f4931ef06273c2873e7816ed1f568d445117b8Fredrik Solenberg}
33304f4931ef06273c2873e7816ed1f568d445117b8Fredrik Solenberg
33423fba1ffa0079f70744a83bcf4e85501dc226013Fredrik Solenbergwebrtc::AudioReceiveStream* Call::CreateAudioReceiveStream(
33523fba1ffa0079f70744a83bcf4e85501dc226013Fredrik Solenberg    const webrtc::AudioReceiveStream::Config& config) {
33623fba1ffa0079f70744a83bcf4e85501dc226013Fredrik Solenberg  TRACE_EVENT0("webrtc", "Call::CreateAudioReceiveStream");
3375a289393928c18af580c6339ba77600fb67006e2solenberg  RTC_DCHECK(configuration_thread_checker_.CalledOnValidThread());
33823fba1ffa0079f70744a83bcf4e85501dc226013Fredrik Solenberg  AudioReceiveStream* receive_stream = new AudioReceiveStream(
3393842c5c7f73639527e653f41c65334245d2317a1Stefan Holmer      congestion_controller_.get(), config, config_.audio_state);
34023fba1ffa0079f70744a83bcf4e85501dc226013Fredrik Solenberg  {
34123fba1ffa0079f70744a83bcf4e85501dc226013Fredrik Solenberg    WriteLockScoped write_lock(*receive_crit_);
34291d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg    RTC_DCHECK(audio_receive_ssrcs_.find(config.rtp.remote_ssrc) ==
34391d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg               audio_receive_ssrcs_.end());
34423fba1ffa0079f70744a83bcf4e85501dc226013Fredrik Solenberg    audio_receive_ssrcs_[config.rtp.remote_ssrc] = receive_stream;
3458fc7fa798f7a36955f1b933980401afad2aff592pbos    ConfigureSync(config.sync_group);
34623fba1ffa0079f70744a83bcf4e85501dc226013Fredrik Solenberg  }
34723fba1ffa0079f70744a83bcf4e85501dc226013Fredrik Solenberg  return receive_stream;
34823fba1ffa0079f70744a83bcf4e85501dc226013Fredrik Solenberg}
34923fba1ffa0079f70744a83bcf4e85501dc226013Fredrik Solenberg
35023fba1ffa0079f70744a83bcf4e85501dc226013Fredrik Solenbergvoid Call::DestroyAudioReceiveStream(
35123fba1ffa0079f70744a83bcf4e85501dc226013Fredrik Solenberg    webrtc::AudioReceiveStream* receive_stream) {
35223fba1ffa0079f70744a83bcf4e85501dc226013Fredrik Solenberg  TRACE_EVENT0("webrtc", "Call::DestroyAudioReceiveStream");
3535a289393928c18af580c6339ba77600fb67006e2solenberg  RTC_DCHECK(configuration_thread_checker_.CalledOnValidThread());
35491d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg  RTC_DCHECK(receive_stream != nullptr);
355c7a8b08a7cd8d8f37d7f5fb9930d0cdc74baba35solenberg  webrtc::internal::AudioReceiveStream* audio_receive_stream =
356c7a8b08a7cd8d8f37d7f5fb9930d0cdc74baba35solenberg      static_cast<webrtc::internal::AudioReceiveStream*>(receive_stream);
35723fba1ffa0079f70744a83bcf4e85501dc226013Fredrik Solenberg  {
35823fba1ffa0079f70744a83bcf4e85501dc226013Fredrik Solenberg    WriteLockScoped write_lock(*receive_crit_);
35923fba1ffa0079f70744a83bcf4e85501dc226013Fredrik Solenberg    size_t num_deleted = audio_receive_ssrcs_.erase(
36023fba1ffa0079f70744a83bcf4e85501dc226013Fredrik Solenberg        audio_receive_stream->config().rtp.remote_ssrc);
36191d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg    RTC_DCHECK(num_deleted == 1);
3628fc7fa798f7a36955f1b933980401afad2aff592pbos    const std::string& sync_group = audio_receive_stream->config().sync_group;
3638fc7fa798f7a36955f1b933980401afad2aff592pbos    const auto it = sync_stream_mapping_.find(sync_group);
3648fc7fa798f7a36955f1b933980401afad2aff592pbos    if (it != sync_stream_mapping_.end() &&
3658fc7fa798f7a36955f1b933980401afad2aff592pbos        it->second == audio_receive_stream) {
3668fc7fa798f7a36955f1b933980401afad2aff592pbos      sync_stream_mapping_.erase(it);
3678fc7fa798f7a36955f1b933980401afad2aff592pbos      ConfigureSync(sync_group);
3688fc7fa798f7a36955f1b933980401afad2aff592pbos    }
36923fba1ffa0079f70744a83bcf4e85501dc226013Fredrik Solenberg  }
37023fba1ffa0079f70744a83bcf4e85501dc226013Fredrik Solenberg  delete audio_receive_stream;
37123fba1ffa0079f70744a83bcf4e85501dc226013Fredrik Solenberg}
37223fba1ffa0079f70744a83bcf4e85501dc226013Fredrik Solenberg
37323fba1ffa0079f70744a83bcf4e85501dc226013Fredrik Solenbergwebrtc::VideoSendStream* Call::CreateVideoSendStream(
37423fba1ffa0079f70744a83bcf4e85501dc226013Fredrik Solenberg    const webrtc::VideoSendStream::Config& config,
375bbe0a8517d7f9da7aa779bff77cdbb70df358437pbos@webrtc.org    const VideoEncoderConfig& encoder_config) {
37650fe359eb614e1bbe41124b9c19263019da0395dpbos@webrtc.org  TRACE_EVENT0("webrtc", "Call::CreateVideoSendStream");
3775a289393928c18af580c6339ba77600fb67006e2solenberg  RTC_DCHECK(configuration_thread_checker_.CalledOnValidThread());
3781819fd711aa081b7303f3fbe1e041cf5bf26706bpbos@webrtc.org
379eb16b811fb5c21954f9e4a6f4c64e297e9fd65b9mflodman@webrtc.org  // TODO(mflodman): Base the start bitrate on a current bandwidth estimate, if
380eb16b811fb5c21954f9e4a6f4c64e297e9fd65b9mflodman@webrtc.org  // the call has already started.
3810c478b3d75be3c026e68f03a11cb558c3655c926mflodman  VideoSendStream* send_stream = new VideoSendStream(
3820c478b3d75be3c026e68f03a11cb558c3655c926mflodman      num_cpu_cores_, module_process_thread_.get(), call_stats_.get(),
3830e7e259ebd69993bb5670a991f43aa1b06c9bf9emflodman      congestion_controller_.get(), bitrate_allocator_.get(), config,
3840e7e259ebd69993bb5670a991f43aa1b06c9bf9emflodman      encoder_config, suspended_video_send_ssrcs_);
3851819fd711aa081b7303f3fbe1e041cf5bf26706bpbos@webrtc.org
386717432f13016d2668a584bfd864338ecffd106b2mflodman  if (!network_enabled_)
387717432f13016d2668a584bfd864338ecffd106b2mflodman    send_stream->SignalNetworkState(kNetworkDown);
388717432f13016d2668a584bfd864338ecffd106b2mflodman
38926c0c41a06d77af54df547169d952a21319dea8cpbos@webrtc.org  WriteLockScoped write_lock(*send_crit_);
39023fba1ffa0079f70744a83bcf4e85501dc226013Fredrik Solenberg  for (uint32_t ssrc : config.rtp.ssrcs) {
39191d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg    RTC_DCHECK(video_send_ssrcs_.find(ssrc) == video_send_ssrcs_.end());
39223fba1ffa0079f70744a83bcf4e85501dc226013Fredrik Solenberg    video_send_ssrcs_[ssrc] = send_stream;
39329d5839233b19743286a89676bd748a6bd8623d6pbos@webrtc.org  }
39423fba1ffa0079f70744a83bcf4e85501dc226013Fredrik Solenberg  video_send_streams_.insert(send_stream);
39523fba1ffa0079f70744a83bcf4e85501dc226013Fredrik Solenberg
396b04965ccf83c2bc6e2758abab9bea0c18551a54civoc  if (event_log_)
397b04965ccf83c2bc6e2758abab9bea0c18551a54civoc    event_log_->LogVideoSendStreamConfig(config);
398b04965ccf83c2bc6e2758abab9bea0c18551a54civoc
39929d5839233b19743286a89676bd748a6bd8623d6pbos@webrtc.org  return send_stream;
40029d5839233b19743286a89676bd748a6bd8623d6pbos@webrtc.org}
40129d5839233b19743286a89676bd748a6bd8623d6pbos@webrtc.org
4022c46f8d854c1fc3e10f8151ee5109923287aee8bpbos@webrtc.orgvoid Call::DestroyVideoSendStream(webrtc::VideoSendStream* send_stream) {
40350fe359eb614e1bbe41124b9c19263019da0395dpbos@webrtc.org  TRACE_EVENT0("webrtc", "Call::DestroyVideoSendStream");
40491d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg  RTC_DCHECK(send_stream != nullptr);
4055a289393928c18af580c6339ba77600fb67006e2solenberg  RTC_DCHECK(configuration_thread_checker_.CalledOnValidThread());
40695e51f509c73eb4d62d25cacb052c97b88fefd7dpbos@webrtc.org
4072bb1bdab8d11f5445693c028335fb3ace631f636pbos@webrtc.org  send_stream->Stop();
4082bb1bdab8d11f5445693c028335fb3ace631f636pbos@webrtc.org
4092b4ce3a501b8d679f84c1ad10317dea5c78fa595pbos@webrtc.org  VideoSendStream* send_stream_impl = nullptr;
41095e51f509c73eb4d62d25cacb052c97b88fefd7dpbos@webrtc.org  {
41126c0c41a06d77af54df547169d952a21319dea8cpbos@webrtc.org    WriteLockScoped write_lock(*send_crit_);
41223fba1ffa0079f70744a83bcf4e85501dc226013Fredrik Solenberg    auto it = video_send_ssrcs_.begin();
41323fba1ffa0079f70744a83bcf4e85501dc226013Fredrik Solenberg    while (it != video_send_ssrcs_.end()) {
41495e51f509c73eb4d62d25cacb052c97b88fefd7dpbos@webrtc.org      if (it->second == static_cast<VideoSendStream*>(send_stream)) {
41595e51f509c73eb4d62d25cacb052c97b88fefd7dpbos@webrtc.org        send_stream_impl = it->second;
41623fba1ffa0079f70744a83bcf4e85501dc226013Fredrik Solenberg        video_send_ssrcs_.erase(it++);
4172bb1bdab8d11f5445693c028335fb3ace631f636pbos@webrtc.org      } else {
4182bb1bdab8d11f5445693c028335fb3ace631f636pbos@webrtc.org        ++it;
41995e51f509c73eb4d62d25cacb052c97b88fefd7dpbos@webrtc.org      }
42095e51f509c73eb4d62d25cacb052c97b88fefd7dpbos@webrtc.org    }
42123fba1ffa0079f70744a83bcf4e85501dc226013Fredrik Solenberg    video_send_streams_.erase(send_stream_impl);
42229d5839233b19743286a89676bd748a6bd8623d6pbos@webrtc.org  }
42391d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg  RTC_CHECK(send_stream_impl != nullptr);
42495e51f509c73eb4d62d25cacb052c97b88fefd7dpbos@webrtc.org
4252bb1bdab8d11f5445693c028335fb3ace631f636pbos@webrtc.org  VideoSendStream::RtpStateMap rtp_state = send_stream_impl->GetRtpStates();
4262bb1bdab8d11f5445693c028335fb3ace631f636pbos@webrtc.org
4272bb1bdab8d11f5445693c028335fb3ace631f636pbos@webrtc.org  for (VideoSendStream::RtpStateMap::iterator it = rtp_state.begin();
4282bb1bdab8d11f5445693c028335fb3ace631f636pbos@webrtc.org       it != rtp_state.end();
4292bb1bdab8d11f5445693c028335fb3ace631f636pbos@webrtc.org       ++it) {
43023fba1ffa0079f70744a83bcf4e85501dc226013Fredrik Solenberg    suspended_video_send_ssrcs_[it->first] = it->second;
4312bb1bdab8d11f5445693c028335fb3ace631f636pbos@webrtc.org  }
4322bb1bdab8d11f5445693c028335fb3ace631f636pbos@webrtc.org
43395e51f509c73eb4d62d25cacb052c97b88fefd7dpbos@webrtc.org  delete send_stream_impl;
43429d5839233b19743286a89676bd748a6bd8623d6pbos@webrtc.org}
43529d5839233b19743286a89676bd748a6bd8623d6pbos@webrtc.org
43623fba1ffa0079f70744a83bcf4e85501dc226013Fredrik Solenbergwebrtc::VideoReceiveStream* Call::CreateVideoReceiveStream(
43723fba1ffa0079f70744a83bcf4e85501dc226013Fredrik Solenberg    const webrtc::VideoReceiveStream::Config& config) {
43850fe359eb614e1bbe41124b9c19263019da0395dpbos@webrtc.org  TRACE_EVENT0("webrtc", "Call::CreateVideoReceiveStream");
4395a289393928c18af580c6339ba77600fb67006e2solenberg  RTC_DCHECK(configuration_thread_checker_.CalledOnValidThread());
440c4188fd3c74688264621393fc622cb81c042c1acPeter Boström  VideoReceiveStream* receive_stream = new VideoReceiveStream(
4410c478b3d75be3c026e68f03a11cb558c3655c926mflodman      num_cpu_cores_, congestion_controller_.get(), config,
442566ef247b9779f6c9d0e7ec9eea6b037f4682c53solenberg      voice_engine(), module_process_thread_.get(), call_stats_.get());
44329d5839233b19743286a89676bd748a6bd8623d6pbos@webrtc.org
44426c0c41a06d77af54df547169d952a21319dea8cpbos@webrtc.org  WriteLockScoped write_lock(*receive_crit_);
44591d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg  RTC_DCHECK(video_receive_ssrcs_.find(config.rtp.remote_ssrc) ==
44691d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg             video_receive_ssrcs_.end());
44723fba1ffa0079f70744a83bcf4e85501dc226013Fredrik Solenberg  video_receive_ssrcs_[config.rtp.remote_ssrc] = receive_stream;
448c279a5d72c885b1a1737018ee26dc7c0475a38bfpbos@webrtc.org  // TODO(pbos): Configure different RTX payloads per receive payload.
449c279a5d72c885b1a1737018ee26dc7c0475a38bfpbos@webrtc.org  VideoReceiveStream::Config::Rtp::RtxMap::const_iterator it =
450c279a5d72c885b1a1737018ee26dc7c0475a38bfpbos@webrtc.org      config.rtp.rtx.begin();
451c279a5d72c885b1a1737018ee26dc7c0475a38bfpbos@webrtc.org  if (it != config.rtp.rtx.end())
45223fba1ffa0079f70744a83bcf4e85501dc226013Fredrik Solenberg    video_receive_ssrcs_[it->second.ssrc] = receive_stream;
45323fba1ffa0079f70744a83bcf4e85501dc226013Fredrik Solenberg  video_receive_streams_.insert(receive_stream);
454c279a5d72c885b1a1737018ee26dc7c0475a38bfpbos@webrtc.org
4558fc7fa798f7a36955f1b933980401afad2aff592pbos  ConfigureSync(config.sync_group);
4568fc7fa798f7a36955f1b933980401afad2aff592pbos
45726c0c41a06d77af54df547169d952a21319dea8cpbos@webrtc.org  if (!network_enabled_)
45826c0c41a06d77af54df547169d952a21319dea8cpbos@webrtc.org    receive_stream->SignalNetworkState(kNetworkDown);
4598fc7fa798f7a36955f1b933980401afad2aff592pbos
460b04965ccf83c2bc6e2758abab9bea0c18551a54civoc  if (event_log_)
461b04965ccf83c2bc6e2758abab9bea0c18551a54civoc    event_log_->LogVideoReceiveStreamConfig(config);
462b04965ccf83c2bc6e2758abab9bea0c18551a54civoc
46329d5839233b19743286a89676bd748a6bd8623d6pbos@webrtc.org  return receive_stream;
46429d5839233b19743286a89676bd748a6bd8623d6pbos@webrtc.org}
46529d5839233b19743286a89676bd748a6bd8623d6pbos@webrtc.org
4662c46f8d854c1fc3e10f8151ee5109923287aee8bpbos@webrtc.orgvoid Call::DestroyVideoReceiveStream(
4672c46f8d854c1fc3e10f8151ee5109923287aee8bpbos@webrtc.org    webrtc::VideoReceiveStream* receive_stream) {
46850fe359eb614e1bbe41124b9c19263019da0395dpbos@webrtc.org  TRACE_EVENT0("webrtc", "Call::DestroyVideoReceiveStream");
4695a289393928c18af580c6339ba77600fb67006e2solenberg  RTC_DCHECK(configuration_thread_checker_.CalledOnValidThread());
47091d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg  RTC_DCHECK(receive_stream != nullptr);
4712b4ce3a501b8d679f84c1ad10317dea5c78fa595pbos@webrtc.org  VideoReceiveStream* receive_stream_impl = nullptr;
47295e51f509c73eb4d62d25cacb052c97b88fefd7dpbos@webrtc.org  {
47326c0c41a06d77af54df547169d952a21319dea8cpbos@webrtc.org    WriteLockScoped write_lock(*receive_crit_);
474c279a5d72c885b1a1737018ee26dc7c0475a38bfpbos@webrtc.org    // Remove all ssrcs pointing to a receive stream. As RTX retransmits on a
475c279a5d72c885b1a1737018ee26dc7c0475a38bfpbos@webrtc.org    // separate SSRC there can be either one or two.
47623fba1ffa0079f70744a83bcf4e85501dc226013Fredrik Solenberg    auto it = video_receive_ssrcs_.begin();
47723fba1ffa0079f70744a83bcf4e85501dc226013Fredrik Solenberg    while (it != video_receive_ssrcs_.end()) {
47895e51f509c73eb4d62d25cacb052c97b88fefd7dpbos@webrtc.org      if (it->second == static_cast<VideoReceiveStream*>(receive_stream)) {
4792b4ce3a501b8d679f84c1ad10317dea5c78fa595pbos@webrtc.org        if (receive_stream_impl != nullptr)
48091d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg          RTC_DCHECK(receive_stream_impl == it->second);
48195e51f509c73eb4d62d25cacb052c97b88fefd7dpbos@webrtc.org        receive_stream_impl = it->second;
48223fba1ffa0079f70744a83bcf4e85501dc226013Fredrik Solenberg        video_receive_ssrcs_.erase(it++);
483c279a5d72c885b1a1737018ee26dc7c0475a38bfpbos@webrtc.org      } else {
484c279a5d72c885b1a1737018ee26dc7c0475a38bfpbos@webrtc.org        ++it;
48595e51f509c73eb4d62d25cacb052c97b88fefd7dpbos@webrtc.org      }
48695e51f509c73eb4d62d25cacb052c97b88fefd7dpbos@webrtc.org    }
48723fba1ffa0079f70744a83bcf4e85501dc226013Fredrik Solenberg    video_receive_streams_.erase(receive_stream_impl);
48891d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg    RTC_CHECK(receive_stream_impl != nullptr);
4898fc7fa798f7a36955f1b933980401afad2aff592pbos    ConfigureSync(receive_stream_impl->config().sync_group);
49029d5839233b19743286a89676bd748a6bd8623d6pbos@webrtc.org  }
49195e51f509c73eb4d62d25cacb052c97b88fefd7dpbos@webrtc.org  delete receive_stream_impl;
49229d5839233b19743286a89676bd748a6bd8623d6pbos@webrtc.org}
49329d5839233b19743286a89676bd748a6bd8623d6pbos@webrtc.org
4940bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.orgCall::Stats Call::GetStats() const {
4955a289393928c18af580c6339ba77600fb67006e2solenberg  // TODO(solenberg): Some test cases in EndToEndTest use this from a different
4965a289393928c18af580c6339ba77600fb67006e2solenberg  // thread. Re-enable once that is fixed.
4975a289393928c18af580c6339ba77600fb67006e2solenberg  // RTC_DCHECK(configuration_thread_checker_.CalledOnValidThread());
4980bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org  Stats stats;
49945553aefacb797818da83ccef1c3679a8aa0fc7fPeter Boström  // Fetch available send/receive bitrates.
5000bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org  uint32_t send_bandwidth = 0;
5010c478b3d75be3c026e68f03a11cb558c3655c926mflodman  congestion_controller_->GetBitrateController()->AvailableBandwidth(
5020c478b3d75be3c026e68f03a11cb558c3655c926mflodman      &send_bandwidth);
50345553aefacb797818da83ccef1c3679a8aa0fc7fPeter Boström  std::vector<unsigned int> ssrcs;
5040bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org  uint32_t recv_bandwidth = 0;
5050c478b3d75be3c026e68f03a11cb558c3655c926mflodman  congestion_controller_->GetRemoteBitrateEstimator(false)->LatestEstimate(
506a20de2030f7f3a3c5e252ccc76a467109f5a93dcmflodman      &ssrcs, &recv_bandwidth);
50745553aefacb797818da83ccef1c3679a8aa0fc7fPeter Boström  stats.send_bandwidth_bps = send_bandwidth;
5080bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org  stats.recv_bandwidth_bps = recv_bandwidth;
5090c478b3d75be3c026e68f03a11cb558c3655c926mflodman  stats.pacer_delay_ms = congestion_controller_->GetPacerQueuingDelayMs();
5100bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org  {
5110bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org    ReadLockScoped read_lock(*send_crit_);
512c7a8b08a7cd8d8f37d7f5fb9930d0cdc74baba35solenberg    // TODO(solenberg): Add audio send streams.
51323fba1ffa0079f70744a83bcf4e85501dc226013Fredrik Solenberg    for (const auto& kv : video_send_ssrcs_) {
51423fba1ffa0079f70744a83bcf4e85501dc226013Fredrik Solenberg      int rtt_ms = kv.second->GetRtt();
5152b19f0631233488e891d9db0d170b637dc8fc464pbos@webrtc.org      if (rtt_ms > 0)
5162b19f0631233488e891d9db0d170b637dc8fc464pbos@webrtc.org        stats.rtt_ms = rtt_ms;
5170bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org    }
5180bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org  }
5190bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org  return stats;
52029d5839233b19743286a89676bd748a6bd8623d6pbos@webrtc.org}
52129d5839233b19743286a89676bd748a6bd8623d6pbos@webrtc.org
522008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.orgvoid Call::SetBitrateConfig(
523008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org    const webrtc::Call::Config::BitrateConfig& bitrate_config) {
52450fe359eb614e1bbe41124b9c19263019da0395dpbos@webrtc.org  TRACE_EVENT0("webrtc", "Call::SetBitrateConfig");
5255a289393928c18af580c6339ba77600fb67006e2solenberg  RTC_DCHECK(configuration_thread_checker_.CalledOnValidThread());
52691d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg  RTC_DCHECK_GE(bitrate_config.min_bitrate_bps, 0);
5272b4ce3a501b8d679f84c1ad10317dea5c78fa595pbos@webrtc.org  if (bitrate_config.max_bitrate_bps != -1)
52891d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg    RTC_DCHECK_GT(bitrate_config.max_bitrate_bps, 0);
529e59041672283a28bde0b043c0c2bc198272f82e1Stefan Holmer  if (config_.bitrate_config.min_bitrate_bps ==
530008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org          bitrate_config.min_bitrate_bps &&
531008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org      (bitrate_config.start_bitrate_bps <= 0 ||
532e59041672283a28bde0b043c0c2bc198272f82e1Stefan Holmer       config_.bitrate_config.start_bitrate_bps ==
533008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org           bitrate_config.start_bitrate_bps) &&
534e59041672283a28bde0b043c0c2bc198272f82e1Stefan Holmer      config_.bitrate_config.max_bitrate_bps ==
535008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org          bitrate_config.max_bitrate_bps) {
536008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org    // Nothing new to set, early abort to avoid encoder reconfigurations.
537008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org    return;
538008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org  }
539e59041672283a28bde0b043c0c2bc198272f82e1Stefan Holmer  config_.bitrate_config = bitrate_config;
5400c478b3d75be3c026e68f03a11cb558c3655c926mflodman  congestion_controller_->SetBweBitrates(bitrate_config.min_bitrate_bps,
5410c478b3d75be3c026e68f03a11cb558c3655c926mflodman                                         bitrate_config.start_bitrate_bps,
5420c478b3d75be3c026e68f03a11cb558c3655c926mflodman                                         bitrate_config.max_bitrate_bps);
543008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org}
544008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org
54526c0c41a06d77af54df547169d952a21319dea8cpbos@webrtc.orgvoid Call::SignalNetworkState(NetworkState state) {
5465a289393928c18af580c6339ba77600fb67006e2solenberg  RTC_DCHECK(configuration_thread_checker_.CalledOnValidThread());
54726c0c41a06d77af54df547169d952a21319dea8cpbos@webrtc.org  network_enabled_ = state == kNetworkUp;
5480c478b3d75be3c026e68f03a11cb558c3655c926mflodman  congestion_controller_->SignalNetworkState(state);
54926c0c41a06d77af54df547169d952a21319dea8cpbos@webrtc.org  {
55026c0c41a06d77af54df547169d952a21319dea8cpbos@webrtc.org    ReadLockScoped write_lock(*send_crit_);
551c7a8b08a7cd8d8f37d7f5fb9930d0cdc74baba35solenberg    for (auto& kv : audio_send_ssrcs_) {
552c7a8b08a7cd8d8f37d7f5fb9930d0cdc74baba35solenberg      kv.second->SignalNetworkState(state);
553c7a8b08a7cd8d8f37d7f5fb9930d0cdc74baba35solenberg    }
55423fba1ffa0079f70744a83bcf4e85501dc226013Fredrik Solenberg    for (auto& kv : video_send_ssrcs_) {
55523fba1ffa0079f70744a83bcf4e85501dc226013Fredrik Solenberg      kv.second->SignalNetworkState(state);
55626c0c41a06d77af54df547169d952a21319dea8cpbos@webrtc.org    }
55726c0c41a06d77af54df547169d952a21319dea8cpbos@webrtc.org  }
55826c0c41a06d77af54df547169d952a21319dea8cpbos@webrtc.org  {
55926c0c41a06d77af54df547169d952a21319dea8cpbos@webrtc.org    ReadLockScoped write_lock(*receive_crit_);
56023fba1ffa0079f70744a83bcf4e85501dc226013Fredrik Solenberg    for (auto& kv : video_receive_ssrcs_) {
56123fba1ffa0079f70744a83bcf4e85501dc226013Fredrik Solenberg      kv.second->SignalNetworkState(state);
56226c0c41a06d77af54df547169d952a21319dea8cpbos@webrtc.org    }
56326c0c41a06d77af54df547169d952a21319dea8cpbos@webrtc.org  }
56426c0c41a06d77af54df547169d952a21319dea8cpbos@webrtc.org}
56526c0c41a06d77af54df547169d952a21319dea8cpbos@webrtc.org
566c1aeaf0dc37d96f31c92f893f4e30e7a5f7cc2b7stefanvoid Call::OnSentPacket(const rtc::SentPacket& sent_packet) {
56718adf0a79d4a0ea124c7f27fd553382d0b0cb7acstefan  if (first_packet_sent_ms_ == -1)
56818adf0a79d4a0ea124c7f27fd553382d0b0cb7acstefan    first_packet_sent_ms_ = clock_->TimeInMilliseconds();
5690c478b3d75be3c026e68f03a11cb558c3655c926mflodman  congestion_controller_->OnSentPacket(sent_packet);
570c1aeaf0dc37d96f31c92f893f4e30e7a5f7cc2b7stefan}
571c1aeaf0dc37d96f31c92f893f4e30e7a5f7cc2b7stefan
5720e7e259ebd69993bb5670a991f43aa1b06c9bf9emflodmanvoid Call::OnNetworkChanged(uint32_t target_bitrate_bps, uint8_t fraction_loss,
5730e7e259ebd69993bb5670a991f43aa1b06c9bf9emflodman                            int64_t rtt_ms) {
5740e7e259ebd69993bb5670a991f43aa1b06c9bf9emflodman  uint32_t allocated_bitrate_bps = bitrate_allocator_->OnNetworkChanged(
5750e7e259ebd69993bb5670a991f43aa1b06c9bf9emflodman      target_bitrate_bps, fraction_loss, rtt_ms);
5760e7e259ebd69993bb5670a991f43aa1b06c9bf9emflodman
5770e7e259ebd69993bb5670a991f43aa1b06c9bf9emflodman  int pad_up_to_bitrate_bps = 0;
5780e7e259ebd69993bb5670a991f43aa1b06c9bf9emflodman  {
5790e7e259ebd69993bb5670a991f43aa1b06c9bf9emflodman    ReadLockScoped read_lock(*send_crit_);
5800e7e259ebd69993bb5670a991f43aa1b06c9bf9emflodman    // No need to update as long as we're not sending.
5810e7e259ebd69993bb5670a991f43aa1b06c9bf9emflodman    if (video_send_streams_.empty())
5820e7e259ebd69993bb5670a991f43aa1b06c9bf9emflodman      return;
5830e7e259ebd69993bb5670a991f43aa1b06c9bf9emflodman
5840e7e259ebd69993bb5670a991f43aa1b06c9bf9emflodman    for (VideoSendStream* stream : video_send_streams_)
5850e7e259ebd69993bb5670a991f43aa1b06c9bf9emflodman      pad_up_to_bitrate_bps += stream->GetPaddingNeededBps();
5860e7e259ebd69993bb5670a991f43aa1b06c9bf9emflodman  }
5870e7e259ebd69993bb5670a991f43aa1b06c9bf9emflodman  // Allocated bitrate might be higher than bitrate estimate if enforcing min
5880e7e259ebd69993bb5670a991f43aa1b06c9bf9emflodman  // bitrate, or lower if estimate is higher than the sum of max bitrates, so
5890e7e259ebd69993bb5670a991f43aa1b06c9bf9emflodman  // set the pacer bitrate to the maximum of the two.
5900e7e259ebd69993bb5670a991f43aa1b06c9bf9emflodman  uint32_t pacer_bitrate_bps =
5910e7e259ebd69993bb5670a991f43aa1b06c9bf9emflodman      std::max(target_bitrate_bps, allocated_bitrate_bps);
59218adf0a79d4a0ea124c7f27fd553382d0b0cb7acstefan  {
59318adf0a79d4a0ea124c7f27fd553382d0b0cb7acstefan    rtc::CritScope lock(&bitrate_crit_);
594226befecfb5e56287482a2d6250f01d019761884Stefan Holmer    // We only update these stats if we have send streams, and assume that
595226befecfb5e56287482a2d6250f01d019761884Stefan Holmer    // OnNetworkChanged is called roughly with a fixed frequency.
596226befecfb5e56287482a2d6250f01d019761884Stefan Holmer    estimated_send_bitrate_sum_kbits_ += target_bitrate_bps / 1000;
597226befecfb5e56287482a2d6250f01d019761884Stefan Holmer    pacer_bitrate_sum_kbits_ += pacer_bitrate_bps / 1000;
598226befecfb5e56287482a2d6250f01d019761884Stefan Holmer    ++num_bitrate_updates_;
59918adf0a79d4a0ea124c7f27fd553382d0b0cb7acstefan  }
6000e7e259ebd69993bb5670a991f43aa1b06c9bf9emflodman  congestion_controller_->UpdatePacerBitrate(
6010e7e259ebd69993bb5670a991f43aa1b06c9bf9emflodman      target_bitrate_bps / 1000,
6020e7e259ebd69993bb5670a991f43aa1b06c9bf9emflodman      PacedSender::kDefaultPaceMultiplier * pacer_bitrate_bps / 1000,
6030e7e259ebd69993bb5670a991f43aa1b06c9bf9emflodman      pad_up_to_bitrate_bps / 1000);
6040e7e259ebd69993bb5670a991f43aa1b06c9bf9emflodman}
6050e7e259ebd69993bb5670a991f43aa1b06c9bf9emflodman
6068fc7fa798f7a36955f1b933980401afad2aff592pbosvoid Call::ConfigureSync(const std::string& sync_group) {
6078fc7fa798f7a36955f1b933980401afad2aff592pbos  // Set sync only if there was no previous one.
608566ef247b9779f6c9d0e7ec9eea6b037f4682c53solenberg  if (voice_engine() == nullptr || sync_group.empty())
6098fc7fa798f7a36955f1b933980401afad2aff592pbos    return;
6108fc7fa798f7a36955f1b933980401afad2aff592pbos
6118fc7fa798f7a36955f1b933980401afad2aff592pbos  AudioReceiveStream* sync_audio_stream = nullptr;
6128fc7fa798f7a36955f1b933980401afad2aff592pbos  // Find existing audio stream.
6138fc7fa798f7a36955f1b933980401afad2aff592pbos  const auto it = sync_stream_mapping_.find(sync_group);
6148fc7fa798f7a36955f1b933980401afad2aff592pbos  if (it != sync_stream_mapping_.end()) {
6158fc7fa798f7a36955f1b933980401afad2aff592pbos    sync_audio_stream = it->second;
6168fc7fa798f7a36955f1b933980401afad2aff592pbos  } else {
6178fc7fa798f7a36955f1b933980401afad2aff592pbos    // No configured audio stream, see if we can find one.
6188fc7fa798f7a36955f1b933980401afad2aff592pbos    for (const auto& kv : audio_receive_ssrcs_) {
6198fc7fa798f7a36955f1b933980401afad2aff592pbos      if (kv.second->config().sync_group == sync_group) {
6208fc7fa798f7a36955f1b933980401afad2aff592pbos        if (sync_audio_stream != nullptr) {
6218fc7fa798f7a36955f1b933980401afad2aff592pbos          LOG(LS_WARNING) << "Attempting to sync more than one audio stream "
6228fc7fa798f7a36955f1b933980401afad2aff592pbos                             "within the same sync group. This is not "
6238fc7fa798f7a36955f1b933980401afad2aff592pbos                             "supported in the current implementation.";
6248fc7fa798f7a36955f1b933980401afad2aff592pbos          break;
6258fc7fa798f7a36955f1b933980401afad2aff592pbos        }
6268fc7fa798f7a36955f1b933980401afad2aff592pbos        sync_audio_stream = kv.second;
6278fc7fa798f7a36955f1b933980401afad2aff592pbos      }
6288fc7fa798f7a36955f1b933980401afad2aff592pbos    }
6298fc7fa798f7a36955f1b933980401afad2aff592pbos  }
6308fc7fa798f7a36955f1b933980401afad2aff592pbos  if (sync_audio_stream)
6318fc7fa798f7a36955f1b933980401afad2aff592pbos    sync_stream_mapping_[sync_group] = sync_audio_stream;
6328fc7fa798f7a36955f1b933980401afad2aff592pbos  size_t num_synced_streams = 0;
6338fc7fa798f7a36955f1b933980401afad2aff592pbos  for (VideoReceiveStream* video_stream : video_receive_streams_) {
6348fc7fa798f7a36955f1b933980401afad2aff592pbos    if (video_stream->config().sync_group != sync_group)
6358fc7fa798f7a36955f1b933980401afad2aff592pbos      continue;
6368fc7fa798f7a36955f1b933980401afad2aff592pbos    ++num_synced_streams;
6378fc7fa798f7a36955f1b933980401afad2aff592pbos    if (num_synced_streams > 1) {
6388fc7fa798f7a36955f1b933980401afad2aff592pbos      // TODO(pbos): Support synchronizing more than one A/V pair.
6398fc7fa798f7a36955f1b933980401afad2aff592pbos      // https://code.google.com/p/webrtc/issues/detail?id=4762
6408fc7fa798f7a36955f1b933980401afad2aff592pbos      LOG(LS_WARNING) << "Attempting to sync more than one audio/video pair "
6418fc7fa798f7a36955f1b933980401afad2aff592pbos                         "within the same sync group. This is not supported in "
6428fc7fa798f7a36955f1b933980401afad2aff592pbos                         "the current implementation.";
6438fc7fa798f7a36955f1b933980401afad2aff592pbos    }
6448fc7fa798f7a36955f1b933980401afad2aff592pbos    // Only sync the first A/V pair within this sync group.
6458fc7fa798f7a36955f1b933980401afad2aff592pbos    if (sync_audio_stream != nullptr && num_synced_streams == 1) {
646566ef247b9779f6c9d0e7ec9eea6b037f4682c53solenberg      video_stream->SetSyncChannel(voice_engine(),
6478fc7fa798f7a36955f1b933980401afad2aff592pbos                                   sync_audio_stream->config().voe_channel_id);
6488fc7fa798f7a36955f1b933980401afad2aff592pbos    } else {
649566ef247b9779f6c9d0e7ec9eea6b037f4682c53solenberg      video_stream->SetSyncChannel(voice_engine(), -1);
6508fc7fa798f7a36955f1b933980401afad2aff592pbos    }
6518fc7fa798f7a36955f1b933980401afad2aff592pbos  }
6528fc7fa798f7a36955f1b933980401afad2aff592pbos}
6538fc7fa798f7a36955f1b933980401afad2aff592pbos
65423fba1ffa0079f70744a83bcf4e85501dc226013Fredrik SolenbergPacketReceiver::DeliveryStatus Call::DeliverRtcp(MediaType media_type,
65523fba1ffa0079f70744a83bcf4e85501dc226013Fredrik Solenberg                                                 const uint8_t* packet,
65623fba1ffa0079f70744a83bcf4e85501dc226013Fredrik Solenberg                                                 size_t length) {
6576f28cf0b951a9d41246f022f48a6cd035fad151dPeter Boström  TRACE_EVENT0("webrtc", "Call::DeliverRtcp");
65829d5839233b19743286a89676bd748a6bd8623d6pbos@webrtc.org  // TODO(pbos): Figure out what channel needs it actually.
65929d5839233b19743286a89676bd748a6bd8623d6pbos@webrtc.org  //             Do NOT broadcast! Also make sure it's a valid packet.
660caba2d2a370cb6b5e67c881ecfa57fdac7411de8pbos@webrtc.org  //             Return DELIVERY_UNKNOWN_SSRC if it can be determined that
661caba2d2a370cb6b5e67c881ecfa57fdac7411de8pbos@webrtc.org  //             there's no receiver of the packet.
662226befecfb5e56287482a2d6250f01d019761884Stefan Holmer  received_rtcp_bytes_ += length;
66329d5839233b19743286a89676bd748a6bd8623d6pbos@webrtc.org  bool rtcp_delivered = false;
66423fba1ffa0079f70744a83bcf4e85501dc226013Fredrik Solenberg  if (media_type == MediaType::ANY || media_type == MediaType::VIDEO) {
66526c0c41a06d77af54df547169d952a21319dea8cpbos@webrtc.org    ReadLockScoped read_lock(*receive_crit_);
66623fba1ffa0079f70744a83bcf4e85501dc226013Fredrik Solenberg    for (VideoReceiveStream* stream : video_receive_streams_) {
667b04965ccf83c2bc6e2758abab9bea0c18551a54civoc      if (stream->DeliverRtcp(packet, length)) {
6684052370e89a662119a302cad397ca562846ecf38pbos@webrtc.org        rtcp_delivered = true;
669b04965ccf83c2bc6e2758abab9bea0c18551a54civoc        if (event_log_)
670b04965ccf83c2bc6e2758abab9bea0c18551a54civoc          event_log_->LogRtcpPacket(true, media_type, packet, length);
671b04965ccf83c2bc6e2758abab9bea0c18551a54civoc      }
672bbb07e69e55761ca43b38f929f3e39f4bba70ef1pbos@webrtc.org    }
673bbb07e69e55761ca43b38f929f3e39f4bba70ef1pbos@webrtc.org  }
67423fba1ffa0079f70744a83bcf4e85501dc226013Fredrik Solenberg  if (media_type == MediaType::ANY || media_type == MediaType::VIDEO) {
67526c0c41a06d77af54df547169d952a21319dea8cpbos@webrtc.org    ReadLockScoped read_lock(*send_crit_);
67623fba1ffa0079f70744a83bcf4e85501dc226013Fredrik Solenberg    for (VideoSendStream* stream : video_send_streams_) {
677b04965ccf83c2bc6e2758abab9bea0c18551a54civoc      if (stream->DeliverRtcp(packet, length)) {
6784052370e89a662119a302cad397ca562846ecf38pbos@webrtc.org        rtcp_delivered = true;
679b04965ccf83c2bc6e2758abab9bea0c18551a54civoc        if (event_log_)
680b04965ccf83c2bc6e2758abab9bea0c18551a54civoc          event_log_->LogRtcpPacket(false, media_type, packet, length);
681b04965ccf83c2bc6e2758abab9bea0c18551a54civoc      }
68229d5839233b19743286a89676bd748a6bd8623d6pbos@webrtc.org    }
68329d5839233b19743286a89676bd748a6bd8623d6pbos@webrtc.org  }
684caba2d2a370cb6b5e67c881ecfa57fdac7411de8pbos@webrtc.org  return rtcp_delivered ? DELIVERY_OK : DELIVERY_PACKET_ERROR;
68529d5839233b19743286a89676bd748a6bd8623d6pbos@webrtc.org}
68629d5839233b19743286a89676bd748a6bd8623d6pbos@webrtc.org
68723fba1ffa0079f70744a83bcf4e85501dc226013Fredrik SolenbergPacketReceiver::DeliveryStatus Call::DeliverRtp(MediaType media_type,
68823fba1ffa0079f70744a83bcf4e85501dc226013Fredrik Solenberg                                                const uint8_t* packet,
68968786d20400f1f3744ad83549325665c18ea9e5bstefan                                                size_t length,
69068786d20400f1f3744ad83549325665c18ea9e5bstefan                                                const PacketTime& packet_time) {
6916f28cf0b951a9d41246f022f48a6cd035fad151dPeter Boström  TRACE_EVENT0("webrtc", "Call::DeliverRtp");
692af38f4e5116a9963015695e4bdc81bb03352800apbos@webrtc.org  // Minimum RTP header size.
693af38f4e5116a9963015695e4bdc81bb03352800apbos@webrtc.org  if (length < 12)
694af38f4e5116a9963015695e4bdc81bb03352800apbos@webrtc.org    return DELIVERY_PACKET_ERROR;
695af38f4e5116a9963015695e4bdc81bb03352800apbos@webrtc.org
696226befecfb5e56287482a2d6250f01d019761884Stefan Holmer  last_rtp_packet_received_ms_ = clock_->TimeInMilliseconds();
69791d926038f7cebf889ef843f2f087d72bc8c60c2stefan  if (first_rtp_packet_received_ms_ == -1)
698226befecfb5e56287482a2d6250f01d019761884Stefan Holmer    first_rtp_packet_received_ms_ = last_rtp_packet_received_ms_;
699af38f4e5116a9963015695e4bdc81bb03352800apbos@webrtc.org
70091d926038f7cebf889ef843f2f087d72bc8c60c2stefan  uint32_t ssrc = ByteReader<uint32_t>::ReadBigEndian(&packet[8]);
70126c0c41a06d77af54df547169d952a21319dea8cpbos@webrtc.org  ReadLockScoped read_lock(*receive_crit_);
70223fba1ffa0079f70744a83bcf4e85501dc226013Fredrik Solenberg  if (media_type == MediaType::ANY || media_type == MediaType::AUDIO) {
70323fba1ffa0079f70744a83bcf4e85501dc226013Fredrik Solenberg    auto it = audio_receive_ssrcs_.find(ssrc);
70423fba1ffa0079f70744a83bcf4e85501dc226013Fredrik Solenberg    if (it != audio_receive_ssrcs_.end()) {
705226befecfb5e56287482a2d6250f01d019761884Stefan Holmer      received_audio_bytes_ += length;
706b04965ccf83c2bc6e2758abab9bea0c18551a54civoc      auto status = it->second->DeliverRtp(packet, length, packet_time)
707b04965ccf83c2bc6e2758abab9bea0c18551a54civoc                        ? DELIVERY_OK
708b04965ccf83c2bc6e2758abab9bea0c18551a54civoc                        : DELIVERY_PACKET_ERROR;
709b04965ccf83c2bc6e2758abab9bea0c18551a54civoc      if (status == DELIVERY_OK && event_log_)
710b04965ccf83c2bc6e2758abab9bea0c18551a54civoc        event_log_->LogRtpHeader(true, media_type, packet, length);
711b04965ccf83c2bc6e2758abab9bea0c18551a54civoc      return status;
71223fba1ffa0079f70744a83bcf4e85501dc226013Fredrik Solenberg    }
71323fba1ffa0079f70744a83bcf4e85501dc226013Fredrik Solenberg  }
71423fba1ffa0079f70744a83bcf4e85501dc226013Fredrik Solenberg  if (media_type == MediaType::ANY || media_type == MediaType::VIDEO) {
71523fba1ffa0079f70744a83bcf4e85501dc226013Fredrik Solenberg    auto it = video_receive_ssrcs_.find(ssrc);
71623fba1ffa0079f70744a83bcf4e85501dc226013Fredrik Solenberg    if (it != video_receive_ssrcs_.end()) {
717226befecfb5e56287482a2d6250f01d019761884Stefan Holmer      received_video_bytes_ += length;
718b04965ccf83c2bc6e2758abab9bea0c18551a54civoc      auto status = it->second->DeliverRtp(packet, length, packet_time)
719b04965ccf83c2bc6e2758abab9bea0c18551a54civoc                        ? DELIVERY_OK
720b04965ccf83c2bc6e2758abab9bea0c18551a54civoc                        : DELIVERY_PACKET_ERROR;
721b04965ccf83c2bc6e2758abab9bea0c18551a54civoc      if (status == DELIVERY_OK && event_log_)
722b04965ccf83c2bc6e2758abab9bea0c18551a54civoc        event_log_->LogRtpHeader(true, media_type, packet, length);
723b04965ccf83c2bc6e2758abab9bea0c18551a54civoc      return status;
72423fba1ffa0079f70744a83bcf4e85501dc226013Fredrik Solenberg    }
72523fba1ffa0079f70744a83bcf4e85501dc226013Fredrik Solenberg  }
72623fba1ffa0079f70744a83bcf4e85501dc226013Fredrik Solenberg  return DELIVERY_UNKNOWN_SSRC;
72729d5839233b19743286a89676bd748a6bd8623d6pbos@webrtc.org}
72829d5839233b19743286a89676bd748a6bd8623d6pbos@webrtc.org
72968786d20400f1f3744ad83549325665c18ea9e5bstefanPacketReceiver::DeliveryStatus Call::DeliverPacket(
73068786d20400f1f3744ad83549325665c18ea9e5bstefan    MediaType media_type,
73168786d20400f1f3744ad83549325665c18ea9e5bstefan    const uint8_t* packet,
73268786d20400f1f3744ad83549325665c18ea9e5bstefan    size_t length,
73368786d20400f1f3744ad83549325665c18ea9e5bstefan    const PacketTime& packet_time) {
7345a289393928c18af580c6339ba77600fb67006e2solenberg  // TODO(solenberg): Tests call this function on a network thread, libjingle
7355a289393928c18af580c6339ba77600fb67006e2solenberg  // calls on the worker thread. We should move towards always using a network
7365a289393928c18af580c6339ba77600fb67006e2solenberg  // thread. Then this check can be enabled.
7375a289393928c18af580c6339ba77600fb67006e2solenberg  // RTC_DCHECK(!configuration_thread_checker_.CalledOnValidThread());
73862bafae6618fe3aefbd18657062abc98a40c3375pbos@webrtc.org  if (RtpHeaderParser::IsRtcp(packet, length))
73923fba1ffa0079f70744a83bcf4e85501dc226013Fredrik Solenberg    return DeliverRtcp(media_type, packet, length);
74029d5839233b19743286a89676bd748a6bd8623d6pbos@webrtc.org
74168786d20400f1f3744ad83549325665c18ea9e5bstefan  return DeliverRtp(media_type, packet, length, packet_time);
74229d5839233b19743286a89676bd748a6bd8623d6pbos@webrtc.org}
74329d5839233b19743286a89676bd748a6bd8623d6pbos@webrtc.org
74429d5839233b19743286a89676bd748a6bd8623d6pbos@webrtc.org}  // namespace internal
74529d5839233b19743286a89676bd748a6bd8623d6pbos@webrtc.org}  // namespace webrtc
746