ModuleRtpRtcpImpl2: update test code.
This change prepares for later CLs that partly replaces logic in the module that depends on the Module system for logic that depends on task queues. The change also changes SendTransport::SendRTCP to schedule packet reception with the simulated time controller. This fixes the problem that SendRTCP itself updates the simulated time which makes it hard to understand the tests. Finally, GlobalSimulatedTimeController was updated to support addition of custom SimulatedSequenceRunners like SendTransport. Bug: webrtc:11581 Change-Id: I0aa310ad0a10526479ad8c28affc38a413363ffd Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/222602 Commit-Queue: Markus Handell <handellm@webrtc.org> Reviewed-by: Erik Språng <sprang@webrtc.org> Cr-Commit-Position: refs/heads/master@{#34348}
This commit is contained in:
parent
fb7fd24b3d
commit
049ed447b0
@ -10,18 +10,22 @@
|
||||
|
||||
#include "modules/rtp_rtcp/source/rtp_rtcp_impl2.h"
|
||||
|
||||
#include <deque>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <set>
|
||||
#include <utility>
|
||||
|
||||
#include "absl/types/optional.h"
|
||||
#include "api/transport/field_trial_based_config.h"
|
||||
#include "api/units/time_delta.h"
|
||||
#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
|
||||
#include "modules/rtp_rtcp/source/rtcp_packet.h"
|
||||
#include "modules/rtp_rtcp/source/rtcp_packet/nack.h"
|
||||
#include "modules/rtp_rtcp/source/rtp_packet_received.h"
|
||||
#include "modules/rtp_rtcp/source/rtp_rtcp_interface.h"
|
||||
#include "modules/rtp_rtcp/source/rtp_sender_video.h"
|
||||
#include "rtc_base/logging.h"
|
||||
#include "rtc_base/rate_limiter.h"
|
||||
#include "rtc_base/strings/string_builder.h"
|
||||
#include "test/gmock.h"
|
||||
@ -42,16 +46,17 @@ using ::testing::SizeIs;
|
||||
|
||||
namespace webrtc {
|
||||
namespace {
|
||||
const uint32_t kSenderSsrc = 0x12345;
|
||||
const uint32_t kReceiverSsrc = 0x23456;
|
||||
const int64_t kOneWayNetworkDelayMs = 100;
|
||||
const uint8_t kBaseLayerTid = 0;
|
||||
const uint8_t kHigherLayerTid = 1;
|
||||
const uint16_t kSequenceNumber = 100;
|
||||
const uint8_t kPayloadType = 100;
|
||||
const int kWidth = 320;
|
||||
const int kHeight = 100;
|
||||
const int kCaptureTimeMsToRtpTimestamp = 90; // 90 kHz clock.
|
||||
constexpr uint32_t kSenderSsrc = 0x12345;
|
||||
constexpr uint32_t kReceiverSsrc = 0x23456;
|
||||
constexpr TimeDelta kOneWayNetworkDelay = TimeDelta::Millis(100);
|
||||
constexpr uint8_t kBaseLayerTid = 0;
|
||||
constexpr uint8_t kHigherLayerTid = 1;
|
||||
constexpr uint16_t kSequenceNumber = 100;
|
||||
constexpr uint8_t kPayloadType = 100;
|
||||
constexpr int kWidth = 320;
|
||||
constexpr int kHeight = 100;
|
||||
constexpr int kCaptureTimeMsToRtpTimestamp = 90; // 90 kHz clock.
|
||||
constexpr TimeDelta kDefaultReportInterval = TimeDelta::Millis(1000);
|
||||
|
||||
// RTP header extension ids.
|
||||
enum : int {
|
||||
@ -70,21 +75,25 @@ class RtcpRttStatsTestImpl : public RtcpRttStats {
|
||||
int64_t rtt_ms_;
|
||||
};
|
||||
|
||||
class SendTransport : public Transport {
|
||||
// TODO(bugs.webrtc.org/11581): remove inheritance once the ModuleRtpRtcpImpl2
|
||||
// Module/ProcessThread dependency is gone.
|
||||
class SendTransport : public Transport,
|
||||
public sim_time_impl::SimulatedSequenceRunner {
|
||||
public:
|
||||
SendTransport()
|
||||
SendTransport(TimeDelta delay, GlobalSimulatedTimeController* time_controller)
|
||||
: receiver_(nullptr),
|
||||
time_controller_(nullptr),
|
||||
delay_ms_(0),
|
||||
time_controller_(time_controller),
|
||||
delay_(delay),
|
||||
rtp_packets_sent_(0),
|
||||
rtcp_packets_sent_(0),
|
||||
last_packet_(&header_extensions_) {}
|
||||
last_packet_(&header_extensions_) {
|
||||
time_controller_->Register(this);
|
||||
}
|
||||
|
||||
~SendTransport() { time_controller_->Unregister(this); }
|
||||
|
||||
void SetRtpRtcpModule(ModuleRtpRtcpImpl2* receiver) { receiver_ = receiver; }
|
||||
void SimulateNetworkDelay(int64_t delay_ms, TimeController* time_controller) {
|
||||
time_controller_ = time_controller;
|
||||
delay_ms_ = delay_ms;
|
||||
}
|
||||
void SimulateNetworkDelay(TimeDelta delay) { delay_ = delay; }
|
||||
bool SendRtp(const uint8_t* data,
|
||||
size_t len,
|
||||
const PacketOptions& options) override {
|
||||
@ -96,26 +105,49 @@ class SendTransport : public Transport {
|
||||
test::RtcpPacketParser parser;
|
||||
parser.Parse(data, len);
|
||||
last_nack_list_ = parser.nack()->packet_ids();
|
||||
|
||||
if (time_controller_) {
|
||||
time_controller_->AdvanceTime(TimeDelta::Millis(delay_ms_));
|
||||
}
|
||||
EXPECT_TRUE(receiver_);
|
||||
receiver_->IncomingRtcpPacket(data, len);
|
||||
Timestamp current_time = time_controller_->GetClock()->CurrentTime();
|
||||
Timestamp delivery_time = current_time + delay_;
|
||||
rtcp_packets_.push_back(
|
||||
Packet{delivery_time, std::vector<uint8_t>(data, data + len)});
|
||||
++rtcp_packets_sent_;
|
||||
RunReady(current_time);
|
||||
return true;
|
||||
}
|
||||
|
||||
// sim_time_impl::SimulatedSequenceRunner
|
||||
Timestamp GetNextRunTime() const override {
|
||||
if (!rtcp_packets_.empty())
|
||||
return rtcp_packets_.front().send_time;
|
||||
return Timestamp::PlusInfinity();
|
||||
}
|
||||
void RunReady(Timestamp at_time) override {
|
||||
while (!rtcp_packets_.empty() &&
|
||||
rtcp_packets_.front().send_time <= at_time) {
|
||||
Packet packet = std::move(rtcp_packets_.front());
|
||||
rtcp_packets_.pop_front();
|
||||
EXPECT_TRUE(receiver_);
|
||||
receiver_->IncomingRtcpPacket(packet.data.data(), packet.data.size());
|
||||
}
|
||||
}
|
||||
TaskQueueBase* GetAsTaskQueue() override {
|
||||
return reinterpret_cast<TaskQueueBase*>(this);
|
||||
}
|
||||
|
||||
size_t NumRtcpSent() { return rtcp_packets_sent_; }
|
||||
|
||||
ModuleRtpRtcpImpl2* receiver_;
|
||||
TimeController* time_controller_;
|
||||
int64_t delay_ms_;
|
||||
GlobalSimulatedTimeController* const time_controller_;
|
||||
TimeDelta delay_;
|
||||
int rtp_packets_sent_;
|
||||
size_t rtcp_packets_sent_;
|
||||
std::vector<uint16_t> last_nack_list_;
|
||||
RtpHeaderExtensionMap header_extensions_;
|
||||
RtpPacketReceived last_packet_;
|
||||
struct Packet {
|
||||
Timestamp send_time;
|
||||
std::vector<uint8_t> data;
|
||||
};
|
||||
std::deque<Packet> rtcp_packets_;
|
||||
};
|
||||
|
||||
struct TestConfig {
|
||||
@ -166,27 +198,32 @@ class RtpRtcpModule : public RtcpPacketTypeCounterObserver,
|
||||
uint32_t ssrc;
|
||||
};
|
||||
|
||||
RtpRtcpModule(TimeController* time_controller,
|
||||
RtpRtcpModule(GlobalSimulatedTimeController* time_controller,
|
||||
ProcessThread* process_thread,
|
||||
bool is_sender,
|
||||
const FieldTrialConfig& trials)
|
||||
: is_sender_(is_sender),
|
||||
: time_controller_(time_controller),
|
||||
is_sender_(is_sender),
|
||||
trials_(trials),
|
||||
process_thread_(process_thread),
|
||||
receive_statistics_(
|
||||
ReceiveStatistics::Create(time_controller->GetClock())),
|
||||
time_controller_(time_controller) {
|
||||
transport_(kOneWayNetworkDelay, time_controller) {
|
||||
CreateModuleImpl();
|
||||
transport_.SimulateNetworkDelay(kOneWayNetworkDelayMs, time_controller);
|
||||
}
|
||||
|
||||
~RtpRtcpModule() { process_thread_->DeRegisterModule(impl_.get()); }
|
||||
|
||||
TimeController* const time_controller_;
|
||||
const bool is_sender_;
|
||||
const FieldTrialConfig& trials_;
|
||||
ProcessThread* const process_thread_;
|
||||
RtcpPacketTypeCounter packets_sent_;
|
||||
RtcpPacketTypeCounter packets_received_;
|
||||
std::unique_ptr<ReceiveStatistics> receive_statistics_;
|
||||
SendTransport transport_;
|
||||
RtcpRttStatsTestImpl rtt_stats_;
|
||||
std::unique_ptr<ModuleRtpRtcpImpl2> impl_;
|
||||
int rtcp_report_interval_ms_ = 0;
|
||||
|
||||
void RtcpPacketTypesCounterUpdated(
|
||||
uint32_t ssrc,
|
||||
@ -218,8 +255,8 @@ class RtpRtcpModule : public RtcpPacketTypeCounterObserver,
|
||||
std::vector<uint16_t> LastNackListSent() {
|
||||
return transport_.last_nack_list_;
|
||||
}
|
||||
void SetRtcpReportIntervalAndReset(int rtcp_report_interval_ms) {
|
||||
rtcp_report_interval_ms_ = rtcp_report_interval_ms;
|
||||
void SetRtcpReportIntervalAndReset(TimeDelta rtcp_report_interval) {
|
||||
rtcp_report_interval_ = rtcp_report_interval;
|
||||
CreateModuleImpl();
|
||||
}
|
||||
const RtpPacketReceived& last_packet() { return transport_.last_packet_; }
|
||||
@ -242,23 +279,25 @@ class RtpRtcpModule : public RtcpPacketTypeCounterObserver,
|
||||
config.receive_statistics = receive_statistics_.get();
|
||||
config.rtcp_packet_type_counter_observer = this;
|
||||
config.rtt_stats = &rtt_stats_;
|
||||
config.rtcp_report_interval_ms = rtcp_report_interval_ms_;
|
||||
config.rtcp_report_interval_ms = rtcp_report_interval_.ms();
|
||||
config.local_media_ssrc = is_sender_ ? kSenderSsrc : kReceiverSsrc;
|
||||
config.need_rtp_packet_infos = true;
|
||||
config.non_sender_rtt_measurement = true;
|
||||
config.field_trials = &trials_;
|
||||
config.send_packet_observer = this;
|
||||
config.fec_generator = fec_generator_;
|
||||
|
||||
if (impl_)
|
||||
process_thread_->DeRegisterModule(impl_.get());
|
||||
impl_.reset(new ModuleRtpRtcpImpl2(config));
|
||||
process_thread_->RegisterModule(impl_.get(), RTC_FROM_HERE);
|
||||
impl_->SetRemoteSSRC(is_sender_ ? kReceiverSsrc : kSenderSsrc);
|
||||
impl_->SetRTCPStatus(RtcpMode::kCompound);
|
||||
}
|
||||
|
||||
TimeController* const time_controller_;
|
||||
std::map<uint32_t, RtcpPacketTypeCounter> counter_map_;
|
||||
absl::optional<SentPacket> last_sent_packet_;
|
||||
VideoFecGenerator* fec_generator_ = nullptr;
|
||||
TimeDelta rtcp_report_interval_ = kDefaultReportInterval;
|
||||
};
|
||||
} // namespace
|
||||
|
||||
@ -267,12 +306,20 @@ class RtpRtcpImpl2Test : public ::testing::TestWithParam<TestConfig> {
|
||||
RtpRtcpImpl2Test()
|
||||
: time_controller_(Timestamp::Micros(133590000000000)),
|
||||
field_trials_(FieldTrialConfig::GetFromTestConfig(GetParam())),
|
||||
process_thread_(
|
||||
time_controller_.CreateProcessThread("RtpRtcpImpl2Test")),
|
||||
sender_(&time_controller_,
|
||||
process_thread_.get(),
|
||||
/*is_sender=*/true,
|
||||
field_trials_),
|
||||
receiver_(&time_controller_,
|
||||
process_thread_.get(),
|
||||
/*is_sender=*/false,
|
||||
field_trials_) {}
|
||||
field_trials_) {
|
||||
process_thread_->Start();
|
||||
}
|
||||
|
||||
~RtpRtcpImpl2Test() { process_thread_->Stop(); }
|
||||
|
||||
void SetUp() override {
|
||||
// Send module.
|
||||
@ -295,8 +342,8 @@ class RtpRtcpImpl2Test : public ::testing::TestWithParam<TestConfig> {
|
||||
receiver_.transport_.SetRtpRtcpModule(sender_.impl_.get());
|
||||
}
|
||||
|
||||
void AdvanceTimeMs(int64_t milliseconds) {
|
||||
time_controller_.AdvanceTime(TimeDelta::Millis(milliseconds));
|
||||
void AdvanceTime(TimeDelta duration) {
|
||||
time_controller_.AdvanceTime(duration);
|
||||
}
|
||||
|
||||
void ReinitWithFec(VideoFecGenerator* fec_generator,
|
||||
@ -320,6 +367,7 @@ class RtpRtcpImpl2Test : public ::testing::TestWithParam<TestConfig> {
|
||||
|
||||
GlobalSimulatedTimeController time_controller_;
|
||||
FieldTrialConfig field_trials_;
|
||||
std::unique_ptr<ProcessThread> process_thread_;
|
||||
RtpRtcpModule sender_;
|
||||
std::unique_ptr<RTPSenderVideo> sender_video_;
|
||||
RtpRtcpModule receiver_;
|
||||
@ -389,7 +437,7 @@ TEST_P(RtpRtcpImpl2Test, RetransmitsAllLayers) {
|
||||
EXPECT_EQ(kSequenceNumber + 2, sender_.LastRtpSequenceNumber());
|
||||
|
||||
// Min required delay until retransmit = 5 + RTT ms (RTT = 0).
|
||||
AdvanceTimeMs(5);
|
||||
AdvanceTime(TimeDelta::Millis(5));
|
||||
|
||||
// Frame with kBaseLayerTid re-sent.
|
||||
IncomingRtcpNack(&sender_, kSequenceNumber);
|
||||
@ -417,10 +465,11 @@ TEST_P(RtpRtcpImpl2Test, Rtt) {
|
||||
EXPECT_TRUE(SendFrame(&sender_, sender_video_.get(), kBaseLayerTid));
|
||||
// Sender module should send an SR.
|
||||
EXPECT_EQ(0, sender_.impl_->SendRTCP(kRtcpReport));
|
||||
AdvanceTime(kOneWayNetworkDelay);
|
||||
|
||||
// Receiver module should send a RR with a response to the last received SR.
|
||||
AdvanceTimeMs(1000);
|
||||
EXPECT_EQ(0, receiver_.impl_->SendRTCP(kRtcpReport));
|
||||
AdvanceTime(kOneWayNetworkDelay);
|
||||
|
||||
// Verify RTT.
|
||||
int64_t rtt;
|
||||
@ -429,10 +478,10 @@ TEST_P(RtpRtcpImpl2Test, Rtt) {
|
||||
int64_t max_rtt;
|
||||
EXPECT_EQ(
|
||||
0, sender_.impl_->RTT(kReceiverSsrc, &rtt, &avg_rtt, &min_rtt, &max_rtt));
|
||||
EXPECT_NEAR(2 * kOneWayNetworkDelayMs, rtt, 1);
|
||||
EXPECT_NEAR(2 * kOneWayNetworkDelayMs, avg_rtt, 1);
|
||||
EXPECT_NEAR(2 * kOneWayNetworkDelayMs, min_rtt, 1);
|
||||
EXPECT_NEAR(2 * kOneWayNetworkDelayMs, max_rtt, 1);
|
||||
EXPECT_NEAR(2 * kOneWayNetworkDelay.ms(), rtt, 1);
|
||||
EXPECT_NEAR(2 * kOneWayNetworkDelay.ms(), avg_rtt, 1);
|
||||
EXPECT_NEAR(2 * kOneWayNetworkDelay.ms(), min_rtt, 1);
|
||||
EXPECT_NEAR(2 * kOneWayNetworkDelay.ms(), max_rtt, 1);
|
||||
|
||||
// No RTT from other ssrc.
|
||||
EXPECT_EQ(-1, sender_.impl_->RTT(kReceiverSsrc + 1, &rtt, &avg_rtt, &min_rtt,
|
||||
@ -441,11 +490,11 @@ TEST_P(RtpRtcpImpl2Test, Rtt) {
|
||||
// Verify RTT from rtt_stats config.
|
||||
EXPECT_EQ(0, sender_.rtt_stats_.LastProcessedRtt());
|
||||
EXPECT_EQ(0, sender_.impl_->rtt_ms());
|
||||
AdvanceTimeMs(1000);
|
||||
AdvanceTime(TimeDelta::Millis(1000));
|
||||
|
||||
EXPECT_NEAR(2 * kOneWayNetworkDelayMs, sender_.rtt_stats_.LastProcessedRtt(),
|
||||
1);
|
||||
EXPECT_NEAR(2 * kOneWayNetworkDelayMs, sender_.impl_->rtt_ms(), 1);
|
||||
EXPECT_NEAR(2 * kOneWayNetworkDelay.ms(),
|
||||
sender_.rtt_stats_.LastProcessedRtt(), 1);
|
||||
EXPECT_NEAR(2 * kOneWayNetworkDelay.ms(), sender_.impl_->rtt_ms(), 1);
|
||||
}
|
||||
|
||||
TEST_P(RtpRtcpImpl2Test, RttForReceiverOnly) {
|
||||
@ -453,7 +502,7 @@ TEST_P(RtpRtcpImpl2Test, RttForReceiverOnly) {
|
||||
EXPECT_EQ(0, receiver_.impl_->SendRTCP(kRtcpReport));
|
||||
|
||||
// Sender module should send a response to the last received RTRR (DLRR).
|
||||
AdvanceTimeMs(1000);
|
||||
AdvanceTime(TimeDelta::Millis(1000));
|
||||
// Send Frame before sending a SR.
|
||||
EXPECT_TRUE(SendFrame(&sender_, sender_video_.get(), kBaseLayerTid));
|
||||
EXPECT_EQ(0, sender_.impl_->SendRTCP(kRtcpReport));
|
||||
@ -461,29 +510,26 @@ TEST_P(RtpRtcpImpl2Test, RttForReceiverOnly) {
|
||||
// Verify RTT.
|
||||
EXPECT_EQ(0, receiver_.rtt_stats_.LastProcessedRtt());
|
||||
EXPECT_EQ(0, receiver_.impl_->rtt_ms());
|
||||
AdvanceTimeMs(1000);
|
||||
EXPECT_NEAR(2 * kOneWayNetworkDelayMs,
|
||||
AdvanceTime(TimeDelta::Millis(1000));
|
||||
EXPECT_NEAR(2 * kOneWayNetworkDelay.ms(),
|
||||
receiver_.rtt_stats_.LastProcessedRtt(), 1);
|
||||
EXPECT_NEAR(2 * kOneWayNetworkDelayMs, receiver_.impl_->rtt_ms(), 1);
|
||||
EXPECT_NEAR(2 * kOneWayNetworkDelay.ms(), receiver_.impl_->rtt_ms(), 1);
|
||||
}
|
||||
|
||||
TEST_P(RtpRtcpImpl2Test, NoSrBeforeMedia) {
|
||||
// Ignore fake transport delays in this test.
|
||||
sender_.transport_.SimulateNetworkDelay(0, &time_controller_);
|
||||
receiver_.transport_.SimulateNetworkDelay(0, &time_controller_);
|
||||
|
||||
sender_.impl_->Process();
|
||||
EXPECT_EQ(-1, sender_.RtcpSent().first_packet_time_ms);
|
||||
sender_.transport_.SimulateNetworkDelay(TimeDelta::Millis(0));
|
||||
receiver_.transport_.SimulateNetworkDelay(TimeDelta::Millis(0));
|
||||
|
||||
// Move ahead to the instant a rtcp is expected.
|
||||
// Verify no SR is sent before media has been sent, RR should still be sent
|
||||
// from the receiving module though.
|
||||
AdvanceTimeMs(2000);
|
||||
AdvanceTime(kDefaultReportInterval / 2);
|
||||
int64_t current_time = time_controller_.GetClock()->TimeInMilliseconds();
|
||||
sender_.impl_->Process();
|
||||
receiver_.impl_->Process();
|
||||
EXPECT_EQ(-1, sender_.RtcpSent().first_packet_time_ms);
|
||||
EXPECT_EQ(receiver_.RtcpSent().first_packet_time_ms, current_time);
|
||||
|
||||
// RTCP should be triggered by the RTP send.
|
||||
EXPECT_TRUE(SendFrame(&sender_, sender_video_.get(), kBaseLayerTid));
|
||||
EXPECT_EQ(sender_.RtcpSent().first_packet_time_ms, current_time);
|
||||
}
|
||||
@ -498,6 +544,7 @@ TEST_P(RtpRtcpImpl2Test, RtcpPacketTypeCounter_Nack) {
|
||||
const uint16_t kNackLength = 1;
|
||||
uint16_t nack_list[kNackLength] = {123};
|
||||
EXPECT_EQ(0, receiver_.impl_->SendNACK(nack_list, kNackLength));
|
||||
AdvanceTime(kOneWayNetworkDelay);
|
||||
EXPECT_EQ(1U, receiver_.RtcpSent().nack_packets);
|
||||
EXPECT_GT(receiver_.RtcpSent().first_packet_time_ms, -1);
|
||||
|
||||
@ -586,7 +633,7 @@ TEST_P(RtpRtcpImpl2Test, SendsExtendedNackList) {
|
||||
}
|
||||
|
||||
TEST_P(RtpRtcpImpl2Test, ReSendsNackListAfterRttMs) {
|
||||
sender_.transport_.SimulateNetworkDelay(0, &time_controller_);
|
||||
sender_.transport_.SimulateNetworkDelay(TimeDelta::Millis(0));
|
||||
// Send module sends a NACK.
|
||||
const uint16_t kNackLength = 2;
|
||||
uint16_t nack_list[kNackLength] = {123, 125};
|
||||
@ -598,20 +645,20 @@ TEST_P(RtpRtcpImpl2Test, ReSendsNackListAfterRttMs) {
|
||||
EXPECT_THAT(sender_.LastNackListSent(), ElementsAre(123, 125));
|
||||
|
||||
// Same list not re-send, rtt interval has not passed.
|
||||
const int kStartupRttMs = 100;
|
||||
AdvanceTimeMs(kStartupRttMs);
|
||||
const TimeDelta kStartupRtt = TimeDelta::Millis(100);
|
||||
AdvanceTime(kStartupRtt);
|
||||
EXPECT_EQ(0, sender_.impl_->SendNACK(nack_list, kNackLength));
|
||||
EXPECT_EQ(1U, sender_.RtcpSent().nack_packets);
|
||||
|
||||
// Rtt interval passed, full list sent.
|
||||
AdvanceTimeMs(1);
|
||||
AdvanceTime(TimeDelta::Millis(1));
|
||||
EXPECT_EQ(0, sender_.impl_->SendNACK(nack_list, kNackLength));
|
||||
EXPECT_EQ(2U, sender_.RtcpSent().nack_packets);
|
||||
EXPECT_THAT(sender_.LastNackListSent(), ElementsAre(123, 125));
|
||||
}
|
||||
|
||||
TEST_P(RtpRtcpImpl2Test, UniqueNackRequests) {
|
||||
receiver_.transport_.SimulateNetworkDelay(0, &time_controller_);
|
||||
receiver_.transport_.SimulateNetworkDelay(TimeDelta::Millis(0));
|
||||
EXPECT_EQ(0U, receiver_.RtcpSent().nack_packets);
|
||||
EXPECT_EQ(0U, receiver_.RtcpSent().nack_requests);
|
||||
EXPECT_EQ(0U, receiver_.RtcpSent().unique_nack_requests);
|
||||
@ -633,8 +680,8 @@ TEST_P(RtpRtcpImpl2Test, UniqueNackRequests) {
|
||||
EXPECT_EQ(100, sender_.RtcpReceived().UniqueNackRequestsInPercent());
|
||||
|
||||
// Receive module sends new request with duplicated packets.
|
||||
const int kStartupRttMs = 100;
|
||||
AdvanceTimeMs(kStartupRttMs + 1);
|
||||
const TimeDelta kStartupRtt = TimeDelta::Millis(100);
|
||||
AdvanceTime(kStartupRtt + TimeDelta::Millis(1));
|
||||
const uint16_t kNackLength2 = 4;
|
||||
uint16_t nack_list2[kNackLength2] = {11, 18, 20, 21};
|
||||
EXPECT_EQ(0, receiver_.impl_->SendNACK(nack_list2, kNackLength2));
|
||||
@ -651,7 +698,7 @@ TEST_P(RtpRtcpImpl2Test, UniqueNackRequests) {
|
||||
}
|
||||
|
||||
TEST_P(RtpRtcpImpl2Test, ConfigurableRtcpReportInterval) {
|
||||
const int kVideoReportInterval = 3000;
|
||||
const TimeDelta kVideoReportInterval = TimeDelta::Millis(3000);
|
||||
|
||||
// Recreate sender impl with new configuration, and redo setup.
|
||||
sender_.SetRtcpReportIntervalAndReset(kVideoReportInterval);
|
||||
@ -660,41 +707,34 @@ TEST_P(RtpRtcpImpl2Test, ConfigurableRtcpReportInterval) {
|
||||
EXPECT_TRUE(SendFrame(&sender_, sender_video_.get(), kBaseLayerTid));
|
||||
|
||||
// Initial state
|
||||
sender_.impl_->Process();
|
||||
EXPECT_EQ(sender_.RtcpSent().first_packet_time_ms, -1);
|
||||
EXPECT_EQ(0u, sender_.transport_.NumRtcpSent());
|
||||
|
||||
// Move ahead to the last ms before a rtcp is expected, no action.
|
||||
AdvanceTimeMs(kVideoReportInterval / 2 - 1);
|
||||
sender_.impl_->Process();
|
||||
AdvanceTime(kVideoReportInterval / 2 - TimeDelta::Millis(1));
|
||||
EXPECT_EQ(sender_.RtcpSent().first_packet_time_ms, -1);
|
||||
EXPECT_EQ(sender_.transport_.NumRtcpSent(), 0u);
|
||||
|
||||
// Move ahead to the first rtcp. Send RTCP.
|
||||
AdvanceTimeMs(1);
|
||||
sender_.impl_->Process();
|
||||
AdvanceTime(TimeDelta::Millis(1));
|
||||
EXPECT_GT(sender_.RtcpSent().first_packet_time_ms, -1);
|
||||
EXPECT_EQ(sender_.transport_.NumRtcpSent(), 1u);
|
||||
|
||||
EXPECT_TRUE(SendFrame(&sender_, sender_video_.get(), kBaseLayerTid));
|
||||
|
||||
// Move ahead to the last possible second before second rtcp is expected.
|
||||
AdvanceTimeMs(kVideoReportInterval * 1 / 2 - 1);
|
||||
sender_.impl_->Process();
|
||||
AdvanceTime(kVideoReportInterval * 1 / 2 - TimeDelta::Millis(1));
|
||||
EXPECT_EQ(sender_.transport_.NumRtcpSent(), 1u);
|
||||
|
||||
// Move ahead into the range of second rtcp, the second rtcp may be sent.
|
||||
AdvanceTimeMs(1);
|
||||
sender_.impl_->Process();
|
||||
AdvanceTime(TimeDelta::Millis(1));
|
||||
EXPECT_GE(sender_.transport_.NumRtcpSent(), 1u);
|
||||
|
||||
AdvanceTimeMs(kVideoReportInterval / 2);
|
||||
sender_.impl_->Process();
|
||||
AdvanceTime(kVideoReportInterval / 2);
|
||||
EXPECT_GE(sender_.transport_.NumRtcpSent(), 1u);
|
||||
|
||||
// Move out the range of second rtcp, the second rtcp must have been sent.
|
||||
AdvanceTimeMs(kVideoReportInterval / 2);
|
||||
sender_.impl_->Process();
|
||||
AdvanceTime(kVideoReportInterval / 2);
|
||||
EXPECT_EQ(sender_.transport_.NumRtcpSent(), 2u);
|
||||
}
|
||||
|
||||
@ -716,7 +756,7 @@ TEST_P(RtpRtcpImpl2Test, StoresPacketInfoForSentPackets) {
|
||||
packet.set_first_packet_of_frame(true);
|
||||
packet.SetMarker(true);
|
||||
sender_.impl_->TrySendPacket(&packet, pacing_info);
|
||||
AdvanceTimeMs(1);
|
||||
AdvanceTime(TimeDelta::Millis(1));
|
||||
|
||||
std::vector<RtpSequenceNumberMap::Info> seqno_info =
|
||||
sender_.impl_->GetSentRtpPacketInfos(std::vector<uint16_t>{1});
|
||||
@ -741,7 +781,7 @@ TEST_P(RtpRtcpImpl2Test, StoresPacketInfoForSentPackets) {
|
||||
packet.SetMarker(true);
|
||||
sender_.impl_->TrySendPacket(&packet, pacing_info);
|
||||
|
||||
AdvanceTimeMs(1);
|
||||
AdvanceTime(TimeDelta::Millis(1));
|
||||
|
||||
seqno_info =
|
||||
sender_.impl_->GetSentRtpPacketInfos(std::vector<uint16_t>{2, 3, 4});
|
||||
@ -771,6 +811,7 @@ TEST_P(RtpRtcpImpl2Test, SenderReportStatsAvailable) {
|
||||
EXPECT_TRUE(SendFrame(&sender_, sender_video_.get(), kBaseLayerTid));
|
||||
// Send an SR.
|
||||
ASSERT_THAT(sender_.impl_->SendRTCP(kRtcpReport), Eq(0));
|
||||
AdvanceTime(kOneWayNetworkDelay);
|
||||
EXPECT_THAT(receiver_.impl_->GetSenderReportStats(), Not(Eq(absl::nullopt)));
|
||||
}
|
||||
|
||||
@ -821,10 +862,12 @@ TEST_P(RtpRtcpImpl2Test, SenderReportStatsCount) {
|
||||
EXPECT_TRUE(SendFrame(&sender_, sender_video_.get(), kBaseLayerTid));
|
||||
// Send the first SR.
|
||||
ASSERT_THAT(sender_.impl_->SendRTCP(kRtcpReport), Eq(0));
|
||||
AdvanceTime(kOneWayNetworkDelay);
|
||||
EXPECT_THAT(receiver_.impl_->GetSenderReportStats(),
|
||||
Optional(Field(&SenderReportStats::reports_count, Eq(1u))));
|
||||
// Send the second SR.
|
||||
ASSERT_THAT(sender_.impl_->SendRTCP(kRtcpReport), Eq(0));
|
||||
AdvanceTime(kOneWayNetworkDelay);
|
||||
EXPECT_THAT(receiver_.impl_->GetSenderReportStats(),
|
||||
Optional(Field(&SenderReportStats::reports_count, Eq(2u))));
|
||||
}
|
||||
@ -836,6 +879,7 @@ TEST_P(RtpRtcpImpl2Test, SenderReportStatsArrivalTimestampSet) {
|
||||
EXPECT_TRUE(SendFrame(&sender_, sender_video_.get(), kBaseLayerTid));
|
||||
// Send an SR.
|
||||
ASSERT_THAT(sender_.impl_->SendRTCP(kRtcpReport), Eq(0));
|
||||
AdvanceTime(kOneWayNetworkDelay);
|
||||
auto stats = receiver_.impl_->GetSenderReportStats();
|
||||
ASSERT_THAT(stats, Not(Eq(absl::nullopt)));
|
||||
EXPECT_TRUE(stats->last_arrival_timestamp.Valid());
|
||||
@ -850,9 +894,10 @@ TEST_P(RtpRtcpImpl2Test, SenderReportStatsPacketByteCounters) {
|
||||
ASSERT_THAT(sender_.transport_.rtp_packets_sent_, Gt(0));
|
||||
// Advance time otherwise the RTCP SR report will not include any packets
|
||||
// generated by `SendFrame()`.
|
||||
AdvanceTimeMs(1);
|
||||
AdvanceTime(TimeDelta::Millis(1));
|
||||
// Send an SR.
|
||||
ASSERT_THAT(sender_.impl_->SendRTCP(kRtcpReport), Eq(0));
|
||||
AdvanceTime(kOneWayNetworkDelay);
|
||||
EXPECT_THAT(receiver_.impl_->GetSenderReportStats(),
|
||||
Optional(AllOf(Field(&SenderReportStats::packets_sent, Gt(0u)),
|
||||
Field(&SenderReportStats::bytes_sent, Gt(0u)))));
|
||||
@ -960,16 +1005,16 @@ TEST_P(RtpRtcpImpl2Test, AssignsTransmissionTimeOffset) {
|
||||
sender_.RegisterHeaderExtension(TransmissionOffset::kUri,
|
||||
kTransmissionOffsetExtensionId);
|
||||
|
||||
constexpr int kOffsetMs = 100;
|
||||
constexpr TimeDelta kOffset = TimeDelta::Millis(100);
|
||||
// Transmission offset is calculated from difference between capture time
|
||||
// and send time.
|
||||
int64_t capture_time_ms = time_controller_.GetClock()->TimeInMilliseconds();
|
||||
time_controller_.AdvanceTime(TimeDelta::Millis(kOffsetMs));
|
||||
time_controller_.AdvanceTime(kOffset);
|
||||
|
||||
EXPECT_TRUE(SendFrame(&sender_, sender_video_.get(), kBaseLayerTid,
|
||||
/*timestamp=*/0, capture_time_ms));
|
||||
EXPECT_EQ(sender_.last_packet().GetExtension<TransmissionOffset>(),
|
||||
kOffsetMs * kCaptureTimeMsToRtpTimestamp);
|
||||
kOffset.ms() * kCaptureTimeMsToRtpTimestamp);
|
||||
}
|
||||
|
||||
TEST_P(RtpRtcpImpl2Test, PropagatesSentPacketInfo) {
|
||||
|
||||
@ -226,4 +226,14 @@ void GlobalSimulatedTimeController::AdvanceTime(TimeDelta duration) {
|
||||
impl_.RunReadyRunners();
|
||||
}
|
||||
|
||||
void GlobalSimulatedTimeController::Register(
|
||||
sim_time_impl::SimulatedSequenceRunner* runner) {
|
||||
impl_.Register(runner);
|
||||
}
|
||||
|
||||
void GlobalSimulatedTimeController::Unregister(
|
||||
sim_time_impl::SimulatedSequenceRunner* runner) {
|
||||
impl_.Unregister(runner);
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
@ -140,6 +140,17 @@ class GlobalSimulatedTimeController : public TimeController {
|
||||
|
||||
void AdvanceTime(TimeDelta duration) override;
|
||||
|
||||
// Makes the simulated time controller aware of a custom
|
||||
// SimulatedSequenceRunner.
|
||||
// TODO(bugs.webrtc.org/11581): remove method once the ModuleRtpRtcpImpl2 unit
|
||||
// test stops using it.
|
||||
void Register(sim_time_impl::SimulatedSequenceRunner* runner);
|
||||
// Removes a previously installed custom SimulatedSequenceRunner from the
|
||||
// simulated time controller.
|
||||
// TODO(bugs.webrtc.org/11581): remove method once the ModuleRtpRtcpImpl2 unit
|
||||
// test stops using it.
|
||||
void Unregister(sim_time_impl::SimulatedSequenceRunner* runner);
|
||||
|
||||
private:
|
||||
rtc::ScopedBaseFakeClock global_clock_;
|
||||
// Provides simulated CurrentNtpInMilliseconds()
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user