Introduce PacketReceiver and remove configuration of simulations via the BweTestConfig.
This makes it possible to build more flexible simulations, and makes it easier to implement bi-directional simulations. This also removes support for generating baseline files and comparing against a baseline, which hasn't turned out to be particuarly useful. BUG=4173 R=pbos@webrtc.org Review URL: https://webrtc-codereview.appspot.com/35069004 Cr-Commit-Position: refs/heads/master@{#8311} git-svn-id: http://webrtc.googlecode.com/svn/trunk@8311 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
@ -19,57 +19,34 @@ namespace webrtc {
|
|||||||
namespace testing {
|
namespace testing {
|
||||||
namespace bwe {
|
namespace bwe {
|
||||||
#if BWE_TEST_LOGGING_COMPILE_TIME_ENABLE
|
#if BWE_TEST_LOGGING_COMPILE_TIME_ENABLE
|
||||||
BweTestConfig::EstimatorConfig CreateEstimatorConfig(
|
|
||||||
int flow_id, bool plot_delay, bool plot_estimate) {
|
|
||||||
static const AbsoluteSendTimeRemoteBitrateEstimatorFactory factory =
|
|
||||||
AbsoluteSendTimeRemoteBitrateEstimatorFactory();
|
|
||||||
|
|
||||||
return BweTestConfig::EstimatorConfig("AST", flow_id, &factory, kAimdControl,
|
|
||||||
kRembEstimator, plot_delay,
|
|
||||||
plot_estimate);
|
|
||||||
}
|
|
||||||
|
|
||||||
BweTestConfig MakeAdaptiveBweTestConfig() {
|
|
||||||
BweTestConfig result;
|
|
||||||
result.estimator_configs.push_back(CreateEstimatorConfig(0, true, true));
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
BweTestConfig MakeMultiFlowBweTestConfig(int flow_count) {
|
|
||||||
BweTestConfig result;
|
|
||||||
for (int i = 0; i < flow_count; ++i) {
|
|
||||||
result.estimator_configs.push_back(CreateEstimatorConfig(i, false, true));
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
// This test fixture is used to instantiate tests running with adaptive video
|
// This test fixture is used to instantiate tests running with adaptive video
|
||||||
// senders.
|
// senders.
|
||||||
class BweSimulation : public BweTest,
|
class BweSimulation : public BweTest,
|
||||||
public ::testing::TestWithParam<BweTestConfig> {
|
public ::testing::TestWithParam<BandwidthEstimatorType> {
|
||||||
public:
|
public:
|
||||||
BweSimulation() : BweTest() {}
|
BweSimulation() : BweTest() {}
|
||||||
virtual ~BweSimulation() {}
|
virtual ~BweSimulation() {}
|
||||||
|
|
||||||
virtual void SetUp() {
|
protected:
|
||||||
const BweTestConfig& config = GetParam();
|
virtual void SetUp() OVERRIDE { BweTest::SetUp(); }
|
||||||
SetupTestFromConfig(config);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DISALLOW_COPY_AND_ASSIGN(BweSimulation);
|
DISALLOW_COPY_AND_ASSIGN(BweSimulation);
|
||||||
};
|
};
|
||||||
|
|
||||||
INSTANTIATE_TEST_CASE_P(VideoSendersTest, BweSimulation,
|
INSTANTIATE_TEST_CASE_P(VideoSendersTest,
|
||||||
::testing::Values(MakeAdaptiveBweTestConfig()));
|
BweSimulation,
|
||||||
|
::testing::Values(kRembEstimator,
|
||||||
|
kFullSendSideEstimator));
|
||||||
|
|
||||||
TEST_P(BweSimulation, SprintUplinkTest) {
|
TEST_P(BweSimulation, SprintUplinkTest) {
|
||||||
VerboseLogging(true);
|
VerboseLogging(true);
|
||||||
AdaptiveVideoSource source(0, 30, 300, 0, 0);
|
AdaptiveVideoSource source(0, 30, 300, 0, 0);
|
||||||
PacketSender sender(this, &source, kRembEstimator);
|
PacketSender sender(this, &source, GetParam());
|
||||||
RateCounterFilter counter1(this, "sender_output");
|
RateCounterFilter counter1(this, "sender_output");
|
||||||
TraceBasedDeliveryFilter filter(this, "link_capacity");
|
TraceBasedDeliveryFilter filter(this, "link_capacity");
|
||||||
RateCounterFilter counter2(this, "receiver_input");
|
RateCounterFilter counter2(this, "receiver_input");
|
||||||
|
PacketReceiver receiver(this, 0, GetParam(), true, true);
|
||||||
ASSERT_TRUE(filter.Init(test::ResourcePath("sprint-uplink", "rx")));
|
ASSERT_TRUE(filter.Init(test::ResourcePath("sprint-uplink", "rx")));
|
||||||
RunFor(60 * 1000);
|
RunFor(60 * 1000);
|
||||||
}
|
}
|
||||||
@ -77,10 +54,11 @@ TEST_P(BweSimulation, SprintUplinkTest) {
|
|||||||
TEST_P(BweSimulation, Verizon4gDownlinkTest) {
|
TEST_P(BweSimulation, Verizon4gDownlinkTest) {
|
||||||
VerboseLogging(true);
|
VerboseLogging(true);
|
||||||
AdaptiveVideoSource source(0, 30, 300, 0, 0);
|
AdaptiveVideoSource source(0, 30, 300, 0, 0);
|
||||||
PacketSender sender(this, &source, kRembEstimator);
|
PacketSender sender(this, &source, GetParam());
|
||||||
RateCounterFilter counter1(this, "sender_output");
|
RateCounterFilter counter1(this, "sender_output");
|
||||||
TraceBasedDeliveryFilter filter(this, "link_capacity");
|
TraceBasedDeliveryFilter filter(this, "link_capacity");
|
||||||
RateCounterFilter counter2(this, "receiver_input");
|
RateCounterFilter counter2(this, "receiver_input");
|
||||||
|
PacketReceiver receiver(this, 0, GetParam(), true, true);
|
||||||
ASSERT_TRUE(filter.Init(test::ResourcePath("verizon4g-downlink", "rx")));
|
ASSERT_TRUE(filter.Init(test::ResourcePath("verizon4g-downlink", "rx")));
|
||||||
RunFor(22 * 60 * 1000);
|
RunFor(22 * 60 * 1000);
|
||||||
}
|
}
|
||||||
@ -88,9 +66,10 @@ TEST_P(BweSimulation, Verizon4gDownlinkTest) {
|
|||||||
TEST_P(BweSimulation, Choke1000kbps500kbps1000kbps) {
|
TEST_P(BweSimulation, Choke1000kbps500kbps1000kbps) {
|
||||||
VerboseLogging(true);
|
VerboseLogging(true);
|
||||||
AdaptiveVideoSource source(0, 30, 300, 0, 0);
|
AdaptiveVideoSource source(0, 30, 300, 0, 0);
|
||||||
PacketSender sender(this, &source, kRembEstimator);
|
PacketSender sender(this, &source, GetParam());
|
||||||
ChokeFilter filter(this);
|
ChokeFilter filter(this);
|
||||||
RateCounterFilter counter(this, "receiver_input");
|
RateCounterFilter counter(this, "receiver_input");
|
||||||
|
PacketReceiver receiver(this, 0, GetParam(), true, true);
|
||||||
filter.SetCapacity(1000);
|
filter.SetCapacity(1000);
|
||||||
filter.SetMaxDelay(500);
|
filter.SetMaxDelay(500);
|
||||||
RunFor(60 * 1000);
|
RunFor(60 * 1000);
|
||||||
@ -103,9 +82,10 @@ TEST_P(BweSimulation, Choke1000kbps500kbps1000kbps) {
|
|||||||
TEST_P(BweSimulation, PacerChoke1000kbps500kbps1000kbps) {
|
TEST_P(BweSimulation, PacerChoke1000kbps500kbps1000kbps) {
|
||||||
VerboseLogging(true);
|
VerboseLogging(true);
|
||||||
PeriodicKeyFrameSource source(0, 30, 300, 0, 0, 1000);
|
PeriodicKeyFrameSource source(0, 30, 300, 0, 0, 1000);
|
||||||
PacedVideoSender sender(this, &source, kRembEstimator);
|
PacedVideoSender sender(this, &source, GetParam());
|
||||||
ChokeFilter filter(this);
|
ChokeFilter filter(this);
|
||||||
RateCounterFilter counter(this, "receiver_input");
|
RateCounterFilter counter(this, "receiver_input");
|
||||||
|
PacketReceiver receiver(this, 0, GetParam(), true, true);
|
||||||
filter.SetCapacity(1000);
|
filter.SetCapacity(1000);
|
||||||
filter.SetMaxDelay(500);
|
filter.SetMaxDelay(500);
|
||||||
RunFor(60 * 1000);
|
RunFor(60 * 1000);
|
||||||
@ -118,9 +98,10 @@ TEST_P(BweSimulation, PacerChoke1000kbps500kbps1000kbps) {
|
|||||||
TEST_P(BweSimulation, PacerChoke10000kbps) {
|
TEST_P(BweSimulation, PacerChoke10000kbps) {
|
||||||
VerboseLogging(true);
|
VerboseLogging(true);
|
||||||
PeriodicKeyFrameSource source(0, 30, 300, 0, 0, 1000);
|
PeriodicKeyFrameSource source(0, 30, 300, 0, 0, 1000);
|
||||||
PacedVideoSender sender(this, &source, kRembEstimator);
|
PacedVideoSender sender(this, &source, GetParam());
|
||||||
ChokeFilter filter(this);
|
ChokeFilter filter(this);
|
||||||
RateCounterFilter counter(this, "receiver_input");
|
RateCounterFilter counter(this, "receiver_input");
|
||||||
|
PacketReceiver receiver(this, 0, GetParam(), true, true);
|
||||||
filter.SetCapacity(10000);
|
filter.SetCapacity(10000);
|
||||||
filter.SetMaxDelay(500);
|
filter.SetMaxDelay(500);
|
||||||
RunFor(60 * 1000);
|
RunFor(60 * 1000);
|
||||||
@ -129,9 +110,10 @@ TEST_P(BweSimulation, PacerChoke10000kbps) {
|
|||||||
TEST_P(BweSimulation, PacerChoke200kbps30kbps200kbps) {
|
TEST_P(BweSimulation, PacerChoke200kbps30kbps200kbps) {
|
||||||
VerboseLogging(true);
|
VerboseLogging(true);
|
||||||
PeriodicKeyFrameSource source(0, 30, 300, 0, 0, 1000);
|
PeriodicKeyFrameSource source(0, 30, 300, 0, 0, 1000);
|
||||||
PacedVideoSender sender(this, &source, kRembEstimator);
|
PacedVideoSender sender(this, &source, GetParam());
|
||||||
ChokeFilter filter(this);
|
ChokeFilter filter(this);
|
||||||
RateCounterFilter counter(this, "receiver_input");
|
RateCounterFilter counter(this, "receiver_input");
|
||||||
|
PacketReceiver receiver(this, 0, GetParam(), true, true);
|
||||||
filter.SetCapacity(200);
|
filter.SetCapacity(200);
|
||||||
filter.SetMaxDelay(500);
|
filter.SetMaxDelay(500);
|
||||||
RunFor(60 * 1000);
|
RunFor(60 * 1000);
|
||||||
@ -144,9 +126,10 @@ TEST_P(BweSimulation, PacerChoke200kbps30kbps200kbps) {
|
|||||||
TEST_P(BweSimulation, Choke200kbps30kbps200kbps) {
|
TEST_P(BweSimulation, Choke200kbps30kbps200kbps) {
|
||||||
VerboseLogging(true);
|
VerboseLogging(true);
|
||||||
AdaptiveVideoSource source(0, 30, 300, 0, 0);
|
AdaptiveVideoSource source(0, 30, 300, 0, 0);
|
||||||
PacketSender sender(this, &source, kRembEstimator);
|
PacketSender sender(this, &source, GetParam());
|
||||||
ChokeFilter filter(this);
|
ChokeFilter filter(this);
|
||||||
RateCounterFilter counter(this, "receiver_input");
|
RateCounterFilter counter(this, "receiver_input");
|
||||||
|
PacketReceiver receiver(this, 0, GetParam(), true, true);
|
||||||
filter.SetCapacity(200);
|
filter.SetCapacity(200);
|
||||||
filter.SetMaxDelay(500);
|
filter.SetMaxDelay(500);
|
||||||
RunFor(60 * 1000);
|
RunFor(60 * 1000);
|
||||||
@ -164,6 +147,7 @@ TEST_P(BweSimulation, GoogleWifiTrace3Mbps) {
|
|||||||
TraceBasedDeliveryFilter filter(this, "link_capacity");
|
TraceBasedDeliveryFilter filter(this, "link_capacity");
|
||||||
filter.SetMaxDelay(500);
|
filter.SetMaxDelay(500);
|
||||||
RateCounterFilter counter2(this, "receiver_input");
|
RateCounterFilter counter2(this, "receiver_input");
|
||||||
|
PacketReceiver receiver(this, 0, GetParam(), true, true);
|
||||||
ASSERT_TRUE(filter.Init(test::ResourcePath("google-wifi-3mbps", "rx")));
|
ASSERT_TRUE(filter.Init(test::ResourcePath("google-wifi-3mbps", "rx")));
|
||||||
RunFor(300 * 1000);
|
RunFor(300 * 1000);
|
||||||
}
|
}
|
||||||
@ -176,23 +160,12 @@ TEST_P(BweSimulation, PacerGoogleWifiTrace3Mbps) {
|
|||||||
TraceBasedDeliveryFilter filter(this, "link_capacity");
|
TraceBasedDeliveryFilter filter(this, "link_capacity");
|
||||||
filter.SetMaxDelay(500);
|
filter.SetMaxDelay(500);
|
||||||
RateCounterFilter counter2(this, "receiver_input");
|
RateCounterFilter counter2(this, "receiver_input");
|
||||||
|
PacketReceiver receiver(this, 0, GetParam(), true, true);
|
||||||
ASSERT_TRUE(filter.Init(test::ResourcePath("google-wifi-3mbps", "rx")));
|
ASSERT_TRUE(filter.Init(test::ResourcePath("google-wifi-3mbps", "rx")));
|
||||||
RunFor(300 * 1000);
|
RunFor(300 * 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
class MultiFlowBweSimulation : public BweSimulation {
|
TEST_P(BweSimulation, SelfFairnessTest) {
|
||||||
public:
|
|
||||||
MultiFlowBweSimulation() : BweSimulation() {}
|
|
||||||
virtual ~MultiFlowBweSimulation() {}
|
|
||||||
|
|
||||||
private:
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(MultiFlowBweSimulation);
|
|
||||||
};
|
|
||||||
|
|
||||||
INSTANTIATE_TEST_CASE_P(VideoSendersTest, MultiFlowBweSimulation,
|
|
||||||
::testing::Values(MakeMultiFlowBweTestConfig(3)));
|
|
||||||
|
|
||||||
TEST_P(MultiFlowBweSimulation, SelfFairnessTest) {
|
|
||||||
VerboseLogging(true);
|
VerboseLogging(true);
|
||||||
const int kAllFlowIds[] = {0, 1, 2};
|
const int kAllFlowIds[] = {0, 1, 2};
|
||||||
const size_t kNumFlows = sizeof(kAllFlowIds) / sizeof(kAllFlowIds[0]);
|
const size_t kNumFlows = sizeof(kAllFlowIds) / sizeof(kAllFlowIds[0]);
|
||||||
@ -203,7 +176,7 @@ TEST_P(MultiFlowBweSimulation, SelfFairnessTest) {
|
|||||||
// competing for the bandwidth.
|
// competing for the bandwidth.
|
||||||
sources[i].reset(
|
sources[i].reset(
|
||||||
new AdaptiveVideoSource(kAllFlowIds[i], 30, 300, 0, i * 20000));
|
new AdaptiveVideoSource(kAllFlowIds[i], 30, 300, 0, i * 20000));
|
||||||
senders[i].reset(new PacketSender(this, sources[i].get(), kRembEstimator));
|
senders[i].reset(new PacketSender(this, sources[i].get(), GetParam()));
|
||||||
}
|
}
|
||||||
|
|
||||||
ChokeFilter choke(this, CreateFlowIds(kAllFlowIds, kNumFlows));
|
ChokeFilter choke(this, CreateFlowIds(kAllFlowIds, kNumFlows));
|
||||||
@ -218,10 +191,16 @@ TEST_P(MultiFlowBweSimulation, SelfFairnessTest) {
|
|||||||
RateCounterFilter total_utilization(
|
RateCounterFilter total_utilization(
|
||||||
this, CreateFlowIds(kAllFlowIds, kNumFlows), "total_utilization");
|
this, CreateFlowIds(kAllFlowIds, kNumFlows), "total_utilization");
|
||||||
|
|
||||||
|
scoped_ptr<PacketReceiver> receivers[kNumFlows];
|
||||||
|
for (size_t i = 0; i < kNumFlows; ++i) {
|
||||||
|
receivers[i].reset(
|
||||||
|
new PacketReceiver(this, kAllFlowIds[i], GetParam(), i == 0, false));
|
||||||
|
}
|
||||||
|
|
||||||
RunFor(30 * 60 * 1000);
|
RunFor(30 * 60 * 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_P(MultiFlowBweSimulation, PacedSelfFairnessTest) {
|
TEST_P(BweSimulation, PacedSelfFairnessTest) {
|
||||||
VerboseLogging(true);
|
VerboseLogging(true);
|
||||||
const int kAllFlowIds[] = {0, 1, 2};
|
const int kAllFlowIds[] = {0, 1, 2};
|
||||||
const size_t kNumFlows = sizeof(kAllFlowIds) / sizeof(kAllFlowIds[0]);
|
const size_t kNumFlows = sizeof(kAllFlowIds) / sizeof(kAllFlowIds[0]);
|
||||||
@ -233,8 +212,7 @@ TEST_P(MultiFlowBweSimulation, PacedSelfFairnessTest) {
|
|||||||
// competing for the bandwidth.
|
// competing for the bandwidth.
|
||||||
sources[i].reset(new PeriodicKeyFrameSource(kAllFlowIds[i], 30, 300, 0,
|
sources[i].reset(new PeriodicKeyFrameSource(kAllFlowIds[i], 30, 300, 0,
|
||||||
i * 20000, 1000));
|
i * 20000, 1000));
|
||||||
senders[i].reset(
|
senders[i].reset(new PacedVideoSender(this, sources[i].get(), GetParam()));
|
||||||
new PacedVideoSender(this, sources[i].get(), kRembEstimator));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ChokeFilter choke(this, CreateFlowIds(kAllFlowIds, kNumFlows));
|
ChokeFilter choke(this, CreateFlowIds(kAllFlowIds, kNumFlows));
|
||||||
@ -249,6 +227,12 @@ TEST_P(MultiFlowBweSimulation, PacedSelfFairnessTest) {
|
|||||||
RateCounterFilter total_utilization(
|
RateCounterFilter total_utilization(
|
||||||
this, CreateFlowIds(kAllFlowIds, kNumFlows), "total_utilization");
|
this, CreateFlowIds(kAllFlowIds, kNumFlows), "total_utilization");
|
||||||
|
|
||||||
|
scoped_ptr<PacketReceiver> receivers[kNumFlows];
|
||||||
|
for (size_t i = 0; i < kNumFlows; ++i) {
|
||||||
|
receivers[i].reset(
|
||||||
|
new PacketReceiver(this, kAllFlowIds[i], GetParam(), i == 0, false));
|
||||||
|
}
|
||||||
|
|
||||||
RunFor(30 * 60 * 1000);
|
RunFor(30 * 60 * 1000);
|
||||||
}
|
}
|
||||||
#endif // BWE_TEST_LOGGING_COMPILE_TIME_ENABLE
|
#endif // BWE_TEST_LOGGING_COMPILE_TIME_ENABLE
|
||||||
|
@ -20,92 +20,39 @@ using std::string;
|
|||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
namespace testing {
|
namespace testing {
|
||||||
namespace bwe {
|
namespace bwe {
|
||||||
enum Estimator { kAbsSendTime, kTransmissionOffset };
|
|
||||||
|
|
||||||
BweTestConfig::EstimatorConfig EstimatorConfigs(Estimator estimator,
|
|
||||||
int flow_id) {
|
|
||||||
static const RemoteBitrateEstimatorFactory factories[] = {
|
|
||||||
RemoteBitrateEstimatorFactory(),
|
|
||||||
AbsoluteSendTimeRemoteBitrateEstimatorFactory()
|
|
||||||
};
|
|
||||||
switch (estimator) {
|
|
||||||
case kTransmissionOffset:
|
|
||||||
return BweTestConfig::EstimatorConfig("TOF", flow_id, &factories[0],
|
|
||||||
kAimdControl, kRembEstimator, false,
|
|
||||||
false);
|
|
||||||
case kAbsSendTime:
|
|
||||||
return BweTestConfig::EstimatorConfig("AST", flow_id, &factories[1],
|
|
||||||
kAimdControl, kRembEstimator, false,
|
|
||||||
false);
|
|
||||||
}
|
|
||||||
assert(false);
|
|
||||||
return BweTestConfig::EstimatorConfig();
|
|
||||||
}
|
|
||||||
|
|
||||||
struct DefaultBweTestConfig {
|
|
||||||
BweTestConfig bwe_test_config;
|
|
||||||
size_t number_of_senders;
|
|
||||||
};
|
|
||||||
|
|
||||||
DefaultBweTestConfig MakeBweTestConfig(uint32_t sender_count,
|
|
||||||
Estimator estimator) {
|
|
||||||
DefaultBweTestConfig result;
|
|
||||||
result.bwe_test_config.estimator_configs.push_back(
|
|
||||||
EstimatorConfigs(estimator, 0));
|
|
||||||
result.number_of_senders = sender_count;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
class DefaultBweTest : public BweTest,
|
class DefaultBweTest : public BweTest,
|
||||||
public ::testing::TestWithParam<DefaultBweTestConfig> {
|
public ::testing::TestWithParam<BandwidthEstimatorType> {
|
||||||
public:
|
public:
|
||||||
virtual ~DefaultBweTest() {}
|
virtual ~DefaultBweTest() {}
|
||||||
|
|
||||||
virtual void SetUp() {
|
|
||||||
const DefaultBweTestConfig& config = GetParam();
|
|
||||||
SetupTestFromConfig(config.bwe_test_config);
|
|
||||||
for (size_t i = 0; i < config.number_of_senders; ++i) {
|
|
||||||
sources_.push_back(new VideoSource(0, 30, 300, 0, 0));
|
|
||||||
packet_senders_.push_back(
|
|
||||||
new PacketSender(this, sources_.back(), kNullEstimator));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void TearDown() {
|
|
||||||
while (!packet_senders_.empty()) {
|
|
||||||
delete packet_senders_.front();
|
|
||||||
packet_senders_.pop_front();
|
|
||||||
}
|
|
||||||
while (!sources_.empty()) {
|
|
||||||
delete sources_.front();
|
|
||||||
sources_.pop_front();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
std::list<VideoSource*> sources_;
|
|
||||||
std::list<PacketSender*> packet_senders_;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
INSTANTIATE_TEST_CASE_P(VideoSendersTest, DefaultBweTest,
|
INSTANTIATE_TEST_CASE_P(VideoSendersTest,
|
||||||
::testing::Values(MakeBweTestConfig(1, kAbsSendTime),
|
DefaultBweTest,
|
||||||
MakeBweTestConfig(3, kAbsSendTime),
|
::testing::Values(kRembEstimator,
|
||||||
MakeBweTestConfig(1, kTransmissionOffset),
|
kFullSendSideEstimator));
|
||||||
MakeBweTestConfig(3, kTransmissionOffset)));
|
|
||||||
|
|
||||||
TEST_P(DefaultBweTest, UnlimitedSpeed) {
|
TEST_P(DefaultBweTest, UnlimitedSpeed) {
|
||||||
VerboseLogging(false);
|
VideoSource source(0, 30, 300, 0, 0);
|
||||||
|
PacketSender sender(this, &source, GetParam());
|
||||||
|
PacketReceiver receiver(this, 0, GetParam(), false, false);
|
||||||
RunFor(10 * 60 * 1000);
|
RunFor(10 * 60 * 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_P(DefaultBweTest, DISABLED_SteadyLoss) {
|
TEST_P(DefaultBweTest, DISABLED_SteadyLoss) {
|
||||||
|
VideoSource source(0, 30, 300, 0, 0);
|
||||||
|
PacketSender sender(this, &source, GetParam());
|
||||||
LossFilter loss(this);
|
LossFilter loss(this);
|
||||||
|
PacketReceiver receiver(this, 0, GetParam(), false, false);
|
||||||
loss.SetLoss(20.0);
|
loss.SetLoss(20.0);
|
||||||
RunFor(10 * 60 * 1000);
|
RunFor(10 * 60 * 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_P(DefaultBweTest, IncreasingLoss1) {
|
TEST_P(DefaultBweTest, IncreasingLoss1) {
|
||||||
|
VideoSource source(0, 30, 300, 0, 0);
|
||||||
|
PacketSender sender(this, &source, GetParam());
|
||||||
LossFilter loss(this);
|
LossFilter loss(this);
|
||||||
|
PacketReceiver receiver(this, 0, GetParam(), false, false);
|
||||||
for (int i = 0; i < 76; ++i) {
|
for (int i = 0; i < 76; ++i) {
|
||||||
loss.SetLoss(i);
|
loss.SetLoss(i);
|
||||||
RunFor(5000);
|
RunFor(5000);
|
||||||
@ -113,13 +60,19 @@ TEST_P(DefaultBweTest, IncreasingLoss1) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST_P(DefaultBweTest, SteadyDelay) {
|
TEST_P(DefaultBweTest, SteadyDelay) {
|
||||||
|
VideoSource source(0, 30, 300, 0, 0);
|
||||||
|
PacketSender sender(this, &source, GetParam());
|
||||||
DelayFilter delay(this);
|
DelayFilter delay(this);
|
||||||
|
PacketReceiver receiver(this, 0, GetParam(), false, false);
|
||||||
delay.SetDelay(1000);
|
delay.SetDelay(1000);
|
||||||
RunFor(10 * 60 * 1000);
|
RunFor(10 * 60 * 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_P(DefaultBweTest, DISABLED_IncreasingDelay1) {
|
TEST_P(DefaultBweTest, DISABLED_IncreasingDelay1) {
|
||||||
|
VideoSource source(0, 30, 300, 0, 0);
|
||||||
|
PacketSender sender(this, &source, GetParam());
|
||||||
DelayFilter delay(this);
|
DelayFilter delay(this);
|
||||||
|
PacketReceiver receiver(this, 0, GetParam(), false, false);
|
||||||
RunFor(10 * 60 * 1000);
|
RunFor(10 * 60 * 1000);
|
||||||
for (int i = 0; i < 30 * 2; ++i) {
|
for (int i = 0; i < 30 * 2; ++i) {
|
||||||
delay.SetDelay(i);
|
delay.SetDelay(i);
|
||||||
@ -129,8 +82,11 @@ TEST_P(DefaultBweTest, DISABLED_IncreasingDelay1) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST_P(DefaultBweTest, IncreasingDelay2) {
|
TEST_P(DefaultBweTest, IncreasingDelay2) {
|
||||||
|
VideoSource source(0, 30, 300, 0, 0);
|
||||||
|
PacketSender sender(this, &source, GetParam());
|
||||||
DelayFilter delay(this);
|
DelayFilter delay(this);
|
||||||
RateCounterFilter counter(this);
|
RateCounterFilter counter(this);
|
||||||
|
PacketReceiver receiver(this, 0, GetParam(), false, false);
|
||||||
RunFor(1 * 60 * 1000);
|
RunFor(1 * 60 * 1000);
|
||||||
for (int i = 1; i < 51; ++i) {
|
for (int i = 1; i < 51; ++i) {
|
||||||
delay.SetDelay(10.0f * i);
|
delay.SetDelay(10.0f * i);
|
||||||
@ -141,7 +97,10 @@ TEST_P(DefaultBweTest, IncreasingDelay2) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST_P(DefaultBweTest, JumpyDelay1) {
|
TEST_P(DefaultBweTest, JumpyDelay1) {
|
||||||
|
VideoSource source(0, 30, 300, 0, 0);
|
||||||
|
PacketSender sender(this, &source, GetParam());
|
||||||
DelayFilter delay(this);
|
DelayFilter delay(this);
|
||||||
|
PacketReceiver receiver(this, 0, GetParam(), false, false);
|
||||||
RunFor(10 * 60 * 1000);
|
RunFor(10 * 60 * 1000);
|
||||||
for (int i = 1; i < 200; ++i) {
|
for (int i = 1; i < 200; ++i) {
|
||||||
delay.SetDelay((10 * i) % 500);
|
delay.SetDelay((10 * i) % 500);
|
||||||
@ -154,14 +113,20 @@ TEST_P(DefaultBweTest, JumpyDelay1) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST_P(DefaultBweTest, SteadyJitter) {
|
TEST_P(DefaultBweTest, SteadyJitter) {
|
||||||
|
VideoSource source(0, 30, 300, 0, 0);
|
||||||
|
PacketSender sender(this, &source, GetParam());
|
||||||
JitterFilter jitter(this);
|
JitterFilter jitter(this);
|
||||||
RateCounterFilter counter(this);
|
RateCounterFilter counter(this);
|
||||||
|
PacketReceiver receiver(this, 0, GetParam(), false, false);
|
||||||
jitter.SetJitter(20);
|
jitter.SetJitter(20);
|
||||||
RunFor(2 * 60 * 1000);
|
RunFor(2 * 60 * 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_P(DefaultBweTest, IncreasingJitter1) {
|
TEST_P(DefaultBweTest, IncreasingJitter1) {
|
||||||
|
VideoSource source(0, 30, 300, 0, 0);
|
||||||
|
PacketSender sender(this, &source, GetParam());
|
||||||
JitterFilter jitter(this);
|
JitterFilter jitter(this);
|
||||||
|
PacketReceiver receiver(this, 0, GetParam(), false, false);
|
||||||
for (int i = 0; i < 2 * 60 * 2; ++i) {
|
for (int i = 0; i < 2 * 60 * 2; ++i) {
|
||||||
jitter.SetJitter(i);
|
jitter.SetJitter(i);
|
||||||
RunFor(10 * 1000);
|
RunFor(10 * 1000);
|
||||||
@ -170,7 +135,10 @@ TEST_P(DefaultBweTest, IncreasingJitter1) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST_P(DefaultBweTest, IncreasingJitter2) {
|
TEST_P(DefaultBweTest, IncreasingJitter2) {
|
||||||
|
VideoSource source(0, 30, 300, 0, 0);
|
||||||
|
PacketSender sender(this, &source, GetParam());
|
||||||
JitterFilter jitter(this);
|
JitterFilter jitter(this);
|
||||||
|
PacketReceiver receiver(this, 0, GetParam(), false, false);
|
||||||
RunFor(30 * 1000);
|
RunFor(30 * 1000);
|
||||||
for (int i = 1; i < 51; ++i) {
|
for (int i = 1; i < 51; ++i) {
|
||||||
jitter.SetJitter(10.0f * i);
|
jitter.SetJitter(10.0f * i);
|
||||||
@ -181,13 +149,19 @@ TEST_P(DefaultBweTest, IncreasingJitter2) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST_P(DefaultBweTest, SteadyReorder) {
|
TEST_P(DefaultBweTest, SteadyReorder) {
|
||||||
|
VideoSource source(0, 30, 300, 0, 0);
|
||||||
|
PacketSender sender(this, &source, GetParam());
|
||||||
ReorderFilter reorder(this);
|
ReorderFilter reorder(this);
|
||||||
|
PacketReceiver receiver(this, 0, GetParam(), false, false);
|
||||||
reorder.SetReorder(20.0);
|
reorder.SetReorder(20.0);
|
||||||
RunFor(10 * 60 * 1000);
|
RunFor(10 * 60 * 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_P(DefaultBweTest, IncreasingReorder1) {
|
TEST_P(DefaultBweTest, IncreasingReorder1) {
|
||||||
|
VideoSource source(0, 30, 300, 0, 0);
|
||||||
|
PacketSender sender(this, &source, GetParam());
|
||||||
ReorderFilter reorder(this);
|
ReorderFilter reorder(this);
|
||||||
|
PacketReceiver receiver(this, 0, GetParam(), false, false);
|
||||||
for (int i = 0; i < 76; ++i) {
|
for (int i = 0; i < 76; ++i) {
|
||||||
reorder.SetReorder(i);
|
reorder.SetReorder(i);
|
||||||
RunFor(5000);
|
RunFor(5000);
|
||||||
@ -195,13 +169,19 @@ TEST_P(DefaultBweTest, IncreasingReorder1) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST_P(DefaultBweTest, DISABLED_SteadyChoke) {
|
TEST_P(DefaultBweTest, DISABLED_SteadyChoke) {
|
||||||
|
VideoSource source(0, 30, 300, 0, 0);
|
||||||
|
PacketSender sender(this, &source, GetParam());
|
||||||
ChokeFilter choke(this);
|
ChokeFilter choke(this);
|
||||||
|
PacketReceiver receiver(this, 0, GetParam(), false, false);
|
||||||
choke.SetCapacity(140);
|
choke.SetCapacity(140);
|
||||||
RunFor(10 * 60 * 1000);
|
RunFor(10 * 60 * 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_P(DefaultBweTest, DISABLED_IncreasingChoke1) {
|
TEST_P(DefaultBweTest, DISABLED_IncreasingChoke1) {
|
||||||
|
VideoSource source(0, 30, 300, 0, 0);
|
||||||
|
PacketSender sender(this, &source, GetParam());
|
||||||
ChokeFilter choke(this);
|
ChokeFilter choke(this);
|
||||||
|
PacketReceiver receiver(this, 0, GetParam(), false, false);
|
||||||
for (int i = 1200; i >= 100; i -= 100) {
|
for (int i = 1200; i >= 100; i -= 100) {
|
||||||
choke.SetCapacity(i);
|
choke.SetCapacity(i);
|
||||||
RunFor(5000);
|
RunFor(5000);
|
||||||
@ -209,7 +189,10 @@ TEST_P(DefaultBweTest, DISABLED_IncreasingChoke1) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST_P(DefaultBweTest, DISABLED_IncreasingChoke2) {
|
TEST_P(DefaultBweTest, DISABLED_IncreasingChoke2) {
|
||||||
|
VideoSource source(0, 30, 300, 0, 0);
|
||||||
|
PacketSender sender(this, &source, GetParam());
|
||||||
ChokeFilter choke(this);
|
ChokeFilter choke(this);
|
||||||
|
PacketReceiver receiver(this, 0, GetParam(), false, false);
|
||||||
RunFor(60 * 1000);
|
RunFor(60 * 1000);
|
||||||
for (int i = 1200; i >= 100; i -= 20) {
|
for (int i = 1200; i >= 100; i -= 20) {
|
||||||
choke.SetCapacity(i);
|
choke.SetCapacity(i);
|
||||||
@ -218,9 +201,12 @@ TEST_P(DefaultBweTest, DISABLED_IncreasingChoke2) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST_P(DefaultBweTest, DISABLED_Multi1) {
|
TEST_P(DefaultBweTest, DISABLED_Multi1) {
|
||||||
|
VideoSource source(0, 30, 300, 0, 0);
|
||||||
|
PacketSender sender(this, &source, GetParam());
|
||||||
DelayFilter delay(this);
|
DelayFilter delay(this);
|
||||||
ChokeFilter choke(this);
|
ChokeFilter choke(this);
|
||||||
RateCounterFilter counter(this);
|
RateCounterFilter counter(this);
|
||||||
|
PacketReceiver receiver(this, 0, GetParam(), false, false);
|
||||||
choke.SetCapacity(1000);
|
choke.SetCapacity(1000);
|
||||||
RunFor(1 * 60 * 1000);
|
RunFor(1 * 60 * 1000);
|
||||||
for (int i = 1; i < 51; ++i) {
|
for (int i = 1; i < 51; ++i) {
|
||||||
@ -233,9 +219,12 @@ TEST_P(DefaultBweTest, DISABLED_Multi1) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST_P(DefaultBweTest, Multi2) {
|
TEST_P(DefaultBweTest, Multi2) {
|
||||||
|
VideoSource source(0, 30, 300, 0, 0);
|
||||||
|
PacketSender sender(this, &source, GetParam());
|
||||||
ChokeFilter choke(this);
|
ChokeFilter choke(this);
|
||||||
JitterFilter jitter(this);
|
JitterFilter jitter(this);
|
||||||
RateCounterFilter counter(this);
|
RateCounterFilter counter(this);
|
||||||
|
PacketReceiver receiver(this, 0, GetParam(), false, false);
|
||||||
choke.SetCapacity(2000);
|
choke.SetCapacity(2000);
|
||||||
jitter.SetJitter(120);
|
jitter.SetJitter(120);
|
||||||
RunFor(5 * 60 * 1000);
|
RunFor(5 * 60 * 1000);
|
||||||
@ -243,18 +232,13 @@ TEST_P(DefaultBweTest, Multi2) {
|
|||||||
|
|
||||||
// This test fixture is used to instantiate tests running with adaptive video
|
// This test fixture is used to instantiate tests running with adaptive video
|
||||||
// senders.
|
// senders.
|
||||||
class BweFeedbackTest : public BweTest,
|
class BweFeedbackTest
|
||||||
public ::testing::TestWithParam<BweTestConfig> {
|
: public BweTest,
|
||||||
|
public ::testing::TestWithParam<BandwidthEstimatorType> {
|
||||||
public:
|
public:
|
||||||
BweFeedbackTest() : BweTest() {}
|
BweFeedbackTest() : BweTest() {}
|
||||||
virtual ~BweFeedbackTest() {}
|
virtual ~BweFeedbackTest() {}
|
||||||
|
|
||||||
virtual void SetUp() {
|
|
||||||
BweTestConfig config;
|
|
||||||
config.estimator_configs.push_back(EstimatorConfigs(kAbsSendTime, 0));
|
|
||||||
SetupTestFromConfig(config);
|
|
||||||
}
|
|
||||||
|
|
||||||
void PrintResults(double max_throughput_kbps, Stats<double> throughput_kbps,
|
void PrintResults(double max_throughput_kbps, Stats<double> throughput_kbps,
|
||||||
Stats<double> delay_ms) {
|
Stats<double> delay_ms) {
|
||||||
double utilization = throughput_kbps.GetMean() / max_throughput_kbps;
|
double utilization = throughput_kbps.GetMean() / max_throughput_kbps;
|
||||||
@ -280,15 +264,24 @@ class BweFeedbackTest : public BweTest,
|
|||||||
false);
|
false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void SetUp() OVERRIDE { BweTest::SetUp(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DISALLOW_COPY_AND_ASSIGN(BweFeedbackTest);
|
DISALLOW_COPY_AND_ASSIGN(BweFeedbackTest);
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST_F(BweFeedbackTest, Choke1000kbps500kbps1000kbps) {
|
INSTANTIATE_TEST_CASE_P(VideoSendersTest,
|
||||||
|
BweFeedbackTest,
|
||||||
|
::testing::Values(kRembEstimator,
|
||||||
|
kFullSendSideEstimator));
|
||||||
|
|
||||||
|
TEST_P(BweFeedbackTest, Choke1000kbps500kbps1000kbps) {
|
||||||
AdaptiveVideoSource source(0, 30, 300, 0, 0);
|
AdaptiveVideoSource source(0, 30, 300, 0, 0);
|
||||||
PacketSender sender(this, &source, kRembEstimator);
|
PacketSender sender(this, &source, GetParam());
|
||||||
ChokeFilter filter(this);
|
ChokeFilter filter(this);
|
||||||
RateCounterFilter counter(this, "receiver_input");
|
RateCounterFilter counter(this, "receiver_input");
|
||||||
|
PacketReceiver receiver(this, 0, GetParam(), false, false);
|
||||||
const int kHighCapacityKbps = 1000;
|
const int kHighCapacityKbps = 1000;
|
||||||
const int kLowCapacityKbps = 500;
|
const int kLowCapacityKbps = 500;
|
||||||
filter.SetCapacity(kHighCapacityKbps);
|
filter.SetCapacity(kHighCapacityKbps);
|
||||||
@ -302,11 +295,12 @@ TEST_F(BweFeedbackTest, Choke1000kbps500kbps1000kbps) {
|
|||||||
counter.GetBitrateStats(), filter.GetDelayStats());
|
counter.GetBitrateStats(), filter.GetDelayStats());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(BweFeedbackTest, Choke200kbps30kbps200kbps) {
|
TEST_P(BweFeedbackTest, Choke200kbps30kbps200kbps) {
|
||||||
AdaptiveVideoSource source(0, 30, 300, 0, 0);
|
AdaptiveVideoSource source(0, 30, 300, 0, 0);
|
||||||
PacketSender sender(this, &source, kRembEstimator);
|
PacketSender sender(this, &source, GetParam());
|
||||||
ChokeFilter filter(this);
|
ChokeFilter filter(this);
|
||||||
RateCounterFilter counter(this, "receiver_input");
|
RateCounterFilter counter(this, "receiver_input");
|
||||||
|
PacketReceiver receiver(this, 0, GetParam(), false, false);
|
||||||
const int kHighCapacityKbps = 200;
|
const int kHighCapacityKbps = 200;
|
||||||
const int kLowCapacityKbps = 30;
|
const int kLowCapacityKbps = 30;
|
||||||
filter.SetCapacity(kHighCapacityKbps);
|
filter.SetCapacity(kHighCapacityKbps);
|
||||||
@ -321,12 +315,13 @@ TEST_F(BweFeedbackTest, Choke200kbps30kbps200kbps) {
|
|||||||
counter.GetBitrateStats(), filter.GetDelayStats());
|
counter.GetBitrateStats(), filter.GetDelayStats());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(BweFeedbackTest, Verizon4gDownlinkTest) {
|
TEST_P(BweFeedbackTest, Verizon4gDownlinkTest) {
|
||||||
AdaptiveVideoSource source(0, 30, 300, 0, 0);
|
AdaptiveVideoSource source(0, 30, 300, 0, 0);
|
||||||
PacketSender sender(this, &source, kRembEstimator);
|
PacketSender sender(this, &source, GetParam());
|
||||||
RateCounterFilter counter1(this, "sender_output");
|
RateCounterFilter counter1(this, "sender_output");
|
||||||
TraceBasedDeliveryFilter filter(this, "link_capacity");
|
TraceBasedDeliveryFilter filter(this, "link_capacity");
|
||||||
RateCounterFilter counter2(this, "receiver_input");
|
RateCounterFilter counter2(this, "receiver_input");
|
||||||
|
PacketReceiver receiver(this, 0, GetParam(), false, false);
|
||||||
ASSERT_TRUE(filter.Init(test::ResourcePath("verizon4g-downlink", "rx")));
|
ASSERT_TRUE(filter.Init(test::ResourcePath("verizon4g-downlink", "rx")));
|
||||||
RunFor(22 * 60 * 1000);
|
RunFor(22 * 60 * 1000);
|
||||||
PrintResults(filter.GetBitrateStats().GetMean(), counter2.GetBitrateStats(),
|
PrintResults(filter.GetBitrateStats().GetMean(), counter2.GetBitrateStats(),
|
||||||
@ -334,13 +329,14 @@ TEST_F(BweFeedbackTest, Verizon4gDownlinkTest) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// webrtc:3277
|
// webrtc:3277
|
||||||
TEST_F(BweFeedbackTest, DISABLED_GoogleWifiTrace3Mbps) {
|
TEST_P(BweFeedbackTest, DISABLED_GoogleWifiTrace3Mbps) {
|
||||||
AdaptiveVideoSource source(0, 30, 300, 0, 0);
|
AdaptiveVideoSource source(0, 30, 300, 0, 0);
|
||||||
PacketSender sender(this, &source, kRembEstimator);
|
PacketSender sender(this, &source, GetParam());
|
||||||
RateCounterFilter counter1(this, "sender_output");
|
RateCounterFilter counter1(this, "sender_output");
|
||||||
TraceBasedDeliveryFilter filter(this, "link_capacity");
|
TraceBasedDeliveryFilter filter(this, "link_capacity");
|
||||||
filter.SetMaxDelay(500);
|
filter.SetMaxDelay(500);
|
||||||
RateCounterFilter counter2(this, "receiver_input");
|
RateCounterFilter counter2(this, "receiver_input");
|
||||||
|
PacketReceiver receiver(this, 0, GetParam(), false, false);
|
||||||
ASSERT_TRUE(filter.Init(test::ResourcePath("google-wifi-3mbps", "rx")));
|
ASSERT_TRUE(filter.Init(test::ResourcePath("google-wifi-3mbps", "rx")));
|
||||||
RunFor(300 * 1000);
|
RunFor(300 * 1000);
|
||||||
PrintResults(filter.GetBitrateStats().GetMean(), counter2.GetBitrateStats(),
|
PrintResults(filter.GetBitrateStats().GetMean(), counter2.GetBitrateStats(),
|
||||||
|
@ -25,81 +25,41 @@ using std::vector;
|
|||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
namespace testing {
|
namespace testing {
|
||||||
namespace bwe {
|
namespace bwe {
|
||||||
|
class BweReceiver {
|
||||||
class PacketReceiver {
|
|
||||||
public:
|
public:
|
||||||
PacketReceiver(const string& test_name,
|
explicit BweReceiver(int flow_id) : flow_id_(flow_id) {}
|
||||||
const BweTestConfig::EstimatorConfig& config)
|
virtual ~BweReceiver() {}
|
||||||
: flow_id_(config.flow_id),
|
|
||||||
debug_name_(config.debug_name),
|
|
||||||
delay_log_prefix_(),
|
|
||||||
last_delay_plot_ms_(0),
|
|
||||||
plot_delay_(config.plot_delay),
|
|
||||||
baseline_(BaseLineFileInterface::Create(test_name + "_" + debug_name_,
|
|
||||||
config.update_baseline)) {
|
|
||||||
// Setup the prefix strings used when logging.
|
|
||||||
std::stringstream ss;
|
|
||||||
ss << "Delay_" << config.flow_id << "#2";
|
|
||||||
delay_log_prefix_ = ss.str();
|
|
||||||
}
|
|
||||||
virtual ~PacketReceiver() {}
|
|
||||||
|
|
||||||
virtual void ReceivePacket(const Packet& packet) {}
|
|
||||||
|
|
||||||
|
virtual void ReceivePacket(int64_t arrival_time_ms,
|
||||||
|
size_t payload_size,
|
||||||
|
const RTPHeader& header) {}
|
||||||
virtual FeedbackPacket* GetFeedback() { return NULL; }
|
virtual FeedbackPacket* GetFeedback() { return NULL; }
|
||||||
|
|
||||||
void LogStats() {
|
|
||||||
BWE_TEST_LOGGING_CONTEXT(debug_name_);
|
|
||||||
BWE_TEST_LOGGING_CONTEXT("Mean");
|
|
||||||
stats_.Log("kbps");
|
|
||||||
}
|
|
||||||
|
|
||||||
void VerifyOrWriteBaseline() { EXPECT_TRUE(baseline_->VerifyOrWrite()); }
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
static const int kDelayPlotIntervalMs = 100;
|
int flow_id_;
|
||||||
|
|
||||||
void LogDelay(int64_t arrival_time_ms, int64_t send_time_ms) {
|
|
||||||
if (plot_delay_) {
|
|
||||||
if (arrival_time_ms - last_delay_plot_ms_ > kDelayPlotIntervalMs) {
|
|
||||||
BWE_TEST_LOGGING_PLOT(delay_log_prefix_, arrival_time_ms,
|
|
||||||
arrival_time_ms - send_time_ms);
|
|
||||||
last_delay_plot_ms_ = arrival_time_ms;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const int flow_id_;
|
|
||||||
const string debug_name_;
|
|
||||||
string delay_log_prefix_;
|
|
||||||
int64_t last_delay_plot_ms_;
|
|
||||||
bool plot_delay_;
|
|
||||||
scoped_ptr<BaseLineFileInterface> baseline_;
|
|
||||||
Stats<double> stats_;
|
|
||||||
|
|
||||||
private:
|
|
||||||
DISALLOW_IMPLICIT_CONSTRUCTORS(PacketReceiver);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class SendSideBweReceiver : public PacketReceiver {
|
int64_t GetAbsSendTimeInMs(uint32_t abs_send_time) {
|
||||||
public:
|
const int kInterArrivalShift = 26;
|
||||||
SendSideBweReceiver(const string& test_name,
|
const int kAbsSendTimeInterArrivalUpshift = 8;
|
||||||
const BweTestConfig::EstimatorConfig& config)
|
const double kTimestampToMs =
|
||||||
: PacketReceiver(test_name, config) {}
|
1000.0 / static_cast<double>(1 << kInterArrivalShift);
|
||||||
|
uint32_t timestamp = abs_send_time << kAbsSendTimeInterArrivalUpshift;
|
||||||
|
return static_cast<int64_t>(timestamp) * kTimestampToMs;
|
||||||
|
}
|
||||||
|
|
||||||
virtual void EatPacket(const Packet& packet) {
|
class SendSideBweReceiver : public BweReceiver {
|
||||||
const MediaPacket& media_packet = static_cast<const MediaPacket&>(packet);
|
public:
|
||||||
// We're treating the send time (from previous filter) as the arrival
|
explicit SendSideBweReceiver(int flow_id) : BweReceiver(flow_id) {}
|
||||||
// time once packet reaches the estimator.
|
virtual void ReceivePacket(int64_t arrival_time_ms,
|
||||||
int64_t arrival_time_ms = (media_packet.send_time_us() + 500) / 1000;
|
size_t payload_size,
|
||||||
BWE_TEST_LOGGING_TIME(arrival_time_ms);
|
const RTPHeader& header) OVERRIDE {
|
||||||
LogDelay(arrival_time_ms, (media_packet.creation_time_us() + 500) / 1000);
|
|
||||||
packet_feedback_vector_.push_back(PacketInfo(
|
packet_feedback_vector_.push_back(PacketInfo(
|
||||||
arrival_time_ms, media_packet.GetAbsSendTimeInMs(),
|
arrival_time_ms, GetAbsSendTimeInMs(header.extension.absoluteSendTime),
|
||||||
media_packet.header().sequenceNumber, media_packet.payload_size()));
|
header.sequenceNumber, payload_size));
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual FeedbackPacket* GetFeedback() {
|
virtual FeedbackPacket* GetFeedback() OVERRIDE {
|
||||||
FeedbackPacket* fb =
|
FeedbackPacket* fb =
|
||||||
new SendSideBweFeedback(flow_id_, 0, packet_feedback_vector_);
|
new SendSideBweFeedback(flow_id_, 0, packet_feedback_vector_);
|
||||||
packet_feedback_vector_.clear();
|
packet_feedback_vector_.clear();
|
||||||
@ -110,44 +70,33 @@ class SendSideBweReceiver : public PacketReceiver {
|
|||||||
std::vector<PacketInfo> packet_feedback_vector_;
|
std::vector<PacketInfo> packet_feedback_vector_;
|
||||||
};
|
};
|
||||||
|
|
||||||
class RembReceiver : public PacketReceiver, public RemoteBitrateObserver {
|
class RembReceiver : public BweReceiver, public RemoteBitrateObserver {
|
||||||
public:
|
public:
|
||||||
static const uint32_t kRemoteBitrateEstimatorMinBitrateBps = 30000;
|
static const uint32_t kRemoteBitrateEstimatorMinBitrateBps = 30000;
|
||||||
|
|
||||||
RembReceiver(const string& test_name,
|
RembReceiver(int flow_id, bool plot)
|
||||||
const BweTestConfig::EstimatorConfig& config)
|
: BweReceiver(flow_id),
|
||||||
: PacketReceiver(test_name, config),
|
|
||||||
estimate_log_prefix_(),
|
estimate_log_prefix_(),
|
||||||
plot_estimate_(config.plot_estimate),
|
plot_estimate_(plot),
|
||||||
clock_(0),
|
clock_(0),
|
||||||
recv_stats_(ReceiveStatistics::Create(&clock_)),
|
recv_stats_(ReceiveStatistics::Create(&clock_)),
|
||||||
latest_estimate_bps_(-1),
|
latest_estimate_bps_(-1),
|
||||||
estimator_(config.estimator_factory->Create(
|
estimator_(AbsoluteSendTimeRemoteBitrateEstimatorFactory().Create(
|
||||||
this,
|
this,
|
||||||
&clock_,
|
&clock_,
|
||||||
config.control_type,
|
kAimdControl,
|
||||||
kRemoteBitrateEstimatorMinBitrateBps)) {
|
kRemoteBitrateEstimatorMinBitrateBps)) {
|
||||||
assert(estimator_.get());
|
|
||||||
assert(baseline_.get());
|
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
ss.str("");
|
ss << "Estimate_" << flow_id_ << "#1";
|
||||||
ss << "Estimate_" << config.flow_id << "#1";
|
|
||||||
estimate_log_prefix_ = ss.str();
|
estimate_log_prefix_ = ss.str();
|
||||||
// Default RTT in RemoteRateControl is 200 ms ; 50 ms is more realistic.
|
// Default RTT in RemoteRateControl is 200 ms ; 50 ms is more realistic.
|
||||||
estimator_->OnRttUpdate(50);
|
estimator_->OnRttUpdate(50);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void ReceivePacket(const Packet& packet) {
|
virtual void ReceivePacket(int64_t arrival_time_ms,
|
||||||
BWE_TEST_LOGGING_CONTEXT(debug_name_);
|
size_t payload_size,
|
||||||
assert(packet.GetPacketType() == Packet::kMediaPacket);
|
const RTPHeader& header) {
|
||||||
const MediaPacket& media_packet = static_cast<const MediaPacket&>(packet);
|
recv_stats_->IncomingPacket(header, payload_size, false);
|
||||||
// We're treating the send time (from previous filter) as the arrival
|
|
||||||
// time once packet reaches the estimator.
|
|
||||||
int64_t arrival_time_ms = (media_packet.send_time_us() + 500) / 1000;
|
|
||||||
BWE_TEST_LOGGING_TIME(arrival_time_ms);
|
|
||||||
LogDelay(arrival_time_ms, (media_packet.creation_time_us() + 500) / 1000);
|
|
||||||
recv_stats_->IncomingPacket(media_packet.header(),
|
|
||||||
media_packet.payload_size(), false);
|
|
||||||
|
|
||||||
latest_estimate_bps_ = -1;
|
latest_estimate_bps_ = -1;
|
||||||
|
|
||||||
@ -157,15 +106,14 @@ class RembReceiver : public PacketReceiver, public RemoteBitrateObserver {
|
|||||||
estimator_->Process();
|
estimator_->Process();
|
||||||
step_ms = std::max<int64_t>(estimator_->TimeUntilNextProcess(), 0);
|
step_ms = std::max<int64_t>(estimator_->TimeUntilNextProcess(), 0);
|
||||||
}
|
}
|
||||||
estimator_->IncomingPacket(arrival_time_ms, media_packet.payload_size(),
|
estimator_->IncomingPacket(arrival_time_ms, payload_size, header);
|
||||||
media_packet.header());
|
|
||||||
clock_.AdvanceTimeMilliseconds(arrival_time_ms -
|
clock_.AdvanceTimeMilliseconds(arrival_time_ms -
|
||||||
clock_.TimeInMilliseconds());
|
clock_.TimeInMilliseconds());
|
||||||
ASSERT_TRUE(arrival_time_ms == clock_.TimeInMilliseconds());
|
ASSERT_TRUE(arrival_time_ms == clock_.TimeInMilliseconds());
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual FeedbackPacket* GetFeedback() {
|
virtual FeedbackPacket* GetFeedback() {
|
||||||
BWE_TEST_LOGGING_CONTEXT(debug_name_);
|
BWE_TEST_LOGGING_CONTEXT("Remb");
|
||||||
uint32_t estimated_bps = 0;
|
uint32_t estimated_bps = 0;
|
||||||
RembFeedback* feedback = NULL;
|
RembFeedback* feedback = NULL;
|
||||||
if (LatestEstimate(&estimated_bps)) {
|
if (LatestEstimate(&estimated_bps)) {
|
||||||
@ -176,10 +124,9 @@ class RembReceiver : public PacketReceiver, public RemoteBitrateObserver {
|
|||||||
}
|
}
|
||||||
feedback = new RembFeedback(flow_id_, clock_.TimeInMilliseconds(),
|
feedback = new RembFeedback(flow_id_, clock_.TimeInMilliseconds(),
|
||||||
estimated_bps, report_block);
|
estimated_bps, report_block);
|
||||||
baseline_->Estimate(clock_.TimeInMilliseconds(), estimated_bps);
|
|
||||||
|
|
||||||
double estimated_kbps = static_cast<double>(estimated_bps) / 1000.0;
|
double estimated_kbps = static_cast<double>(estimated_bps) / 1000.0;
|
||||||
stats_.Push(estimated_kbps);
|
RTC_UNUSED(estimated_kbps);
|
||||||
if (plot_estimate_) {
|
if (plot_estimate_) {
|
||||||
BWE_TEST_LOGGING_PLOT(estimate_log_prefix_, clock_.TimeInMilliseconds(),
|
BWE_TEST_LOGGING_PLOT(estimate_log_prefix_, clock_.TimeInMilliseconds(),
|
||||||
estimated_kbps);
|
estimated_kbps);
|
||||||
@ -228,22 +175,77 @@ class RembReceiver : public PacketReceiver, public RemoteBitrateObserver {
|
|||||||
DISALLOW_IMPLICIT_CONSTRUCTORS(RembReceiver);
|
DISALLOW_IMPLICIT_CONSTRUCTORS(RembReceiver);
|
||||||
};
|
};
|
||||||
|
|
||||||
PacketReceiver* CreatePacketReceiver(
|
BweReceiver* CreateBweReceiver(BandwidthEstimatorType type,
|
||||||
BandwidthEstimatorType type,
|
int flow_id,
|
||||||
const string& test_name,
|
bool plot) {
|
||||||
const BweTestConfig::EstimatorConfig& config) {
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case kRembEstimator:
|
case kRembEstimator:
|
||||||
return new RembReceiver(test_name, config);
|
return new RembReceiver(flow_id, plot);
|
||||||
case kFullSendSideEstimator:
|
case kFullSendSideEstimator:
|
||||||
return new SendSideBweReceiver(test_name, config);
|
return new SendSideBweReceiver(flow_id);
|
||||||
case kNullEstimator:
|
case kNullEstimator:
|
||||||
return new PacketReceiver(test_name, config);
|
return new BweReceiver(flow_id);
|
||||||
}
|
}
|
||||||
assert(false);
|
assert(false);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PacketReceiver::PacketReceiver(PacketProcessorListener* listener,
|
||||||
|
int flow_id,
|
||||||
|
BandwidthEstimatorType bwe_type,
|
||||||
|
bool plot_delay,
|
||||||
|
bool plot_bwe)
|
||||||
|
: PacketProcessor(listener, flow_id, kReceiver),
|
||||||
|
delay_log_prefix_(),
|
||||||
|
last_delay_plot_ms_(0),
|
||||||
|
plot_delay_(plot_delay),
|
||||||
|
bwe_receiver_(CreateBweReceiver(bwe_type, flow_id, plot_bwe)) {
|
||||||
|
// Setup the prefix strings used when logging.
|
||||||
|
std::stringstream ss;
|
||||||
|
ss << "Delay_" << flow_id << "#2";
|
||||||
|
delay_log_prefix_ = ss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
PacketReceiver::~PacketReceiver() {
|
||||||
|
}
|
||||||
|
|
||||||
|
void PacketReceiver::RunFor(int64_t time_ms, Packets* in_out) {
|
||||||
|
for (const auto* packet : *in_out) {
|
||||||
|
// PacketReceivers are only associated with a single stream, and therefore
|
||||||
|
// should only process a single flow id.
|
||||||
|
// TODO(holmer): Break this out into a Demuxer which implements both
|
||||||
|
// PacketProcessorListener and PacketProcessor.
|
||||||
|
if (packet->flow_id() != *flow_ids().begin())
|
||||||
|
continue;
|
||||||
|
BWE_TEST_LOGGING_CONTEXT("Receiver");
|
||||||
|
assert(packet->GetPacketType() == Packet::kMedia);
|
||||||
|
const MediaPacket& media_packet = static_cast<const MediaPacket&>(*packet);
|
||||||
|
// We're treating the send time (from previous filter) as the arrival
|
||||||
|
// time once packet reaches the estimator.
|
||||||
|
int64_t arrival_time_ms = (media_packet.send_time_us() + 500) / 1000;
|
||||||
|
BWE_TEST_LOGGING_TIME(arrival_time_ms);
|
||||||
|
PlotDelay(arrival_time_ms, (media_packet.creation_time_us() + 500) / 1000);
|
||||||
|
|
||||||
|
bwe_receiver_->ReceivePacket(arrival_time_ms, media_packet.payload_size(),
|
||||||
|
media_packet.header());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FeedbackPacket* PacketReceiver::GetFeedback() {
|
||||||
|
return bwe_receiver_->GetFeedback();
|
||||||
|
}
|
||||||
|
|
||||||
|
void PacketReceiver::PlotDelay(int64_t arrival_time_ms, int64_t send_time_ms) {
|
||||||
|
static const int kDelayPlotIntervalMs = 100;
|
||||||
|
if (!plot_delay_)
|
||||||
|
return;
|
||||||
|
if (arrival_time_ms - last_delay_plot_ms_ > kDelayPlotIntervalMs) {
|
||||||
|
BWE_TEST_LOGGING_PLOT(delay_log_prefix_, arrival_time_ms,
|
||||||
|
arrival_time_ms - send_time_ms);
|
||||||
|
last_delay_plot_ms_ = arrival_time_ms;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class PacketProcessorRunner {
|
class PacketProcessorRunner {
|
||||||
public:
|
public:
|
||||||
explicit PacketProcessorRunner(PacketProcessor* processor)
|
explicit PacketProcessorRunner(PacketProcessor* processor)
|
||||||
@ -309,51 +311,35 @@ class PacketProcessorRunner {
|
|||||||
};
|
};
|
||||||
|
|
||||||
BweTest::BweTest()
|
BweTest::BweTest()
|
||||||
: run_time_ms_(0),
|
: run_time_ms_(0), time_now_ms_(-1), simulation_interval_ms_(-1) {
|
||||||
time_now_ms_(-1),
|
|
||||||
simulation_interval_ms_(-1),
|
|
||||||
estimators_(),
|
|
||||||
processors_() {
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BweTest::~BweTest() {
|
BweTest::~BweTest() {
|
||||||
BWE_TEST_LOGGING_GLOBAL_ENABLE(true);
|
|
||||||
for (const auto& estimator : estimators_) {
|
|
||||||
estimator.second->VerifyOrWriteBaseline();
|
|
||||||
estimator.second->LogStats();
|
|
||||||
}
|
|
||||||
BWE_TEST_LOGGING_GLOBAL_CONTEXT("");
|
|
||||||
|
|
||||||
for (const auto& estimator : estimators_) {
|
|
||||||
delete estimator.second;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void BweTest::SetupTestFromConfig(const BweTestConfig& config) {
|
void BweTest::SetUp() {
|
||||||
const ::testing::TestInfo* const test_info =
|
const ::testing::TestInfo* const test_info =
|
||||||
::testing::UnitTest::GetInstance()->current_test_info();
|
::testing::UnitTest::GetInstance()->current_test_info();
|
||||||
string test_name =
|
string test_name =
|
||||||
string(test_info->test_case_name()) + "_" + string(test_info->name());
|
string(test_info->test_case_name()) + "_" + string(test_info->name());
|
||||||
BWE_TEST_LOGGING_GLOBAL_CONTEXT(test_name);
|
BWE_TEST_LOGGING_GLOBAL_CONTEXT(test_name);
|
||||||
for (const auto& estimator_config : config.estimator_configs) {
|
|
||||||
estimators_.insert(
|
|
||||||
std::make_pair(estimator_config.flow_id,
|
|
||||||
CreatePacketReceiver(estimator_config.bwe_type,
|
|
||||||
test_name, estimator_config)));
|
|
||||||
}
|
|
||||||
BWE_TEST_LOGGING_GLOBAL_ENABLE(false);
|
BWE_TEST_LOGGING_GLOBAL_ENABLE(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BweTest::AddPacketProcessor(PacketProcessor* processor, bool is_sender) {
|
void BweTest::AddPacketProcessor(PacketProcessor* processor,
|
||||||
|
ProcessorType processor_type) {
|
||||||
assert(processor);
|
assert(processor);
|
||||||
if (is_sender) {
|
switch (processor_type) {
|
||||||
senders_.push_back(static_cast<PacketSender*>(processor));
|
case kSender:
|
||||||
|
senders_.push_back(static_cast<PacketSender*>(processor));
|
||||||
|
break;
|
||||||
|
case kReceiver:
|
||||||
|
receivers_.push_back(static_cast<PacketReceiver*>(processor));
|
||||||
|
break;
|
||||||
|
case kRegular:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
processors_.push_back(PacketProcessorRunner(processor));
|
processors_.push_back(PacketProcessorRunner(processor));
|
||||||
for (const int& flow_id : processor->flow_ids()) {
|
|
||||||
RTC_UNUSED(flow_id);
|
|
||||||
assert(estimators_.count(flow_id) == 1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void BweTest::RemovePacketProcessor(PacketProcessor* processor) {
|
void BweTest::RemovePacketProcessor(PacketProcessor* processor) {
|
||||||
@ -371,8 +357,8 @@ void BweTest::VerboseLogging(bool enable) {
|
|||||||
BWE_TEST_LOGGING_GLOBAL_ENABLE(enable);
|
BWE_TEST_LOGGING_GLOBAL_ENABLE(enable);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BweTest::GiveFeedbackToAffectedSenders(PacketReceiver* estimator) {
|
void BweTest::GiveFeedbackToAffectedSenders(PacketReceiver* receiver) {
|
||||||
FeedbackPacket* feedback = estimator->GetFeedback();
|
FeedbackPacket* feedback = receiver->GetFeedback();
|
||||||
if (feedback) {
|
if (feedback) {
|
||||||
for (PacketSender* sender : senders_) {
|
for (PacketSender* sender : senders_) {
|
||||||
if (sender->flow_ids().find(feedback->flow_id()) !=
|
if (sender->flow_ids().find(feedback->flow_id()) !=
|
||||||
@ -418,15 +404,11 @@ void BweTest::RunFor(int64_t time_ms) {
|
|||||||
ASSERT_TRUE(IsTimeSorted(packets));
|
ASSERT_TRUE(IsTimeSorted(packets));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const Packet* packet : packets) {
|
for (const auto* packet : packets)
|
||||||
EstimatorMap::iterator est_it = estimators_.find(packet->flow_id());
|
|
||||||
ASSERT_TRUE(est_it != estimators_.end());
|
|
||||||
est_it->second->ReceivePacket(*packet);
|
|
||||||
delete packet;
|
delete packet;
|
||||||
}
|
|
||||||
|
|
||||||
for (const auto& estimator : estimators_) {
|
for (const auto& receiver : receivers_) {
|
||||||
GiveFeedbackToAffectedSenders(estimator.second);
|
GiveFeedbackToAffectedSenders(receiver);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,108 +18,68 @@
|
|||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
|
|
||||||
struct RemoteBitrateEstimatorFactory;
|
|
||||||
|
|
||||||
namespace testing {
|
namespace testing {
|
||||||
namespace bwe {
|
namespace bwe {
|
||||||
|
|
||||||
struct BweTestConfig {
|
class BweReceiver;
|
||||||
struct EstimatorConfig {
|
|
||||||
EstimatorConfig()
|
|
||||||
: debug_name(),
|
|
||||||
flow_id(0),
|
|
||||||
estimator_factory(NULL),
|
|
||||||
control_type(kAimdControl),
|
|
||||||
bwe_type(kRembEstimator),
|
|
||||||
update_baseline(false),
|
|
||||||
plot_delay(true),
|
|
||||||
plot_estimate(true) {}
|
|
||||||
EstimatorConfig(std::string debug_name,
|
|
||||||
int flow_id,
|
|
||||||
const RemoteBitrateEstimatorFactory* estimator_factory,
|
|
||||||
BandwidthEstimatorType estimator_type,
|
|
||||||
bool plot_delay,
|
|
||||||
bool plot_estimate)
|
|
||||||
: debug_name(debug_name),
|
|
||||||
flow_id(flow_id),
|
|
||||||
estimator_factory(estimator_factory),
|
|
||||||
control_type(kAimdControl),
|
|
||||||
bwe_type(kRembEstimator),
|
|
||||||
update_baseline(false),
|
|
||||||
plot_delay(plot_delay),
|
|
||||||
plot_estimate(plot_estimate) {}
|
|
||||||
EstimatorConfig(std::string debug_name,
|
|
||||||
int flow_id,
|
|
||||||
const RemoteBitrateEstimatorFactory* estimator_factory,
|
|
||||||
RateControlType control_type,
|
|
||||||
BandwidthEstimatorType estimator_type,
|
|
||||||
bool plot_delay,
|
|
||||||
bool plot_estimate)
|
|
||||||
: debug_name(debug_name),
|
|
||||||
flow_id(flow_id),
|
|
||||||
estimator_factory(estimator_factory),
|
|
||||||
control_type(control_type),
|
|
||||||
bwe_type(estimator_type),
|
|
||||||
update_baseline(false),
|
|
||||||
plot_delay(plot_delay),
|
|
||||||
plot_estimate(plot_estimate) {}
|
|
||||||
EstimatorConfig(std::string debug_name,
|
|
||||||
int flow_id,
|
|
||||||
const RemoteBitrateEstimatorFactory* estimator_factory,
|
|
||||||
RateControlType control_type,
|
|
||||||
BandwidthEstimatorType estimator_type,
|
|
||||||
bool update_baseline)
|
|
||||||
: debug_name(debug_name),
|
|
||||||
flow_id(flow_id),
|
|
||||||
estimator_factory(estimator_factory),
|
|
||||||
control_type(control_type),
|
|
||||||
bwe_type(kRembEstimator),
|
|
||||||
update_baseline(update_baseline),
|
|
||||||
plot_delay(false),
|
|
||||||
plot_estimate(false) {}
|
|
||||||
std::string debug_name;
|
|
||||||
int flow_id;
|
|
||||||
const RemoteBitrateEstimatorFactory* estimator_factory;
|
|
||||||
RateControlType control_type;
|
|
||||||
BandwidthEstimatorType bwe_type;
|
|
||||||
bool update_baseline;
|
|
||||||
bool plot_delay;
|
|
||||||
bool plot_estimate;
|
|
||||||
};
|
|
||||||
|
|
||||||
std::vector<EstimatorConfig> estimator_configs;
|
|
||||||
};
|
|
||||||
|
|
||||||
class PacketReceiver;
|
class PacketReceiver;
|
||||||
class PacketProcessorRunner;
|
class PacketProcessorRunner;
|
||||||
|
|
||||||
|
class PacketReceiver : public PacketProcessor {
|
||||||
|
public:
|
||||||
|
PacketReceiver(PacketProcessorListener* listener,
|
||||||
|
int flow_id,
|
||||||
|
BandwidthEstimatorType bwe_type,
|
||||||
|
bool plot_delay,
|
||||||
|
bool plot_bwe);
|
||||||
|
~PacketReceiver();
|
||||||
|
|
||||||
|
// Implements PacketProcessor.
|
||||||
|
virtual void RunFor(int64_t time_ms, Packets* in_out) OVERRIDE;
|
||||||
|
|
||||||
|
FeedbackPacket* GetFeedback();
|
||||||
|
|
||||||
|
void LogStats();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void PlotDelay(int64_t arrival_time_ms, int64_t send_time_ms);
|
||||||
|
|
||||||
|
std::string delay_log_prefix_;
|
||||||
|
int64_t last_delay_plot_ms_;
|
||||||
|
bool plot_delay_;
|
||||||
|
scoped_ptr<BweReceiver> bwe_receiver_;
|
||||||
|
|
||||||
|
private:
|
||||||
|
DISALLOW_IMPLICIT_CONSTRUCTORS(PacketReceiver);
|
||||||
|
};
|
||||||
|
|
||||||
class BweTest : public PacketProcessorListener {
|
class BweTest : public PacketProcessorListener {
|
||||||
public:
|
public:
|
||||||
BweTest();
|
BweTest();
|
||||||
virtual ~BweTest();
|
virtual ~BweTest();
|
||||||
|
|
||||||
virtual void AddPacketProcessor(PacketProcessor* processor, bool is_sender);
|
virtual void AddPacketProcessor(PacketProcessor* processor,
|
||||||
|
ProcessorType type);
|
||||||
virtual void RemovePacketProcessor(PacketProcessor* processor);
|
virtual void RemovePacketProcessor(PacketProcessor* processor);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void SetupTestFromConfig(const BweTestConfig& config);
|
virtual void SetUp();
|
||||||
|
|
||||||
void VerboseLogging(bool enable);
|
void VerboseLogging(bool enable);
|
||||||
void RunFor(int64_t time_ms);
|
void RunFor(int64_t time_ms);
|
||||||
std::string GetTestName() const;
|
std::string GetTestName() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
typedef std::map<int, PacketReceiver*> EstimatorMap;
|
|
||||||
|
|
||||||
void FindPacketsToProcess(const FlowIds& flow_ids, Packets* in,
|
void FindPacketsToProcess(const FlowIds& flow_ids, Packets* in,
|
||||||
Packets* out);
|
Packets* out);
|
||||||
void GiveFeedbackToAffectedSenders(PacketReceiver* estimator);
|
void GiveFeedbackToAffectedSenders(PacketReceiver* receiver);
|
||||||
|
|
||||||
int64_t run_time_ms_;
|
int64_t run_time_ms_;
|
||||||
int64_t time_now_ms_;
|
int64_t time_now_ms_;
|
||||||
int64_t simulation_interval_ms_;
|
int64_t simulation_interval_ms_;
|
||||||
EstimatorMap estimators_;
|
|
||||||
Packets previous_packets_;
|
Packets previous_packets_;
|
||||||
std::vector<PacketSender*> senders_;
|
std::vector<PacketSender*> senders_;
|
||||||
|
std::vector<PacketReceiver*> receivers_;
|
||||||
std::vector<PacketProcessorRunner> processors_;
|
std::vector<PacketProcessorRunner> processors_;
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(BweTest);
|
DISALLOW_COPY_AND_ASSIGN(BweTest);
|
||||||
|
@ -163,16 +163,6 @@ MediaPacket::MediaPacket(int64_t send_time_us, uint32_t sequence_number)
|
|||||||
header_.sequenceNumber = sequence_number;
|
header_.sequenceNumber = sequence_number;
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t MediaPacket::GetAbsSendTimeInMs() const {
|
|
||||||
const int kInterArrivalShift = 26;
|
|
||||||
const int kAbsSendTimeInterArrivalUpshift = 8;
|
|
||||||
const double kTimestampToMs =
|
|
||||||
1000.0 / static_cast<double>(1 << kInterArrivalShift);
|
|
||||||
uint32_t timestamp = header_.extension.absoluteSendTime
|
|
||||||
<< kAbsSendTimeInterArrivalUpshift;
|
|
||||||
return static_cast<int64_t>(timestamp) * kTimestampToMs;
|
|
||||||
}
|
|
||||||
|
|
||||||
void MediaPacket::SetAbsSendTimeMs(int64_t abs_send_time_ms) {
|
void MediaPacket::SetAbsSendTimeMs(int64_t abs_send_time_ms) {
|
||||||
header_.extension.hasAbsoluteSendTime = true;
|
header_.extension.hasAbsoluteSendTime = true;
|
||||||
header_.extension.absoluteSendTime = ((static_cast<int64_t>(abs_send_time_ms *
|
header_.extension.absoluteSendTime = ((static_cast<int64_t>(abs_send_time_ms *
|
||||||
@ -208,30 +198,30 @@ bool IsTimeSorted(const Packets& packets) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
PacketProcessor::PacketProcessor(PacketProcessorListener* listener,
|
PacketProcessor::PacketProcessor(PacketProcessorListener* listener,
|
||||||
bool is_sender)
|
ProcessorType type)
|
||||||
: listener_(listener) {
|
: listener_(listener) {
|
||||||
flow_ids_.insert(0);
|
flow_ids_.insert(0);
|
||||||
if (listener_) {
|
if (listener_) {
|
||||||
listener_->AddPacketProcessor(this, is_sender);
|
listener_->AddPacketProcessor(this, type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PacketProcessor::PacketProcessor(PacketProcessorListener* listener,
|
PacketProcessor::PacketProcessor(PacketProcessorListener* listener,
|
||||||
int flow_id,
|
int flow_id,
|
||||||
bool is_sender)
|
ProcessorType type)
|
||||||
: listener_(listener) {
|
: listener_(listener) {
|
||||||
flow_ids_.insert(flow_id);
|
flow_ids_.insert(flow_id);
|
||||||
if (listener_) {
|
if (listener_) {
|
||||||
listener_->AddPacketProcessor(this, is_sender);
|
listener_->AddPacketProcessor(this, type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PacketProcessor::PacketProcessor(PacketProcessorListener* listener,
|
PacketProcessor::PacketProcessor(PacketProcessorListener* listener,
|
||||||
const FlowIds& flow_ids,
|
const FlowIds& flow_ids,
|
||||||
bool is_sender)
|
ProcessorType type)
|
||||||
: listener_(listener), flow_ids_(flow_ids) {
|
: listener_(listener), flow_ids_(flow_ids) {
|
||||||
if (listener_) {
|
if (listener_) {
|
||||||
listener_->AddPacketProcessor(this, is_sender);
|
listener_->AddPacketProcessor(this, type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -242,24 +232,26 @@ PacketProcessor::~PacketProcessor() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
RateCounterFilter::RateCounterFilter(PacketProcessorListener* listener)
|
RateCounterFilter::RateCounterFilter(PacketProcessorListener* listener)
|
||||||
: PacketProcessor(listener, false),
|
: PacketProcessor(listener, kRegular),
|
||||||
rate_counter_(new RateCounter()),
|
rate_counter_(new RateCounter()),
|
||||||
packets_per_second_stats_(),
|
packets_per_second_stats_(),
|
||||||
kbps_stats_(),
|
kbps_stats_(),
|
||||||
name_("") {}
|
name_("") {
|
||||||
|
}
|
||||||
|
|
||||||
RateCounterFilter::RateCounterFilter(PacketProcessorListener* listener,
|
RateCounterFilter::RateCounterFilter(PacketProcessorListener* listener,
|
||||||
const std::string& name)
|
const std::string& name)
|
||||||
: PacketProcessor(listener, false),
|
: PacketProcessor(listener, kRegular),
|
||||||
rate_counter_(new RateCounter()),
|
rate_counter_(new RateCounter()),
|
||||||
packets_per_second_stats_(),
|
packets_per_second_stats_(),
|
||||||
kbps_stats_(),
|
kbps_stats_(),
|
||||||
name_(name) {}
|
name_(name) {
|
||||||
|
}
|
||||||
|
|
||||||
RateCounterFilter::RateCounterFilter(PacketProcessorListener* listener,
|
RateCounterFilter::RateCounterFilter(PacketProcessorListener* listener,
|
||||||
const FlowIds& flow_ids,
|
const FlowIds& flow_ids,
|
||||||
const std::string& name)
|
const std::string& name)
|
||||||
: PacketProcessor(listener, flow_ids, false),
|
: PacketProcessor(listener, flow_ids, kRegular),
|
||||||
rate_counter_(new RateCounter()),
|
rate_counter_(new RateCounter()),
|
||||||
packets_per_second_stats_(),
|
packets_per_second_stats_(),
|
||||||
kbps_stats_(),
|
kbps_stats_(),
|
||||||
@ -310,7 +302,7 @@ void RateCounterFilter::RunFor(int64_t /*time_ms*/, Packets* in_out) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
LossFilter::LossFilter(PacketProcessorListener* listener)
|
LossFilter::LossFilter(PacketProcessorListener* listener)
|
||||||
: PacketProcessor(listener, false),
|
: PacketProcessor(listener, kRegular),
|
||||||
random_(0x12345678),
|
random_(0x12345678),
|
||||||
loss_fraction_(0.0f) {
|
loss_fraction_(0.0f) {
|
||||||
}
|
}
|
||||||
@ -336,9 +328,7 @@ void LossFilter::RunFor(int64_t /*time_ms*/, Packets* in_out) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
DelayFilter::DelayFilter(PacketProcessorListener* listener)
|
DelayFilter::DelayFilter(PacketProcessorListener* listener)
|
||||||
: PacketProcessor(listener, false),
|
: PacketProcessor(listener, kRegular), delay_us_(0), last_send_time_us_(0) {
|
||||||
delay_us_(0),
|
|
||||||
last_send_time_us_(0) {
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DelayFilter::SetDelay(int64_t delay_ms) {
|
void DelayFilter::SetDelay(int64_t delay_ms) {
|
||||||
@ -358,7 +348,7 @@ void DelayFilter::RunFor(int64_t /*time_ms*/, Packets* in_out) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
JitterFilter::JitterFilter(PacketProcessorListener* listener)
|
JitterFilter::JitterFilter(PacketProcessorListener* listener)
|
||||||
: PacketProcessor(listener, false),
|
: PacketProcessor(listener, kRegular),
|
||||||
random_(0x89674523),
|
random_(0x89674523),
|
||||||
stddev_jitter_us_(0),
|
stddev_jitter_us_(0),
|
||||||
last_send_time_us_(0) {
|
last_send_time_us_(0) {
|
||||||
@ -383,7 +373,7 @@ void JitterFilter::RunFor(int64_t /*time_ms*/, Packets* in_out) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ReorderFilter::ReorderFilter(PacketProcessorListener* listener)
|
ReorderFilter::ReorderFilter(PacketProcessorListener* listener)
|
||||||
: PacketProcessor(listener, false),
|
: PacketProcessor(listener, kRegular),
|
||||||
random_(0x27452389),
|
random_(0x27452389),
|
||||||
reorder_fraction_(0.0f) {
|
reorder_fraction_(0.0f) {
|
||||||
}
|
}
|
||||||
@ -415,7 +405,7 @@ void ReorderFilter::RunFor(int64_t /*time_ms*/, Packets* in_out) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ChokeFilter::ChokeFilter(PacketProcessorListener* listener)
|
ChokeFilter::ChokeFilter(PacketProcessorListener* listener)
|
||||||
: PacketProcessor(listener, false),
|
: PacketProcessor(listener, kRegular),
|
||||||
kbps_(1200),
|
kbps_(1200),
|
||||||
last_send_time_us_(0),
|
last_send_time_us_(0),
|
||||||
delay_cap_helper_(new DelayCapHelper()) {
|
delay_cap_helper_(new DelayCapHelper()) {
|
||||||
@ -423,7 +413,7 @@ ChokeFilter::ChokeFilter(PacketProcessorListener* listener)
|
|||||||
|
|
||||||
ChokeFilter::ChokeFilter(PacketProcessorListener* listener,
|
ChokeFilter::ChokeFilter(PacketProcessorListener* listener,
|
||||||
const FlowIds& flow_ids)
|
const FlowIds& flow_ids)
|
||||||
: PacketProcessor(listener, flow_ids, false),
|
: PacketProcessor(listener, flow_ids, kRegular),
|
||||||
kbps_(1200),
|
kbps_(1200),
|
||||||
last_send_time_us_(0),
|
last_send_time_us_(0),
|
||||||
delay_cap_helper_(new DelayCapHelper()) {
|
delay_cap_helper_(new DelayCapHelper()) {
|
||||||
@ -467,7 +457,7 @@ Stats<double> ChokeFilter::GetDelayStats() const {
|
|||||||
|
|
||||||
TraceBasedDeliveryFilter::TraceBasedDeliveryFilter(
|
TraceBasedDeliveryFilter::TraceBasedDeliveryFilter(
|
||||||
PacketProcessorListener* listener)
|
PacketProcessorListener* listener)
|
||||||
: PacketProcessor(listener, false),
|
: PacketProcessor(listener, kRegular),
|
||||||
current_offset_us_(0),
|
current_offset_us_(0),
|
||||||
delivery_times_us_(),
|
delivery_times_us_(),
|
||||||
next_delivery_it_(),
|
next_delivery_it_(),
|
||||||
@ -476,12 +466,13 @@ TraceBasedDeliveryFilter::TraceBasedDeliveryFilter(
|
|||||||
name_(""),
|
name_(""),
|
||||||
delay_cap_helper_(new DelayCapHelper()),
|
delay_cap_helper_(new DelayCapHelper()),
|
||||||
packets_per_second_stats_(),
|
packets_per_second_stats_(),
|
||||||
kbps_stats_() {}
|
kbps_stats_() {
|
||||||
|
}
|
||||||
|
|
||||||
TraceBasedDeliveryFilter::TraceBasedDeliveryFilter(
|
TraceBasedDeliveryFilter::TraceBasedDeliveryFilter(
|
||||||
PacketProcessorListener* listener,
|
PacketProcessorListener* listener,
|
||||||
const std::string& name)
|
const std::string& name)
|
||||||
: PacketProcessor(listener, false),
|
: PacketProcessor(listener, kRegular),
|
||||||
current_offset_us_(0),
|
current_offset_us_(0),
|
||||||
delivery_times_us_(),
|
delivery_times_us_(),
|
||||||
next_delivery_it_(),
|
next_delivery_it_(),
|
||||||
@ -490,7 +481,8 @@ TraceBasedDeliveryFilter::TraceBasedDeliveryFilter(
|
|||||||
name_(name),
|
name_(name),
|
||||||
delay_cap_helper_(new DelayCapHelper()),
|
delay_cap_helper_(new DelayCapHelper()),
|
||||||
packets_per_second_stats_(),
|
packets_per_second_stats_(),
|
||||||
kbps_stats_() {}
|
kbps_stats_() {
|
||||||
|
}
|
||||||
|
|
||||||
TraceBasedDeliveryFilter::~TraceBasedDeliveryFilter() {
|
TraceBasedDeliveryFilter::~TraceBasedDeliveryFilter() {
|
||||||
}
|
}
|
||||||
@ -771,6 +763,9 @@ void FullSendSideBwe::GiveFeedback(const FeedbackPacket& feedback) {
|
|||||||
int expected_packets = fb.packet_feedback_vector().back().sequence_number -
|
int expected_packets = fb.packet_feedback_vector().back().sequence_number -
|
||||||
fb.packet_feedback_vector().front().sequence_number +
|
fb.packet_feedback_vector().front().sequence_number +
|
||||||
1;
|
1;
|
||||||
|
// Assuming no reordering for now.
|
||||||
|
if (expected_packets <= 0)
|
||||||
|
return;
|
||||||
int lost_packets = expected_packets - fb.packet_feedback_vector().size();
|
int lost_packets = expected_packets - fb.packet_feedback_vector().size();
|
||||||
report_block_.fractionLost = (lost_packets << 8) / expected_packets;
|
report_block_.fractionLost = (lost_packets << 8) / expected_packets;
|
||||||
report_block_.cumulativeLost += lost_packets;
|
report_block_.cumulativeLost += lost_packets;
|
||||||
@ -815,7 +810,7 @@ SendSideBwe* CreateEstimator(BandwidthEstimatorType estimator,
|
|||||||
PacketSender::PacketSender(PacketProcessorListener* listener,
|
PacketSender::PacketSender(PacketProcessorListener* listener,
|
||||||
VideoSource* source,
|
VideoSource* source,
|
||||||
BandwidthEstimatorType estimator)
|
BandwidthEstimatorType estimator)
|
||||||
: PacketProcessor(listener, source->flow_id(), true),
|
: PacketProcessor(listener, source->flow_id(), kSender),
|
||||||
// For Packet::send_time_us() to be comparable with timestamps from
|
// For Packet::send_time_us() to be comparable with timestamps from
|
||||||
// clock_, the clock of the PacketSender and the Source must be aligned.
|
// clock_, the clock of the PacketSender and the Source must be aligned.
|
||||||
// We assume that both start at time 0.
|
// We assume that both start at time 0.
|
||||||
|
@ -162,7 +162,7 @@ class Random {
|
|||||||
|
|
||||||
class Packet {
|
class Packet {
|
||||||
public:
|
public:
|
||||||
enum Type { kMediaPacket, kFeedbackPacket };
|
enum Type { kMedia, kFeedback };
|
||||||
|
|
||||||
Packet();
|
Packet();
|
||||||
Packet(int flow_id, int64_t send_time_us, size_t payload_size);
|
Packet(int flow_id, int64_t send_time_us, size_t payload_size);
|
||||||
@ -197,7 +197,7 @@ class MediaPacket : public Packet {
|
|||||||
int64_t GetAbsSendTimeInMs() const;
|
int64_t GetAbsSendTimeInMs() const;
|
||||||
void SetAbsSendTimeMs(int64_t abs_send_time_ms);
|
void SetAbsSendTimeMs(int64_t abs_send_time_ms);
|
||||||
const RTPHeader& header() const { return header_; }
|
const RTPHeader& header() const { return header_; }
|
||||||
virtual Packet::Type GetPacketType() const { return kMediaPacket; }
|
virtual Packet::Type GetPacketType() const { return kMedia; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
RTPHeader header_;
|
RTPHeader header_;
|
||||||
@ -209,7 +209,7 @@ class FeedbackPacket : public Packet {
|
|||||||
: Packet(flow_id, send_time_us, 0) {}
|
: Packet(flow_id, send_time_us, 0) {}
|
||||||
virtual ~FeedbackPacket() {}
|
virtual ~FeedbackPacket() {}
|
||||||
|
|
||||||
virtual Packet::Type GetPacketType() const { return kFeedbackPacket; }
|
virtual Packet::Type GetPacketType() const { return kFeedback; }
|
||||||
};
|
};
|
||||||
|
|
||||||
class RembFeedback : public FeedbackPacket {
|
class RembFeedback : public FeedbackPacket {
|
||||||
@ -252,23 +252,26 @@ bool IsTimeSorted(const Packets& packets);
|
|||||||
|
|
||||||
class PacketProcessor;
|
class PacketProcessor;
|
||||||
|
|
||||||
|
enum ProcessorType { kSender, kReceiver, kRegular };
|
||||||
|
|
||||||
class PacketProcessorListener {
|
class PacketProcessorListener {
|
||||||
public:
|
public:
|
||||||
virtual ~PacketProcessorListener() {}
|
virtual ~PacketProcessorListener() {}
|
||||||
|
|
||||||
virtual void AddPacketProcessor(PacketProcessor* processor,
|
virtual void AddPacketProcessor(PacketProcessor* processor,
|
||||||
bool is_sender) = 0;
|
ProcessorType type) = 0;
|
||||||
virtual void RemovePacketProcessor(PacketProcessor* processor) = 0;
|
virtual void RemovePacketProcessor(PacketProcessor* processor) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class PacketProcessor {
|
class PacketProcessor {
|
||||||
public:
|
public:
|
||||||
PacketProcessor(PacketProcessorListener* listener, bool is_sender);
|
PacketProcessor(PacketProcessorListener* listener, ProcessorType type);
|
||||||
PacketProcessor(PacketProcessorListener* listener,
|
PacketProcessor(PacketProcessorListener* listener,
|
||||||
int flow_id,
|
int flow_id,
|
||||||
bool is_sender);
|
ProcessorType type);
|
||||||
PacketProcessor(PacketProcessorListener* listener, const FlowIds& flow_ids,
|
PacketProcessor(PacketProcessorListener* listener,
|
||||||
bool is_sender);
|
const FlowIds& flow_ids,
|
||||||
|
ProcessorType type);
|
||||||
virtual ~PacketProcessor();
|
virtual ~PacketProcessor();
|
||||||
|
|
||||||
// Called after each simulation batch to allow the processor to plot any
|
// Called after each simulation batch to allow the processor to plot any
|
||||||
|
Reference in New Issue
Block a user