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