Add sending REMB support to RtcpTransceiver
Bug: webrtc:8239 Change-Id: If22de91a69b5752baf616520a247f2fdedacc220 Reviewed-on: https://webrtc-review.googlesource.com/22080 Commit-Queue: Danil Chapovalov <danilchap@webrtc.org> Reviewed-by: Niels Moller <nisse@webrtc.org> Cr-Commit-Position: refs/heads/master@{#20657}
This commit is contained in:
parent
b5b5bcee72
commit
d328229d38
@ -230,6 +230,7 @@ rtc_source_set("rtcp_transceiver") {
|
||||
deps = [
|
||||
":rtp_rtcp",
|
||||
"../../api:array_view",
|
||||
"../../api:optional",
|
||||
"../../api:transport_api",
|
||||
"../../rtc_base:rtc_base_approved",
|
||||
"../../rtc_base:rtc_task_queue",
|
||||
|
||||
@ -97,6 +97,21 @@ void RtcpTransceiverImpl::SendCompoundPacket() {
|
||||
ReschedulePeriodicCompoundPackets(config_.report_period_ms);
|
||||
}
|
||||
|
||||
void RtcpTransceiverImpl::SetRemb(int bitrate_bps,
|
||||
std::vector<uint32_t> ssrcs) {
|
||||
RTC_DCHECK_GE(bitrate_bps, 0);
|
||||
remb_.emplace();
|
||||
remb_->SetSsrcs(std::move(ssrcs));
|
||||
remb_->SetBitrateBps(bitrate_bps);
|
||||
// TODO(bugs.webrtc.org/8239): Move logic from PacketRouter for sending remb
|
||||
// immideately on large bitrate change when there is one RtcpTransceiver per
|
||||
// rtp transport.
|
||||
}
|
||||
|
||||
void RtcpTransceiverImpl::UnsetRemb() {
|
||||
remb_.reset();
|
||||
}
|
||||
|
||||
void RtcpTransceiverImpl::HandleReceivedPacket(
|
||||
const rtcp::CommonHeader& rtcp_packet_header) {
|
||||
switch (rtcp_packet_header.type()) {
|
||||
@ -149,9 +164,10 @@ void RtcpTransceiverImpl::ReschedulePeriodicCompoundPackets(int64_t delay_ms) {
|
||||
|
||||
void RtcpTransceiverImpl::SendPacket() {
|
||||
PacketSender sender(config_.outgoing_transport, config_.max_packet_size);
|
||||
const uint32_t sender_ssrc = config_.feedback_ssrc;
|
||||
|
||||
rtcp::ReceiverReport receiver_report;
|
||||
receiver_report.SetSenderSsrc(config_.feedback_ssrc);
|
||||
receiver_report.SetSenderSsrc(sender_ssrc);
|
||||
receiver_report.SetReportBlocks(CreateReportBlocks());
|
||||
sender.AppendPacket(receiver_report);
|
||||
|
||||
@ -162,6 +178,10 @@ void RtcpTransceiverImpl::SendPacket() {
|
||||
<< " to rtcp sdes packet.";
|
||||
sender.AppendPacket(sdes);
|
||||
}
|
||||
if (remb_) {
|
||||
remb_->SetSenderSsrc(sender_ssrc);
|
||||
sender.AppendPacket(*remb_);
|
||||
}
|
||||
|
||||
sender.Send();
|
||||
}
|
||||
|
||||
@ -17,7 +17,9 @@
|
||||
#include <vector>
|
||||
|
||||
#include "api/array_view.h"
|
||||
#include "api/optional.h"
|
||||
#include "modules/rtp_rtcp/source/rtcp_packet/common_header.h"
|
||||
#include "modules/rtp_rtcp/source/rtcp_packet/remb.h"
|
||||
#include "modules/rtp_rtcp/source/rtcp_packet/report_block.h"
|
||||
#include "modules/rtp_rtcp/source/rtcp_transceiver_config.h"
|
||||
#include "rtc_base/constructormagic.h"
|
||||
@ -40,6 +42,12 @@ class RtcpTransceiverImpl {
|
||||
// Sends RTCP packets starting with a sender or receiver report.
|
||||
void SendCompoundPacket();
|
||||
|
||||
// (REMB) Receiver Estimated Max Bitrate.
|
||||
// Includes REMB in following compound packets.
|
||||
void SetRemb(int bitrate_bps, std::vector<uint32_t> ssrcs);
|
||||
// Stops sending REMB in following compound packets.
|
||||
void UnsetRemb();
|
||||
|
||||
private:
|
||||
struct SenderReportTimes {
|
||||
int64_t local_received_time_us;
|
||||
@ -56,6 +64,7 @@ class RtcpTransceiverImpl {
|
||||
|
||||
const RtcpTransceiverConfig config_;
|
||||
|
||||
rtc::Optional<rtcp::Remb> remb_;
|
||||
std::map<uint32_t, SenderReportTimes> last_received_sender_reports_;
|
||||
rtc::WeakPtrFactory<RtcpTransceiverImpl> ptr_factory_;
|
||||
|
||||
|
||||
@ -26,6 +26,7 @@
|
||||
namespace {
|
||||
|
||||
using ::testing::_;
|
||||
using ::testing::ElementsAre;
|
||||
using ::testing::Invoke;
|
||||
using ::testing::Return;
|
||||
using ::testing::SizeIs;
|
||||
@ -208,6 +209,112 @@ TEST(RtcpTransceiverImplTest, SendsMinimalCompoundPacket) {
|
||||
EXPECT_EQ(rtcp_parser.sdes()->chunks()[0].cname, config.cname);
|
||||
}
|
||||
|
||||
TEST(RtcpTransceiverImplTest, SendsNoRembInitially) {
|
||||
const uint32_t kSenderSsrc = 12345;
|
||||
MockTransport outgoing_transport;
|
||||
RtcpTransceiverConfig config;
|
||||
config.feedback_ssrc = kSenderSsrc;
|
||||
config.outgoing_transport = &outgoing_transport;
|
||||
config.schedule_periodic_compound_packets = false;
|
||||
RtcpTransceiverImpl rtcp_transceiver(config);
|
||||
RtcpPacketParser rtcp_parser;
|
||||
EXPECT_CALL(outgoing_transport, SendRtcp(_, _))
|
||||
.WillOnce(Invoke(&rtcp_parser, &RtcpPacketParser::Parse));
|
||||
|
||||
rtcp_transceiver.SendCompoundPacket();
|
||||
|
||||
EXPECT_EQ(rtcp_parser.remb()->num_packets(), 0);
|
||||
}
|
||||
|
||||
TEST(RtcpTransceiverImplTest, SetRembIncludesRembInNextCompoundPacket) {
|
||||
const uint32_t kSenderSsrc = 12345;
|
||||
MockTransport outgoing_transport;
|
||||
RtcpTransceiverConfig config;
|
||||
config.feedback_ssrc = kSenderSsrc;
|
||||
config.outgoing_transport = &outgoing_transport;
|
||||
config.schedule_periodic_compound_packets = false;
|
||||
RtcpTransceiverImpl rtcp_transceiver(config);
|
||||
RtcpPacketParser rtcp_parser;
|
||||
EXPECT_CALL(outgoing_transport, SendRtcp(_, _))
|
||||
.WillOnce(Invoke(&rtcp_parser, &RtcpPacketParser::Parse));
|
||||
|
||||
rtcp_transceiver.SetRemb(/*bitrate_bps=*/10000, /*ssrc=*/{54321, 64321});
|
||||
rtcp_transceiver.SendCompoundPacket();
|
||||
|
||||
EXPECT_EQ(rtcp_parser.remb()->num_packets(), 1);
|
||||
EXPECT_EQ(rtcp_parser.remb()->sender_ssrc(), kSenderSsrc);
|
||||
EXPECT_EQ(rtcp_parser.remb()->bitrate_bps(), 10000u);
|
||||
EXPECT_THAT(rtcp_parser.remb()->ssrcs(), ElementsAre(54321, 64321));
|
||||
}
|
||||
|
||||
TEST(RtcpTransceiverImplTest, SetRembUpdatesValuesToSend) {
|
||||
const uint32_t kSenderSsrc = 12345;
|
||||
MockTransport outgoing_transport;
|
||||
RtcpTransceiverConfig config;
|
||||
config.feedback_ssrc = kSenderSsrc;
|
||||
config.outgoing_transport = &outgoing_transport;
|
||||
config.schedule_periodic_compound_packets = false;
|
||||
RtcpTransceiverImpl rtcp_transceiver(config);
|
||||
RtcpPacketParser rtcp_parser;
|
||||
EXPECT_CALL(outgoing_transport, SendRtcp(_, _))
|
||||
.WillRepeatedly(Invoke(&rtcp_parser, &RtcpPacketParser::Parse));
|
||||
|
||||
rtcp_transceiver.SetRemb(/*bitrate_bps=*/10000, /*ssrc=*/{54321, 64321});
|
||||
rtcp_transceiver.SendCompoundPacket();
|
||||
|
||||
EXPECT_EQ(rtcp_parser.remb()->num_packets(), 1);
|
||||
EXPECT_EQ(rtcp_parser.remb()->bitrate_bps(), 10000u);
|
||||
EXPECT_THAT(rtcp_parser.remb()->ssrcs(), ElementsAre(54321, 64321));
|
||||
|
||||
rtcp_transceiver.SetRemb(/*bitrate_bps=*/70000, /*ssrc=*/{67321});
|
||||
rtcp_transceiver.SendCompoundPacket();
|
||||
|
||||
EXPECT_EQ(rtcp_parser.remb()->num_packets(), 2);
|
||||
EXPECT_EQ(rtcp_parser.remb()->bitrate_bps(), 70000u);
|
||||
EXPECT_THAT(rtcp_parser.remb()->ssrcs(), ElementsAre(67321));
|
||||
}
|
||||
|
||||
TEST(RtcpTransceiverImplTest, SetRembIncludesRembInAllCompoundPackets) {
|
||||
const uint32_t kSenderSsrc = 12345;
|
||||
MockTransport outgoing_transport;
|
||||
RtcpTransceiverConfig config;
|
||||
config.feedback_ssrc = kSenderSsrc;
|
||||
config.outgoing_transport = &outgoing_transport;
|
||||
config.schedule_periodic_compound_packets = false;
|
||||
RtcpTransceiverImpl rtcp_transceiver(config);
|
||||
RtcpPacketParser rtcp_parser;
|
||||
EXPECT_CALL(outgoing_transport, SendRtcp(_, _))
|
||||
.WillRepeatedly(Invoke(&rtcp_parser, &RtcpPacketParser::Parse));
|
||||
|
||||
rtcp_transceiver.SetRemb(/*bitrate_bps=*/10000, /*ssrc=*/{54321, 64321});
|
||||
rtcp_transceiver.SendCompoundPacket();
|
||||
rtcp_transceiver.SendCompoundPacket();
|
||||
|
||||
EXPECT_EQ(rtcp_parser.remb()->num_packets(), 2);
|
||||
}
|
||||
|
||||
TEST(RtcpTransceiverImplTest, SendsNoRembAfterUnset) {
|
||||
const uint32_t kSenderSsrc = 12345;
|
||||
MockTransport outgoing_transport;
|
||||
RtcpTransceiverConfig config;
|
||||
config.feedback_ssrc = kSenderSsrc;
|
||||
config.outgoing_transport = &outgoing_transport;
|
||||
config.schedule_periodic_compound_packets = false;
|
||||
RtcpTransceiverImpl rtcp_transceiver(config);
|
||||
RtcpPacketParser rtcp_parser;
|
||||
EXPECT_CALL(outgoing_transport, SendRtcp(_, _))
|
||||
.WillRepeatedly(Invoke(&rtcp_parser, &RtcpPacketParser::Parse));
|
||||
|
||||
rtcp_transceiver.SetRemb(/*bitrate_bps=*/10000, /*ssrc=*/{54321, 64321});
|
||||
rtcp_transceiver.SendCompoundPacket();
|
||||
ASSERT_EQ(rtcp_parser.remb()->num_packets(), 1);
|
||||
|
||||
rtcp_transceiver.UnsetRemb();
|
||||
rtcp_transceiver.SendCompoundPacket();
|
||||
|
||||
EXPECT_EQ(rtcp_parser.remb()->num_packets(), 1);
|
||||
}
|
||||
|
||||
TEST(RtcpTransceiverImplTest, ReceiverReportUsesReceiveStatistics) {
|
||||
const uint32_t kSenderSsrc = 12345;
|
||||
const uint32_t kMediaSsrc = 54321;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user