Move FecController to RtpVideoSender.
This also moves the packet feedback tracking to RtpVideoSender. Bug: webrtc:9517 Change-Id: Ifb1ff85051730108a0b0d1dd30f6f8595ad2af6e Reviewed-on: https://webrtc-review.googlesource.com/c/95920 Reviewed-by: Sebastian Jansson <srte@webrtc.org> Reviewed-by: Niels Moller <nisse@webrtc.org> Commit-Queue: Stefan Holmer <stefan@webrtc.org> Cr-Commit-Position: refs/heads/master@{#25019}
This commit is contained in:
parent
8e87852cbe
commit
64be7fa7d8
@ -138,7 +138,7 @@ class NoBandwidthDropAfterDtx : public AudioBweTest {
|
|||||||
void PerformTest() override {
|
void PerformTest() override {
|
||||||
stats_poller_.PostDelayedTask(
|
stats_poller_.PostDelayedTask(
|
||||||
std::unique_ptr<rtc::QueuedTask>(new StatsPollTask(sender_call_)), 100);
|
std::unique_ptr<rtc::QueuedTask>(new StatsPollTask(sender_call_)), 100);
|
||||||
sender_call_->OnTransportOverheadChanged(webrtc::MediaType::AUDIO, 0);
|
sender_call_->OnAudioTransportOverheadChanged(0);
|
||||||
AudioBweTest::PerformTest();
|
AudioBweTest::PerformTest();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -65,6 +65,7 @@ rtc_source_set("rtp_interfaces") {
|
|||||||
]
|
]
|
||||||
deps = [
|
deps = [
|
||||||
"../api:array_view",
|
"../api:array_view",
|
||||||
|
"../api:fec_controller_api",
|
||||||
"../api:libjingle_peerconnection_api",
|
"../api:libjingle_peerconnection_api",
|
||||||
"../api/transport:bitrate_settings",
|
"../api/transport:bitrate_settings",
|
||||||
"../logging:rtc_event_log_api",
|
"../logging:rtc_event_log_api",
|
||||||
@ -117,6 +118,7 @@ rtc_source_set("rtp_sender") {
|
|||||||
":bitrate_configurator",
|
":bitrate_configurator",
|
||||||
":rtp_interfaces",
|
":rtp_interfaces",
|
||||||
"..:webrtc_common",
|
"..:webrtc_common",
|
||||||
|
"../api:fec_controller_api",
|
||||||
"../api:transport_api",
|
"../api:transport_api",
|
||||||
"../api/transport:network_control",
|
"../api/transport:network_control",
|
||||||
"../api/video_codecs:video_codecs_api",
|
"../api/video_codecs:video_codecs_api",
|
||||||
@ -341,6 +343,7 @@ if (rtc_include_tests) {
|
|||||||
"../modules/rtp_rtcp:rtp_rtcp_format",
|
"../modules/rtp_rtcp:rtp_rtcp_format",
|
||||||
"../modules/utility:mock_process_thread",
|
"../modules/utility:mock_process_thread",
|
||||||
"../modules/video_coding:video_codec_interface",
|
"../modules/video_coding:video_codec_interface",
|
||||||
|
"../modules/video_coding:video_coding",
|
||||||
"../rtc_base:checks",
|
"../rtc_base:checks",
|
||||||
"../rtc_base:rate_limiter",
|
"../rtc_base:rate_limiter",
|
||||||
"../rtc_base:rtc_base_approved",
|
"../rtc_base:rtc_base_approved",
|
||||||
|
|||||||
21
call/call.cc
21
call/call.cc
@ -221,7 +221,7 @@ class Call final : public webrtc::Call,
|
|||||||
|
|
||||||
void SignalChannelNetworkState(MediaType media, NetworkState state) override;
|
void SignalChannelNetworkState(MediaType media, NetworkState state) override;
|
||||||
|
|
||||||
void OnTransportOverheadChanged(MediaType media,
|
void OnAudioTransportOverheadChanged(
|
||||||
int transport_overhead_per_packet) override;
|
int transport_overhead_per_packet) override;
|
||||||
|
|
||||||
void OnSentPacket(const rtc::SentPacket& sent_packet) override;
|
void OnSentPacket(const rtc::SentPacket& sent_packet) override;
|
||||||
@ -997,28 +997,11 @@ void Call::SignalChannelNetworkState(MediaType media, NetworkState state) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Call::OnTransportOverheadChanged(MediaType media,
|
void Call::OnAudioTransportOverheadChanged(int transport_overhead_per_packet) {
|
||||||
int transport_overhead_per_packet) {
|
|
||||||
switch (media) {
|
|
||||||
case MediaType::AUDIO: {
|
|
||||||
ReadLockScoped read_lock(*send_crit_);
|
ReadLockScoped read_lock(*send_crit_);
|
||||||
for (auto& kv : audio_send_ssrcs_) {
|
for (auto& kv : audio_send_ssrcs_) {
|
||||||
kv.second->SetTransportOverhead(transport_overhead_per_packet);
|
kv.second->SetTransportOverhead(transport_overhead_per_packet);
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
}
|
|
||||||
case MediaType::VIDEO: {
|
|
||||||
ReadLockScoped read_lock(*send_crit_);
|
|
||||||
for (auto& kv : video_send_ssrcs_) {
|
|
||||||
kv.second->SetTransportOverhead(transport_overhead_per_packet);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case MediaType::ANY:
|
|
||||||
case MediaType::DATA:
|
|
||||||
RTC_NOTREACHED();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Call::UpdateAggregateNetworkState() {
|
void Call::UpdateAggregateNetworkState() {
|
||||||
|
|||||||
@ -113,8 +113,7 @@ class Call {
|
|||||||
virtual void SignalChannelNetworkState(MediaType media,
|
virtual void SignalChannelNetworkState(MediaType media,
|
||||||
NetworkState state) = 0;
|
NetworkState state) = 0;
|
||||||
|
|
||||||
virtual void OnTransportOverheadChanged(
|
virtual void OnAudioTransportOverheadChanged(
|
||||||
MediaType media,
|
|
||||||
int transport_overhead_per_packet) = 0;
|
int transport_overhead_per_packet) = 0;
|
||||||
|
|
||||||
virtual void OnSentPacket(const rtc::SentPacket& sent_packet) = 0;
|
virtual void OnSentPacket(const rtc::SentPacket& sent_packet) = 0;
|
||||||
|
|||||||
@ -157,10 +157,9 @@ void DegradedCall::SignalChannelNetworkState(MediaType media,
|
|||||||
call_->SignalChannelNetworkState(media, state);
|
call_->SignalChannelNetworkState(media, state);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DegradedCall::OnTransportOverheadChanged(
|
void DegradedCall::OnAudioTransportOverheadChanged(
|
||||||
MediaType media,
|
|
||||||
int transport_overhead_per_packet) {
|
int transport_overhead_per_packet) {
|
||||||
call_->OnTransportOverheadChanged(media, transport_overhead_per_packet);
|
call_->OnAudioTransportOverheadChanged(transport_overhead_per_packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DegradedCall::OnSentPacket(const rtc::SentPacket& sent_packet) {
|
void DegradedCall::OnSentPacket(const rtc::SentPacket& sent_packet) {
|
||||||
|
|||||||
@ -70,10 +70,8 @@ class DegradedCall : public Call, private Transport, private PacketReceiver {
|
|||||||
bitrate_allocation_strategy) override;
|
bitrate_allocation_strategy) override;
|
||||||
|
|
||||||
void SignalChannelNetworkState(MediaType media, NetworkState state) override;
|
void SignalChannelNetworkState(MediaType media, NetworkState state) override;
|
||||||
|
void OnAudioTransportOverheadChanged(
|
||||||
void OnTransportOverheadChanged(MediaType media,
|
|
||||||
int transport_overhead_per_packet) override;
|
int transport_overhead_per_packet) override;
|
||||||
|
|
||||||
void OnSentPacket(const rtc::SentPacket& sent_packet) override;
|
void OnSentPacket(const rtc::SentPacket& sent_packet) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|||||||
@ -22,6 +22,7 @@
|
|||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
namespace {
|
namespace {
|
||||||
static const int64_t kRetransmitWindowSizeMs = 500;
|
static const int64_t kRetransmitWindowSizeMs = 500;
|
||||||
|
static const size_t kMaxOverheadBytes = 500;
|
||||||
const char kTaskQueueExperiment[] = "WebRTC-TaskQueueCongestionControl";
|
const char kTaskQueueExperiment[] = "WebRTC-TaskQueueCongestionControl";
|
||||||
using TaskQueueController = webrtc::webrtc_cc::SendSideCongestionController;
|
using TaskQueueController = webrtc::webrtc_cc::SendSideCongestionController;
|
||||||
|
|
||||||
@ -92,13 +93,15 @@ RtpVideoSenderInterface* RtpTransportControllerSend::CreateRtpVideoSender(
|
|||||||
const RtcpConfig& rtcp_config,
|
const RtcpConfig& rtcp_config,
|
||||||
Transport* send_transport,
|
Transport* send_transport,
|
||||||
const RtpSenderObservers& observers,
|
const RtpSenderObservers& observers,
|
||||||
RtcEventLog* event_log) {
|
RtcEventLog* event_log,
|
||||||
|
std::unique_ptr<FecController> fec_controller) {
|
||||||
video_rtp_senders_.push_back(absl::make_unique<RtpVideoSender>(
|
video_rtp_senders_.push_back(absl::make_unique<RtpVideoSender>(
|
||||||
ssrcs, suspended_ssrcs, states, rtp_config, rtcp_config, send_transport,
|
ssrcs, suspended_ssrcs, states, rtp_config, rtcp_config, send_transport,
|
||||||
observers,
|
observers,
|
||||||
// TODO(holmer): Remove this circular dependency by injecting
|
// TODO(holmer): Remove this circular dependency by injecting
|
||||||
// the parts of RtpTransportControllerSendInterface that are really used.
|
// the parts of RtpTransportControllerSendInterface that are really used.
|
||||||
this, event_log, &retransmission_rate_limiter_));
|
this, event_log, &retransmission_rate_limiter_,
|
||||||
|
std::move(fec_controller)));
|
||||||
return video_rtp_senders_.back().get();
|
return video_rtp_senders_.back().get();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -315,4 +318,19 @@ void RtpTransportControllerSend::SetAllocatedBitrateWithoutFeedback(
|
|||||||
send_side_cc_->SetAllocatedBitrateWithoutFeedback(bitrate_bps);
|
send_side_cc_->SetAllocatedBitrateWithoutFeedback(bitrate_bps);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RtpTransportControllerSend::OnTransportOverheadChanged(
|
||||||
|
size_t transport_overhead_bytes_per_packet) {
|
||||||
|
if (transport_overhead_bytes_per_packet >= kMaxOverheadBytes) {
|
||||||
|
RTC_LOG(LS_ERROR) << "Transport overhead exceeds " << kMaxOverheadBytes;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO(holmer): Call AudioRtpSenders when they have been moved to
|
||||||
|
// RtpTransportControllerSend.
|
||||||
|
for (auto& rtp_video_sender : video_rtp_senders_) {
|
||||||
|
rtp_video_sender->OnTransportOverheadChanged(
|
||||||
|
transport_overhead_bytes_per_packet);
|
||||||
|
}
|
||||||
|
}
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
|
|||||||
@ -55,7 +55,8 @@ class RtpTransportControllerSend final
|
|||||||
const RtcpConfig& rtcp_config,
|
const RtcpConfig& rtcp_config,
|
||||||
Transport* send_transport,
|
Transport* send_transport,
|
||||||
const RtpSenderObservers& observers,
|
const RtpSenderObservers& observers,
|
||||||
RtcEventLog* event_log) override;
|
RtcEventLog* event_log,
|
||||||
|
std::unique_ptr<FecController> fec_controller) override;
|
||||||
void DestroyRtpVideoSender(
|
void DestroyRtpVideoSender(
|
||||||
RtpVideoSenderInterface* rtp_video_sender) override;
|
RtpVideoSenderInterface* rtp_video_sender) override;
|
||||||
|
|
||||||
@ -102,6 +103,9 @@ class RtpTransportControllerSend final
|
|||||||
|
|
||||||
void SetAllocatedBitrateWithoutFeedback(uint32_t bitrate_bps) override;
|
void SetAllocatedBitrateWithoutFeedback(uint32_t bitrate_bps) override;
|
||||||
|
|
||||||
|
void OnTransportOverheadChanged(
|
||||||
|
size_t transport_overhead_per_packet) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const Clock* const clock_;
|
const Clock* const clock_;
|
||||||
PacketRouter packet_router_;
|
PacketRouter packet_router_;
|
||||||
|
|||||||
@ -14,11 +14,13 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "absl/types/optional.h"
|
#include "absl/types/optional.h"
|
||||||
#include "api/bitrate_constraints.h"
|
#include "api/bitrate_constraints.h"
|
||||||
|
#include "api/fec_controller.h"
|
||||||
#include "api/transport/bitrate_settings.h"
|
#include "api/transport/bitrate_settings.h"
|
||||||
#include "call/rtp_config.h"
|
#include "call/rtp_config.h"
|
||||||
#include "logging/rtc_event_log/rtc_event_log.h"
|
#include "logging/rtc_event_log/rtc_event_log.h"
|
||||||
@ -58,7 +60,6 @@ struct RtpSenderObservers {
|
|||||||
RtcpPacketTypeCounterObserver* rtcp_type_observer;
|
RtcpPacketTypeCounterObserver* rtcp_type_observer;
|
||||||
SendSideDelayObserver* send_delay_observer;
|
SendSideDelayObserver* send_delay_observer;
|
||||||
SendPacketObserver* send_packet_observer;
|
SendPacketObserver* send_packet_observer;
|
||||||
OverheadObserver* overhead_observer;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// An RtpTransportController should own everything related to the RTP
|
// An RtpTransportController should own everything related to the RTP
|
||||||
@ -99,7 +100,8 @@ class RtpTransportControllerSendInterface {
|
|||||||
const RtcpConfig& rtcp_config,
|
const RtcpConfig& rtcp_config,
|
||||||
Transport* send_transport,
|
Transport* send_transport,
|
||||||
const RtpSenderObservers& observers,
|
const RtpSenderObservers& observers,
|
||||||
RtcEventLog* event_log) = 0;
|
RtcEventLog* event_log,
|
||||||
|
std::unique_ptr<FecController> fec_controller) = 0;
|
||||||
virtual void DestroyRtpVideoSender(
|
virtual void DestroyRtpVideoSender(
|
||||||
RtpVideoSenderInterface* rtp_video_sender) = 0;
|
RtpVideoSenderInterface* rtp_video_sender) = 0;
|
||||||
|
|
||||||
@ -149,6 +151,9 @@ class RtpTransportControllerSendInterface {
|
|||||||
const BitrateSettings& preferences) = 0;
|
const BitrateSettings& preferences) = 0;
|
||||||
|
|
||||||
virtual void SetAllocatedBitrateWithoutFeedback(uint32_t bitrate_bps) = 0;
|
virtual void SetAllocatedBitrateWithoutFeedback(uint32_t bitrate_bps) = 0;
|
||||||
|
|
||||||
|
virtual void OnTransportOverheadChanged(
|
||||||
|
size_t transport_overhead_per_packet) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
|
|||||||
@ -31,6 +31,12 @@ namespace webrtc {
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
static const int kMinSendSidePacketHistorySize = 600;
|
static const int kMinSendSidePacketHistorySize = 600;
|
||||||
|
// Assume an average video stream has around 3 packets per frame (1 mbps / 30
|
||||||
|
// fps / 1400B) A sequence number set with size 5500 will be able to store
|
||||||
|
// packet sequence number for at least last 60 seconds.
|
||||||
|
static const int kSendSideSeqNumSetMaxSize = 5500;
|
||||||
|
// We don't do MTU discovery, so assume that we have the standard ethernet MTU.
|
||||||
|
static const size_t kPathMTU = 1500;
|
||||||
|
|
||||||
std::vector<std::unique_ptr<RtpRtcp>> CreateRtpRtcpModules(
|
std::vector<std::unique_ptr<RtpRtcp>> CreateRtpRtcpModules(
|
||||||
const std::vector<uint32_t>& ssrcs,
|
const std::vector<uint32_t>& ssrcs,
|
||||||
@ -149,6 +155,21 @@ std::unique_ptr<FlexfecSender> MaybeCreateFlexfecSender(
|
|||||||
rtp.flexfec.protected_media_ssrcs[0], rtp.mid, rtp.extensions,
|
rtp.flexfec.protected_media_ssrcs[0], rtp.mid, rtp.extensions,
|
||||||
RTPSender::FecExtensionSizes(), rtp_state, Clock::GetRealTimeClock());
|
RTPSender::FecExtensionSizes(), rtp_state, Clock::GetRealTimeClock());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t CalculateOverheadRateBps(int packets_per_second,
|
||||||
|
size_t overhead_bytes_per_packet,
|
||||||
|
uint32_t max_overhead_bps) {
|
||||||
|
uint32_t overhead_bps =
|
||||||
|
static_cast<uint32_t>(8 * overhead_bytes_per_packet * packets_per_second);
|
||||||
|
return std::min(overhead_bps, max_overhead_bps);
|
||||||
|
}
|
||||||
|
|
||||||
|
int CalculatePacketRate(uint32_t bitrate_bps, size_t packet_size_bytes) {
|
||||||
|
size_t packet_size_bits = 8 * packet_size_bytes;
|
||||||
|
// Ceil for int value of bitrate_bps / packet_size_bits.
|
||||||
|
return static_cast<int>((bitrate_bps + packet_size_bits - 1) /
|
||||||
|
packet_size_bits);
|
||||||
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
RtpVideoSender::RtpVideoSender(
|
RtpVideoSender::RtpVideoSender(
|
||||||
@ -161,11 +182,15 @@ RtpVideoSender::RtpVideoSender(
|
|||||||
const RtpSenderObservers& observers,
|
const RtpSenderObservers& observers,
|
||||||
RtpTransportControllerSendInterface* transport,
|
RtpTransportControllerSendInterface* transport,
|
||||||
RtcEventLog* event_log,
|
RtcEventLog* event_log,
|
||||||
RateLimiter* retransmission_limiter)
|
RateLimiter* retransmission_limiter,
|
||||||
: active_(false),
|
std::unique_ptr<FecController> fec_controller)
|
||||||
|
: send_side_bwe_with_overhead_(
|
||||||
|
webrtc::field_trial::IsEnabled("WebRTC-SendSideBwe-WithOverhead")),
|
||||||
|
active_(false),
|
||||||
module_process_thread_(nullptr),
|
module_process_thread_(nullptr),
|
||||||
suspended_ssrcs_(std::move(suspended_ssrcs)),
|
suspended_ssrcs_(std::move(suspended_ssrcs)),
|
||||||
flexfec_sender_(MaybeCreateFlexfecSender(rtp_config, suspended_ssrcs_)),
|
flexfec_sender_(MaybeCreateFlexfecSender(rtp_config, suspended_ssrcs_)),
|
||||||
|
fec_controller_(std::move(fec_controller)),
|
||||||
rtp_modules_(
|
rtp_modules_(
|
||||||
CreateRtpRtcpModules(ssrcs,
|
CreateRtpRtcpModules(ssrcs,
|
||||||
rtp_config.flexfec.protected_media_ssrcs,
|
rtp_config.flexfec.protected_media_ssrcs,
|
||||||
@ -183,10 +208,13 @@ RtpVideoSender::RtpVideoSender(
|
|||||||
observers.send_packet_observer,
|
observers.send_packet_observer,
|
||||||
event_log,
|
event_log,
|
||||||
retransmission_limiter,
|
retransmission_limiter,
|
||||||
observers.overhead_observer,
|
this,
|
||||||
transport->keepalive_config())),
|
transport->keepalive_config())),
|
||||||
rtp_config_(rtp_config),
|
rtp_config_(rtp_config),
|
||||||
transport_(transport) {
|
transport_(transport),
|
||||||
|
transport_overhead_bytes_per_packet_(0),
|
||||||
|
overhead_bytes_per_packet_(0),
|
||||||
|
encoder_target_rate_bps_(0) {
|
||||||
RTC_DCHECK_EQ(ssrcs.size(), rtp_modules_.size());
|
RTC_DCHECK_EQ(ssrcs.size(), rtp_modules_.size());
|
||||||
module_process_thread_checker_.DetachFromThread();
|
module_process_thread_checker_.DetachFromThread();
|
||||||
// SSRCs are assumed to be sorted in the same order as |rtp_modules|.
|
// SSRCs are assumed to be sorted in the same order as |rtp_modules|.
|
||||||
@ -246,12 +274,24 @@ RtpVideoSender::RtpVideoSender(
|
|||||||
rtp_rtcp->RegisterVideoSendPayload(rtp_config.payload_type,
|
rtp_rtcp->RegisterVideoSendPayload(rtp_config.payload_type,
|
||||||
rtp_config.payload_name.c_str());
|
rtp_config.payload_name.c_str());
|
||||||
}
|
}
|
||||||
|
// Currently, both ULPFEC and FlexFEC use the same FEC rate calculation logic,
|
||||||
|
// so enable that logic if either of those FEC schemes are enabled.
|
||||||
|
fec_controller_->SetProtectionMethod(FecEnabled(), NackEnabled());
|
||||||
|
|
||||||
|
fec_controller_->SetProtectionCallback(this);
|
||||||
|
// Signal congestion controller this object is ready for OnPacket* callbacks.
|
||||||
|
if (fec_controller_->UseLossVectorMask()) {
|
||||||
|
transport_->RegisterPacketFeedbackObserver(this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
RtpVideoSender::~RtpVideoSender() {
|
RtpVideoSender::~RtpVideoSender() {
|
||||||
for (auto& rtp_rtcp : rtp_modules_) {
|
for (auto& rtp_rtcp : rtp_modules_) {
|
||||||
transport_->packet_router()->RemoveSendRtpModule(rtp_rtcp.get());
|
transport_->packet_router()->RemoveSendRtpModule(rtp_rtcp.get());
|
||||||
}
|
}
|
||||||
|
if (fec_controller_->UseLossVectorMask()) {
|
||||||
|
transport_->DeRegisterPacketFeedbackObserver(this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RtpVideoSender::RegisterProcessThread(
|
void RtpVideoSender::RegisterProcessThread(
|
||||||
@ -302,6 +342,8 @@ EncodedImageCallback::Result RtpVideoSender::OnEncodedImage(
|
|||||||
const EncodedImage& encoded_image,
|
const EncodedImage& encoded_image,
|
||||||
const CodecSpecificInfo* codec_specific_info,
|
const CodecSpecificInfo* codec_specific_info,
|
||||||
const RTPFragmentationHeader* fragmentation) {
|
const RTPFragmentationHeader* fragmentation) {
|
||||||
|
fec_controller_->UpdateWithEncodedData(encoded_image._length,
|
||||||
|
encoded_image._frameType);
|
||||||
rtc::CritScope lock(&crit_);
|
rtc::CritScope lock(&crit_);
|
||||||
RTC_DCHECK(!rtp_modules_.empty());
|
RTC_DCHECK(!rtp_modules_.empty());
|
||||||
if (!active_)
|
if (!active_)
|
||||||
@ -440,34 +482,6 @@ void RtpVideoSender::DeliverRtcp(const uint8_t* packet, size_t length) {
|
|||||||
rtp_rtcp->IncomingRtcpPacket(packet, length);
|
rtp_rtcp->IncomingRtcpPacket(packet, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RtpVideoSender::ProtectionRequest(const FecProtectionParams* delta_params,
|
|
||||||
const FecProtectionParams* key_params,
|
|
||||||
uint32_t* sent_video_rate_bps,
|
|
||||||
uint32_t* sent_nack_rate_bps,
|
|
||||||
uint32_t* sent_fec_rate_bps) {
|
|
||||||
*sent_video_rate_bps = 0;
|
|
||||||
*sent_nack_rate_bps = 0;
|
|
||||||
*sent_fec_rate_bps = 0;
|
|
||||||
for (auto& rtp_rtcp : rtp_modules_) {
|
|
||||||
uint32_t not_used = 0;
|
|
||||||
uint32_t module_video_rate = 0;
|
|
||||||
uint32_t module_fec_rate = 0;
|
|
||||||
uint32_t module_nack_rate = 0;
|
|
||||||
rtp_rtcp->SetFecParameters(*delta_params, *key_params);
|
|
||||||
rtp_rtcp->BitrateSent(¬_used, &module_video_rate, &module_fec_rate,
|
|
||||||
&module_nack_rate);
|
|
||||||
*sent_video_rate_bps += module_video_rate;
|
|
||||||
*sent_nack_rate_bps += module_nack_rate;
|
|
||||||
*sent_fec_rate_bps += module_fec_rate;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void RtpVideoSender::SetMaxRtpPacketSize(size_t max_rtp_packet_size) {
|
|
||||||
for (auto& rtp_rtcp : rtp_modules_) {
|
|
||||||
rtp_rtcp->SetMaxRtpPacketSize(max_rtp_packet_size);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void RtpVideoSender::ConfigureSsrcs(const RtpConfig& rtp_config) {
|
void RtpVideoSender::ConfigureSsrcs(const RtpConfig& rtp_config) {
|
||||||
// Configure regular SSRCs.
|
// Configure regular SSRCs.
|
||||||
for (size_t i = 0; i < rtp_config.ssrcs.size(); ++i) {
|
for (size_t i = 0; i < rtp_config.ssrcs.size(); ++i) {
|
||||||
@ -551,4 +565,126 @@ std::map<uint32_t, RtpPayloadState> RtpVideoSender::GetRtpPayloadStates()
|
|||||||
}
|
}
|
||||||
return payload_states;
|
return payload_states;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RtpVideoSender::OnTransportOverheadChanged(
|
||||||
|
size_t transport_overhead_bytes_per_packet) {
|
||||||
|
rtc::CritScope lock(&crit_);
|
||||||
|
transport_overhead_bytes_per_packet_ = transport_overhead_bytes_per_packet;
|
||||||
|
|
||||||
|
size_t max_rtp_packet_size =
|
||||||
|
std::min(rtp_config_.max_packet_size,
|
||||||
|
kPathMTU - transport_overhead_bytes_per_packet_);
|
||||||
|
for (auto& rtp_rtcp : rtp_modules_) {
|
||||||
|
rtp_rtcp->SetMaxRtpPacketSize(max_rtp_packet_size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RtpVideoSender::OnOverheadChanged(size_t overhead_bytes_per_packet) {
|
||||||
|
rtc::CritScope lock(&crit_);
|
||||||
|
overhead_bytes_per_packet_ = overhead_bytes_per_packet;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RtpVideoSender::OnBitrateUpdated(uint32_t bitrate_bps,
|
||||||
|
uint8_t fraction_loss,
|
||||||
|
int64_t rtt,
|
||||||
|
int framerate) {
|
||||||
|
// Substract overhead from bitrate.
|
||||||
|
rtc::CritScope lock(&crit_);
|
||||||
|
uint32_t payload_bitrate_bps = bitrate_bps;
|
||||||
|
if (send_side_bwe_with_overhead_) {
|
||||||
|
payload_bitrate_bps -= CalculateOverheadRateBps(
|
||||||
|
CalculatePacketRate(
|
||||||
|
bitrate_bps,
|
||||||
|
rtp_config_.max_packet_size + transport_overhead_bytes_per_packet_),
|
||||||
|
overhead_bytes_per_packet_ + transport_overhead_bytes_per_packet_,
|
||||||
|
bitrate_bps);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the encoder target rate. It is the estimated network rate -
|
||||||
|
// protection overhead.
|
||||||
|
encoder_target_rate_bps_ = fec_controller_->UpdateFecRates(
|
||||||
|
payload_bitrate_bps, framerate, fraction_loss, loss_mask_vector_, rtt);
|
||||||
|
loss_mask_vector_.clear();
|
||||||
|
|
||||||
|
uint32_t encoder_overhead_rate_bps =
|
||||||
|
send_side_bwe_with_overhead_
|
||||||
|
? CalculateOverheadRateBps(
|
||||||
|
CalculatePacketRate(encoder_target_rate_bps_,
|
||||||
|
rtp_config_.max_packet_size +
|
||||||
|
transport_overhead_bytes_per_packet_ -
|
||||||
|
overhead_bytes_per_packet_),
|
||||||
|
overhead_bytes_per_packet_ +
|
||||||
|
transport_overhead_bytes_per_packet_,
|
||||||
|
bitrate_bps - encoder_target_rate_bps_)
|
||||||
|
: 0;
|
||||||
|
|
||||||
|
// When the field trial "WebRTC-SendSideBwe-WithOverhead" is enabled
|
||||||
|
// protection_bitrate includes overhead.
|
||||||
|
protection_bitrate_bps_ =
|
||||||
|
bitrate_bps - (encoder_target_rate_bps_ + encoder_overhead_rate_bps);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t RtpVideoSender::GetPayloadBitrateBps() const {
|
||||||
|
return encoder_target_rate_bps_;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t RtpVideoSender::GetProtectionBitrateBps() const {
|
||||||
|
return protection_bitrate_bps_;
|
||||||
|
}
|
||||||
|
|
||||||
|
int RtpVideoSender::ProtectionRequest(const FecProtectionParams* delta_params,
|
||||||
|
const FecProtectionParams* key_params,
|
||||||
|
uint32_t* sent_video_rate_bps,
|
||||||
|
uint32_t* sent_nack_rate_bps,
|
||||||
|
uint32_t* sent_fec_rate_bps) {
|
||||||
|
*sent_video_rate_bps = 0;
|
||||||
|
*sent_nack_rate_bps = 0;
|
||||||
|
*sent_fec_rate_bps = 0;
|
||||||
|
for (auto& rtp_rtcp : rtp_modules_) {
|
||||||
|
uint32_t not_used = 0;
|
||||||
|
uint32_t module_video_rate = 0;
|
||||||
|
uint32_t module_fec_rate = 0;
|
||||||
|
uint32_t module_nack_rate = 0;
|
||||||
|
rtp_rtcp->SetFecParameters(*delta_params, *key_params);
|
||||||
|
rtp_rtcp->BitrateSent(¬_used, &module_video_rate, &module_fec_rate,
|
||||||
|
&module_nack_rate);
|
||||||
|
*sent_video_rate_bps += module_video_rate;
|
||||||
|
*sent_nack_rate_bps += module_nack_rate;
|
||||||
|
*sent_fec_rate_bps += module_fec_rate;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RtpVideoSender::OnPacketAdded(uint32_t ssrc, uint16_t seq_num) {
|
||||||
|
const auto ssrcs = rtp_config_.ssrcs;
|
||||||
|
if (std::find(ssrcs.begin(), ssrcs.end(), ssrc) != ssrcs.end()) {
|
||||||
|
feedback_packet_seq_num_set_.insert(seq_num);
|
||||||
|
if (feedback_packet_seq_num_set_.size() > kSendSideSeqNumSetMaxSize) {
|
||||||
|
RTC_LOG(LS_WARNING) << "Feedback packet sequence number set exceed it's "
|
||||||
|
"max size', will get reset.";
|
||||||
|
feedback_packet_seq_num_set_.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RtpVideoSender::OnPacketFeedbackVector(
|
||||||
|
const std::vector<PacketFeedback>& packet_feedback_vector) {
|
||||||
|
rtc::CritScope lock(&crit_);
|
||||||
|
// Lost feedbacks are not considered to be lost packets.
|
||||||
|
for (const PacketFeedback& packet : packet_feedback_vector) {
|
||||||
|
auto it = feedback_packet_seq_num_set_.find(packet.sequence_number);
|
||||||
|
if (it != feedback_packet_seq_num_set_.end()) {
|
||||||
|
const bool lost = packet.arrival_time_ms == PacketFeedback::kNotReceived;
|
||||||
|
loss_mask_vector_.push_back(lost);
|
||||||
|
feedback_packet_seq_num_set_.erase(it);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RtpVideoSender::SetEncodingData(size_t width,
|
||||||
|
size_t height,
|
||||||
|
size_t num_temporal_layers) {
|
||||||
|
fec_controller_->SetEncodingData(width, height, num_temporal_layers,
|
||||||
|
rtp_config_.max_packet_size);
|
||||||
|
}
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
|
|||||||
@ -13,9 +13,11 @@
|
|||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <unordered_set>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "api/call/transport.h"
|
#include "api/call/transport.h"
|
||||||
|
#include "api/fec_controller.h"
|
||||||
#include "api/video_codecs/video_encoder.h"
|
#include "api/video_codecs/video_encoder.h"
|
||||||
#include "call/rtp_config.h"
|
#include "call/rtp_config.h"
|
||||||
#include "call/rtp_payload_params.h"
|
#include "call/rtp_payload_params.h"
|
||||||
@ -40,7 +42,10 @@ class RtpTransportControllerSendInterface;
|
|||||||
|
|
||||||
// RtpVideoSender routes outgoing data to the correct sending RTP module, based
|
// RtpVideoSender routes outgoing data to the correct sending RTP module, based
|
||||||
// on the simulcast layer in RTPVideoHeader.
|
// on the simulcast layer in RTPVideoHeader.
|
||||||
class RtpVideoSender : public RtpVideoSenderInterface {
|
class RtpVideoSender : public RtpVideoSenderInterface,
|
||||||
|
public OverheadObserver,
|
||||||
|
public VCMProtectionCallback,
|
||||||
|
public PacketFeedbackObserver {
|
||||||
public:
|
public:
|
||||||
// Rtp modules are assumed to be sorted in simulcast index order.
|
// Rtp modules are assumed to be sorted in simulcast index order.
|
||||||
RtpVideoSender(
|
RtpVideoSender(
|
||||||
@ -53,7 +58,8 @@ class RtpVideoSender : public RtpVideoSenderInterface {
|
|||||||
const RtpSenderObservers& observers,
|
const RtpSenderObservers& observers,
|
||||||
RtpTransportControllerSendInterface* transport,
|
RtpTransportControllerSendInterface* transport,
|
||||||
RtcEventLog* event_log,
|
RtcEventLog* event_log,
|
||||||
RateLimiter* retransmission_limiter); // move inside RtpTransport
|
RateLimiter* retransmission_limiter, // move inside RtpTransport
|
||||||
|
std::unique_ptr<FecController> fec_controller);
|
||||||
~RtpVideoSender() override;
|
~RtpVideoSender() override;
|
||||||
|
|
||||||
// RegisterProcessThread register |module_process_thread| with those objects
|
// RegisterProcessThread register |module_process_thread| with those objects
|
||||||
@ -76,20 +82,15 @@ class RtpVideoSender : public RtpVideoSenderInterface {
|
|||||||
std::map<uint32_t, RtpState> GetRtpStates() const override;
|
std::map<uint32_t, RtpState> GetRtpStates() const override;
|
||||||
std::map<uint32_t, RtpPayloadState> GetRtpPayloadStates() const override;
|
std::map<uint32_t, RtpPayloadState> GetRtpPayloadStates() const override;
|
||||||
|
|
||||||
bool FecEnabled() const override;
|
|
||||||
|
|
||||||
bool NackEnabled() const override;
|
|
||||||
|
|
||||||
void DeliverRtcp(const uint8_t* packet, size_t length) override;
|
void DeliverRtcp(const uint8_t* packet, size_t length) override;
|
||||||
|
|
||||||
void ProtectionRequest(const FecProtectionParams* delta_params,
|
// Implements webrtc::VCMProtectionCallback.
|
||||||
|
int ProtectionRequest(const FecProtectionParams* delta_params,
|
||||||
const FecProtectionParams* key_params,
|
const FecProtectionParams* key_params,
|
||||||
uint32_t* sent_video_rate_bps,
|
uint32_t* sent_video_rate_bps,
|
||||||
uint32_t* sent_nack_rate_bps,
|
uint32_t* sent_nack_rate_bps,
|
||||||
uint32_t* sent_fec_rate_bps) override;
|
uint32_t* sent_fec_rate_bps) override;
|
||||||
|
|
||||||
void SetMaxRtpPacketSize(size_t max_rtp_packet_size) override;
|
|
||||||
|
|
||||||
// Implements EncodedImageCallback.
|
// Implements EncodedImageCallback.
|
||||||
// Returns 0 if the packet was routed / sent, -1 otherwise.
|
// Returns 0 if the packet was routed / sent, -1 otherwise.
|
||||||
EncodedImageCallback::Result OnEncodedImage(
|
EncodedImageCallback::Result OnEncodedImage(
|
||||||
@ -100,11 +101,36 @@ class RtpVideoSender : public RtpVideoSenderInterface {
|
|||||||
void OnBitrateAllocationUpdated(
|
void OnBitrateAllocationUpdated(
|
||||||
const VideoBitrateAllocation& bitrate) override;
|
const VideoBitrateAllocation& bitrate) override;
|
||||||
|
|
||||||
|
void OnTransportOverheadChanged(
|
||||||
|
size_t transport_overhead_bytes_per_packet) override;
|
||||||
|
// Implements OverheadObserver.
|
||||||
|
void OnOverheadChanged(size_t overhead_bytes_per_packet) override;
|
||||||
|
void OnBitrateUpdated(uint32_t bitrate_bps,
|
||||||
|
uint8_t fraction_loss,
|
||||||
|
int64_t rtt,
|
||||||
|
int framerate) override;
|
||||||
|
uint32_t GetPayloadBitrateBps() const override;
|
||||||
|
uint32_t GetProtectionBitrateBps() const override;
|
||||||
|
void SetEncodingData(size_t width,
|
||||||
|
size_t height,
|
||||||
|
size_t num_temporal_layers) override;
|
||||||
|
|
||||||
|
// From PacketFeedbackObserver.
|
||||||
|
void OnPacketAdded(uint32_t ssrc, uint16_t seq_num) override;
|
||||||
|
void OnPacketFeedbackVector(
|
||||||
|
const std::vector<PacketFeedback>& packet_feedback_vector) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void UpdateModuleSendingState() RTC_EXCLUSIVE_LOCKS_REQUIRED(crit_);
|
void UpdateModuleSendingState() RTC_EXCLUSIVE_LOCKS_REQUIRED(crit_);
|
||||||
void ConfigureProtection(const RtpConfig& rtp_config);
|
void ConfigureProtection(const RtpConfig& rtp_config);
|
||||||
void ConfigureSsrcs(const RtpConfig& rtp_config);
|
void ConfigureSsrcs(const RtpConfig& rtp_config);
|
||||||
|
bool FecEnabled() const;
|
||||||
|
bool NackEnabled() const;
|
||||||
|
|
||||||
|
const bool send_side_bwe_with_overhead_;
|
||||||
|
|
||||||
|
// TODO(holmer): Remove crit_ once RtpVideoSender runs on the
|
||||||
|
// transport task queue.
|
||||||
rtc::CriticalSection crit_;
|
rtc::CriticalSection crit_;
|
||||||
bool active_ RTC_GUARDED_BY(crit_);
|
bool active_ RTC_GUARDED_BY(crit_);
|
||||||
|
|
||||||
@ -113,6 +139,7 @@ class RtpVideoSender : public RtpVideoSenderInterface {
|
|||||||
std::map<uint32_t, RtpState> suspended_ssrcs_;
|
std::map<uint32_t, RtpState> suspended_ssrcs_;
|
||||||
|
|
||||||
std::unique_ptr<FlexfecSender> flexfec_sender_;
|
std::unique_ptr<FlexfecSender> flexfec_sender_;
|
||||||
|
std::unique_ptr<FecController> fec_controller_;
|
||||||
// Rtp modules are assumed to be sorted in simulcast index order.
|
// Rtp modules are assumed to be sorted in simulcast index order.
|
||||||
const std::vector<std::unique_ptr<RtpRtcp>> rtp_modules_;
|
const std::vector<std::unique_ptr<RtpRtcp>> rtp_modules_;
|
||||||
const RtpConfig rtp_config_;
|
const RtpConfig rtp_config_;
|
||||||
@ -125,6 +152,14 @@ class RtpVideoSender : public RtpVideoSenderInterface {
|
|||||||
int64_t shared_frame_id_ = 0;
|
int64_t shared_frame_id_ = 0;
|
||||||
std::vector<RtpPayloadParams> params_ RTC_GUARDED_BY(crit_);
|
std::vector<RtpPayloadParams> params_ RTC_GUARDED_BY(crit_);
|
||||||
|
|
||||||
|
size_t transport_overhead_bytes_per_packet_ RTC_GUARDED_BY(crit_);
|
||||||
|
size_t overhead_bytes_per_packet_ RTC_GUARDED_BY(crit_);
|
||||||
|
uint32_t protection_bitrate_bps_;
|
||||||
|
uint32_t encoder_target_rate_bps_;
|
||||||
|
|
||||||
|
std::unordered_set<uint16_t> feedback_packet_seq_num_set_;
|
||||||
|
std::vector<bool> loss_mask_vector_ RTC_GUARDED_BY(crit_);
|
||||||
|
|
||||||
RTC_DISALLOW_COPY_AND_ASSIGN(RtpVideoSender);
|
RTC_DISALLOW_COPY_AND_ASSIGN(RtpVideoSender);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -40,21 +40,21 @@ class RtpVideoSenderInterface : public EncodedImageCallback {
|
|||||||
virtual std::map<uint32_t, RtpState> GetRtpStates() const = 0;
|
virtual std::map<uint32_t, RtpState> GetRtpStates() const = 0;
|
||||||
virtual std::map<uint32_t, RtpPayloadState> GetRtpPayloadStates() const = 0;
|
virtual std::map<uint32_t, RtpPayloadState> GetRtpPayloadStates() const = 0;
|
||||||
|
|
||||||
virtual bool FecEnabled() const = 0;
|
|
||||||
|
|
||||||
virtual bool NackEnabled() const = 0;
|
|
||||||
|
|
||||||
virtual void DeliverRtcp(const uint8_t* packet, size_t length) = 0;
|
virtual void DeliverRtcp(const uint8_t* packet, size_t length) = 0;
|
||||||
|
|
||||||
virtual void ProtectionRequest(const FecProtectionParams* delta_params,
|
|
||||||
const FecProtectionParams* key_params,
|
|
||||||
uint32_t* sent_video_rate_bps,
|
|
||||||
uint32_t* sent_nack_rate_bps,
|
|
||||||
uint32_t* sent_fec_rate_bps) = 0;
|
|
||||||
|
|
||||||
virtual void SetMaxRtpPacketSize(size_t max_rtp_packet_size) = 0;
|
|
||||||
virtual void OnBitrateAllocationUpdated(
|
virtual void OnBitrateAllocationUpdated(
|
||||||
const VideoBitrateAllocation& bitrate) = 0;
|
const VideoBitrateAllocation& bitrate) = 0;
|
||||||
|
virtual void OnBitrateUpdated(uint32_t bitrate_bps,
|
||||||
|
uint8_t fraction_loss,
|
||||||
|
int64_t rtt,
|
||||||
|
int framerate) = 0;
|
||||||
|
virtual void OnTransportOverheadChanged(
|
||||||
|
size_t transport_overhead_bytes_per_packet) = 0;
|
||||||
|
virtual uint32_t GetPayloadBitrateBps() const = 0;
|
||||||
|
virtual uint32_t GetProtectionBitrateBps() const = 0;
|
||||||
|
virtual void SetEncodingData(size_t width,
|
||||||
|
size_t height,
|
||||||
|
size_t num_temporal_layers) = 0;
|
||||||
};
|
};
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
#endif // CALL_RTP_VIDEO_SENDER_INTERFACE_H_
|
#endif // CALL_RTP_VIDEO_SENDER_INTERFACE_H_
|
||||||
|
|||||||
@ -13,6 +13,7 @@
|
|||||||
|
|
||||||
#include "call/rtp_transport_controller_send.h"
|
#include "call/rtp_transport_controller_send.h"
|
||||||
#include "call/rtp_video_sender.h"
|
#include "call/rtp_video_sender.h"
|
||||||
|
#include "modules/video_coding/fec_controller_default.h"
|
||||||
#include "modules/video_coding/include/video_codec_interface.h"
|
#include "modules/video_coding/include/video_codec_interface.h"
|
||||||
#include "rtc_base/rate_limiter.h"
|
#include "rtc_base/rate_limiter.h"
|
||||||
#include "test/field_trial.h"
|
#include "test/field_trial.h"
|
||||||
@ -46,11 +47,6 @@ class MockRtcpIntraFrameObserver : public RtcpIntraFrameObserver {
|
|||||||
MOCK_METHOD1(OnReceivedIntraFrameRequest, void(uint32_t));
|
MOCK_METHOD1(OnReceivedIntraFrameRequest, void(uint32_t));
|
||||||
};
|
};
|
||||||
|
|
||||||
class MockOverheadObserver : public OverheadObserver {
|
|
||||||
public:
|
|
||||||
MOCK_METHOD1(OnOverheadChanged, void(size_t overhead_bytes_per_packet));
|
|
||||||
};
|
|
||||||
|
|
||||||
class MockCongestionObserver : public NetworkChangedObserver {
|
class MockCongestionObserver : public NetworkChangedObserver {
|
||||||
public:
|
public:
|
||||||
MOCK_METHOD4(OnNetworkChanged,
|
MOCK_METHOD4(OnNetworkChanged,
|
||||||
@ -69,8 +65,7 @@ RtpSenderObservers CreateObservers(
|
|||||||
FrameCountObserver* frame_count_observer,
|
FrameCountObserver* frame_count_observer,
|
||||||
RtcpPacketTypeCounterObserver* rtcp_type_observer,
|
RtcpPacketTypeCounterObserver* rtcp_type_observer,
|
||||||
SendSideDelayObserver* send_delay_observer,
|
SendSideDelayObserver* send_delay_observer,
|
||||||
SendPacketObserver* send_packet_observer,
|
SendPacketObserver* send_packet_observer) {
|
||||||
OverheadObserver* overhead_observer) {
|
|
||||||
RtpSenderObservers observers;
|
RtpSenderObservers observers;
|
||||||
observers.rtcp_rtt_stats = rtcp_rtt_stats;
|
observers.rtcp_rtt_stats = rtcp_rtt_stats;
|
||||||
observers.intra_frame_callback = intra_frame_callback;
|
observers.intra_frame_callback = intra_frame_callback;
|
||||||
@ -81,7 +76,6 @@ RtpSenderObservers CreateObservers(
|
|||||||
observers.rtcp_type_observer = rtcp_type_observer;
|
observers.rtcp_type_observer = rtcp_type_observer;
|
||||||
observers.send_delay_observer = send_delay_observer;
|
observers.send_delay_observer = send_delay_observer;
|
||||||
observers.send_packet_observer = send_packet_observer;
|
observers.send_packet_observer = send_packet_observer;
|
||||||
observers.overhead_observer = overhead_observer;
|
|
||||||
return observers;
|
return observers;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -111,9 +105,9 @@ class RtpVideoSenderTestFixture {
|
|||||||
config_.rtp, config_.rtcp, &transport_,
|
config_.rtp, config_.rtcp, &transport_,
|
||||||
CreateObservers(&call_stats_, &encoder_feedback_, &stats_proxy_,
|
CreateObservers(&call_stats_, &encoder_feedback_, &stats_proxy_,
|
||||||
&stats_proxy_, &stats_proxy_, &stats_proxy_,
|
&stats_proxy_, &stats_proxy_, &stats_proxy_,
|
||||||
&stats_proxy_, &stats_proxy_, &send_delay_stats_,
|
&stats_proxy_, &stats_proxy_, &send_delay_stats_),
|
||||||
&overhead_observer_),
|
&transport_controller_, &event_log_, &retransmission_rate_limiter_,
|
||||||
&transport_controller_, &event_log_, &retransmission_rate_limiter_);
|
absl::make_unique<FecControllerDefault>(&clock_));
|
||||||
}
|
}
|
||||||
|
|
||||||
RtpVideoSender* router() { return router_.get(); }
|
RtpVideoSender* router() { return router_.get(); }
|
||||||
@ -121,7 +115,6 @@ class RtpVideoSenderTestFixture {
|
|||||||
private:
|
private:
|
||||||
NiceMock<MockTransport> transport_;
|
NiceMock<MockTransport> transport_;
|
||||||
NiceMock<MockCongestionObserver> congestion_observer_;
|
NiceMock<MockCongestionObserver> congestion_observer_;
|
||||||
NiceMock<MockOverheadObserver> overhead_observer_;
|
|
||||||
NiceMock<MockRtcpIntraFrameObserver> encoder_feedback_;
|
NiceMock<MockRtcpIntraFrameObserver> encoder_feedback_;
|
||||||
SimulatedClock clock_;
|
SimulatedClock clock_;
|
||||||
RtcEventLogNullImpl event_log_;
|
RtcEventLogNullImpl event_log_;
|
||||||
|
|||||||
@ -12,6 +12,7 @@
|
|||||||
#define CALL_TEST_MOCK_RTP_TRANSPORT_CONTROLLER_SEND_H_
|
#define CALL_TEST_MOCK_RTP_TRANSPORT_CONTROLLER_SEND_H_
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
@ -29,7 +30,7 @@ namespace webrtc {
|
|||||||
class MockRtpTransportControllerSend
|
class MockRtpTransportControllerSend
|
||||||
: public RtpTransportControllerSendInterface {
|
: public RtpTransportControllerSendInterface {
|
||||||
public:
|
public:
|
||||||
MOCK_METHOD8(
|
MOCK_METHOD9(
|
||||||
CreateRtpVideoSender,
|
CreateRtpVideoSender,
|
||||||
RtpVideoSenderInterface*(const std::vector<uint32_t>&,
|
RtpVideoSenderInterface*(const std::vector<uint32_t>&,
|
||||||
std::map<uint32_t, RtpState>,
|
std::map<uint32_t, RtpState>,
|
||||||
@ -38,7 +39,8 @@ class MockRtpTransportControllerSend
|
|||||||
const RtcpConfig&,
|
const RtcpConfig&,
|
||||||
Transport*,
|
Transport*,
|
||||||
const RtpSenderObservers&,
|
const RtpSenderObservers&,
|
||||||
RtcEventLog*));
|
RtcEventLog*,
|
||||||
|
std::unique_ptr<FecController>));
|
||||||
MOCK_METHOD1(DestroyRtpVideoSender, void(RtpVideoSenderInterface*));
|
MOCK_METHOD1(DestroyRtpVideoSender, void(RtpVideoSenderInterface*));
|
||||||
MOCK_METHOD0(GetWorkerQueue, rtc::TaskQueue*());
|
MOCK_METHOD0(GetWorkerQueue, rtc::TaskQueue*());
|
||||||
MOCK_METHOD0(packet_router, PacketRouter*());
|
MOCK_METHOD0(packet_router, PacketRouter*());
|
||||||
@ -65,6 +67,7 @@ class MockRtpTransportControllerSend
|
|||||||
MOCK_METHOD1(SetSdpBitrateParameters, void(const BitrateConstraints&));
|
MOCK_METHOD1(SetSdpBitrateParameters, void(const BitrateConstraints&));
|
||||||
MOCK_METHOD1(SetClientBitratePreferences, void(const BitrateSettings&));
|
MOCK_METHOD1(SetClientBitratePreferences, void(const BitrateSettings&));
|
||||||
MOCK_METHOD1(SetAllocatedBitrateWithoutFeedback, void(uint32_t));
|
MOCK_METHOD1(SetAllocatedBitrateWithoutFeedback, void(uint32_t));
|
||||||
|
MOCK_METHOD1(OnTransportOverheadChanged, void(size_t));
|
||||||
};
|
};
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
#endif // CALL_TEST_MOCK_RTP_TRANSPORT_CONTROLLER_SEND_H_
|
#endif // CALL_TEST_MOCK_RTP_TRANSPORT_CONTROLLER_SEND_H_
|
||||||
|
|||||||
@ -390,9 +390,7 @@ FakeCall::FakeCall()
|
|||||||
: audio_network_state_(webrtc::kNetworkUp),
|
: audio_network_state_(webrtc::kNetworkUp),
|
||||||
video_network_state_(webrtc::kNetworkUp),
|
video_network_state_(webrtc::kNetworkUp),
|
||||||
num_created_send_streams_(0),
|
num_created_send_streams_(0),
|
||||||
num_created_receive_streams_(0),
|
num_created_receive_streams_(0) {}
|
||||||
audio_transport_overhead_(0),
|
|
||||||
video_transport_overhead_(0) {}
|
|
||||||
|
|
||||||
FakeCall::~FakeCall() {
|
FakeCall::~FakeCall() {
|
||||||
EXPECT_EQ(0u, video_send_streams_.size());
|
EXPECT_EQ(0u, video_send_streams_.size());
|
||||||
@ -635,21 +633,8 @@ void FakeCall::SignalChannelNetworkState(webrtc::MediaType media,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void FakeCall::OnTransportOverheadChanged(webrtc::MediaType media,
|
void FakeCall::OnAudioTransportOverheadChanged(
|
||||||
int transport_overhead_per_packet) {
|
int transport_overhead_per_packet) {}
|
||||||
switch (media) {
|
|
||||||
case webrtc::MediaType::AUDIO:
|
|
||||||
audio_transport_overhead_ = transport_overhead_per_packet;
|
|
||||||
break;
|
|
||||||
case webrtc::MediaType::VIDEO:
|
|
||||||
video_transport_overhead_ = transport_overhead_per_packet;
|
|
||||||
break;
|
|
||||||
case webrtc::MediaType::DATA:
|
|
||||||
case webrtc::MediaType::ANY:
|
|
||||||
ADD_FAILURE()
|
|
||||||
<< "SignalChannelNetworkState called with unknown parameter.";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void FakeCall::OnSentPacket(const rtc::SentPacket& sent_packet) {
|
void FakeCall::OnSentPacket(const rtc::SentPacket& sent_packet) {
|
||||||
last_sent_packet_ = sent_packet;
|
last_sent_packet_ = sent_packet;
|
||||||
|
|||||||
@ -317,7 +317,7 @@ class FakeCall final : public webrtc::Call, public webrtc::PacketReceiver {
|
|||||||
|
|
||||||
void SignalChannelNetworkState(webrtc::MediaType media,
|
void SignalChannelNetworkState(webrtc::MediaType media,
|
||||||
webrtc::NetworkState state) override;
|
webrtc::NetworkState state) override;
|
||||||
void OnTransportOverheadChanged(webrtc::MediaType media,
|
void OnAudioTransportOverheadChanged(
|
||||||
int transport_overhead_per_packet) override;
|
int transport_overhead_per_packet) override;
|
||||||
void OnSentPacket(const rtc::SentPacket& sent_packet) override;
|
void OnSentPacket(const rtc::SentPacket& sent_packet) override;
|
||||||
|
|
||||||
@ -338,9 +338,6 @@ class FakeCall final : public webrtc::Call, public webrtc::PacketReceiver {
|
|||||||
|
|
||||||
int num_created_send_streams_;
|
int num_created_send_streams_;
|
||||||
int num_created_receive_streams_;
|
int num_created_receive_streams_;
|
||||||
|
|
||||||
int audio_transport_overhead_;
|
|
||||||
int video_transport_overhead_;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace cricket
|
} // namespace cricket
|
||||||
|
|||||||
@ -1408,7 +1408,7 @@ void WebRtcVideoChannel::OnNetworkRouteChanged(
|
|||||||
const rtc::NetworkRoute& network_route) {
|
const rtc::NetworkRoute& network_route) {
|
||||||
call_->GetTransportControllerSend()->OnNetworkRouteChanged(transport_name,
|
call_->GetTransportControllerSend()->OnNetworkRouteChanged(transport_name,
|
||||||
network_route);
|
network_route);
|
||||||
call_->OnTransportOverheadChanged(webrtc::MediaType::VIDEO,
|
call_->GetTransportControllerSend()->OnTransportOverheadChanged(
|
||||||
network_route.packet_overhead);
|
network_route.packet_overhead);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -2059,8 +2059,7 @@ void WebRtcVoiceMediaChannel::OnNetworkRouteChanged(
|
|||||||
RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
|
RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
|
||||||
call_->GetTransportControllerSend()->OnNetworkRouteChanged(transport_name,
|
call_->GetTransportControllerSend()->OnNetworkRouteChanged(transport_name,
|
||||||
network_route);
|
network_route);
|
||||||
call_->OnTransportOverheadChanged(webrtc::MediaType::AUDIO,
|
call_->OnAudioTransportOverheadChanged(network_route.packet_overhead);
|
||||||
network_route.packet_overhead);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WebRtcVoiceMediaChannel::MuteStream(uint32_t ssrc, bool muted) {
|
bool WebRtcVoiceMediaChannel::MuteStream(uint32_t ssrc, bool muted) {
|
||||||
|
|||||||
@ -75,8 +75,8 @@ SendAudioStream::SendAudioStream(
|
|||||||
}
|
}
|
||||||
send_stream_ = sender_->call_->CreateAudioSendStream(send_config);
|
send_stream_ = sender_->call_->CreateAudioSendStream(send_config);
|
||||||
if (field_trial::IsEnabled("WebRTC-SendSideBwe-WithOverhead")) {
|
if (field_trial::IsEnabled("WebRTC-SendSideBwe-WithOverhead")) {
|
||||||
sender->call_->OnTransportOverheadChanged(
|
sender->call_->OnAudioTransportOverheadChanged(
|
||||||
MediaType::AUDIO, config.stream.packet_overhead.bytes());
|
config.stream.packet_overhead.bytes());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -197,15 +197,6 @@ void VideoSendStream::StopPermanentlyAndGetRtpStates(
|
|||||||
thread_sync_event_.Wait(rtc::Event::kForever);
|
thread_sync_event_.Wait(rtc::Event::kForever);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VideoSendStream::SetTransportOverhead(
|
|
||||||
size_t transport_overhead_per_packet) {
|
|
||||||
RTC_DCHECK_RUN_ON(&thread_checker_);
|
|
||||||
VideoSendStreamImpl* send_stream = send_stream_.get();
|
|
||||||
worker_queue_->PostTask([send_stream, transport_overhead_per_packet] {
|
|
||||||
send_stream->SetTransportOverhead(transport_overhead_per_packet);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
bool VideoSendStream::DeliverRtcp(const uint8_t* packet, size_t length) {
|
bool VideoSendStream::DeliverRtcp(const uint8_t* packet, size_t length) {
|
||||||
// Called on a network thread.
|
// Called on a network thread.
|
||||||
return send_stream_->DeliverRtcp(packet, length);
|
return send_stream_->DeliverRtcp(packet, length);
|
||||||
|
|||||||
@ -88,8 +88,6 @@ class VideoSendStream : public webrtc::VideoSendStream {
|
|||||||
void StopPermanentlyAndGetRtpStates(RtpStateMap* rtp_state_map,
|
void StopPermanentlyAndGetRtpStates(RtpStateMap* rtp_state_map,
|
||||||
RtpPayloadStateMap* payload_state_map);
|
RtpPayloadStateMap* payload_state_map);
|
||||||
|
|
||||||
void SetTransportOverhead(size_t transport_overhead_per_packet);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class test::VideoSendStreamPeer;
|
friend class test::VideoSendStreamPeer;
|
||||||
|
|
||||||
|
|||||||
@ -28,19 +28,12 @@
|
|||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
namespace internal {
|
namespace internal {
|
||||||
namespace {
|
namespace {
|
||||||
// Assume an average video stream has around 3 packets per frame (1 mbps / 30
|
|
||||||
// fps / 1400B) A sequence number set with size 5500 will be able to store
|
|
||||||
// packet sequence number for at least last 60 seconds.
|
|
||||||
static const int kSendSideSeqNumSetMaxSize = 5500;
|
|
||||||
|
|
||||||
// Max positive size difference to treat allocations as "similar".
|
// Max positive size difference to treat allocations as "similar".
|
||||||
static constexpr int kMaxVbaSizeDifferencePercent = 10;
|
static constexpr int kMaxVbaSizeDifferencePercent = 10;
|
||||||
// Max time we will throttle similar video bitrate allocations.
|
// Max time we will throttle similar video bitrate allocations.
|
||||||
static constexpr int64_t kMaxVbaThrottleTimeMs = 500;
|
static constexpr int64_t kMaxVbaThrottleTimeMs = 500;
|
||||||
|
|
||||||
// We don't do MTU discovery, so assume that we have the standard ethernet MTU.
|
|
||||||
const size_t kPathMTU = 1500;
|
|
||||||
|
|
||||||
bool TransportSeqNumExtensionConfigured(const VideoSendStream::Config& config) {
|
bool TransportSeqNumExtensionConfigured(const VideoSendStream::Config& config) {
|
||||||
const std::vector<RtpExtension>& extensions = config.rtp.extensions;
|
const std::vector<RtpExtension>& extensions = config.rtp.extensions;
|
||||||
return std::find_if(
|
return std::find_if(
|
||||||
@ -118,26 +111,10 @@ int CalculateMaxPadBitrateBps(const std::vector<VideoStream>& streams,
|
|||||||
return pad_up_to_bitrate_bps;
|
return pad_up_to_bitrate_bps;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t CalculateOverheadRateBps(int packets_per_second,
|
|
||||||
size_t overhead_bytes_per_packet,
|
|
||||||
uint32_t max_overhead_bps) {
|
|
||||||
uint32_t overhead_bps =
|
|
||||||
static_cast<uint32_t>(8 * overhead_bytes_per_packet * packets_per_second);
|
|
||||||
return std::min(overhead_bps, max_overhead_bps);
|
|
||||||
}
|
|
||||||
|
|
||||||
int CalculatePacketRate(uint32_t bitrate_bps, size_t packet_size_bytes) {
|
|
||||||
size_t packet_size_bits = 8 * packet_size_bytes;
|
|
||||||
// Ceil for int value of bitrate_bps / packet_size_bits.
|
|
||||||
return static_cast<int>((bitrate_bps + packet_size_bits - 1) /
|
|
||||||
packet_size_bits);
|
|
||||||
}
|
|
||||||
|
|
||||||
RtpSenderObservers CreateObservers(CallStats* call_stats,
|
RtpSenderObservers CreateObservers(CallStats* call_stats,
|
||||||
EncoderRtcpFeedback* encoder_feedback,
|
EncoderRtcpFeedback* encoder_feedback,
|
||||||
SendStatisticsProxy* stats_proxy,
|
SendStatisticsProxy* stats_proxy,
|
||||||
SendDelayStats* send_delay_stats,
|
SendDelayStats* send_delay_stats) {
|
||||||
OverheadObserver* overhead_observer) {
|
|
||||||
RtpSenderObservers observers;
|
RtpSenderObservers observers;
|
||||||
observers.rtcp_rtt_stats = call_stats;
|
observers.rtcp_rtt_stats = call_stats;
|
||||||
observers.intra_frame_callback = encoder_feedback;
|
observers.intra_frame_callback = encoder_feedback;
|
||||||
@ -148,7 +125,6 @@ RtpSenderObservers CreateObservers(CallStats* call_stats,
|
|||||||
observers.rtcp_type_observer = stats_proxy;
|
observers.rtcp_type_observer = stats_proxy;
|
||||||
observers.send_delay_observer = stats_proxy;
|
observers.send_delay_observer = stats_proxy;
|
||||||
observers.send_packet_observer = send_delay_stats;
|
observers.send_packet_observer = send_delay_stats;
|
||||||
observers.overhead_observer = overhead_observer;
|
|
||||||
return observers;
|
return observers;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -243,13 +219,10 @@ VideoSendStreamImpl::VideoSendStreamImpl(
|
|||||||
std::map<uint32_t, RtpPayloadState> suspended_payload_states,
|
std::map<uint32_t, RtpPayloadState> suspended_payload_states,
|
||||||
VideoEncoderConfig::ContentType content_type,
|
VideoEncoderConfig::ContentType content_type,
|
||||||
std::unique_ptr<FecController> fec_controller)
|
std::unique_ptr<FecController> fec_controller)
|
||||||
: send_side_bwe_with_overhead_(
|
: has_alr_probing_(config->periodic_alr_bandwidth_probing ||
|
||||||
webrtc::field_trial::IsEnabled("WebRTC-SendSideBwe-WithOverhead")),
|
|
||||||
has_alr_probing_(config->periodic_alr_bandwidth_probing ||
|
|
||||||
GetAlrSettings(content_type)),
|
GetAlrSettings(content_type)),
|
||||||
stats_proxy_(stats_proxy),
|
stats_proxy_(stats_proxy),
|
||||||
config_(config),
|
config_(config),
|
||||||
fec_controller_(std::move(fec_controller)),
|
|
||||||
worker_queue_(worker_queue),
|
worker_queue_(worker_queue),
|
||||||
check_encoder_activity_task_(nullptr),
|
check_encoder_activity_task_(nullptr),
|
||||||
call_stats_(call_stats),
|
call_stats_(call_stats),
|
||||||
@ -275,12 +248,10 @@ VideoSendStreamImpl::VideoSendStreamImpl(
|
|||||||
CreateObservers(call_stats,
|
CreateObservers(call_stats,
|
||||||
&encoder_feedback_,
|
&encoder_feedback_,
|
||||||
stats_proxy_,
|
stats_proxy_,
|
||||||
send_delay_stats,
|
send_delay_stats),
|
||||||
this),
|
event_log,
|
||||||
event_log)),
|
std::move(fec_controller))),
|
||||||
weak_ptr_factory_(this),
|
weak_ptr_factory_(this) {
|
||||||
overhead_bytes_per_packet_(0),
|
|
||||||
transport_overhead_bytes_per_packet_(0) {
|
|
||||||
RTC_DCHECK_RUN_ON(worker_queue_);
|
RTC_DCHECK_RUN_ON(worker_queue_);
|
||||||
RTC_LOG(LS_INFO) << "VideoSendStreamInternal: " << config_->ToString();
|
RTC_LOG(LS_INFO) << "VideoSendStreamInternal: " << config_->ToString();
|
||||||
weak_ptr_ = weak_ptr_factory_.GetWeakPtr();
|
weak_ptr_ = weak_ptr_factory_.GetWeakPtr();
|
||||||
@ -332,17 +303,6 @@ VideoSendStreamImpl::VideoSendStreamImpl(
|
|||||||
transport->EnablePeriodicAlrProbing(true);
|
transport->EnablePeriodicAlrProbing(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Currently, both ULPFEC and FlexFEC use the same FEC rate calculation logic,
|
|
||||||
// so enable that logic if either of those FEC schemes are enabled.
|
|
||||||
fec_controller_->SetProtectionMethod(rtp_video_sender_->FecEnabled(),
|
|
||||||
rtp_video_sender_->NackEnabled());
|
|
||||||
|
|
||||||
fec_controller_->SetProtectionCallback(this);
|
|
||||||
// Signal congestion controller this object is ready for OnPacket* callbacks.
|
|
||||||
if (fec_controller_->UseLossVectorMask()) {
|
|
||||||
transport_->RegisterPacketFeedbackObserver(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
RTC_DCHECK_GE(config_->rtp.payload_type, 0);
|
RTC_DCHECK_GE(config_->rtp.payload_type, 0);
|
||||||
RTC_DCHECK_LE(config_->rtp.payload_type, 127);
|
RTC_DCHECK_LE(config_->rtp.payload_type, 127);
|
||||||
|
|
||||||
@ -368,9 +328,6 @@ VideoSendStreamImpl::~VideoSendStreamImpl() {
|
|||||||
RTC_DCHECK(!rtp_video_sender_->IsActive())
|
RTC_DCHECK(!rtp_video_sender_->IsActive())
|
||||||
<< "VideoSendStreamImpl::Stop not called";
|
<< "VideoSendStreamImpl::Stop not called";
|
||||||
RTC_LOG(LS_INFO) << "~VideoSendStreamInternal: " << config_->ToString();
|
RTC_LOG(LS_INFO) << "~VideoSendStreamInternal: " << config_->ToString();
|
||||||
if (fec_controller_->UseLossVectorMask()) {
|
|
||||||
transport_->DeRegisterPacketFeedbackObserver(this);
|
|
||||||
}
|
|
||||||
transport_->DestroyRtpVideoSender(rtp_video_sender_);
|
transport_->DestroyRtpVideoSender(rtp_video_sender_);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -582,9 +539,9 @@ void VideoSendStreamImpl::OnEncoderConfigurationChanged(
|
|||||||
|
|
||||||
const size_t num_temporal_layers =
|
const size_t num_temporal_layers =
|
||||||
streams.back().num_temporal_layers.value_or(1);
|
streams.back().num_temporal_layers.value_or(1);
|
||||||
fec_controller_->SetEncodingData(streams[0].width, streams[0].height,
|
|
||||||
num_temporal_layers,
|
rtp_video_sender_->SetEncodingData(streams[0].width, streams[0].height,
|
||||||
config_->rtp.max_packet_size);
|
num_temporal_layers);
|
||||||
|
|
||||||
if (rtp_video_sender_->IsActive()) {
|
if (rtp_video_sender_->IsActive()) {
|
||||||
// The send stream is started already. Update the allocator with new bitrate
|
// The send stream is started already. Update the allocator with new bitrate
|
||||||
@ -623,8 +580,6 @@ EncodedImageCallback::Result VideoSendStreamImpl::OnEncodedImage(
|
|||||||
check_encoder_activity_task_->UpdateEncoderActivity();
|
check_encoder_activity_task_->UpdateEncoderActivity();
|
||||||
}
|
}
|
||||||
|
|
||||||
fec_controller_->UpdateWithEncodedData(encoded_image._length,
|
|
||||||
encoded_image._frameType);
|
|
||||||
EncodedImageCallback::Result result = rtp_video_sender_->OnEncodedImage(
|
EncodedImageCallback::Result result = rtp_video_sender_->OnEncodedImage(
|
||||||
encoded_image, codec_specific_info, fragmentation);
|
encoded_image, codec_specific_info, fragmentation);
|
||||||
|
|
||||||
@ -666,125 +621,16 @@ uint32_t VideoSendStreamImpl::OnBitrateUpdated(uint32_t bitrate_bps,
|
|||||||
RTC_DCHECK(rtp_video_sender_->IsActive())
|
RTC_DCHECK(rtp_video_sender_->IsActive())
|
||||||
<< "VideoSendStream::Start has not been called.";
|
<< "VideoSendStream::Start has not been called.";
|
||||||
|
|
||||||
// Substract overhead from bitrate.
|
rtp_video_sender_->OnBitrateUpdated(bitrate_bps, fraction_loss, rtt,
|
||||||
rtc::CritScope lock(&overhead_bytes_per_packet_crit_);
|
stats_proxy_->GetSendFrameRate());
|
||||||
uint32_t payload_bitrate_bps = bitrate_bps;
|
encoder_target_rate_bps_ = rtp_video_sender_->GetPayloadBitrateBps();
|
||||||
if (send_side_bwe_with_overhead_) {
|
|
||||||
payload_bitrate_bps -= CalculateOverheadRateBps(
|
|
||||||
CalculatePacketRate(bitrate_bps,
|
|
||||||
config_->rtp.max_packet_size +
|
|
||||||
transport_overhead_bytes_per_packet_),
|
|
||||||
overhead_bytes_per_packet_ + transport_overhead_bytes_per_packet_,
|
|
||||||
bitrate_bps);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the encoder target rate. It is the estimated network rate -
|
|
||||||
// protection overhead.
|
|
||||||
encoder_target_rate_bps_ = fec_controller_->UpdateFecRates(
|
|
||||||
payload_bitrate_bps, stats_proxy_->GetSendFrameRate(), fraction_loss,
|
|
||||||
loss_mask_vector_, rtt);
|
|
||||||
loss_mask_vector_.clear();
|
|
||||||
|
|
||||||
uint32_t encoder_overhead_rate_bps =
|
|
||||||
send_side_bwe_with_overhead_
|
|
||||||
? CalculateOverheadRateBps(
|
|
||||||
CalculatePacketRate(encoder_target_rate_bps_,
|
|
||||||
config_->rtp.max_packet_size +
|
|
||||||
transport_overhead_bytes_per_packet_ -
|
|
||||||
overhead_bytes_per_packet_),
|
|
||||||
overhead_bytes_per_packet_ +
|
|
||||||
transport_overhead_bytes_per_packet_,
|
|
||||||
bitrate_bps - encoder_target_rate_bps_)
|
|
||||||
: 0;
|
|
||||||
|
|
||||||
// When the field trial "WebRTC-SendSideBwe-WithOverhead" is enabled
|
|
||||||
// protection_bitrate includes overhead.
|
|
||||||
uint32_t protection_bitrate =
|
|
||||||
bitrate_bps - (encoder_target_rate_bps_ + encoder_overhead_rate_bps);
|
|
||||||
|
|
||||||
encoder_target_rate_bps_ =
|
encoder_target_rate_bps_ =
|
||||||
std::min(encoder_max_bitrate_bps_, encoder_target_rate_bps_);
|
std::min(encoder_max_bitrate_bps_, encoder_target_rate_bps_);
|
||||||
video_stream_encoder_->OnBitrateUpdated(encoder_target_rate_bps_,
|
video_stream_encoder_->OnBitrateUpdated(encoder_target_rate_bps_,
|
||||||
fraction_loss, rtt);
|
fraction_loss, rtt);
|
||||||
stats_proxy_->OnSetEncoderTargetRate(encoder_target_rate_bps_);
|
stats_proxy_->OnSetEncoderTargetRate(encoder_target_rate_bps_);
|
||||||
return protection_bitrate;
|
return rtp_video_sender_->GetProtectionBitrateBps();
|
||||||
}
|
}
|
||||||
|
|
||||||
int VideoSendStreamImpl::ProtectionRequest(
|
|
||||||
const FecProtectionParams* delta_params,
|
|
||||||
const FecProtectionParams* key_params,
|
|
||||||
uint32_t* sent_video_rate_bps,
|
|
||||||
uint32_t* sent_nack_rate_bps,
|
|
||||||
uint32_t* sent_fec_rate_bps) {
|
|
||||||
RTC_DCHECK_RUN_ON(worker_queue_);
|
|
||||||
rtp_video_sender_->ProtectionRequest(delta_params, key_params,
|
|
||||||
sent_video_rate_bps, sent_nack_rate_bps,
|
|
||||||
sent_fec_rate_bps);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void VideoSendStreamImpl::OnOverheadChanged(size_t overhead_bytes_per_packet) {
|
|
||||||
rtc::CritScope lock(&overhead_bytes_per_packet_crit_);
|
|
||||||
overhead_bytes_per_packet_ = overhead_bytes_per_packet;
|
|
||||||
}
|
|
||||||
|
|
||||||
void VideoSendStreamImpl::SetTransportOverhead(
|
|
||||||
size_t transport_overhead_bytes_per_packet) {
|
|
||||||
if (transport_overhead_bytes_per_packet >= static_cast<int>(kPathMTU)) {
|
|
||||||
RTC_LOG(LS_ERROR) << "Transport overhead exceeds size of ethernet frame";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
transport_overhead_bytes_per_packet_ = transport_overhead_bytes_per_packet;
|
|
||||||
|
|
||||||
size_t rtp_packet_size =
|
|
||||||
std::min(config_->rtp.max_packet_size,
|
|
||||||
kPathMTU - transport_overhead_bytes_per_packet_);
|
|
||||||
|
|
||||||
rtp_video_sender_->SetMaxRtpPacketSize(rtp_packet_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
void VideoSendStreamImpl::OnPacketAdded(uint32_t ssrc, uint16_t seq_num) {
|
|
||||||
if (!worker_queue_->IsCurrent()) {
|
|
||||||
auto ptr = weak_ptr_;
|
|
||||||
worker_queue_->PostTask([=] {
|
|
||||||
if (!ptr.get())
|
|
||||||
return;
|
|
||||||
ptr->OnPacketAdded(ssrc, seq_num);
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const auto ssrcs = config_->rtp.ssrcs;
|
|
||||||
if (std::find(ssrcs.begin(), ssrcs.end(), ssrc) != ssrcs.end()) {
|
|
||||||
feedback_packet_seq_num_set_.insert(seq_num);
|
|
||||||
if (feedback_packet_seq_num_set_.size() > kSendSideSeqNumSetMaxSize) {
|
|
||||||
RTC_LOG(LS_WARNING) << "Feedback packet sequence number set exceed it's "
|
|
||||||
"max size', will get reset.";
|
|
||||||
feedback_packet_seq_num_set_.clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void VideoSendStreamImpl::OnPacketFeedbackVector(
|
|
||||||
const std::vector<PacketFeedback>& packet_feedback_vector) {
|
|
||||||
if (!worker_queue_->IsCurrent()) {
|
|
||||||
auto ptr = weak_ptr_;
|
|
||||||
worker_queue_->PostTask([=] {
|
|
||||||
if (!ptr.get())
|
|
||||||
return;
|
|
||||||
ptr->OnPacketFeedbackVector(packet_feedback_vector);
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// Lost feedbacks are not considered to be lost packets.
|
|
||||||
for (const PacketFeedback& packet : packet_feedback_vector) {
|
|
||||||
auto it = feedback_packet_seq_num_set_.find(packet.sequence_number);
|
|
||||||
if (it != feedback_packet_seq_num_set_.end()) {
|
|
||||||
const bool lost = packet.arrival_time_ms == PacketFeedback::kNotReceived;
|
|
||||||
loss_mask_vector_.push_back(lost);
|
|
||||||
feedback_packet_seq_num_set_.erase(it);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} // namespace internal
|
} // namespace internal
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
|
|||||||
@ -12,7 +12,6 @@
|
|||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <unordered_set>
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "api/video/video_bitrate_allocator.h"
|
#include "api/video/video_bitrate_allocator.h"
|
||||||
@ -39,11 +38,8 @@ namespace internal {
|
|||||||
// An encoder may deliver frames through the EncodedImageCallback on an
|
// An encoder may deliver frames through the EncodedImageCallback on an
|
||||||
// arbitrary thread.
|
// arbitrary thread.
|
||||||
class VideoSendStreamImpl : public webrtc::BitrateAllocatorObserver,
|
class VideoSendStreamImpl : public webrtc::BitrateAllocatorObserver,
|
||||||
public webrtc::OverheadObserver,
|
|
||||||
public webrtc::VCMProtectionCallback,
|
|
||||||
public VideoStreamEncoderInterface::EncoderSink,
|
public VideoStreamEncoderInterface::EncoderSink,
|
||||||
public VideoBitrateAllocationObserver,
|
public VideoBitrateAllocationObserver {
|
||||||
public webrtc::PacketFeedbackObserver {
|
|
||||||
public:
|
public:
|
||||||
VideoSendStreamImpl(
|
VideoSendStreamImpl(
|
||||||
SendStatisticsProxy* stats_proxy,
|
SendStatisticsProxy* stats_proxy,
|
||||||
@ -81,15 +77,8 @@ class VideoSendStreamImpl : public webrtc::BitrateAllocatorObserver,
|
|||||||
|
|
||||||
std::map<uint32_t, RtpPayloadState> GetRtpPayloadStates() const;
|
std::map<uint32_t, RtpPayloadState> GetRtpPayloadStates() const;
|
||||||
|
|
||||||
void SetTransportOverhead(size_t transport_overhead_per_packet);
|
|
||||||
|
|
||||||
absl::optional<float> configured_pacing_factor_;
|
absl::optional<float> configured_pacing_factor_;
|
||||||
|
|
||||||
// From PacketFeedbackObserver.
|
|
||||||
void OnPacketAdded(uint32_t ssrc, uint16_t seq_num) override;
|
|
||||||
void OnPacketFeedbackVector(
|
|
||||||
const std::vector<PacketFeedback>& packet_feedback_vector) override;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
class CheckEncoderActivityTask;
|
class CheckEncoderActivityTask;
|
||||||
|
|
||||||
@ -99,16 +88,6 @@ class VideoSendStreamImpl : public webrtc::BitrateAllocatorObserver,
|
|||||||
int64_t rtt,
|
int64_t rtt,
|
||||||
int64_t probing_interval_ms) override;
|
int64_t probing_interval_ms) override;
|
||||||
|
|
||||||
// Implements webrtc::VCMProtectionCallback.
|
|
||||||
int ProtectionRequest(const FecProtectionParams* delta_params,
|
|
||||||
const FecProtectionParams* key_params,
|
|
||||||
uint32_t* sent_video_rate_bps,
|
|
||||||
uint32_t* sent_nack_rate_bps,
|
|
||||||
uint32_t* sent_fec_rate_bps) override;
|
|
||||||
|
|
||||||
// Implements OverheadObserver.
|
|
||||||
void OnOverheadChanged(size_t overhead_bytes_per_packet) override;
|
|
||||||
|
|
||||||
void OnEncoderConfigurationChanged(std::vector<VideoStream> streams,
|
void OnEncoderConfigurationChanged(std::vector<VideoStream> streams,
|
||||||
int min_transmit_bitrate_bps) override;
|
int min_transmit_bitrate_bps) override;
|
||||||
|
|
||||||
@ -135,13 +114,11 @@ class VideoSendStreamImpl : public webrtc::BitrateAllocatorObserver,
|
|||||||
void SignalEncoderTimedOut();
|
void SignalEncoderTimedOut();
|
||||||
void SignalEncoderActive();
|
void SignalEncoderActive();
|
||||||
|
|
||||||
const bool send_side_bwe_with_overhead_;
|
|
||||||
const bool has_alr_probing_;
|
const bool has_alr_probing_;
|
||||||
|
|
||||||
SendStatisticsProxy* const stats_proxy_;
|
SendStatisticsProxy* const stats_proxy_;
|
||||||
const VideoSendStream::Config* const config_;
|
const VideoSendStream::Config* const config_;
|
||||||
|
|
||||||
std::unique_ptr<FecController> fec_controller_;
|
|
||||||
rtc::TaskQueue* const worker_queue_;
|
rtc::TaskQueue* const worker_queue_;
|
||||||
|
|
||||||
rtc::CriticalSection encoder_activity_crit_sect_;
|
rtc::CriticalSection encoder_activity_crit_sect_;
|
||||||
@ -175,14 +152,6 @@ class VideoSendStreamImpl : public webrtc::BitrateAllocatorObserver,
|
|||||||
// invalidated before any other members are destroyed.
|
// invalidated before any other members are destroyed.
|
||||||
rtc::WeakPtrFactory<VideoSendStreamImpl> weak_ptr_factory_;
|
rtc::WeakPtrFactory<VideoSendStreamImpl> weak_ptr_factory_;
|
||||||
|
|
||||||
rtc::CriticalSection overhead_bytes_per_packet_crit_;
|
|
||||||
size_t overhead_bytes_per_packet_
|
|
||||||
RTC_GUARDED_BY(overhead_bytes_per_packet_crit_);
|
|
||||||
size_t transport_overhead_bytes_per_packet_;
|
|
||||||
|
|
||||||
std::unordered_set<uint16_t> feedback_packet_seq_num_set_;
|
|
||||||
std::vector<bool> loss_mask_vector_;
|
|
||||||
|
|
||||||
// Context for the most recent and last sent video bitrate allocation. Used to
|
// Context for the most recent and last sent video bitrate allocation. Used to
|
||||||
// throttle sending of similar bitrate allocations.
|
// throttle sending of similar bitrate allocations.
|
||||||
struct VbaSendContext {
|
struct VbaSendContext {
|
||||||
|
|||||||
@ -45,7 +45,7 @@ std::string GetAlrProbingExperimentString() {
|
|||||||
AlrExperimentSettings::kScreenshareProbingBweExperimentName) +
|
AlrExperimentSettings::kScreenshareProbingBweExperimentName) +
|
||||||
"/1.0,2875,80,40,-60,3/";
|
"/1.0,2875,80,40,-60,3/";
|
||||||
}
|
}
|
||||||
class MockPayloadRouter : public RtpVideoSenderInterface {
|
class MockRtpVideoSender : public RtpVideoSenderInterface {
|
||||||
public:
|
public:
|
||||||
MOCK_METHOD1(RegisterProcessThread, void(ProcessThread*));
|
MOCK_METHOD1(RegisterProcessThread, void(ProcessThread*));
|
||||||
MOCK_METHOD0(DeRegisterProcessThread, void());
|
MOCK_METHOD0(DeRegisterProcessThread, void());
|
||||||
@ -56,21 +56,18 @@ class MockPayloadRouter : public RtpVideoSenderInterface {
|
|||||||
MOCK_CONST_METHOD0(GetRtpStates, std::map<uint32_t, RtpState>());
|
MOCK_CONST_METHOD0(GetRtpStates, std::map<uint32_t, RtpState>());
|
||||||
MOCK_CONST_METHOD0(GetRtpPayloadStates,
|
MOCK_CONST_METHOD0(GetRtpPayloadStates,
|
||||||
std::map<uint32_t, RtpPayloadState>());
|
std::map<uint32_t, RtpPayloadState>());
|
||||||
MOCK_CONST_METHOD0(FecEnabled, bool());
|
|
||||||
MOCK_CONST_METHOD0(NackEnabled, bool());
|
|
||||||
MOCK_METHOD2(DeliverRtcp, void(const uint8_t*, size_t));
|
MOCK_METHOD2(DeliverRtcp, void(const uint8_t*, size_t));
|
||||||
MOCK_METHOD5(ProtectionRequest,
|
|
||||||
void(const FecProtectionParams*,
|
|
||||||
const FecProtectionParams*,
|
|
||||||
uint32_t*,
|
|
||||||
uint32_t*,
|
|
||||||
uint32_t*));
|
|
||||||
MOCK_METHOD1(SetMaxRtpPacketSize, void(size_t));
|
|
||||||
MOCK_METHOD1(OnBitrateAllocationUpdated, void(const VideoBitrateAllocation&));
|
MOCK_METHOD1(OnBitrateAllocationUpdated, void(const VideoBitrateAllocation&));
|
||||||
MOCK_METHOD3(OnEncodedImage,
|
MOCK_METHOD3(OnEncodedImage,
|
||||||
EncodedImageCallback::Result(const EncodedImage&,
|
EncodedImageCallback::Result(const EncodedImage&,
|
||||||
const CodecSpecificInfo*,
|
const CodecSpecificInfo*,
|
||||||
const RTPFragmentationHeader*));
|
const RTPFragmentationHeader*));
|
||||||
|
MOCK_METHOD1(OnTransportOverheadChanged, void(size_t));
|
||||||
|
MOCK_METHOD1(OnOverheadChanged, void(size_t));
|
||||||
|
MOCK_METHOD4(OnBitrateUpdated, void(uint32_t, uint8_t, int64_t, int));
|
||||||
|
MOCK_CONST_METHOD0(GetPayloadBitrateBps, uint32_t());
|
||||||
|
MOCK_CONST_METHOD0(GetProtectionBitrateBps, uint32_t());
|
||||||
|
MOCK_METHOD3(SetEncodingData, void(size_t, size_t, size_t));
|
||||||
};
|
};
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
@ -94,14 +91,14 @@ class VideoSendStreamImplTest : public ::testing::Test {
|
|||||||
EXPECT_CALL(transport_controller_, packet_router())
|
EXPECT_CALL(transport_controller_, packet_router())
|
||||||
.WillRepeatedly(Return(&packet_router_));
|
.WillRepeatedly(Return(&packet_router_));
|
||||||
EXPECT_CALL(transport_controller_,
|
EXPECT_CALL(transport_controller_,
|
||||||
CreateRtpVideoSender(_, _, _, _, _, _, _, _))
|
CreateRtpVideoSender(_, _, _, _, _, _, _, _, _))
|
||||||
.WillRepeatedly(Return(&payload_router_));
|
.WillRepeatedly(Return(&rtp_video_sender_));
|
||||||
EXPECT_CALL(payload_router_, SetActive(_))
|
EXPECT_CALL(rtp_video_sender_, SetActive(_))
|
||||||
.WillRepeatedly(testing::Invoke(
|
.WillRepeatedly(testing::Invoke(
|
||||||
[&](bool active) { payload_router_active_ = active; }));
|
[&](bool active) { rtp_video_sender_active_ = active; }));
|
||||||
EXPECT_CALL(payload_router_, IsActive())
|
EXPECT_CALL(rtp_video_sender_, IsActive())
|
||||||
.WillRepeatedly(
|
.WillRepeatedly(
|
||||||
testing::Invoke([&]() { return payload_router_active_; }));
|
testing::Invoke([&]() { return rtp_video_sender_active_; }));
|
||||||
}
|
}
|
||||||
~VideoSendStreamImplTest() {}
|
~VideoSendStreamImplTest() {}
|
||||||
|
|
||||||
@ -127,9 +124,9 @@ class VideoSendStreamImplTest : public ::testing::Test {
|
|||||||
NiceMock<MockRtpTransportControllerSend> transport_controller_;
|
NiceMock<MockRtpTransportControllerSend> transport_controller_;
|
||||||
NiceMock<MockBitrateAllocator> bitrate_allocator_;
|
NiceMock<MockBitrateAllocator> bitrate_allocator_;
|
||||||
NiceMock<MockVideoStreamEncoder> video_stream_encoder_;
|
NiceMock<MockVideoStreamEncoder> video_stream_encoder_;
|
||||||
NiceMock<MockPayloadRouter> payload_router_;
|
NiceMock<MockRtpVideoSender> rtp_video_sender_;
|
||||||
|
|
||||||
bool payload_router_active_ = false;
|
bool rtp_video_sender_active_ = false;
|
||||||
SimulatedClock clock_;
|
SimulatedClock clock_;
|
||||||
RtcEventLogNullImpl event_log_;
|
RtcEventLogNullImpl event_log_;
|
||||||
VideoSendStream::Config config_;
|
VideoSendStream::Config config_;
|
||||||
@ -361,19 +358,26 @@ TEST_F(VideoSendStreamImplTest, ForwardsVideoBitrateAllocationWhenEnabled) {
|
|||||||
alloc.SetBitrate(1, 1, 40000);
|
alloc.SetBitrate(1, 1, 40000);
|
||||||
|
|
||||||
// Encoder starts out paused, don't forward allocation.
|
// Encoder starts out paused, don't forward allocation.
|
||||||
EXPECT_CALL(payload_router_, OnBitrateAllocationUpdated(alloc)).Times(0);
|
EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc)).Times(0);
|
||||||
observer->OnBitrateAllocationUpdated(alloc);
|
observer->OnBitrateAllocationUpdated(alloc);
|
||||||
|
|
||||||
// Unpause encoder, allocation should be passed through.
|
// Unpause encoder, allocation should be passed through.
|
||||||
|
const uint32_t kBitrateBps = 100000;
|
||||||
|
EXPECT_CALL(rtp_video_sender_, GetPayloadBitrateBps())
|
||||||
|
.Times(1)
|
||||||
|
.WillOnce(Return(kBitrateBps));
|
||||||
static_cast<BitrateAllocatorObserver*>(vss_impl.get())
|
static_cast<BitrateAllocatorObserver*>(vss_impl.get())
|
||||||
->OnBitrateUpdated(100000, 0, 0, 0);
|
->OnBitrateUpdated(kBitrateBps, 0, 0, 0);
|
||||||
EXPECT_CALL(payload_router_, OnBitrateAllocationUpdated(alloc)).Times(1);
|
EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc)).Times(1);
|
||||||
observer->OnBitrateAllocationUpdated(alloc);
|
observer->OnBitrateAllocationUpdated(alloc);
|
||||||
|
|
||||||
// Pause encoder again, and block allocations.
|
// Pause encoder again, and block allocations.
|
||||||
|
EXPECT_CALL(rtp_video_sender_, GetPayloadBitrateBps())
|
||||||
|
.Times(1)
|
||||||
|
.WillOnce(Return(0));
|
||||||
static_cast<BitrateAllocatorObserver*>(vss_impl.get())
|
static_cast<BitrateAllocatorObserver*>(vss_impl.get())
|
||||||
->OnBitrateUpdated(0, 0, 0, 0);
|
->OnBitrateUpdated(0, 0, 0, 0);
|
||||||
EXPECT_CALL(payload_router_, OnBitrateAllocationUpdated(alloc)).Times(0);
|
EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc)).Times(0);
|
||||||
observer->OnBitrateAllocationUpdated(alloc);
|
observer->OnBitrateAllocationUpdated(alloc);
|
||||||
|
|
||||||
vss_impl->Stop();
|
vss_impl->Stop();
|
||||||
@ -387,8 +391,12 @@ TEST_F(VideoSendStreamImplTest, ThrottlesVideoBitrateAllocationWhenTooSimilar) {
|
|||||||
VideoEncoderConfig::ContentType::kScreen);
|
VideoEncoderConfig::ContentType::kScreen);
|
||||||
vss_impl->Start();
|
vss_impl->Start();
|
||||||
// Unpause encoder, to allows allocations to be passed through.
|
// Unpause encoder, to allows allocations to be passed through.
|
||||||
|
const uint32_t kBitrateBps = 100000;
|
||||||
|
EXPECT_CALL(rtp_video_sender_, GetPayloadBitrateBps())
|
||||||
|
.Times(1)
|
||||||
|
.WillOnce(Return(kBitrateBps));
|
||||||
static_cast<BitrateAllocatorObserver*>(vss_impl.get())
|
static_cast<BitrateAllocatorObserver*>(vss_impl.get())
|
||||||
->OnBitrateUpdated(100000, 0, 0, 0);
|
->OnBitrateUpdated(kBitrateBps, 0, 0, 0);
|
||||||
VideoBitrateAllocationObserver* const observer =
|
VideoBitrateAllocationObserver* const observer =
|
||||||
static_cast<VideoBitrateAllocationObserver*>(vss_impl.get());
|
static_cast<VideoBitrateAllocationObserver*>(vss_impl.get());
|
||||||
|
|
||||||
@ -400,7 +408,7 @@ TEST_F(VideoSendStreamImplTest, ThrottlesVideoBitrateAllocationWhenTooSimilar) {
|
|||||||
alloc.SetBitrate(1, 1, 40000);
|
alloc.SetBitrate(1, 1, 40000);
|
||||||
|
|
||||||
// Initial value.
|
// Initial value.
|
||||||
EXPECT_CALL(payload_router_, OnBitrateAllocationUpdated(alloc)).Times(1);
|
EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc)).Times(1);
|
||||||
observer->OnBitrateAllocationUpdated(alloc);
|
observer->OnBitrateAllocationUpdated(alloc);
|
||||||
|
|
||||||
VideoBitrateAllocation updated_alloc = alloc;
|
VideoBitrateAllocation updated_alloc = alloc;
|
||||||
@ -410,19 +418,19 @@ TEST_F(VideoSendStreamImplTest, ThrottlesVideoBitrateAllocationWhenTooSimilar) {
|
|||||||
|
|
||||||
// Too small increase, don't forward.
|
// Too small increase, don't forward.
|
||||||
updated_alloc.SetBitrate(0, 0, base_layer_min_update_bitrate_bps - 1);
|
updated_alloc.SetBitrate(0, 0, base_layer_min_update_bitrate_bps - 1);
|
||||||
EXPECT_CALL(payload_router_, OnBitrateAllocationUpdated(_)).Times(0);
|
EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(_)).Times(0);
|
||||||
observer->OnBitrateAllocationUpdated(updated_alloc);
|
observer->OnBitrateAllocationUpdated(updated_alloc);
|
||||||
|
|
||||||
// Large enough increase, do forward.
|
// Large enough increase, do forward.
|
||||||
updated_alloc.SetBitrate(0, 0, base_layer_min_update_bitrate_bps);
|
updated_alloc.SetBitrate(0, 0, base_layer_min_update_bitrate_bps);
|
||||||
EXPECT_CALL(payload_router_, OnBitrateAllocationUpdated(updated_alloc))
|
EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(updated_alloc))
|
||||||
.Times(1);
|
.Times(1);
|
||||||
observer->OnBitrateAllocationUpdated(updated_alloc);
|
observer->OnBitrateAllocationUpdated(updated_alloc);
|
||||||
|
|
||||||
// This is now a decrease compared to last forward allocation, forward
|
// This is now a decrease compared to last forward allocation, forward
|
||||||
// immediately.
|
// immediately.
|
||||||
updated_alloc.SetBitrate(0, 0, base_layer_min_update_bitrate_bps - 1);
|
updated_alloc.SetBitrate(0, 0, base_layer_min_update_bitrate_bps - 1);
|
||||||
EXPECT_CALL(payload_router_, OnBitrateAllocationUpdated(updated_alloc))
|
EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(updated_alloc))
|
||||||
.Times(1);
|
.Times(1);
|
||||||
observer->OnBitrateAllocationUpdated(updated_alloc);
|
observer->OnBitrateAllocationUpdated(updated_alloc);
|
||||||
|
|
||||||
@ -437,8 +445,12 @@ TEST_F(VideoSendStreamImplTest, ForwardsVideoBitrateAllocationOnLayerChange) {
|
|||||||
VideoEncoderConfig::ContentType::kScreen);
|
VideoEncoderConfig::ContentType::kScreen);
|
||||||
vss_impl->Start();
|
vss_impl->Start();
|
||||||
// Unpause encoder, to allows allocations to be passed through.
|
// Unpause encoder, to allows allocations to be passed through.
|
||||||
|
const uint32_t kBitrateBps = 100000;
|
||||||
|
EXPECT_CALL(rtp_video_sender_, GetPayloadBitrateBps())
|
||||||
|
.Times(1)
|
||||||
|
.WillOnce(Return(kBitrateBps));
|
||||||
static_cast<BitrateAllocatorObserver*>(vss_impl.get())
|
static_cast<BitrateAllocatorObserver*>(vss_impl.get())
|
||||||
->OnBitrateUpdated(100000, 0, 0, 0);
|
->OnBitrateUpdated(kBitrateBps, 0, 0, 0);
|
||||||
VideoBitrateAllocationObserver* const observer =
|
VideoBitrateAllocationObserver* const observer =
|
||||||
static_cast<VideoBitrateAllocationObserver*>(vss_impl.get());
|
static_cast<VideoBitrateAllocationObserver*>(vss_impl.get());
|
||||||
|
|
||||||
@ -450,7 +462,7 @@ TEST_F(VideoSendStreamImplTest, ForwardsVideoBitrateAllocationOnLayerChange) {
|
|||||||
alloc.SetBitrate(1, 1, 40000);
|
alloc.SetBitrate(1, 1, 40000);
|
||||||
|
|
||||||
// Initial value.
|
// Initial value.
|
||||||
EXPECT_CALL(payload_router_, OnBitrateAllocationUpdated(alloc)).Times(1);
|
EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc)).Times(1);
|
||||||
observer->OnBitrateAllocationUpdated(alloc);
|
observer->OnBitrateAllocationUpdated(alloc);
|
||||||
|
|
||||||
// Move some bitrate from one layer to a new one, but keep sum the same.
|
// Move some bitrate from one layer to a new one, but keep sum the same.
|
||||||
@ -459,7 +471,7 @@ TEST_F(VideoSendStreamImplTest, ForwardsVideoBitrateAllocationOnLayerChange) {
|
|||||||
updated_alloc.SetBitrate(2, 0, 10000);
|
updated_alloc.SetBitrate(2, 0, 10000);
|
||||||
updated_alloc.SetBitrate(1, 1, alloc.GetBitrate(1, 1) - 10000);
|
updated_alloc.SetBitrate(1, 1, alloc.GetBitrate(1, 1) - 10000);
|
||||||
EXPECT_EQ(alloc.get_sum_bps(), updated_alloc.get_sum_bps());
|
EXPECT_EQ(alloc.get_sum_bps(), updated_alloc.get_sum_bps());
|
||||||
EXPECT_CALL(payload_router_, OnBitrateAllocationUpdated(updated_alloc))
|
EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(updated_alloc))
|
||||||
.Times(1);
|
.Times(1);
|
||||||
observer->OnBitrateAllocationUpdated(updated_alloc);
|
observer->OnBitrateAllocationUpdated(updated_alloc);
|
||||||
|
|
||||||
@ -476,9 +488,13 @@ TEST_F(VideoSendStreamImplTest, ForwardsVideoBitrateAllocationAfterTimeout) {
|
|||||||
kDefaultInitialBitrateBps, kDefaultBitratePriority,
|
kDefaultInitialBitrateBps, kDefaultBitratePriority,
|
||||||
VideoEncoderConfig::ContentType::kScreen);
|
VideoEncoderConfig::ContentType::kScreen);
|
||||||
vss_impl->Start();
|
vss_impl->Start();
|
||||||
|
const uint32_t kBitrateBps = 100000;
|
||||||
// Unpause encoder, to allows allocations to be passed through.
|
// Unpause encoder, to allows allocations to be passed through.
|
||||||
|
EXPECT_CALL(rtp_video_sender_, GetPayloadBitrateBps())
|
||||||
|
.Times(1)
|
||||||
|
.WillRepeatedly(Return(kBitrateBps));
|
||||||
static_cast<BitrateAllocatorObserver*>(vss_impl.get())
|
static_cast<BitrateAllocatorObserver*>(vss_impl.get())
|
||||||
->OnBitrateUpdated(100000, 0, 0, 0);
|
->OnBitrateUpdated(kBitrateBps, 0, 0, 0);
|
||||||
VideoBitrateAllocationObserver* const observer =
|
VideoBitrateAllocationObserver* const observer =
|
||||||
static_cast<VideoBitrateAllocationObserver*>(vss_impl.get());
|
static_cast<VideoBitrateAllocationObserver*>(vss_impl.get());
|
||||||
|
|
||||||
@ -491,7 +507,7 @@ TEST_F(VideoSendStreamImplTest, ForwardsVideoBitrateAllocationAfterTimeout) {
|
|||||||
|
|
||||||
EncodedImage encoded_image;
|
EncodedImage encoded_image;
|
||||||
CodecSpecificInfo codec_specific;
|
CodecSpecificInfo codec_specific;
|
||||||
EXPECT_CALL(payload_router_, OnEncodedImage(_, _, _))
|
EXPECT_CALL(rtp_video_sender_, OnEncodedImage(_, _, _))
|
||||||
.WillRepeatedly(Return(
|
.WillRepeatedly(Return(
|
||||||
EncodedImageCallback::Result(EncodedImageCallback::Result::OK)));
|
EncodedImageCallback::Result(EncodedImageCallback::Result::OK)));
|
||||||
|
|
||||||
@ -500,13 +516,15 @@ TEST_F(VideoSendStreamImplTest, ForwardsVideoBitrateAllocationAfterTimeout) {
|
|||||||
|
|
||||||
{
|
{
|
||||||
// Initial value.
|
// Initial value.
|
||||||
EXPECT_CALL(payload_router_, OnBitrateAllocationUpdated(alloc)).Times(1);
|
EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc))
|
||||||
|
.Times(1);
|
||||||
observer->OnBitrateAllocationUpdated(alloc);
|
observer->OnBitrateAllocationUpdated(alloc);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
// Sending same allocation again, this one should be throttled.
|
// Sending same allocation again, this one should be throttled.
|
||||||
EXPECT_CALL(payload_router_, OnBitrateAllocationUpdated(alloc)).Times(0);
|
EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc))
|
||||||
|
.Times(0);
|
||||||
observer->OnBitrateAllocationUpdated(alloc);
|
observer->OnBitrateAllocationUpdated(alloc);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -514,19 +532,22 @@ TEST_F(VideoSendStreamImplTest, ForwardsVideoBitrateAllocationAfterTimeout) {
|
|||||||
|
|
||||||
{
|
{
|
||||||
// Sending similar allocation again after timeout, should forward.
|
// Sending similar allocation again after timeout, should forward.
|
||||||
EXPECT_CALL(payload_router_, OnBitrateAllocationUpdated(alloc)).Times(1);
|
EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc))
|
||||||
|
.Times(1);
|
||||||
observer->OnBitrateAllocationUpdated(alloc);
|
observer->OnBitrateAllocationUpdated(alloc);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
// Sending similar allocation again without timeout, throttle.
|
// Sending similar allocation again without timeout, throttle.
|
||||||
EXPECT_CALL(payload_router_, OnBitrateAllocationUpdated(alloc)).Times(0);
|
EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc))
|
||||||
|
.Times(0);
|
||||||
observer->OnBitrateAllocationUpdated(alloc);
|
observer->OnBitrateAllocationUpdated(alloc);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
// Send encoded image, should be a noop.
|
// Send encoded image, should be a noop.
|
||||||
EXPECT_CALL(payload_router_, OnBitrateAllocationUpdated(alloc)).Times(0);
|
EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc))
|
||||||
|
.Times(0);
|
||||||
static_cast<EncodedImageCallback*>(vss_impl.get())
|
static_cast<EncodedImageCallback*>(vss_impl.get())
|
||||||
->OnEncodedImage(encoded_image, &codec_specific, nullptr);
|
->OnEncodedImage(encoded_image, &codec_specific, nullptr);
|
||||||
}
|
}
|
||||||
@ -535,7 +556,8 @@ TEST_F(VideoSendStreamImplTest, ForwardsVideoBitrateAllocationAfterTimeout) {
|
|||||||
// Advance time and send encoded image, this should wake up and send
|
// Advance time and send encoded image, this should wake up and send
|
||||||
// cached bitrate allocation.
|
// cached bitrate allocation.
|
||||||
fake_clock.AdvanceTimeMicros(kMaxVbaThrottleTimeMs * 1000);
|
fake_clock.AdvanceTimeMicros(kMaxVbaThrottleTimeMs * 1000);
|
||||||
EXPECT_CALL(payload_router_, OnBitrateAllocationUpdated(alloc)).Times(1);
|
EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc))
|
||||||
|
.Times(1);
|
||||||
static_cast<EncodedImageCallback*>(vss_impl.get())
|
static_cast<EncodedImageCallback*>(vss_impl.get())
|
||||||
->OnEncodedImage(encoded_image, &codec_specific, nullptr);
|
->OnEncodedImage(encoded_image, &codec_specific, nullptr);
|
||||||
}
|
}
|
||||||
@ -544,7 +566,8 @@ TEST_F(VideoSendStreamImplTest, ForwardsVideoBitrateAllocationAfterTimeout) {
|
|||||||
// Advance time and send encoded image, there should be no cached
|
// Advance time and send encoded image, there should be no cached
|
||||||
// allocation to send.
|
// allocation to send.
|
||||||
fake_clock.AdvanceTimeMicros(kMaxVbaThrottleTimeMs * 1000);
|
fake_clock.AdvanceTimeMicros(kMaxVbaThrottleTimeMs * 1000);
|
||||||
EXPECT_CALL(payload_router_, OnBitrateAllocationUpdated(alloc)).Times(0);
|
EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc))
|
||||||
|
.Times(0);
|
||||||
static_cast<EncodedImageCallback*>(vss_impl.get())
|
static_cast<EncodedImageCallback*>(vss_impl.get())
|
||||||
->OnEncodedImage(encoded_image, &codec_specific, nullptr);
|
->OnEncodedImage(encoded_image, &codec_specific, nullptr);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1734,7 +1734,7 @@ TEST_P(VideoSendStreamTest, ChangingTransportOverhead) {
|
|||||||
void PerformTest() override {
|
void PerformTest() override {
|
||||||
task_queue_->SendTask([this]() {
|
task_queue_->SendTask([this]() {
|
||||||
transport_overhead_ = 100;
|
transport_overhead_ = 100;
|
||||||
call_->OnTransportOverheadChanged(webrtc::MediaType::VIDEO,
|
call_->GetTransportControllerSend()->OnTransportOverheadChanged(
|
||||||
transport_overhead_);
|
transport_overhead_);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -1747,7 +1747,7 @@ TEST_P(VideoSendStreamTest, ChangingTransportOverhead) {
|
|||||||
|
|
||||||
task_queue_->SendTask([this]() {
|
task_queue_->SendTask([this]() {
|
||||||
transport_overhead_ = 500;
|
transport_overhead_ = 500;
|
||||||
call_->OnTransportOverheadChanged(webrtc::MediaType::VIDEO,
|
call_->GetTransportControllerSend()->OnTransportOverheadChanged(
|
||||||
transport_overhead_);
|
transport_overhead_);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -3725,7 +3725,7 @@ TEST_P(VideoSendStreamTest, RemoveOverheadFromBandwidth) {
|
|||||||
task_queue_->SendTask([this, &bitrate_config]() {
|
task_queue_->SendTask([this, &bitrate_config]() {
|
||||||
call_->GetTransportControllerSend()->SetSdpBitrateParameters(
|
call_->GetTransportControllerSend()->SetSdpBitrateParameters(
|
||||||
bitrate_config);
|
bitrate_config);
|
||||||
call_->OnTransportOverheadChanged(webrtc::MediaType::VIDEO, 40);
|
call_->GetTransportControllerSend()->OnTransportOverheadChanged(40);
|
||||||
});
|
});
|
||||||
|
|
||||||
// At a bitrate of 60kbps with a packet size of 1200B video and an
|
// At a bitrate of 60kbps with a packet size of 1200B video and an
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user