Implements start bitrate for new video API.

Added  a new rampup test.

BUG=2879
R=pbos@webrtc.org

Review URL: https://webrtc-codereview.appspot.com/15769004

git-svn-id: http://webrtc.googlecode.com/svn/trunk@6443 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
mflodman@webrtc.org 2014-06-16 08:57:39 +00:00
parent 0a1e7e0b00
commit eb16b811fb
6 changed files with 71 additions and 20 deletions

View File

@ -61,7 +61,8 @@ class Call {
: webrtc_config(NULL),
send_transport(send_transport),
voice_engine(NULL),
overuse_callback(NULL) {}
overuse_callback(NULL),
start_bitrate_bps(-1) {}
webrtc::Config* webrtc_config;
@ -73,6 +74,11 @@ class Call {
// Callback for overuse and normal usage based on the jitter of incoming
// captured frames. 'NULL' disables the callback.
OveruseCallback* overuse_callback;
// Start bitrate used before a valid bitrate estimate is calculated. '-1'
// lets the call decide start bitrate.
// Note: This currently only affects video.
int start_bitrate_bps;
};
static Call* Create(const Call::Config& config);

View File

@ -131,6 +131,8 @@ Call* Call::Create(const Call::Config& config) {
namespace internal {
const int kDefaultVideoStreamBitrateBps = 300000;
Call::Call(webrtc::VideoEngine* video_engine, const Call::Config& config)
: config_(config),
receive_lock_(RWLockWrapper::CreateRWLock()),
@ -182,14 +184,18 @@ VideoSendStream* Call::CreateVideoSendStream(
const void* encoder_settings) {
assert(config.rtp.ssrcs.size() > 0);
VideoSendStream* send_stream =
new VideoSendStream(config_.send_transport,
overuse_observer_proxy_.get(),
video_engine_,
config,
video_streams,
encoder_settings,
base_channel_id_);
// TODO(mflodman): Base the start bitrate on a current bandwidth estimate, if
// the call has already started.
VideoSendStream* send_stream = new VideoSendStream(
config_.send_transport,
overuse_observer_proxy_.get(),
video_engine_,
config,
video_streams,
encoder_settings,
base_channel_id_,
config_.start_bitrate_bps != -1 ? config_.start_bitrate_bps
: kDefaultVideoStreamBitrateBps);
WriteLockScoped write_lock(*send_lock_);
for (size_t i = 0; i < config.rtp.ssrcs.size(); ++i) {

View File

@ -61,6 +61,8 @@ void Loopback() {
test::DirectTransport transport;
Call::Config call_config(&transport);
call_config.start_bitrate_bps =
static_cast<int>(flags::StartBitrate()) * 1000;
scoped_ptr<Call> call(Call::Create(call_config));
// Loopback, call sends to itself.

View File

@ -40,6 +40,7 @@ namespace webrtc {
namespace {
static const int kTransmissionTimeOffsetExtensionId = 6;
static const int kMaxPacketSize = 1500;
static const unsigned int kSingleStreamTargetBps = 1000000;
class StreamObserver : public newapi::Transport, public RemoteBitrateObserver {
public:
@ -57,6 +58,7 @@ class StreamObserver : public newapi::Transport, public RemoteBitrateObserver {
new RTPPayloadRegistry(RTPPayloadStrategy::CreateStrategy(false))),
crit_(CriticalSectionWrapper::CreateCriticalSection()),
expected_bitrate_bps_(0),
start_bitrate_bps_(0),
rtx_media_ssrcs_(rtx_media_ssrcs),
total_sent_(0),
padding_sent_(0),
@ -89,10 +91,25 @@ class StreamObserver : public newapi::Transport, public RemoteBitrateObserver {
expected_bitrate_bps_ = expected_bitrate_bps;
}
void set_start_bitrate_bps(unsigned int start_bitrate_bps) {
CriticalSectionScoped lock(crit_.get());
start_bitrate_bps_ = start_bitrate_bps;
}
virtual void OnReceiveBitrateChanged(const std::vector<unsigned int>& ssrcs,
unsigned int bitrate) OVERRIDE {
CriticalSectionScoped lock(crit_.get());
assert(expected_bitrate_bps_ > 0);
if (start_bitrate_bps_ != 0) {
// For tests with an explicitly set start bitrate, verify the first
// bitrate estimate is close to the start bitrate and lower than the
// test target bitrate. This is to verify a call respects the configured
// start bitrate, but due to the BWE implementation we can't guarantee the
// first estimate really is as high as the start bitrate.
EXPECT_GT(bitrate, 0.9 * start_bitrate_bps_);
EXPECT_LT(bitrate, expected_bitrate_bps_);
start_bitrate_bps_ = 0;
}
if (bitrate >= expected_bitrate_bps_) {
// Just trigger if there was any rtx padding packet.
if (rtx_media_ssrcs_.empty() || rtx_media_sent_ > 0) {
@ -178,6 +195,7 @@ class StreamObserver : public newapi::Transport, public RemoteBitrateObserver {
const scoped_ptr<CriticalSectionWrapper> crit_;
unsigned int expected_bitrate_bps_ GUARDED_BY(crit_);
unsigned int start_bitrate_bps_ GUARDED_BY(crit_);
SsrcMap rtx_media_ssrcs_ GUARDED_BY(crit_);
size_t total_sent_ GUARDED_BY(crit_);
size_t padding_sent_ GUARDED_BY(crit_);
@ -400,14 +418,16 @@ class LowRateStreamObserver : public test::DirectTransport,
size_t total_overuse_bytes_ GUARDED_BY(crit_);
bool suspended_in_stats_ GUARDED_BY(crit_);
};
}
} // namespace
class RampUpTest : public ::testing::Test {
public:
virtual void SetUp() { reserved_ssrcs_.clear(); }
protected:
void RunRampUpTest(bool rtx, size_t num_streams) {
void RunRampUpTest(bool rtx,
size_t num_streams,
unsigned int start_bitrate_bps) {
std::vector<uint32_t> ssrcs(GenerateSsrcs(num_streams, 100));
std::vector<uint32_t> rtx_ssrcs(GenerateSsrcs(num_streams, 200));
StreamObserver::SsrcMap rtx_ssrc_map;
@ -421,6 +441,10 @@ class RampUpTest : public ::testing::Test {
Clock::GetRealTimeClock());
Call::Config call_config(&stream_observer);
if (start_bitrate_bps != 0) {
call_config.start_bitrate_bps = start_bitrate_bps;
stream_observer.set_start_bitrate_bps(start_bitrate_bps);
}
scoped_ptr<Call> call(Call::Create(call_config));
VideoSendStream::Config send_config = call->GetDefaultSendConfig();
@ -451,10 +475,10 @@ class RampUpTest : public ::testing::Test {
if (num_streams == 1) {
// For single stream rampup until 1mbps
stream_observer.set_expected_bitrate_bps(1000000);
stream_observer.set_expected_bitrate_bps(kSingleStreamTargetBps);
} else {
// For multi stream rampup until all streams are being sent. That means
// enough birate to sent all the target streams plus the min bitrate of
// enough birate to send all the target streams plus the min bitrate of
// the last one.
int expected_bitrate_bps = video_streams.back().min_bitrate_bps;
for (size_t i = 0; i < video_streams.size() - 1; ++i) {
@ -564,15 +588,19 @@ class RampUpTest : public ::testing::Test {
};
TEST_F(RampUpTest, SingleStream) {
RunRampUpTest(false, 1);
RunRampUpTest(false, 1, 0);
}
TEST_F(RampUpTest, Simulcast) {
RunRampUpTest(false, 3);
RunRampUpTest(false, 3, 0);
}
TEST_F(RampUpTest, SimulcastWithRtx) {
RunRampUpTest(true, 3);
RunRampUpTest(true, 3, 0);
}
TEST_F(RampUpTest, SingleStreamWithHighStartBitrate) {
RunRampUpTest(false, 1, 0.9 * kSingleStreamTargetBps);
}
TEST_F(RampUpTest, UpDownUpOneStream) { RunRampUpDownUpTest(1, false); }

View File

@ -114,16 +114,19 @@ VideoSendStream::VideoSendStream(newapi::Transport* transport,
const VideoSendStream::Config& config,
const std::vector<VideoStream> video_streams,
const void* encoder_settings,
int base_channel)
int base_channel,
int start_bitrate_bps)
: transport_adapter_(transport),
encoded_frame_proxy_(config.post_encode_callback),
config_(config),
start_bitrate_bps_(start_bitrate_bps),
external_codec_(NULL),
channel_(-1),
stats_proxy_(new SendStatisticsProxy(config, this)) {
video_engine_base_ = ViEBase::GetInterface(video_engine);
video_engine_base_->CreateChannel(channel_, base_channel);
assert(channel_ != -1);
assert(start_bitrate_bps_ > 0);
rtp_rtcp_ = ViERTP_RTCP::GetInterface(video_engine);
assert(rtp_rtcp_ != NULL);
@ -350,13 +353,17 @@ bool VideoSendStream::ReconfigureVideoEncoder(
video_codec.qpMax = std::max(video_codec.qpMax,
static_cast<unsigned int>(streams[i].max_qp));
}
video_codec.startBitrate =
static_cast<unsigned int>(start_bitrate_bps_) / 1000;
if (video_codec.minBitrate < kViEMinCodecBitrate)
video_codec.minBitrate = kViEMinCodecBitrate;
if (video_codec.maxBitrate < kViEMinCodecBitrate)
video_codec.maxBitrate = kViEMinCodecBitrate;
video_codec.startBitrate = 300;
if (video_codec.startBitrate < video_codec.minBitrate)
video_codec.startBitrate = video_codec.minBitrate;
if (video_codec.startBitrate > video_codec.maxBitrate)
video_codec.startBitrate = video_codec.maxBitrate;
if (video_codec.startBitrate < video_codec.minBitrate)
video_codec.startBitrate = video_codec.minBitrate;

View File

@ -44,7 +44,8 @@ class VideoSendStream : public webrtc::VideoSendStream,
const VideoSendStream::Config& config,
const std::vector<VideoStream> video_streams,
const void* encoder_settings,
int base_channel);
int base_channel,
int start_bitrate);
virtual ~VideoSendStream();
@ -73,6 +74,7 @@ class VideoSendStream : public webrtc::VideoSendStream,
TransportAdapter transport_adapter_;
EncodedFrameCallbackAdapter encoded_frame_proxy_;
const VideoSendStream::Config config_;
const int start_bitrate_bps_;
ViEBase* video_engine_base_;
ViECapture* capture_;