diff --git a/webrtc/call/rtc_event_log_unittest.cc b/webrtc/call/rtc_event_log_unittest.cc index ff5abad99d..973e5424eb 100644 --- a/webrtc/call/rtc_event_log_unittest.cc +++ b/webrtc/call/rtc_event_log_unittest.cc @@ -10,7 +10,6 @@ #ifdef ENABLE_RTC_EVENT_LOG -#include #include #include @@ -23,6 +22,7 @@ #include "webrtc/call/rtc_event_log.h" #include "webrtc/modules/rtp_rtcp/source/rtp_sender.h" #include "webrtc/system_wrappers/include/clock.h" +#include "webrtc/test/random.h" #include "webrtc/test/test_suite.h" #include "webrtc/test/testsupport/fileutils.h" #include "webrtc/test/testsupport/gtest_disable.h" @@ -304,7 +304,8 @@ void VerifyLogStartEvent(const rtclog::Event& event) { size_t GenerateRtpPacket(uint32_t extensions_bitvector, uint32_t csrcs_count, uint8_t* packet, - size_t packet_size) { + size_t packet_size, + test::Random* prng) { RTC_CHECK_GE(packet_size, 16 + 4 * csrcs_count + 4 * kNumExtensions); Clock* clock = Clock::GetRealTimeClock(); @@ -321,12 +322,12 @@ size_t GenerateRtpPacket(uint32_t extensions_bitvector, std::vector csrcs; for (unsigned i = 0; i < csrcs_count; i++) { - csrcs.push_back(rand()); + csrcs.push_back(prng->Rand()); } rtp_sender.SetCsrcs(csrcs); - rtp_sender.SetSSRC(rand()); - rtp_sender.SetStartTimestamp(rand(), true); - rtp_sender.SetSequenceNumber(rand()); + rtp_sender.SetSSRC(prng->Rand()); + rtp_sender.SetStartTimestamp(prng->Rand(), true); + rtp_sender.SetSequenceNumber(prng->Rand()); for (unsigned i = 0; i < kNumExtensions; i++) { if (extensions_bitvector & (1u << i)) { @@ -334,76 +335,80 @@ size_t GenerateRtpPacket(uint32_t extensions_bitvector, } } - int8_t payload_type = rand() % 128; - bool marker_bit = (rand() % 2 == 1); - uint32_t capture_timestamp = rand(); - int64_t capture_time_ms = rand(); - bool timestamp_provided = (rand() % 2 == 1); - bool inc_sequence_number = (rand() % 2 == 1); + int8_t payload_type = prng->Rand(0, 127); + bool marker_bit = prng->Rand(); + uint32_t capture_timestamp = prng->Rand(); + int64_t capture_time_ms = prng->Rand(); + bool timestamp_provided = prng->Rand(); + bool inc_sequence_number = prng->Rand(); size_t header_size = rtp_sender.BuildRTPheader( packet, payload_type, marker_bit, capture_timestamp, capture_time_ms, timestamp_provided, inc_sequence_number); for (size_t i = header_size; i < packet_size; i++) { - packet[i] = rand(); + packet[i] = prng->Rand(); } return header_size; } -void GenerateRtcpPacket(uint8_t* packet, size_t packet_size) { +void GenerateRtcpPacket(uint8_t* packet, + size_t packet_size, + test::Random* prng) { for (size_t i = 0; i < packet_size; i++) { - packet[i] = rand(); + packet[i] = prng->Rand(); } } void GenerateVideoReceiveConfig(uint32_t extensions_bitvector, - VideoReceiveStream::Config* config) { + VideoReceiveStream::Config* config, + test::Random* prng) { // Create a map from a payload type to an encoder name. VideoReceiveStream::Decoder decoder; - decoder.payload_type = rand(); - decoder.payload_name = (rand() % 2 ? "VP8" : "H264"); + decoder.payload_type = prng->Rand(0, 127); + decoder.payload_name = (prng->Rand() ? "VP8" : "H264"); config->decoders.push_back(decoder); // Add SSRCs for the stream. - config->rtp.remote_ssrc = rand(); - config->rtp.local_ssrc = rand(); + config->rtp.remote_ssrc = prng->Rand(); + config->rtp.local_ssrc = prng->Rand(); // Add extensions and settings for RTCP. config->rtp.rtcp_mode = - rand() % 2 ? RtcpMode::kCompound : RtcpMode::kReducedSize; - config->rtp.rtcp_xr.receiver_reference_time_report = (rand() % 2 == 1); - config->rtp.remb = (rand() % 2 == 1); + prng->Rand() ? RtcpMode::kCompound : RtcpMode::kReducedSize; + config->rtp.rtcp_xr.receiver_reference_time_report = prng->Rand(); + config->rtp.remb = prng->Rand(); // Add a map from a payload type to a new ssrc and a new payload type for RTX. VideoReceiveStream::Config::Rtp::Rtx rtx_pair; - rtx_pair.ssrc = rand(); - rtx_pair.payload_type = rand(); - config->rtp.rtx.insert(std::make_pair(rand(), rtx_pair)); + rtx_pair.ssrc = prng->Rand(); + rtx_pair.payload_type = prng->Rand(0, 127); + config->rtp.rtx.insert(std::make_pair(prng->Rand(0, 127), rtx_pair)); // Add header extensions. for (unsigned i = 0; i < kNumExtensions; i++) { if (extensions_bitvector & (1u << i)) { config->rtp.extensions.push_back( - RtpExtension(kExtensionNames[i], rand())); + RtpExtension(kExtensionNames[i], prng->Rand())); } } } void GenerateVideoSendConfig(uint32_t extensions_bitvector, - VideoSendStream::Config* config) { + VideoSendStream::Config* config, + test::Random* prng) { // Create a map from a payload type to an encoder name. - config->encoder_settings.payload_type = rand(); - config->encoder_settings.payload_name = (rand() % 2 ? "VP8" : "H264"); + config->encoder_settings.payload_type = prng->Rand(0, 127); + config->encoder_settings.payload_name = (prng->Rand() ? "VP8" : "H264"); // Add SSRCs for the stream. - config->rtp.ssrcs.push_back(rand()); + config->rtp.ssrcs.push_back(prng->Rand()); // Add a map from a payload type to new ssrcs and a new payload type for RTX. - config->rtp.rtx.ssrcs.push_back(rand()); - config->rtp.rtx.payload_type = rand(); + config->rtp.rtx.ssrcs.push_back(prng->Rand()); + config->rtp.rtx.payload_type = prng->Rand(0, 127); // Add a CNAME. config->rtp.c_name = "some.user@some.host"; // Add header extensions. for (unsigned i = 0; i < kNumExtensions; i++) { if (extensions_bitvector & (1u << i)) { config->rtp.extensions.push_back( - RtpExtension(kExtensionNames[i], rand())); + RtpExtension(kExtensionNames[i], prng->Rand())); } } } @@ -429,33 +434,34 @@ void LogSessionAndReadBack(size_t rtp_count, VideoReceiveStream::Config receiver_config(nullptr); VideoSendStream::Config sender_config(nullptr); - srand(random_seed); + test::Random prng(random_seed); // Create rtp_count RTP packets containing random data. for (size_t i = 0; i < rtp_count; i++) { - size_t packet_size = 1000 + rand() % 64; + size_t packet_size = prng.Rand(1000, 1100); rtp_packets.push_back(rtc::Buffer(packet_size)); - size_t header_size = GenerateRtpPacket(extensions_bitvector, csrcs_count, - rtp_packets[i].data(), packet_size); + size_t header_size = + GenerateRtpPacket(extensions_bitvector, csrcs_count, + rtp_packets[i].data(), packet_size, &prng); rtp_header_sizes.push_back(header_size); } // Create rtcp_count RTCP packets containing random data. for (size_t i = 0; i < rtcp_count; i++) { - size_t packet_size = 1000 + rand() % 64; + size_t packet_size = prng.Rand(1000, 1100); rtcp_packets.push_back(rtc::Buffer(packet_size)); - GenerateRtcpPacket(rtcp_packets[i].data(), packet_size); + GenerateRtcpPacket(rtcp_packets[i].data(), packet_size, &prng); } // Create playout_count random SSRCs to use when logging AudioPlayout events. for (size_t i = 0; i < playout_count; i++) { - playout_ssrcs.push_back(static_cast(rand())); + playout_ssrcs.push_back(prng.Rand()); } // Create bwe_loss_count random bitrate updates for BwePacketLoss. for (size_t i = 0; i < bwe_loss_count; i++) { bwe_loss_updates.push_back(std::pair(rand(), rand())); } // Create configurations for the video streams. - GenerateVideoReceiveConfig(extensions_bitvector, &receiver_config); - GenerateVideoSendConfig(extensions_bitvector, &sender_config); + GenerateVideoReceiveConfig(extensions_bitvector, &receiver_config, &prng); + GenerateVideoSendConfig(extensions_bitvector, &sender_config, &prng); const int config_count = 2; // Find the name of the current test, in order to use it as a temporary @@ -586,7 +592,7 @@ TEST(RtcEventLogTest, LogSessionAndReadBack) { 1 + csrcs_count, // Number of BWE loss events. extensions, // Bit vector choosing extensions. csrcs_count, // Number of contributing sources. - rand()); + extensions + csrcs_count); // Random seed. } } } @@ -604,29 +610,30 @@ void DropOldEvents(uint32_t extensions_bitvector, VideoReceiveStream::Config receiver_config(nullptr); VideoSendStream::Config sender_config(nullptr); - srand(random_seed); + test::Random prng(random_seed); // Create two RTP packets containing random data. - size_t packet_size = 1000 + rand() % 64; + size_t packet_size = prng.Rand(1000, 1100); old_rtp_packet.SetSize(packet_size); GenerateRtpPacket(extensions_bitvector, csrcs_count, old_rtp_packet.data(), - packet_size); - packet_size = 1000 + rand() % 64; + packet_size, &prng); + packet_size = prng.Rand(1000, 1100); recent_rtp_packet.SetSize(packet_size); - size_t recent_header_size = GenerateRtpPacket( - extensions_bitvector, csrcs_count, recent_rtp_packet.data(), packet_size); + size_t recent_header_size = + GenerateRtpPacket(extensions_bitvector, csrcs_count, + recent_rtp_packet.data(), packet_size, &prng); // Create two RTCP packets containing random data. - packet_size = 1000 + rand() % 64; + packet_size = prng.Rand(1000, 1100); old_rtcp_packet.SetSize(packet_size); - GenerateRtcpPacket(old_rtcp_packet.data(), packet_size); - packet_size = 1000 + rand() % 64; + GenerateRtcpPacket(old_rtcp_packet.data(), packet_size, &prng); + packet_size = prng.Rand(1000, 1100); recent_rtcp_packet.SetSize(packet_size); - GenerateRtcpPacket(recent_rtcp_packet.data(), packet_size); + GenerateRtcpPacket(recent_rtcp_packet.data(), packet_size, &prng); // Create configurations for the video streams. - GenerateVideoReceiveConfig(extensions_bitvector, &receiver_config); - GenerateVideoSendConfig(extensions_bitvector, &sender_config); + GenerateVideoReceiveConfig(extensions_bitvector, &receiver_config, &prng); + GenerateVideoSendConfig(extensions_bitvector, &sender_config, &prng); // Find the name of the current test, in order to use it as a temporary // filename. diff --git a/webrtc/modules/remote_bitrate_estimator/bwe_simulations.cc b/webrtc/modules/remote_bitrate_estimator/bwe_simulations.cc index cb8d0db5c7..fb8de7cabc 100644 --- a/webrtc/modules/remote_bitrate_estimator/bwe_simulations.cc +++ b/webrtc/modules/remote_bitrate_estimator/bwe_simulations.cc @@ -283,9 +283,9 @@ TEST_P(BweSimulation, PacedSelfFairness50msTest) { const int64_t kAverageOffsetMs = 20 * 1000; const int kNumRmcatFlows = 4; int64_t offsets_ms[kNumRmcatFlows]; - offsets_ms[0] = random_.Rand(0, 2 * kAverageOffsetMs); + offsets_ms[0] = random_.Rand(2 * kAverageOffsetMs); for (int i = 1; i < kNumRmcatFlows; ++i) { - offsets_ms[i] = offsets_ms[i - 1] + random_.Rand(0, 2 * kAverageOffsetMs); + offsets_ms[i] = offsets_ms[i - 1] + random_.Rand(2 * kAverageOffsetMs); } RunFairnessTest(GetParam(), kNumRmcatFlows, 0, 1000, 3000, 50, 50, 0, offsets_ms); @@ -295,9 +295,9 @@ TEST_P(BweSimulation, PacedSelfFairness500msTest) { const int64_t kAverageOffsetMs = 20 * 1000; const int kNumRmcatFlows = 4; int64_t offsets_ms[kNumRmcatFlows]; - offsets_ms[0] = random_.Rand(0, 2 * kAverageOffsetMs); + offsets_ms[0] = random_.Rand(2 * kAverageOffsetMs); for (int i = 1; i < kNumRmcatFlows; ++i) { - offsets_ms[i] = offsets_ms[i - 1] + random_.Rand(0, 2 * kAverageOffsetMs); + offsets_ms[i] = offsets_ms[i - 1] + random_.Rand(2 * kAverageOffsetMs); } RunFairnessTest(GetParam(), kNumRmcatFlows, 0, 1000, 3000, 500, 50, 0, offsets_ms); @@ -307,28 +307,28 @@ TEST_P(BweSimulation, PacedSelfFairness1000msTest) { const int64_t kAverageOffsetMs = 20 * 1000; const int kNumRmcatFlows = 4; int64_t offsets_ms[kNumRmcatFlows]; - offsets_ms[0] = random_.Rand(0, 2 * kAverageOffsetMs); + offsets_ms[0] = random_.Rand(2 * kAverageOffsetMs); for (int i = 1; i < kNumRmcatFlows; ++i) { - offsets_ms[i] = offsets_ms[i - 1] + random_.Rand(0, 2 * kAverageOffsetMs); + offsets_ms[i] = offsets_ms[i - 1] + random_.Rand(2 * kAverageOffsetMs); } RunFairnessTest(GetParam(), 4, 0, 1000, 3000, 1000, 50, 0, offsets_ms); } TEST_P(BweSimulation, TcpFairness50msTest) { const int64_t kAverageOffsetMs = 20 * 1000; - int64_t offset_ms[] = {random_.Rand(0, 2 * kAverageOffsetMs), 0}; + int64_t offset_ms[] = {random_.Rand(2 * kAverageOffsetMs), 0}; RunFairnessTest(GetParam(), 1, 1, 1000, 2000, 50, 50, 0, offset_ms); } TEST_P(BweSimulation, TcpFairness500msTest) { const int64_t kAverageOffsetMs = 20 * 1000; - int64_t offset_ms[] = {random_.Rand(0, 2 * kAverageOffsetMs), 0}; + int64_t offset_ms[] = {random_.Rand(2 * kAverageOffsetMs), 0}; RunFairnessTest(GetParam(), 1, 1, 1000, 2000, 500, 50, 0, offset_ms); } TEST_P(BweSimulation, TcpFairness1000msTest) { const int kAverageOffsetMs = 20 * 1000; - int64_t offset_ms[] = {random_.Rand(0, 2 * kAverageOffsetMs), 0}; + int64_t offset_ms[] = {random_.Rand(2 * kAverageOffsetMs), 0}; RunFairnessTest(GetParam(), 1, 1, 1000, 2000, 1000, 50, 0, offset_ms); } diff --git a/webrtc/modules/remote_bitrate_estimator/test/bwe_test_framework.cc b/webrtc/modules/remote_bitrate_estimator/test/bwe_test_framework.cc index 4574d3d8a1..120f50166f 100644 --- a/webrtc/modules/remote_bitrate_estimator/test/bwe_test_framework.cc +++ b/webrtc/modules/remote_bitrate_estimator/test/bwe_test_framework.cc @@ -323,7 +323,7 @@ void LossFilter::SetLoss(float loss_percent) { void LossFilter::RunFor(int64_t /*time_ms*/, Packets* in_out) { assert(in_out); for (PacketsIt it = in_out->begin(); it != in_out->end(); ) { - if (random_.Rand() < loss_fraction_) { + if (random_.Rand() < loss_fraction_) { delete *it; it = in_out->erase(it); } else { @@ -459,7 +459,7 @@ void ReorderFilter::RunFor(int64_t /*time_ms*/, Packets* in_out) { PacketsIt last_it = in_out->begin(); PacketsIt it = last_it; while (++it != in_out->end()) { - if (random_.Rand() < reorder_fraction_) { + if (random_.Rand() < reorder_fraction_) { int64_t t1 = (*last_it)->send_time_us(); int64_t t2 = (*it)->send_time_us(); std::swap(*last_it, *it); diff --git a/webrtc/test/random.cc b/webrtc/test/random.cc index c4c405f6b8..0a82b8d72d 100644 --- a/webrtc/test/random.cc +++ b/webrtc/test/random.cc @@ -21,7 +21,23 @@ namespace test { Random::Random(uint32_t seed) : a_(0x531FDB97 ^ seed), b_(0x6420ECA8 + seed) { } -float Random::Rand() { +uint32_t Random::Rand(uint32_t t) { + // If b / 2^32 is uniform on [0,1), then b / 2^32 * (t+1) is uniform on + // the interval [0,t+1), so the integer part is uniform on [0,t]. + uint64_t result = b_ * (static_cast(t) + 1); + result >>= 32; + a_ ^= b_; + b_ += a_; + return result; +} + +uint32_t Random::Rand(uint32_t low, uint32_t high) { + RTC_DCHECK(low <= high); + return Rand(high - low) + low; +} + +template <> +float Random::Rand() { const double kScale = 1.0f / (static_cast(1) << 32); double result = kScale * b_; a_ ^= b_; @@ -29,10 +45,9 @@ float Random::Rand() { return static_cast(result); } -int Random::Rand(int low, int high) { - RTC_DCHECK(low <= high); - float uniform = Rand() * (high - low + 1) + low; - return static_cast(uniform); +template <> +bool Random::Rand() { + return Rand(0, 1) == 1; } int Random::Gaussian(int mean, int standard_deviation) { @@ -50,7 +65,7 @@ int Random::Gaussian(int mean, int standard_deviation) { } int Random::Exponential(float lambda) { - float uniform = Rand(); + float uniform = Rand(); return static_cast(-log(uniform) / lambda); } } // namespace test diff --git a/webrtc/test/random.h b/webrtc/test/random.h index 5cc54f2129..c7254a9b49 100644 --- a/webrtc/test/random.h +++ b/webrtc/test/random.h @@ -11,6 +11,8 @@ #ifndef WEBRTC_TEST_RANDOM_H_ #define WEBRTC_TEST_RANDOM_H_ +#include + #include "webrtc/typedefs.h" #include "webrtc/base/constructormagic.h" @@ -22,11 +24,22 @@ class Random { public: explicit Random(uint32_t seed); - // Return pseudo-random number in the interval [0.0, 1.0). - float Rand(); + // Return pseudo-random integer of the specified type. + template + T Rand() { + static_assert(std::numeric_limits::is_integer && + std::numeric_limits::radix == 2 && + std::numeric_limits::digits <= 32, + "Rand is only supported for built-in integer types that are " + "32 bits or smaller."); + return static_cast(Rand(std::numeric_limits::max())); + } - // Return pseudo-random number mapped to the interval [low, high]. - int Rand(int low, int high); + // Uniformly distributed pseudo-random number in the interval [0, t]. + uint32_t Rand(uint32_t t); + + // Uniformly distributed pseudo-random number in the interval [low, high]. + uint32_t Rand(uint32_t low, uint32_t high); // Normal Distribution. int Gaussian(int mean, int standard_deviation); @@ -43,6 +56,15 @@ class Random { RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(Random); }; + +// Return pseudo-random number in the interval [0.0, 1.0). +template <> +float Random::Rand(); + +// Return pseudo-random boolean value. +template <> +bool Random::Rand(); + } // namespace test } // namespace webrtc