congestion_controller.cc revision 867fb5224e1ba6a1c2cd523c005499a93ed61a08
19ec883e8bd334acfc246741f7a2cca3e55d7f5b2mflodman@webrtc.org/* 29ec883e8bd334acfc246741f7a2cca3e55d7f5b2mflodman@webrtc.org * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 39ec883e8bd334acfc246741f7a2cca3e55d7f5b2mflodman@webrtc.org * 49ec883e8bd334acfc246741f7a2cca3e55d7f5b2mflodman@webrtc.org * Use of this source code is governed by a BSD-style license 59ec883e8bd334acfc246741f7a2cca3e55d7f5b2mflodman@webrtc.org * that can be found in the LICENSE file in the root of the source 69ec883e8bd334acfc246741f7a2cca3e55d7f5b2mflodman@webrtc.org * tree. An additional intellectual property rights grant can be found 79ec883e8bd334acfc246741f7a2cca3e55d7f5b2mflodman@webrtc.org * in the file PATENTS. All contributing project authors may 89ec883e8bd334acfc246741f7a2cca3e55d7f5b2mflodman@webrtc.org * be found in the AUTHORS file in the root of the source tree. 99ec883e8bd334acfc246741f7a2cca3e55d7f5b2mflodman@webrtc.org */ 109ec883e8bd334acfc246741f7a2cca3e55d7f5b2mflodman@webrtc.org 1129b2219914a059fe5164c312e7cc6d1bf0b4e610andresp@webrtc.org#include "webrtc/video_engine/vie_channel_group.h" 129ec883e8bd334acfc246741f7a2cca3e55d7f5b2mflodman@webrtc.org 13a50e6f073deecfd9004e6e4946eabd8c34621608stefan@webrtc.org#include "webrtc/base/checks.h" 1438344ed2806c8fed60d67d280ca44c32e36707c0pbos@webrtc.org#include "webrtc/base/thread_annotations.h" 1529b2219914a059fe5164c312e7cc6d1bf0b4e610andresp@webrtc.org#include "webrtc/common.h" 16e59041672283a28bde0b043c0c2bc198272f82e1Stefan Holmer#include "webrtc/modules/pacing/include/paced_sender.h" 17e59041672283a28bde0b043c0c2bc198272f82e1Stefan Holmer#include "webrtc/modules/pacing/include/packet_router.h" 18867fb5224e1ba6a1c2cd523c005499a93ed61a08sprang#include "webrtc/modules/remote_bitrate_estimator/include/send_time_history.h" 19468e62a97426a8d001e9187f3ca1d1e43f80b970Erik Språng#include "webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_abs_send_time.h" 20468e62a97426a8d001e9187f3ca1d1e43f80b970Erik Språng#include "webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_single_stream.h" 2129b2219914a059fe5164c312e7cc6d1bf0b4e610andresp@webrtc.org#include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp.h" 2229b2219914a059fe5164c312e7cc6d1bf0b4e610andresp@webrtc.org#include "webrtc/modules/utility/interface/process_thread.h" 23a6db54d4c9a2bfc703bc208eb5cbc19505e9cef3solenberg@webrtc.org#include "webrtc/system_wrappers/interface/critical_section_wrapper.h" 245574dacd1f83d8ac83458d27e54be6507f3a06a4mflodman@webrtc.org#include "webrtc/system_wrappers/interface/logging.h" 2529b2219914a059fe5164c312e7cc6d1bf0b4e610andresp@webrtc.org#include "webrtc/video_engine/call_stats.h" 2629b2219914a059fe5164c312e7cc6d1bf0b4e610andresp@webrtc.org#include "webrtc/video_engine/encoder_state_feedback.h" 27a50e6f073deecfd9004e6e4946eabd8c34621608stefan@webrtc.org#include "webrtc/video_engine/payload_router.h" 2829b2219914a059fe5164c312e7cc6d1bf0b4e610andresp@webrtc.org#include "webrtc/video_engine/vie_channel.h" 2929b2219914a059fe5164c312e7cc6d1bf0b4e610andresp@webrtc.org#include "webrtc/video_engine/vie_encoder.h" 3029b2219914a059fe5164c312e7cc6d1bf0b4e610andresp@webrtc.org#include "webrtc/video_engine/vie_remb.h" 31a50e6f073deecfd9004e6e4946eabd8c34621608stefan@webrtc.org#include "webrtc/voice_engine/include/voe_video_sync.h" 329ec883e8bd334acfc246741f7a2cca3e55d7f5b2mflodman@webrtc.org 339ec883e8bd334acfc246741f7a2cca3e55d7f5b2mflodman@webrtc.orgnamespace webrtc { 34a6db54d4c9a2bfc703bc208eb5cbc19505e9cef3solenberg@webrtc.orgnamespace { 35a6db54d4c9a2bfc703bc208eb5cbc19505e9cef3solenberg@webrtc.org 365ab756703ea32f2c2ff9878d6eae628c7380bc14pbos@webrtc.orgstatic const uint32_t kTimeOffsetSwitchThreshold = 30; 37ef35f069e739feaae16fdfcc815d7af5cb05e9aepbosstatic const uint32_t kMinBitrateBps = 30000; 385ab756703ea32f2c2ff9878d6eae628c7380bc14pbos@webrtc.org 39a6db54d4c9a2bfc703bc208eb5cbc19505e9cef3solenberg@webrtc.orgclass WrappingBitrateEstimator : public RemoteBitrateEstimator { 40a6db54d4c9a2bfc703bc208eb5cbc19505e9cef3solenberg@webrtc.org public: 41ef35f069e739feaae16fdfcc815d7af5cb05e9aepbos WrappingBitrateEstimator(RemoteBitrateObserver* observer, Clock* clock) 42a6db54d4c9a2bfc703bc208eb5cbc19505e9cef3solenberg@webrtc.org : observer_(observer), 43a6db54d4c9a2bfc703bc208eb5cbc19505e9cef3solenberg@webrtc.org clock_(clock), 44a6db54d4c9a2bfc703bc208eb5cbc19505e9cef3solenberg@webrtc.org crit_sect_(CriticalSectionWrapper::CreateCriticalSection()), 45ef35f069e739feaae16fdfcc815d7af5cb05e9aepbos min_bitrate_bps_(kMinBitrateBps), 46468e62a97426a8d001e9187f3ca1d1e43f80b970Erik Språng rbe_(new RemoteBitrateEstimatorSingleStream(observer_, 47a16147c03726e54b2ecb1e48c7171a33d83a5261stefan@webrtc.org clock_, 48e9abd591d73218e11a8bd3e7c72d4d7af9a3cea8henrik.lundin@webrtc.org min_bitrate_bps_)), 495ab756703ea32f2c2ff9878d6eae628c7380bc14pbos@webrtc.org using_absolute_send_time_(false), 50468e62a97426a8d001e9187f3ca1d1e43f80b970Erik Språng packets_since_absolute_send_time_(0) {} 51a6db54d4c9a2bfc703bc208eb5cbc19505e9cef3solenberg@webrtc.org 521295dc6a237a7c2d2cb0dbfd53c57babf1034901andresp@webrtc.org virtual ~WrappingBitrateEstimator() {} 531295dc6a237a7c2d2cb0dbfd53c57babf1034901andresp@webrtc.org 5414665ff7d4024d07e58622f498b23fd980001871kjellander@webrtc.org void IncomingPacket(int64_t arrival_time_ms, 5514665ff7d4024d07e58622f498b23fd980001871kjellander@webrtc.org size_t payload_size, 56ff4ea9310e981da6292fb044cff9eeefd986cf2bStefan Holmer const RTPHeader& header, 57ff4ea9310e981da6292fb044cff9eeefd986cf2bStefan Holmer bool was_paced) override { 58a6db54d4c9a2bfc703bc208eb5cbc19505e9cef3solenberg@webrtc.org CriticalSectionScoped cs(crit_sect_.get()); 59a16147c03726e54b2ecb1e48c7171a33d83a5261stefan@webrtc.org PickEstimatorFromHeader(header); 60ff4ea9310e981da6292fb044cff9eeefd986cf2bStefan Holmer rbe_->IncomingPacket(arrival_time_ms, payload_size, header, was_paced); 61a6db54d4c9a2bfc703bc208eb5cbc19505e9cef3solenberg@webrtc.org } 62a6db54d4c9a2bfc703bc208eb5cbc19505e9cef3solenberg@webrtc.org 6314665ff7d4024d07e58622f498b23fd980001871kjellander@webrtc.org int32_t Process() override { 641295dc6a237a7c2d2cb0dbfd53c57babf1034901andresp@webrtc.org CriticalSectionScoped cs(crit_sect_.get()); 651295dc6a237a7c2d2cb0dbfd53c57babf1034901andresp@webrtc.org return rbe_->Process(); 66a6db54d4c9a2bfc703bc208eb5cbc19505e9cef3solenberg@webrtc.org } 67a6db54d4c9a2bfc703bc208eb5cbc19505e9cef3solenberg@webrtc.org 6814665ff7d4024d07e58622f498b23fd980001871kjellander@webrtc.org int64_t TimeUntilNextProcess() override { 691295dc6a237a7c2d2cb0dbfd53c57babf1034901andresp@webrtc.org CriticalSectionScoped cs(crit_sect_.get()); 701295dc6a237a7c2d2cb0dbfd53c57babf1034901andresp@webrtc.org return rbe_->TimeUntilNextProcess(); 71a6db54d4c9a2bfc703bc208eb5cbc19505e9cef3solenberg@webrtc.org } 72a6db54d4c9a2bfc703bc208eb5cbc19505e9cef3solenberg@webrtc.org 7314665ff7d4024d07e58622f498b23fd980001871kjellander@webrtc.org void OnRttUpdate(int64_t rtt) override { 74a6db54d4c9a2bfc703bc208eb5cbc19505e9cef3solenberg@webrtc.org CriticalSectionScoped cs(crit_sect_.get()); 75a6db54d4c9a2bfc703bc208eb5cbc19505e9cef3solenberg@webrtc.org rbe_->OnRttUpdate(rtt); 76a6db54d4c9a2bfc703bc208eb5cbc19505e9cef3solenberg@webrtc.org } 77a6db54d4c9a2bfc703bc208eb5cbc19505e9cef3solenberg@webrtc.org 7814665ff7d4024d07e58622f498b23fd980001871kjellander@webrtc.org void RemoveStream(unsigned int ssrc) override { 79a6db54d4c9a2bfc703bc208eb5cbc19505e9cef3solenberg@webrtc.org CriticalSectionScoped cs(crit_sect_.get()); 80a6db54d4c9a2bfc703bc208eb5cbc19505e9cef3solenberg@webrtc.org rbe_->RemoveStream(ssrc); 81a6db54d4c9a2bfc703bc208eb5cbc19505e9cef3solenberg@webrtc.org } 82a6db54d4c9a2bfc703bc208eb5cbc19505e9cef3solenberg@webrtc.org 8314665ff7d4024d07e58622f498b23fd980001871kjellander@webrtc.org bool LatestEstimate(std::vector<unsigned int>* ssrcs, 8414665ff7d4024d07e58622f498b23fd980001871kjellander@webrtc.org unsigned int* bitrate_bps) const override { 85a6db54d4c9a2bfc703bc208eb5cbc19505e9cef3solenberg@webrtc.org CriticalSectionScoped cs(crit_sect_.get()); 86a6db54d4c9a2bfc703bc208eb5cbc19505e9cef3solenberg@webrtc.org return rbe_->LatestEstimate(ssrcs, bitrate_bps); 87a6db54d4c9a2bfc703bc208eb5cbc19505e9cef3solenberg@webrtc.org } 88a6db54d4c9a2bfc703bc208eb5cbc19505e9cef3solenberg@webrtc.org 8914665ff7d4024d07e58622f498b23fd980001871kjellander@webrtc.org bool GetStats(ReceiveBandwidthEstimatorStats* output) const override { 901f64f067840212b3e5b67a0d6a50bcd805b5bc1ajiayl@webrtc.org CriticalSectionScoped cs(crit_sect_.get()); 911f64f067840212b3e5b67a0d6a50bcd805b5bc1ajiayl@webrtc.org return rbe_->GetStats(output); 921f64f067840212b3e5b67a0d6a50bcd805b5bc1ajiayl@webrtc.org } 931f64f067840212b3e5b67a0d6a50bcd805b5bc1ajiayl@webrtc.org 94a6db54d4c9a2bfc703bc208eb5cbc19505e9cef3solenberg@webrtc.org private: 95a16147c03726e54b2ecb1e48c7171a33d83a5261stefan@webrtc.org void PickEstimatorFromHeader(const RTPHeader& header) 96a16147c03726e54b2ecb1e48c7171a33d83a5261stefan@webrtc.org EXCLUSIVE_LOCKS_REQUIRED(crit_sect_.get()) { 975ab756703ea32f2c2ff9878d6eae628c7380bc14pbos@webrtc.org if (header.extension.hasAbsoluteSendTime) { 985ab756703ea32f2c2ff9878d6eae628c7380bc14pbos@webrtc.org // If we see AST in header, switch RBE strategy immediately. 995ab756703ea32f2c2ff9878d6eae628c7380bc14pbos@webrtc.org if (!using_absolute_send_time_) { 1005574dacd1f83d8ac83458d27e54be6507f3a06a4mflodman@webrtc.org LOG(LS_INFO) << 1015574dacd1f83d8ac83458d27e54be6507f3a06a4mflodman@webrtc.org "WrappingBitrateEstimator: Switching to absolute send time RBE."; 1025ab756703ea32f2c2ff9878d6eae628c7380bc14pbos@webrtc.org using_absolute_send_time_ = true; 103a16147c03726e54b2ecb1e48c7171a33d83a5261stefan@webrtc.org PickEstimator(); 1045ab756703ea32f2c2ff9878d6eae628c7380bc14pbos@webrtc.org } 1055ab756703ea32f2c2ff9878d6eae628c7380bc14pbos@webrtc.org packets_since_absolute_send_time_ = 0; 1065ab756703ea32f2c2ff9878d6eae628c7380bc14pbos@webrtc.org } else { 1075ab756703ea32f2c2ff9878d6eae628c7380bc14pbos@webrtc.org // When we don't see AST, wait for a few packets before going back to TOF. 1085ab756703ea32f2c2ff9878d6eae628c7380bc14pbos@webrtc.org if (using_absolute_send_time_) { 1095ab756703ea32f2c2ff9878d6eae628c7380bc14pbos@webrtc.org ++packets_since_absolute_send_time_; 1105ab756703ea32f2c2ff9878d6eae628c7380bc14pbos@webrtc.org if (packets_since_absolute_send_time_ >= kTimeOffsetSwitchThreshold) { 1115574dacd1f83d8ac83458d27e54be6507f3a06a4mflodman@webrtc.org LOG(LS_INFO) << "WrappingBitrateEstimator: Switching to transmission " 1125574dacd1f83d8ac83458d27e54be6507f3a06a4mflodman@webrtc.org << "time offset RBE."; 1135ab756703ea32f2c2ff9878d6eae628c7380bc14pbos@webrtc.org using_absolute_send_time_ = false; 114a16147c03726e54b2ecb1e48c7171a33d83a5261stefan@webrtc.org PickEstimator(); 1155ab756703ea32f2c2ff9878d6eae628c7380bc14pbos@webrtc.org } 1165ab756703ea32f2c2ff9878d6eae628c7380bc14pbos@webrtc.org } 1175ab756703ea32f2c2ff9878d6eae628c7380bc14pbos@webrtc.org } 1185ab756703ea32f2c2ff9878d6eae628c7380bc14pbos@webrtc.org } 1195ab756703ea32f2c2ff9878d6eae628c7380bc14pbos@webrtc.org 120a16147c03726e54b2ecb1e48c7171a33d83a5261stefan@webrtc.org // Instantiate RBE for Time Offset or Absolute Send Time extensions. 121a16147c03726e54b2ecb1e48c7171a33d83a5261stefan@webrtc.org void PickEstimator() EXCLUSIVE_LOCKS_REQUIRED(crit_sect_.get()) { 122a16147c03726e54b2ecb1e48c7171a33d83a5261stefan@webrtc.org if (using_absolute_send_time_) { 123468e62a97426a8d001e9187f3ca1d1e43f80b970Erik Språng rbe_.reset(new RemoteBitrateEstimatorAbsSendTime(observer_, clock_, 124468e62a97426a8d001e9187f3ca1d1e43f80b970Erik Språng min_bitrate_bps_)); 125a16147c03726e54b2ecb1e48c7171a33d83a5261stefan@webrtc.org } else { 126468e62a97426a8d001e9187f3ca1d1e43f80b970Erik Språng rbe_.reset(new RemoteBitrateEstimatorSingleStream(observer_, clock_, 127468e62a97426a8d001e9187f3ca1d1e43f80b970Erik Språng min_bitrate_bps_)); 128a16147c03726e54b2ecb1e48c7171a33d83a5261stefan@webrtc.org } 129a16147c03726e54b2ecb1e48c7171a33d83a5261stefan@webrtc.org } 130a16147c03726e54b2ecb1e48c7171a33d83a5261stefan@webrtc.org 131a6db54d4c9a2bfc703bc208eb5cbc19505e9cef3solenberg@webrtc.org RemoteBitrateObserver* observer_; 132a6db54d4c9a2bfc703bc208eb5cbc19505e9cef3solenberg@webrtc.org Clock* clock_; 13300b8f6b3643332cce1ee711715f7fbb824d793cakwiberg@webrtc.org rtc::scoped_ptr<CriticalSectionWrapper> crit_sect_; 134e9abd591d73218e11a8bd3e7c72d4d7af9a3cea8henrik.lundin@webrtc.org const uint32_t min_bitrate_bps_; 13500b8f6b3643332cce1ee711715f7fbb824d793cakwiberg@webrtc.org rtc::scoped_ptr<RemoteBitrateEstimator> rbe_; 1365ab756703ea32f2c2ff9878d6eae628c7380bc14pbos@webrtc.org bool using_absolute_send_time_; 1375ab756703ea32f2c2ff9878d6eae628c7380bc14pbos@webrtc.org uint32_t packets_since_absolute_send_time_; 138a6db54d4c9a2bfc703bc208eb5cbc19505e9cef3solenberg@webrtc.org 139a6db54d4c9a2bfc703bc208eb5cbc19505e9cef3solenberg@webrtc.org DISALLOW_IMPLICIT_CONSTRUCTORS(WrappingBitrateEstimator); 140a6db54d4c9a2bfc703bc208eb5cbc19505e9cef3solenberg@webrtc.org}; 141867fb5224e1ba6a1c2cd523c005499a93ed61a08sprang 142867fb5224e1ba6a1c2cd523c005499a93ed61a08sprangstatic const int64_t kSendTimeHistoryWindowMs = 2000; 143867fb5224e1ba6a1c2cd523c005499a93ed61a08sprang 144a6db54d4c9a2bfc703bc208eb5cbc19505e9cef3solenberg@webrtc.org} // namespace 1459ec883e8bd334acfc246741f7a2cca3e55d7f5b2mflodman@webrtc.org 146867fb5224e1ba6a1c2cd523c005499a93ed61a08sprangclass AdaptedSendTimeHistory : public SendTimeHistory, public SendTimeObserver { 147867fb5224e1ba6a1c2cd523c005499a93ed61a08sprang public: 148867fb5224e1ba6a1c2cd523c005499a93ed61a08sprang AdaptedSendTimeHistory() : SendTimeHistory(kSendTimeHistoryWindowMs) {} 149867fb5224e1ba6a1c2cd523c005499a93ed61a08sprang virtual ~AdaptedSendTimeHistory() {} 150867fb5224e1ba6a1c2cd523c005499a93ed61a08sprang 151867fb5224e1ba6a1c2cd523c005499a93ed61a08sprang void OnPacketSent(uint16_t sequence_number, int64_t send_time) override { 152867fb5224e1ba6a1c2cd523c005499a93ed61a08sprang SendTimeHistory::AddAndRemoveOldSendTimes(sequence_number, send_time); 153867fb5224e1ba6a1c2cd523c005499a93ed61a08sprang } 154867fb5224e1ba6a1c2cd523c005499a93ed61a08sprang}; 155867fb5224e1ba6a1c2cd523c005499a93ed61a08sprang 1562251d6e17438e1a085ff4f88ad19de513214bec1Peter BoströmChannelGroup::ChannelGroup(ProcessThread* process_thread) 157b5865079868c4dec49571e7aef0aa52124b50c64stefan@webrtc.org : remb_(new VieRemb()), 158792f1a14e2b62382c5c6080d0b8fdc5c89d27bc6stefan@webrtc.org bitrate_allocator_(new BitrateAllocator()), 1597c894b7cc718773f32d21985ff33a64f9e13946emflodman@webrtc.org call_stats_(new CallStats()), 1607c894b7cc718773f32d21985ff33a64f9e13946emflodman@webrtc.org encoder_state_feedback_(new EncoderStateFeedback()), 161e59041672283a28bde0b043c0c2bc198272f82e1Stefan Holmer packet_router_(new PacketRouter()), 162e59041672283a28bde0b043c0c2bc198272f82e1Stefan Holmer pacer_(new PacedSender(Clock::GetRealTimeClock(), 163e59041672283a28bde0b043c0c2bc198272f82e1Stefan Holmer packet_router_.get(), 164e59041672283a28bde0b043c0c2bc198272f82e1Stefan Holmer BitrateController::kDefaultStartBitrateKbps, 165e59041672283a28bde0b043c0c2bc198272f82e1Stefan Holmer PacedSender::kDefaultPaceMultiplier * 166e59041672283a28bde0b043c0c2bc198272f82e1Stefan Holmer BitrateController::kDefaultStartBitrateKbps, 167e59041672283a28bde0b043c0c2bc198272f82e1Stefan Holmer 0)), 168e59041672283a28bde0b043c0c2bc198272f82e1Stefan Holmer process_thread_(process_thread), 169e59041672283a28bde0b043c0c2bc198272f82e1Stefan Holmer pacer_thread_(ProcessThread::Create()), 170e59041672283a28bde0b043c0c2bc198272f82e1Stefan Holmer // Constructed last as this object calls the provided callback on 171e59041672283a28bde0b043c0c2bc198272f82e1Stefan Holmer // construction. 172e59041672283a28bde0b043c0c2bc198272f82e1Stefan Holmer bitrate_controller_( 173e59041672283a28bde0b043c0c2bc198272f82e1Stefan Holmer BitrateController::CreateBitrateController(Clock::GetRealTimeClock(), 174867fb5224e1ba6a1c2cd523c005499a93ed61a08sprang this)), 175867fb5224e1ba6a1c2cd523c005499a93ed61a08sprang send_time_history_(new AdaptedSendTimeHistory()) { 1762251d6e17438e1a085ff4f88ad19de513214bec1Peter Boström remote_bitrate_estimator_.reset(new WrappingBitrateEstimator( 177ef35f069e739feaae16fdfcc815d7af5cb05e9aepbos remb_.get(), Clock::GetRealTimeClock())); 1781295dc6a237a7c2d2cb0dbfd53c57babf1034901andresp@webrtc.org 1791295dc6a237a7c2d2cb0dbfd53c57babf1034901andresp@webrtc.org call_stats_->RegisterStatsObserver(remote_bitrate_estimator_.get()); 18044caf01c34d4fddec039f917c83fed7e0ce977b2andresp@webrtc.org 181e59041672283a28bde0b043c0c2bc198272f82e1Stefan Holmer pacer_thread_->RegisterModule(pacer_.get()); 182e59041672283a28bde0b043c0c2bc198272f82e1Stefan Holmer pacer_thread_->Start(); 183e59041672283a28bde0b043c0c2bc198272f82e1Stefan Holmer 1841295dc6a237a7c2d2cb0dbfd53c57babf1034901andresp@webrtc.org process_thread->RegisterModule(remote_bitrate_estimator_.get()); 1857c894b7cc718773f32d21985ff33a64f9e13946emflodman@webrtc.org process_thread->RegisterModule(call_stats_.get()); 18644caf01c34d4fddec039f917c83fed7e0ce977b2andresp@webrtc.org process_thread->RegisterModule(bitrate_controller_.get()); 18749888ce42858e308c7b0575697f06e2483a34daepwestin@webrtc.org} 1889ec883e8bd334acfc246741f7a2cca3e55d7f5b2mflodman@webrtc.org 1899ec883e8bd334acfc246741f7a2cca3e55d7f5b2mflodman@webrtc.orgChannelGroup::~ChannelGroup() { 190e59041672283a28bde0b043c0c2bc198272f82e1Stefan Holmer pacer_thread_->Stop(); 191e59041672283a28bde0b043c0c2bc198272f82e1Stefan Holmer pacer_thread_->DeRegisterModule(pacer_.get()); 19244caf01c34d4fddec039f917c83fed7e0ce977b2andresp@webrtc.org process_thread_->DeRegisterModule(bitrate_controller_.get()); 1936cd201cf31dc8e50bf815139b0c9fdc83d3ba2bfandrew@webrtc.org process_thread_->DeRegisterModule(call_stats_.get()); 1941295dc6a237a7c2d2cb0dbfd53c57babf1034901andresp@webrtc.org process_thread_->DeRegisterModule(remote_bitrate_estimator_.get()); 19544caf01c34d4fddec039f917c83fed7e0ce977b2andresp@webrtc.org call_stats_->DeregisterStatsObserver(remote_bitrate_estimator_.get()); 196a50e6f073deecfd9004e6e4946eabd8c34621608stefan@webrtc.org DCHECK(channel_map_.empty()); 197a50e6f073deecfd9004e6e4946eabd8c34621608stefan@webrtc.org DCHECK(!remb_->InUse()); 198a50e6f073deecfd9004e6e4946eabd8c34621608stefan@webrtc.org DCHECK(vie_encoder_map_.empty()); 199a50e6f073deecfd9004e6e4946eabd8c34621608stefan@webrtc.org} 200a50e6f073deecfd9004e6e4946eabd8c34621608stefan@webrtc.org 201a50e6f073deecfd9004e6e4946eabd8c34621608stefan@webrtc.orgbool ChannelGroup::CreateSendChannel(int channel_id, 202a50e6f073deecfd9004e6e4946eabd8c34621608stefan@webrtc.org int engine_id, 2032251d6e17438e1a085ff4f88ad19de513214bec1Peter Boström Transport* transport, 2045a3ebd761cb2789aa63e4ae7c0035234a3e3b5f3Peter Boström int number_of_cores, 205d6fc47ea9585fa405d8617ccc0b7704d2c9e8a0apbos const std::vector<uint32_t>& ssrcs) { 2068ff04d6b3b9a2fc28394ef6ad77201a1443e24c8pbos // TODO(pbos): Remove checks for empty ssrcs and add this check when there's 2078ff04d6b3b9a2fc28394ef6ad77201a1443e24c8pbos // no base channel. 2088ff04d6b3b9a2fc28394ef6ad77201a1443e24c8pbos // DCHECK(!ssrcs.empty()); 209ef35f069e739feaae16fdfcc815d7af5cb05e9aepbos rtc::scoped_ptr<ViEEncoder> vie_encoder(new ViEEncoder( 210ef35f069e739feaae16fdfcc815d7af5cb05e9aepbos channel_id, number_of_cores, *process_thread_, pacer_.get(), 211ef35f069e739feaae16fdfcc815d7af5cb05e9aepbos bitrate_allocator_.get(), bitrate_controller_.get(), false)); 212a50e6f073deecfd9004e6e4946eabd8c34621608stefan@webrtc.org if (!vie_encoder->Init()) { 213a50e6f073deecfd9004e6e4946eabd8c34621608stefan@webrtc.org return false; 214a50e6f073deecfd9004e6e4946eabd8c34621608stefan@webrtc.org } 215a50e6f073deecfd9004e6e4946eabd8c34621608stefan@webrtc.org ViEEncoder* encoder = vie_encoder.get(); 2162251d6e17438e1a085ff4f88ad19de513214bec1Peter Boström if (!CreateChannel(channel_id, engine_id, transport, number_of_cores, 2178ff04d6b3b9a2fc28394ef6ad77201a1443e24c8pbos vie_encoder.release(), ssrcs.empty() ? 1 : ssrcs.size(), 218d6fc47ea9585fa405d8617ccc0b7704d2c9e8a0apbos true)) { 219a50e6f073deecfd9004e6e4946eabd8c34621608stefan@webrtc.org return false; 220a50e6f073deecfd9004e6e4946eabd8c34621608stefan@webrtc.org } 221a50e6f073deecfd9004e6e4946eabd8c34621608stefan@webrtc.org ViEChannel* channel = channel_map_[channel_id]; 222a50e6f073deecfd9004e6e4946eabd8c34621608stefan@webrtc.org // Connect the encoder with the send packet router, to enable sending. 223a50e6f073deecfd9004e6e4946eabd8c34621608stefan@webrtc.org encoder->StartThreadsAndSetSharedMembers(channel->send_payload_router(), 224a50e6f073deecfd9004e6e4946eabd8c34621608stefan@webrtc.org channel->vcm_protection_callback()); 225a50e6f073deecfd9004e6e4946eabd8c34621608stefan@webrtc.org 2268ff04d6b3b9a2fc28394ef6ad77201a1443e24c8pbos if (!ssrcs.empty()) { 2278ff04d6b3b9a2fc28394ef6ad77201a1443e24c8pbos encoder_state_feedback_->AddEncoder(ssrcs, encoder); 2288ff04d6b3b9a2fc28394ef6ad77201a1443e24c8pbos std::vector<uint32_t> first_ssrc(1, ssrcs[0]); 2298ff04d6b3b9a2fc28394ef6ad77201a1443e24c8pbos encoder->SetSsrcs(first_ssrc); 2308ff04d6b3b9a2fc28394ef6ad77201a1443e24c8pbos } 231a50e6f073deecfd9004e6e4946eabd8c34621608stefan@webrtc.org return true; 232a50e6f073deecfd9004e6e4946eabd8c34621608stefan@webrtc.org} 233a50e6f073deecfd9004e6e4946eabd8c34621608stefan@webrtc.org 234a50e6f073deecfd9004e6e4946eabd8c34621608stefan@webrtc.orgbool ChannelGroup::CreateReceiveChannel(int channel_id, 235a50e6f073deecfd9004e6e4946eabd8c34621608stefan@webrtc.org int engine_id, 2362251d6e17438e1a085ff4f88ad19de513214bec1Peter Boström Transport* transport, 237d6fc47ea9585fa405d8617ccc0b7704d2c9e8a0apbos int number_of_cores) { 2382251d6e17438e1a085ff4f88ad19de513214bec1Peter Boström return CreateChannel(channel_id, engine_id, transport, number_of_cores, 239d6fc47ea9585fa405d8617ccc0b7704d2c9e8a0apbos nullptr, 1, false); 240a50e6f073deecfd9004e6e4946eabd8c34621608stefan@webrtc.org} 241a50e6f073deecfd9004e6e4946eabd8c34621608stefan@webrtc.org 242a50e6f073deecfd9004e6e4946eabd8c34621608stefan@webrtc.orgbool ChannelGroup::CreateChannel(int channel_id, 243a50e6f073deecfd9004e6e4946eabd8c34621608stefan@webrtc.org int engine_id, 2442251d6e17438e1a085ff4f88ad19de513214bec1Peter Boström Transport* transport, 245a50e6f073deecfd9004e6e4946eabd8c34621608stefan@webrtc.org int number_of_cores, 246a50e6f073deecfd9004e6e4946eabd8c34621608stefan@webrtc.org ViEEncoder* vie_encoder, 247d6f1a38165455d743fbe61f6980f22be6a3c4de9Peter Boström size_t max_rtp_streams, 248d6fc47ea9585fa405d8617ccc0b7704d2c9e8a0apbos bool sender) { 249a50e6f073deecfd9004e6e4946eabd8c34621608stefan@webrtc.org rtc::scoped_ptr<ViEChannel> channel(new ViEChannel( 250ef35f069e739feaae16fdfcc815d7af5cb05e9aepbos channel_id, engine_id, number_of_cores, transport, process_thread_, 251ef35f069e739feaae16fdfcc815d7af5cb05e9aepbos encoder_state_feedback_->GetRtcpIntraFrameObserver(), 252a50e6f073deecfd9004e6e4946eabd8c34621608stefan@webrtc.org bitrate_controller_->CreateRtcpBandwidthObserver(), 253867fb5224e1ba6a1c2cd523c005499a93ed61a08sprang send_time_history_.get(), remote_bitrate_estimator_.get(), 254867fb5224e1ba6a1c2cd523c005499a93ed61a08sprang call_stats_->rtcp_rtt_stats(), pacer_.get(), packet_router_.get(), 255867fb5224e1ba6a1c2cd523c005499a93ed61a08sprang max_rtp_streams, sender)); 256a50e6f073deecfd9004e6e4946eabd8c34621608stefan@webrtc.org if (channel->Init() != 0) { 257a50e6f073deecfd9004e6e4946eabd8c34621608stefan@webrtc.org return false; 258a50e6f073deecfd9004e6e4946eabd8c34621608stefan@webrtc.org } 259a50e6f073deecfd9004e6e4946eabd8c34621608stefan@webrtc.org 260a50e6f073deecfd9004e6e4946eabd8c34621608stefan@webrtc.org // Register the channel to receive stats updates. 261a50e6f073deecfd9004e6e4946eabd8c34621608stefan@webrtc.org call_stats_->RegisterStatsObserver(channel->GetStatsObserver()); 262a50e6f073deecfd9004e6e4946eabd8c34621608stefan@webrtc.org 263a50e6f073deecfd9004e6e4946eabd8c34621608stefan@webrtc.org // Store the channel, add it to the channel group and save the vie_encoder. 264a50e6f073deecfd9004e6e4946eabd8c34621608stefan@webrtc.org channel_map_[channel_id] = channel.release(); 265d6fc47ea9585fa405d8617ccc0b7704d2c9e8a0apbos if (vie_encoder) { 266d6fc47ea9585fa405d8617ccc0b7704d2c9e8a0apbos rtc::CritScope lock(&encoder_map_crit_); 267e59041672283a28bde0b043c0c2bc198272f82e1Stefan Holmer vie_encoder_map_[channel_id] = vie_encoder; 268e59041672283a28bde0b043c0c2bc198272f82e1Stefan Holmer } 269a50e6f073deecfd9004e6e4946eabd8c34621608stefan@webrtc.org 270a50e6f073deecfd9004e6e4946eabd8c34621608stefan@webrtc.org return true; 271a50e6f073deecfd9004e6e4946eabd8c34621608stefan@webrtc.org} 272a50e6f073deecfd9004e6e4946eabd8c34621608stefan@webrtc.org 273a50e6f073deecfd9004e6e4946eabd8c34621608stefan@webrtc.orgvoid ChannelGroup::DeleteChannel(int channel_id) { 274a50e6f073deecfd9004e6e4946eabd8c34621608stefan@webrtc.org ViEChannel* vie_channel = PopChannel(channel_id); 275a50e6f073deecfd9004e6e4946eabd8c34621608stefan@webrtc.org 276a50e6f073deecfd9004e6e4946eabd8c34621608stefan@webrtc.org ViEEncoder* vie_encoder = GetEncoder(channel_id); 277a50e6f073deecfd9004e6e4946eabd8c34621608stefan@webrtc.org 278a50e6f073deecfd9004e6e4946eabd8c34621608stefan@webrtc.org call_stats_->DeregisterStatsObserver(vie_channel->GetStatsObserver()); 27976c53d36bc455fe89ca1f860d5171633198fe907Peter Boström SetChannelRembStatus(false, false, vie_channel); 280a50e6f073deecfd9004e6e4946eabd8c34621608stefan@webrtc.org 281d6fc47ea9585fa405d8617ccc0b7704d2c9e8a0apbos // If we're a sender, remove the feedback and stop all encoding threads and 282d6fc47ea9585fa405d8617ccc0b7704d2c9e8a0apbos // processing. This must be done before deleting the channel. 283d6fc47ea9585fa405d8617ccc0b7704d2c9e8a0apbos if (vie_encoder) { 284a50e6f073deecfd9004e6e4946eabd8c34621608stefan@webrtc.org encoder_state_feedback_->RemoveEncoder(vie_encoder); 285a50e6f073deecfd9004e6e4946eabd8c34621608stefan@webrtc.org vie_encoder->StopThreadsAndRemoveSharedMembers(); 286a50e6f073deecfd9004e6e4946eabd8c34621608stefan@webrtc.org } 287a50e6f073deecfd9004e6e4946eabd8c34621608stefan@webrtc.org 288a50e6f073deecfd9004e6e4946eabd8c34621608stefan@webrtc.org unsigned int remote_ssrc = 0; 289a50e6f073deecfd9004e6e4946eabd8c34621608stefan@webrtc.org vie_channel->GetRemoteSSRC(&remote_ssrc); 290d6fc47ea9585fa405d8617ccc0b7704d2c9e8a0apbos channel_map_.erase(channel_id); 291a50e6f073deecfd9004e6e4946eabd8c34621608stefan@webrtc.org remote_bitrate_estimator_->RemoveStream(remote_ssrc); 292a50e6f073deecfd9004e6e4946eabd8c34621608stefan@webrtc.org 293a50e6f073deecfd9004e6e4946eabd8c34621608stefan@webrtc.org delete vie_channel; 294d6fc47ea9585fa405d8617ccc0b7704d2c9e8a0apbos 295a50e6f073deecfd9004e6e4946eabd8c34621608stefan@webrtc.org if (vie_encoder) { 296d6fc47ea9585fa405d8617ccc0b7704d2c9e8a0apbos { 297d6fc47ea9585fa405d8617ccc0b7704d2c9e8a0apbos rtc::CritScope lock(&encoder_map_crit_); 298d6fc47ea9585fa405d8617ccc0b7704d2c9e8a0apbos vie_encoder_map_.erase(vie_encoder_map_.find(channel_id)); 299d6fc47ea9585fa405d8617ccc0b7704d2c9e8a0apbos } 300a50e6f073deecfd9004e6e4946eabd8c34621608stefan@webrtc.org delete vie_encoder; 301a50e6f073deecfd9004e6e4946eabd8c34621608stefan@webrtc.org } 302a50e6f073deecfd9004e6e4946eabd8c34621608stefan@webrtc.org 303a50e6f073deecfd9004e6e4946eabd8c34621608stefan@webrtc.org LOG(LS_VERBOSE) << "Channel deleted " << channel_id; 3049ec883e8bd334acfc246741f7a2cca3e55d7f5b2mflodman@webrtc.org} 305a6db54d4c9a2bfc703bc208eb5cbc19505e9cef3solenberg@webrtc.org 306a50e6f073deecfd9004e6e4946eabd8c34621608stefan@webrtc.orgViEChannel* ChannelGroup::GetChannel(int channel_id) const { 307a50e6f073deecfd9004e6e4946eabd8c34621608stefan@webrtc.org ChannelMap::const_iterator it = channel_map_.find(channel_id); 308a50e6f073deecfd9004e6e4946eabd8c34621608stefan@webrtc.org if (it == channel_map_.end()) { 309a50e6f073deecfd9004e6e4946eabd8c34621608stefan@webrtc.org LOG(LS_ERROR) << "Channel doesn't exist " << channel_id; 310a50e6f073deecfd9004e6e4946eabd8c34621608stefan@webrtc.org return NULL; 311a50e6f073deecfd9004e6e4946eabd8c34621608stefan@webrtc.org } 312a50e6f073deecfd9004e6e4946eabd8c34621608stefan@webrtc.org return it->second; 313a50e6f073deecfd9004e6e4946eabd8c34621608stefan@webrtc.org} 314a50e6f073deecfd9004e6e4946eabd8c34621608stefan@webrtc.org 315a50e6f073deecfd9004e6e4946eabd8c34621608stefan@webrtc.orgViEEncoder* ChannelGroup::GetEncoder(int channel_id) const { 316d6fc47ea9585fa405d8617ccc0b7704d2c9e8a0apbos rtc::CritScope lock(&encoder_map_crit_); 317a50e6f073deecfd9004e6e4946eabd8c34621608stefan@webrtc.org EncoderMap::const_iterator it = vie_encoder_map_.find(channel_id); 318d6fc47ea9585fa405d8617ccc0b7704d2c9e8a0apbos if (it == vie_encoder_map_.end()) 319d6fc47ea9585fa405d8617ccc0b7704d2c9e8a0apbos return nullptr; 320a50e6f073deecfd9004e6e4946eabd8c34621608stefan@webrtc.org return it->second; 321a50e6f073deecfd9004e6e4946eabd8c34621608stefan@webrtc.org} 322a50e6f073deecfd9004e6e4946eabd8c34621608stefan@webrtc.org 323a50e6f073deecfd9004e6e4946eabd8c34621608stefan@webrtc.orgViEChannel* ChannelGroup::PopChannel(int channel_id) { 324a50e6f073deecfd9004e6e4946eabd8c34621608stefan@webrtc.org ChannelMap::iterator c_it = channel_map_.find(channel_id); 325a50e6f073deecfd9004e6e4946eabd8c34621608stefan@webrtc.org DCHECK(c_it != channel_map_.end()); 326a50e6f073deecfd9004e6e4946eabd8c34621608stefan@webrtc.org ViEChannel* channel = c_it->second; 327a50e6f073deecfd9004e6e4946eabd8c34621608stefan@webrtc.org channel_map_.erase(c_it); 328a50e6f073deecfd9004e6e4946eabd8c34621608stefan@webrtc.org 329a50e6f073deecfd9004e6e4946eabd8c34621608stefan@webrtc.org return channel; 330a50e6f073deecfd9004e6e4946eabd8c34621608stefan@webrtc.org} 331a50e6f073deecfd9004e6e4946eabd8c34621608stefan@webrtc.org 332a50e6f073deecfd9004e6e4946eabd8c34621608stefan@webrtc.orgvoid ChannelGroup::SetSyncInterface(VoEVideoSync* sync_interface) { 333d6fc47ea9585fa405d8617ccc0b7704d2c9e8a0apbos for (auto channel : channel_map_) 334a50e6f073deecfd9004e6e4946eabd8c34621608stefan@webrtc.org channel.second->SetVoiceChannel(-1, sync_interface); 335792f1a14e2b62382c5c6080d0b8fdc5c89d27bc6stefan@webrtc.org} 336792f1a14e2b62382c5c6080d0b8fdc5c89d27bc6stefan@webrtc.org 337a50e6f073deecfd9004e6e4946eabd8c34621608stefan@webrtc.orgBitrateController* ChannelGroup::GetBitrateController() const { 338cb89c6f91491e683e47e5505536c154c905d5194bjornv@webrtc.org return bitrate_controller_.get(); 339f72881406fba86adc2d649bb1caee0d5604f9339stefan@webrtc.org} 340f72881406fba86adc2d649bb1caee0d5604f9339stefan@webrtc.org 341a50e6f073deecfd9004e6e4946eabd8c34621608stefan@webrtc.orgRemoteBitrateEstimator* ChannelGroup::GetRemoteBitrateEstimator() const { 3429354cc965c04a0c79ea36622043751596a6fd015stefan@webrtc.org return remote_bitrate_estimator_.get(); 3439354cc965c04a0c79ea36622043751596a6fd015stefan@webrtc.org} 3449354cc965c04a0c79ea36622043751596a6fd015stefan@webrtc.org 345a50e6f073deecfd9004e6e4946eabd8c34621608stefan@webrtc.orgCallStats* ChannelGroup::GetCallStats() const { 3467c894b7cc718773f32d21985ff33a64f9e13946emflodman@webrtc.org return call_stats_.get(); 3477c894b7cc718773f32d21985ff33a64f9e13946emflodman@webrtc.org} 3487c894b7cc718773f32d21985ff33a64f9e13946emflodman@webrtc.org 349a50e6f073deecfd9004e6e4946eabd8c34621608stefan@webrtc.orgEncoderStateFeedback* ChannelGroup::GetEncoderStateFeedback() const { 350aca26292aeb35c91e70dd22d5923bf74ce68fa30mflodman@webrtc.org return encoder_state_feedback_.get(); 351aca26292aeb35c91e70dd22d5923bf74ce68fa30mflodman@webrtc.org} 352aca26292aeb35c91e70dd22d5923bf74ce68fa30mflodman@webrtc.org 353e59041672283a28bde0b043c0c2bc198272f82e1Stefan Holmerint64_t ChannelGroup::GetPacerQueuingDelayMs() const { 354e59041672283a28bde0b043c0c2bc198272f82e1Stefan Holmer return pacer_->QueueInMs(); 355e59041672283a28bde0b043c0c2bc198272f82e1Stefan Holmer} 356e59041672283a28bde0b043c0c2bc198272f82e1Stefan Holmer 35776c53d36bc455fe89ca1f860d5171633198fe907Peter Boströmvoid ChannelGroup::SetChannelRembStatus(bool sender, 358d16e839c6d29831e79312180085b6a19149df43fpbos@webrtc.org bool receiver, 359d16e839c6d29831e79312180085b6a19149df43fpbos@webrtc.org ViEChannel* channel) { 3609ec883e8bd334acfc246741f7a2cca3e55d7f5b2mflodman@webrtc.org // Update the channel state. 361d16e839c6d29831e79312180085b6a19149df43fpbos@webrtc.org channel->EnableRemb(sender || receiver); 3629354cc965c04a0c79ea36622043751596a6fd015stefan@webrtc.org // Update the REMB instance with necessary RTP modules. 3639ec883e8bd334acfc246741f7a2cca3e55d7f5b2mflodman@webrtc.org RtpRtcp* rtp_module = channel->rtp_rtcp(); 3649ec883e8bd334acfc246741f7a2cca3e55d7f5b2mflodman@webrtc.org if (sender) { 3659ec883e8bd334acfc246741f7a2cca3e55d7f5b2mflodman@webrtc.org remb_->AddRembSender(rtp_module); 3669ec883e8bd334acfc246741f7a2cca3e55d7f5b2mflodman@webrtc.org } else { 3679ec883e8bd334acfc246741f7a2cca3e55d7f5b2mflodman@webrtc.org remb_->RemoveRembSender(rtp_module); 3689ec883e8bd334acfc246741f7a2cca3e55d7f5b2mflodman@webrtc.org } 3699ec883e8bd334acfc246741f7a2cca3e55d7f5b2mflodman@webrtc.org if (receiver) { 3709ec883e8bd334acfc246741f7a2cca3e55d7f5b2mflodman@webrtc.org remb_->AddReceiveChannel(rtp_module); 3719ec883e8bd334acfc246741f7a2cca3e55d7f5b2mflodman@webrtc.org } else { 3729ec883e8bd334acfc246741f7a2cca3e55d7f5b2mflodman@webrtc.org remb_->RemoveReceiveChannel(rtp_module); 3739ec883e8bd334acfc246741f7a2cca3e55d7f5b2mflodman@webrtc.org } 3749ec883e8bd334acfc246741f7a2cca3e55d7f5b2mflodman@webrtc.org} 375792f1a14e2b62382c5c6080d0b8fdc5c89d27bc6stefan@webrtc.org 376792f1a14e2b62382c5c6080d0b8fdc5c89d27bc6stefan@webrtc.orgvoid ChannelGroup::OnNetworkChanged(uint32_t target_bitrate_bps, 377792f1a14e2b62382c5c6080d0b8fdc5c89d27bc6stefan@webrtc.org uint8_t fraction_loss, 378792f1a14e2b62382c5c6080d0b8fdc5c89d27bc6stefan@webrtc.org int64_t rtt) { 379792f1a14e2b62382c5c6080d0b8fdc5c89d27bc6stefan@webrtc.org bitrate_allocator_->OnNetworkChanged(target_bitrate_bps, fraction_loss, rtt); 380e59041672283a28bde0b043c0c2bc198272f82e1Stefan Holmer int pad_up_to_bitrate_bps = 0; 381e59041672283a28bde0b043c0c2bc198272f82e1Stefan Holmer { 382d6fc47ea9585fa405d8617ccc0b7704d2c9e8a0apbos rtc::CritScope lock(&encoder_map_crit_); 383d6fc47ea9585fa405d8617ccc0b7704d2c9e8a0apbos for (const auto& encoder : vie_encoder_map_) 384a4a8d4ad27bd0bd7a6cc5df697951d4531ddb4eestefan pad_up_to_bitrate_bps += encoder.second->GetPaddingNeededBps(); 385e59041672283a28bde0b043c0c2bc198272f82e1Stefan Holmer } 386e59041672283a28bde0b043c0c2bc198272f82e1Stefan Holmer pacer_->UpdateBitrate( 387e59041672283a28bde0b043c0c2bc198272f82e1Stefan Holmer target_bitrate_bps / 1000, 388e59041672283a28bde0b043c0c2bc198272f82e1Stefan Holmer PacedSender::kDefaultPaceMultiplier * target_bitrate_bps / 1000, 389e59041672283a28bde0b043c0c2bc198272f82e1Stefan Holmer pad_up_to_bitrate_bps / 1000); 390792f1a14e2b62382c5c6080d0b8fdc5c89d27bc6stefan@webrtc.org} 3919ec883e8bd334acfc246741f7a2cca3e55d7f5b2mflodman@webrtc.org} // namespace webrtc 392