Allow to turn RtcpTransciever on and off at runtime.
Bug: webrtc:8239 Change-Id: I8678d1ee9cd0da194a1243d40b508bb62cb3f257 Reviewed-on: https://webrtc-review.googlesource.com/60180 Commit-Queue: Danil Chapovalov <danilchap@webrtc.org> Reviewed-by: Niels Moller <nisse@webrtc.org> Cr-Commit-Position: refs/heads/master@{#22311}
This commit is contained in:

committed by
Commit Bot

parent
70473fcac4
commit
e3927c5885
@ -73,6 +73,14 @@ void RtcpTransceiver::RemoveMediaReceiverRtcpObserver(
|
|||||||
task_queue_->PostTaskAndReply(std::move(remove), std::move(on_removed));
|
task_queue_->PostTaskAndReply(std::move(remove), std::move(on_removed));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RtcpTransceiver::SetReadyToSend(bool ready) {
|
||||||
|
rtc::WeakPtr<RtcpTransceiverImpl> ptr = ptr_;
|
||||||
|
task_queue_->PostTask([ptr, ready] {
|
||||||
|
if (ptr)
|
||||||
|
ptr->SetReadyToSend(ready);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
void RtcpTransceiver::ReceivePacket(rtc::CopyOnWriteBuffer packet) {
|
void RtcpTransceiver::ReceivePacket(rtc::CopyOnWriteBuffer packet) {
|
||||||
rtc::WeakPtr<RtcpTransceiverImpl> ptr = ptr_;
|
rtc::WeakPtr<RtcpTransceiverImpl> ptr = ptr_;
|
||||||
int64_t now_us = rtc::TimeMicros();
|
int64_t now_us = rtc::TimeMicros();
|
||||||
|
@ -43,6 +43,11 @@ class RtcpTransceiver : public RtcpFeedbackSenderInterface {
|
|||||||
MediaReceiverRtcpObserver* observer,
|
MediaReceiverRtcpObserver* observer,
|
||||||
std::unique_ptr<rtc::QueuedTask> on_removed);
|
std::unique_ptr<rtc::QueuedTask> on_removed);
|
||||||
|
|
||||||
|
// Enables/disables sending rtcp packets eventually.
|
||||||
|
// Packets may be sent after the SetReadyToSend(false) returns, but no new
|
||||||
|
// packets will be scheduled.
|
||||||
|
void SetReadyToSend(bool ready);
|
||||||
|
|
||||||
// Handles incoming rtcp packets.
|
// Handles incoming rtcp packets.
|
||||||
void ReceivePacket(rtc::CopyOnWriteBuffer packet);
|
void ReceivePacket(rtc::CopyOnWriteBuffer packet);
|
||||||
|
|
||||||
|
@ -80,6 +80,8 @@ struct RtcpTransceiverConfig {
|
|||||||
//
|
//
|
||||||
// Tuning parameters.
|
// Tuning parameters.
|
||||||
//
|
//
|
||||||
|
// Initial state if |outgoing_transport| ready to accept packets.
|
||||||
|
bool initial_ready_to_send = true;
|
||||||
// Delay before 1st periodic compound packet.
|
// Delay before 1st periodic compound packet.
|
||||||
int initial_report_delay_ms = 500;
|
int initial_report_delay_ms = 500;
|
||||||
|
|
||||||
|
@ -86,9 +86,11 @@ class RtcpTransceiverImpl::PacketSender {
|
|||||||
};
|
};
|
||||||
|
|
||||||
RtcpTransceiverImpl::RtcpTransceiverImpl(const RtcpTransceiverConfig& config)
|
RtcpTransceiverImpl::RtcpTransceiverImpl(const RtcpTransceiverConfig& config)
|
||||||
: config_(config), ptr_factory_(this) {
|
: config_(config),
|
||||||
|
ready_to_send_(config.initial_ready_to_send),
|
||||||
|
ptr_factory_(this) {
|
||||||
RTC_CHECK(config_.Validate());
|
RTC_CHECK(config_.Validate());
|
||||||
if (config_.schedule_periodic_compound_packets)
|
if (ready_to_send_ && config_.schedule_periodic_compound_packets)
|
||||||
SchedulePeriodicCompoundPackets(config_.initial_report_delay_ms);
|
SchedulePeriodicCompoundPackets(config_.initial_report_delay_ms);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -115,6 +117,17 @@ void RtcpTransceiverImpl::RemoveMediaReceiverRtcpObserver(
|
|||||||
stored.erase(it);
|
stored.erase(it);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RtcpTransceiverImpl::SetReadyToSend(bool ready) {
|
||||||
|
if (config_.schedule_periodic_compound_packets) {
|
||||||
|
if (ready_to_send_ && !ready) // Stop existent send task.
|
||||||
|
ptr_factory_.InvalidateWeakPtrs();
|
||||||
|
|
||||||
|
if (!ready_to_send_ && ready) // Restart periodic sending.
|
||||||
|
SchedulePeriodicCompoundPackets(config_.report_period_ms / 2);
|
||||||
|
}
|
||||||
|
ready_to_send_ = ready;
|
||||||
|
}
|
||||||
|
|
||||||
void RtcpTransceiverImpl::ReceivePacket(rtc::ArrayView<const uint8_t> packet,
|
void RtcpTransceiverImpl::ReceivePacket(rtc::ArrayView<const uint8_t> packet,
|
||||||
int64_t now_us) {
|
int64_t now_us) {
|
||||||
while (!packet.empty()) {
|
while (!packet.empty()) {
|
||||||
@ -130,6 +143,8 @@ void RtcpTransceiverImpl::ReceivePacket(rtc::ArrayView<const uint8_t> packet,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void RtcpTransceiverImpl::SendCompoundPacket() {
|
void RtcpTransceiverImpl::SendCompoundPacket() {
|
||||||
|
if (!ready_to_send_)
|
||||||
|
return;
|
||||||
SendPeriodicCompoundPacket();
|
SendPeriodicCompoundPacket();
|
||||||
ReschedulePeriodicCompoundPackets();
|
ReschedulePeriodicCompoundPackets();
|
||||||
}
|
}
|
||||||
@ -150,6 +165,8 @@ void RtcpTransceiverImpl::UnsetRemb() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void RtcpTransceiverImpl::SendRawPacket(rtc::ArrayView<const uint8_t> packet) {
|
void RtcpTransceiverImpl::SendRawPacket(rtc::ArrayView<const uint8_t> packet) {
|
||||||
|
if (!ready_to_send_)
|
||||||
|
return;
|
||||||
// Unlike other senders, this functions just tries to send packet away and
|
// Unlike other senders, this functions just tries to send packet away and
|
||||||
// disregard rtcp_mode, max_packet_size or anything else.
|
// disregard rtcp_mode, max_packet_size or anything else.
|
||||||
// TODO(bugs.webrtc.org/8239): respect config_ by creating the
|
// TODO(bugs.webrtc.org/8239): respect config_ by creating the
|
||||||
@ -160,6 +177,8 @@ void RtcpTransceiverImpl::SendRawPacket(rtc::ArrayView<const uint8_t> packet) {
|
|||||||
void RtcpTransceiverImpl::SendNack(uint32_t ssrc,
|
void RtcpTransceiverImpl::SendNack(uint32_t ssrc,
|
||||||
std::vector<uint16_t> sequence_numbers) {
|
std::vector<uint16_t> sequence_numbers) {
|
||||||
RTC_DCHECK(!sequence_numbers.empty());
|
RTC_DCHECK(!sequence_numbers.empty());
|
||||||
|
if (!ready_to_send_)
|
||||||
|
return;
|
||||||
rtcp::Nack nack;
|
rtcp::Nack nack;
|
||||||
nack.SetSenderSsrc(config_.feedback_ssrc);
|
nack.SetSenderSsrc(config_.feedback_ssrc);
|
||||||
nack.SetMediaSsrc(ssrc);
|
nack.SetMediaSsrc(ssrc);
|
||||||
@ -168,6 +187,8 @@ void RtcpTransceiverImpl::SendNack(uint32_t ssrc,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void RtcpTransceiverImpl::SendPictureLossIndication(uint32_t ssrc) {
|
void RtcpTransceiverImpl::SendPictureLossIndication(uint32_t ssrc) {
|
||||||
|
if (!ready_to_send_)
|
||||||
|
return;
|
||||||
rtcp::Pli pli;
|
rtcp::Pli pli;
|
||||||
pli.SetSenderSsrc(config_.feedback_ssrc);
|
pli.SetSenderSsrc(config_.feedback_ssrc);
|
||||||
pli.SetMediaSsrc(ssrc);
|
pli.SetMediaSsrc(ssrc);
|
||||||
@ -177,6 +198,8 @@ void RtcpTransceiverImpl::SendPictureLossIndication(uint32_t ssrc) {
|
|||||||
void RtcpTransceiverImpl::SendFullIntraRequest(
|
void RtcpTransceiverImpl::SendFullIntraRequest(
|
||||||
rtc::ArrayView<const uint32_t> ssrcs) {
|
rtc::ArrayView<const uint32_t> ssrcs) {
|
||||||
RTC_DCHECK(!ssrcs.empty());
|
RTC_DCHECK(!ssrcs.empty());
|
||||||
|
if (!ready_to_send_)
|
||||||
|
return;
|
||||||
rtcp::Fir fir;
|
rtcp::Fir fir;
|
||||||
fir.SetSenderSsrc(config_.feedback_ssrc);
|
fir.SetSenderSsrc(config_.feedback_ssrc);
|
||||||
for (uint32_t media_ssrc : ssrcs)
|
for (uint32_t media_ssrc : ssrcs)
|
||||||
|
@ -43,6 +43,8 @@ class RtcpTransceiverImpl {
|
|||||||
void RemoveMediaReceiverRtcpObserver(uint32_t remote_ssrc,
|
void RemoveMediaReceiverRtcpObserver(uint32_t remote_ssrc,
|
||||||
MediaReceiverRtcpObserver* observer);
|
MediaReceiverRtcpObserver* observer);
|
||||||
|
|
||||||
|
void SetReadyToSend(bool ready);
|
||||||
|
|
||||||
void ReceivePacket(rtc::ArrayView<const uint8_t> packet, int64_t now_us);
|
void ReceivePacket(rtc::ArrayView<const uint8_t> packet, int64_t now_us);
|
||||||
|
|
||||||
void SendCompoundPacket();
|
void SendCompoundPacket();
|
||||||
@ -88,6 +90,7 @@ class RtcpTransceiverImpl {
|
|||||||
|
|
||||||
const RtcpTransceiverConfig config_;
|
const RtcpTransceiverConfig config_;
|
||||||
|
|
||||||
|
bool ready_to_send_;
|
||||||
rtc::Optional<rtcp::Remb> remb_;
|
rtc::Optional<rtcp::Remb> remb_;
|
||||||
// TODO(danilchap): Remove entries from remote_senders_ that are no longer
|
// TODO(danilchap): Remove entries from remote_senders_ that are no longer
|
||||||
// needed.
|
// needed.
|
||||||
|
@ -130,6 +130,8 @@ RtcpTransceiverConfig DefaultTestConfig() {
|
|||||||
RtcpTransceiverConfig config;
|
RtcpTransceiverConfig config;
|
||||||
config.outgoing_transport = &null_transport;
|
config.outgoing_transport = &null_transport;
|
||||||
config.schedule_periodic_compound_packets = false;
|
config.schedule_periodic_compound_packets = false;
|
||||||
|
config.initial_report_delay_ms = 10;
|
||||||
|
config.report_period_ms = kReportPeriodMs;
|
||||||
return config;
|
return config;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -235,6 +237,71 @@ TEST(RtcpTransceiverImplTest, SendCompoundPacketDelaysPeriodicSendPackets) {
|
|||||||
ASSERT_TRUE(done.Wait(kAlmostForeverMs));
|
ASSERT_TRUE(done.Wait(kAlmostForeverMs));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(RtcpTransceiverImplTest, SendsNoRtcpWhenNetworkStateIsDown) {
|
||||||
|
MockTransport mock_transport;
|
||||||
|
RtcpTransceiverConfig config = DefaultTestConfig();
|
||||||
|
config.initial_ready_to_send = false;
|
||||||
|
config.outgoing_transport = &mock_transport;
|
||||||
|
RtcpTransceiverImpl rtcp_transceiver(config);
|
||||||
|
|
||||||
|
|
||||||
|
EXPECT_CALL(mock_transport, SendRtcp(_, _)).Times(0);
|
||||||
|
|
||||||
|
const uint8_t raw[] = {1, 2, 3, 4};
|
||||||
|
const std::vector<uint16_t> sequence_numbers = {45, 57};
|
||||||
|
const uint32_t ssrcs[] = {123};
|
||||||
|
rtcp_transceiver.SendCompoundPacket();
|
||||||
|
rtcp_transceiver.SendRawPacket(raw);
|
||||||
|
rtcp_transceiver.SendNack(ssrcs[0], sequence_numbers);
|
||||||
|
rtcp_transceiver.SendPictureLossIndication(ssrcs[0]);
|
||||||
|
rtcp_transceiver.SendFullIntraRequest(ssrcs);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(RtcpTransceiverImplTest, SendsRtcpWhenNetworkStateIsUp) {
|
||||||
|
MockTransport mock_transport;
|
||||||
|
RtcpTransceiverConfig config = DefaultTestConfig();
|
||||||
|
config.initial_ready_to_send = false;
|
||||||
|
config.outgoing_transport = &mock_transport;
|
||||||
|
RtcpTransceiverImpl rtcp_transceiver(config);
|
||||||
|
|
||||||
|
rtcp_transceiver.SetReadyToSend(true);
|
||||||
|
|
||||||
|
EXPECT_CALL(mock_transport, SendRtcp(_, _)).Times(5);
|
||||||
|
|
||||||
|
const uint8_t raw[] = {1, 2, 3, 4};
|
||||||
|
const std::vector<uint16_t> sequence_numbers = {45, 57};
|
||||||
|
const uint32_t ssrcs[] = {123};
|
||||||
|
rtcp_transceiver.SendCompoundPacket();
|
||||||
|
rtcp_transceiver.SendRawPacket(raw);
|
||||||
|
rtcp_transceiver.SendNack(ssrcs[0], sequence_numbers);
|
||||||
|
rtcp_transceiver.SendPictureLossIndication(ssrcs[0]);
|
||||||
|
rtcp_transceiver.SendFullIntraRequest(ssrcs);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(RtcpTransceiverImplTest, SendsPeriodicRtcpWhenNetworkStateIsUp) {
|
||||||
|
rtc::TaskQueue queue("rtcp");
|
||||||
|
FakeRtcpTransport transport;
|
||||||
|
RtcpTransceiverConfig config = DefaultTestConfig();
|
||||||
|
config.schedule_periodic_compound_packets = true;
|
||||||
|
config.initial_ready_to_send = false;
|
||||||
|
config.outgoing_transport = &transport;
|
||||||
|
config.task_queue = &queue;
|
||||||
|
rtc::Optional<RtcpTransceiverImpl> rtcp_transceiver;
|
||||||
|
rtcp_transceiver.emplace(config);
|
||||||
|
|
||||||
|
rtcp_transceiver->SetReadyToSend(true);
|
||||||
|
|
||||||
|
EXPECT_TRUE(transport.WaitPacket());
|
||||||
|
|
||||||
|
// Cleanup.
|
||||||
|
rtc::Event done(false, false);
|
||||||
|
queue.PostTask([&] {
|
||||||
|
rtcp_transceiver.reset();
|
||||||
|
done.Set();
|
||||||
|
});
|
||||||
|
ASSERT_TRUE(done.Wait(kAlmostForeverMs));
|
||||||
|
}
|
||||||
|
|
||||||
TEST(RtcpTransceiverImplTest, SendsMinimalCompoundPacket) {
|
TEST(RtcpTransceiverImplTest, SendsMinimalCompoundPacket) {
|
||||||
const uint32_t kSenderSsrc = 12345;
|
const uint32_t kSenderSsrc = 12345;
|
||||||
RtcpTransceiverConfig config;
|
RtcpTransceiverConfig config;
|
||||||
|
Reference in New Issue
Block a user