Removes deprecated InsertPacket/TimeToSendPacket/TimeToSendPadding
The methods are no longer in use, this CL cleans away references and updates any tests using them. Bug: webrtc:10633 Change-Id: I2db301e0a021a2f85a8b9a74e409303baba407da Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/150520 Reviewed-by: Stefan Holmer <stefan@webrtc.org> Reviewed-by: Sebastian Jansson <srte@webrtc.org> Commit-Queue: Erik Språng <sprang@webrtc.org> Cr-Commit-Position: refs/heads/master@{#28956}
This commit is contained in:
@ -385,20 +385,6 @@ class RtpPacketSenderProxy : public RtpPacketSender {
|
|||||||
rtp_packet_pacer_->EnqueuePacket(std::move(packet));
|
rtp_packet_pacer_->EnqueuePacket(std::move(packet));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Implements RtpPacketSender.
|
|
||||||
void InsertPacket(Priority priority,
|
|
||||||
uint32_t ssrc,
|
|
||||||
uint16_t sequence_number,
|
|
||||||
int64_t capture_time_ms,
|
|
||||||
size_t bytes,
|
|
||||||
bool retransmission) override {
|
|
||||||
rtc::CritScope lock(&crit_);
|
|
||||||
if (rtp_packet_pacer_) {
|
|
||||||
rtp_packet_pacer_->InsertPacket(priority, ssrc, sequence_number,
|
|
||||||
capture_time_ms, bytes, retransmission);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
rtc::ThreadChecker thread_checker_;
|
rtc::ThreadChecker thread_checker_;
|
||||||
rtc::CriticalSection crit_;
|
rtc::CriticalSection crit_;
|
||||||
|
|||||||
@ -11,6 +11,7 @@
|
|||||||
#ifndef MODULES_PACING_MOCK_MOCK_PACED_SENDER_H_
|
#ifndef MODULES_PACING_MOCK_MOCK_PACED_SENDER_H_
|
||||||
#define MODULES_PACING_MOCK_MOCK_PACED_SENDER_H_
|
#define MODULES_PACING_MOCK_MOCK_PACED_SENDER_H_
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "modules/pacing/paced_sender.h"
|
#include "modules/pacing/paced_sender.h"
|
||||||
@ -23,20 +24,12 @@ class MockPacedSender : public PacedSender {
|
|||||||
public:
|
public:
|
||||||
MockPacedSender()
|
MockPacedSender()
|
||||||
: PacedSender(Clock::GetRealTimeClock(), nullptr, nullptr) {}
|
: PacedSender(Clock::GetRealTimeClock(), nullptr, nullptr) {}
|
||||||
MOCK_METHOD6(SendPacket,
|
MOCK_METHOD1(EnqueuePacket, void(std::unique_ptr<RtpPacketToSend> packet));
|
||||||
bool(Priority priority,
|
|
||||||
uint32_t ssrc,
|
|
||||||
uint16_t sequence_number,
|
|
||||||
int64_t capture_time_ms,
|
|
||||||
size_t bytes,
|
|
||||||
bool retransmission));
|
|
||||||
MOCK_METHOD2(CreateProbeCluster, void(DataRate, int));
|
MOCK_METHOD2(CreateProbeCluster, void(DataRate, int));
|
||||||
MOCK_METHOD1(SetEstimatedBitrate, void(uint32_t));
|
|
||||||
MOCK_METHOD2(SetPacingRates, void(DataRate, DataRate));
|
MOCK_METHOD2(SetPacingRates, void(DataRate, DataRate));
|
||||||
MOCK_CONST_METHOD0(QueueInMs, int64_t());
|
MOCK_CONST_METHOD0(OldestPacketWaitTime, TimeDelta());
|
||||||
MOCK_CONST_METHOD0(QueueInPackets, int());
|
MOCK_CONST_METHOD0(QueueSizePackets, size_t());
|
||||||
MOCK_CONST_METHOD0(ExpectedQueueTimeMs, int64_t());
|
MOCK_CONST_METHOD0(ExpectedQueueTime, TimeDelta());
|
||||||
MOCK_METHOD0(GetApplicationLimitedRegionStartTime, absl::optional<int64_t>());
|
|
||||||
MOCK_METHOD0(Process, void());
|
MOCK_METHOD0(Process, void());
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -83,17 +83,6 @@ void PacedSender::SetPacingRates(DataRate pacing_rate, DataRate padding_rate) {
|
|||||||
pacing_controller_.SetPacingRates(pacing_rate, padding_rate);
|
pacing_controller_.SetPacingRates(pacing_rate, padding_rate);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PacedSender::InsertPacket(RtpPacketSender::Priority priority,
|
|
||||||
uint32_t ssrc,
|
|
||||||
uint16_t sequence_number,
|
|
||||||
int64_t capture_time_ms,
|
|
||||||
size_t bytes,
|
|
||||||
bool retransmission) {
|
|
||||||
rtc::CritScope cs(&critsect_);
|
|
||||||
pacing_controller_.InsertPacket(priority, ssrc, sequence_number,
|
|
||||||
capture_time_ms, bytes, retransmission);
|
|
||||||
}
|
|
||||||
|
|
||||||
void PacedSender::EnqueuePacket(std::unique_ptr<RtpPacketToSend> packet) {
|
void PacedSender::EnqueuePacket(std::unique_ptr<RtpPacketToSend> packet) {
|
||||||
rtc::CritScope cs(&critsect_);
|
rtc::CritScope cs(&critsect_);
|
||||||
pacing_controller_.EnqueuePacket(std::move(packet));
|
pacing_controller_.EnqueuePacket(std::move(packet));
|
||||||
|
|||||||
@ -65,14 +65,6 @@ class PacedSender : public Module,
|
|||||||
|
|
||||||
// Methods implementing RtpPacketSender.
|
// Methods implementing RtpPacketSender.
|
||||||
|
|
||||||
// Adds the packet information to the queue and calls TimeToSendPacket
|
|
||||||
// when it's time to send.
|
|
||||||
void InsertPacket(RtpPacketSender::Priority priority,
|
|
||||||
uint32_t ssrc,
|
|
||||||
uint16_t sequence_number,
|
|
||||||
int64_t capture_time_ms,
|
|
||||||
size_t bytes,
|
|
||||||
bool retransmission) override;
|
|
||||||
// Adds the packet to the queue and calls PacketRouter::SendPacket() when
|
// Adds the packet to the queue and calls PacketRouter::SendPacket() when
|
||||||
// it's time to send.
|
// it's time to send.
|
||||||
void EnqueuePacket(std::unique_ptr<RtpPacketToSend> packet) override;
|
void EnqueuePacket(std::unique_ptr<RtpPacketToSend> packet) override;
|
||||||
|
|||||||
@ -42,15 +42,6 @@ namespace test {
|
|||||||
// Mock callback implementing the raw api.
|
// Mock callback implementing the raw api.
|
||||||
class MockCallback : public PacketRouter {
|
class MockCallback : public PacketRouter {
|
||||||
public:
|
public:
|
||||||
MOCK_METHOD5(TimeToSendPacket,
|
|
||||||
RtpPacketSendResult(uint32_t ssrc,
|
|
||||||
uint16_t sequence_number,
|
|
||||||
int64_t capture_time_ms,
|
|
||||||
bool retransmission,
|
|
||||||
const PacedPacketInfo& pacing_info));
|
|
||||||
MOCK_METHOD2(TimeToSendPadding,
|
|
||||||
size_t(size_t bytes, const PacedPacketInfo& pacing_info));
|
|
||||||
|
|
||||||
MOCK_METHOD2(SendPacket,
|
MOCK_METHOD2(SendPacket,
|
||||||
void(std::unique_ptr<RtpPacketToSend> packet,
|
void(std::unique_ptr<RtpPacketToSend> packet,
|
||||||
const PacedPacketInfo& cluster_info));
|
const PacedPacketInfo& cluster_info));
|
||||||
|
|||||||
@ -184,15 +184,6 @@ void PacingController::SetPacingRates(DataRate pacing_rate,
|
|||||||
<< " padding_budget_kbps=" << padding_rate.kbps();
|
<< " padding_budget_kbps=" << padding_rate.kbps();
|
||||||
}
|
}
|
||||||
|
|
||||||
void PacingController::InsertPacket(RtpPacketSender::Priority priority,
|
|
||||||
uint32_t ssrc,
|
|
||||||
uint16_t sequence_number,
|
|
||||||
int64_t capture_time_ms,
|
|
||||||
size_t bytes,
|
|
||||||
bool retransmission) {
|
|
||||||
RTC_NOTREACHED();
|
|
||||||
}
|
|
||||||
|
|
||||||
void PacingController::EnqueuePacket(std::unique_ptr<RtpPacketToSend> packet) {
|
void PacingController::EnqueuePacket(std::unique_ptr<RtpPacketToSend> packet) {
|
||||||
RTC_DCHECK(pacing_bitrate_ > DataRate::Zero())
|
RTC_DCHECK(pacing_bitrate_ > DataRate::Zero())
|
||||||
<< "SetPacingRate must be called before InsertPacket.";
|
<< "SetPacingRate must be called before InsertPacket.";
|
||||||
|
|||||||
@ -76,14 +76,6 @@ class PacingController {
|
|||||||
|
|
||||||
~PacingController();
|
~PacingController();
|
||||||
|
|
||||||
// Adds the packet information to the queue and calls TimeToSendPacket
|
|
||||||
// when it's time to send.
|
|
||||||
void InsertPacket(RtpPacketSender::Priority priority,
|
|
||||||
uint32_t ssrc,
|
|
||||||
uint16_t sequence_number,
|
|
||||||
int64_t capture_time_ms,
|
|
||||||
size_t bytes,
|
|
||||||
bool retransmission);
|
|
||||||
// Adds the packet to the queue and calls PacketRouter::SendPacket() when
|
// Adds the packet to the queue and calls PacketRouter::SendPacket() when
|
||||||
// it's time to send.
|
// it's time to send.
|
||||||
void EnqueuePacket(std::unique_ptr<RtpPacketToSend> packet);
|
void EnqueuePacket(std::unique_ptr<RtpPacketToSend> packet);
|
||||||
|
|||||||
@ -54,7 +54,7 @@ void PacketRouter::AddSendRtpModule(RtpRtcp* rtp_module, bool remb_candidate) {
|
|||||||
rtp_module) == rtp_send_modules_.end());
|
rtp_module) == rtp_send_modules_.end());
|
||||||
// Put modules which can use regular payload packets (over rtx) instead of
|
// Put modules which can use regular payload packets (over rtx) instead of
|
||||||
// padding first as it's less of a waste
|
// padding first as it's less of a waste
|
||||||
if ((rtp_module->RtxSendStatus() & kRtxRedundantPayloads) > 0) {
|
if (rtp_module->SupportsRtxPayloadPadding()) {
|
||||||
rtp_send_modules_.push_front(rtp_module);
|
rtp_send_modules_.push_front(rtp_module);
|
||||||
} else {
|
} else {
|
||||||
rtp_send_modules_.push_back(rtp_module);
|
rtp_send_modules_.push_back(rtp_module);
|
||||||
@ -102,29 +102,6 @@ void PacketRouter::RemoveReceiveRtpModule(
|
|||||||
rtcp_feedback_senders_.erase(it);
|
rtcp_feedback_senders_.erase(it);
|
||||||
}
|
}
|
||||||
|
|
||||||
RtpPacketSendResult PacketRouter::TimeToSendPacket(
|
|
||||||
uint32_t ssrc,
|
|
||||||
uint16_t sequence_number,
|
|
||||||
int64_t capture_timestamp,
|
|
||||||
bool retransmission,
|
|
||||||
const PacedPacketInfo& pacing_info) {
|
|
||||||
rtc::CritScope cs(&modules_crit_);
|
|
||||||
RtpRtcp* rtp_module = FindRtpModule(ssrc);
|
|
||||||
if (rtp_module == nullptr || !rtp_module->SendingMedia()) {
|
|
||||||
return RtpPacketSendResult::kPacketNotFound;
|
|
||||||
}
|
|
||||||
|
|
||||||
RtpPacketSendResult result = rtp_module->TimeToSendPacket(
|
|
||||||
ssrc, sequence_number, capture_timestamp, retransmission, pacing_info);
|
|
||||||
if (result == RtpPacketSendResult::kSuccess &&
|
|
||||||
rtp_module->SupportsRtxPayloadPadding()) {
|
|
||||||
// This is now the last module to send media, and has the desired
|
|
||||||
// properties needed for payload based padding. Cache it for later use.
|
|
||||||
last_send_module_ = rtp_module;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
RtpRtcp* PacketRouter::FindRtpModule(uint32_t ssrc) {
|
RtpRtcp* PacketRouter::FindRtpModule(uint32_t ssrc) {
|
||||||
auto it = rtp_module_cache_map_.find(ssrc);
|
auto it = rtp_module_cache_map_.find(ssrc);
|
||||||
if (it != rtp_module_cache_map_.end()) {
|
if (it != rtp_module_cache_map_.end()) {
|
||||||
@ -150,7 +127,7 @@ void PacketRouter::SendPacket(std::unique_ptr<RtpPacketToSend> packet,
|
|||||||
// With the new pacer code path, transport sequence numbers are only set here,
|
// With the new pacer code path, transport sequence numbers are only set here,
|
||||||
// on the pacer thread. Therefore we don't need atomics/synchronization.
|
// on the pacer thread. Therefore we don't need atomics/synchronization.
|
||||||
if (packet->IsExtensionReserved<TransportSequenceNumber>()) {
|
if (packet->IsExtensionReserved<TransportSequenceNumber>()) {
|
||||||
packet->SetExtension<TransportSequenceNumber>(++transport_seq_);
|
packet->SetExtension<TransportSequenceNumber>(AllocateSequenceNumber());
|
||||||
}
|
}
|
||||||
|
|
||||||
auto it = rtp_module_cache_map_.find(packet->Ssrc());
|
auto it = rtp_module_cache_map_.find(packet->Ssrc());
|
||||||
@ -175,41 +152,6 @@ void PacketRouter::SendPacket(std::unique_ptr<RtpPacketToSend> packet,
|
|||||||
<< packet->SequenceNumber();
|
<< packet->SequenceNumber();
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t PacketRouter::TimeToSendPadding(size_t bytes_to_send,
|
|
||||||
const PacedPacketInfo& pacing_info) {
|
|
||||||
size_t total_bytes_sent = 0;
|
|
||||||
rtc::CritScope cs(&modules_crit_);
|
|
||||||
// First try on the last rtp module to have sent media. This increases the
|
|
||||||
// the chance that any payload based padding will be useful as it will be
|
|
||||||
// somewhat distributed over modules according the packet rate, even if it
|
|
||||||
// will be more skewed towards the highest bitrate stream. At the very least
|
|
||||||
// this prevents sending payload padding on a disabled stream where it's
|
|
||||||
// guaranteed not to be useful.
|
|
||||||
if (last_send_module_ != nullptr &&
|
|
||||||
last_send_module_->SupportsRtxPayloadPadding()) {
|
|
||||||
RTC_DCHECK(std::find(rtp_send_modules_.begin(), rtp_send_modules_.end(),
|
|
||||||
last_send_module_) != rtp_send_modules_.end());
|
|
||||||
total_bytes_sent += last_send_module_->TimeToSendPadding(
|
|
||||||
bytes_to_send - total_bytes_sent, pacing_info);
|
|
||||||
if (total_bytes_sent >= bytes_to_send) {
|
|
||||||
return total_bytes_sent;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Rtp modules are ordered by which stream can most benefit from padding.
|
|
||||||
// Don't require RTX payload padding in the general case.
|
|
||||||
for (RtpRtcp* module : rtp_send_modules_) {
|
|
||||||
if (module->SupportsPadding()) {
|
|
||||||
size_t bytes_sent = module->TimeToSendPadding(
|
|
||||||
bytes_to_send - total_bytes_sent, pacing_info);
|
|
||||||
total_bytes_sent += bytes_sent;
|
|
||||||
if (total_bytes_sent >= bytes_to_send)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return total_bytes_sent;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<std::unique_ptr<RtpPacketToSend>> PacketRouter::GeneratePadding(
|
std::vector<std::unique_ptr<RtpPacketToSend>> PacketRouter::GeneratePadding(
|
||||||
size_t target_size_bytes) {
|
size_t target_size_bytes) {
|
||||||
rtc::CritScope cs(&modules_crit_);
|
rtc::CritScope cs(&modules_crit_);
|
||||||
|
|||||||
@ -53,19 +53,9 @@ class PacketRouter : public TransportSequenceNumberAllocator,
|
|||||||
bool remb_candidate);
|
bool remb_candidate);
|
||||||
void RemoveReceiveRtpModule(RtcpFeedbackSenderInterface* rtcp_sender);
|
void RemoveReceiveRtpModule(RtcpFeedbackSenderInterface* rtcp_sender);
|
||||||
|
|
||||||
virtual RtpPacketSendResult TimeToSendPacket(
|
|
||||||
uint32_t ssrc,
|
|
||||||
uint16_t sequence_number,
|
|
||||||
int64_t capture_timestamp,
|
|
||||||
bool retransmission,
|
|
||||||
const PacedPacketInfo& packet_info);
|
|
||||||
|
|
||||||
virtual void SendPacket(std::unique_ptr<RtpPacketToSend> packet,
|
virtual void SendPacket(std::unique_ptr<RtpPacketToSend> packet,
|
||||||
const PacedPacketInfo& cluster_info);
|
const PacedPacketInfo& cluster_info);
|
||||||
|
|
||||||
virtual size_t TimeToSendPadding(size_t bytes,
|
|
||||||
const PacedPacketInfo& packet_info);
|
|
||||||
|
|
||||||
virtual std::vector<std::unique_ptr<RtpPacketToSend>> GeneratePadding(
|
virtual std::vector<std::unique_ptr<RtpPacketToSend>> GeneratePadding(
|
||||||
size_t target_size_bytes);
|
size_t target_size_bytes);
|
||||||
|
|
||||||
|
|||||||
@ -42,7 +42,6 @@ using ::testing::Le;
|
|||||||
using ::testing::NiceMock;
|
using ::testing::NiceMock;
|
||||||
using ::testing::Property;
|
using ::testing::Property;
|
||||||
using ::testing::Return;
|
using ::testing::Return;
|
||||||
using ::testing::ReturnPointee;
|
|
||||||
using ::testing::SaveArg;
|
using ::testing::SaveArg;
|
||||||
|
|
||||||
constexpr int kProbeMinProbes = 5;
|
constexpr int kProbeMinProbes = 5;
|
||||||
@ -50,217 +49,54 @@ constexpr int kProbeMinBytes = 1000;
|
|||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
TEST(PacketRouterTest, Sanity_NoModuleRegistered_TimeToSendPacket) {
|
class PacketRouterTest : public ::testing::Test {
|
||||||
PacketRouter packet_router;
|
public:
|
||||||
|
PacketRouterTest() {
|
||||||
constexpr uint16_t ssrc = 1234;
|
const int kTransportSequenceNumberExtensionId = 1;
|
||||||
constexpr uint16_t sequence_number = 17;
|
extension_manager.Register(kRtpExtensionTransportSequenceNumber,
|
||||||
constexpr uint64_t timestamp = 7890;
|
kTransportSequenceNumberExtensionId);
|
||||||
constexpr bool retransmission = false;
|
|
||||||
const PacedPacketInfo paced_info(1, kProbeMinProbes, kProbeMinBytes);
|
|
||||||
|
|
||||||
EXPECT_EQ(RtpPacketSendResult::kPacketNotFound,
|
|
||||||
packet_router.TimeToSendPacket(ssrc, sequence_number, timestamp,
|
|
||||||
retransmission, paced_info));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(PacketRouterTest, Sanity_NoModuleRegistered_TimeToSendPadding) {
|
protected:
|
||||||
PacketRouter packet_router;
|
std::unique_ptr<RtpPacketToSend> BuildRtpPacket(uint32_t ssrc) {
|
||||||
|
std::unique_ptr<RtpPacketToSend> packet =
|
||||||
|
absl::make_unique<RtpPacketToSend>(&extension_manager);
|
||||||
|
packet->SetSsrc(ssrc);
|
||||||
|
return packet;
|
||||||
|
}
|
||||||
|
|
||||||
|
PacketRouter packet_router_;
|
||||||
|
RtpHeaderExtensionMap extension_manager;
|
||||||
|
};
|
||||||
|
|
||||||
|
TEST_F(PacketRouterTest, Sanity_NoModuleRegistered_GeneratePadding) {
|
||||||
constexpr size_t bytes = 300;
|
constexpr size_t bytes = 300;
|
||||||
const PacedPacketInfo paced_info(1, kProbeMinProbes, kProbeMinBytes);
|
const PacedPacketInfo paced_info(1, kProbeMinProbes, kProbeMinBytes);
|
||||||
|
|
||||||
EXPECT_EQ(packet_router.TimeToSendPadding(bytes, paced_info), 0u);
|
EXPECT_TRUE(packet_router_.GeneratePadding(bytes).empty());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(PacketRouterTest, Sanity_NoModuleRegistered_OnReceiveBitrateChanged) {
|
TEST_F(PacketRouterTest, Sanity_NoModuleRegistered_OnReceiveBitrateChanged) {
|
||||||
PacketRouter packet_router;
|
|
||||||
|
|
||||||
const std::vector<uint32_t> ssrcs = {1, 2, 3};
|
const std::vector<uint32_t> ssrcs = {1, 2, 3};
|
||||||
constexpr uint32_t bitrate_bps = 10000;
|
constexpr uint32_t bitrate_bps = 10000;
|
||||||
|
|
||||||
packet_router.OnReceiveBitrateChanged(ssrcs, bitrate_bps);
|
packet_router_.OnReceiveBitrateChanged(ssrcs, bitrate_bps);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(PacketRouterTest, Sanity_NoModuleRegistered_SendRemb) {
|
TEST_F(PacketRouterTest, Sanity_NoModuleRegistered_SendRemb) {
|
||||||
PacketRouter packet_router;
|
|
||||||
|
|
||||||
const std::vector<uint32_t> ssrcs = {1, 2, 3};
|
const std::vector<uint32_t> ssrcs = {1, 2, 3};
|
||||||
constexpr uint32_t bitrate_bps = 10000;
|
constexpr uint32_t bitrate_bps = 10000;
|
||||||
|
|
||||||
EXPECT_FALSE(packet_router.SendRemb(bitrate_bps, ssrcs));
|
EXPECT_FALSE(packet_router_.SendRemb(bitrate_bps, ssrcs));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(PacketRouterTest, Sanity_NoModuleRegistered_SendTransportFeedback) {
|
TEST_F(PacketRouterTest, Sanity_NoModuleRegistered_SendTransportFeedback) {
|
||||||
PacketRouter packet_router;
|
|
||||||
|
|
||||||
rtcp::TransportFeedback feedback;
|
rtcp::TransportFeedback feedback;
|
||||||
|
|
||||||
EXPECT_FALSE(packet_router.SendTransportFeedback(&feedback));
|
EXPECT_FALSE(packet_router_.SendTransportFeedback(&feedback));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(PacketRouterTest, TimeToSendPacket) {
|
TEST_F(PacketRouterTest, GeneratePaddingPicksCorrectModule) {
|
||||||
PacketRouter packet_router;
|
|
||||||
NiceMock<MockRtpRtcp> rtp_1;
|
|
||||||
NiceMock<MockRtpRtcp> rtp_2;
|
|
||||||
|
|
||||||
packet_router.AddSendRtpModule(&rtp_1, false);
|
|
||||||
packet_router.AddSendRtpModule(&rtp_2, false);
|
|
||||||
|
|
||||||
const uint16_t kSsrc1 = 1234;
|
|
||||||
uint16_t sequence_number = 17;
|
|
||||||
uint64_t timestamp = 7890;
|
|
||||||
bool retransmission = false;
|
|
||||||
|
|
||||||
// Send on the first module by letting rtp_1 be sending with correct ssrc.
|
|
||||||
ON_CALL(rtp_1, SendingMedia).WillByDefault(Return(true));
|
|
||||||
ON_CALL(rtp_1, SSRC).WillByDefault(Return(kSsrc1));
|
|
||||||
EXPECT_CALL(rtp_1, TimeToSendPacket(
|
|
||||||
kSsrc1, sequence_number, timestamp, retransmission,
|
|
||||||
Field(&PacedPacketInfo::probe_cluster_id, 1)))
|
|
||||||
.Times(1)
|
|
||||||
.WillOnce(Return(RtpPacketSendResult::kSuccess));
|
|
||||||
EXPECT_CALL(rtp_2, TimeToSendPacket).Times(0);
|
|
||||||
EXPECT_EQ(RtpPacketSendResult::kSuccess,
|
|
||||||
packet_router.TimeToSendPacket(
|
|
||||||
kSsrc1, sequence_number, timestamp, retransmission,
|
|
||||||
PacedPacketInfo(1, kProbeMinProbes, kProbeMinBytes)));
|
|
||||||
|
|
||||||
// Send on the second module by letting rtp_2 be sending, but not rtp_1.
|
|
||||||
++sequence_number;
|
|
||||||
timestamp += 30;
|
|
||||||
retransmission = true;
|
|
||||||
const uint16_t kSsrc2 = 4567;
|
|
||||||
ON_CALL(rtp_1, SendingMedia).WillByDefault(Return(false));
|
|
||||||
ON_CALL(rtp_2, SendingMedia).WillByDefault(Return(true));
|
|
||||||
ON_CALL(rtp_2, SSRC).WillByDefault(Return(kSsrc2));
|
|
||||||
EXPECT_CALL(rtp_1, TimeToSendPacket).Times(0);
|
|
||||||
EXPECT_CALL(rtp_2, TimeToSendPacket(
|
|
||||||
kSsrc2, sequence_number, timestamp, retransmission,
|
|
||||||
Field(&PacedPacketInfo::probe_cluster_id, 2)))
|
|
||||||
.Times(1)
|
|
||||||
.WillOnce(Return(RtpPacketSendResult::kSuccess));
|
|
||||||
EXPECT_EQ(RtpPacketSendResult::kSuccess,
|
|
||||||
packet_router.TimeToSendPacket(
|
|
||||||
kSsrc2, sequence_number, timestamp, retransmission,
|
|
||||||
PacedPacketInfo(2, kProbeMinProbes, kProbeMinBytes)));
|
|
||||||
|
|
||||||
// No module is sending, hence no packet should be sent.
|
|
||||||
ON_CALL(rtp_1, SendingMedia).WillByDefault(Return(false));
|
|
||||||
ON_CALL(rtp_2, SendingMedia).WillByDefault(Return(false));
|
|
||||||
EXPECT_CALL(rtp_1, TimeToSendPacket).Times(0);
|
|
||||||
EXPECT_CALL(rtp_2, TimeToSendPacket).Times(0);
|
|
||||||
EXPECT_EQ(RtpPacketSendResult::kPacketNotFound,
|
|
||||||
packet_router.TimeToSendPacket(
|
|
||||||
kSsrc1, sequence_number, timestamp, retransmission,
|
|
||||||
PacedPacketInfo(1, kProbeMinProbes, kProbeMinBytes)));
|
|
||||||
|
|
||||||
// Add a packet with incorrect ssrc and test it's dropped in the router.
|
|
||||||
ON_CALL(rtp_1, SendingMedia).WillByDefault(Return(true));
|
|
||||||
ON_CALL(rtp_1, SSRC).WillByDefault(Return(kSsrc1));
|
|
||||||
ON_CALL(rtp_2, SendingMedia).WillByDefault(Return(true));
|
|
||||||
ON_CALL(rtp_2, SSRC).WillByDefault(Return(kSsrc2));
|
|
||||||
EXPECT_CALL(rtp_1, TimeToSendPacket).Times(0);
|
|
||||||
EXPECT_CALL(rtp_2, TimeToSendPacket).Times(0);
|
|
||||||
EXPECT_EQ(RtpPacketSendResult::kPacketNotFound,
|
|
||||||
packet_router.TimeToSendPacket(
|
|
||||||
kSsrc1 + kSsrc2, sequence_number, timestamp, retransmission,
|
|
||||||
PacedPacketInfo(1, kProbeMinProbes, kProbeMinBytes)));
|
|
||||||
|
|
||||||
packet_router.RemoveSendRtpModule(&rtp_1);
|
|
||||||
|
|
||||||
// rtp_1 has been removed, try sending a packet on that ssrc and make sure
|
|
||||||
// it is dropped as expected by not expecting any calls to rtp_1.
|
|
||||||
ON_CALL(rtp_2, SendingMedia).WillByDefault(Return(true));
|
|
||||||
ON_CALL(rtp_2, SSRC).WillByDefault(Return(kSsrc2));
|
|
||||||
EXPECT_CALL(rtp_2, TimeToSendPacket).Times(0);
|
|
||||||
EXPECT_EQ(RtpPacketSendResult::kPacketNotFound,
|
|
||||||
packet_router.TimeToSendPacket(
|
|
||||||
kSsrc1, sequence_number, timestamp, retransmission,
|
|
||||||
PacedPacketInfo(PacedPacketInfo::kNotAProbe, kProbeMinBytes,
|
|
||||||
kProbeMinBytes)));
|
|
||||||
|
|
||||||
packet_router.RemoveSendRtpModule(&rtp_2);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(PacketRouterTest, TimeToSendPadding) {
|
|
||||||
PacketRouter packet_router;
|
|
||||||
|
|
||||||
const uint16_t kSsrc1 = 1234;
|
|
||||||
const uint16_t kSsrc2 = 4567;
|
|
||||||
|
|
||||||
NiceMock<MockRtpRtcp> rtp_1;
|
|
||||||
EXPECT_CALL(rtp_1, RtxSendStatus()).WillOnce(Return(kRtxOff));
|
|
||||||
EXPECT_CALL(rtp_1, SSRC()).WillRepeatedly(Return(kSsrc1));
|
|
||||||
NiceMock<MockRtpRtcp> rtp_2;
|
|
||||||
// rtp_2 will be prioritized for padding.
|
|
||||||
EXPECT_CALL(rtp_2, RtxSendStatus()).WillOnce(Return(kRtxRedundantPayloads));
|
|
||||||
EXPECT_CALL(rtp_2, SSRC()).WillRepeatedly(Return(kSsrc2));
|
|
||||||
packet_router.AddSendRtpModule(&rtp_1, false);
|
|
||||||
packet_router.AddSendRtpModule(&rtp_2, false);
|
|
||||||
|
|
||||||
// Default configuration, sending padding on all modules sending media,
|
|
||||||
// ordered by priority (based on rtx mode).
|
|
||||||
const size_t requested_padding_bytes = 1000;
|
|
||||||
const size_t sent_padding_bytes = 890;
|
|
||||||
EXPECT_CALL(rtp_2, SupportsPadding).Times(1).WillOnce(Return(true));
|
|
||||||
EXPECT_CALL(rtp_2,
|
|
||||||
TimeToSendPadding(requested_padding_bytes,
|
|
||||||
Field(&PacedPacketInfo::probe_cluster_id, 111)))
|
|
||||||
.Times(1)
|
|
||||||
.WillOnce(Return(sent_padding_bytes));
|
|
||||||
EXPECT_CALL(rtp_1, SupportsPadding).WillOnce(Return(true));
|
|
||||||
EXPECT_CALL(rtp_1,
|
|
||||||
TimeToSendPadding(requested_padding_bytes - sent_padding_bytes,
|
|
||||||
Field(&PacedPacketInfo::probe_cluster_id, 111)))
|
|
||||||
.Times(1)
|
|
||||||
.WillOnce(Return(requested_padding_bytes - sent_padding_bytes));
|
|
||||||
EXPECT_EQ(requested_padding_bytes,
|
|
||||||
packet_router.TimeToSendPadding(
|
|
||||||
requested_padding_bytes,
|
|
||||||
PacedPacketInfo(111, kProbeMinBytes, kProbeMinBytes)));
|
|
||||||
|
|
||||||
// Let only the lower priority module be sending and verify the padding
|
|
||||||
// request is routed there.
|
|
||||||
EXPECT_CALL(rtp_2, SupportsPadding).WillOnce(Return(false));
|
|
||||||
EXPECT_CALL(rtp_2, TimeToSendPadding(requested_padding_bytes, _)).Times(0);
|
|
||||||
EXPECT_CALL(rtp_1, SupportsPadding).WillOnce(Return(true));
|
|
||||||
EXPECT_CALL(rtp_1, TimeToSendPadding(_, _))
|
|
||||||
.Times(1)
|
|
||||||
.WillOnce(Return(sent_padding_bytes));
|
|
||||||
EXPECT_EQ(sent_padding_bytes,
|
|
||||||
packet_router.TimeToSendPadding(
|
|
||||||
requested_padding_bytes,
|
|
||||||
PacedPacketInfo(PacedPacketInfo::kNotAProbe, kProbeMinBytes,
|
|
||||||
kProbeMinBytes)));
|
|
||||||
|
|
||||||
// No sending module at all.
|
|
||||||
EXPECT_CALL(rtp_1, SupportsPadding).WillOnce(Return(false));
|
|
||||||
EXPECT_CALL(rtp_1, TimeToSendPadding(requested_padding_bytes, _)).Times(0);
|
|
||||||
EXPECT_CALL(rtp_2, SupportsPadding).WillOnce(Return(false));
|
|
||||||
EXPECT_CALL(rtp_2, TimeToSendPadding(_, _)).Times(0);
|
|
||||||
EXPECT_EQ(0u, packet_router.TimeToSendPadding(
|
|
||||||
requested_padding_bytes,
|
|
||||||
PacedPacketInfo(PacedPacketInfo::kNotAProbe, kProbeMinBytes,
|
|
||||||
kProbeMinBytes)));
|
|
||||||
|
|
||||||
packet_router.RemoveSendRtpModule(&rtp_1);
|
|
||||||
|
|
||||||
// rtp_1 has been removed, try sending padding and make sure rtp_1 isn't asked
|
|
||||||
// to send by not expecting any calls. Instead verify rtp_2 is called.
|
|
||||||
EXPECT_CALL(rtp_2, SupportsPadding).WillOnce(Return(true));
|
|
||||||
EXPECT_CALL(rtp_2, TimeToSendPadding(requested_padding_bytes, _)).Times(1);
|
|
||||||
EXPECT_EQ(0u, packet_router.TimeToSendPadding(
|
|
||||||
requested_padding_bytes,
|
|
||||||
PacedPacketInfo(PacedPacketInfo::kNotAProbe, kProbeMinBytes,
|
|
||||||
kProbeMinBytes)));
|
|
||||||
|
|
||||||
packet_router.RemoveSendRtpModule(&rtp_2);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(PacketRouterTest, GeneratePaddingPicksCorrectModule) {
|
|
||||||
PacketRouter packet_router;
|
|
||||||
|
|
||||||
// Two RTP modules. The first (prioritized due to rtx) isn't sending media so
|
// Two RTP modules. The first (prioritized due to rtx) isn't sending media so
|
||||||
// should not be called.
|
// should not be called.
|
||||||
const uint16_t kSsrc1 = 1234;
|
const uint16_t kSsrc1 = 1234;
|
||||||
@ -276,8 +112,8 @@ TEST(PacketRouterTest, GeneratePaddingPicksCorrectModule) {
|
|||||||
ON_CALL(rtp_2, SSRC()).WillByDefault(Return(kSsrc2));
|
ON_CALL(rtp_2, SSRC()).WillByDefault(Return(kSsrc2));
|
||||||
ON_CALL(rtp_2, SupportsPadding).WillByDefault(Return(true));
|
ON_CALL(rtp_2, SupportsPadding).WillByDefault(Return(true));
|
||||||
|
|
||||||
packet_router.AddSendRtpModule(&rtp_1, false);
|
packet_router_.AddSendRtpModule(&rtp_1, false);
|
||||||
packet_router.AddSendRtpModule(&rtp_2, false);
|
packet_router_.AddSendRtpModule(&rtp_2, false);
|
||||||
|
|
||||||
const size_t kPaddingSize = 123;
|
const size_t kPaddingSize = 123;
|
||||||
const size_t kExpectedPaddingPackets = 1;
|
const size_t kExpectedPaddingPackets = 1;
|
||||||
@ -287,187 +123,244 @@ TEST(PacketRouterTest, GeneratePaddingPicksCorrectModule) {
|
|||||||
return std::vector<std::unique_ptr<RtpPacketToSend>>(
|
return std::vector<std::unique_ptr<RtpPacketToSend>>(
|
||||||
kExpectedPaddingPackets);
|
kExpectedPaddingPackets);
|
||||||
});
|
});
|
||||||
auto generated_padding = packet_router.GeneratePadding(kPaddingSize);
|
auto generated_padding = packet_router_.GeneratePadding(kPaddingSize);
|
||||||
EXPECT_EQ(generated_padding.size(), kExpectedPaddingPackets);
|
EXPECT_EQ(generated_padding.size(), kExpectedPaddingPackets);
|
||||||
|
|
||||||
packet_router.RemoveSendRtpModule(&rtp_1);
|
packet_router_.RemoveSendRtpModule(&rtp_1);
|
||||||
packet_router.RemoveSendRtpModule(&rtp_2);
|
packet_router_.RemoveSendRtpModule(&rtp_2);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(PacketRouterTest, PadsOnLastActiveMediaStream) {
|
TEST_F(PacketRouterTest, PadsOnLastActiveMediaStream) {
|
||||||
PacketRouter packet_router;
|
|
||||||
|
|
||||||
const uint16_t kSsrc1 = 1234;
|
const uint16_t kSsrc1 = 1234;
|
||||||
const uint16_t kSsrc2 = 4567;
|
const uint16_t kSsrc2 = 4567;
|
||||||
const uint16_t kSsrc3 = 8901;
|
const uint16_t kSsrc3 = 8901;
|
||||||
|
|
||||||
// First two rtp modules send media and have rtx.
|
// First two rtp modules send media and have rtx.
|
||||||
NiceMock<MockRtpRtcp> rtp_1;
|
NiceMock<MockRtpRtcp> rtp_1;
|
||||||
EXPECT_CALL(rtp_1, RtxSendStatus())
|
|
||||||
.WillRepeatedly(Return(kRtxRedundantPayloads));
|
|
||||||
EXPECT_CALL(rtp_1, SSRC()).WillRepeatedly(Return(kSsrc1));
|
EXPECT_CALL(rtp_1, SSRC()).WillRepeatedly(Return(kSsrc1));
|
||||||
EXPECT_CALL(rtp_1, SendingMedia()).WillRepeatedly(Return(true));
|
|
||||||
EXPECT_CALL(rtp_1, SupportsPadding).WillRepeatedly(Return(true));
|
EXPECT_CALL(rtp_1, SupportsPadding).WillRepeatedly(Return(true));
|
||||||
EXPECT_CALL(rtp_1, SupportsRtxPayloadPadding).WillRepeatedly(Return(true));
|
EXPECT_CALL(rtp_1, SupportsRtxPayloadPadding).WillRepeatedly(Return(true));
|
||||||
|
EXPECT_CALL(rtp_1, TrySendPacket).WillRepeatedly(Return(false));
|
||||||
|
EXPECT_CALL(
|
||||||
|
rtp_1,
|
||||||
|
TrySendPacket(
|
||||||
|
::testing::Pointee(Property(&RtpPacketToSend::Ssrc, kSsrc1)), _))
|
||||||
|
.WillRepeatedly(Return(true));
|
||||||
|
|
||||||
NiceMock<MockRtpRtcp> rtp_2;
|
NiceMock<MockRtpRtcp> rtp_2;
|
||||||
EXPECT_CALL(rtp_2, RtxSendStatus())
|
|
||||||
.WillRepeatedly(Return(kRtxRedundantPayloads));
|
|
||||||
EXPECT_CALL(rtp_2, SSRC()).WillRepeatedly(Return(kSsrc2));
|
EXPECT_CALL(rtp_2, SSRC()).WillRepeatedly(Return(kSsrc2));
|
||||||
EXPECT_CALL(rtp_2, SendingMedia()).WillRepeatedly(Return(true));
|
|
||||||
EXPECT_CALL(rtp_2, SupportsPadding).WillRepeatedly(Return(true));
|
EXPECT_CALL(rtp_2, SupportsPadding).WillRepeatedly(Return(true));
|
||||||
EXPECT_CALL(rtp_2, SupportsRtxPayloadPadding).WillRepeatedly(Return(true));
|
EXPECT_CALL(rtp_2, SupportsRtxPayloadPadding).WillRepeatedly(Return(true));
|
||||||
|
EXPECT_CALL(rtp_2, TrySendPacket).WillRepeatedly(Return(false));
|
||||||
|
EXPECT_CALL(
|
||||||
|
rtp_2,
|
||||||
|
TrySendPacket(
|
||||||
|
::testing::Pointee(Property(&RtpPacketToSend::Ssrc, kSsrc2)), _))
|
||||||
|
.WillRepeatedly(Return(true));
|
||||||
|
|
||||||
// Third module is sending media, but does not support rtx.
|
// Third module is sending media, but does not support rtx.
|
||||||
NiceMock<MockRtpRtcp> rtp_3;
|
NiceMock<MockRtpRtcp> rtp_3;
|
||||||
EXPECT_CALL(rtp_3, RtxSendStatus()).WillRepeatedly(Return(kRtxOff));
|
|
||||||
EXPECT_CALL(rtp_3, SSRC()).WillRepeatedly(Return(kSsrc3));
|
EXPECT_CALL(rtp_3, SSRC()).WillRepeatedly(Return(kSsrc3));
|
||||||
EXPECT_CALL(rtp_3, SendingMedia()).WillRepeatedly(Return(true));
|
|
||||||
EXPECT_CALL(rtp_3, SupportsPadding).WillRepeatedly(Return(true));
|
EXPECT_CALL(rtp_3, SupportsPadding).WillRepeatedly(Return(true));
|
||||||
EXPECT_CALL(rtp_3, SupportsRtxPayloadPadding).WillRepeatedly(Return(true));
|
EXPECT_CALL(rtp_3, SupportsRtxPayloadPadding).WillRepeatedly(Return(false));
|
||||||
|
EXPECT_CALL(rtp_3, TrySendPacket).WillRepeatedly(Return(false));
|
||||||
|
EXPECT_CALL(
|
||||||
|
rtp_3,
|
||||||
|
TrySendPacket(
|
||||||
|
::testing::Pointee(Property(&RtpPacketToSend::Ssrc, kSsrc3)), _))
|
||||||
|
.WillRepeatedly(Return(true));
|
||||||
|
|
||||||
packet_router.AddSendRtpModule(&rtp_1, false);
|
packet_router_.AddSendRtpModule(&rtp_1, false);
|
||||||
packet_router.AddSendRtpModule(&rtp_2, false);
|
packet_router_.AddSendRtpModule(&rtp_2, false);
|
||||||
packet_router.AddSendRtpModule(&rtp_3, false);
|
packet_router_.AddSendRtpModule(&rtp_3, false);
|
||||||
|
|
||||||
const size_t kPaddingBytes = 100;
|
const size_t kPaddingBytes = 100;
|
||||||
|
|
||||||
// Initially, padding will be sent on last added rtp module that sends media
|
// Initially, padding will be sent on last added rtp module that sends media
|
||||||
// and supports rtx.
|
// and supports rtx.
|
||||||
EXPECT_CALL(rtp_2, TimeToSendPadding(kPaddingBytes, _))
|
EXPECT_CALL(rtp_2, GeneratePadding(kPaddingBytes))
|
||||||
.Times(1)
|
.Times(1)
|
||||||
.WillOnce(Return(kPaddingBytes));
|
.WillOnce([](size_t target_size_bytes) {
|
||||||
packet_router.TimeToSendPadding(kPaddingBytes, PacedPacketInfo());
|
return std::vector<std::unique_ptr<RtpPacketToSend>>();
|
||||||
|
});
|
||||||
|
packet_router_.GeneratePadding(kPaddingBytes);
|
||||||
|
|
||||||
// Send media on first module. Padding should be sent on that module.
|
// Send media on first module. Padding should be sent on that module.
|
||||||
EXPECT_CALL(rtp_1, TimeToSendPacket(kSsrc1, _, _, _, _));
|
packet_router_.SendPacket(BuildRtpPacket(kSsrc1), PacedPacketInfo());
|
||||||
packet_router.TimeToSendPacket(kSsrc1, 0, 0, false, PacedPacketInfo());
|
|
||||||
|
|
||||||
EXPECT_CALL(rtp_1, TimeToSendPadding(kPaddingBytes, _))
|
EXPECT_CALL(rtp_1, GeneratePadding(kPaddingBytes))
|
||||||
.Times(1)
|
.Times(1)
|
||||||
.WillOnce(Return(kPaddingBytes));
|
.WillOnce([](size_t target_size_bytes) {
|
||||||
packet_router.TimeToSendPadding(kPaddingBytes, PacedPacketInfo());
|
return std::vector<std::unique_ptr<RtpPacketToSend>>();
|
||||||
|
});
|
||||||
|
packet_router_.GeneratePadding(kPaddingBytes);
|
||||||
|
|
||||||
// Send media on second module. Padding should be sent there.
|
// Send media on second module. Padding should be sent there.
|
||||||
EXPECT_CALL(rtp_2, TimeToSendPacket(kSsrc2, _, _, _, _));
|
packet_router_.SendPacket(BuildRtpPacket(kSsrc2), PacedPacketInfo());
|
||||||
packet_router.TimeToSendPacket(kSsrc2, 0, 0, false, PacedPacketInfo());
|
|
||||||
|
|
||||||
EXPECT_CALL(rtp_2, TimeToSendPadding(kPaddingBytes, _))
|
EXPECT_CALL(rtp_2, GeneratePadding(kPaddingBytes))
|
||||||
.Times(1)
|
.Times(1)
|
||||||
.WillOnce(Return(kPaddingBytes));
|
.WillOnce([](size_t target_size_bytes) {
|
||||||
packet_router.TimeToSendPadding(kPaddingBytes, PacedPacketInfo());
|
return std::vector<std::unique_ptr<RtpPacketToSend>>();
|
||||||
|
});
|
||||||
|
packet_router_.GeneratePadding(kPaddingBytes);
|
||||||
|
|
||||||
// Remove second module, padding should now fall back to first module.
|
// Remove second module, padding should now fall back to first module.
|
||||||
packet_router.RemoveSendRtpModule(&rtp_2);
|
packet_router_.RemoveSendRtpModule(&rtp_2);
|
||||||
EXPECT_CALL(rtp_1, TimeToSendPadding(kPaddingBytes, _))
|
EXPECT_CALL(rtp_1, GeneratePadding(kPaddingBytes))
|
||||||
.Times(1)
|
.Times(1)
|
||||||
.WillOnce(Return(kPaddingBytes));
|
.WillOnce([](size_t target_size_bytes) {
|
||||||
packet_router.TimeToSendPadding(kPaddingBytes, PacedPacketInfo());
|
return std::vector<std::unique_ptr<RtpPacketToSend>>();
|
||||||
|
});
|
||||||
|
packet_router_.GeneratePadding(kPaddingBytes);
|
||||||
|
|
||||||
// Remove first module too, leaving only the one without rtx.
|
// Remove first module too, leaving only the one without rtx.
|
||||||
packet_router.RemoveSendRtpModule(&rtp_1);
|
packet_router_.RemoveSendRtpModule(&rtp_1);
|
||||||
|
|
||||||
EXPECT_CALL(rtp_3, TimeToSendPadding(kPaddingBytes, _))
|
EXPECT_CALL(rtp_3, GeneratePadding(kPaddingBytes))
|
||||||
.Times(1)
|
.Times(1)
|
||||||
.WillOnce(Return(kPaddingBytes));
|
.WillOnce([](size_t target_size_bytes) {
|
||||||
packet_router.TimeToSendPadding(kPaddingBytes, PacedPacketInfo());
|
return std::vector<std::unique_ptr<RtpPacketToSend>>();
|
||||||
|
});
|
||||||
|
packet_router_.GeneratePadding(kPaddingBytes);
|
||||||
|
|
||||||
packet_router.RemoveSendRtpModule(&rtp_3);
|
packet_router_.RemoveSendRtpModule(&rtp_3);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(PacketRouterTest, SenderOnlyFunctionsRespectSendingMedia) {
|
TEST_F(PacketRouterTest, AllocateSequenceNumbers) {
|
||||||
PacketRouter packet_router;
|
|
||||||
NiceMock<MockRtpRtcp> rtp;
|
|
||||||
packet_router.AddSendRtpModule(&rtp, false);
|
|
||||||
static const uint16_t kSsrc = 1234;
|
|
||||||
EXPECT_CALL(rtp, SSRC()).WillRepeatedly(Return(kSsrc));
|
|
||||||
EXPECT_CALL(rtp, SendingMedia()).WillRepeatedly(Return(false));
|
|
||||||
|
|
||||||
// Verify that TimeToSendPacket does not end up in a receiver.
|
|
||||||
EXPECT_CALL(rtp, TimeToSendPacket(_, _, _, _, _)).Times(0);
|
|
||||||
EXPECT_EQ(RtpPacketSendResult::kPacketNotFound,
|
|
||||||
packet_router.TimeToSendPacket(
|
|
||||||
kSsrc, 1, 1, false,
|
|
||||||
PacedPacketInfo(PacedPacketInfo::kNotAProbe, kProbeMinBytes,
|
|
||||||
kProbeMinBytes)));
|
|
||||||
// Verify that TimeToSendPadding does not end up in a receiver.
|
|
||||||
EXPECT_CALL(rtp, TimeToSendPadding(_, _)).Times(0);
|
|
||||||
EXPECT_EQ(0u, packet_router.TimeToSendPadding(
|
|
||||||
200, PacedPacketInfo(PacedPacketInfo::kNotAProbe,
|
|
||||||
kProbeMinBytes, kProbeMinBytes)));
|
|
||||||
|
|
||||||
packet_router.RemoveSendRtpModule(&rtp);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(PacketRouterTest, AllocateSequenceNumbers) {
|
|
||||||
PacketRouter packet_router;
|
|
||||||
|
|
||||||
const uint16_t kStartSeq = 0xFFF0;
|
const uint16_t kStartSeq = 0xFFF0;
|
||||||
const size_t kNumPackets = 32;
|
const size_t kNumPackets = 32;
|
||||||
|
|
||||||
packet_router.SetTransportWideSequenceNumber(kStartSeq - 1);
|
packet_router_.SetTransportWideSequenceNumber(kStartSeq - 1);
|
||||||
|
|
||||||
for (size_t i = 0; i < kNumPackets; ++i) {
|
for (size_t i = 0; i < kNumPackets; ++i) {
|
||||||
uint16_t seq = packet_router.AllocateSequenceNumber();
|
uint16_t seq = packet_router_.AllocateSequenceNumber();
|
||||||
uint32_t expected_unwrapped_seq = static_cast<uint32_t>(kStartSeq) + i;
|
uint32_t expected_unwrapped_seq = static_cast<uint32_t>(kStartSeq) + i;
|
||||||
EXPECT_EQ(static_cast<uint16_t>(expected_unwrapped_seq & 0xFFFF), seq);
|
EXPECT_EQ(static_cast<uint16_t>(expected_unwrapped_seq & 0xFFFF), seq);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(PacketRouterTest, SendTransportFeedback) {
|
TEST_F(PacketRouterTest, SendTransportFeedback) {
|
||||||
PacketRouter packet_router;
|
|
||||||
NiceMock<MockRtpRtcp> rtp_1;
|
NiceMock<MockRtpRtcp> rtp_1;
|
||||||
NiceMock<MockRtpRtcp> rtp_2;
|
NiceMock<MockRtpRtcp> rtp_2;
|
||||||
|
|
||||||
packet_router.AddSendRtpModule(&rtp_1, false);
|
packet_router_.AddSendRtpModule(&rtp_1, false);
|
||||||
packet_router.AddReceiveRtpModule(&rtp_2, false);
|
packet_router_.AddReceiveRtpModule(&rtp_2, false);
|
||||||
|
|
||||||
rtcp::TransportFeedback feedback;
|
rtcp::TransportFeedback feedback;
|
||||||
EXPECT_CALL(rtp_1, SendFeedbackPacket(_)).Times(1).WillOnce(Return(true));
|
EXPECT_CALL(rtp_1, SendFeedbackPacket(_)).Times(1).WillOnce(Return(true));
|
||||||
packet_router.SendTransportFeedback(&feedback);
|
packet_router_.SendTransportFeedback(&feedback);
|
||||||
packet_router.RemoveSendRtpModule(&rtp_1);
|
packet_router_.RemoveSendRtpModule(&rtp_1);
|
||||||
EXPECT_CALL(rtp_2, SendFeedbackPacket(_)).Times(1).WillOnce(Return(true));
|
EXPECT_CALL(rtp_2, SendFeedbackPacket(_)).Times(1).WillOnce(Return(true));
|
||||||
packet_router.SendTransportFeedback(&feedback);
|
packet_router_.SendTransportFeedback(&feedback);
|
||||||
packet_router.RemoveReceiveRtpModule(&rtp_2);
|
packet_router_.RemoveReceiveRtpModule(&rtp_2);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(PacketRouterTest, SendPacketWithoutTransportSequenceNumbers) {
|
||||||
|
NiceMock<MockRtpRtcp> rtp_1;
|
||||||
|
packet_router_.AddSendRtpModule(&rtp_1, false);
|
||||||
|
|
||||||
|
const uint16_t kSsrc1 = 1234;
|
||||||
|
ON_CALL(rtp_1, SendingMedia).WillByDefault(Return(true));
|
||||||
|
ON_CALL(rtp_1, SSRC).WillByDefault(Return(kSsrc1));
|
||||||
|
|
||||||
|
// Send a packet without TransportSequenceNumber extension registered,
|
||||||
|
// packets sent should not have the extension set.
|
||||||
|
RtpHeaderExtensionMap extension_manager;
|
||||||
|
auto packet = absl::make_unique<RtpPacketToSend>(&extension_manager);
|
||||||
|
packet->SetSsrc(kSsrc1);
|
||||||
|
EXPECT_CALL(
|
||||||
|
rtp_1,
|
||||||
|
TrySendPacket(
|
||||||
|
Property(&RtpPacketToSend::HasExtension<TransportSequenceNumber>,
|
||||||
|
false),
|
||||||
|
_))
|
||||||
|
.WillOnce(Return(true));
|
||||||
|
packet_router_.SendPacket(std::move(packet), PacedPacketInfo());
|
||||||
|
|
||||||
|
packet_router_.RemoveSendRtpModule(&rtp_1);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(PacketRouterTest, SendPacketAssignsTransportSequenceNumbers) {
|
||||||
|
NiceMock<MockRtpRtcp> rtp_1;
|
||||||
|
NiceMock<MockRtpRtcp> rtp_2;
|
||||||
|
|
||||||
|
packet_router_.AddSendRtpModule(&rtp_1, false);
|
||||||
|
packet_router_.AddSendRtpModule(&rtp_2, false);
|
||||||
|
|
||||||
|
const uint16_t kSsrc1 = 1234;
|
||||||
|
const uint16_t kSsrc2 = 2345;
|
||||||
|
|
||||||
|
ON_CALL(rtp_1, SSRC).WillByDefault(Return(kSsrc1));
|
||||||
|
ON_CALL(rtp_2, SSRC).WillByDefault(Return(kSsrc2));
|
||||||
|
|
||||||
|
// Transport sequence numbers start at 1, for historical reasons.
|
||||||
|
uint16_t transport_sequence_number = 1;
|
||||||
|
|
||||||
|
auto packet = BuildRtpPacket(kSsrc1);
|
||||||
|
EXPECT_TRUE(packet->ReserveExtension<TransportSequenceNumber>());
|
||||||
|
EXPECT_CALL(
|
||||||
|
rtp_1,
|
||||||
|
TrySendPacket(
|
||||||
|
Property(&RtpPacketToSend::GetExtension<TransportSequenceNumber>,
|
||||||
|
transport_sequence_number),
|
||||||
|
_))
|
||||||
|
.WillOnce(Return(true));
|
||||||
|
packet_router_.SendPacket(std::move(packet), PacedPacketInfo());
|
||||||
|
|
||||||
|
++transport_sequence_number;
|
||||||
|
packet = BuildRtpPacket(kSsrc2);
|
||||||
|
EXPECT_TRUE(packet->ReserveExtension<TransportSequenceNumber>());
|
||||||
|
|
||||||
|
// There will be a failed attempt to send on kSsrc1 before trying
|
||||||
|
// the correct RTP module.
|
||||||
|
EXPECT_CALL(rtp_1, TrySendPacket).WillOnce(Return(false));
|
||||||
|
EXPECT_CALL(
|
||||||
|
rtp_2,
|
||||||
|
TrySendPacket(
|
||||||
|
Property(&RtpPacketToSend::GetExtension<TransportSequenceNumber>,
|
||||||
|
transport_sequence_number),
|
||||||
|
_))
|
||||||
|
.WillOnce(Return(true));
|
||||||
|
packet_router_.SendPacket(std::move(packet), PacedPacketInfo());
|
||||||
|
|
||||||
|
packet_router_.RemoveSendRtpModule(&rtp_1);
|
||||||
|
packet_router_.RemoveSendRtpModule(&rtp_2);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)
|
#if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)
|
||||||
TEST(PacketRouterTest, DoubleRegistrationOfSendModuleDisallowed) {
|
TEST_F(PacketRouterTest, DoubleRegistrationOfSendModuleDisallowed) {
|
||||||
PacketRouter packet_router;
|
|
||||||
NiceMock<MockRtpRtcp> module;
|
NiceMock<MockRtpRtcp> module;
|
||||||
|
|
||||||
constexpr bool remb_candidate = false; // Value irrelevant.
|
constexpr bool remb_candidate = false; // Value irrelevant.
|
||||||
packet_router.AddSendRtpModule(&module, remb_candidate);
|
packet_router_.AddSendRtpModule(&module, remb_candidate);
|
||||||
EXPECT_DEATH(packet_router.AddSendRtpModule(&module, remb_candidate), "");
|
EXPECT_DEATH(packet_router_.AddSendRtpModule(&module, remb_candidate), "");
|
||||||
|
|
||||||
// Test tear-down
|
// Test tear-down
|
||||||
packet_router.RemoveSendRtpModule(&module);
|
packet_router_.RemoveSendRtpModule(&module);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(PacketRouterTest, DoubleRegistrationOfReceiveModuleDisallowed) {
|
TEST_F(PacketRouterTest, DoubleRegistrationOfReceiveModuleDisallowed) {
|
||||||
PacketRouter packet_router;
|
|
||||||
NiceMock<MockRtpRtcp> module;
|
NiceMock<MockRtpRtcp> module;
|
||||||
|
|
||||||
constexpr bool remb_candidate = false; // Value irrelevant.
|
constexpr bool remb_candidate = false; // Value irrelevant.
|
||||||
packet_router.AddReceiveRtpModule(&module, remb_candidate);
|
packet_router_.AddReceiveRtpModule(&module, remb_candidate);
|
||||||
EXPECT_DEATH(packet_router.AddReceiveRtpModule(&module, remb_candidate), "");
|
EXPECT_DEATH(packet_router_.AddReceiveRtpModule(&module, remb_candidate), "");
|
||||||
|
|
||||||
// Test tear-down
|
// Test tear-down
|
||||||
packet_router.RemoveReceiveRtpModule(&module);
|
packet_router_.RemoveReceiveRtpModule(&module);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(PacketRouterTest, RemovalOfNeverAddedSendModuleDisallowed) {
|
TEST_F(PacketRouterTest, RemovalOfNeverAddedSendModuleDisallowed) {
|
||||||
PacketRouter packet_router;
|
|
||||||
NiceMock<MockRtpRtcp> module;
|
NiceMock<MockRtpRtcp> module;
|
||||||
|
|
||||||
EXPECT_DEATH(packet_router.RemoveSendRtpModule(&module), "");
|
EXPECT_DEATH(packet_router_.RemoveSendRtpModule(&module), "");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(PacketRouterTest, RemovalOfNeverAddedReceiveModuleDisallowed) {
|
TEST_F(PacketRouterTest, RemovalOfNeverAddedReceiveModuleDisallowed) {
|
||||||
PacketRouter packet_router;
|
|
||||||
NiceMock<MockRtpRtcp> module;
|
NiceMock<MockRtpRtcp> module;
|
||||||
|
|
||||||
EXPECT_DEATH(packet_router.RemoveReceiveRtpModule(&module), "");
|
EXPECT_DEATH(packet_router_.RemoveReceiveRtpModule(&module), "");
|
||||||
}
|
}
|
||||||
#endif // RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)
|
#endif // RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)
|
||||||
|
|
||||||
@ -931,87 +824,4 @@ TEST(PacketRouterRembTest, ReceiveModuleTakesOverWhenLastSendModuleRemoved) {
|
|||||||
packet_router.RemoveReceiveRtpModule(&receive_module);
|
packet_router.RemoveReceiveRtpModule(&receive_module);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(PacketRouterTest, SendPacketWithoutTransportSequenceNumbers) {
|
|
||||||
PacketRouter packet_router;
|
|
||||||
NiceMock<MockRtpRtcp> rtp_1;
|
|
||||||
packet_router.AddSendRtpModule(&rtp_1, false);
|
|
||||||
|
|
||||||
const uint16_t kSsrc1 = 1234;
|
|
||||||
ON_CALL(rtp_1, SendingMedia).WillByDefault(Return(true));
|
|
||||||
ON_CALL(rtp_1, SSRC).WillByDefault(Return(kSsrc1));
|
|
||||||
|
|
||||||
// Send a packet without TransportSequenceNumber extension registered,
|
|
||||||
// packets sent should not have the extension set.
|
|
||||||
RtpHeaderExtensionMap extension_manager;
|
|
||||||
auto packet = absl::make_unique<RtpPacketToSend>(&extension_manager);
|
|
||||||
packet->SetSsrc(kSsrc1);
|
|
||||||
EXPECT_CALL(
|
|
||||||
rtp_1,
|
|
||||||
TrySendPacket(
|
|
||||||
Property(&RtpPacketToSend::HasExtension<TransportSequenceNumber>,
|
|
||||||
false),
|
|
||||||
_))
|
|
||||||
.WillOnce(Return(true));
|
|
||||||
packet_router.SendPacket(std::move(packet), PacedPacketInfo());
|
|
||||||
|
|
||||||
packet_router.RemoveSendRtpModule(&rtp_1);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(PacketRouterTest, SendPacketAssignsTransportSequenceNumbers) {
|
|
||||||
PacketRouter packet_router;
|
|
||||||
NiceMock<MockRtpRtcp> rtp_1;
|
|
||||||
NiceMock<MockRtpRtcp> rtp_2;
|
|
||||||
|
|
||||||
packet_router.AddSendRtpModule(&rtp_1, false);
|
|
||||||
packet_router.AddSendRtpModule(&rtp_2, false);
|
|
||||||
|
|
||||||
const uint16_t kSsrc1 = 1234;
|
|
||||||
const uint16_t kSsrc2 = 2345;
|
|
||||||
|
|
||||||
ON_CALL(rtp_1, SendingMedia).WillByDefault(Return(true));
|
|
||||||
ON_CALL(rtp_1, SSRC).WillByDefault(Return(kSsrc1));
|
|
||||||
ON_CALL(rtp_2, SendingMedia).WillByDefault(Return(true));
|
|
||||||
ON_CALL(rtp_2, SSRC).WillByDefault(Return(kSsrc2));
|
|
||||||
|
|
||||||
RtpHeaderExtensionMap extension_manager;
|
|
||||||
const int kTransportSequenceNumberExtensionId = 1;
|
|
||||||
extension_manager.Register(kRtpExtensionTransportSequenceNumber,
|
|
||||||
kTransportSequenceNumberExtensionId);
|
|
||||||
|
|
||||||
// Transport sequence numbers start at 1, for historical reasons.
|
|
||||||
uint16_t transport_sequence_number = 1;
|
|
||||||
|
|
||||||
auto packet = absl::make_unique<RtpPacketToSend>(&extension_manager);
|
|
||||||
EXPECT_TRUE(packet->ReserveExtension<TransportSequenceNumber>());
|
|
||||||
packet->SetSsrc(kSsrc1);
|
|
||||||
EXPECT_CALL(
|
|
||||||
rtp_1,
|
|
||||||
TrySendPacket(
|
|
||||||
Property(&RtpPacketToSend::GetExtension<TransportSequenceNumber>,
|
|
||||||
transport_sequence_number),
|
|
||||||
_))
|
|
||||||
.WillOnce(Return(true));
|
|
||||||
packet_router.SendPacket(std::move(packet), PacedPacketInfo());
|
|
||||||
|
|
||||||
++transport_sequence_number;
|
|
||||||
packet = absl::make_unique<RtpPacketToSend>(&extension_manager);
|
|
||||||
EXPECT_TRUE(packet->ReserveExtension<TransportSequenceNumber>());
|
|
||||||
packet->SetSsrc(kSsrc2);
|
|
||||||
|
|
||||||
// There will be a failed attempt to send on kSsrc1 before trying
|
|
||||||
// the correct RTP module.
|
|
||||||
EXPECT_CALL(rtp_1, TrySendPacket).WillOnce(Return(false));
|
|
||||||
EXPECT_CALL(
|
|
||||||
rtp_2,
|
|
||||||
TrySendPacket(
|
|
||||||
Property(&RtpPacketToSend::GetExtension<TransportSequenceNumber>,
|
|
||||||
transport_sequence_number),
|
|
||||||
_))
|
|
||||||
.WillOnce(Return(true));
|
|
||||||
packet_router.SendPacket(std::move(packet), PacedPacketInfo());
|
|
||||||
|
|
||||||
packet_router.RemoveSendRtpModule(&rtp_1);
|
|
||||||
packet_router.RemoveSendRtpModule(&rtp_2);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
|
|||||||
@ -18,28 +18,10 @@
|
|||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
|
|
||||||
// TODO(bugs.webrtc.org/10633): Remove Priority and InsertPacket when old pacer
|
|
||||||
// code path is gone.
|
|
||||||
class RtpPacketSender {
|
class RtpPacketSender {
|
||||||
public:
|
public:
|
||||||
virtual ~RtpPacketSender() = default;
|
virtual ~RtpPacketSender() = default;
|
||||||
|
|
||||||
// These are part of the legacy PacedSender interface and will be removed.
|
|
||||||
enum Priority {
|
|
||||||
kHighPriority = 0, // Pass through; will be sent immediately.
|
|
||||||
kNormalPriority = 2, // Put in back of the line.
|
|
||||||
kLowPriority = 3, // Put in back of the low priority line.
|
|
||||||
};
|
|
||||||
|
|
||||||
// Adds the packet information to the queue and call TimeToSendPacket when
|
|
||||||
// it's time to send.
|
|
||||||
virtual void InsertPacket(Priority priority,
|
|
||||||
uint32_t ssrc,
|
|
||||||
uint16_t sequence_number,
|
|
||||||
int64_t capture_time_ms,
|
|
||||||
size_t bytes,
|
|
||||||
bool retransmission) = 0;
|
|
||||||
|
|
||||||
// Insert packet into queue, for eventual transmission. Based on the type of
|
// Insert packet into queue, for eventual transmission. Based on the type of
|
||||||
// the packet, it will be prioritized and scheduled relative to other packets
|
// the packet, it will be prioritized and scheduled relative to other packets
|
||||||
// and the current target send rate.
|
// and the current target send rate.
|
||||||
|
|||||||
@ -282,22 +282,12 @@ class RtpRtcp : public Module, public RtcpFeedbackSenderInterface {
|
|||||||
int payload_type,
|
int payload_type,
|
||||||
bool force_sender_report) = 0;
|
bool force_sender_report) = 0;
|
||||||
|
|
||||||
virtual RtpPacketSendResult TimeToSendPacket(
|
|
||||||
uint32_t ssrc,
|
|
||||||
uint16_t sequence_number,
|
|
||||||
int64_t capture_time_ms,
|
|
||||||
bool retransmission,
|
|
||||||
const PacedPacketInfo& pacing_info) = 0;
|
|
||||||
|
|
||||||
// Try to send the provided packet. Returns true iff packet matches any of
|
// Try to send the provided packet. Returns true iff packet matches any of
|
||||||
// the SSRCs for this module (media/rtx/fec etc) and was forwarded to the
|
// the SSRCs for this module (media/rtx/fec etc) and was forwarded to the
|
||||||
// transport.
|
// transport.
|
||||||
virtual bool TrySendPacket(RtpPacketToSend* packet,
|
virtual bool TrySendPacket(RtpPacketToSend* packet,
|
||||||
const PacedPacketInfo& pacing_info) = 0;
|
const PacedPacketInfo& pacing_info) = 0;
|
||||||
|
|
||||||
virtual size_t TimeToSendPadding(size_t bytes,
|
|
||||||
const PacedPacketInfo& pacing_info) = 0;
|
|
||||||
|
|
||||||
virtual std::vector<std::unique_ptr<RtpPacketToSend>> GeneratePadding(
|
virtual std::vector<std::unique_ptr<RtpPacketToSend>> GeneratePadding(
|
||||||
size_t target_size_bytes) = 0;
|
size_t target_size_bytes) = 0;
|
||||||
|
|
||||||
|
|||||||
@ -85,17 +85,9 @@ class MockRtpRtcp : public RtpRtcp {
|
|||||||
MOCK_CONST_METHOD1(EstimatedReceiveBandwidth,
|
MOCK_CONST_METHOD1(EstimatedReceiveBandwidth,
|
||||||
int(uint32_t* available_bandwidth));
|
int(uint32_t* available_bandwidth));
|
||||||
MOCK_METHOD4(OnSendingRtpFrame, bool(uint32_t, int64_t, int, bool));
|
MOCK_METHOD4(OnSendingRtpFrame, bool(uint32_t, int64_t, int, bool));
|
||||||
MOCK_METHOD5(TimeToSendPacket,
|
|
||||||
RtpPacketSendResult(uint32_t ssrc,
|
|
||||||
uint16_t sequence_number,
|
|
||||||
int64_t capture_time_ms,
|
|
||||||
bool retransmission,
|
|
||||||
const PacedPacketInfo& pacing_info));
|
|
||||||
MOCK_METHOD2(TrySendPacket,
|
MOCK_METHOD2(TrySendPacket,
|
||||||
bool(RtpPacketToSend* packet,
|
bool(RtpPacketToSend* packet,
|
||||||
const PacedPacketInfo& pacing_info));
|
const PacedPacketInfo& pacing_info));
|
||||||
MOCK_METHOD2(TimeToSendPadding,
|
|
||||||
size_t(size_t bytes, const PacedPacketInfo& pacing_info));
|
|
||||||
MOCK_METHOD1(
|
MOCK_METHOD1(
|
||||||
GeneratePadding,
|
GeneratePadding,
|
||||||
std::vector<std::unique_ptr<RtpPacketToSend>>(size_t target_size_bytes));
|
std::vector<std::unique_ptr<RtpPacketToSend>>(size_t target_size_bytes));
|
||||||
|
|||||||
@ -314,7 +314,7 @@ std::unique_ptr<RtpPacketToSend> RtpPacketHistory::GetPayloadPaddingPacket(
|
|||||||
StoredPacket* best_packet = *best_packet_it;
|
StoredPacket* best_packet = *best_packet_it;
|
||||||
if (best_packet->pending_transmission_) {
|
if (best_packet->pending_transmission_) {
|
||||||
// Because PacedSender releases it's lock when it calls
|
// Because PacedSender releases it's lock when it calls
|
||||||
// TimeToSendPadding() there is the potential for a race where a new
|
// GeneratePadding() there is the potential for a race where a new
|
||||||
// packet ends up here instead of the regular transmit path. In such a
|
// packet ends up here instead of the regular transmit path. In such a
|
||||||
// case, just return empty and it will be picked up on the next
|
// case, just return empty and it will be picked up on the next
|
||||||
// Process() call.
|
// Process() call.
|
||||||
|
|||||||
@ -354,16 +354,6 @@ bool ModuleRtpRtcpImpl::OnSendingRtpFrame(uint32_t timestamp,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
RtpPacketSendResult ModuleRtpRtcpImpl::TimeToSendPacket(
|
|
||||||
uint32_t ssrc,
|
|
||||||
uint16_t sequence_number,
|
|
||||||
int64_t capture_time_ms,
|
|
||||||
bool retransmission,
|
|
||||||
const PacedPacketInfo& pacing_info) {
|
|
||||||
return rtp_sender_->TimeToSendPacket(ssrc, sequence_number, capture_time_ms,
|
|
||||||
retransmission, pacing_info);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ModuleRtpRtcpImpl::TrySendPacket(RtpPacketToSend* packet,
|
bool ModuleRtpRtcpImpl::TrySendPacket(RtpPacketToSend* packet,
|
||||||
const PacedPacketInfo& pacing_info) {
|
const PacedPacketInfo& pacing_info) {
|
||||||
return rtp_sender_->TrySendPacket(packet, pacing_info);
|
return rtp_sender_->TrySendPacket(packet, pacing_info);
|
||||||
@ -377,12 +367,6 @@ bool ModuleRtpRtcpImpl::SupportsRtxPayloadPadding() const {
|
|||||||
return rtp_sender_->SupportsRtxPayloadPadding();
|
return rtp_sender_->SupportsRtxPayloadPadding();
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t ModuleRtpRtcpImpl::TimeToSendPadding(
|
|
||||||
size_t bytes,
|
|
||||||
const PacedPacketInfo& pacing_info) {
|
|
||||||
return rtp_sender_->TimeToSendPadding(bytes, pacing_info);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<std::unique_ptr<RtpPacketToSend>>
|
std::vector<std::unique_ptr<RtpPacketToSend>>
|
||||||
ModuleRtpRtcpImpl::GeneratePadding(size_t target_size_bytes) {
|
ModuleRtpRtcpImpl::GeneratePadding(size_t target_size_bytes) {
|
||||||
return rtp_sender_->GeneratePadding(target_size_bytes);
|
return rtp_sender_->GeneratePadding(target_size_bytes);
|
||||||
|
|||||||
@ -135,20 +135,9 @@ class ModuleRtpRtcpImpl : public RtpRtcp, public RTCPReceiver::ModuleRtpRtcp {
|
|||||||
int payload_type,
|
int payload_type,
|
||||||
bool force_sender_report) override;
|
bool force_sender_report) override;
|
||||||
|
|
||||||
RtpPacketSendResult TimeToSendPacket(
|
|
||||||
uint32_t ssrc,
|
|
||||||
uint16_t sequence_number,
|
|
||||||
int64_t capture_time_ms,
|
|
||||||
bool retransmission,
|
|
||||||
const PacedPacketInfo& pacing_info) override;
|
|
||||||
|
|
||||||
bool TrySendPacket(RtpPacketToSend* packet,
|
bool TrySendPacket(RtpPacketToSend* packet,
|
||||||
const PacedPacketInfo& pacing_info) override;
|
const PacedPacketInfo& pacing_info) override;
|
||||||
|
|
||||||
// Returns the number of padding bytes actually sent, which can be more or
|
|
||||||
// less than |bytes|.
|
|
||||||
size_t TimeToSendPadding(size_t bytes,
|
|
||||||
const PacedPacketInfo& pacing_info) override;
|
|
||||||
|
|
||||||
std::vector<std::unique_ptr<RtpPacketToSend>> GeneratePadding(
|
std::vector<std::unique_ptr<RtpPacketToSend>> GeneratePadding(
|
||||||
size_t target_size_bytes) override;
|
size_t target_size_bytes) override;
|
||||||
|
|||||||
@ -471,17 +471,6 @@ void RTPSender::OnReceivedNack(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Called from pacer when we can send the packet.
|
|
||||||
RtpPacketSendResult RTPSender::TimeToSendPacket(
|
|
||||||
uint32_t ssrc,
|
|
||||||
uint16_t sequence_number,
|
|
||||||
int64_t capture_time_ms,
|
|
||||||
bool retransmission,
|
|
||||||
const PacedPacketInfo& pacing_info) {
|
|
||||||
RTC_NOTREACHED();
|
|
||||||
return RtpPacketSendResult::kSuccess;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Called from pacer when we can send the packet.
|
// Called from pacer when we can send the packet.
|
||||||
bool RTPSender::TrySendPacket(RtpPacketToSend* packet,
|
bool RTPSender::TrySendPacket(RtpPacketToSend* packet,
|
||||||
const PacedPacketInfo& pacing_info) {
|
const PacedPacketInfo& pacing_info) {
|
||||||
@ -715,19 +704,6 @@ void RTPSender::UpdateRtpStats(const RtpPacketToSend& packet,
|
|||||||
rtp_stats_callback_->DataCountersUpdated(*counters, packet.Ssrc());
|
rtp_stats_callback_->DataCountersUpdated(*counters, packet.Ssrc());
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t RTPSender::TimeToSendPadding(size_t bytes,
|
|
||||||
const PacedPacketInfo& pacing_info) {
|
|
||||||
// TODO(bugs.webrtc.org/10633): Remove when downstream test usage is gone.
|
|
||||||
size_t padding_bytes_sent = 0;
|
|
||||||
for (auto& packet : GeneratePadding(bytes)) {
|
|
||||||
const size_t packet_size = packet->payload_size() + packet->padding_size();
|
|
||||||
if (TrySendPacket(packet.get(), pacing_info)) {
|
|
||||||
padding_bytes_sent += packet_size;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return padding_bytes_sent;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<std::unique_ptr<RtpPacketToSend>> RTPSender::GeneratePadding(
|
std::vector<std::unique_ptr<RtpPacketToSend>> RTPSender::GeneratePadding(
|
||||||
size_t target_size_bytes) {
|
size_t target_size_bytes) {
|
||||||
// This method does not actually send packets, it just generates
|
// This method does not actually send packets, it just generates
|
||||||
|
|||||||
@ -111,16 +111,10 @@ class RTPSender {
|
|||||||
|
|
||||||
// Returns an RtpPacketSendResult indicating success, network unavailable,
|
// Returns an RtpPacketSendResult indicating success, network unavailable,
|
||||||
// or packet not found.
|
// or packet not found.
|
||||||
RtpPacketSendResult TimeToSendPacket(uint32_t ssrc,
|
|
||||||
uint16_t sequence_number,
|
|
||||||
int64_t capture_time_ms,
|
|
||||||
bool retransmission,
|
|
||||||
const PacedPacketInfo& pacing_info);
|
|
||||||
bool TrySendPacket(RtpPacketToSend* packet,
|
bool TrySendPacket(RtpPacketToSend* packet,
|
||||||
const PacedPacketInfo& pacing_info);
|
const PacedPacketInfo& pacing_info);
|
||||||
bool SupportsPadding() const;
|
bool SupportsPadding() const;
|
||||||
bool SupportsRtxPayloadPadding() const;
|
bool SupportsRtxPayloadPadding() const;
|
||||||
size_t TimeToSendPadding(size_t bytes, const PacedPacketInfo& pacing_info);
|
|
||||||
std::vector<std::unique_ptr<RtpPacketToSend>> GeneratePadding(
|
std::vector<std::unique_ptr<RtpPacketToSend>> GeneratePadding(
|
||||||
size_t target_size_bytes);
|
size_t target_size_bytes);
|
||||||
|
|
||||||
|
|||||||
@ -165,14 +165,6 @@ class MockRtpPacketPacer : public RtpPacketSender {
|
|||||||
|
|
||||||
MOCK_METHOD1(EnqueuePacket, void(std::unique_ptr<RtpPacketToSend>));
|
MOCK_METHOD1(EnqueuePacket, void(std::unique_ptr<RtpPacketToSend>));
|
||||||
|
|
||||||
MOCK_METHOD6(InsertPacket,
|
|
||||||
void(Priority priority,
|
|
||||||
uint32_t ssrc,
|
|
||||||
uint16_t sequence_number,
|
|
||||||
int64_t capture_time_ms,
|
|
||||||
size_t bytes,
|
|
||||||
bool retransmission));
|
|
||||||
|
|
||||||
MOCK_METHOD2(CreateProbeCluster, void(int bitrate_bps, int cluster_id));
|
MOCK_METHOD2(CreateProbeCluster, void(int bitrate_bps, int cluster_id));
|
||||||
|
|
||||||
MOCK_METHOD0(Pause, void());
|
MOCK_METHOD0(Pause, void());
|
||||||
@ -296,6 +288,15 @@ class RtpSenderTest : public ::testing::TestWithParam<TestConfig> {
|
|||||||
return SendPacket(kCaptureTimeMs, sizeof(kPayloadData));
|
return SendPacket(kCaptureTimeMs, sizeof(kPayloadData));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t GenerateAndSendPadding(size_t target_size_bytes) {
|
||||||
|
size_t generated_bytes = 0;
|
||||||
|
for (auto& packet : rtp_sender_->GeneratePadding(target_size_bytes)) {
|
||||||
|
generated_bytes += packet->payload_size() + packet->padding_size();
|
||||||
|
rtp_sender_->TrySendPacket(packet.get(), PacedPacketInfo());
|
||||||
|
}
|
||||||
|
return generated_bytes;
|
||||||
|
}
|
||||||
|
|
||||||
// The following are helpers for configuring the RTPSender. They must be
|
// The following are helpers for configuring the RTPSender. They must be
|
||||||
// called before sending any packets.
|
// called before sending any packets.
|
||||||
|
|
||||||
@ -399,16 +400,16 @@ TEST_P(RtpSenderTestWithoutPacer, AssignSequenceNumberMayAllowPaddingOnVideo) {
|
|||||||
auto packet = rtp_sender_->AllocatePacket();
|
auto packet = rtp_sender_->AllocatePacket();
|
||||||
ASSERT_TRUE(packet);
|
ASSERT_TRUE(packet);
|
||||||
|
|
||||||
ASSERT_FALSE(rtp_sender_->TimeToSendPadding(kPaddingSize, PacedPacketInfo()));
|
ASSERT_TRUE(rtp_sender_->GeneratePadding(kPaddingSize).empty());
|
||||||
packet->SetMarker(false);
|
packet->SetMarker(false);
|
||||||
ASSERT_TRUE(rtp_sender_->AssignSequenceNumber(packet.get()));
|
ASSERT_TRUE(rtp_sender_->AssignSequenceNumber(packet.get()));
|
||||||
// Packet without marker bit doesn't allow padding on video stream.
|
// Packet without marker bit doesn't allow padding on video stream.
|
||||||
EXPECT_FALSE(rtp_sender_->TimeToSendPadding(kPaddingSize, PacedPacketInfo()));
|
ASSERT_TRUE(rtp_sender_->GeneratePadding(kPaddingSize).empty());
|
||||||
|
|
||||||
packet->SetMarker(true);
|
packet->SetMarker(true);
|
||||||
ASSERT_TRUE(rtp_sender_->AssignSequenceNumber(packet.get()));
|
ASSERT_TRUE(rtp_sender_->AssignSequenceNumber(packet.get()));
|
||||||
// Packet with marker bit allows send padding.
|
// Packet with marker bit allows send padding.
|
||||||
EXPECT_TRUE(rtp_sender_->TimeToSendPadding(kPaddingSize, PacedPacketInfo()));
|
ASSERT_FALSE(rtp_sender_->GeneratePadding(kPaddingSize).empty());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_P(RtpSenderTest, AssignSequenceNumberAllowsPaddingOnAudio) {
|
TEST_P(RtpSenderTest, AssignSequenceNumberAllowsPaddingOnAudio) {
|
||||||
@ -434,15 +435,13 @@ TEST_P(RtpSenderTest, AssignSequenceNumberAllowsPaddingOnAudio) {
|
|||||||
const size_t kPaddingSize = 59;
|
const size_t kPaddingSize = 59;
|
||||||
EXPECT_CALL(transport, SendRtp(_, kPaddingSize + kRtpHeaderSize, _))
|
EXPECT_CALL(transport, SendRtp(_, kPaddingSize + kRtpHeaderSize, _))
|
||||||
.WillOnce(Return(true));
|
.WillOnce(Return(true));
|
||||||
EXPECT_EQ(kPaddingSize,
|
EXPECT_EQ(kPaddingSize, GenerateAndSendPadding(kPaddingSize));
|
||||||
rtp_sender_->TimeToSendPadding(kPaddingSize, PacedPacketInfo()));
|
|
||||||
|
|
||||||
// Requested padding size is too small, will send a larger one.
|
// Requested padding size is too small, will send a larger one.
|
||||||
const size_t kMinPaddingSize = 50;
|
const size_t kMinPaddingSize = 50;
|
||||||
EXPECT_CALL(transport, SendRtp(_, kMinPaddingSize + kRtpHeaderSize, _))
|
EXPECT_CALL(transport, SendRtp(_, kMinPaddingSize + kRtpHeaderSize, _))
|
||||||
.WillOnce(Return(true));
|
.WillOnce(Return(true));
|
||||||
EXPECT_EQ(kMinPaddingSize, rtp_sender_->TimeToSendPadding(kMinPaddingSize - 5,
|
EXPECT_EQ(kMinPaddingSize, GenerateAndSendPadding(kMinPaddingSize - 5));
|
||||||
PacedPacketInfo()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_P(RtpSenderTestWithoutPacer, AssignSequenceNumberSetPaddingTimestamps) {
|
TEST_P(RtpSenderTestWithoutPacer, AssignSequenceNumberSetPaddingTimestamps) {
|
||||||
@ -453,11 +452,11 @@ TEST_P(RtpSenderTestWithoutPacer, AssignSequenceNumberSetPaddingTimestamps) {
|
|||||||
packet->SetTimestamp(kTimestamp);
|
packet->SetTimestamp(kTimestamp);
|
||||||
|
|
||||||
ASSERT_TRUE(rtp_sender_->AssignSequenceNumber(packet.get()));
|
ASSERT_TRUE(rtp_sender_->AssignSequenceNumber(packet.get()));
|
||||||
ASSERT_TRUE(rtp_sender_->TimeToSendPadding(kPaddingSize, PacedPacketInfo()));
|
auto padding_packets = rtp_sender_->GeneratePadding(kPaddingSize);
|
||||||
|
|
||||||
ASSERT_EQ(1u, transport_.sent_packets_.size());
|
ASSERT_EQ(1u, padding_packets.size());
|
||||||
// Verify padding packet timestamp.
|
// Verify padding packet timestamp.
|
||||||
EXPECT_EQ(kTimestamp, transport_.last_sent_packet().Timestamp());
|
EXPECT_EQ(kTimestamp, padding_packets[0]->Timestamp());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_P(RtpSenderTestWithoutPacer,
|
TEST_P(RtpSenderTestWithoutPacer,
|
||||||
@ -1003,8 +1002,7 @@ TEST_P(RtpSenderTest, SendPadding) {
|
|||||||
const size_t kPaddingBytes = 100;
|
const size_t kPaddingBytes = 100;
|
||||||
const size_t kMaxPaddingLength = 224; // Value taken from rtp_sender.cc.
|
const size_t kMaxPaddingLength = 224; // Value taken from rtp_sender.cc.
|
||||||
// Padding will be forced to full packets.
|
// Padding will be forced to full packets.
|
||||||
EXPECT_EQ(kMaxPaddingLength,
|
EXPECT_EQ(kMaxPaddingLength, GenerateAndSendPadding(kPaddingBytes));
|
||||||
rtp_sender_->TimeToSendPadding(kPaddingBytes, PacedPacketInfo()));
|
|
||||||
|
|
||||||
// Process send bucket. Padding should now be sent.
|
// Process send bucket. Padding should now be sent.
|
||||||
EXPECT_EQ(++total_packets_sent, transport_.packets_sent());
|
EXPECT_EQ(++total_packets_sent, transport_.packets_sent());
|
||||||
@ -1878,7 +1876,7 @@ TEST_P(RtpSenderTestWithoutPacer, StreamDataCountersCallbacks) {
|
|||||||
callback.Matches(ssrc, expected);
|
callback.Matches(ssrc, expected);
|
||||||
|
|
||||||
// Send padding.
|
// Send padding.
|
||||||
rtp_sender_->TimeToSendPadding(kMaxPaddingSize, PacedPacketInfo());
|
GenerateAndSendPadding(kMaxPaddingSize);
|
||||||
expected.transmitted.payload_bytes = 12;
|
expected.transmitted.payload_bytes = 12;
|
||||||
expected.transmitted.header_bytes = 36;
|
expected.transmitted.header_bytes = 36;
|
||||||
expected.transmitted.padding_bytes = kMaxPaddingSize;
|
expected.transmitted.padding_bytes = kMaxPaddingSize;
|
||||||
@ -1913,8 +1911,8 @@ TEST_P(RtpSenderTestWithoutPacer, BytesReportedCorrectly) {
|
|||||||
|
|
||||||
SendGenericPacket();
|
SendGenericPacket();
|
||||||
// Will send 2 full-size padding packets.
|
// Will send 2 full-size padding packets.
|
||||||
rtp_sender_->TimeToSendPadding(1, PacedPacketInfo());
|
GenerateAndSendPadding(1);
|
||||||
rtp_sender_->TimeToSendPadding(1, PacedPacketInfo());
|
GenerateAndSendPadding(1);
|
||||||
|
|
||||||
StreamDataCounters rtp_stats;
|
StreamDataCounters rtp_stats;
|
||||||
StreamDataCounters rtx_stats;
|
StreamDataCounters rtx_stats;
|
||||||
|
|||||||
Reference in New Issue
Block a user