From 622c8bd0cc2d6051b070d63b08c7b575dba5d70b Mon Sep 17 00:00:00 2001 From: "mikhal@webrtc.org" Date: Tue, 18 Dec 2012 17:21:51 +0000 Subject: [PATCH] ViE autotest: Adding loss models to the external transport Review URL: https://webrtc-codereview.appspot.com/1000004 git-svn-id: http://webrtc.googlecode.com/svn/trunk@3309 4adac7df-926f-26a2-2b94-8c16560cd09d --- .../automated/vie_video_verification_test.cc | 20 +++++- .../include/tb_external_transport.h | 11 ++++ .../testbed/tb_external_transport.cc | 62 +++++++++++++++++-- 3 files changed, 86 insertions(+), 7 deletions(-) diff --git a/webrtc/video_engine/test/auto_test/automated/vie_video_verification_test.cc b/webrtc/video_engine/test/auto_test/automated/vie_video_verification_test.cc index 23e56a9fba..829828a9a6 100644 --- a/webrtc/video_engine/test/auto_test/automated/vie_video_verification_test.cc +++ b/webrtc/video_engine/test/auto_test/automated/vie_video_verification_test.cc @@ -125,7 +125,10 @@ class ParameterizedFullStackTest : public ViEVideoVerificationTest, void SetUp() { int i = 0; + // Uniform loss => Setting burst length to -1. + parameter_table_[i].network.loss_model = kUniformLoss; parameter_table_[i].network.packet_loss_rate = 0; + parameter_table_[i].network.burst_length = -1; parameter_table_[i].network.mean_one_way_delay = 0; parameter_table_[i].network.std_dev_one_way_delay = 0; parameter_table_[i].bitrate = 300; @@ -133,7 +136,9 @@ class ParameterizedFullStackTest : public ViEVideoVerificationTest, parameter_table_[i].avg_ssim_threshold = 0.96; parameter_table_[i].test_label = "net delay (0, 0), plr 0"; ++i; + parameter_table_[i].network.loss_model = kUniformLoss; parameter_table_[i].network.packet_loss_rate = 5; + parameter_table_[i].network.burst_length = -1; parameter_table_[i].network.mean_one_way_delay = 50; parameter_table_[i].network.std_dev_one_way_delay = 5; parameter_table_[i].bitrate = 300; @@ -141,7 +146,19 @@ class ParameterizedFullStackTest : public ViEVideoVerificationTest, parameter_table_[i].avg_ssim_threshold = 0.96; parameter_table_[i].test_label = "net delay (50, 5), plr 5"; ++i; + parameter_table_[i].network.loss_model = kUniformLoss; parameter_table_[i].network.packet_loss_rate = 0; + parameter_table_[i].network.burst_length = -1; + parameter_table_[i].network.mean_one_way_delay = 100; + parameter_table_[i].network.std_dev_one_way_delay = 10; + parameter_table_[i].bitrate = 300; + parameter_table_[i].avg_psnr_threshold = 35; + parameter_table_[i].avg_ssim_threshold = 0.96; + parameter_table_[i].test_label = "net delay (100, 10), plr 0"; + ++i; + parameter_table_[i].network.loss_model = kGilbertElliotLoss; + parameter_table_[i].network.packet_loss_rate = 5; + parameter_table_[i].network.burst_length = 3; parameter_table_[i].network.mean_one_way_delay = 100; parameter_table_[i].network.std_dev_one_way_delay = 10; parameter_table_[i].bitrate = 300; @@ -150,7 +167,7 @@ class ParameterizedFullStackTest : public ViEVideoVerificationTest, parameter_table_[i].test_label = "net delay (100, 10), plr 0"; } - TestParameters parameter_table_[3]; + TestParameters parameter_table_[4]; }; TEST_F(ViEVideoVerificationTest, RunsBaseStandardTestWithoutErrors) { @@ -207,6 +224,7 @@ TEST_P(ParameterizedFullStackTest, RunsFullStackWithoutErrors) { // frames every now and then. const int kBitRateKbps = parameter_table_[GetParam()].bitrate; const NetworkParameters network = parameter_table_[GetParam()].network; + // TODO(mikhal): Resolution and file name should be in the parameter list. int width = 352; int height = 288; ViETest::Log("Bit rate : %5d kbps", kBitRateKbps); diff --git a/webrtc/video_engine/test/libvietest/include/tb_external_transport.h b/webrtc/video_engine/test/libvietest/include/tb_external_transport.h index e27e9e37e8..1724e64c37 100644 --- a/webrtc/video_engine/test/libvietest/include/tb_external_transport.h +++ b/webrtc/video_engine/test/libvietest/include/tb_external_transport.h @@ -28,10 +28,17 @@ class ThreadWrapper; class ViENetwork; } +enum RandomLossModel { + kNoLoss, + kUniformLoss, + kGilbertElliotLoss +}; struct NetworkParameters { int packet_loss_rate; + int burst_length; // Only applicable for kGilbertElliotLoss. int mean_one_way_delay; int std_dev_one_way_delay; + RandomLossModel loss_model; }; // Allows to subscribe for callback when a frame is started being sent. @@ -109,7 +116,10 @@ protected: static bool ViEExternalTransportRun(void* object); bool ViEExternalTransportProcess(); private: + // TODO(mikhal): Break these out to classes. static int GaussianRandom(int mean_ms, int standard_deviation_ms); + bool UniformLoss(int loss_rate); + bool GilbertElliotLoss(int loss_rate, int burst_length); WebRtc_Word64 NowMs(); enum @@ -169,6 +179,7 @@ private: WebRtc_UWord32 _lastSendRTPTimestamp; WebRtc_UWord32 _lastReceiveRTPTimestamp; int64_t last_receive_time_; + bool previous_drop_; }; #endif // WEBRTC_VIDEO_ENGINE_TEST_AUTOTEST_INTERFACE_TB_EXTERNAL_TRANSPORT_H_ diff --git a/webrtc/video_engine/test/libvietest/testbed/tb_external_transport.cc b/webrtc/video_engine/test/libvietest/testbed/tb_external_transport.cc index 48e11498b0..25dbbe6868 100644 --- a/webrtc/video_engine/test/libvietest/testbed/tb_external_transport.cc +++ b/webrtc/video_engine/test/libvietest/testbed/tb_external_transport.cc @@ -73,7 +73,8 @@ TbExternalTransport::TbExternalTransport( _firstRTPTimestamp(0), _lastSendRTPTimestamp(0), _lastReceiveRTPTimestamp(0), - last_receive_time_(-1) + last_receive_time_(-1), + previous_drop_(false) { srand((int) webrtc::TickTime::MicrosecondTimestamp()); unsigned int tId = 0; @@ -190,11 +191,24 @@ int TbExternalTransport::SendPacket(int channel, const void *data, int len) _rtpCount++; _statCrit.Leave(); - // Packet loss. Never drop packets from the first RTP timestamp, i.e. the - // first frame being transmitted. - int dropThis = rand() % 100; - if (dropThis < network_parameters_.packet_loss_rate && - _firstRTPTimestamp != rtp_timestamp) + // Packet loss. + switch (network_parameters_.loss_model) + { + case (kNoLoss): + previous_drop_ = false; + break; + case (kUniformLoss): + previous_drop_ = UniformLoss(network_parameters_.packet_loss_rate); + break; + case (kGilbertElliotLoss): + previous_drop_ = GilbertElliotLoss( + network_parameters_.packet_loss_rate, + network_parameters_.burst_length); + break; + } + // Never drop packets from the first RTP timestamp (first frame) + // transmitted. + if (previous_drop_ && _firstRTPTimestamp != rtp_timestamp) { _statCrit.Enter(); _dropCount++; @@ -501,6 +515,42 @@ WebRtc_Word64 TbExternalTransport::NowMs() return webrtc::TickTime::MillisecondTimestamp(); } +bool TbExternalTransport::UniformLoss(int loss_rate) { + int dropThis = rand() % 100; + return (dropThis < loss_rate); +} + +bool TbExternalTransport::GilbertElliotLoss(int loss_rate, int burst_length) { + // Simulate bursty channel (Gilbert model) + // (1st order) Markov chain model with memory of the previous/last + // packet state (loss or received) + + // 0 = received state + // 1 = loss state + + // probTrans10: if previous packet is lost, prob. to -> received state + // probTrans11: if previous packet is lost, prob. to -> loss state + + // probTrans01: if previous packet is received, prob. to -> loss state + // probTrans00: if previous packet is received, prob. to -> received + + // Map the two channel parameters (average loss rate and burst length) + // to the transition probabilities: + double probTrans10 = 100 * (1.0 / burst_length); + double probTrans11 = (100.0 - probTrans10); + double probTrans01 = (probTrans10 * ( loss_rate / (100.0 - loss_rate))); + + // Note: Random loss (Bernoulli) model is a special case where: + // burstLength = 100.0 / (100.0 - _lossPct) (i.e., p10 + p01 = 100) + + if (previous_drop_) { + // Previous packet was not received. + return UniformLoss(probTrans11); + } else { + return UniformLoss(probTrans01); + } +} + #define PI 3.14159265 int TbExternalTransport::GaussianRandom(int mean_ms, int standard_deviation_ms) {