Add simulation of network effects to video_loopback tool.
Also add support for uniform random packet loss to the fake network pipe.
R=pbos@webrtc.org
Review URL: https://webrtc-codereview.appspot.com/14039004
git-svn-id: http://webrtc.googlecode.com/svn/trunk@6803 4adac7df-926f-26a2-2b94-8c16560cd09d
diff --git a/webrtc/test/fake_network_pipe.cc b/webrtc/test/fake_network_pipe.cc
index 06bf062..c88205b 100644
--- a/webrtc/test/fake_network_pipe.cc
+++ b/webrtc/test/fake_network_pipe.cc
@@ -33,6 +33,11 @@
sqrt(-2 * log(uniform1)) * cos(2 * kPi * uniform2));
}
+static bool UniformLoss(int loss_percent) {
+ int outcome = rand() % 100;
+ return outcome < loss_percent;
+}
+
class NetworkPacket {
public:
NetworkPacket(const uint8_t* data, size_t length, int64_t send_time,
@@ -159,6 +164,12 @@
NetworkPacket* packet = capacity_link_.front();
capacity_link_.pop();
+ // Packets are randomly dropped after being affected by the bottleneck.
+ if (UniformLoss(config_.loss_percent)) {
+ delete packet;
+ continue;
+ }
+
// Add extra delay and jitter, but make sure the arrival time is not
// earlier than the last packet in the queue.
int extra_delay = GaussianRandom(config_.queue_delay_ms,
diff --git a/webrtc/test/fake_network_pipe.h b/webrtc/test/fake_network_pipe.h
index c741501..a9ca760 100644
--- a/webrtc/test/fake_network_pipe.h
+++ b/webrtc/test/fake_network_pipe.h
@@ -47,7 +47,7 @@
int delay_standard_deviation_ms;
// Link capacity in kbps.
int link_capacity_kbps;
- // Random packet loss. Not implemented.
+ // Random packet loss.
int loss_percent;
};
diff --git a/webrtc/video/loopback.cc b/webrtc/video/loopback.cc
index 614ef47..4ec7388 100644
--- a/webrtc/video/loopback.cc
+++ b/webrtc/video/loopback.cc
@@ -51,18 +51,58 @@
DEFINE_string(codec, "VP8", "Video codec to use.");
std::string Codec() { return static_cast<std::string>(FLAGS_codec); }
+
+DEFINE_int32(loss_percent, 0, "Percentage of packets randomly lost.");
+int LossPercent() {
+ return static_cast<int>(FLAGS_loss_percent);
+}
+
+DEFINE_int32(link_capacity,
+ 0,
+ "Capacity (kbps) of the fake link. 0 means infinite.");
+int LinkCapacity() {
+ return static_cast<int>(FLAGS_link_capacity);
+}
+
+DEFINE_int32(queue_size, 0, "Size of the bottleneck link queue in packets.");
+int QueueSize() {
+ return static_cast<int>(FLAGS_queue_size);
+}
+
+DEFINE_int32(avg_propagation_delay_ms,
+ 0,
+ "Average link propagation delay in ms.");
+int AvgPropagationDelayMs() {
+ return static_cast<int>(FLAGS_avg_propagation_delay_ms);
+}
+
+DEFINE_int32(std_propagation_delay_ms,
+ 0,
+ "Link propagation delay standard deviation in ms.");
+int StdPropagationDelayMs() {
+ return static_cast<int>(FLAGS_std_propagation_delay_ms);
+}
} // namespace flags
static const uint32_t kSendSsrc = 0x654321;
+static const uint32_t kSendRtxSsrc = 0x654322;
static const uint32_t kReceiverLocalSsrc = 0x123456;
+static const uint8_t kRtxPayloadType = 96;
+
void Loopback() {
scoped_ptr<test::VideoRenderer> local_preview(test::VideoRenderer::Create(
"Local Preview", flags::Width(), flags::Height()));
scoped_ptr<test::VideoRenderer> loopback_video(test::VideoRenderer::Create(
"Loopback Video", flags::Width(), flags::Height()));
- test::DirectTransport transport;
+ FakeNetworkPipe::Config pipe_config;
+ pipe_config.loss_percent = flags::LossPercent();
+ pipe_config.link_capacity_kbps = flags::LinkCapacity();
+ pipe_config.queue_length_packets = flags::QueueSize();
+ pipe_config.queue_delay_ms = flags::AvgPropagationDelayMs();
+ pipe_config.delay_standard_deviation_ms = flags::StdPropagationDelayMs();
+ test::DirectTransport transport(pipe_config);
Call::Config call_config(&transport);
call_config.start_bitrate_bps =
static_cast<int>(flags::StartBitrate()) * 1000;
@@ -73,6 +113,9 @@
VideoSendStream::Config send_config;
send_config.rtp.ssrcs.push_back(kSendSsrc);
+ send_config.rtp.rtx.ssrcs.push_back(kSendRtxSsrc);
+ send_config.rtp.rtx.payload_type = kRtxPayloadType;
+ send_config.rtp.nack.rtp_history_ms = 1000;
send_config.local_renderer = local_preview.get();
scoped_ptr<VideoEncoder> encoder;
@@ -111,6 +154,9 @@
VideoReceiveStream::Config receive_config;
receive_config.rtp.remote_ssrc = send_config.rtp.ssrcs[0];
receive_config.rtp.local_ssrc = kReceiverLocalSsrc;
+ receive_config.rtp.nack.rtp_history_ms = 1000;
+ receive_config.rtp.rtx[kRtxPayloadType].ssrc = kSendRtxSsrc;
+ receive_config.rtp.rtx[kRtxPayloadType].payload_type = kRtxPayloadType;
receive_config.renderer = loopback_video.get();
VideoCodec codec =
test::CreateDecoderVideoCodec(send_config.encoder_settings);