Move Ownership of RtpModules to VideoSendStream from VieChannel and remove use of vie_channel and vie_receiver from video_send_stream.
The purpose of this refactoring is a first step of separating the encoder parts from the RTP transport.
BUG=webrtc:5687
R=mflodman@webrtc.org, pbos@webrtc.org, stefan@webrtc.org
Review URL: https://codereview.webrtc.org/1864313003 .
Cr-Original-Commit-Position: refs/heads/master@{#12377}
Cr-Mirrored-From: https://chromium.googlesource.com/external/webrtc
Cr-Mirrored-Commit: 83d09106943b3b70d9aaa92bc674fae473443f89
diff --git a/modules/rtp_rtcp/include/rtp_rtcp.h b/modules/rtp_rtcp/include/rtp_rtcp.h
index d01465b..50fb35e 100644
--- a/modules/rtp_rtcp/include/rtp_rtcp.h
+++ b/modules/rtp_rtcp/include/rtp_rtcp.h
@@ -210,10 +210,10 @@
*/
virtual void SetSequenceNumber(uint16_t seq) = 0;
- // Returns true if the ssrc matched this module, false otherwise.
- virtual bool SetRtpStateForSsrc(uint32_t ssrc,
- const RtpState& rtp_state) = 0;
- virtual bool GetRtpStateForSsrc(uint32_t ssrc, RtpState* rtp_state) = 0;
+ virtual void SetRtpState(const RtpState& rtp_state) = 0;
+ virtual void SetRtxState(const RtpState& rtp_state) = 0;
+ virtual RtpState GetRtpState() const = 0;
+ virtual RtpState GetRtxState() const = 0;
/*
* Get SSRC
diff --git a/modules/rtp_rtcp/mocks/mock_rtp_rtcp.h b/modules/rtp_rtcp/mocks/mock_rtp_rtcp.h
index 9991aa2..4cbb042 100644
--- a/modules/rtp_rtcp/mocks/mock_rtp_rtcp.h
+++ b/modules/rtp_rtcp/mocks/mock_rtp_rtcp.h
@@ -85,12 +85,12 @@
MOCK_CONST_METHOD0(StartTimestamp,
uint32_t());
MOCK_METHOD1(SetStartTimestamp, void(const uint32_t timestamp));
- MOCK_CONST_METHOD0(SequenceNumber,
- uint16_t());
+ MOCK_CONST_METHOD0(SequenceNumber, uint16_t());
MOCK_METHOD1(SetSequenceNumber, void(const uint16_t seq));
- MOCK_METHOD2(SetRtpStateForSsrc,
- bool(uint32_t ssrc, const RtpState& rtp_state));
- MOCK_METHOD2(GetRtpStateForSsrc, bool(uint32_t ssrc, RtpState* rtp_state));
+ MOCK_METHOD1(SetRtpState, void(const RtpState& rtp_state));
+ MOCK_METHOD1(SetRtxState, void(const RtpState& rtp_state));
+ MOCK_CONST_METHOD0(GetRtpState, RtpState());
+ MOCK_CONST_METHOD0(GetRtxState, RtpState());
MOCK_CONST_METHOD0(SSRC,
uint32_t());
MOCK_METHOD1(SetSSRC,
diff --git a/modules/rtp_rtcp/source/rtcp_sender.cc b/modules/rtp_rtcp/source/rtcp_sender.cc
index 95bfeee..7579a36 100644
--- a/modules/rtp_rtcp/source/rtcp_sender.cc
+++ b/modules/rtp_rtcp/source/rtcp_sender.cc
@@ -871,11 +871,13 @@
random_.Rand(minIntervalMs * 1 / 2, minIntervalMs * 3 / 2);
next_time_to_send_rtcp_ = clock_->TimeInMilliseconds() + timeToNext;
- StatisticianMap statisticians =
- receive_statistics_->GetActiveStatisticians();
- RTC_DCHECK(report_blocks_.empty());
- for (auto& it : statisticians) {
- AddReportBlock(feedback_state, it.first, it.second);
+ if (receive_statistics_) {
+ StatisticianMap statisticians =
+ receive_statistics_->GetActiveStatisticians();
+ RTC_DCHECK(report_blocks_.empty());
+ for (auto& it : statisticians) {
+ AddReportBlock(feedback_state, it.first, it.second);
+ }
}
}
}
diff --git a/modules/rtp_rtcp/source/rtp_rtcp_impl.cc b/modules/rtp_rtcp/source/rtp_rtcp_impl.cc
index 64f64d8..ec767d8 100644
--- a/modules/rtp_rtcp/source/rtp_rtcp_impl.cc
+++ b/modules/rtp_rtcp/source/rtp_rtcp_impl.cc
@@ -300,30 +300,21 @@
rtp_sender_.SetSequenceNumber(seq_num);
}
-bool ModuleRtpRtcpImpl::SetRtpStateForSsrc(uint32_t ssrc,
- const RtpState& rtp_state) {
- if (rtp_sender_.SSRC() == ssrc) {
- SetStartTimestamp(rtp_state.start_timestamp);
- rtp_sender_.SetRtpState(rtp_state);
- return true;
- }
- if (rtp_sender_.RtxSsrc() == ssrc) {
- rtp_sender_.SetRtxRtpState(rtp_state);
- return true;
- }
- return false;
+void ModuleRtpRtcpImpl::SetRtpState(const RtpState& rtp_state) {
+ SetStartTimestamp(rtp_state.start_timestamp);
+ rtp_sender_.SetRtpState(rtp_state);
}
-bool ModuleRtpRtcpImpl::GetRtpStateForSsrc(uint32_t ssrc, RtpState* rtp_state) {
- if (rtp_sender_.SSRC() == ssrc) {
- *rtp_state = rtp_sender_.GetRtpState();
- return true;
- }
- if (rtp_sender_.RtxSsrc() == ssrc) {
- *rtp_state = rtp_sender_.GetRtxRtpState();
- return true;
- }
- return false;
+void ModuleRtpRtcpImpl::SetRtxState(const RtpState& rtp_state) {
+ rtp_sender_.SetRtxRtpState(rtp_state);
+}
+
+RtpState ModuleRtpRtcpImpl::GetRtpState() const {
+ return rtp_sender_.GetRtpState();
+}
+
+RtpState ModuleRtpRtcpImpl::GetRtxState() const {
+ return rtp_sender_.GetRtxRtpState();
}
uint32_t ModuleRtpRtcpImpl::SSRC() const {
diff --git a/modules/rtp_rtcp/source/rtp_rtcp_impl.h b/modules/rtp_rtcp/source/rtp_rtcp_impl.h
index ec8e84a..997a19b 100644
--- a/modules/rtp_rtcp/source/rtp_rtcp_impl.h
+++ b/modules/rtp_rtcp/source/rtp_rtcp_impl.h
@@ -75,8 +75,10 @@
// Set SequenceNumber, default is a random number.
void SetSequenceNumber(uint16_t seq) override;
- bool SetRtpStateForSsrc(uint32_t ssrc, const RtpState& rtp_state) override;
- bool GetRtpStateForSsrc(uint32_t ssrc, RtpState* rtp_state) override;
+ void SetRtpState(const RtpState& rtp_state) override;
+ void SetRtxState(const RtpState& rtp_state) override;
+ RtpState GetRtpState() const override;
+ RtpState GetRtxState() const override;
uint32_t SSRC() const override;
diff --git a/video/encoder_state_feedback.cc b/video/encoder_state_feedback.cc
index 0240e48..52f5111 100644
--- a/video/encoder_state_feedback.cc
+++ b/video/encoder_state_feedback.cc
@@ -25,13 +25,6 @@
vie_encoder_ = encoder;
}
-void EncoderStateFeedback::TearDown() {
- rtc::CritScope lock(&crit_);
- RTC_DCHECK(vie_encoder_);
- ssrcs_.clear();
- vie_encoder_ = nullptr;
-}
-
bool EncoderStateFeedback::HasSsrc(uint32_t ssrc) {
for (uint32_t registered_ssrc : ssrcs_) {
if (registered_ssrc == ssrc)
diff --git a/video/encoder_state_feedback.h b/video/encoder_state_feedback.h
index 6326bed..57595a0 100644
--- a/video/encoder_state_feedback.h
+++ b/video/encoder_state_feedback.h
@@ -31,12 +31,6 @@
// Adds an encoder to receive feedback for a set of SSRCs.
void Init(const std::vector<uint32_t>& ssrc, ViEEncoder* encoder);
- // Removes the registered encoder. Necessary since RTP modules outlive
- // ViEEncoder.
- // TODO(pbos): Make sure RTP modules are not running when tearing down
- // ViEEncoder, then remove this function.
- void TearDown();
-
void OnReceivedIntraFrameRequest(uint32_t ssrc) override;
void OnReceivedSLI(uint32_t ssrc, uint8_t picture_id) override;
void OnReceivedRPSI(uint32_t ssrc, uint64_t picture_id) override;
diff --git a/video/payload_router.cc b/video/payload_router.cc
index 968d82d..d466e41 100644
--- a/video/payload_router.cc
+++ b/video/payload_router.cc
@@ -16,8 +16,10 @@
namespace webrtc {
-PayloadRouter::PayloadRouter()
- : active_(false), num_sending_modules_(0) {}
+PayloadRouter::PayloadRouter(const std::vector<RtpRtcp*>& rtp_modules)
+ : active_(false), num_sending_modules_(1), rtp_modules_(rtp_modules) {
+ UpdateModuleSendingState();
+}
PayloadRouter::~PayloadRouter() {}
@@ -26,12 +28,6 @@
return IP_PACKET_SIZE - kIpUdpSrtpLength;
}
-void PayloadRouter::Init(
- const std::vector<RtpRtcp*>& rtp_modules) {
- RTC_DCHECK(rtp_modules_.empty());
- rtp_modules_ = rtp_modules;
-}
-
void PayloadRouter::set_active(bool active) {
rtc::CritScope lock(&crit_);
if (active_ == active)
diff --git a/video/payload_router.h b/video/payload_router.h
index 9eaf716..81ec0dd 100644
--- a/video/payload_router.h
+++ b/video/payload_router.h
@@ -29,14 +29,11 @@
// on the simulcast layer in RTPVideoHeader.
class PayloadRouter {
public:
- PayloadRouter();
+ // Rtp modules are assumed to be sorted in simulcast index order.
+ explicit PayloadRouter(const std::vector<RtpRtcp*>& rtp_modules);
~PayloadRouter();
static size_t DefaultMaxPayloadLength();
-
- // Rtp modules are assumed to be sorted in simulcast index order.
- void Init(const std::vector<RtpRtcp*>& rtp_modules);
-
void SetSendingRtpModules(size_t num_sending_modules);
// PayloadRouter will only route packets if being active, all packets will be
@@ -66,13 +63,13 @@
private:
void UpdateModuleSendingState() EXCLUSIVE_LOCKS_REQUIRED(crit_);
- // TODO(pbos): Set once and for all on construction and make const.
- std::vector<RtpRtcp*> rtp_modules_;
-
rtc::CriticalSection crit_;
bool active_ GUARDED_BY(crit_);
size_t num_sending_modules_ GUARDED_BY(crit_);
+ // Rtp modules are assumed to be sorted in simulcast index order. Not owned.
+ const std::vector<RtpRtcp*> rtp_modules_;
+
RTC_DISALLOW_COPY_AND_ASSIGN(PayloadRouter);
};
diff --git a/video/payload_router_unittest.cc b/video/payload_router_unittest.cc
index 5b3dc93..c5d3f38 100644
--- a/video/payload_router_unittest.cc
+++ b/video/payload_router_unittest.cc
@@ -23,20 +23,12 @@
namespace webrtc {
-class PayloadRouterTest : public ::testing::Test {
- protected:
- virtual void SetUp() {
- payload_router_.reset(new PayloadRouter());
- }
- std::unique_ptr<PayloadRouter> payload_router_;
-};
-
-TEST_F(PayloadRouterTest, SendOnOneModule) {
+TEST(PayloadRouterTest, SendOnOneModule) {
MockRtpRtcp rtp;
std::vector<RtpRtcp*> modules(1, &rtp);
- payload_router_->Init(modules);
- payload_router_->SetSendingRtpModules(modules.size());
+ PayloadRouter payload_router(modules);
+ payload_router.SetSendingRtpModules(modules.size());
uint8_t payload = 'a';
FrameType frame_type = kVideoFrameKey;
@@ -45,47 +37,47 @@
EXPECT_CALL(rtp, SendOutgoingData(frame_type, payload_type, 0, 0, _, 1,
nullptr, nullptr))
.Times(0);
- EXPECT_FALSE(payload_router_->RoutePayload(frame_type, payload_type, 0, 0,
- &payload, 1, nullptr, nullptr));
+ EXPECT_FALSE(payload_router.RoutePayload(frame_type, payload_type, 0, 0,
+ &payload, 1, nullptr, nullptr));
- payload_router_->set_active(true);
+ payload_router.set_active(true);
EXPECT_CALL(rtp, SendOutgoingData(frame_type, payload_type, 0, 0, _, 1,
nullptr, nullptr))
.Times(1);
- EXPECT_TRUE(payload_router_->RoutePayload(frame_type, payload_type, 0, 0,
- &payload, 1, nullptr, nullptr));
+ EXPECT_TRUE(payload_router.RoutePayload(frame_type, payload_type, 0, 0,
+ &payload, 1, nullptr, nullptr));
- payload_router_->set_active(false);
+ payload_router.set_active(false);
EXPECT_CALL(rtp, SendOutgoingData(frame_type, payload_type, 0, 0, _, 1,
nullptr, nullptr))
.Times(0);
- EXPECT_FALSE(payload_router_->RoutePayload(frame_type, payload_type, 0, 0,
- &payload, 1, nullptr, nullptr));
+ EXPECT_FALSE(payload_router.RoutePayload(frame_type, payload_type, 0, 0,
+ &payload, 1, nullptr, nullptr));
- payload_router_->set_active(true);
+ payload_router.set_active(true);
EXPECT_CALL(rtp, SendOutgoingData(frame_type, payload_type, 0, 0, _, 1,
nullptr, nullptr))
.Times(1);
- EXPECT_TRUE(payload_router_->RoutePayload(frame_type, payload_type, 0, 0,
- &payload, 1, nullptr, nullptr));
+ EXPECT_TRUE(payload_router.RoutePayload(frame_type, payload_type, 0, 0,
+ &payload, 1, nullptr, nullptr));
- payload_router_->SetSendingRtpModules(0);
+ payload_router.SetSendingRtpModules(0);
EXPECT_CALL(rtp, SendOutgoingData(frame_type, payload_type, 0, 0, _, 1,
nullptr, nullptr))
.Times(0);
- EXPECT_FALSE(payload_router_->RoutePayload(frame_type, payload_type, 0, 0,
- &payload, 1, nullptr, nullptr));
+ EXPECT_FALSE(payload_router.RoutePayload(frame_type, payload_type, 0, 0,
+ &payload, 1, nullptr, nullptr));
}
-TEST_F(PayloadRouterTest, SendSimulcast) {
+TEST(PayloadRouterTest, SendSimulcast) {
MockRtpRtcp rtp_1;
MockRtpRtcp rtp_2;
std::vector<RtpRtcp*> modules;
modules.push_back(&rtp_1);
modules.push_back(&rtp_2);
- payload_router_->Init(modules);
- payload_router_->SetSendingRtpModules(modules.size());
+ PayloadRouter payload_router(modules);
+ payload_router.SetSendingRtpModules(modules.size());
uint8_t payload_1 = 'a';
FrameType frame_type_1 = kVideoFrameKey;
@@ -93,14 +85,14 @@
RTPVideoHeader rtp_hdr_1;
rtp_hdr_1.simulcastIdx = 0;
- payload_router_->set_active(true);
+ payload_router.set_active(true);
EXPECT_CALL(rtp_1, SendOutgoingData(frame_type_1, payload_type_1, 0, 0, _, 1,
nullptr, &rtp_hdr_1))
.Times(1);
EXPECT_CALL(rtp_2, SendOutgoingData(_, _, _, _, _, _, _, _))
.Times(0);
- EXPECT_TRUE(payload_router_->RoutePayload(
- frame_type_1, payload_type_1, 0, 0, &payload_1, 1, nullptr, &rtp_hdr_1));
+ EXPECT_TRUE(payload_router.RoutePayload(frame_type_1, payload_type_1, 0, 0,
+ &payload_1, 1, nullptr, &rtp_hdr_1));
uint8_t payload_2 = 'b';
FrameType frame_type_2 = kVideoFrameDelta;
@@ -112,46 +104,45 @@
.Times(1);
EXPECT_CALL(rtp_1, SendOutgoingData(_, _, _, _, _, _, _, _))
.Times(0);
- EXPECT_TRUE(payload_router_->RoutePayload(
- frame_type_2, payload_type_2, 0, 0, &payload_2, 1, nullptr, &rtp_hdr_2));
+ EXPECT_TRUE(payload_router.RoutePayload(frame_type_2, payload_type_2, 0, 0,
+ &payload_2, 1, nullptr, &rtp_hdr_2));
// Inactive.
- payload_router_->set_active(false);
+ payload_router.set_active(false);
EXPECT_CALL(rtp_1, SendOutgoingData(_, _, _, _, _, _, _, _))
.Times(0);
EXPECT_CALL(rtp_2, SendOutgoingData(_, _, _, _, _, _, _, _))
.Times(0);
- EXPECT_FALSE(payload_router_->RoutePayload(
- frame_type_1, payload_type_1, 0, 0, &payload_1, 1, nullptr, &rtp_hdr_1));
- EXPECT_FALSE(payload_router_->RoutePayload(
- frame_type_2, payload_type_2, 0, 0, &payload_2, 1, nullptr, &rtp_hdr_2));
+ EXPECT_FALSE(payload_router.RoutePayload(frame_type_1, payload_type_1, 0, 0,
+ &payload_1, 1, nullptr, &rtp_hdr_1));
+ EXPECT_FALSE(payload_router.RoutePayload(frame_type_2, payload_type_2, 0, 0,
+ &payload_2, 1, nullptr, &rtp_hdr_2));
// Invalid simulcast index.
- payload_router_->SetSendingRtpModules(1);
- payload_router_->set_active(true);
+ payload_router.SetSendingRtpModules(1);
+ payload_router.set_active(true);
EXPECT_CALL(rtp_1, SendOutgoingData(_, _, _, _, _, _, _, _))
.Times(0);
EXPECT_CALL(rtp_2, SendOutgoingData(_, _, _, _, _, _, _, _))
.Times(0);
rtp_hdr_1.simulcastIdx = 1;
- EXPECT_FALSE(payload_router_->RoutePayload(
- frame_type_1, payload_type_1, 0, 0, &payload_1, 1, nullptr, &rtp_hdr_1));
+ EXPECT_FALSE(payload_router.RoutePayload(frame_type_1, payload_type_1, 0, 0,
+ &payload_1, 1, nullptr, &rtp_hdr_1));
}
-TEST_F(PayloadRouterTest, MaxPayloadLength) {
+TEST(PayloadRouterTest, MaxPayloadLength) {
// Without any limitations from the modules, verify we get the max payload
// length for IP/UDP/SRTP with a MTU of 150 bytes.
const size_t kDefaultMaxLength = 1500 - 20 - 8 - 12 - 4;
- EXPECT_EQ(kDefaultMaxLength, payload_router_->DefaultMaxPayloadLength());
- EXPECT_EQ(kDefaultMaxLength, payload_router_->MaxPayloadLength());
-
MockRtpRtcp rtp_1;
MockRtpRtcp rtp_2;
std::vector<RtpRtcp*> modules;
modules.push_back(&rtp_1);
modules.push_back(&rtp_2);
- payload_router_->Init(modules);
- payload_router_->SetSendingRtpModules(modules.size());
+ PayloadRouter payload_router(modules);
+
+ EXPECT_EQ(kDefaultMaxLength, PayloadRouter::DefaultMaxPayloadLength());
+ payload_router.SetSendingRtpModules(modules.size());
// Modules return a higher length than the default value.
EXPECT_CALL(rtp_1, MaxDataPayloadLength())
@@ -160,7 +151,7 @@
EXPECT_CALL(rtp_2, MaxDataPayloadLength())
.Times(1)
.WillOnce(Return(kDefaultMaxLength + 10));
- EXPECT_EQ(kDefaultMaxLength, payload_router_->MaxPayloadLength());
+ EXPECT_EQ(kDefaultMaxLength, payload_router.MaxPayloadLength());
// The modules return a value lower than default.
const size_t kTestMinPayloadLength = 1001;
@@ -170,17 +161,17 @@
EXPECT_CALL(rtp_2, MaxDataPayloadLength())
.Times(1)
.WillOnce(Return(kTestMinPayloadLength));
- EXPECT_EQ(kTestMinPayloadLength, payload_router_->MaxPayloadLength());
+ EXPECT_EQ(kTestMinPayloadLength, payload_router.MaxPayloadLength());
}
-TEST_F(PayloadRouterTest, SetTargetSendBitrates) {
+TEST(PayloadRouterTest, SetTargetSendBitrates) {
MockRtpRtcp rtp_1;
MockRtpRtcp rtp_2;
std::vector<RtpRtcp*> modules;
modules.push_back(&rtp_1);
modules.push_back(&rtp_2);
- payload_router_->Init(modules);
- payload_router_->SetSendingRtpModules(modules.size());
+ PayloadRouter payload_router(modules);
+ payload_router.SetSendingRtpModules(modules.size());
const uint32_t bitrate_1 = 10000;
const uint32_t bitrate_2 = 76543;
@@ -190,13 +181,13 @@
.Times(1);
EXPECT_CALL(rtp_2, SetTargetSendBitrate(bitrate_2))
.Times(1);
- payload_router_->SetTargetSendBitrates(bitrates);
+ payload_router.SetTargetSendBitrates(bitrates);
bitrates.resize(1);
EXPECT_CALL(rtp_1, SetTargetSendBitrate(bitrate_1))
.Times(1);
EXPECT_CALL(rtp_2, SetTargetSendBitrate(bitrate_2))
.Times(0);
- payload_router_->SetTargetSendBitrates(bitrates);
+ payload_router.SetTargetSendBitrates(bitrates);
}
} // namespace webrtc
diff --git a/video/video_receive_stream.cc b/video/video_receive_stream.cc
index a34544d..131469f 100644
--- a/video/video_receive_stream.cc
+++ b/video/video_receive_stream.cc
@@ -172,21 +172,15 @@
stats_proxy_(config_, clock_),
vie_channel_(&transport_adapter_,
process_thread,
- nullptr,
vcm_.get(),
- nullptr,
- nullptr,
- nullptr,
congestion_controller_->GetRemoteBitrateEstimator(
UseSendSideBwe(config_)),
call_stats_->rtcp_rtt_stats(),
congestion_controller_->pacer(),
- congestion_controller_->packet_router(),
- 1,
- false),
+ congestion_controller_->packet_router()),
vie_receiver_(vie_channel_.vie_receiver()),
vie_sync_(vcm_.get()),
- rtp_rtcp_(vie_channel_.rtp_rtcp().front()) {
+ rtp_rtcp_(vie_channel_.rtp_rtcp()) {
LOG(LS_INFO) << "VideoReceiveStream: " << config_.ToString();
RTC_DCHECK(process_thread_);
diff --git a/video/video_send_stream.cc b/video/video_send_stream.cc
index 1c6638e..baec5a2 100644
--- a/video/video_send_stream.cc
+++ b/video/video_send_stream.cc
@@ -34,6 +34,52 @@
class RtcpIntraFrameObserver;
class TransportFeedbackObserver;
+static const int kMinSendSidePacketHistorySize = 600;
+
+namespace {
+
+std::vector<RtpRtcp*> CreateRtpRtcpModules(
+ Transport* outgoing_transport,
+ RtcpIntraFrameObserver* intra_frame_callback,
+ RtcpBandwidthObserver* bandwidth_callback,
+ TransportFeedbackObserver* transport_feedback_callback,
+ RtcpRttStats* rtt_stats,
+ RtpPacketSender* paced_sender,
+ TransportSequenceNumberAllocator* transport_sequence_number_allocator,
+ SendStatisticsProxy* stats_proxy,
+ size_t num_modules) {
+ RTC_DCHECK_GT(num_modules, 0u);
+ RtpRtcp::Configuration configuration;
+ ReceiveStatistics* null_receive_statistics = configuration.receive_statistics;
+ configuration.audio = false;
+ configuration.receiver_only = false;
+ configuration.receive_statistics = null_receive_statistics;
+ configuration.outgoing_transport = outgoing_transport;
+ configuration.intra_frame_callback = intra_frame_callback;
+ configuration.rtt_stats = rtt_stats;
+ configuration.rtcp_packet_type_counter_observer = stats_proxy;
+ configuration.paced_sender = paced_sender;
+ configuration.transport_sequence_number_allocator =
+ transport_sequence_number_allocator;
+ configuration.send_bitrate_observer = stats_proxy;
+ configuration.send_frame_count_observer = stats_proxy;
+ configuration.send_side_delay_observer = stats_proxy;
+ configuration.bandwidth_callback = bandwidth_callback;
+ configuration.transport_feedback_callback = transport_feedback_callback;
+
+ std::vector<RtpRtcp*> modules;
+ for (size_t i = 0; i < num_modules; ++i) {
+ RtpRtcp* rtp_rtcp = RtpRtcp::CreateRtpRtcp(configuration);
+ rtp_rtcp->SetSendingStatus(false);
+ rtp_rtcp->SetSendingMediaStatus(false);
+ rtp_rtcp->SetRTCPStatus(RtcpMode::kCompound);
+ modules.push_back(rtp_rtcp);
+ }
+ return modules;
+}
+
+} // namespace
+
std::string
VideoSendStream::Config::EncoderSettings::ToString() const {
std::stringstream ss;
@@ -183,21 +229,6 @@
this,
config.post_encode_callback,
&stats_proxy_),
- vie_channel_(config.send_transport,
- module_process_thread_,
- &payload_router_,
- nullptr,
- &encoder_feedback_,
- congestion_controller_->GetBitrateController()
- ->CreateRtcpBandwidthObserver(),
- congestion_controller_->GetTransportFeedbackObserver(),
- nullptr,
- call_stats_->rtcp_rtt_stats(),
- congestion_controller_->pacer(),
- congestion_controller_->packet_router(),
- config_.rtp.ssrcs.size(),
- true),
- vie_receiver_(vie_channel_.vie_receiver()),
vie_encoder_(num_cpu_cores,
config_.rtp.ssrcs,
module_process_thread_,
@@ -207,7 +238,19 @@
congestion_controller_->pacer(),
&payload_router_),
vcm_(vie_encoder_.vcm()),
- rtp_rtcp_modules_(vie_channel_.rtp_rtcp()),
+ bandwidth_observer_(congestion_controller_->GetBitrateController()
+ ->CreateRtcpBandwidthObserver()),
+ rtp_rtcp_modules_(CreateRtpRtcpModules(
+ config.send_transport,
+ &encoder_feedback_,
+ bandwidth_observer_.get(),
+ congestion_controller_->GetTransportFeedbackObserver(),
+ call_stats_->rtcp_rtt_stats(),
+ congestion_controller_->pacer(),
+ congestion_controller_->packet_router(),
+ &stats_proxy_,
+ config_.rtp.ssrcs.size())),
+ payload_router_(rtp_rtcp_modules_),
input_(&encoder_wakeup_event_,
config_.local_renderer,
&stats_proxy_,
@@ -220,14 +263,16 @@
RTC_DCHECK(congestion_controller_);
RTC_DCHECK(remb_);
- payload_router_.Init(rtp_rtcp_modules_);
RTC_CHECK(vie_encoder_.Init());
encoder_feedback_.Init(config_.rtp.ssrcs, &vie_encoder_);
- RTC_CHECK(vie_channel_.Init() == 0);
- vcm_->RegisterProtectionCallback(vie_channel_.vcm_protection_callback());
+ // RTP/RTCP initialization.
+ for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) {
+ module_process_thread_->RegisterModule(rtp_rtcp);
+ congestion_controller_->packet_router()->AddRtpModule(rtp_rtcp);
+ }
- call_stats_->RegisterStatsObserver(vie_channel_.GetStatsObserver());
+ vcm_->RegisterProtectionCallback(this);
for (size_t i = 0; i < config_.rtp.extensions.size(); ++i) {
const std::string& extension = config_.rtp.extensions[i].name;
@@ -245,28 +290,7 @@
remb_->AddRembSender(rtp_rtcp_modules_[0]);
rtp_rtcp_modules_[0]->SetREMBStatus(true);
- // Enable NACK, FEC or both.
- const bool enable_protection_nack = config_.rtp.nack.rtp_history_ms > 0;
- bool enable_protection_fec = config_.rtp.fec.red_payload_type != -1;
- // Payload types without picture ID cannot determine that a stream is complete
- // without retransmitting FEC, so using FEC + NACK for H.264 (for instance) is
- // a waste of bandwidth since FEC packets still have to be transmitted. Note
- // that this is not the case with FLEXFEC.
- if (enable_protection_nack &&
- !PayloadTypeSupportsSkippingFecPackets(
- config_.encoder_settings.payload_name)) {
- LOG(LS_WARNING) << "Transmitting payload type without picture ID using"
- "NACK+FEC is a waste of bandwidth since FEC packets "
- "also have to be retransmitted. Disabling FEC.";
- enable_protection_fec = false;
- }
- // TODO(changbin): Should set RTX for RED mapping in RTP sender in future.
- vie_channel_.SetProtectionMode(enable_protection_nack, enable_protection_fec,
- config_.rtp.fec.red_payload_type,
- config_.rtp.fec.ulpfec_payload_type);
- vie_encoder_.SetProtectionMethod(enable_protection_nack,
- enable_protection_fec);
-
+ ConfigureProtection();
ConfigureSsrcs();
// TODO(pbos): Should we set CNAME on all RTP modules?
@@ -295,8 +319,6 @@
ReconfigureVideoEncoder(encoder_config);
- vie_channel_.RegisterSendSideDelayObserver(&stats_proxy_);
-
if (config_.post_encode_callback)
vie_encoder_.RegisterPostEncodeImageCallback(&encoded_frame_proxy_);
@@ -305,10 +327,6 @@
bitrate_allocator_->EnforceMinBitrate(false);
}
- vie_channel_.RegisterRtcpPacketTypeCounterObserver(&stats_proxy_);
- vie_channel_.RegisterSendBitrateObserver(&stats_proxy_);
- vie_channel_.RegisterSendFrameCountObserver(&stats_proxy_);
-
module_process_thread_->RegisterModule(&overuse_detector_);
encoder_thread_.Start();
@@ -330,22 +348,17 @@
bitrate_allocator_->RemoveObserver(this);
module_process_thread_->DeRegisterModule(&overuse_detector_);
- vie_channel_.RegisterSendFrameCountObserver(nullptr);
- vie_channel_.RegisterSendBitrateObserver(nullptr);
- vie_channel_.RegisterRtcpPacketTypeCounterObserver(nullptr);
vie_encoder_.DeRegisterExternalEncoder(config_.encoder_settings.payload_type);
- call_stats_->DeregisterStatsObserver(vie_channel_.GetStatsObserver());
rtp_rtcp_modules_[0]->SetREMBStatus(false);
remb_->RemoveRembSender(rtp_rtcp_modules_[0]);
- // ViEChannel outlives ViEEncoder so remove encoder from feedback before
- // destruction.
- encoder_feedback_.TearDown();
-
- congestion_controller_->GetRemoteBitrateEstimator(false)->RemoveStream(
- vie_receiver_->GetRemoteSsrc());
+ for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) {
+ congestion_controller_->packet_router()->RemoveRtpModule(rtp_rtcp);
+ module_process_thread_->DeRegisterModule(rtp_rtcp);
+ delete rtp_rtcp;
+ }
}
VideoCaptureInput* VideoSendStream::Input() {
@@ -361,7 +374,6 @@
// Was not already started, trigger a keyframe.
vie_encoder_.SendKeyFrame();
vie_encoder_.Restart();
- vie_receiver_->StartReceive();
}
void VideoSendStream::Stop() {
@@ -370,7 +382,6 @@
TRACE_EVENT_INSTANT0("webrtc", "VideoSendStream::Stop");
// TODO(pbos): Make sure the encoder stops here.
payload_router_.set_active(false);
- vie_receiver_->StopReceive();
}
bool VideoSendStream::EncoderThreadFunction(void* obj) {
@@ -535,7 +546,9 @@
}
bool VideoSendStream::DeliverRtcp(const uint8_t* packet, size_t length) {
- return vie_receiver_->DeliverRtcp(packet, length);
+ for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_)
+ rtp_rtcp->IncomingRtcpPacket(packet, length);
+ return true;
}
VideoSendStream::Stats VideoSendStream::GetStats() {
@@ -552,6 +565,60 @@
config_.overuse_callback->OnLoadUpdate(LoadObserver::kUnderuse);
}
+void VideoSendStream::ConfigureProtection() {
+ // Enable NACK, FEC or both.
+ const bool enable_protection_nack = config_.rtp.nack.rtp_history_ms > 0;
+ bool enable_protection_fec = config_.rtp.fec.red_payload_type != -1;
+ // Payload types without picture ID cannot determine that a stream is complete
+ // without retransmitting FEC, so using FEC + NACK for H.264 (for instance) is
+ // a waste of bandwidth since FEC packets still have to be transmitted. Note
+ // that this is not the case with FLEXFEC.
+ if (enable_protection_nack &&
+ !PayloadTypeSupportsSkippingFecPackets(
+ config_.encoder_settings.payload_name)) {
+ LOG(LS_WARNING) << "Transmitting payload type without picture ID using"
+ "NACK+FEC is a waste of bandwidth since FEC packets "
+ "also have to be retransmitted. Disabling FEC.";
+ enable_protection_fec = false;
+ }
+
+ // Set to valid uint8_ts to be castable later without signed overflows.
+ uint8_t payload_type_red = 0;
+ uint8_t payload_type_fec = 0;
+ // TODO(changbin): Should set RTX for RED mapping in RTP sender in future.
+ // Validate payload types. If either RED or FEC payload types are set then
+ // both should be. If FEC is enabled then they both have to be set.
+ if (enable_protection_fec || config_.rtp.fec.red_payload_type != -1 ||
+ config_.rtp.fec.ulpfec_payload_type != -1) {
+ RTC_DCHECK_GE(config_.rtp.fec.red_payload_type, 0);
+ RTC_DCHECK_GE(config_.rtp.fec.ulpfec_payload_type, 0);
+ RTC_DCHECK_LE(config_.rtp.fec.red_payload_type, 127);
+ RTC_DCHECK_LE(config_.rtp.fec.ulpfec_payload_type, 127);
+ payload_type_red = static_cast<uint8_t>(config_.rtp.fec.red_payload_type);
+ payload_type_fec =
+ static_cast<uint8_t>(config_.rtp.fec.ulpfec_payload_type);
+ } else {
+ // Payload types unset.
+ RTC_DCHECK_EQ(config_.rtp.fec.red_payload_type, -1);
+ RTC_DCHECK_EQ(config_.rtp.fec.ulpfec_payload_type, -1);
+ }
+
+ for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) {
+ // Set NACK.
+ rtp_rtcp->SetStorePacketsStatus(
+ enable_protection_nack || congestion_controller_->pacer(),
+ kMinSendSidePacketHistorySize);
+ // Set FEC.
+ for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) {
+ rtp_rtcp->SetGenericFECStatus(enable_protection_fec, payload_type_red,
+ payload_type_fec);
+ }
+ }
+
+ vie_encoder_.SetProtectionMethod(enable_protection_nack,
+ enable_protection_fec);
+}
+
void VideoSendStream::ConfigureSsrcs() {
// Configure regular SSRCs.
for (size_t i = 0; i < config_.rtp.ssrcs.size(); ++i) {
@@ -562,7 +629,7 @@
// Restore RTP state if previous existed.
RtpStateMap::iterator it = suspended_ssrcs_.find(ssrc);
if (it != suspended_ssrcs_.end())
- rtp_rtcp->SetRtpStateForSsrc(ssrc, it->second);
+ rtp_rtcp->SetRtpState(it->second);
}
// Set up RTX if available.
@@ -577,7 +644,7 @@
rtp_rtcp->SetRtxSsrc(ssrc);
RtpStateMap::iterator it = suspended_ssrcs_.find(ssrc);
if (it != suspended_ssrcs_.end())
- rtp_rtcp->SetRtpStateForSsrc(ssrc, it->second);
+ rtp_rtcp->SetRtxState(it->second);
}
// Configure RTX payload types.
@@ -600,12 +667,13 @@
std::map<uint32_t, RtpState> rtp_states;
for (size_t i = 0; i < config_.rtp.ssrcs.size(); ++i) {
uint32_t ssrc = config_.rtp.ssrcs[i];
- rtp_states[ssrc] = vie_channel_.GetRtpStateForSsrc(ssrc);
+ RTC_DCHECK_EQ(ssrc, rtp_rtcp_modules_[i]->SSRC());
+ rtp_states[ssrc] = rtp_rtcp_modules_[i]->GetRtpState();
}
for (size_t i = 0; i < config_.rtp.rtx.ssrcs.size(); ++i) {
uint32_t ssrc = config_.rtp.rtx.ssrcs[i];
- rtp_states[ssrc] = vie_channel_.GetRtpStateForSsrc(ssrc);
+ rtp_states[ssrc] = rtp_rtcp_modules_[i]->GetRtxState();
}
return rtp_states;
@@ -636,5 +704,28 @@
vie_encoder_.OnBitrateUpdated(bitrate_bps, fraction_loss, rtt);
}
+int VideoSendStream::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 (RtpRtcp* rtp_rtcp : rtp_rtcp_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;
+}
+
} // namespace internal
} // namespace webrtc
diff --git a/video/video_send_stream.h b/video/video_send_stream.h
index 8b3d064..688e8fc 100644
--- a/video/video_send_stream.h
+++ b/video/video_send_stream.h
@@ -42,7 +42,8 @@
class VideoSendStream : public webrtc::VideoSendStream,
public webrtc::CpuOveruseObserver,
- public webrtc::BitrateAllocatorObserver {
+ public webrtc::BitrateAllocatorObserver,
+ public webrtc::VCMProtectionCallback {
public:
VideoSendStream(int num_cpu_cores,
ProcessThread* module_process_thread,
@@ -81,10 +82,18 @@
uint8_t fraction_loss,
int64_t rtt) 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;
+
private:
static bool EncoderThreadFunction(void* obj);
void EncoderProcess();
+ void ConfigureProtection();
void ConfigureSsrcs();
SendStatisticsProxy stats_proxy_;
@@ -103,16 +112,14 @@
volatile int stop_encoder_thread_;
OveruseFrameDetector overuse_detector_;
- PayloadRouter payload_router_;
EncoderStateFeedback encoder_feedback_;
- ViEChannel vie_channel_;
- ViEReceiver* const vie_receiver_;
ViEEncoder vie_encoder_;
VideoCodingModule* const vcm_;
- // TODO(pbos): Move RtpRtcp ownership to VideoSendStream.
- // RtpRtcp modules, currently owned by ViEChannel but ownership should
- // eventually move here.
+
+ const std::unique_ptr<RtcpBandwidthObserver> bandwidth_observer_;
+ // RtpRtcp modules, declared here as they use other members on construction.
const std::vector<RtpRtcp*> rtp_rtcp_modules_;
+ PayloadRouter payload_router_;
VideoCaptureInput input_;
};
} // namespace internal
diff --git a/video/vie_channel.cc b/video/vie_channel.cc
index c0676bc..842558b 100644
--- a/video/vie_channel.cc
+++ b/video/vie_channel.cc
@@ -35,10 +35,47 @@
namespace webrtc {
-static const int kMinSendSidePacketHistorySize = 600;
static const int kMaxPacketAgeToNack = 450;
static const int kMaxNackListSize = 250;
+namespace {
+
+std::unique_ptr<RtpRtcp> CreateRtpRtcpModule(
+ ReceiveStatistics* receive_statistics,
+ Transport* outgoing_transport,
+ RtcpRttStats* rtt_stats,
+ RtcpPacketTypeCounterObserver* rtcp_packet_type_counter_observer,
+ RemoteBitrateEstimator* remote_bitrate_estimator,
+ RtpPacketSender* paced_sender,
+ TransportSequenceNumberAllocator* transport_sequence_number_allocator) {
+ RtpRtcp::Configuration configuration;
+ configuration.audio = false;
+ configuration.receiver_only = true;
+ configuration.receive_statistics = receive_statistics;
+ configuration.outgoing_transport = outgoing_transport;
+ configuration.intra_frame_callback = nullptr;
+ configuration.rtt_stats = rtt_stats;
+ configuration.rtcp_packet_type_counter_observer =
+ rtcp_packet_type_counter_observer;
+ configuration.paced_sender = paced_sender;
+ configuration.transport_sequence_number_allocator =
+ transport_sequence_number_allocator;
+ configuration.send_bitrate_observer = nullptr;
+ configuration.send_frame_count_observer = nullptr;
+ configuration.send_side_delay_observer = nullptr;
+ configuration.bandwidth_callback = nullptr;
+ configuration.transport_feedback_callback = nullptr;
+
+ std::unique_ptr<RtpRtcp> rtp_rtcp(RtpRtcp::CreateRtpRtcp(configuration));
+ rtp_rtcp->SetSendingStatus(false);
+ rtp_rtcp->SetSendingMediaStatus(false);
+ rtp_rtcp->SetRTCPStatus(RtcpMode::kCompound);
+
+ return rtp_rtcp;
+}
+
+} // namespace
+
// Helper class receiving statistics callbacks.
class ChannelStatsObserver : public CallStatsObserver {
public:
@@ -54,82 +91,35 @@
ViEChannel* const owner_;
};
-class ViEChannelProtectionCallback : public VCMProtectionCallback {
- public:
- explicit ViEChannelProtectionCallback(ViEChannel* owner) : owner_(owner) {}
- ~ViEChannelProtectionCallback() {}
-
-
- int ProtectionRequest(
- const FecProtectionParams* delta_fec_params,
- const FecProtectionParams* key_fec_params,
- uint32_t* sent_video_rate_bps,
- uint32_t* sent_nack_rate_bps,
- uint32_t* sent_fec_rate_bps) override {
- return owner_->ProtectionRequest(delta_fec_params, key_fec_params,
- sent_video_rate_bps, sent_nack_rate_bps,
- sent_fec_rate_bps);
- }
- private:
- ViEChannel* owner_;
-};
-
ViEChannel::ViEChannel(Transport* transport,
ProcessThread* module_process_thread,
- PayloadRouter* send_payload_router,
VideoCodingModule* vcm,
- RtcpIntraFrameObserver* intra_frame_observer,
- RtcpBandwidthObserver* bandwidth_observer,
- TransportFeedbackObserver* transport_feedback_observer,
RemoteBitrateEstimator* remote_bitrate_estimator,
RtcpRttStats* rtt_stats,
PacedSender* paced_sender,
- PacketRouter* packet_router,
- size_t max_rtp_streams,
- bool sender)
- : sender_(sender),
- module_process_thread_(module_process_thread),
- send_payload_router_(send_payload_router),
- vcm_protection_callback_(new ViEChannelProtectionCallback(this)),
+ PacketRouter* packet_router)
+ : module_process_thread_(module_process_thread),
vcm_(vcm),
vie_receiver_(vcm_, remote_bitrate_estimator, this),
stats_observer_(new ChannelStatsObserver(this)),
receive_stats_callback_(nullptr),
incoming_video_stream_(nullptr),
- intra_frame_observer_(intra_frame_observer),
rtt_stats_(rtt_stats),
paced_sender_(paced_sender),
packet_router_(packet_router),
- bandwidth_observer_(bandwidth_observer),
- transport_feedback_observer_(transport_feedback_observer),
max_nack_reordering_threshold_(kMaxPacketAgeToNack),
pre_render_callback_(nullptr),
last_rtt_ms_(0),
- rtp_rtcp_modules_(
- CreateRtpRtcpModules(!sender,
- vie_receiver_.GetReceiveStatistics(),
- transport,
- intra_frame_observer_,
- bandwidth_observer_.get(),
- transport_feedback_observer_,
- rtt_stats_,
- &rtcp_packet_type_counter_observer_,
- remote_bitrate_estimator,
- paced_sender_,
- packet_router_,
- &send_bitrate_observer_,
- &send_frame_count_observer_,
- &send_side_delay_observer_,
- max_rtp_streams)) {
- vie_receiver_.Init(rtp_rtcp_modules_);
- if (sender_) {
- RTC_DCHECK(send_payload_router_);
- RTC_DCHECK(!vcm_);
- } else {
- RTC_DCHECK(!send_payload_router_);
- RTC_DCHECK(vcm_);
- vcm_->SetNackSettings(kMaxNackListSize, max_nack_reordering_threshold_, 0);
- }
+ rtp_rtcp_(CreateRtpRtcpModule(vie_receiver_.GetReceiveStatistics(),
+ transport,
+ rtt_stats_,
+ &rtcp_packet_type_counter_observer_,
+ remote_bitrate_estimator,
+ paced_sender_,
+ packet_router_)) {
+ vie_receiver_.Init(rtp_rtcp_.get());
+ RTC_DCHECK(vcm_);
+ vcm_->SetNackSettings(kMaxNackListSize, max_nack_reordering_threshold_, 0);
}
int32_t ViEChannel::Init() {
@@ -137,28 +127,18 @@
module_process_thread_->RegisterModule(vie_receiver_.GetReceiveStatistics());
// RTP/RTCP initialization.
- for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) {
- module_process_thread_->RegisterModule(rtp_rtcp);
- packet_router_->AddRtpModule(rtp_rtcp);
- }
+ module_process_thread_->RegisterModule(rtp_rtcp_.get());
+ packet_router_->AddRtpModule(rtp_rtcp_.get());
- rtp_rtcp_modules_[0]->SetKeyFrameRequestMethod(kKeyFrameReqPliRtcp);
- if (paced_sender_) {
- for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_)
- rtp_rtcp->SetStorePacketsStatus(true, kMinSendSidePacketHistorySize);
+ rtp_rtcp_->SetKeyFrameRequestMethod(kKeyFrameReqPliRtcp);
+ if (vcm_->RegisterReceiveCallback(this) != 0) {
+ return -1;
}
- if (sender_) {
- send_payload_router_->SetSendingRtpModules(1);
- RTC_DCHECK(!send_payload_router_->active());
- } else {
- if (vcm_->RegisterReceiveCallback(this) != 0) {
- return -1;
- }
- vcm_->RegisterFrameTypeCallback(this);
- vcm_->RegisterReceiveStatisticsCallback(this);
- vcm_->RegisterDecoderTimingCallback(this);
- vcm_->SetRenderDelay(kDefaultRenderDelayMs);
- }
+ vcm_->RegisterFrameTypeCallback(this);
+ vcm_->RegisterReceiveStatisticsCallback(this);
+ vcm_->RegisterDecoderTimingCallback(this);
+ vcm_->SetRenderDelay(kDefaultRenderDelayMs);
+
return 0;
}
@@ -166,14 +146,9 @@
// Make sure we don't get more callbacks from the RTP module.
module_process_thread_->DeRegisterModule(
vie_receiver_.GetReceiveStatistics());
- if (sender_) {
- send_payload_router_->SetSendingRtpModules(0);
- }
- for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) {
- packet_router_->RemoveRtpModule(rtp_rtcp);
- module_process_thread_->DeRegisterModule(rtp_rtcp);
- delete rtp_rtcp;
- }
+
+ packet_router_->RemoveRtpModule(rtp_rtcp_.get());
+ module_process_thread_->DeRegisterModule(rtp_rtcp_.get());
}
void ViEChannel::SetProtectionMode(bool enable_nack,
@@ -203,44 +178,32 @@
protection_method = kProtectionNone;
}
- if (!sender_)
- vcm_->SetVideoProtection(protection_method, true);
+ vcm_->SetVideoProtection(protection_method, true);
// Set NACK.
ProcessNACKRequest(enable_nack);
// Set FEC.
- for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) {
- rtp_rtcp->SetGenericFECStatus(enable_fec,
- static_cast<uint8_t>(payload_type_red),
- static_cast<uint8_t>(payload_type_fec));
- }
+ rtp_rtcp_->SetGenericFECStatus(enable_fec,
+ static_cast<uint8_t>(payload_type_red),
+ static_cast<uint8_t>(payload_type_fec));
}
void ViEChannel::ProcessNACKRequest(const bool enable) {
if (enable) {
// Turn on NACK.
- if (rtp_rtcp_modules_[0]->RTCP() == RtcpMode::kOff)
+ if (rtp_rtcp_->RTCP() == RtcpMode::kOff)
return;
vie_receiver_.SetNackStatus(true, max_nack_reordering_threshold_);
+ vcm_->RegisterPacketRequestCallback(this);
+ // Don't introduce errors when NACK is enabled.
+ vcm_->SetDecodeErrorMode(kNoErrors);
- for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_)
- rtp_rtcp->SetStorePacketsStatus(true, kMinSendSidePacketHistorySize);
-
- if (!sender_) {
- vcm_->RegisterPacketRequestCallback(this);
- // Don't introduce errors when NACK is enabled.
- vcm_->SetDecodeErrorMode(kNoErrors);
- }
} else {
- if (!sender_) {
- vcm_->RegisterPacketRequestCallback(nullptr);
- for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_)
- rtp_rtcp->SetStorePacketsStatus(false, 0);
- // When NACK is off, allow decoding with errors. Otherwise, the video
- // will freeze, and will only recover with a complete key frame.
- vcm_->SetDecodeErrorMode(kWithErrors);
- }
+ vcm_->RegisterPacketRequestCallback(nullptr);
+ // When NACK is off, allow decoding with errors. Otherwise, the video
+ // will freeze, and will only recover with a complete key frame.
+ vcm_->SetDecodeErrorMode(kWithErrors);
vie_receiver_.SetNackStatus(false, max_nack_reordering_threshold_);
}
}
@@ -253,14 +216,9 @@
}
RtpState ViEChannel::GetRtpStateForSsrc(uint32_t ssrc) const {
- RTC_DCHECK(!rtp_rtcp_modules_[0]->Sending());
- RtpState rtp_state;
- for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) {
- if (rtp_rtcp->GetRtpStateForSsrc(ssrc, &rtp_state))
- return rtp_state;
- }
- LOG(LS_ERROR) << "Couldn't get RTP state for ssrc: " << ssrc;
- return rtp_state;
+ RTC_DCHECK(!rtp_rtcp_->Sending());
+ RTC_DCHECK_EQ(ssrc, rtp_rtcp_->SSRC());
+ return rtp_rtcp_->GetRtpState();
}
void ViEChannel::RegisterRtcpPacketTypeCounterObserver(
@@ -268,42 +226,14 @@
rtcp_packet_type_counter_observer_.Set(observer);
}
-void ViEChannel::GetSendStreamDataCounters(
- StreamDataCounters* rtp_counters,
- StreamDataCounters* rtx_counters) const {
- *rtp_counters = StreamDataCounters();
- *rtx_counters = StreamDataCounters();
- for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) {
- StreamDataCounters rtp_data;
- StreamDataCounters rtx_data;
- rtp_rtcp->GetSendStreamDataCounters(&rtp_data, &rtx_data);
- rtp_counters->Add(rtp_data);
- rtx_counters->Add(rtx_data);
- }
-}
-
-void ViEChannel::RegisterSendSideDelayObserver(
- SendSideDelayObserver* observer) {
- send_side_delay_observer_.Set(observer);
-}
-
-void ViEChannel::RegisterSendBitrateObserver(
- BitrateStatisticsObserver* observer) {
- send_bitrate_observer_.Set(observer);
-}
-
-const std::vector<RtpRtcp*>& ViEChannel::rtp_rtcp() const {
- return rtp_rtcp_modules_;
+RtpRtcp* ViEChannel::rtp_rtcp() const {
+ return rtp_rtcp_.get();
}
ViEReceiver* ViEChannel::vie_receiver() {
return &vie_receiver_;
}
-VCMProtectionCallback* ViEChannel::vcm_protection_callback() {
- return vcm_protection_callback_.get();
-}
-
CallStatsObserver* ViEChannel::GetStatsObserver() {
return stats_observer_.get();
}
@@ -325,7 +255,7 @@
int32_t ViEChannel::ReceivedDecodedReferenceFrame(
const uint64_t picture_id) {
- return rtp_rtcp_modules_[0]->SendRTCPReferencePictureSelection(picture_id);
+ return rtp_rtcp_->SendRTCPReferencePictureSelection(picture_id);
}
void ViEChannel::OnIncomingPayloadType(int payload_type) {
@@ -375,105 +305,29 @@
}
int32_t ViEChannel::RequestKeyFrame() {
- return rtp_rtcp_modules_[0]->RequestKeyFrame();
+ return rtp_rtcp_->RequestKeyFrame();
}
int32_t ViEChannel::SliceLossIndicationRequest(
const uint64_t picture_id) {
- return rtp_rtcp_modules_[0]->SendRTCPSliceLossIndication(
+ return rtp_rtcp_->SendRTCPSliceLossIndication(
static_cast<uint8_t>(picture_id));
}
int32_t ViEChannel::ResendPackets(const uint16_t* sequence_numbers,
uint16_t length) {
- return rtp_rtcp_modules_[0]->SendNACK(sequence_numbers, length);
+ return rtp_rtcp_->SendNACK(sequence_numbers, length);
}
void ViEChannel::OnRttUpdate(int64_t avg_rtt_ms, int64_t max_rtt_ms) {
- if (!sender_)
- vcm_->SetReceiveChannelParameters(max_rtt_ms);
+ vcm_->SetReceiveChannelParameters(max_rtt_ms);
rtc::CritScope lock(&crit_);
last_rtt_ms_ = avg_rtt_ms;
}
-int ViEChannel::ProtectionRequest(const FecProtectionParams* delta_fec_params,
- const FecProtectionParams* key_fec_params,
- uint32_t* video_rate_bps,
- uint32_t* nack_rate_bps,
- uint32_t* fec_rate_bps) {
- *video_rate_bps = 0;
- *nack_rate_bps = 0;
- *fec_rate_bps = 0;
- for (RtpRtcp* rtp_rtcp : rtp_rtcp_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_fec_params, key_fec_params);
- rtp_rtcp->BitrateSent(¬_used, &module_video_rate, &module_fec_rate,
- &module_nack_rate);
- *video_rate_bps += module_video_rate;
- *nack_rate_bps += module_nack_rate;
- *fec_rate_bps += module_fec_rate;
- }
- return 0;
-}
-
-std::vector<RtpRtcp*> ViEChannel::CreateRtpRtcpModules(
- bool receiver_only,
- ReceiveStatistics* receive_statistics,
- Transport* outgoing_transport,
- RtcpIntraFrameObserver* intra_frame_callback,
- RtcpBandwidthObserver* bandwidth_callback,
- TransportFeedbackObserver* transport_feedback_callback,
- RtcpRttStats* rtt_stats,
- RtcpPacketTypeCounterObserver* rtcp_packet_type_counter_observer,
- RemoteBitrateEstimator* remote_bitrate_estimator,
- RtpPacketSender* paced_sender,
- TransportSequenceNumberAllocator* transport_sequence_number_allocator,
- BitrateStatisticsObserver* send_bitrate_observer,
- FrameCountObserver* send_frame_count_observer,
- SendSideDelayObserver* send_side_delay_observer,
- size_t num_modules) {
- RTC_DCHECK_GT(num_modules, 0u);
- RtpRtcp::Configuration configuration;
- ReceiveStatistics* null_receive_statistics = configuration.receive_statistics;
- configuration.audio = false;
- configuration.receiver_only = receiver_only;
- configuration.receive_statistics = receive_statistics;
- configuration.outgoing_transport = outgoing_transport;
- configuration.intra_frame_callback = intra_frame_callback;
- configuration.rtt_stats = rtt_stats;
- configuration.rtcp_packet_type_counter_observer =
- rtcp_packet_type_counter_observer;
- configuration.paced_sender = paced_sender;
- configuration.transport_sequence_number_allocator =
- transport_sequence_number_allocator;
- configuration.send_bitrate_observer = send_bitrate_observer;
- configuration.send_frame_count_observer = send_frame_count_observer;
- configuration.send_side_delay_observer = send_side_delay_observer;
- configuration.bandwidth_callback = bandwidth_callback;
- configuration.transport_feedback_callback = transport_feedback_callback;
-
- std::vector<RtpRtcp*> modules;
- for (size_t i = 0; i < num_modules; ++i) {
- RtpRtcp* rtp_rtcp = RtpRtcp::CreateRtpRtcp(configuration);
- rtp_rtcp->SetSendingStatus(false);
- rtp_rtcp->SetSendingMediaStatus(false);
- rtp_rtcp->SetRTCPStatus(RtcpMode::kCompound);
- modules.push_back(rtp_rtcp);
- // Receive statistics and remote bitrate estimator should only be set for
- // the primary (first) module.
- configuration.receive_statistics = null_receive_statistics;
- configuration.remote_bitrate_estimator = nullptr;
- }
- return modules;
-}
-
void ViEChannel::RegisterPreRenderCallback(
I420FrameCallback* pre_render_callback) {
- RTC_DCHECK(!sender_);
rtc::CritScope lock(&crit_);
pre_render_callback_ = pre_render_callback;
}
@@ -491,16 +345,11 @@
}
void ViEChannel::OnIncomingSSRCChanged(const uint32_t ssrc) {
- rtp_rtcp_modules_[0]->SetRemoteSSRC(ssrc);
+ rtp_rtcp_->SetRemoteSSRC(ssrc);
}
void ViEChannel::OnIncomingCSRCChanged(const uint32_t CSRC, const bool added) {}
-void ViEChannel::RegisterSendFrameCountObserver(
- FrameCountObserver* observer) {
- send_frame_count_observer_.Set(observer);
-}
-
void ViEChannel::RegisterReceiveStatisticsProxy(
ReceiveStatisticsProxy* receive_statistics_proxy) {
rtc::CritScope lock(&crit_);
diff --git a/video/vie_channel.h b/video/vie_channel.h
index 8a9d70e..1bcae19 100644
--- a/video/vie_channel.h
+++ b/video/vie_channel.h
@@ -42,7 +42,6 @@
class ProcessThread;
class ReceiveStatisticsProxy;
class RtcpRttStats;
-class ViEChannelProtectionCallback;
class ViERTPObserver;
class VideoCodingModule;
class VideoRenderCallback;
@@ -61,21 +60,14 @@
public RtpFeedback {
public:
friend class ChannelStatsObserver;
- friend class ViEChannelProtectionCallback;
ViEChannel(Transport* transport,
ProcessThread* module_process_thread,
- PayloadRouter* send_payload_router,
VideoCodingModule* vcm,
- RtcpIntraFrameObserver* intra_frame_observer,
- RtcpBandwidthObserver* bandwidth_observer,
- TransportFeedbackObserver* transport_feedback_observer,
RemoteBitrateEstimator* remote_bitrate_estimator,
RtcpRttStats* rtt_stats,
PacedSender* paced_sender,
- PacketRouter* packet_router,
- size_t max_rtp_streams,
- bool sender);
+ PacketRouter* packet_router);
~ViEChannel();
int32_t Init();
@@ -87,15 +79,6 @@
RtpState GetRtpStateForSsrc(uint32_t ssrc) const;
- // Gets send statistics for the rtp and rtx stream.
- void GetSendStreamDataCounters(StreamDataCounters* rtp_counters,
- StreamDataCounters* rtx_counters) const;
-
- void RegisterSendSideDelayObserver(SendSideDelayObserver* observer);
-
- // Called on any new send bitrate estimate.
- void RegisterSendBitrateObserver(BitrateStatisticsObserver* observer);
-
// Implements RtpFeedback.
int32_t OnInitializeDecoder(const int8_t payload_type,
const char payload_name[RTP_PAYLOAD_NAME_SIZE],
@@ -105,11 +88,9 @@
void OnIncomingSSRCChanged(const uint32_t ssrc) override;
void OnIncomingCSRCChanged(const uint32_t CSRC, const bool added) override;
- // Gets the modules used by the channel.
- const std::vector<RtpRtcp*>& rtp_rtcp() const;
+ // Gets the module used by the channel.
+ RtpRtcp* rtp_rtcp() const;
ViEReceiver* vie_receiver();
- VCMProtectionCallback* vcm_protection_callback();
-
CallStatsObserver* GetStatsObserver();
@@ -151,7 +132,6 @@
void RegisterPreRenderCallback(I420FrameCallback* pre_render_callback);
- void RegisterSendFrameCountObserver(FrameCountObserver* observer);
void RegisterRtcpPacketTypeCounterObserver(
RtcpPacketTypeCounterObserver* observer);
void RegisterReceiveStatisticsProxy(
@@ -161,30 +141,7 @@
protected:
void OnRttUpdate(int64_t avg_rtt_ms, int64_t max_rtt_ms);
- int ProtectionRequest(const FecProtectionParams* delta_fec_params,
- const FecProtectionParams* key_fec_params,
- uint32_t* sent_video_rate_bps,
- uint32_t* sent_nack_rate_bps,
- uint32_t* sent_fec_rate_bps);
-
private:
- static std::vector<RtpRtcp*> CreateRtpRtcpModules(
- bool receiver_only,
- ReceiveStatistics* receive_statistics,
- Transport* outgoing_transport,
- RtcpIntraFrameObserver* intra_frame_callback,
- RtcpBandwidthObserver* bandwidth_callback,
- TransportFeedbackObserver* transport_feedback_callback,
- RtcpRttStats* rtt_stats,
- RtcpPacketTypeCounterObserver* rtcp_packet_type_counter_observer,
- RemoteBitrateEstimator* remote_bitrate_estimator,
- RtpPacketSender* paced_sender,
- TransportSequenceNumberAllocator* transport_sequence_number_allocator,
- BitrateStatisticsObserver* send_bitrate_observer,
- FrameCountObserver* send_frame_count_observer,
- SendSideDelayObserver* send_side_delay_observer,
- size_t num_modules);
-
// Assumed to be protected.
void StartDecodeThread();
void StopDecodeThread();
@@ -219,41 +176,6 @@
RTC_DISALLOW_COPY_AND_ASSIGN(RegisterableCallback);
};
- class RegisterableBitrateStatisticsObserver:
- public RegisterableCallback<BitrateStatisticsObserver> {
- virtual void Notify(const BitrateStatistics& total_stats,
- const BitrateStatistics& retransmit_stats,
- uint32_t ssrc) {
- rtc::CritScope lock(&critsect_);
- if (callback_)
- callback_->Notify(total_stats, retransmit_stats, ssrc);
- }
- } send_bitrate_observer_;
-
- class RegisterableFrameCountObserver
- : public RegisterableCallback<FrameCountObserver> {
- public:
- virtual void FrameCountUpdated(const FrameCounts& frame_counts,
- uint32_t ssrc) {
- rtc::CritScope lock(&critsect_);
- if (callback_)
- callback_->FrameCountUpdated(frame_counts, ssrc);
- }
-
- private:
- } send_frame_count_observer_;
-
- class RegisterableSendSideDelayObserver :
- public RegisterableCallback<SendSideDelayObserver> {
- void SendSideDelayUpdated(int avg_delay_ms,
- int max_delay_ms,
- uint32_t ssrc) override {
- rtc::CritScope lock(&critsect_);
- if (callback_)
- callback_->SendSideDelayUpdated(avg_delay_ms, max_delay_ms, ssrc);
- }
- } send_side_delay_observer_;
-
class RegisterableRtcpPacketTypeCounterObserver
: public RegisterableCallback<RtcpPacketTypeCounterObserver> {
public:
@@ -268,17 +190,12 @@
private:
} rtcp_packet_type_counter_observer_;
- const bool sender_;
ProcessThread* const module_process_thread_;
- PayloadRouter* const send_payload_router_;
// Used for all registered callbacks except rendering.
rtc::CriticalSection crit_;
- // Owned modules/classes.
- std::unique_ptr<ViEChannelProtectionCallback> vcm_protection_callback_;
-
VideoCodingModule* const vcm_;
ViEReceiver vie_receiver_;
@@ -289,21 +206,17 @@
ReceiveStatisticsProxy* receive_stats_callback_ GUARDED_BY(crit_);
FrameCounts receive_frame_counts_ GUARDED_BY(crit_);
IncomingVideoStream* incoming_video_stream_ GUARDED_BY(crit_);
- RtcpIntraFrameObserver* const intra_frame_observer_;
RtcpRttStats* const rtt_stats_;
PacedSender* const paced_sender_;
PacketRouter* const packet_router_;
- const std::unique_ptr<RtcpBandwidthObserver> bandwidth_observer_;
- TransportFeedbackObserver* const transport_feedback_observer_;
-
int max_nack_reordering_threshold_;
I420FrameCallback* pre_render_callback_ GUARDED_BY(crit_);
int64_t last_rtt_ms_ GUARDED_BY(crit_);
- // RtpRtcp modules, declared last as they use other members on construction.
- const std::vector<RtpRtcp*> rtp_rtcp_modules_;
+ // RtpRtcp module, declared last as it use other members on construction.
+ const std::unique_ptr<RtpRtcp> rtp_rtcp_;
};
} // namespace webrtc
diff --git a/video/vie_receiver.cc b/video/vie_receiver.cc
index e5ec167..9ead910 100644
--- a/video/vie_receiver.cc
+++ b/video/vie_receiver.cc
@@ -124,8 +124,8 @@
return rtp_receiver_->CSRCs(csrcs);
}
-void ViEReceiver::Init(const std::vector<RtpRtcp*>& modules) {
- rtp_rtcp_ = modules;
+void ViEReceiver::Init(RtpRtcp* rtp_rtcp) {
+ rtp_rtcp_ = rtp_rtcp;
}
RtpReceiver* ViEReceiver::GetRtpReceiver() const {
@@ -318,8 +318,6 @@
bool ViEReceiver::DeliverRtcp(const uint8_t* rtcp_packet,
size_t rtcp_packet_length) {
- // Should be set by owner at construction time.
- RTC_DCHECK(!rtp_rtcp_.empty());
{
rtc::CritScope lock(&receive_cs_);
if (!receiving_) {
@@ -327,11 +325,10 @@
}
}
- for (RtpRtcp* rtp_rtcp : rtp_rtcp_)
- rtp_rtcp->IncomingRtcpPacket(rtcp_packet, rtcp_packet_length);
+ rtp_rtcp_->IncomingRtcpPacket(rtcp_packet, rtcp_packet_length);
int64_t rtt = 0;
- rtp_rtcp_[0]->RTT(rtp_receiver_->SSRC(), &rtt, nullptr, nullptr, nullptr);
+ rtp_rtcp_->RTT(rtp_receiver_->SSRC(), &rtt, nullptr, nullptr, nullptr);
if (rtt == 0) {
// Waiting for valid rtt.
return true;
@@ -339,8 +336,8 @@
uint32_t ntp_secs = 0;
uint32_t ntp_frac = 0;
uint32_t rtp_timestamp = 0;
- if (rtp_rtcp_[0]->RemoteNTP(&ntp_secs, &ntp_frac, nullptr, nullptr,
- &rtp_timestamp) != 0) {
+ if (rtp_rtcp_->RemoteNTP(&ntp_secs, &ntp_frac, nullptr, nullptr,
+ &rtp_timestamp) != 0) {
// Waiting for RTCP.
return true;
}
@@ -382,7 +379,7 @@
return false;
// Check if this is a retransmission.
int64_t min_rtt = 0;
- rtp_rtcp_[0]->RTT(rtp_receiver_->SSRC(), nullptr, nullptr, &min_rtt, nullptr);
+ rtp_rtcp_->RTT(rtp_receiver_->SSRC(), nullptr, nullptr, &min_rtt, nullptr);
return !in_order &&
statistician->IsRetransmitOfOldPacket(header, min_rtt);
}
diff --git a/video/vie_receiver.h b/video/vie_receiver.h
index 999e66d..c96bf5e 100644
--- a/video/vie_receiver.h
+++ b/video/vie_receiver.h
@@ -60,7 +60,7 @@
uint32_t GetRemoteSsrc() const;
int GetCsrcs(uint32_t* csrcs) const;
- void Init(const std::vector<RtpRtcp*>& modules);
+ void Init(RtpRtcp* rtp_rtcp);
RtpReceiver* GetRtpReceiver() const;
@@ -102,7 +102,7 @@
RemoteBitrateEstimator* const remote_bitrate_estimator_;
// TODO(pbos): Make const and set on construction.
- std::vector<RtpRtcp*> rtp_rtcp_;
+ RtpRtcp* rtp_rtcp_; // Owned by ViEChannel
RemoteNtpTimeEstimator ntp_estimator_;
RTPPayloadRegistry rtp_payload_registry_;