diff --git a/webrtc/modules/rtp_rtcp/include/rtp_rtcp.h b/webrtc/modules/rtp_rtcp/include/rtp_rtcp.h index d01465b9f8..50fb35e0e4 100644 --- a/webrtc/modules/rtp_rtcp/include/rtp_rtcp.h +++ b/webrtc/modules/rtp_rtcp/include/rtp_rtcp.h @@ -210,10 +210,10 @@ class RtpRtcp : public Module { */ 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/webrtc/modules/rtp_rtcp/mocks/mock_rtp_rtcp.h b/webrtc/modules/rtp_rtcp/mocks/mock_rtp_rtcp.h index 9991aa2110..4cbb042428 100644 --- a/webrtc/modules/rtp_rtcp/mocks/mock_rtp_rtcp.h +++ b/webrtc/modules/rtp_rtcp/mocks/mock_rtp_rtcp.h @@ -85,12 +85,12 @@ class MockRtpRtcp : public RtpRtcp { 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/webrtc/modules/rtp_rtcp/source/rtcp_sender.cc b/webrtc/modules/rtp_rtcp/source/rtcp_sender.cc index 95bfeeea1f..7579a36edc 100644 --- a/webrtc/modules/rtp_rtcp/source/rtcp_sender.cc +++ b/webrtc/modules/rtp_rtcp/source/rtcp_sender.cc @@ -871,11 +871,13 @@ void RTCPSender::PrepareReport(const std::set& packetTypes, 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/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.cc b/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.cc index 64f64d8d14..ec767d8336 100644 --- a/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.cc +++ b/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.cc @@ -300,30 +300,21 @@ void ModuleRtpRtcpImpl::SetSequenceNumber(const uint16_t seq_num) { 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/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.h b/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.h index ec8e84acf1..997a19b9ad 100644 --- a/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.h +++ b/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.h @@ -75,8 +75,10 @@ class ModuleRtpRtcpImpl : public RtpRtcp { // 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/webrtc/video/encoder_state_feedback.cc b/webrtc/video/encoder_state_feedback.cc index 0240e487a6..52f51114fa 100644 --- a/webrtc/video/encoder_state_feedback.cc +++ b/webrtc/video/encoder_state_feedback.cc @@ -25,13 +25,6 @@ void EncoderStateFeedback::Init(const std::vector& ssrcs, 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/webrtc/video/encoder_state_feedback.h b/webrtc/video/encoder_state_feedback.h index 6326bed9c1..57595a0a69 100644 --- a/webrtc/video/encoder_state_feedback.h +++ b/webrtc/video/encoder_state_feedback.h @@ -31,12 +31,6 @@ class EncoderStateFeedback : public RtcpIntraFrameObserver { // Adds an encoder to receive feedback for a set of SSRCs. void Init(const std::vector& 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/webrtc/video/payload_router.cc b/webrtc/video/payload_router.cc index 968d82df62..d466e41bb0 100644 --- a/webrtc/video/payload_router.cc +++ b/webrtc/video/payload_router.cc @@ -16,8 +16,10 @@ namespace webrtc { -PayloadRouter::PayloadRouter() - : active_(false), num_sending_modules_(0) {} +PayloadRouter::PayloadRouter(const std::vector& rtp_modules) + : active_(false), num_sending_modules_(1), rtp_modules_(rtp_modules) { + UpdateModuleSendingState(); +} PayloadRouter::~PayloadRouter() {} @@ -26,12 +28,6 @@ size_t PayloadRouter::DefaultMaxPayloadLength() { return IP_PACKET_SIZE - kIpUdpSrtpLength; } -void PayloadRouter::Init( - const std::vector& 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/webrtc/video/payload_router.h b/webrtc/video/payload_router.h index 9eaf716322..81ec0dd4b1 100644 --- a/webrtc/video/payload_router.h +++ b/webrtc/video/payload_router.h @@ -29,14 +29,11 @@ struct RTPVideoHeader; // 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& rtp_modules); ~PayloadRouter(); static size_t DefaultMaxPayloadLength(); - - // Rtp modules are assumed to be sorted in simulcast index order. - void Init(const std::vector& 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 @@ class PayloadRouter { private: void UpdateModuleSendingState() EXCLUSIVE_LOCKS_REQUIRED(crit_); - // TODO(pbos): Set once and for all on construction and make const. - std::vector 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 rtp_modules_; + RTC_DISALLOW_COPY_AND_ASSIGN(PayloadRouter); }; diff --git a/webrtc/video/payload_router_unittest.cc b/webrtc/video/payload_router_unittest.cc index 5b3dc9340a..c5d3f3865f 100644 --- a/webrtc/video/payload_router_unittest.cc +++ b/webrtc/video/payload_router_unittest.cc @@ -23,20 +23,12 @@ using ::testing::Return; namespace webrtc { -class PayloadRouterTest : public ::testing::Test { - protected: - virtual void SetUp() { - payload_router_.reset(new PayloadRouter()); - } - std::unique_ptr payload_router_; -}; - -TEST_F(PayloadRouterTest, SendOnOneModule) { +TEST(PayloadRouterTest, SendOnOneModule) { MockRtpRtcp rtp; std::vector 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 @@ TEST_F(PayloadRouterTest, SendOnOneModule) { 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 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 @@ TEST_F(PayloadRouterTest, SendSimulcast) { 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 @@ TEST_F(PayloadRouterTest, SendSimulcast) { .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 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 @@ TEST_F(PayloadRouterTest, MaxPayloadLength) { 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 @@ TEST_F(PayloadRouterTest, MaxPayloadLength) { 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 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 @@ TEST_F(PayloadRouterTest, SetTargetSendBitrates) { .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/webrtc/video/video_receive_stream.cc b/webrtc/video/video_receive_stream.cc index a34544d448..131469fe67 100644 --- a/webrtc/video/video_receive_stream.cc +++ b/webrtc/video/video_receive_stream.cc @@ -172,21 +172,15 @@ VideoReceiveStream::VideoReceiveStream( 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/webrtc/video/video_send_stream.cc b/webrtc/video/video_send_stream.cc index 1c6638ebf4..baec5a23d4 100644 --- a/webrtc/video/video_send_stream.cc +++ b/webrtc/video/video_send_stream.cc @@ -34,6 +34,52 @@ namespace webrtc { class RtcpIntraFrameObserver; class TransportFeedbackObserver; +static const int kMinSendSidePacketHistorySize = 600; + +namespace { + +std::vector 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 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 @@ VideoSendStream::VideoSendStream( 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 @@ VideoSendStream::VideoSendStream( 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 @@ VideoSendStream::VideoSendStream( 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 @@ VideoSendStream::VideoSendStream( 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 @@ VideoSendStream::VideoSendStream( ReconfigureVideoEncoder(encoder_config); - vie_channel_.RegisterSendSideDelayObserver(&stats_proxy_); - if (config_.post_encode_callback) vie_encoder_.RegisterPostEncodeImageCallback(&encoded_frame_proxy_); @@ -305,10 +327,6 @@ VideoSendStream::VideoSendStream( 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 @@ VideoSendStream::~VideoSendStream() { 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 @@ void VideoSendStream::Start() { // Was not already started, trigger a keyframe. vie_encoder_.SendKeyFrame(); vie_encoder_.Restart(); - vie_receiver_->StartReceive(); } void VideoSendStream::Stop() { @@ -370,7 +382,6 @@ void VideoSendStream::Stop() { 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 @@ void VideoSendStream::ReconfigureVideoEncoder( } 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 @@ void VideoSendStream::NormalUsage() { 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(config_.rtp.fec.red_payload_type); + payload_type_fec = + static_cast(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 @@ void VideoSendStream::ConfigureSsrcs() { // 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 @@ void VideoSendStream::ConfigureSsrcs() { 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 VideoSendStream::GetRtpStates() const { std::map 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 @@ void VideoSendStream::OnBitrateUpdated(uint32_t bitrate_bps, 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/webrtc/video/video_send_stream.h b/webrtc/video/video_send_stream.h index 8b3d064f3e..688e8fc60f 100644 --- a/webrtc/video/video_send_stream.h +++ b/webrtc/video/video_send_stream.h @@ -42,7 +42,8 @@ namespace internal { 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 @@ class VideoSendStream : public webrtc::VideoSendStream, 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 @@ class VideoSendStream : public webrtc::VideoSendStream, 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 bandwidth_observer_; + // RtpRtcp modules, declared here as they use other members on construction. const std::vector rtp_rtcp_modules_; + PayloadRouter payload_router_; VideoCaptureInput input_; }; } // namespace internal diff --git a/webrtc/video/vie_channel.cc b/webrtc/video/vie_channel.cc index c0676bc83b..842558b7b4 100644 --- a/webrtc/video/vie_channel.cc +++ b/webrtc/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 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 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 @@ class ChannelStatsObserver : public CallStatsObserver { 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 @@ int32_t ViEChannel::Init() { 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); - } - 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); + rtp_rtcp_->SetKeyFrameRequestMethod(kKeyFrameReqPliRtcp); + if (vcm_->RegisterReceiveCallback(this) != 0) { + return -1; } + vcm_->RegisterFrameTypeCallback(this); + vcm_->RegisterReceiveStatisticsCallback(this); + vcm_->RegisterDecoderTimingCallback(this); + vcm_->SetRenderDelay(kDefaultRenderDelayMs); + return 0; } @@ -166,14 +146,9 @@ ViEChannel::~ViEChannel() { // 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 @@ void ViEChannel::SetProtectionMode(bool enable_nack, 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(payload_type_red), - static_cast(payload_type_fec)); - } + rtp_rtcp_->SetGenericFECStatus(enable_fec, + static_cast(payload_type_red), + static_cast(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 @@ int ViEChannel::GetRequiredNackListSize(int target_delay_ms) { } 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 @@ void ViEChannel::RegisterRtcpPacketTypeCounterObserver( 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& 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::FrameToRender(VideoFrame& video_frame) { // NOLINT 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 @@ void ViEChannel::OnDecoderTiming(int decode_ms, } 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(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 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 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 @@ int32_t ViEChannel::OnInitializeDecoder( } 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/webrtc/video/vie_channel.h b/webrtc/video/vie_channel.h index 8a9d70e58e..1bcae198c0 100644 --- a/webrtc/video/vie_channel.h +++ b/webrtc/video/vie_channel.h @@ -42,7 +42,6 @@ class PayloadRouter; class ProcessThread; class ReceiveStatisticsProxy; class RtcpRttStats; -class ViEChannelProtectionCallback; class ViERTPObserver; class VideoCodingModule; class VideoRenderCallback; @@ -61,21 +60,14 @@ class ViEChannel : public VCMFrameTypeCallback, 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 @@ class ViEChannel : public VCMFrameTypeCallback, 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 @@ class ViEChannel : public VCMFrameTypeCallback, 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& 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 @@ class ViEChannel : public VCMFrameTypeCallback, void RegisterPreRenderCallback(I420FrameCallback* pre_render_callback); - void RegisterSendFrameCountObserver(FrameCountObserver* observer); void RegisterRtcpPacketTypeCounterObserver( RtcpPacketTypeCounterObserver* observer); void RegisterReceiveStatisticsProxy( @@ -161,30 +141,7 @@ class ViEChannel : public VCMFrameTypeCallback, 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 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 @@ class ViEChannel : public VCMFrameTypeCallback, RTC_DISALLOW_COPY_AND_ASSIGN(RegisterableCallback); }; - class RegisterableBitrateStatisticsObserver: - public RegisterableCallback { - 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 { - 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 { - 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 { public: @@ -268,17 +190,12 @@ class ViEChannel : public VCMFrameTypeCallback, 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 vcm_protection_callback_; - VideoCodingModule* const vcm_; ViEReceiver vie_receiver_; @@ -289,21 +206,17 @@ class ViEChannel : public VCMFrameTypeCallback, 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 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 rtp_rtcp_modules_; + // RtpRtcp module, declared last as it use other members on construction. + const std::unique_ptr rtp_rtcp_; }; } // namespace webrtc diff --git a/webrtc/video/vie_receiver.cc b/webrtc/video/vie_receiver.cc index e5ec167fa7..9ead910f5c 100644 --- a/webrtc/video/vie_receiver.cc +++ b/webrtc/video/vie_receiver.cc @@ -124,8 +124,8 @@ int ViEReceiver::GetCsrcs(uint32_t* csrcs) const { return rtp_receiver_->CSRCs(csrcs); } -void ViEReceiver::Init(const std::vector& modules) { - rtp_rtcp_ = modules; +void ViEReceiver::Init(RtpRtcp* rtp_rtcp) { + rtp_rtcp_ = rtp_rtcp; } RtpReceiver* ViEReceiver::GetRtpReceiver() const { @@ -318,8 +318,6 @@ void ViEReceiver::NotifyReceiverOfFecPacket(const RTPHeader& header) { 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 @@ bool ViEReceiver::DeliverRtcp(const uint8_t* rtcp_packet, } } - 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 @@ bool ViEReceiver::DeliverRtcp(const uint8_t* rtcp_packet, 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 @@ bool ViEReceiver::IsPacketRetransmitted(const RTPHeader& header, 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/webrtc/video/vie_receiver.h b/webrtc/video/vie_receiver.h index 999e66d68b..c96bf5e107 100644 --- a/webrtc/video/vie_receiver.h +++ b/webrtc/video/vie_receiver.h @@ -60,7 +60,7 @@ class ViEReceiver : public RtpData { uint32_t GetRemoteSsrc() const; int GetCsrcs(uint32_t* csrcs) const; - void Init(const std::vector& modules); + void Init(RtpRtcp* rtp_rtcp); RtpReceiver* GetRtpReceiver() const; @@ -102,7 +102,7 @@ class ViEReceiver : public RtpData { RemoteBitrateEstimator* const remote_bitrate_estimator_; // TODO(pbos): Make const and set on construction. - std::vector rtp_rtcp_; + RtpRtcp* rtp_rtcp_; // Owned by ViEChannel RemoteNtpTimeEstimator ntp_estimator_; RTPPayloadRegistry rtp_payload_registry_;