/* * Copyright (c) 2012 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_REMOTE_BITRATE_ESTIMATOR_UNITTEST_HELPER_H_ #define WEBRTC_MODULES_REMOTE_BITRATE_ESTIMATOR_REMOTE_BITRATE_ESTIMATOR_UNITTEST_HELPER_H_ #include #include #include #include #include "testing/gtest/include/gtest/gtest.h" #include "webrtc/base/constructormagic.h" #include "webrtc/base/scoped_ptr.h" #include "webrtc/modules/remote_bitrate_estimator/include/remote_bitrate_estimator.h" #include "webrtc/system_wrappers/include/clock.h" namespace webrtc { namespace testing { class TestBitrateObserver : public RemoteBitrateObserver { public: TestBitrateObserver() : updated_(false), latest_bitrate_(0) {} virtual ~TestBitrateObserver() {} void OnReceiveBitrateChanged(const std::vector& ssrcs, unsigned int bitrate) override; void Reset() { updated_ = false; } bool updated() const { return updated_; } unsigned int latest_bitrate() const { return latest_bitrate_; } private: bool updated_; unsigned int latest_bitrate_; }; class RtpStream { public: struct RtpPacket { int64_t send_time; int64_t arrival_time; uint32_t rtp_timestamp; size_t size; unsigned int ssrc; }; struct RtcpPacket { uint32_t ntp_secs; uint32_t ntp_frac; uint32_t timestamp; unsigned int ssrc; }; typedef std::list PacketList; enum { kSendSideOffsetUs = 1000000 }; RtpStream(int fps, int bitrate_bps, unsigned int ssrc, unsigned int frequency, uint32_t timestamp_offset, int64_t rtcp_receive_time); void set_rtp_timestamp_offset(uint32_t offset); // Generates a new frame for this stream. If called too soon after the // previous frame, no frame will be generated. The frame is split into // packets. int64_t GenerateFrame(int64_t time_now_us, PacketList* packets); // The send-side time when the next frame can be generated. double next_rtp_time() const; // Generates an RTCP packet. RtcpPacket* Rtcp(int64_t time_now_us); void set_bitrate_bps(int bitrate_bps); int bitrate_bps() const; unsigned int ssrc() const; static bool Compare(const std::pair& left, const std::pair& right); private: enum { kRtcpIntervalUs = 1000000 }; int fps_; int bitrate_bps_; unsigned int ssrc_; unsigned int frequency_; int64_t next_rtp_time_; int64_t next_rtcp_time_; uint32_t rtp_timestamp_offset_; const double kNtpFracPerMs; RTC_DISALLOW_COPY_AND_ASSIGN(RtpStream); }; class StreamGenerator { public: typedef std::list RtcpList; StreamGenerator(int capacity, double time_now); ~StreamGenerator(); // Add a new stream. void AddStream(RtpStream* stream); // Set the link capacity. void set_capacity_bps(int capacity_bps); // Divides |bitrate_bps| among all streams. The allocated bitrate per stream // is decided by the initial allocation ratios. void SetBitrateBps(int bitrate_bps); // Set the RTP timestamp offset for the stream identified by |ssrc|. void set_rtp_timestamp_offset(unsigned int ssrc, uint32_t offset); // TODO(holmer): Break out the channel simulation part from this class to make // it possible to simulate different types of channels. int64_t GenerateFrame(RtpStream::PacketList* packets, int64_t time_now_us); private: typedef std::map StreamMap; // Capacity of the simulated channel in bits per second. int capacity_; // The time when the last packet arrived. int64_t prev_arrival_time_us_; // All streams being transmitted on this simulated channel. StreamMap streams_; RTC_DISALLOW_COPY_AND_ASSIGN(StreamGenerator); }; } // namespace testing class RemoteBitrateEstimatorTest : public ::testing::Test { public: RemoteBitrateEstimatorTest(); virtual ~RemoteBitrateEstimatorTest(); protected: virtual void SetUp() = 0; void AddDefaultStream(); // Helper to convert some time format to resolution used in absolute send time // header extension, rounded upwards. |t| is the time to convert, in some // resolution. |denom| is the value to divide |t| by to get whole seconds, // e.g. |denom| = 1000 if |t| is in milliseconds. static uint32_t AbsSendTime(int64_t t, int64_t denom); // Helper to add two absolute send time values and keep it less than 1<<24. static uint32_t AddAbsSendTime(uint32_t t1, uint32_t t2); // Helper to create a WebRtcRTPHeader containing the relevant data for the // estimator (all other fields are cleared) and call IncomingPacket on the // estimator. void IncomingPacket(uint32_t ssrc, size_t payload_size, int64_t arrival_time, uint32_t rtp_timestamp, uint32_t absolute_send_time, bool was_paced); // Generates a frame of packets belonging to a stream at a given bitrate and // with a given ssrc. The stream is pushed through a very simple simulated // network, and is then given to the receive-side bandwidth estimator. // Returns true if an over-use was seen, false otherwise. // The StreamGenerator::updated() should be used to check for any changes in // target bitrate after the call to this function. bool GenerateAndProcessFrame(unsigned int ssrc, unsigned int bitrate_bps); // Run the bandwidth estimator with a stream of |number_of_frames| frames, or // until it reaches |target_bitrate|. // Can for instance be used to run the estimator for some time to get it // into a steady state. unsigned int SteadyStateRun(unsigned int ssrc, int number_of_frames, unsigned int start_bitrate, unsigned int min_bitrate, unsigned int max_bitrate, unsigned int target_bitrate); void TestTimestampGroupingTestHelper(); void TestGetStatsHelper(); void TestWrappingHelper(int silence_time_s); void InitialBehaviorTestHelper(unsigned int expected_converge_bitrate); void RateIncreaseReorderingTestHelper(unsigned int expected_bitrate); void RateIncreaseRtpTimestampsTestHelper(int expected_iterations); void CapacityDropTestHelper(int number_of_streams, bool wrap_time_stamp, unsigned int expected_bitrate_drop_delta); static const unsigned int kDefaultSsrc; static const int kArrivalTimeClockOffsetMs = 60000; SimulatedClock clock_; // Time at the receiver. rtc::scoped_ptr bitrate_observer_; rtc::scoped_ptr bitrate_estimator_; rtc::scoped_ptr stream_generator_; RTC_DISALLOW_COPY_AND_ASSIGN(RemoteBitrateEstimatorTest); }; } // namespace webrtc #endif // WEBRTC_MODULES_REMOTE_BITRATE_ESTIMATOR_REMOTE_BITRATE_ESTIMATOR_UNITTEST_HELPER_H_