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
This commit is contained in:
stefan@webrtc.org 2014-07-31 12:30:18 +00:00
parent d9843da9ee
commit bfe6e08195
3 changed files with 59 additions and 2 deletions

View File

@ -33,6 +33,11 @@ static int GaussianRandom(int mean_delay_ms, int standard_deviation_ms) {
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 @@ void FakeNetworkPipe::Process() {
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,

View File

@ -47,7 +47,7 @@ class FakeNetworkPipe {
int delay_standard_deviation_ms;
// Link capacity in kbps.
int link_capacity_kbps;
// Random packet loss. Not implemented.
// Random packet loss.
int loss_percent;
};

View File

@ -51,18 +51,58 @@ size_t MaxBitrate() { return static_cast<size_t>(FLAGS_max_bitrate); }
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 @@ void Loopback() {
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 @@ void Loopback() {
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);