Adds a simplified Reno-type TCP sender.
BUG=4559 R=sprang@webrtc.org Review URL: https://webrtc-codereview.appspot.com/44189004 Cr-Commit-Position: refs/heads/master@{#9021}
This commit is contained in:
parent
f49dbfa5c3
commit
3795937920
@ -241,6 +241,8 @@
|
||||
'remote_bitrate_estimator/test/estimators/remb.h',
|
||||
'remote_bitrate_estimator/test/estimators/send_side.cc',
|
||||
'remote_bitrate_estimator/test/estimators/send_side.h',
|
||||
'remote_bitrate_estimator/test/estimators/tcp.cc',
|
||||
'remote_bitrate_estimator/test/estimators/tcp.h',
|
||||
'rtp_rtcp/source/mock/mock_rtp_payload_strategy.h',
|
||||
'rtp_rtcp/source/byte_io_unittest.cc',
|
||||
'rtp_rtcp/source/fec_receiver_unittest.cc',
|
||||
|
@ -46,7 +46,7 @@ INSTANTIATE_TEST_CASE_P(VideoSendersTest,
|
||||
TEST_P(BweSimulation, SprintUplinkTest) {
|
||||
VerboseLogging(true);
|
||||
AdaptiveVideoSource source(0, 30, 300, 0, 0);
|
||||
PacketSender sender(&uplink_, &source, GetParam());
|
||||
VideoSender sender(&uplink_, &source, GetParam());
|
||||
RateCounterFilter counter1(&uplink_, 0, "sender_output");
|
||||
TraceBasedDeliveryFilter filter(&uplink_, 0, "link_capacity");
|
||||
RateCounterFilter counter2(&uplink_, 0, "receiver_input");
|
||||
@ -58,7 +58,7 @@ TEST_P(BweSimulation, SprintUplinkTest) {
|
||||
TEST_P(BweSimulation, Verizon4gDownlinkTest) {
|
||||
VerboseLogging(true);
|
||||
AdaptiveVideoSource source(0, 30, 300, 0, 0);
|
||||
PacketSender sender(&downlink_, &source, GetParam());
|
||||
VideoSender sender(&downlink_, &source, GetParam());
|
||||
RateCounterFilter counter1(&downlink_, 0, "sender_output");
|
||||
TraceBasedDeliveryFilter filter(&downlink_, 0, "link_capacity");
|
||||
RateCounterFilter counter2(&downlink_, 0, "receiver_input");
|
||||
@ -74,13 +74,13 @@ TEST_P(BweSimulation, Choke1000kbps500kbps1000kbpsBiDirectional) {
|
||||
const size_t kNumFlows = sizeof(kFlowIds) / sizeof(kFlowIds[0]);
|
||||
|
||||
AdaptiveVideoSource source(kFlowIds[0], 30, 300, 0, 0);
|
||||
PacketSender sender(&uplink_, &source, GetParam());
|
||||
VideoSender sender(&uplink_, &source, GetParam());
|
||||
ChokeFilter choke(&uplink_, kFlowIds[0]);
|
||||
RateCounterFilter counter(&uplink_, kFlowIds[0], "receiver_input_0");
|
||||
PacketReceiver receiver(&uplink_, kFlowIds[0], GetParam(), true, false);
|
||||
|
||||
AdaptiveVideoSource source2(kFlowIds[1], 30, 300, 0, 0);
|
||||
PacketSender sender2(&downlink_, &source2, GetParam());
|
||||
VideoSender sender2(&downlink_, &source2, GetParam());
|
||||
ChokeFilter choke2(&downlink_, kFlowIds[1]);
|
||||
DelayFilter delay(&downlink_, CreateFlowIds(kFlowIds, kNumFlows));
|
||||
RateCounterFilter counter2(&downlink_, kFlowIds[1], "receiver_input_1");
|
||||
@ -102,7 +102,7 @@ TEST_P(BweSimulation, Choke1000kbps500kbps1000kbps) {
|
||||
VerboseLogging(true);
|
||||
|
||||
AdaptiveVideoSource source(0, 30, 300, 0, 0);
|
||||
PacketSender sender(&uplink_, &source, GetParam());
|
||||
VideoSender sender(&uplink_, &source, GetParam());
|
||||
ChokeFilter choke(&uplink_, 0);
|
||||
RateCounterFilter counter(&uplink_, 0, "receiver_input");
|
||||
PacketReceiver receiver(&uplink_, 0, GetParam(), true, false);
|
||||
@ -163,7 +163,7 @@ TEST_P(BweSimulation, PacerChoke200kbps30kbps200kbps) {
|
||||
TEST_P(BweSimulation, Choke200kbps30kbps200kbps) {
|
||||
VerboseLogging(true);
|
||||
AdaptiveVideoSource source(0, 30, 300, 0, 0);
|
||||
PacketSender sender(&uplink_, &source, GetParam());
|
||||
VideoSender sender(&uplink_, &source, GetParam());
|
||||
ChokeFilter filter(&uplink_, 0);
|
||||
RateCounterFilter counter(&uplink_, 0, "receiver_input");
|
||||
PacketReceiver receiver(&uplink_, 0, GetParam(), true, true);
|
||||
@ -179,7 +179,7 @@ TEST_P(BweSimulation, Choke200kbps30kbps200kbps) {
|
||||
TEST_P(BweSimulation, GoogleWifiTrace3Mbps) {
|
||||
VerboseLogging(true);
|
||||
AdaptiveVideoSource source(0, 30, 300, 0, 0);
|
||||
PacketSender sender(&uplink_, &source, kRembEstimator);
|
||||
VideoSender sender(&uplink_, &source, GetParam());
|
||||
RateCounterFilter counter1(&uplink_, 0, "sender_output");
|
||||
TraceBasedDeliveryFilter filter(&uplink_, 0, "link_capacity");
|
||||
filter.SetMaxDelay(500);
|
||||
@ -192,7 +192,7 @@ TEST_P(BweSimulation, GoogleWifiTrace3Mbps) {
|
||||
TEST_P(BweSimulation, PacerGoogleWifiTrace3Mbps) {
|
||||
VerboseLogging(true);
|
||||
PeriodicKeyFrameSource source(0, 30, 300, 0, 0, 1000);
|
||||
PacedVideoSender sender(&uplink_, &source, kRembEstimator);
|
||||
PacedVideoSender sender(&uplink_, &source, GetParam());
|
||||
RateCounterFilter counter1(&uplink_, 0, "sender_output");
|
||||
TraceBasedDeliveryFilter filter(&uplink_, 0, "link_capacity");
|
||||
filter.SetMaxDelay(500);
|
||||
@ -207,13 +207,13 @@ TEST_P(BweSimulation, SelfFairnessTest) {
|
||||
const int kAllFlowIds[] = {0, 1, 2};
|
||||
const size_t kNumFlows = sizeof(kAllFlowIds) / sizeof(kAllFlowIds[0]);
|
||||
rtc::scoped_ptr<AdaptiveVideoSource> sources[kNumFlows];
|
||||
rtc::scoped_ptr<PacketSender> senders[kNumFlows];
|
||||
rtc::scoped_ptr<VideoSender> senders[kNumFlows];
|
||||
for (size_t i = 0; i < kNumFlows; ++i) {
|
||||
// Streams started 20 seconds apart to give them different advantage when
|
||||
// competing for the bandwidth.
|
||||
sources[i].reset(
|
||||
new AdaptiveVideoSource(kAllFlowIds[i], 30, 300, 0, i * 20000));
|
||||
senders[i].reset(new PacketSender(&uplink_, sources[i].get(), GetParam()));
|
||||
senders[i].reset(new VideoSender(&uplink_, sources[i].get(), GetParam()));
|
||||
}
|
||||
|
||||
ChokeFilter choke(&uplink_, CreateFlowIds(kAllFlowIds, kNumFlows));
|
||||
@ -273,6 +273,64 @@ TEST_P(BweSimulation, PacedSelfFairnessTest) {
|
||||
|
||||
RunFor(30 * 60 * 1000);
|
||||
}
|
||||
|
||||
TEST_P(BweSimulation, PacedTcpFairnessTest) {
|
||||
VerboseLogging(true);
|
||||
|
||||
const int kAllFlowIds[] = {0, 1};
|
||||
const size_t kNumFlows = sizeof(kAllFlowIds) / sizeof(kAllFlowIds[0]);
|
||||
|
||||
const int kAllMediaFlowIds[] = {0};
|
||||
const size_t kNumMediaFlows =
|
||||
sizeof(kAllMediaFlowIds) / sizeof(kAllMediaFlowIds[0]);
|
||||
|
||||
const int kAllTcpFlowIds[] = {1};
|
||||
const size_t kNumTcpFlows =
|
||||
sizeof(kAllTcpFlowIds) / sizeof(kAllTcpFlowIds[0]);
|
||||
|
||||
rtc::scoped_ptr<PeriodicKeyFrameSource> sources[kNumFlows];
|
||||
rtc::scoped_ptr<PacketSender> senders[kNumFlows + kNumTcpFlows];
|
||||
|
||||
for (size_t i = 0; i < kNumMediaFlows; ++i) {
|
||||
// Streams started 20 seconds apart to give them different advantage when
|
||||
// competing for the bandwidth.
|
||||
sources[i].reset(new PeriodicKeyFrameSource(kAllMediaFlowIds[i], 30, 300, 0,
|
||||
i * 20000, 1000));
|
||||
senders[i].reset(
|
||||
new PacedVideoSender(&uplink_, sources[i].get(), GetParam()));
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < kNumTcpFlows; ++i) {
|
||||
senders[kNumMediaFlows + i].reset(
|
||||
new TcpSender(&uplink_, kAllTcpFlowIds[i]));
|
||||
}
|
||||
|
||||
ChokeFilter choke(&uplink_, CreateFlowIds(kAllFlowIds, kNumFlows));
|
||||
choke.SetCapacity(1000);
|
||||
choke.SetMaxDelay(1000);
|
||||
|
||||
rtc::scoped_ptr<RateCounterFilter> rate_counters[kNumFlows];
|
||||
for (size_t i = 0; i < kNumFlows; ++i) {
|
||||
rate_counters[i].reset(new RateCounterFilter(
|
||||
&uplink_, CreateFlowIds(&kAllFlowIds[i], 1), "receiver_input"));
|
||||
}
|
||||
|
||||
RateCounterFilter total_utilization(
|
||||
&uplink_, CreateFlowIds(kAllFlowIds, kNumFlows), "total_utilization");
|
||||
|
||||
rtc::scoped_ptr<PacketReceiver> receivers[kNumFlows];
|
||||
for (size_t i = 0; i < kNumMediaFlows; ++i) {
|
||||
receivers[i].reset(new PacketReceiver(&uplink_, kAllMediaFlowIds[i],
|
||||
GetParam(), i == 0, false));
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < kNumTcpFlows; ++i) {
|
||||
receivers[kNumMediaFlows + i].reset(new PacketReceiver(
|
||||
&uplink_, kAllTcpFlowIds[i], kTcpEstimator, false, false));
|
||||
}
|
||||
|
||||
RunFor(30 * 60 * 1000);
|
||||
}
|
||||
#endif // BWE_TEST_LOGGING_COMPILE_TIME_ENABLE
|
||||
} // namespace bwe
|
||||
} // namespace testing
|
||||
|
@ -36,14 +36,14 @@ INSTANTIATE_TEST_CASE_P(VideoSendersTest,
|
||||
|
||||
TEST_P(DefaultBweTest, UnlimitedSpeed) {
|
||||
VideoSource source(0, 30, 300, 0, 0);
|
||||
PacketSender sender(&uplink_, &source, GetParam());
|
||||
VideoSender sender(&uplink_, &source, GetParam());
|
||||
PacketReceiver receiver(&uplink_, 0, GetParam(), false, false);
|
||||
RunFor(10 * 60 * 1000);
|
||||
}
|
||||
|
||||
TEST_P(DefaultBweTest, SteadyLoss) {
|
||||
VideoSource source(0, 30, 300, 0, 0);
|
||||
PacketSender sender(&uplink_, &source, GetParam());
|
||||
VideoSender sender(&uplink_, &source, GetParam());
|
||||
LossFilter loss(&uplink_, 0);
|
||||
PacketReceiver receiver(&uplink_, 0, GetParam(), false, false);
|
||||
loss.SetLoss(20.0);
|
||||
@ -52,7 +52,7 @@ TEST_P(DefaultBweTest, SteadyLoss) {
|
||||
|
||||
TEST_P(DefaultBweTest, IncreasingLoss1) {
|
||||
VideoSource source(0, 30, 300, 0, 0);
|
||||
PacketSender sender(&uplink_, &source, GetParam());
|
||||
VideoSender sender(&uplink_, &source, GetParam());
|
||||
LossFilter loss(&uplink_, 0);
|
||||
PacketReceiver receiver(&uplink_, 0, GetParam(), false, false);
|
||||
for (int i = 0; i < 76; ++i) {
|
||||
@ -63,7 +63,7 @@ TEST_P(DefaultBweTest, IncreasingLoss1) {
|
||||
|
||||
TEST_P(DefaultBweTest, SteadyDelay) {
|
||||
VideoSource source(0, 30, 300, 0, 0);
|
||||
PacketSender sender(&uplink_, &source, GetParam());
|
||||
VideoSender sender(&uplink_, &source, GetParam());
|
||||
DelayFilter delay(&uplink_, 0);
|
||||
PacketReceiver receiver(&uplink_, 0, GetParam(), false, false);
|
||||
delay.SetDelay(1000);
|
||||
@ -72,7 +72,7 @@ TEST_P(DefaultBweTest, SteadyDelay) {
|
||||
|
||||
TEST_P(DefaultBweTest, IncreasingDelay1) {
|
||||
VideoSource source(0, 30, 300, 0, 0);
|
||||
PacketSender sender(&uplink_, &source, GetParam());
|
||||
VideoSender sender(&uplink_, &source, GetParam());
|
||||
DelayFilter delay(&uplink_, 0);
|
||||
PacketReceiver receiver(&uplink_, 0, GetParam(), false, false);
|
||||
RunFor(10 * 60 * 1000);
|
||||
@ -85,7 +85,7 @@ TEST_P(DefaultBweTest, IncreasingDelay1) {
|
||||
|
||||
TEST_P(DefaultBweTest, IncreasingDelay2) {
|
||||
VideoSource source(0, 30, 300, 0, 0);
|
||||
PacketSender sender(&uplink_, &source, GetParam());
|
||||
VideoSender sender(&uplink_, &source, GetParam());
|
||||
DelayFilter delay(&uplink_, 0);
|
||||
RateCounterFilter counter(&uplink_, 0, "");
|
||||
PacketReceiver receiver(&uplink_, 0, GetParam(), false, false);
|
||||
@ -100,7 +100,7 @@ TEST_P(DefaultBweTest, IncreasingDelay2) {
|
||||
|
||||
TEST_P(DefaultBweTest, JumpyDelay1) {
|
||||
VideoSource source(0, 30, 300, 0, 0);
|
||||
PacketSender sender(&uplink_, &source, GetParam());
|
||||
VideoSender sender(&uplink_, &source, GetParam());
|
||||
DelayFilter delay(&uplink_, 0);
|
||||
PacketReceiver receiver(&uplink_, 0, GetParam(), false, false);
|
||||
RunFor(10 * 60 * 1000);
|
||||
@ -116,7 +116,7 @@ TEST_P(DefaultBweTest, JumpyDelay1) {
|
||||
|
||||
TEST_P(DefaultBweTest, SteadyJitter) {
|
||||
VideoSource source(0, 30, 300, 0, 0);
|
||||
PacketSender sender(&uplink_, &source, GetParam());
|
||||
VideoSender sender(&uplink_, &source, GetParam());
|
||||
JitterFilter jitter(&uplink_, 0);
|
||||
RateCounterFilter counter(&uplink_, 0, "");
|
||||
PacketReceiver receiver(&uplink_, 0, GetParam(), false, false);
|
||||
@ -126,7 +126,7 @@ TEST_P(DefaultBweTest, SteadyJitter) {
|
||||
|
||||
TEST_P(DefaultBweTest, IncreasingJitter1) {
|
||||
VideoSource source(0, 30, 300, 0, 0);
|
||||
PacketSender sender(&uplink_, &source, GetParam());
|
||||
VideoSender sender(&uplink_, &source, GetParam());
|
||||
JitterFilter jitter(&uplink_, 0);
|
||||
PacketReceiver receiver(&uplink_, 0, GetParam(), false, false);
|
||||
for (int i = 0; i < 2 * 60 * 2; ++i) {
|
||||
@ -138,7 +138,7 @@ TEST_P(DefaultBweTest, IncreasingJitter1) {
|
||||
|
||||
TEST_P(DefaultBweTest, IncreasingJitter2) {
|
||||
VideoSource source(0, 30, 300, 0, 0);
|
||||
PacketSender sender(&uplink_, &source, GetParam());
|
||||
VideoSender sender(&uplink_, &source, GetParam());
|
||||
JitterFilter jitter(&uplink_, 0);
|
||||
PacketReceiver receiver(&uplink_, 0, GetParam(), false, false);
|
||||
RunFor(30 * 1000);
|
||||
@ -152,7 +152,7 @@ TEST_P(DefaultBweTest, IncreasingJitter2) {
|
||||
|
||||
TEST_P(DefaultBweTest, SteadyReorder) {
|
||||
VideoSource source(0, 30, 300, 0, 0);
|
||||
PacketSender sender(&uplink_, &source, GetParam());
|
||||
VideoSender sender(&uplink_, &source, GetParam());
|
||||
ReorderFilter reorder(&uplink_, 0);
|
||||
PacketReceiver receiver(&uplink_, 0, GetParam(), false, false);
|
||||
reorder.SetReorder(20.0);
|
||||
@ -161,7 +161,7 @@ TEST_P(DefaultBweTest, SteadyReorder) {
|
||||
|
||||
TEST_P(DefaultBweTest, IncreasingReorder1) {
|
||||
VideoSource source(0, 30, 300, 0, 0);
|
||||
PacketSender sender(&uplink_, &source, GetParam());
|
||||
VideoSender sender(&uplink_, &source, GetParam());
|
||||
ReorderFilter reorder(&uplink_, 0);
|
||||
PacketReceiver receiver(&uplink_, 0, GetParam(), false, false);
|
||||
for (int i = 0; i < 76; ++i) {
|
||||
@ -172,7 +172,7 @@ TEST_P(DefaultBweTest, IncreasingReorder1) {
|
||||
|
||||
TEST_P(DefaultBweTest, SteadyChoke) {
|
||||
VideoSource source(0, 30, 300, 0, 0);
|
||||
PacketSender sender(&uplink_, &source, GetParam());
|
||||
VideoSender sender(&uplink_, &source, GetParam());
|
||||
ChokeFilter choke(&uplink_, 0);
|
||||
PacketReceiver receiver(&uplink_, 0, GetParam(), false, false);
|
||||
choke.SetCapacity(140);
|
||||
@ -181,7 +181,7 @@ TEST_P(DefaultBweTest, SteadyChoke) {
|
||||
|
||||
TEST_P(DefaultBweTest, IncreasingChoke1) {
|
||||
VideoSource source(0, 30, 300, 0, 0);
|
||||
PacketSender sender(&uplink_, &source, GetParam());
|
||||
VideoSender sender(&uplink_, &source, GetParam());
|
||||
ChokeFilter choke(&uplink_, 0);
|
||||
PacketReceiver receiver(&uplink_, 0, GetParam(), false, false);
|
||||
for (int i = 1200; i >= 100; i -= 100) {
|
||||
@ -192,7 +192,7 @@ TEST_P(DefaultBweTest, IncreasingChoke1) {
|
||||
|
||||
TEST_P(DefaultBweTest, IncreasingChoke2) {
|
||||
VideoSource source(0, 30, 300, 0, 0);
|
||||
PacketSender sender(&uplink_, &source, GetParam());
|
||||
VideoSender sender(&uplink_, &source, GetParam());
|
||||
ChokeFilter choke(&uplink_, 0);
|
||||
PacketReceiver receiver(&uplink_, 0, GetParam(), false, false);
|
||||
RunFor(60 * 1000);
|
||||
@ -204,7 +204,7 @@ TEST_P(DefaultBweTest, IncreasingChoke2) {
|
||||
|
||||
TEST_P(DefaultBweTest, Multi1) {
|
||||
VideoSource source(0, 30, 300, 0, 0);
|
||||
PacketSender sender(&uplink_, &source, GetParam());
|
||||
VideoSender sender(&uplink_, &source, GetParam());
|
||||
DelayFilter delay(&uplink_, 0);
|
||||
ChokeFilter choke(&uplink_, 0);
|
||||
RateCounterFilter counter(&uplink_, 0, "");
|
||||
@ -222,7 +222,7 @@ TEST_P(DefaultBweTest, Multi1) {
|
||||
|
||||
TEST_P(DefaultBweTest, Multi2) {
|
||||
VideoSource source(0, 30, 300, 0, 0);
|
||||
PacketSender sender(&uplink_, &source, GetParam());
|
||||
VideoSender sender(&uplink_, &source, GetParam());
|
||||
ChokeFilter choke(&uplink_, 0);
|
||||
JitterFilter jitter(&uplink_, 0);
|
||||
RateCounterFilter counter(&uplink_, 0, "");
|
||||
@ -280,7 +280,7 @@ INSTANTIATE_TEST_CASE_P(VideoSendersTest,
|
||||
|
||||
TEST_P(BweFeedbackTest, Choke1000kbps500kbps1000kbps) {
|
||||
AdaptiveVideoSource source(0, 30, 300, 0, 0);
|
||||
PacketSender sender(&uplink_, &source, GetParam());
|
||||
VideoSender sender(&uplink_, &source, GetParam());
|
||||
ChokeFilter filter(&uplink_, 0);
|
||||
RateCounterFilter counter(&uplink_, 0, "receiver_input");
|
||||
PacketReceiver receiver(&uplink_, 0, GetParam(), false, false);
|
||||
@ -299,7 +299,7 @@ TEST_P(BweFeedbackTest, Choke1000kbps500kbps1000kbps) {
|
||||
|
||||
TEST_P(BweFeedbackTest, Choke200kbps30kbps200kbps) {
|
||||
AdaptiveVideoSource source(0, 30, 300, 0, 0);
|
||||
PacketSender sender(&uplink_, &source, GetParam());
|
||||
VideoSender sender(&uplink_, &source, GetParam());
|
||||
ChokeFilter filter(&uplink_, 0);
|
||||
RateCounterFilter counter(&uplink_, 0, "receiver_input");
|
||||
PacketReceiver receiver(&uplink_, 0, GetParam(), false, false);
|
||||
@ -319,7 +319,7 @@ TEST_P(BweFeedbackTest, Choke200kbps30kbps200kbps) {
|
||||
|
||||
TEST_P(BweFeedbackTest, Verizon4gDownlinkTest) {
|
||||
AdaptiveVideoSource source(0, 30, 300, 0, 0);
|
||||
PacketSender sender(&uplink_, &source, GetParam());
|
||||
VideoSender sender(&uplink_, &source, GetParam());
|
||||
RateCounterFilter counter1(&uplink_, 0, "sender_output");
|
||||
TraceBasedDeliveryFilter filter(&uplink_, 0, "link_capacity");
|
||||
RateCounterFilter counter2(&uplink_, 0, "receiver_input");
|
||||
@ -333,7 +333,7 @@ TEST_P(BweFeedbackTest, Verizon4gDownlinkTest) {
|
||||
// webrtc:3277
|
||||
TEST_P(BweFeedbackTest, DISABLED_GoogleWifiTrace3Mbps) {
|
||||
AdaptiveVideoSource source(0, 30, 300, 0, 0);
|
||||
PacketSender sender(&uplink_, &source, GetParam());
|
||||
VideoSender sender(&uplink_, &source, GetParam());
|
||||
RateCounterFilter counter1(&uplink_, 0, "sender_output");
|
||||
TraceBasedDeliveryFilter filter(&uplink_, 0, "link_capacity");
|
||||
filter.SetMaxDelay(500);
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include "webrtc/modules/remote_bitrate_estimator/test/estimators/nada.h"
|
||||
#include "webrtc/modules/remote_bitrate_estimator/test/estimators/remb.h"
|
||||
#include "webrtc/modules/remote_bitrate_estimator/test/estimators/send_side.h"
|
||||
#include "webrtc/modules/remote_bitrate_estimator/test/estimators/tcp.h"
|
||||
|
||||
namespace webrtc {
|
||||
namespace testing {
|
||||
@ -58,6 +59,8 @@ BweSender* CreateBweSender(BandwidthEstimatorType estimator,
|
||||
return new FullBweSender(kbps, observer, clock);
|
||||
case kNadaEstimator:
|
||||
return new NadaBweSender(kbps, observer, clock);
|
||||
case kTcpEstimator:
|
||||
FALLTHROUGH();
|
||||
case kNullEstimator:
|
||||
return new NullBweSender();
|
||||
}
|
||||
@ -75,6 +78,8 @@ BweReceiver* CreateBweReceiver(BandwidthEstimatorType type,
|
||||
return new SendSideBweReceiver(flow_id);
|
||||
case kNadaEstimator:
|
||||
return new NadaBweReceiver(flow_id);
|
||||
case kTcpEstimator:
|
||||
return new TcpBweReceiver(flow_id);
|
||||
case kNullEstimator:
|
||||
return new BweReceiver(flow_id);
|
||||
}
|
||||
|
@ -53,7 +53,8 @@ enum BandwidthEstimatorType {
|
||||
kNullEstimator,
|
||||
kNadaEstimator,
|
||||
kRembEstimator,
|
||||
kFullSendSideEstimator
|
||||
kFullSendSideEstimator,
|
||||
kTcpEstimator
|
||||
};
|
||||
|
||||
int64_t GetAbsSendTimeInMs(uint32_t abs_send_time);
|
||||
|
@ -148,6 +148,15 @@ MediaPacket::MediaPacket() {
|
||||
memset(&header_, 0, sizeof(header_));
|
||||
}
|
||||
|
||||
MediaPacket::MediaPacket(int flow_id,
|
||||
int64_t send_time_us,
|
||||
size_t payload_size,
|
||||
uint16_t sequence_number)
|
||||
: Packet(flow_id, send_time_us, payload_size) {
|
||||
header_ = RTPHeader();
|
||||
header_.sequenceNumber = sequence_number;
|
||||
}
|
||||
|
||||
MediaPacket::MediaPacket(int flow_id,
|
||||
int64_t send_time_us,
|
||||
size_t payload_size,
|
||||
@ -157,7 +166,7 @@ MediaPacket::MediaPacket(int flow_id,
|
||||
|
||||
MediaPacket::MediaPacket(int64_t send_time_us, uint32_t sequence_number)
|
||||
: Packet(0, send_time_us, 0) {
|
||||
memset(&header_, 0, sizeof(header_));
|
||||
header_ = RTPHeader();
|
||||
header_.sequenceNumber = sequence_number;
|
||||
}
|
||||
|
||||
@ -636,6 +645,9 @@ uint32_t VideoSource::NextPacketSize(uint32_t frame_size,
|
||||
|
||||
void VideoSource::RunFor(int64_t time_ms, Packets* in_out) {
|
||||
assert(in_out);
|
||||
std::stringstream ss;
|
||||
ss << "SendEstimate_" << flow_id_ << "#1";
|
||||
BWE_TEST_LOGGING_PLOT(0, ss.str(), now_ms_, bits_per_second_ / 1000);
|
||||
now_ms_ += time_ms;
|
||||
Packets new_packets;
|
||||
while (now_ms_ >= next_frame_ms_) {
|
||||
|
@ -765,7 +765,7 @@ TEST_F(BweTestFramework_ChokeFilterTest, ShortTraceMaxDelay) {
|
||||
TestChoke(&filter, 25, 1, 1);
|
||||
}
|
||||
|
||||
void TestVideoSender(PacketSender* sender,
|
||||
void TestVideoSender(VideoSender* sender,
|
||||
int64_t run_for_ms,
|
||||
uint32_t expected_packets,
|
||||
uint32_t expected_payload_size,
|
||||
@ -812,7 +812,7 @@ void TestVideoSender(PacketSender* sender,
|
||||
TEST(BweTestFramework_VideoSenderTest, Fps1Kbps80_1s) {
|
||||
// 1 fps, 80 kbps
|
||||
VideoSource source(0, 1.0f, 80, 0x1234, 0);
|
||||
PacketSender sender(NULL, &source, kNullEstimator);
|
||||
VideoSender sender(NULL, &source, kNullEstimator);
|
||||
EXPECT_EQ(80000u, source.bits_per_second());
|
||||
// We're at 1 fps, so all packets should be generated on first call, giving 10
|
||||
// packets of each 1000 bytes, total 10000 bytes.
|
||||
@ -830,7 +830,7 @@ TEST(BweTestFramework_VideoSenderTest, Fps1Kbps80_1s) {
|
||||
TEST(BweTestFramework_VideoSenderTest, Fps1Kbps80_1s_Offset) {
|
||||
// 1 fps, 80 kbps, offset 0.5 of a frame period, ==0.5s in this case.
|
||||
VideoSource source(0, 1.0f, 80, 0x1234, 500);
|
||||
PacketSender sender(NULL, &source, kNullEstimator);
|
||||
VideoSender sender(NULL, &source, kNullEstimator);
|
||||
EXPECT_EQ(80000u, source.bits_per_second());
|
||||
// 499ms, no output.
|
||||
TestVideoSender(&sender, 499, 0, 0, 0);
|
||||
@ -851,7 +851,7 @@ TEST(BweTestFramework_VideoSenderTest, Fps1Kbps80_1s_Offset) {
|
||||
TEST(BweTestFramework_VideoSenderTest, Fps50Kpbs80_11s) {
|
||||
// 50 fps, 80 kbps.
|
||||
VideoSource source(0, 50.0f, 80, 0x1234, 0);
|
||||
PacketSender sender(NULL, &source, kNullEstimator);
|
||||
VideoSender sender(NULL, &source, kNullEstimator);
|
||||
EXPECT_EQ(80000u, source.bits_per_second());
|
||||
// 9998ms, should see 500 frames, 200 byte payloads, total 100000 bytes.
|
||||
TestVideoSender(&sender, 9998, 500, 200, 100000);
|
||||
@ -868,7 +868,7 @@ TEST(BweTestFramework_VideoSenderTest, Fps50Kpbs80_11s) {
|
||||
TEST(BweTestFramework_VideoSenderTest, Fps10Kpbs120_1s) {
|
||||
// 20 fps, 120 kbps.
|
||||
VideoSource source(0, 20.0f, 120, 0x1234, 0);
|
||||
PacketSender sender(NULL, &source, kNullEstimator);
|
||||
VideoSender sender(NULL, &source, kNullEstimator);
|
||||
EXPECT_EQ(120000u, source.bits_per_second());
|
||||
// 498ms, 10 frames with 750 byte payloads, total 7500 bytes.
|
||||
TestVideoSender(&sender, 498, 10, 750, 7500);
|
||||
@ -885,7 +885,7 @@ TEST(BweTestFramework_VideoSenderTest, Fps10Kpbs120_1s) {
|
||||
TEST(BweTestFramework_VideoSenderTest, Fps30Kbps800_20s) {
|
||||
// 20 fps, 820 kbps.
|
||||
VideoSource source(0, 25.0f, 820, 0x1234, 0);
|
||||
PacketSender sender(NULL, &source, kNullEstimator);
|
||||
VideoSender sender(NULL, &source, kNullEstimator);
|
||||
EXPECT_EQ(820000u, source.bits_per_second());
|
||||
// 9998ms, 250 frames. 820 kbps = 102500 bytes/s, so total should be 1025000.
|
||||
// Each frame is 102500/25=4100 bytes, or 5 packets (4 @1000 bytes, 1 @100),
|
||||
@ -907,7 +907,7 @@ TEST(BweTestFramework_VideoSenderTest, Fps30Kbps800_20s) {
|
||||
TEST(BweTestFramework_VideoSenderTest, TestAppendInOrder) {
|
||||
// 1 fps, 80 kbps, 250ms offset.
|
||||
VideoSource source1(0, 1.0f, 80, 0x1234, 250);
|
||||
PacketSender sender1(NULL, &source1, kNullEstimator);
|
||||
VideoSender sender1(NULL, &source1, kNullEstimator);
|
||||
EXPECT_EQ(80000u, source1.bits_per_second());
|
||||
Packets packets;
|
||||
// Generate some packets, verify they are sorted.
|
||||
@ -923,7 +923,7 @@ TEST(BweTestFramework_VideoSenderTest, TestAppendInOrder) {
|
||||
|
||||
// Another sender, 2 fps, 160 kbps, 150ms offset
|
||||
VideoSource source2(0, 2.0f, 160, 0x2234, 150);
|
||||
PacketSender sender2(NULL, &source2, kNullEstimator);
|
||||
VideoSender sender2(NULL, &source2, kNullEstimator);
|
||||
EXPECT_EQ(160000u, source2.bits_per_second());
|
||||
// Generate some packets, verify that they are merged with the packets already
|
||||
// on the list.
|
||||
@ -941,7 +941,7 @@ TEST(BweTestFramework_VideoSenderTest, TestAppendInOrder) {
|
||||
|
||||
TEST(BweTestFramework_VideoSenderTest, FeedbackIneffective) {
|
||||
VideoSource source(0, 25.0f, 820, 0x1234, 0);
|
||||
PacketSender sender(NULL, &source, kNullEstimator);
|
||||
VideoSender sender(NULL, &source, kNullEstimator);
|
||||
|
||||
EXPECT_EQ(820000u, source.bits_per_second());
|
||||
TestVideoSender(&sender, 9998, 1000, 500, 1025000);
|
||||
@ -957,7 +957,7 @@ TEST(BweTestFramework_VideoSenderTest, FeedbackIneffective) {
|
||||
|
||||
TEST(BweTestFramework_AdaptiveVideoSenderTest, FeedbackChangesBitrate) {
|
||||
AdaptiveVideoSource source(0, 25.0f, 820, 0x1234, 0);
|
||||
PacketSender sender(NULL, &source, kRembEstimator);
|
||||
VideoSender sender(NULL, &source, kRembEstimator);
|
||||
EXPECT_EQ(820000u, source.bits_per_second());
|
||||
TestVideoSender(&sender, 9998, 1000, 500, 1025000);
|
||||
|
||||
|
@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright (c) 2015 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "webrtc/modules/remote_bitrate_estimator/test/estimators/tcp.h"
|
||||
|
||||
#include "testing/gtest/include/gtest/gtest.h"
|
||||
#include "webrtc/base/common.h"
|
||||
#include "webrtc/modules/bitrate_controller/include/bitrate_controller.h"
|
||||
#include "webrtc/modules/remote_bitrate_estimator/test/bwe_test_logging.h"
|
||||
#include "webrtc/modules/rtp_rtcp/interface/receive_statistics.h"
|
||||
|
||||
namespace webrtc {
|
||||
namespace testing {
|
||||
namespace bwe {
|
||||
|
||||
TcpBweReceiver::TcpBweReceiver(int flow_id)
|
||||
: BweReceiver(flow_id), last_feedback_ms_(0) {
|
||||
}
|
||||
|
||||
TcpBweReceiver::~TcpBweReceiver() {
|
||||
}
|
||||
|
||||
void TcpBweReceiver::ReceivePacket(int64_t arrival_time_ms,
|
||||
const MediaPacket& media_packet) {
|
||||
acks_.push_back(media_packet.header().sequenceNumber);
|
||||
}
|
||||
|
||||
FeedbackPacket* TcpBweReceiver::GetFeedback(int64_t now_ms) {
|
||||
// if (now_ms - last_feedback_ms_ < 100)
|
||||
// return NULL;
|
||||
last_feedback_ms_ = now_ms;
|
||||
FeedbackPacket* fb = new TcpFeedback(flow_id_, now_ms * 1000, acks_);
|
||||
acks_.clear();
|
||||
return fb;
|
||||
}
|
||||
|
||||
} // namespace bwe
|
||||
} // namespace testing
|
||||
} // namespace webrtc
|
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright (c) 2015 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#ifndef WEBRTC_MODULES_REMOTE_BITRATE_ESTIMATOR_TEST_ESTIMATORS_TCP_H_
|
||||
#define WEBRTC_MODULES_REMOTE_BITRATE_ESTIMATOR_TEST_ESTIMATORS_TCP_H_
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "webrtc/modules/remote_bitrate_estimator/test/bwe.h"
|
||||
|
||||
namespace webrtc {
|
||||
namespace testing {
|
||||
namespace bwe {
|
||||
class TcpBweReceiver : public BweReceiver {
|
||||
public:
|
||||
explicit TcpBweReceiver(int flow_id);
|
||||
virtual ~TcpBweReceiver();
|
||||
|
||||
void ReceivePacket(int64_t arrival_time_ms,
|
||||
const MediaPacket& media_packet) override;
|
||||
FeedbackPacket* GetFeedback(int64_t now_ms) override;
|
||||
|
||||
private:
|
||||
int64_t last_feedback_ms_;
|
||||
std::vector<uint16_t> acks_;
|
||||
};
|
||||
} // namespace bwe
|
||||
} // namespace testing
|
||||
} // namespace webrtc
|
||||
#endif // WEBRTC_MODULES_REMOTE_BITRATE_ESTIMATOR_TEST_ESTIMATORS_TCP_H_
|
@ -50,6 +50,10 @@ class Packet {
|
||||
class MediaPacket : public Packet {
|
||||
public:
|
||||
MediaPacket();
|
||||
MediaPacket(int flow_id,
|
||||
int64_t send_time_us,
|
||||
size_t payload_size,
|
||||
uint16_t sequence_number);
|
||||
MediaPacket(int flow_id,
|
||||
int64_t send_time_us,
|
||||
size_t payload_size,
|
||||
@ -135,6 +139,20 @@ class NadaFeedback : public FeedbackPacket {
|
||||
float derivative_;
|
||||
};
|
||||
|
||||
class TcpFeedback : public FeedbackPacket {
|
||||
public:
|
||||
TcpFeedback(int flow_id,
|
||||
int64_t send_time_us,
|
||||
const std::vector<uint16_t>& acked_packets)
|
||||
: FeedbackPacket(flow_id, send_time_us), acked_packets_(acked_packets) {}
|
||||
virtual ~TcpFeedback() {}
|
||||
|
||||
const std::vector<uint16_t>& acked_packets() const { return acked_packets_; }
|
||||
|
||||
private:
|
||||
const std::vector<uint16_t> acked_packets_;
|
||||
};
|
||||
|
||||
typedef std::list<Packet*> Packets;
|
||||
typedef std::list<Packet*>::iterator PacketsIt;
|
||||
typedef std::list<Packet*>::const_iterator PacketsConstIt;
|
||||
|
@ -14,18 +14,38 @@
|
||||
#include <list>
|
||||
#include <sstream>
|
||||
|
||||
#include "webrtc/base/checks.h"
|
||||
#include "webrtc/modules/interface/module_common_types.h"
|
||||
#include "webrtc/modules/remote_bitrate_estimator/test/bwe.h"
|
||||
|
||||
namespace webrtc {
|
||||
namespace testing {
|
||||
namespace bwe {
|
||||
|
||||
PacketSender::PacketSender(PacketProcessorListener* listener,
|
||||
VideoSource* source,
|
||||
BandwidthEstimatorType estimator_type)
|
||||
: PacketProcessor(listener, source->flow_id(), kSender),
|
||||
std::list<FeedbackPacket*> GetFeedbackPackets(Packets* in_out,
|
||||
int64_t end_time_ms,
|
||||
int flow_id) {
|
||||
std::list<FeedbackPacket*> fb_packets;
|
||||
for (auto it = in_out->begin(); it != in_out->end();) {
|
||||
if ((*it)->send_time_us() > 1000 * end_time_ms)
|
||||
break;
|
||||
if ((*it)->GetPacketType() == Packet::kFeedback &&
|
||||
flow_id == (*it)->flow_id()) {
|
||||
fb_packets.push_back(static_cast<FeedbackPacket*>(*it));
|
||||
it = in_out->erase(it);
|
||||
} else {
|
||||
++it;
|
||||
}
|
||||
}
|
||||
return fb_packets;
|
||||
}
|
||||
|
||||
VideoSender::VideoSender(PacketProcessorListener* listener,
|
||||
VideoSource* source,
|
||||
BandwidthEstimatorType estimator_type)
|
||||
: PacketSender(listener, source->flow_id()),
|
||||
// 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 VideoSender and the Source must be aligned.
|
||||
// We assume that both start at time 0.
|
||||
clock_(0),
|
||||
source_(source),
|
||||
@ -36,17 +56,17 @@ PacketSender::PacketSender(PacketProcessorListener* listener,
|
||||
modules_.push_back(bwe_.get());
|
||||
}
|
||||
|
||||
PacketSender::~PacketSender() {
|
||||
VideoSender::~VideoSender() {
|
||||
}
|
||||
|
||||
void PacketSender::RunFor(int64_t time_ms, Packets* in_out) {
|
||||
void VideoSender::RunFor(int64_t time_ms, Packets* in_out) {
|
||||
int64_t now_ms = clock_.TimeInMilliseconds();
|
||||
std::list<FeedbackPacket*> feedbacks =
|
||||
GetFeedbackPackets(in_out, now_ms + time_ms);
|
||||
GetFeedbackPackets(in_out, now_ms + time_ms, source_->flow_id());
|
||||
ProcessFeedbackAndGeneratePackets(time_ms, &feedbacks, in_out);
|
||||
}
|
||||
|
||||
void PacketSender::ProcessFeedbackAndGeneratePackets(
|
||||
void VideoSender::ProcessFeedbackAndGeneratePackets(
|
||||
int64_t time_ms,
|
||||
std::list<FeedbackPacket*>* feedbacks,
|
||||
Packets* packets) {
|
||||
@ -76,42 +96,20 @@ void PacketSender::ProcessFeedbackAndGeneratePackets(
|
||||
assert(feedbacks->empty());
|
||||
}
|
||||
|
||||
int PacketSender::GetFeedbackIntervalMs() const {
|
||||
int VideoSender::GetFeedbackIntervalMs() const {
|
||||
return bwe_->GetFeedbackIntervalMs();
|
||||
}
|
||||
|
||||
std::list<FeedbackPacket*> PacketSender::GetFeedbackPackets(
|
||||
Packets* in_out,
|
||||
int64_t end_time_ms) {
|
||||
std::list<FeedbackPacket*> fb_packets;
|
||||
for (auto it = in_out->begin(); it != in_out->end();) {
|
||||
if ((*it)->send_time_us() > 1000 * end_time_ms)
|
||||
break;
|
||||
if ((*it)->GetPacketType() == Packet::kFeedback &&
|
||||
source()->flow_id() == (*it)->flow_id()) {
|
||||
fb_packets.push_back(static_cast<FeedbackPacket*>(*it));
|
||||
it = in_out->erase(it);
|
||||
} else {
|
||||
++it;
|
||||
}
|
||||
}
|
||||
return fb_packets;
|
||||
}
|
||||
|
||||
void PacketSender::OnNetworkChanged(uint32_t target_bitrate_bps,
|
||||
uint8_t fraction_lost,
|
||||
int64_t rtt) {
|
||||
void VideoSender::OnNetworkChanged(uint32_t target_bitrate_bps,
|
||||
uint8_t fraction_lost,
|
||||
int64_t rtt) {
|
||||
source_->SetBitrateBps(target_bitrate_bps);
|
||||
std::stringstream ss;
|
||||
ss << "SendEstimate_" << source_->flow_id() << "#1";
|
||||
BWE_TEST_LOGGING_PLOT(0, ss.str(), clock_.TimeInMilliseconds(),
|
||||
target_bitrate_bps / 1000);
|
||||
}
|
||||
|
||||
PacedVideoSender::PacedVideoSender(PacketProcessorListener* listener,
|
||||
VideoSource* source,
|
||||
BandwidthEstimatorType estimator)
|
||||
: PacketSender(listener, source, estimator),
|
||||
: VideoSender(listener, source, estimator),
|
||||
pacer_(&clock_,
|
||||
this,
|
||||
source->bits_per_second() / 1000,
|
||||
@ -132,7 +130,7 @@ void PacedVideoSender::RunFor(int64_t time_ms, Packets* in_out) {
|
||||
int64_t end_time_ms = clock_.TimeInMilliseconds() + time_ms;
|
||||
// Run process periodically to allow the packets to be paced out.
|
||||
std::list<FeedbackPacket*> feedbacks =
|
||||
GetFeedbackPackets(in_out, end_time_ms);
|
||||
GetFeedbackPackets(in_out, end_time_ms, source_->flow_id());
|
||||
int64_t last_run_time_ms = -1;
|
||||
BWE_TEST_LOGGING_CONTEXT("Sender");
|
||||
BWE_TEST_LOGGING_CONTEXT(source_->flow_id());
|
||||
@ -260,11 +258,79 @@ size_t PacedVideoSender::TimeToSendPadding(size_t bytes) {
|
||||
void PacedVideoSender::OnNetworkChanged(uint32_t target_bitrate_bps,
|
||||
uint8_t fraction_lost,
|
||||
int64_t rtt) {
|
||||
PacketSender::OnNetworkChanged(target_bitrate_bps, fraction_lost, rtt);
|
||||
VideoSender::OnNetworkChanged(target_bitrate_bps, fraction_lost, rtt);
|
||||
pacer_.UpdateBitrate(
|
||||
target_bitrate_bps / 1000,
|
||||
PacedSender::kDefaultPaceMultiplier * target_bitrate_bps / 1000, 0);
|
||||
}
|
||||
|
||||
void TcpSender::RunFor(int64_t time_ms, Packets* in_out) {
|
||||
BWE_TEST_LOGGING_CONTEXT("Sender");
|
||||
BWE_TEST_LOGGING_CONTEXT(*flow_ids().begin());
|
||||
std::list<FeedbackPacket*> feedbacks =
|
||||
GetFeedbackPackets(in_out, now_ms_ + time_ms, *flow_ids().begin());
|
||||
// The number of packets which are sent in during time_ms depends on the
|
||||
// number of packets in_flight_ and the max number of packets in flight
|
||||
// (cwnd_). Therefore SendPackets() isn't directly dependent on time_ms.
|
||||
for (FeedbackPacket* fb : feedbacks) {
|
||||
UpdateCongestionControl(fb);
|
||||
SendPackets(in_out);
|
||||
}
|
||||
SendPackets(in_out);
|
||||
now_ms_ += time_ms;
|
||||
}
|
||||
|
||||
void TcpSender::SendPackets(Packets* in_out) {
|
||||
int cwnd = ceil(cwnd_);
|
||||
int packets_to_send = std::max(cwnd - in_flight_, 0);
|
||||
if (packets_to_send > 0) {
|
||||
Packets generated = GeneratePackets(packets_to_send);
|
||||
in_flight_ += generated.size();
|
||||
in_out->merge(generated, DereferencingComparator<Packet>);
|
||||
}
|
||||
}
|
||||
|
||||
void TcpSender::UpdateCongestionControl(const FeedbackPacket* fb) {
|
||||
const TcpFeedback* tcp_fb = static_cast<const TcpFeedback*>(fb);
|
||||
DCHECK(!tcp_fb->acked_packets().empty());
|
||||
ack_received_ = true;
|
||||
|
||||
in_flight_ -= tcp_fb->acked_packets().size();
|
||||
DCHECK_GE(in_flight_, 0);
|
||||
|
||||
if (LossEvent(tcp_fb->acked_packets())) {
|
||||
cwnd_ /= 2.0f;
|
||||
in_slow_start_ = false;
|
||||
} else if (in_slow_start_) {
|
||||
cwnd_ += tcp_fb->acked_packets().size();
|
||||
} else {
|
||||
cwnd_ += 1.0f / cwnd_;
|
||||
}
|
||||
|
||||
last_acked_seq_num_ =
|
||||
LatestSequenceNumber(tcp_fb->acked_packets().back(), last_acked_seq_num_);
|
||||
}
|
||||
|
||||
bool TcpSender::LossEvent(const std::vector<uint16_t>& acked_packets) {
|
||||
int missing = 0;
|
||||
for (int i = last_acked_seq_num_ + 1; i <= acked_packets.back(); ++i) {
|
||||
if (std::find(acked_packets.begin(), acked_packets.end(), i) ==
|
||||
acked_packets.end()) {
|
||||
++missing;
|
||||
}
|
||||
}
|
||||
in_flight_ -= missing;
|
||||
return missing > 0;
|
||||
}
|
||||
|
||||
Packets TcpSender::GeneratePackets(size_t num_packets) {
|
||||
Packets generated;
|
||||
for (size_t i = 0; i < num_packets; ++i) {
|
||||
generated.push_back(new MediaPacket(*flow_ids().begin(), 1000 * now_ms_,
|
||||
1200, next_sequence_number_++));
|
||||
}
|
||||
return generated;
|
||||
}
|
||||
} // namespace bwe
|
||||
} // namespace testing
|
||||
} // namespace webrtc
|
||||
|
@ -24,19 +24,27 @@ namespace webrtc {
|
||||
namespace testing {
|
||||
namespace bwe {
|
||||
|
||||
class PacketSender : public PacketProcessor, public BitrateObserver {
|
||||
class PacketSender : public PacketProcessor {
|
||||
public:
|
||||
PacketSender(PacketProcessorListener* listener,
|
||||
VideoSource* source,
|
||||
BandwidthEstimatorType estimator);
|
||||
virtual ~PacketSender();
|
||||
|
||||
PacketSender(PacketProcessorListener* listener, int flow_id)
|
||||
: PacketProcessor(listener, flow_id, kSender) {}
|
||||
virtual ~PacketSender() {}
|
||||
// Call GiveFeedback() with the returned interval in milliseconds, provided
|
||||
// there is a new estimate available.
|
||||
// Note that changing the feedback interval affects the timing of when the
|
||||
// output of the estimators is sampled and therefore the baseline files may
|
||||
// have to be regenerated.
|
||||
virtual int GetFeedbackIntervalMs() const;
|
||||
virtual int GetFeedbackIntervalMs() const = 0;
|
||||
};
|
||||
|
||||
class VideoSender : public PacketSender, public BitrateObserver {
|
||||
public:
|
||||
VideoSender(PacketProcessorListener* listener,
|
||||
VideoSource* source,
|
||||
BandwidthEstimatorType estimator);
|
||||
virtual ~VideoSender();
|
||||
|
||||
int GetFeedbackIntervalMs() const override;
|
||||
void RunFor(int64_t time_ms, Packets* in_out) override;
|
||||
|
||||
virtual VideoSource* source() const { return source_; }
|
||||
@ -50,8 +58,6 @@ class PacketSender : public PacketProcessor, public BitrateObserver {
|
||||
void ProcessFeedbackAndGeneratePackets(int64_t time_ms,
|
||||
std::list<FeedbackPacket*>* feedbacks,
|
||||
Packets* generated);
|
||||
std::list<FeedbackPacket*> GetFeedbackPackets(Packets* in_out,
|
||||
int64_t end_time_ms);
|
||||
|
||||
SimulatedClock clock_;
|
||||
VideoSource* source_;
|
||||
@ -60,10 +66,10 @@ class PacketSender : public PacketProcessor, public BitrateObserver {
|
||||
std::list<Module*> modules_;
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(PacketSender);
|
||||
DISALLOW_COPY_AND_ASSIGN(VideoSender);
|
||||
};
|
||||
|
||||
class PacedVideoSender : public PacketSender, public PacedSender::Callback {
|
||||
class PacedVideoSender : public VideoSender, public PacedSender::Callback {
|
||||
public:
|
||||
PacedVideoSender(PacketProcessorListener* listener,
|
||||
VideoSource* source,
|
||||
@ -95,6 +101,36 @@ class PacedVideoSender : public PacketSender, public PacedSender::Callback {
|
||||
|
||||
DISALLOW_IMPLICIT_CONSTRUCTORS(PacedVideoSender);
|
||||
};
|
||||
|
||||
class TcpSender : public PacketSender {
|
||||
public:
|
||||
TcpSender(PacketProcessorListener* listener, int flow_id)
|
||||
: PacketSender(listener, flow_id),
|
||||
now_ms_(0),
|
||||
in_slow_start_(false),
|
||||
cwnd_(1),
|
||||
in_flight_(0),
|
||||
ack_received_(false),
|
||||
last_acked_seq_num_(0),
|
||||
next_sequence_number_(0) {}
|
||||
|
||||
void RunFor(int64_t time_ms, Packets* in_out) override;
|
||||
int GetFeedbackIntervalMs() const override { return 10; }
|
||||
|
||||
private:
|
||||
void SendPackets(Packets* in_out);
|
||||
void UpdateCongestionControl(const FeedbackPacket* fb);
|
||||
bool LossEvent(const std::vector<uint16_t>& acked_packets);
|
||||
Packets GeneratePackets(size_t num_packets);
|
||||
|
||||
int64_t now_ms_;
|
||||
bool in_slow_start_;
|
||||
float cwnd_;
|
||||
int in_flight_;
|
||||
bool ack_received_;
|
||||
uint16_t last_acked_seq_num_;
|
||||
uint16_t next_sequence_number_;
|
||||
};
|
||||
} // namespace bwe
|
||||
} // namespace testing
|
||||
} // namespace webrtc
|
||||
|
Loading…
Reference in New Issue
Block a user