- Changed RemoteBitrateEstimator::IncomingPacket() to include a const WebRtcRTPHeader& and remove ssrc, rtp_timestamp.
- Changed RemoteBitrateObserver::OnReceivedBitrateChanged() to use a const & instead of non-const *, to avoid unnecessary copying. - Refactored RemoteBitrateEstimatorTest so it can be instantiated for both single and multi stream BWE (first using a parameterized test, but then as a standard test fixture and a few helper functions). - Refactored some tests in RemoteBitrateEstimatorTest into a common function CapacityDropTestHelper(). BUG= R=andresp@webrtc.org, mflodman@webrtc.org, stefan@webrtc.org Review URL: https://webrtc-codereview.appspot.com/1521004 git-svn-id: http://webrtc.googlecode.com/svn/trunk@4086 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
parent
6ec25073e3
commit
561990fd73
@ -22,7 +22,7 @@ namespace webrtc {
|
||||
class MockRemoteBitrateObserver : public RemoteBitrateObserver {
|
||||
public:
|
||||
MOCK_METHOD2(OnReceiveBitrateChanged,
|
||||
void(std::vector<unsigned int>* ssrcs, unsigned int bitrate));
|
||||
void(const std::vector<unsigned int>& ssrcs, unsigned int bitrate));
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
@ -31,7 +31,7 @@ class RemoteBitrateObserver {
|
||||
public:
|
||||
// Called when a receive channel group has a new bitrate estimate for the
|
||||
// incoming streams.
|
||||
virtual void OnReceiveBitrateChanged(std::vector<unsigned int>* ssrcs,
|
||||
virtual void OnReceiveBitrateChanged(const std::vector<unsigned int>& ssrcs,
|
||||
unsigned int bitrate) = 0;
|
||||
|
||||
virtual ~RemoteBitrateObserver() {}
|
||||
@ -41,7 +41,6 @@ class RemoteBitrateEstimator : public CallStatsObserver, public Module {
|
||||
public:
|
||||
virtual ~RemoteBitrateEstimator() {}
|
||||
|
||||
|
||||
// Stores an RTCP SR (NTP, RTP timestamp) tuple for a specific SSRC to be used
|
||||
// in future RTP timestamp to NTP time conversions. As soon as any SSRC has
|
||||
// two tuples the RemoteBitrateEstimator will switch to multi-stream mode.
|
||||
@ -51,11 +50,12 @@ class RemoteBitrateEstimator : public CallStatsObserver, public Module {
|
||||
// Called for each incoming packet. Updates the incoming payload bitrate
|
||||
// estimate and the over-use detector. If an over-use is detected the
|
||||
// remote bitrate estimate will be updated. Note that |payload_size| is the
|
||||
// packet size excluding headers.
|
||||
virtual void IncomingPacket(unsigned int ssrc,
|
||||
// packet size excluding headers. The estimator can only count on the
|
||||
// "header" (an RTPHeader) and "extension" (an RTPHeaderExtension) fields of
|
||||
// the WebRtcRTPHeader to be initialized.
|
||||
virtual void IncomingPacket(int64_t arrival_time_ms,
|
||||
int payload_size,
|
||||
int64_t arrival_time,
|
||||
uint32_t rtp_timestamp) = 0;
|
||||
const WebRtcRTPHeader& header) = 0;
|
||||
|
||||
// Removes all data for |ssrc|.
|
||||
virtual void RemoveStream(unsigned int ssrc) = 0;
|
||||
|
@ -59,7 +59,8 @@
|
||||
'sources': [
|
||||
'include/mock/mock_remote_bitrate_observer.h',
|
||||
'bitrate_estimator_unittest.cc',
|
||||
'remote_bitrate_estimator_unittest.cc',
|
||||
'remote_bitrate_estimator_multi_stream_unittest.cc',
|
||||
'remote_bitrate_estimator_single_stream_unittest.cc',
|
||||
'remote_bitrate_estimator_unittest_helper.cc',
|
||||
'remote_bitrate_estimator_unittest_helper.h',
|
||||
'rtp_to_ntp_unittest.cc',
|
||||
|
@ -28,14 +28,13 @@ class RemoteBitrateEstimatorMultiStream : public RemoteBitrateEstimator {
|
||||
public:
|
||||
RemoteBitrateEstimatorMultiStream(RemoteBitrateObserver* observer,
|
||||
Clock* clock);
|
||||
|
||||
~RemoteBitrateEstimatorMultiStream() {}
|
||||
virtual ~RemoteBitrateEstimatorMultiStream() {}
|
||||
|
||||
// Stores an RTCP SR (NTP, RTP timestamp) tuple for a specific SSRC to be used
|
||||
// in future RTP timestamp to NTP time conversions. As soon as any SSRC has
|
||||
// two tuples the RemoteBitrateEstimator will switch to multi-stream mode.
|
||||
void IncomingRtcp(unsigned int ssrc, uint32_t ntp_secs, uint32_t ntp_frac,
|
||||
uint32_t rtp_timestamp);
|
||||
virtual void IncomingRtcp(unsigned int ssrc, uint32_t ntp_secs,
|
||||
uint32_t ntp_frac, uint32_t rtp_timestamp);
|
||||
|
||||
// Called for each incoming packet. The first SSRC will immediately be used
|
||||
// for over-use detection. Subsequent SSRCs will only be used when at least
|
||||
@ -43,10 +42,9 @@ class RemoteBitrateEstimatorMultiStream : public RemoteBitrateEstimator {
|
||||
// incoming payload bitrate estimate and the over-use detector.
|
||||
// If an over-use is detected the remote bitrate estimate will be updated.
|
||||
// Note that |payload_size| is the packet size excluding headers.
|
||||
void IncomingPacket(unsigned int ssrc,
|
||||
int payload_size,
|
||||
int64_t arrival_time,
|
||||
uint32_t rtp_timestamp);
|
||||
virtual void IncomingPacket(int64_t arrival_time_ms,
|
||||
int payload_size,
|
||||
const WebRtcRTPHeader& header);
|
||||
|
||||
// Triggers a new estimate calculation.
|
||||
// Implements the Module interface.
|
||||
@ -57,13 +55,13 @@ class RemoteBitrateEstimatorMultiStream : public RemoteBitrateEstimator {
|
||||
virtual void OnRttUpdate(uint32_t rtt);
|
||||
|
||||
// Removes all data for |ssrc|.
|
||||
void RemoveStream(unsigned int ssrc);
|
||||
virtual void RemoveStream(unsigned int ssrc);
|
||||
|
||||
// Returns true if a valid estimate exists and sets |bitrate_bps| to the
|
||||
// estimated payload bitrate in bits per second. |ssrcs| is the list of ssrcs
|
||||
// currently being received and of which the bitrate estimate is based upon.
|
||||
bool LatestEstimate(std::vector<unsigned int>* ssrcs,
|
||||
unsigned int* bitrate_bps) const;
|
||||
virtual bool LatestEstimate(std::vector<unsigned int>* ssrcs,
|
||||
unsigned int* bitrate_bps) const;
|
||||
|
||||
private:
|
||||
typedef std::map<unsigned int, synchronization::RtcpList> StreamMap;
|
||||
@ -138,12 +136,15 @@ void RemoteBitrateEstimatorMultiStream::IncomingRtcp(unsigned int ssrc,
|
||||
rtcp_list->push_front(measurement);
|
||||
}
|
||||
|
||||
void RemoteBitrateEstimatorMultiStream::IncomingPacket(unsigned int ssrc,
|
||||
int payload_size,
|
||||
int64_t arrival_time,
|
||||
uint32_t rtp_timestamp) {
|
||||
void RemoteBitrateEstimatorMultiStream::IncomingPacket(
|
||||
int64_t arrival_time_ms,
|
||||
int payload_size,
|
||||
const WebRtcRTPHeader& header) {
|
||||
uint32_t ssrc = header.header.ssrc;
|
||||
uint32_t rtp_timestamp = header.header.timestamp +
|
||||
header.extension.transmissionTimeOffset;
|
||||
CriticalSectionScoped cs(crit_sect_.get());
|
||||
incoming_bitrate_.Update(payload_size, arrival_time);
|
||||
incoming_bitrate_.Update(payload_size, arrival_time_ms);
|
||||
// Add this stream to the map of streams if it doesn't already exist.
|
||||
std::pair<StreamMap::iterator, bool> stream_insert_result =
|
||||
streams_.insert(std::make_pair(ssrc, synchronization::RtcpList()));
|
||||
@ -167,15 +168,15 @@ void RemoteBitrateEstimatorMultiStream::IncomingPacket(unsigned int ssrc,
|
||||
synchronization::RtpToNtpMs(rtp_timestamp, *rtcp_list, ×tamp_in_ms);
|
||||
}
|
||||
overuse_detector_.Update(payload_size, timestamp_in_ms, rtp_timestamp,
|
||||
arrival_time);
|
||||
arrival_time_ms);
|
||||
if (overuse_detector_.State() == kBwOverusing) {
|
||||
unsigned int incoming_bitrate = incoming_bitrate_.BitRate(arrival_time);
|
||||
unsigned int incoming_bitrate = incoming_bitrate_.BitRate(arrival_time_ms);
|
||||
if (prior_state != kBwOverusing ||
|
||||
remote_rate_.TimeToReduceFurther(arrival_time, incoming_bitrate)) {
|
||||
remote_rate_.TimeToReduceFurther(arrival_time_ms, incoming_bitrate)) {
|
||||
// The first overuse should immediately trigger a new estimate.
|
||||
// We also have to update the estimate immediately if we are overusing
|
||||
// and the target bitrate is too high compared to what we are receiving.
|
||||
UpdateEstimate(arrival_time);
|
||||
UpdateEstimate(arrival_time_ms);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -216,7 +217,7 @@ void RemoteBitrateEstimatorMultiStream::UpdateEstimate(int64_t time_now) {
|
||||
std::vector<unsigned int> ssrcs;
|
||||
GetSsrcs(&ssrcs);
|
||||
if (!ssrcs.empty()) {
|
||||
observer_->OnReceiveBitrateChanged(&ssrcs, target_bitrate);
|
||||
observer_->OnReceiveBitrateChanged(ssrcs, target_bitrate);
|
||||
}
|
||||
}
|
||||
overuse_detector_.SetRateControlRegion(region);
|
||||
|
@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Copyright (c) 2013 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.
|
||||
*/
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "modules/remote_bitrate_estimator/remote_bitrate_estimator_unittest_helper.h"
|
||||
#include "webrtc/system_wrappers/interface/constructor_magic.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
class RemoteBitrateEstimatorMultiTest : public RemoteBitrateEstimatorTest {
|
||||
public:
|
||||
RemoteBitrateEstimatorMultiTest() {}
|
||||
virtual void SetUp() {
|
||||
bitrate_estimator_.reset(MultiStreamRemoteBitrateEstimatorFactory().Create(
|
||||
bitrate_observer_.get(),
|
||||
&clock_));
|
||||
}
|
||||
protected:
|
||||
DISALLOW_COPY_AND_ASSIGN(RemoteBitrateEstimatorMultiTest);
|
||||
};
|
||||
|
||||
TEST_F(RemoteBitrateEstimatorMultiTest, InitialBehavior) {
|
||||
InitialBehaviorTestHelper(497919);
|
||||
}
|
||||
|
||||
TEST_F(RemoteBitrateEstimatorMultiTest, RateIncreaseReordering) {
|
||||
RateIncreaseReorderingTestHelper();
|
||||
}
|
||||
|
||||
TEST_F(RemoteBitrateEstimatorMultiTest, RateIncreaseRtpTimestamps) {
|
||||
RateIncreaseRtpTimestampsTestHelper();
|
||||
}
|
||||
|
||||
TEST_F(RemoteBitrateEstimatorMultiTest, CapacityDropOneStream) {
|
||||
CapacityDropTestHelper(1, false, 956214, 367);
|
||||
}
|
||||
|
||||
TEST_F(RemoteBitrateEstimatorMultiTest, CapacityDropOneStreamWrap) {
|
||||
CapacityDropTestHelper(1, true, 956214, 367);
|
||||
}
|
||||
|
||||
TEST_F(RemoteBitrateEstimatorMultiTest, CapacityDropOneStreamWrapAlign) {
|
||||
align_streams_ = true;
|
||||
CapacityDropTestHelper(1, true, 838645, 533);
|
||||
}
|
||||
|
||||
TEST_F(RemoteBitrateEstimatorMultiTest, CapacityDropTwoStreamsWrapAlign) {
|
||||
align_streams_ = true;
|
||||
CapacityDropTestHelper(2, true, 810646, 433);
|
||||
}
|
||||
|
||||
TEST_F(RemoteBitrateEstimatorMultiTest, CapacityDropThreeStreamsWrapAlign) {
|
||||
align_streams_ = true;
|
||||
CapacityDropTestHelper(3, true, 868522, 2067);
|
||||
}
|
||||
|
||||
TEST_F(RemoteBitrateEstimatorMultiTest, CapacityDropThirteenStreamsWrap) {
|
||||
CapacityDropTestHelper(13, true, 918810, 433);
|
||||
}
|
||||
|
||||
TEST_F(RemoteBitrateEstimatorMultiTest, CapacityDropNineteenStreamsWrap) {
|
||||
CapacityDropTestHelper(19, true, 919119, 433);
|
||||
}
|
||||
|
||||
TEST_F(RemoteBitrateEstimatorMultiTest, CapacityDropThirtyStreamsWrap) {
|
||||
CapacityDropTestHelper(30, true, 918724, 433);
|
||||
}
|
||||
} // namespace webrtc
|
@ -25,19 +25,19 @@ class RemoteBitrateEstimatorSingleStream : public RemoteBitrateEstimator {
|
||||
public:
|
||||
RemoteBitrateEstimatorSingleStream(RemoteBitrateObserver* observer,
|
||||
Clock* clock);
|
||||
virtual ~RemoteBitrateEstimatorSingleStream() {}
|
||||
|
||||
void IncomingRtcp(unsigned int ssrc, uint32_t ntp_secs, uint32_t ntp_frac,
|
||||
uint32_t rtp_timestamp) {}
|
||||
virtual void IncomingRtcp(unsigned int ssrc, uint32_t ntp_secs,
|
||||
uint32_t ntp_frac, uint32_t rtp_timestamp) {}
|
||||
|
||||
// Called for each incoming packet. If this is a new SSRC, a new
|
||||
// BitrateControl will be created. Updates the incoming payload bitrate
|
||||
// estimate and the over-use detector. If an over-use is detected the
|
||||
// remote bitrate estimate will be updated. Note that |payload_size| is the
|
||||
// packet size excluding headers.
|
||||
void IncomingPacket(unsigned int ssrc,
|
||||
int payload_size,
|
||||
int64_t arrival_time,
|
||||
uint32_t rtp_timestamp);
|
||||
virtual void IncomingPacket(int64_t arrival_time_ms,
|
||||
int payload_size,
|
||||
const WebRtcRTPHeader& header);
|
||||
|
||||
// Triggers a new estimate calculation.
|
||||
// Implements the Module interface.
|
||||
@ -48,13 +48,13 @@ class RemoteBitrateEstimatorSingleStream : public RemoteBitrateEstimator {
|
||||
virtual void OnRttUpdate(uint32_t rtt);
|
||||
|
||||
// Removes all data for |ssrc|.
|
||||
void RemoveStream(unsigned int ssrc);
|
||||
virtual void RemoveStream(unsigned int ssrc);
|
||||
|
||||
// Returns true if a valid estimate exists and sets |bitrate_bps| to the
|
||||
// estimated payload bitrate in bits per second. |ssrcs| is the list of ssrcs
|
||||
// currently being received and of which the bitrate estimate is based upon.
|
||||
bool LatestEstimate(std::vector<unsigned int>* ssrcs,
|
||||
unsigned int* bitrate_bps) const;
|
||||
virtual bool LatestEstimate(std::vector<unsigned int>* ssrcs,
|
||||
unsigned int* bitrate_bps) const;
|
||||
|
||||
private:
|
||||
typedef std::map<unsigned int, OveruseDetector> SsrcOveruseDetectorMap;
|
||||
@ -84,10 +84,12 @@ RemoteBitrateEstimatorSingleStream::RemoteBitrateEstimatorSingleStream(
|
||||
}
|
||||
|
||||
void RemoteBitrateEstimatorSingleStream::IncomingPacket(
|
||||
unsigned int ssrc,
|
||||
int64_t arrival_time_ms,
|
||||
int payload_size,
|
||||
int64_t arrival_time,
|
||||
uint32_t rtp_timestamp) {
|
||||
const WebRtcRTPHeader& header) {
|
||||
uint32_t ssrc = header.header.ssrc;
|
||||
uint32_t rtp_timestamp = header.header.timestamp +
|
||||
header.extension.transmissionTimeOffset;
|
||||
CriticalSectionScoped cs(crit_sect_.get());
|
||||
SsrcOveruseDetectorMap::iterator it = overuse_detectors_.find(ssrc);
|
||||
if (it == overuse_detectors_.end()) {
|
||||
@ -103,17 +105,17 @@ void RemoteBitrateEstimatorSingleStream::IncomingPacket(
|
||||
it = insert_result.first;
|
||||
}
|
||||
OveruseDetector* overuse_detector = &it->second;
|
||||
incoming_bitrate_.Update(payload_size, arrival_time);
|
||||
incoming_bitrate_.Update(payload_size, arrival_time_ms);
|
||||
const BandwidthUsage prior_state = overuse_detector->State();
|
||||
overuse_detector->Update(payload_size, -1, rtp_timestamp, arrival_time);
|
||||
overuse_detector->Update(payload_size, -1, rtp_timestamp, arrival_time_ms);
|
||||
if (overuse_detector->State() == kBwOverusing) {
|
||||
unsigned int incoming_bitrate = incoming_bitrate_.BitRate(arrival_time);
|
||||
unsigned int incoming_bitrate = incoming_bitrate_.BitRate(arrival_time_ms);
|
||||
if (prior_state != kBwOverusing ||
|
||||
remote_rate_.TimeToReduceFurther(arrival_time, incoming_bitrate)) {
|
||||
remote_rate_.TimeToReduceFurther(arrival_time_ms, incoming_bitrate)) {
|
||||
// The first overuse should immediately trigger a new estimate.
|
||||
// We also have to update the estimate immediately if we are overusing
|
||||
// and the target bitrate is too high compared to what we are receiving.
|
||||
UpdateEstimate(arrival_time);
|
||||
UpdateEstimate(arrival_time_ms);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -172,7 +174,7 @@ void RemoteBitrateEstimatorSingleStream::UpdateEstimate(int64_t time_now) {
|
||||
if (remote_rate_.ValidEstimate()) {
|
||||
std::vector<unsigned int> ssrcs;
|
||||
GetSsrcs(&ssrcs);
|
||||
observer_->OnReceiveBitrateChanged(&ssrcs, target_bitrate);
|
||||
observer_->OnReceiveBitrateChanged(ssrcs, target_bitrate);
|
||||
}
|
||||
for (it = overuse_detectors_.begin(); it != overuse_detectors_.end(); ++it) {
|
||||
it->second.SetRateControlRegion(region);
|
||||
|
@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Copyright (c) 2013 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.
|
||||
*/
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "modules/remote_bitrate_estimator/remote_bitrate_estimator_unittest_helper.h"
|
||||
#include "webrtc/system_wrappers/interface/constructor_magic.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
class RemoteBitrateEstimatorSingleTest : public RemoteBitrateEstimatorTest {
|
||||
public:
|
||||
RemoteBitrateEstimatorSingleTest() {}
|
||||
virtual void SetUp() {
|
||||
bitrate_estimator_.reset(RemoteBitrateEstimatorFactory().Create(
|
||||
bitrate_observer_.get(),
|
||||
&clock_));
|
||||
}
|
||||
protected:
|
||||
DISALLOW_COPY_AND_ASSIGN(RemoteBitrateEstimatorSingleTest);
|
||||
};
|
||||
|
||||
TEST_F(RemoteBitrateEstimatorSingleTest, InitialBehavior) {
|
||||
InitialBehaviorTestHelper(498075);
|
||||
}
|
||||
|
||||
TEST_F(RemoteBitrateEstimatorSingleTest, RateIncreaseReordering) {
|
||||
RateIncreaseReorderingTestHelper();
|
||||
}
|
||||
|
||||
TEST_F(RemoteBitrateEstimatorSingleTest, RateIncreaseRtpTimestamps) {
|
||||
RateIncreaseRtpTimestampsTestHelper();
|
||||
}
|
||||
|
||||
// Verify that the time it takes for the estimator to reduce the bitrate when
|
||||
// the capacity is tightened stays the same.
|
||||
TEST_F(RemoteBitrateEstimatorSingleTest, CapacityDropOneStream) {
|
||||
CapacityDropTestHelper(1, false, 956214, 367);
|
||||
}
|
||||
|
||||
// Verify that the time it takes for the estimator to reduce the bitrate when
|
||||
// the capacity is tightened stays the same. This test also verifies that we
|
||||
// handle wrap-arounds in this scenario.
|
||||
TEST_F(RemoteBitrateEstimatorSingleTest, CapacityDropOneStreamWrap) {
|
||||
CapacityDropTestHelper(1, true, 956214, 367);
|
||||
}
|
||||
|
||||
// Verify that the time it takes for the estimator to reduce the bitrate when
|
||||
// the capacity is tightened stays the same. This test also verifies that we
|
||||
// handle wrap-arounds in this scenario.
|
||||
TEST_F(RemoteBitrateEstimatorSingleTest, CapacityDropOneStreamWrapAlign) {
|
||||
align_streams_ = true;
|
||||
CapacityDropTestHelper(1, true, 956214, 367);
|
||||
}
|
||||
|
||||
// Verify that the time it takes for the estimator to reduce the bitrate when
|
||||
// the capacity is tightened stays the same. This test also verifies that we
|
||||
// handle wrap-arounds in this scenario. This is a multi-stream test.
|
||||
TEST_F(RemoteBitrateEstimatorSingleTest, CapacityDropTwoStreamsWrapAlign) {
|
||||
align_streams_ = true;
|
||||
CapacityDropTestHelper(2, true, 927088, 267);
|
||||
}
|
||||
|
||||
// Verify that the time it takes for the estimator to reduce the bitrate when
|
||||
// the capacity is tightened stays the same. This test also verifies that we
|
||||
// handle wrap-arounds in this scenario. This is a multi-stream test.
|
||||
TEST_F(RemoteBitrateEstimatorSingleTest, CapacityDropThreeStreamsWrapAlign) {
|
||||
align_streams_ = true;
|
||||
CapacityDropTestHelper(3, true, 920944, 333);
|
||||
}
|
||||
|
||||
TEST_F(RemoteBitrateEstimatorSingleTest, CapacityDropThirteenStreamsWrap) {
|
||||
CapacityDropTestHelper(13, true, 938944, 300);
|
||||
}
|
||||
|
||||
TEST_F(RemoteBitrateEstimatorSingleTest, CapacityDropNineteenStreamsWrap) {
|
||||
CapacityDropTestHelper(19, true, 926718, 300);
|
||||
}
|
||||
|
||||
TEST_F(RemoteBitrateEstimatorSingleTest, CapacityDropThirtyStreamsWrap) {
|
||||
CapacityDropTestHelper(30, true, 927016, 300);
|
||||
}
|
||||
} // namespace webrtc
|
@ -1,367 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
// This file includes unit tests for RemoteBitrateEstimator.
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
|
||||
#include "modules/remote_bitrate_estimator/include/remote_bitrate_estimator.h"
|
||||
#include "modules/remote_bitrate_estimator/remote_bitrate_estimator_unittest_helper.h"
|
||||
#include "system_wrappers/interface/constructor_magic.h"
|
||||
#include "system_wrappers/interface/scoped_ptr.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
TEST_F(RemoteBitrateEstimatorTest, TestInitialBehavior) {
|
||||
const int kFramerate = 50; // 50 fps to avoid rounding errors.
|
||||
const int kFrameIntervalMs = 1000 / kFramerate;
|
||||
unsigned int bitrate_bps = 0;
|
||||
uint32_t timestamp = 0;
|
||||
std::vector<unsigned int> ssrcs;
|
||||
EXPECT_FALSE(bitrate_estimator_->LatestEstimate(&ssrcs, &bitrate_bps));
|
||||
EXPECT_EQ(0u, ssrcs.size());
|
||||
clock_.AdvanceTimeMilliseconds(1000);
|
||||
bitrate_estimator_->Process();
|
||||
EXPECT_FALSE(bitrate_estimator_->LatestEstimate(&ssrcs, &bitrate_bps));
|
||||
EXPECT_FALSE(bitrate_observer_->updated());
|
||||
bitrate_observer_->Reset();
|
||||
clock_.AdvanceTimeMilliseconds(1000);
|
||||
// Inserting a packet. Still no valid estimate. We need to wait 1 second.
|
||||
bitrate_estimator_->IncomingPacket(kDefaultSsrc, kMtu,
|
||||
clock_.TimeInMilliseconds(), timestamp);
|
||||
bitrate_estimator_->Process();
|
||||
EXPECT_FALSE(bitrate_estimator_->LatestEstimate(&ssrcs, &bitrate_bps));
|
||||
EXPECT_EQ(0u, ssrcs.size());
|
||||
EXPECT_FALSE(bitrate_observer_->updated());
|
||||
bitrate_observer_->Reset();
|
||||
// Inserting packets for one second to get a valid estimate.
|
||||
for (int i = 0; i < kFramerate; ++i) {
|
||||
bitrate_estimator_->IncomingPacket(kDefaultSsrc, kMtu,
|
||||
clock_.TimeInMilliseconds(), timestamp);
|
||||
clock_.AdvanceTimeMilliseconds(1000 / kFramerate);
|
||||
timestamp += 90 * kFrameIntervalMs;
|
||||
}
|
||||
bitrate_estimator_->Process();
|
||||
EXPECT_TRUE(bitrate_estimator_->LatestEstimate(&ssrcs, &bitrate_bps));
|
||||
ASSERT_EQ(1u, ssrcs.size());
|
||||
EXPECT_EQ(kDefaultSsrc, ssrcs.front());
|
||||
EXPECT_EQ(498075u, bitrate_bps);
|
||||
EXPECT_TRUE(bitrate_observer_->updated());
|
||||
bitrate_observer_->Reset();
|
||||
EXPECT_EQ(bitrate_observer_->latest_bitrate(), bitrate_bps);
|
||||
}
|
||||
|
||||
TEST_F(RemoteBitrateEstimatorTest, TestRateIncreaseReordering) {
|
||||
uint32_t timestamp = 0;
|
||||
const int kFramerate = 50; // 50 fps to avoid rounding errors.
|
||||
const int kFrameIntervalMs = 1000 / kFramerate;
|
||||
bitrate_estimator_->IncomingPacket(kDefaultSsrc, 1000,
|
||||
clock_.TimeInMilliseconds(), timestamp);
|
||||
bitrate_estimator_->Process();
|
||||
EXPECT_FALSE(bitrate_observer_->updated()); // No valid estimate.
|
||||
// Inserting packets for one second to get a valid estimate.
|
||||
for (int i = 0; i < kFramerate; ++i) {
|
||||
bitrate_estimator_->IncomingPacket(kDefaultSsrc, kMtu,
|
||||
clock_.TimeInMilliseconds(), timestamp);
|
||||
clock_.AdvanceTimeMilliseconds(kFrameIntervalMs);
|
||||
timestamp += 90 * kFrameIntervalMs;
|
||||
}
|
||||
bitrate_estimator_->Process();
|
||||
EXPECT_TRUE(bitrate_observer_->updated());
|
||||
EXPECT_EQ(498136u, bitrate_observer_->latest_bitrate());
|
||||
for (int i = 0; i < 10; ++i) {
|
||||
clock_.AdvanceTimeMilliseconds(2 * kFrameIntervalMs);
|
||||
timestamp += 2 * 90 * kFrameIntervalMs;
|
||||
bitrate_estimator_->IncomingPacket(kDefaultSsrc, 1000,
|
||||
clock_.TimeInMilliseconds(), timestamp);
|
||||
bitrate_estimator_->IncomingPacket(kDefaultSsrc,
|
||||
1000,
|
||||
clock_.TimeInMilliseconds(),
|
||||
timestamp - 90 * kFrameIntervalMs);
|
||||
}
|
||||
bitrate_estimator_->Process();
|
||||
EXPECT_TRUE(bitrate_observer_->updated());
|
||||
EXPECT_EQ(498136u, bitrate_observer_->latest_bitrate());
|
||||
}
|
||||
|
||||
// Make sure we initially increase the bitrate as expected.
|
||||
TEST_F(RemoteBitrateEstimatorTest, TestRateIncreaseRtpTimestamps) {
|
||||
// This threshold corresponds approximately to increasing linearly with
|
||||
// bitrate(i) = 1.04 * bitrate(i-1) + 1000
|
||||
// until bitrate(i) > 500000, with bitrate(1) ~= 30000.
|
||||
const int kExpectedIterations = 1621;
|
||||
unsigned int bitrate_bps = 30000;
|
||||
int iterations = 0;
|
||||
AddDefaultStream();
|
||||
// Feed the estimator with a stream of packets and verify that it reaches
|
||||
// 500 kbps at the expected time.
|
||||
while (bitrate_bps < 5e5) {
|
||||
bool overuse = GenerateAndProcessFrame(kDefaultSsrc, bitrate_bps);
|
||||
if (overuse) {
|
||||
EXPECT_GT(bitrate_observer_->latest_bitrate(), bitrate_bps);
|
||||
bitrate_bps = bitrate_observer_->latest_bitrate();
|
||||
bitrate_observer_->Reset();
|
||||
} else if (bitrate_observer_->updated()) {
|
||||
bitrate_bps = bitrate_observer_->latest_bitrate();
|
||||
bitrate_observer_->Reset();
|
||||
}
|
||||
++iterations;
|
||||
ASSERT_LE(iterations, kExpectedIterations);
|
||||
}
|
||||
ASSERT_EQ(kExpectedIterations, iterations);
|
||||
}
|
||||
|
||||
// Verify that the time it takes for the estimator to reduce the bitrate when
|
||||
// the capacity is tightened stays the same.
|
||||
TEST_F(RemoteBitrateEstimatorTest, TestCapacityDropRtpTimestamps) {
|
||||
const int kNumberOfFrames = 300;
|
||||
const int kStartBitrate = 900e3;
|
||||
const int kMinExpectedBitrate = 800e3;
|
||||
const int kMaxExpectedBitrate = 1100e3;
|
||||
AddDefaultStream();
|
||||
// Run in steady state to make the estimator converge.
|
||||
unsigned int capacity_bps = 1000e3;
|
||||
stream_generator_->set_capacity_bps(1000e3);
|
||||
unsigned int bitrate_bps = SteadyStateRun(kDefaultSsrc, kNumberOfFrames,
|
||||
kStartBitrate, kMinExpectedBitrate,
|
||||
kMaxExpectedBitrate, capacity_bps);
|
||||
// Reduce the capacity and verify the decrease time.
|
||||
capacity_bps = 500e3;
|
||||
stream_generator_->set_capacity_bps(capacity_bps);
|
||||
int64_t overuse_start_time = clock_.TimeInMilliseconds();
|
||||
int64_t bitrate_drop_time = -1;
|
||||
for (int i = 0; i < 200; ++i) {
|
||||
GenerateAndProcessFrame(kDefaultSsrc, bitrate_bps);
|
||||
// Check for either increase or decrease.
|
||||
if (bitrate_observer_->updated()) {
|
||||
if (bitrate_drop_time == -1 &&
|
||||
bitrate_observer_->latest_bitrate() <= capacity_bps) {
|
||||
bitrate_drop_time = clock_.TimeInMilliseconds();
|
||||
}
|
||||
bitrate_bps = bitrate_observer_->latest_bitrate();
|
||||
bitrate_observer_->Reset();
|
||||
}
|
||||
}
|
||||
EXPECT_EQ(367, bitrate_drop_time - overuse_start_time);
|
||||
}
|
||||
|
||||
// Verify that the time it takes for the estimator to reduce the bitrate when
|
||||
// the capacity is tightened stays the same. This test also verifies that we
|
||||
// handle wrap-arounds in this scenario.
|
||||
TEST_F(RemoteBitrateEstimatorTest, TestCapacityDropRtpTimestampsWrap) {
|
||||
const int kFramerate= 30;
|
||||
const int kStartBitrate = 900e3;
|
||||
const int kMinExpectedBitrate = 800e3;
|
||||
const int kMaxExpectedBitrate = 1100e3;
|
||||
const int kSteadyStateTime = 8; // Seconds.
|
||||
AddDefaultStream();
|
||||
// Trigger wrap right after the steady state run.
|
||||
stream_generator_->set_rtp_timestamp_offset(kDefaultSsrc,
|
||||
std::numeric_limits<uint32_t>::max() - kSteadyStateTime * 90000);
|
||||
// Run in steady state to make the estimator converge.
|
||||
unsigned int capacity_bps = 1000e3;
|
||||
stream_generator_->set_capacity_bps(1000e3);
|
||||
unsigned int bitrate_bps = SteadyStateRun(kDefaultSsrc,
|
||||
kSteadyStateTime * kFramerate,
|
||||
kStartBitrate,
|
||||
kMinExpectedBitrate,
|
||||
kMaxExpectedBitrate,
|
||||
capacity_bps);
|
||||
bitrate_observer_->Reset();
|
||||
// Reduce the capacity and verify the decrease time.
|
||||
capacity_bps = 500e3;
|
||||
stream_generator_->set_capacity_bps(capacity_bps);
|
||||
int64_t overuse_start_time = clock_.TimeInMilliseconds();
|
||||
int64_t bitrate_drop_time = -1;
|
||||
for (int i = 0; i < 200; ++i) {
|
||||
GenerateAndProcessFrame(kDefaultSsrc, bitrate_bps);
|
||||
// Check for either increase or decrease.
|
||||
if (bitrate_observer_->updated()) {
|
||||
if (bitrate_drop_time == -1 &&
|
||||
bitrate_observer_->latest_bitrate() <= capacity_bps) {
|
||||
bitrate_drop_time = clock_.TimeInMilliseconds();
|
||||
}
|
||||
bitrate_bps = bitrate_observer_->latest_bitrate();
|
||||
bitrate_observer_->Reset();
|
||||
}
|
||||
}
|
||||
EXPECT_EQ(367, bitrate_drop_time - overuse_start_time);
|
||||
}
|
||||
|
||||
// Verify that the time it takes for the estimator to reduce the bitrate when
|
||||
// the capacity is tightened stays the same. This test also verifies that we
|
||||
// handle wrap-arounds in this scenario. This test also converts the timestamps
|
||||
// to NTP time.
|
||||
TEST_F(RemoteBitrateEstimatorTestAlign, TestCapacityDropRtpTimestampsWrap) {
|
||||
const int kFramerate= 30;
|
||||
const int kStartBitrate = 900e3;
|
||||
const int kMinExpectedBitrate = 800e3;
|
||||
const int kMaxExpectedBitrate = 1100e3;
|
||||
const int kSteadyStateTime = 8; // Seconds.
|
||||
AddDefaultStream();
|
||||
// Trigger wrap right after the steady state run.
|
||||
stream_generator_->set_rtp_timestamp_offset(kDefaultSsrc,
|
||||
std::numeric_limits<uint32_t>::max() - kSteadyStateTime * 90000);
|
||||
// Run in steady state to make the estimator converge.
|
||||
unsigned int capacity_bps = 1000e3;
|
||||
stream_generator_->set_capacity_bps(capacity_bps);
|
||||
unsigned int bitrate_bps = SteadyStateRun(kDefaultSsrc,
|
||||
kSteadyStateTime * kFramerate,
|
||||
kStartBitrate,
|
||||
kMinExpectedBitrate,
|
||||
kMaxExpectedBitrate,
|
||||
capacity_bps);
|
||||
bitrate_observer_->Reset();
|
||||
// Reduce the capacity and verify the decrease time.
|
||||
capacity_bps = 500e3;
|
||||
stream_generator_->set_capacity_bps(capacity_bps);
|
||||
int64_t overuse_start_time = clock_.TimeInMilliseconds();
|
||||
int64_t bitrate_drop_time = -1;
|
||||
for (int i = 0; i < 200; ++i) {
|
||||
GenerateAndProcessFrame(kDefaultSsrc, bitrate_bps);
|
||||
// Check for either increase or decrease.
|
||||
if (bitrate_observer_->updated()) {
|
||||
if (bitrate_drop_time == -1 &&
|
||||
bitrate_observer_->latest_bitrate() <= capacity_bps) {
|
||||
bitrate_drop_time = clock_.TimeInMilliseconds();
|
||||
}
|
||||
bitrate_bps = bitrate_observer_->latest_bitrate();
|
||||
bitrate_observer_->Reset();
|
||||
}
|
||||
}
|
||||
EXPECT_EQ(367, bitrate_drop_time - overuse_start_time);
|
||||
}
|
||||
|
||||
// Verify that the time it takes for the estimator to reduce the bitrate when
|
||||
// the capacity is tightened stays the same. This test also verifies that we
|
||||
// handle wrap-arounds in this scenario. This is a multi-stream test.
|
||||
TEST_F(RemoteBitrateEstimatorTestAlign, TwoStreamsCapacityDropWithWrap) {
|
||||
const int kFramerate= 30;
|
||||
const int kStartBitrate = 900e3;
|
||||
const int kMinExpectedBitrate = 800e3;
|
||||
const int kMaxExpectedBitrate = 1100e3;
|
||||
const int kSteadyStateFrames = 9 * kFramerate;
|
||||
stream_generator_->AddStream(new testing::RtpStream(
|
||||
30, // Frames per second.
|
||||
kStartBitrate/2, // Bitrate.
|
||||
1, // SSRC.
|
||||
90000, // RTP frequency.
|
||||
0xFFFFF000, // Timestamp offset.
|
||||
0)); // RTCP receive time.
|
||||
|
||||
stream_generator_->AddStream(new testing::RtpStream(
|
||||
15, // Frames per second.
|
||||
kStartBitrate/2, // Bitrate.
|
||||
2, // SSRC.
|
||||
90000, // RTP frequency.
|
||||
0x00000FFF, // Timestamp offset.
|
||||
0)); // RTCP receive time.
|
||||
// Trigger wrap right after the steady state run.
|
||||
stream_generator_->set_rtp_timestamp_offset(kDefaultSsrc,
|
||||
std::numeric_limits<uint32_t>::max() - kSteadyStateFrames * 90000);
|
||||
// Run in steady state to make the estimator converge.
|
||||
unsigned int capacity_bps = 1000e3;
|
||||
stream_generator_->set_capacity_bps(capacity_bps);
|
||||
unsigned int bitrate_bps = SteadyStateRun(kDefaultSsrc,
|
||||
kSteadyStateFrames,
|
||||
kStartBitrate,
|
||||
kMinExpectedBitrate,
|
||||
kMaxExpectedBitrate,
|
||||
capacity_bps);
|
||||
bitrate_observer_->Reset();
|
||||
// Reduce the capacity and verify the decrease time.
|
||||
capacity_bps = 500e3;
|
||||
stream_generator_->set_capacity_bps(capacity_bps);
|
||||
int64_t overuse_start_time = clock_.TimeInMilliseconds();
|
||||
int64_t bitrate_drop_time = -1;
|
||||
for (int i = 0; i < 200; ++i) {
|
||||
GenerateAndProcessFrame(kDefaultSsrc, bitrate_bps);
|
||||
// Check for either increase or decrease.
|
||||
if (bitrate_observer_->updated()) {
|
||||
if (bitrate_drop_time == -1 &&
|
||||
bitrate_observer_->latest_bitrate() <= capacity_bps) {
|
||||
bitrate_drop_time = clock_.TimeInMilliseconds();
|
||||
}
|
||||
bitrate_bps = bitrate_observer_->latest_bitrate();
|
||||
bitrate_observer_->Reset();
|
||||
}
|
||||
}
|
||||
EXPECT_EQ(567, bitrate_drop_time - overuse_start_time);
|
||||
}
|
||||
|
||||
// Verify that the time it takes for the estimator to reduce the bitrate when
|
||||
// the capacity is tightened stays the same. This test also verifies that we
|
||||
// handle wrap-arounds in this scenario. This is a multi-stream test.
|
||||
TEST_F(RemoteBitrateEstimatorTestAlign, ThreeStreams) {
|
||||
const int kFramerate= 30;
|
||||
const int kStartBitrate = 900e3;
|
||||
const int kMinExpectedBitrate = 800e3;
|
||||
const int kMaxExpectedBitrate = 1100e3;
|
||||
const int kSteadyStateFrames = 12 * kFramerate;
|
||||
stream_generator_->AddStream(new testing::RtpStream(
|
||||
kFramerate, // Frames per second.
|
||||
kStartBitrate/2, // Bitrate.
|
||||
1, // SSRC.
|
||||
90000, // RTP frequency.
|
||||
0xFFFFF000, // Timestamp offset.
|
||||
0)); // RTCP receive time.
|
||||
|
||||
stream_generator_->AddStream(new testing::RtpStream(
|
||||
kFramerate, // Frames per second.
|
||||
kStartBitrate/3, // Bitrate.
|
||||
2, // SSRC.
|
||||
90000, // RTP frequency.
|
||||
0x00000FFF, // Timestamp offset.
|
||||
0)); // RTCP receive time.
|
||||
|
||||
stream_generator_->AddStream(new testing::RtpStream(
|
||||
kFramerate, // Frames per second.
|
||||
kStartBitrate/6, // Bitrate.
|
||||
3, // SSRC.
|
||||
90000, // RTP frequency.
|
||||
0x00000FFF, // Timestamp offset.
|
||||
0)); // RTCP receive time.
|
||||
// Trigger wrap right after the steady state run.
|
||||
stream_generator_->set_rtp_timestamp_offset(kDefaultSsrc,
|
||||
std::numeric_limits<uint32_t>::max() - kSteadyStateFrames * 90000);
|
||||
// Run in steady state to make the estimator converge.
|
||||
unsigned int capacity_bps = 1000e3;
|
||||
stream_generator_->set_capacity_bps(capacity_bps);
|
||||
unsigned int bitrate_bps = SteadyStateRun(kDefaultSsrc,
|
||||
kSteadyStateFrames,
|
||||
kStartBitrate,
|
||||
kMinExpectedBitrate,
|
||||
kMaxExpectedBitrate,
|
||||
capacity_bps);
|
||||
bitrate_observer_->Reset();
|
||||
// Reduce the capacity and verify the decrease time.
|
||||
capacity_bps = 500e3;
|
||||
stream_generator_->set_capacity_bps(capacity_bps);
|
||||
int64_t overuse_start_time = clock_.TimeInMilliseconds();
|
||||
int64_t bitrate_drop_time = -1;
|
||||
for (int i = 0; i < 200; ++i) {
|
||||
GenerateAndProcessFrame(kDefaultSsrc, bitrate_bps);
|
||||
// Check for either increase or decrease.
|
||||
if (bitrate_observer_->updated()) {
|
||||
if (bitrate_drop_time == -1 &&
|
||||
bitrate_observer_->latest_bitrate() <= capacity_bps) {
|
||||
bitrate_drop_time = clock_.TimeInMilliseconds();
|
||||
}
|
||||
bitrate_bps = bitrate_observer_->latest_bitrate();
|
||||
bitrate_observer_->Reset();
|
||||
}
|
||||
}
|
||||
EXPECT_EQ(433, bitrate_drop_time - overuse_start_time);
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
@ -13,6 +13,9 @@
|
||||
#include <utility>
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
enum { kMtu = 1200 };
|
||||
|
||||
namespace testing {
|
||||
|
||||
RtpStream::RtpStream(int fps,
|
||||
@ -124,22 +127,24 @@ void StreamGenerator::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 StreamGenerator::set_bitrate_bps(int bitrate_bps) {
|
||||
// is decided by the current allocation ratios.
|
||||
void StreamGenerator::SetBitrateBps(int bitrate_bps) {
|
||||
ASSERT_GE(streams_.size(), 0u);
|
||||
double total_bitrate_before = 0;
|
||||
for (StreamMap::iterator it = streams_.begin(); it != streams_.end();
|
||||
++it) {
|
||||
int total_bitrate_before = 0;
|
||||
for (StreamMap::iterator it = streams_.begin(); it != streams_.end(); ++it) {
|
||||
total_bitrate_before += it->second->bitrate_bps();
|
||||
}
|
||||
int64_t bitrate_before = 0;
|
||||
int total_bitrate_after = 0;
|
||||
for (StreamMap::iterator it = streams_.begin(); it != streams_.end();
|
||||
++it) {
|
||||
double ratio = it->second->bitrate_bps() / total_bitrate_before;
|
||||
it->second->set_bitrate_bps(ratio * bitrate_bps + 0.5);
|
||||
for (StreamMap::iterator it = streams_.begin(); it != streams_.end(); ++it) {
|
||||
bitrate_before += it->second->bitrate_bps();
|
||||
int64_t bitrate_after = (bitrate_before * bitrate_bps +
|
||||
total_bitrate_before / 2) / total_bitrate_before;
|
||||
it->second->set_bitrate_bps(bitrate_after - total_bitrate_after);
|
||||
total_bitrate_after += it->second->bitrate_bps();
|
||||
}
|
||||
EXPECT_NEAR(total_bitrate_after, bitrate_bps, 1);
|
||||
ASSERT_EQ(bitrate_before, total_bitrate_before);
|
||||
EXPECT_EQ(total_bitrate_after, bitrate_bps);
|
||||
}
|
||||
|
||||
// Set the RTP timestamp offset for the stream identified by |ssrc|.
|
||||
@ -186,22 +191,11 @@ void StreamGenerator::Rtcps(RtcpList* rtcps, int64_t time_now_us) const {
|
||||
|
||||
RemoteBitrateEstimatorTest::RemoteBitrateEstimatorTest()
|
||||
: clock_(0),
|
||||
align_streams_(false) {}
|
||||
|
||||
RemoteBitrateEstimatorTest::RemoteBitrateEstimatorTest(bool align_streams)
|
||||
: clock_(0),
|
||||
align_streams_(align_streams) {}
|
||||
|
||||
void RemoteBitrateEstimatorTest::SetUp() {
|
||||
bitrate_observer_.reset(new testing::TestBitrateObserver);
|
||||
bitrate_estimator_.reset(
|
||||
RemoteBitrateEstimatorFactory().Create(
|
||||
bitrate_observer_.get(),
|
||||
&clock_));
|
||||
stream_generator_.reset(new testing::StreamGenerator(
|
||||
1e6, // Capacity.
|
||||
clock_.TimeInMicroseconds()));
|
||||
}
|
||||
align_streams_(false),
|
||||
bitrate_observer_(new testing::TestBitrateObserver),
|
||||
stream_generator_(new testing::StreamGenerator(
|
||||
1e6, // Capacity.
|
||||
clock_.TimeInMicroseconds())) {}
|
||||
|
||||
void RemoteBitrateEstimatorTest::AddDefaultStream() {
|
||||
stream_generator_->AddStream(new testing::RtpStream(
|
||||
@ -213,8 +207,29 @@ void RemoteBitrateEstimatorTest::AddDefaultStream() {
|
||||
0)); // RTCP receive time.
|
||||
}
|
||||
|
||||
uint32_t RemoteBitrateEstimatorTest::AbsSendTime(int64_t t, int64_t denom) {
|
||||
return (((t << 18) + (denom >> 1)) / denom) & 0x00fffffful;
|
||||
}
|
||||
|
||||
uint32_t RemoteBitrateEstimatorTest::AddAbsSendTime(uint32_t t1, uint32_t t2) {
|
||||
return (t1 + t2) & 0x00fffffful;
|
||||
}
|
||||
|
||||
const unsigned int RemoteBitrateEstimatorTest::kDefaultSsrc = 1;
|
||||
|
||||
void RemoteBitrateEstimatorTest::IncomingPacket(uint32_t ssrc,
|
||||
uint32_t payload_size,
|
||||
int64_t arrival_time,
|
||||
uint32_t rtp_timestamp,
|
||||
uint32_t absolute_send_time) {
|
||||
WebRtcRTPHeader header;
|
||||
memset(&header, 0, sizeof(header));
|
||||
header.header.ssrc = ssrc;
|
||||
header.header.timestamp = rtp_timestamp;
|
||||
header.extension.absoluteSendTime = absolute_send_time;
|
||||
bitrate_estimator_->IncomingPacket(arrival_time, payload_size, header);
|
||||
}
|
||||
|
||||
// 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.
|
||||
@ -223,7 +238,7 @@ const unsigned int RemoteBitrateEstimatorTest::kDefaultSsrc = 1;
|
||||
// target bitrate after the call to this function.
|
||||
bool RemoteBitrateEstimatorTest::GenerateAndProcessFrame(unsigned int ssrc,
|
||||
unsigned int bitrate_bps) {
|
||||
stream_generator_->set_bitrate_bps(bitrate_bps);
|
||||
stream_generator_->SetBitrateBps(bitrate_bps);
|
||||
testing::RtpStream::PacketList packets;
|
||||
int64_t next_time_us = stream_generator_->GenerateFrame(
|
||||
&packets, clock_.TimeInMicroseconds());
|
||||
@ -243,10 +258,11 @@ bool RemoteBitrateEstimatorTest::GenerateAndProcessFrame(unsigned int ssrc,
|
||||
}
|
||||
}
|
||||
bitrate_observer_->Reset();
|
||||
bitrate_estimator_->IncomingPacket(packet->ssrc,
|
||||
packet->size,
|
||||
(packet->arrival_time + 500) / 1000,
|
||||
packet->rtp_timestamp);
|
||||
IncomingPacket(packet->ssrc,
|
||||
packet->size,
|
||||
(packet->arrival_time + 500) / 1000,
|
||||
packet->rtp_timestamp,
|
||||
AbsSendTime(packet->send_time, 1000000));
|
||||
if (bitrate_observer_->updated()) {
|
||||
// Verify that new estimates only are triggered by an overuse and a
|
||||
// rate decrease.
|
||||
@ -295,4 +311,193 @@ unsigned int RemoteBitrateEstimatorTest::SteadyStateRun(
|
||||
EXPECT_TRUE(bitrate_update_seen);
|
||||
return bitrate_bps;
|
||||
}
|
||||
|
||||
void RemoteBitrateEstimatorTest::InitialBehaviorTestHelper(
|
||||
unsigned int expected_converge_bitrate) {
|
||||
const int kFramerate = 50; // 50 fps to avoid rounding errors.
|
||||
const int kFrameIntervalMs = 1000 / kFramerate;
|
||||
const uint32_t kFrameIntervalAbsSendTime = AbsSendTime(1, kFramerate);
|
||||
unsigned int bitrate_bps = 0;
|
||||
uint32_t timestamp = 0;
|
||||
uint32_t absolute_send_time = 0;
|
||||
std::vector<unsigned int> ssrcs;
|
||||
EXPECT_FALSE(bitrate_estimator_->LatestEstimate(&ssrcs, &bitrate_bps));
|
||||
EXPECT_EQ(0u, ssrcs.size());
|
||||
clock_.AdvanceTimeMilliseconds(1000);
|
||||
bitrate_estimator_->Process();
|
||||
EXPECT_FALSE(bitrate_estimator_->LatestEstimate(&ssrcs, &bitrate_bps));
|
||||
EXPECT_FALSE(bitrate_observer_->updated());
|
||||
bitrate_observer_->Reset();
|
||||
clock_.AdvanceTimeMilliseconds(1000);
|
||||
// Inserting a packet. Still no valid estimate. We need to wait 1 second.
|
||||
IncomingPacket(kDefaultSsrc, kMtu, clock_.TimeInMilliseconds(), timestamp,
|
||||
absolute_send_time);
|
||||
bitrate_estimator_->Process();
|
||||
EXPECT_FALSE(bitrate_estimator_->LatestEstimate(&ssrcs, &bitrate_bps));
|
||||
EXPECT_EQ(0u, ssrcs.size());
|
||||
EXPECT_FALSE(bitrate_observer_->updated());
|
||||
bitrate_observer_->Reset();
|
||||
// Inserting packets for one second to get a valid estimate.
|
||||
for (int i = 0; i < kFramerate; ++i) {
|
||||
IncomingPacket(kDefaultSsrc, kMtu, clock_.TimeInMilliseconds(), timestamp,
|
||||
absolute_send_time);
|
||||
clock_.AdvanceTimeMilliseconds(1000 / kFramerate);
|
||||
timestamp += 90 * kFrameIntervalMs;
|
||||
absolute_send_time = AddAbsSendTime(absolute_send_time,
|
||||
kFrameIntervalAbsSendTime);
|
||||
}
|
||||
bitrate_estimator_->Process();
|
||||
EXPECT_TRUE(bitrate_estimator_->LatestEstimate(&ssrcs, &bitrate_bps));
|
||||
ASSERT_EQ(1u, ssrcs.size());
|
||||
EXPECT_EQ(kDefaultSsrc, ssrcs.front());
|
||||
EXPECT_EQ(expected_converge_bitrate, bitrate_bps);
|
||||
EXPECT_TRUE(bitrate_observer_->updated());
|
||||
bitrate_observer_->Reset();
|
||||
EXPECT_EQ(bitrate_observer_->latest_bitrate(), bitrate_bps);
|
||||
}
|
||||
|
||||
void RemoteBitrateEstimatorTest::RateIncreaseReorderingTestHelper() {
|
||||
const int kFramerate = 50; // 50 fps to avoid rounding errors.
|
||||
const int kFrameIntervalMs = 1000 / kFramerate;
|
||||
const uint32_t kFrameIntervalAbsSendTime = AbsSendTime(1, kFramerate);
|
||||
uint32_t timestamp = 0;
|
||||
uint32_t absolute_send_time = 0;
|
||||
IncomingPacket(kDefaultSsrc, 1000, clock_.TimeInMilliseconds(), timestamp,
|
||||
absolute_send_time);
|
||||
bitrate_estimator_->Process();
|
||||
EXPECT_FALSE(bitrate_observer_->updated()); // No valid estimate.
|
||||
// Inserting packets for one second to get a valid estimate.
|
||||
for (int i = 0; i < kFramerate; ++i) {
|
||||
IncomingPacket(kDefaultSsrc, kMtu, clock_.TimeInMilliseconds(), timestamp,
|
||||
absolute_send_time);
|
||||
clock_.AdvanceTimeMilliseconds(kFrameIntervalMs);
|
||||
timestamp += 90 * kFrameIntervalMs;
|
||||
absolute_send_time = AddAbsSendTime(absolute_send_time,
|
||||
kFrameIntervalAbsSendTime);
|
||||
}
|
||||
bitrate_estimator_->Process();
|
||||
EXPECT_TRUE(bitrate_observer_->updated());
|
||||
EXPECT_EQ(498136u, bitrate_observer_->latest_bitrate());
|
||||
for (int i = 0; i < 10; ++i) {
|
||||
clock_.AdvanceTimeMilliseconds(2 * kFrameIntervalMs);
|
||||
timestamp += 2 * 90 * kFrameIntervalMs;
|
||||
absolute_send_time = AddAbsSendTime(absolute_send_time,
|
||||
2 * kFrameIntervalAbsSendTime);
|
||||
IncomingPacket(kDefaultSsrc, 1000, clock_.TimeInMilliseconds(), timestamp,
|
||||
absolute_send_time);
|
||||
IncomingPacket(kDefaultSsrc, 1000, clock_.TimeInMilliseconds(),
|
||||
timestamp - 90 * kFrameIntervalMs,
|
||||
AddAbsSendTime(absolute_send_time,
|
||||
-int(kFrameIntervalAbsSendTime)));
|
||||
}
|
||||
bitrate_estimator_->Process();
|
||||
EXPECT_TRUE(bitrate_observer_->updated());
|
||||
EXPECT_EQ(498136u, bitrate_observer_->latest_bitrate());
|
||||
}
|
||||
|
||||
// Make sure we initially increase the bitrate as expected.
|
||||
void RemoteBitrateEstimatorTest::RateIncreaseRtpTimestampsTestHelper() {
|
||||
// This threshold corresponds approximately to increasing linearly with
|
||||
// bitrate(i) = 1.04 * bitrate(i-1) + 1000
|
||||
// until bitrate(i) > 500000, with bitrate(1) ~= 30000.
|
||||
const int kExpectedIterations = 1621;
|
||||
unsigned int bitrate_bps = 30000;
|
||||
int iterations = 0;
|
||||
AddDefaultStream();
|
||||
// Feed the estimator with a stream of packets and verify that it reaches
|
||||
// 500 kbps at the expected time.
|
||||
while (bitrate_bps < 5e5) {
|
||||
bool overuse = GenerateAndProcessFrame(kDefaultSsrc, bitrate_bps);
|
||||
if (overuse) {
|
||||
EXPECT_GT(bitrate_observer_->latest_bitrate(), bitrate_bps);
|
||||
bitrate_bps = bitrate_observer_->latest_bitrate();
|
||||
bitrate_observer_->Reset();
|
||||
} else if (bitrate_observer_->updated()) {
|
||||
bitrate_bps = bitrate_observer_->latest_bitrate();
|
||||
bitrate_observer_->Reset();
|
||||
}
|
||||
++iterations;
|
||||
ASSERT_LE(iterations, kExpectedIterations);
|
||||
}
|
||||
ASSERT_EQ(kExpectedIterations, iterations);
|
||||
}
|
||||
|
||||
void RemoteBitrateEstimatorTest::CapacityDropTestHelper(
|
||||
int number_of_streams,
|
||||
bool wrap_time_stamp,
|
||||
unsigned int expected_converge_bitrate,
|
||||
unsigned int expected_bitrate_drop_delta) {
|
||||
const int kFramerate = 30;
|
||||
const int kStartBitrate = 900e3;
|
||||
const int kMinExpectedBitrate = 800e3;
|
||||
const int kMaxExpectedBitrate = 1100e3;
|
||||
const unsigned int kInitialCapacityBps = 1000e3;
|
||||
const unsigned int kReducedCapacityBps = 500e3;
|
||||
|
||||
int steady_state_time = 0;
|
||||
int expected_overuse_start_time = 0;
|
||||
if (number_of_streams <= 1) {
|
||||
steady_state_time = 10;
|
||||
expected_overuse_start_time = 10000;
|
||||
AddDefaultStream();
|
||||
} else {
|
||||
steady_state_time = 8 * number_of_streams;
|
||||
expected_overuse_start_time = 8000;
|
||||
int bitrate_sum = 0;
|
||||
int kBitrateDenom = number_of_streams * (number_of_streams - 1);
|
||||
for (int i = 0; i < number_of_streams; i++) {
|
||||
// First stream gets half available bitrate, while the rest share the
|
||||
// remaining half i.e.: 1/2 = Sum[n/(N*(N-1))] for n=1..N-1 (rounded up)
|
||||
int bitrate = kStartBitrate / 2;
|
||||
if (i > 0) {
|
||||
bitrate = (kStartBitrate * i + kBitrateDenom / 2) / kBitrateDenom;
|
||||
}
|
||||
stream_generator_->AddStream(new testing::RtpStream(
|
||||
kFramerate, // Frames per second.
|
||||
bitrate, // Bitrate.
|
||||
kDefaultSsrc + i, // SSRC.
|
||||
90000, // RTP frequency.
|
||||
0xFFFFF000 ^ (~0 << (32 - i)), // Timestamp offset.
|
||||
0)); // RTCP receive time.
|
||||
bitrate_sum += bitrate;
|
||||
}
|
||||
ASSERT_EQ(bitrate_sum, kStartBitrate);
|
||||
}
|
||||
if (wrap_time_stamp) {
|
||||
stream_generator_->set_rtp_timestamp_offset(kDefaultSsrc,
|
||||
std::numeric_limits<uint32_t>::max() - steady_state_time * 90000);
|
||||
}
|
||||
|
||||
// Run in steady state to make the estimator converge.
|
||||
stream_generator_->set_capacity_bps(kInitialCapacityBps);
|
||||
unsigned int bitrate_bps = SteadyStateRun(kDefaultSsrc,
|
||||
steady_state_time * kFramerate,
|
||||
kStartBitrate,
|
||||
kMinExpectedBitrate,
|
||||
kMaxExpectedBitrate,
|
||||
kInitialCapacityBps);
|
||||
EXPECT_EQ(expected_converge_bitrate, bitrate_bps);
|
||||
bitrate_observer_->Reset();
|
||||
|
||||
// Reduce the capacity and verify the decrease time.
|
||||
stream_generator_->set_capacity_bps(kReducedCapacityBps);
|
||||
int64_t overuse_start_time = clock_.TimeInMilliseconds();
|
||||
EXPECT_EQ(expected_overuse_start_time, overuse_start_time);
|
||||
int64_t bitrate_drop_time = -1;
|
||||
for (int i = 0; i < 100 * number_of_streams; ++i) {
|
||||
GenerateAndProcessFrame(kDefaultSsrc, bitrate_bps);
|
||||
// Check for either increase or decrease.
|
||||
if (bitrate_observer_->updated()) {
|
||||
if (bitrate_drop_time == -1 &&
|
||||
bitrate_observer_->latest_bitrate() <= kReducedCapacityBps) {
|
||||
bitrate_drop_time = clock_.TimeInMilliseconds();
|
||||
}
|
||||
bitrate_bps = bitrate_observer_->latest_bitrate();
|
||||
bitrate_observer_->Reset();
|
||||
}
|
||||
}
|
||||
|
||||
EXPECT_EQ(expected_bitrate_drop_delta,
|
||||
bitrate_drop_time - overuse_start_time);
|
||||
}
|
||||
} // namespace webrtc
|
||||
|
@ -23,17 +23,15 @@
|
||||
#include "webrtc/system_wrappers/interface/scoped_ptr.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
enum { kMtu = 1200 };
|
||||
|
||||
namespace testing {
|
||||
|
||||
class TestBitrateObserver : public RemoteBitrateObserver {
|
||||
public:
|
||||
TestBitrateObserver() : updated_(false), latest_bitrate_(0) {}
|
||||
virtual ~TestBitrateObserver() {}
|
||||
|
||||
void OnReceiveBitrateChanged(std::vector<unsigned int>* ssrcs,
|
||||
unsigned int bitrate) {
|
||||
virtual void OnReceiveBitrateChanged(const std::vector<unsigned int>& ssrcs,
|
||||
unsigned int bitrate) {
|
||||
latest_bitrate_ = bitrate;
|
||||
updated_ = true;
|
||||
}
|
||||
@ -55,7 +53,6 @@ class TestBitrateObserver : public RemoteBitrateObserver {
|
||||
unsigned int latest_bitrate_;
|
||||
};
|
||||
|
||||
|
||||
class RtpStream {
|
||||
public:
|
||||
struct RtpPacket {
|
||||
@ -132,7 +129,7 @@ class StreamGenerator {
|
||||
|
||||
// Divides |bitrate_bps| among all streams. The allocated bitrate per stream
|
||||
// is decided by the initial allocation ratios.
|
||||
void set_bitrate_bps(int bitrate_bps);
|
||||
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);
|
||||
@ -160,13 +157,30 @@ class StreamGenerator {
|
||||
class RemoteBitrateEstimatorTest : public ::testing::Test {
|
||||
public:
|
||||
RemoteBitrateEstimatorTest();
|
||||
explicit RemoteBitrateEstimatorTest(bool align_streams);
|
||||
|
||||
protected:
|
||||
virtual void SetUp();
|
||||
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,
|
||||
uint32_t payload_size,
|
||||
int64_t arrival_time,
|
||||
uint32_t rtp_timestamp,
|
||||
uint32_t absolute_send_time);
|
||||
|
||||
// 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.
|
||||
@ -186,25 +200,24 @@ class RemoteBitrateEstimatorTest : public ::testing::Test {
|
||||
unsigned int max_bitrate,
|
||||
unsigned int target_bitrate);
|
||||
|
||||
void InitialBehaviorTestHelper(unsigned int expected_converge_bitrate);
|
||||
void RateIncreaseReorderingTestHelper();
|
||||
void RateIncreaseRtpTimestampsTestHelper();
|
||||
void CapacityDropTestHelper(int number_of_streams,
|
||||
bool wrap_time_stamp,
|
||||
unsigned int expected_converge_bitrate,
|
||||
unsigned int expected_bitrate_drop_delta);
|
||||
|
||||
static const unsigned int kDefaultSsrc;
|
||||
|
||||
SimulatedClock clock_; // Time at the receiver.
|
||||
OverUseDetectorOptions overuse_detector_options_;
|
||||
scoped_ptr<RemoteBitrateEstimator> bitrate_estimator_;
|
||||
bool align_streams_;
|
||||
scoped_ptr<testing::TestBitrateObserver> bitrate_observer_;
|
||||
scoped_ptr<RemoteBitrateEstimator> bitrate_estimator_;
|
||||
scoped_ptr<testing::StreamGenerator> stream_generator_;
|
||||
const bool align_streams_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(RemoteBitrateEstimatorTest);
|
||||
};
|
||||
|
||||
class RemoteBitrateEstimatorTestAlign : public RemoteBitrateEstimatorTest {
|
||||
public:
|
||||
RemoteBitrateEstimatorTestAlign() : RemoteBitrateEstimatorTest(true) {}
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(RemoteBitrateEstimatorTestAlign);
|
||||
};
|
||||
} // namespace testing
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // WEBRTC_MODULES_REMOTE_BITRATE_ESTIMATOR_REMOTE_BITRATE_ESTIMATOR_UNITTEST_HELPER_H_
|
||||
|
@ -268,12 +268,12 @@ double RemoteRateControl::RateIncreaseFactor(int64_t now_ms,
|
||||
}
|
||||
|
||||
void RemoteRateControl::UpdateChangePeriod(int64_t now_ms) {
|
||||
int64_t changePeriod = 0;
|
||||
int64_t change_period = 0;
|
||||
if (last_change_ms_ > -1) {
|
||||
changePeriod = now_ms - last_change_ms_;
|
||||
change_period = now_ms - last_change_ms_;
|
||||
}
|
||||
last_change_ms_ = now_ms;
|
||||
avg_change_period_ = 0.9f * avg_change_period_ + 0.1f * changePeriod;
|
||||
avg_change_period_ = 0.9f * avg_change_period_ + 0.1f * change_period;
|
||||
}
|
||||
|
||||
void RemoteRateControl::UpdateMaxBitRateEstimate(float incoming_bit_rate_kbps) {
|
||||
@ -288,8 +288,8 @@ void RemoteRateControl::UpdateMaxBitRateEstimate(float incoming_bit_rate_kbps) {
|
||||
// with the average max bit rate.
|
||||
const float norm = std::max(avg_max_bit_rate_, 1.0f);
|
||||
var_max_bit_rate_ = (1 - alpha) * var_max_bit_rate_ +
|
||||
alpha * (avg_max_bit_rate_ - incoming_bit_rate_kbps) *
|
||||
(avg_max_bit_rate_ - incoming_bit_rate_kbps) / norm;
|
||||
alpha * (avg_max_bit_rate_ - incoming_bit_rate_kbps) *
|
||||
(avg_max_bit_rate_ - incoming_bit_rate_kbps) / norm;
|
||||
// 0.4 ~= 14 kbit/s at 500 kbit/s
|
||||
if (var_max_bit_rate_ < 0.4f) {
|
||||
var_max_bit_rate_ = 0.4f;
|
||||
@ -347,7 +347,7 @@ void RemoteRateControl::ChangeState(RateControlState new_state) {
|
||||
StateStr(rate_control_state_, state2);
|
||||
StateStr(current_input_._bwState, state3);
|
||||
WEBRTC_TRACE(kTraceStream, kTraceRtpRtcp, -1,
|
||||
"\t%s => %s due to %s\n", state1, state2, state3);
|
||||
"\t%s => %s due to %s\n", state1, state2, state3);
|
||||
}
|
||||
|
||||
void RemoteRateControl::StateStr(RateControlState state, char* str) {
|
||||
|
@ -115,11 +115,8 @@ int32_t ViEReceiver::OnReceivedPayloadData(
|
||||
// TODO(holmer): Make sure packets reconstructed using FEC are not passed to
|
||||
// the bandwidth estimator.
|
||||
const int packet_size = payload_size + rtp_header->header.paddingLength;
|
||||
uint32_t compensated_timestamp = rtp_header->header.timestamp +
|
||||
rtp_header->extension.transmissionTimeOffset;
|
||||
remote_bitrate_estimator_->IncomingPacket(
|
||||
rtp_header->header.ssrc, packet_size,
|
||||
TickTime::MillisecondTimestamp(), compensated_timestamp);
|
||||
remote_bitrate_estimator_->IncomingPacket(TickTime::MillisecondTimestamp(),
|
||||
packet_size, *rtp_header);
|
||||
if (vcm_->IncomingPacket(payload_data, payload_size, *rtp_header) != 0) {
|
||||
// Check this...
|
||||
return -1;
|
||||
|
@ -104,11 +104,10 @@ bool VieRemb::InUse() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
void VieRemb::OnReceiveBitrateChanged(std::vector<unsigned int>* ssrcs,
|
||||
void VieRemb::OnReceiveBitrateChanged(const std::vector<unsigned int>& ssrcs,
|
||||
unsigned int bitrate) {
|
||||
WEBRTC_TRACE(kTraceStream, kTraceVideo, -1,
|
||||
"VieRemb::UpdateBitrateEstimate(bitrate: %u)", bitrate);
|
||||
assert(ssrcs);
|
||||
list_crit_->Enter();
|
||||
// If we already have an estimate, check if the new total estimate is below
|
||||
// kSendThresholdPercent of the previous estimate.
|
||||
@ -132,7 +131,7 @@ void VieRemb::OnReceiveBitrateChanged(std::vector<unsigned int>* ssrcs,
|
||||
}
|
||||
last_remb_time_ = now;
|
||||
|
||||
if (ssrcs->empty() || receive_modules_.empty()) {
|
||||
if (ssrcs.empty() || receive_modules_.empty()) {
|
||||
list_crit_->Leave();
|
||||
return;
|
||||
}
|
||||
@ -154,8 +153,8 @@ void VieRemb::OnReceiveBitrateChanged(std::vector<unsigned int>* ssrcs,
|
||||
list_crit_->Leave();
|
||||
|
||||
if (sender) {
|
||||
// TODO(holmer): Change RTP module API to take a vector pointer.
|
||||
sender->SetREMBData(bitrate_, ssrcs->size(), &(*ssrcs)[0]);
|
||||
// TODO(holmer): Change RTP module API to take a const vector reference.
|
||||
sender->SetREMBData(bitrate_, ssrcs.size(), &ssrcs[0]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -51,7 +51,7 @@ class VieRemb : public RemoteBitrateObserver {
|
||||
// estimate has decreased or if no RTCP REMB packet has been sent for
|
||||
// a certain time interval.
|
||||
// Implements RtpReceiveBitrateUpdate.
|
||||
virtual void OnReceiveBitrateChanged(std::vector<unsigned int>* ssrcs,
|
||||
virtual void OnReceiveBitrateChanged(const std::vector<unsigned int>& ssrcs,
|
||||
unsigned int bitrate);
|
||||
|
||||
private:
|
||||
|
@ -59,17 +59,17 @@ TEST_F(ViERembTest, OneModuleTestForSendingRemb) {
|
||||
unsigned int ssrc = 1234;
|
||||
std::vector<unsigned int> ssrcs(&ssrc, &ssrc + 1);
|
||||
|
||||
vie_remb_->OnReceiveBitrateChanged(&ssrcs, bitrate_estimate);
|
||||
vie_remb_->OnReceiveBitrateChanged(ssrcs, bitrate_estimate);
|
||||
|
||||
TickTime::AdvanceFakeClock(1000);
|
||||
EXPECT_CALL(rtp, SetREMBData(bitrate_estimate, 1, _))
|
||||
.Times(1);
|
||||
vie_remb_->OnReceiveBitrateChanged(&ssrcs, bitrate_estimate);
|
||||
vie_remb_->OnReceiveBitrateChanged(ssrcs, bitrate_estimate);
|
||||
|
||||
// Lower bitrate to send another REMB packet.
|
||||
EXPECT_CALL(rtp, SetREMBData(bitrate_estimate - 100, 1, _))
|
||||
.Times(1);
|
||||
vie_remb_->OnReceiveBitrateChanged(&ssrcs, bitrate_estimate - 100);
|
||||
vie_remb_->OnReceiveBitrateChanged(ssrcs, bitrate_estimate - 100);
|
||||
|
||||
vie_remb_->RemoveReceiveChannel(&rtp);
|
||||
vie_remb_->RemoveRembSender(&rtp);
|
||||
@ -84,19 +84,19 @@ TEST_F(ViERembTest, LowerEstimateToSendRemb) {
|
||||
unsigned int ssrc = 1234;
|
||||
std::vector<unsigned int> ssrcs(&ssrc, &ssrc + 1);
|
||||
|
||||
vie_remb_->OnReceiveBitrateChanged(&ssrcs, bitrate_estimate);
|
||||
vie_remb_->OnReceiveBitrateChanged(ssrcs, bitrate_estimate);
|
||||
// Call OnReceiveBitrateChanged twice to get a first estimate.
|
||||
TickTime::AdvanceFakeClock(1000);
|
||||
EXPECT_CALL(rtp, SetREMBData(bitrate_estimate, 1, _))
|
||||
.Times(1);
|
||||
vie_remb_->OnReceiveBitrateChanged(&ssrcs, bitrate_estimate);
|
||||
vie_remb_->OnReceiveBitrateChanged(ssrcs, bitrate_estimate);
|
||||
|
||||
// Lower the estimate with more than 3% to trigger a call to SetREMBData right
|
||||
// away.
|
||||
bitrate_estimate = bitrate_estimate - 100;
|
||||
EXPECT_CALL(rtp, SetREMBData(bitrate_estimate, 1, _))
|
||||
.Times(1);
|
||||
vie_remb_->OnReceiveBitrateChanged(&ssrcs, bitrate_estimate);
|
||||
vie_remb_->OnReceiveBitrateChanged(ssrcs, bitrate_estimate);
|
||||
}
|
||||
|
||||
TEST_F(ViERembTest, VerifyIncreasingAndDecreasing) {
|
||||
@ -110,20 +110,20 @@ TEST_F(ViERembTest, VerifyIncreasingAndDecreasing) {
|
||||
unsigned int ssrc[] = { 1234, 5678 };
|
||||
std::vector<unsigned int> ssrcs(ssrc, ssrc + sizeof(ssrc) / sizeof(ssrc[0]));
|
||||
|
||||
vie_remb_->OnReceiveBitrateChanged(&ssrcs, bitrate_estimate[0]);
|
||||
vie_remb_->OnReceiveBitrateChanged(ssrcs, bitrate_estimate[0]);
|
||||
|
||||
// Call OnReceiveBitrateChanged twice to get a first estimate.
|
||||
EXPECT_CALL(rtp_0, SetREMBData(bitrate_estimate[0], 2, _))
|
||||
.Times(1);
|
||||
TickTime::AdvanceFakeClock(1000);
|
||||
vie_remb_->OnReceiveBitrateChanged(&ssrcs, bitrate_estimate[0]);
|
||||
vie_remb_->OnReceiveBitrateChanged(ssrcs, bitrate_estimate[0]);
|
||||
|
||||
vie_remb_->OnReceiveBitrateChanged(&ssrcs, bitrate_estimate[1] + 100);
|
||||
vie_remb_->OnReceiveBitrateChanged(ssrcs, bitrate_estimate[1] + 100);
|
||||
|
||||
// Lower the estimate to trigger a callback.
|
||||
EXPECT_CALL(rtp_0, SetREMBData(bitrate_estimate[1], 2, _))
|
||||
.Times(1);
|
||||
vie_remb_->OnReceiveBitrateChanged(&ssrcs, bitrate_estimate[1]);
|
||||
vie_remb_->OnReceiveBitrateChanged(ssrcs, bitrate_estimate[1]);
|
||||
|
||||
vie_remb_->RemoveReceiveChannel(&rtp_0);
|
||||
vie_remb_->RemoveRembSender(&rtp_0);
|
||||
@ -141,23 +141,23 @@ TEST_F(ViERembTest, NoRembForIncreasedBitrate) {
|
||||
unsigned int ssrc[] = { 1234, 5678 };
|
||||
std::vector<unsigned int> ssrcs(ssrc, ssrc + sizeof(ssrc) / sizeof(ssrc[0]));
|
||||
|
||||
vie_remb_->OnReceiveBitrateChanged(&ssrcs, bitrate_estimate);
|
||||
vie_remb_->OnReceiveBitrateChanged(ssrcs, bitrate_estimate);
|
||||
// Call OnReceiveBitrateChanged twice to get a first estimate.
|
||||
TickTime::AdvanceFakeClock(1000);
|
||||
EXPECT_CALL(rtp_0, SetREMBData(bitrate_estimate, 2, _))
|
||||
.Times(1);
|
||||
vie_remb_->OnReceiveBitrateChanged(&ssrcs, bitrate_estimate);
|
||||
vie_remb_->OnReceiveBitrateChanged(ssrcs, bitrate_estimate);
|
||||
|
||||
// Increased estimate shouldn't trigger a callback right away.
|
||||
EXPECT_CALL(rtp_0, SetREMBData(_, _, _))
|
||||
.Times(0);
|
||||
vie_remb_->OnReceiveBitrateChanged(&ssrcs, bitrate_estimate + 1);
|
||||
vie_remb_->OnReceiveBitrateChanged(ssrcs, bitrate_estimate + 1);
|
||||
|
||||
// Decreasing the estimate less than 3% shouldn't trigger a new callback.
|
||||
EXPECT_CALL(rtp_0, SetREMBData(_, _, _))
|
||||
.Times(0);
|
||||
int lower_estimate = bitrate_estimate * 98 / 100;
|
||||
vie_remb_->OnReceiveBitrateChanged(&ssrcs, lower_estimate);
|
||||
vie_remb_->OnReceiveBitrateChanged(ssrcs, lower_estimate);
|
||||
|
||||
vie_remb_->RemoveReceiveChannel(&rtp_1);
|
||||
vie_remb_->RemoveReceiveChannel(&rtp_0);
|
||||
@ -175,29 +175,29 @@ TEST_F(ViERembTest, ChangeSendRtpModule) {
|
||||
unsigned int ssrc[] = { 1234, 5678 };
|
||||
std::vector<unsigned int> ssrcs(ssrc, ssrc + sizeof(ssrc) / sizeof(ssrc[0]));
|
||||
|
||||
vie_remb_->OnReceiveBitrateChanged(&ssrcs, bitrate_estimate);
|
||||
vie_remb_->OnReceiveBitrateChanged(ssrcs, bitrate_estimate);
|
||||
// Call OnReceiveBitrateChanged twice to get a first estimate.
|
||||
TickTime::AdvanceFakeClock(1000);
|
||||
EXPECT_CALL(rtp_0, SetREMBData(bitrate_estimate, 2, _))
|
||||
.Times(1);
|
||||
vie_remb_->OnReceiveBitrateChanged(&ssrcs, bitrate_estimate);
|
||||
vie_remb_->OnReceiveBitrateChanged(ssrcs, bitrate_estimate);
|
||||
|
||||
// Decrease estimate to trigger a REMB.
|
||||
bitrate_estimate = bitrate_estimate - 100;
|
||||
EXPECT_CALL(rtp_0, SetREMBData(bitrate_estimate, 2, _))
|
||||
.Times(1);
|
||||
vie_remb_->OnReceiveBitrateChanged(&ssrcs, bitrate_estimate);
|
||||
vie_remb_->OnReceiveBitrateChanged(ssrcs, bitrate_estimate);
|
||||
|
||||
// Remove the sending module, add it again -> should get remb on the second
|
||||
// module.
|
||||
vie_remb_->RemoveRembSender(&rtp_0);
|
||||
vie_remb_->AddRembSender(&rtp_1);
|
||||
vie_remb_->OnReceiveBitrateChanged(&ssrcs, bitrate_estimate);
|
||||
vie_remb_->OnReceiveBitrateChanged(ssrcs, bitrate_estimate);
|
||||
|
||||
bitrate_estimate = bitrate_estimate - 100;
|
||||
EXPECT_CALL(rtp_1, SetREMBData(bitrate_estimate, 2, _))
|
||||
.Times(1);
|
||||
vie_remb_->OnReceiveBitrateChanged(&ssrcs, bitrate_estimate);
|
||||
vie_remb_->OnReceiveBitrateChanged(ssrcs, bitrate_estimate);
|
||||
|
||||
vie_remb_->RemoveReceiveChannel(&rtp_0);
|
||||
vie_remb_->RemoveReceiveChannel(&rtp_1);
|
||||
@ -211,23 +211,23 @@ TEST_F(ViERembTest, OnlyOneRembForDoubleProcess) {
|
||||
|
||||
vie_remb_->AddReceiveChannel(&rtp);
|
||||
vie_remb_->AddRembSender(&rtp);
|
||||
vie_remb_->OnReceiveBitrateChanged(&ssrcs, bitrate_estimate);
|
||||
vie_remb_->OnReceiveBitrateChanged(ssrcs, bitrate_estimate);
|
||||
// Call OnReceiveBitrateChanged twice to get a first estimate.
|
||||
TickTime::AdvanceFakeClock(1000);
|
||||
EXPECT_CALL(rtp, SetREMBData(_, _, _))
|
||||
.Times(1);
|
||||
vie_remb_->OnReceiveBitrateChanged(&ssrcs, bitrate_estimate);
|
||||
vie_remb_->OnReceiveBitrateChanged(ssrcs, bitrate_estimate);
|
||||
|
||||
// Lower the estimate, should trigger a call to SetREMBData right away.
|
||||
bitrate_estimate = bitrate_estimate - 100;
|
||||
EXPECT_CALL(rtp, SetREMBData(bitrate_estimate, 1, _))
|
||||
.Times(1);
|
||||
vie_remb_->OnReceiveBitrateChanged(&ssrcs, bitrate_estimate);
|
||||
vie_remb_->OnReceiveBitrateChanged(ssrcs, bitrate_estimate);
|
||||
|
||||
// Call OnReceiveBitrateChanged again, this should not trigger a new callback.
|
||||
EXPECT_CALL(rtp, SetREMBData(_, _, _))
|
||||
.Times(0);
|
||||
vie_remb_->OnReceiveBitrateChanged(&ssrcs, bitrate_estimate);
|
||||
vie_remb_->OnReceiveBitrateChanged(ssrcs, bitrate_estimate);
|
||||
vie_remb_->RemoveReceiveChannel(&rtp);
|
||||
vie_remb_->RemoveRembSender(&rtp);
|
||||
}
|
||||
@ -242,19 +242,19 @@ TEST_F(ViERembTest, NoSendingRtpModule) {
|
||||
unsigned int ssrc = 1234;
|
||||
std::vector<unsigned int> ssrcs(&ssrc, &ssrc + 1);
|
||||
|
||||
vie_remb_->OnReceiveBitrateChanged(&ssrcs, bitrate_estimate);
|
||||
vie_remb_->OnReceiveBitrateChanged(ssrcs, bitrate_estimate);
|
||||
|
||||
// Call OnReceiveBitrateChanged twice to get a first estimate.
|
||||
TickTime::AdvanceFakeClock(1000);
|
||||
EXPECT_CALL(rtp, SetREMBData(_, _, _))
|
||||
.Times(1);
|
||||
vie_remb_->OnReceiveBitrateChanged(&ssrcs, bitrate_estimate);
|
||||
vie_remb_->OnReceiveBitrateChanged(ssrcs, bitrate_estimate);
|
||||
|
||||
// Lower the estimate to trigger a new packet REMB packet.
|
||||
bitrate_estimate = bitrate_estimate - 100;
|
||||
EXPECT_CALL(rtp, SetREMBData(_, _, _))
|
||||
.Times(1);
|
||||
vie_remb_->OnReceiveBitrateChanged(&ssrcs, bitrate_estimate);
|
||||
vie_remb_->OnReceiveBitrateChanged(ssrcs, bitrate_estimate);
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
|
Loading…
x
Reference in New Issue
Block a user