Index: webrtc/video/end_to_end_tests.cc |
diff --git a/webrtc/video/end_to_end_tests.cc b/webrtc/video/end_to_end_tests.cc |
index e5b12ce0b1e96027dfac849543c2965303307bca..ac2af53c38e26c34469a83c0ba84ac917d9b2982 100644 |
--- a/webrtc/video/end_to_end_tests.cc |
+++ b/webrtc/video/end_to_end_tests.cc |
@@ -25,6 +25,7 @@ |
#include "webrtc/modules/include/module_common_types.h" |
#include "webrtc/modules/rtp_rtcp/include/rtp_rtcp.h" |
#include "webrtc/modules/rtp_rtcp/source/byte_io.h" |
+#include "webrtc/modules/rtp_rtcp/source/rtp_utility.h" |
#include "webrtc/modules/rtp_rtcp/source/rtcp_utility.h" |
#include "webrtc/modules/video_coding/codecs/h264/include/h264.h" |
#include "webrtc/modules/video_coding/codecs/vp8/include/vp8.h" |
@@ -2498,6 +2499,119 @@ TEST_F(EndToEndTest, ReportsSetEncoderRates) { |
RunBaseTest(&test); |
} |
+class MinTransmitBitrateTest : public test::EndToEndTest, |
perkj_webrtc
2016/07/04 07:24:49
Why is this not a VideoSendStream test? What is th
perkj_webrtc
2016/07/04 07:24:49
How about testing padding instead? There are test
sprang_webrtc
2016/07/04 09:08:47
I did that at first, it turned out to flake way to
sprang_webrtc
2016/07/04 09:08:47
I initially had planned to check received padding,
|
+ public test::FakeEncoder { |
+ public: |
+ static const uint32_t kMinTransmitBitrateBps = 400000; |
+ static const uint32_t kActualEncodeBitrateBps = 40000; |
+ static const uint32_t kMinFramesToSend = 10; |
+ |
+ explicit MinTransmitBitrateTest(bool run_init_phase_without_mtb) |
perkj_webrtc
2016/07/04 07:24:49
bool test_switch_content_type ?
sprang_webrtc
2016/07/04 09:08:47
Done.
|
+ : EndToEndTest(test::CallTest::kDefaultTimeoutMs), |
+ FakeEncoder(Clock::GetRealTimeClock()), |
+ call_(nullptr), |
+ send_stream_(nullptr), |
+ frames_sent_(0), |
+ in_init_phase_(run_init_phase_without_mtb) {} |
+ |
+ void OnVideoStreamsCreated( |
+ VideoSendStream* send_stream, |
+ const std::vector<VideoReceiveStream*>& receive_streams) override { |
+ send_stream_ = send_stream; |
+ } |
+ |
+ void ModifyVideoConfigs( |
+ VideoSendStream::Config* send_config, |
+ std::vector<VideoReceiveStream::Config>* receive_configs, |
+ VideoEncoderConfig* encoder_config) override { |
+ send_config->encoder_settings.encoder = this; |
+ RTC_DCHECK_EQ(1u, encoder_config->streams.size()); |
+ encoder_config->streams[0].target_bitrate_bps = kMinTransmitBitrateBps * 2; |
+ encoder_config->streams[0].max_bitrate_bps = kMinTransmitBitrateBps * 4; |
+ if (in_init_phase_) { |
+ encoder_config->min_transmit_bitrate_bps = 0; |
+ encoder_config->content_type = |
+ VideoEncoderConfig::ContentType::kRealtimeVideo; |
+ } else { |
+ encoder_config->min_transmit_bitrate_bps = kMinTransmitBitrateBps; |
+ encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen; |
+ } |
+ encoder_config_ = *encoder_config; |
+ } |
+ |
+ int32_t SetRates(uint32_t new_target_bitrate, uint32_t framerate) override { |
+ // Make sure not to trigger on any default zero bitrates. |
+ if (new_target_bitrate == 0) |
+ return 0; |
+ rtc::CritScope lock(&crit_); |
+ return FakeEncoder::SetRates( |
+ std::min<uint32_t>(new_target_bitrate, kActualEncodeBitrateBps / 1000), |
+ framerate); |
+ } |
+ |
+ int32_t Encode(const VideoFrame& input_image, |
+ const CodecSpecificInfo* codec_specific_info, |
+ const std::vector<FrameType>* frame_types) override { |
+ int32_t res = |
+ FakeEncoder::Encode(input_image, codec_specific_info, frame_types); |
+ CheckDoneState(); |
+ return res; |
+ } |
+ |
+ void OnCallsCreated(Call* sender_call, Call* receiver_call) override { |
+ call_ = sender_call; |
+ } |
+ |
+ void CheckDoneState() { |
+ rtc::CritScope lock(&crit_); |
+ |
+ if (in_init_phase_) |
+ EXPECT_EQ(0, call_->GetStats().min_transmit_bitrate_bps); |
+ |
+ // Wait until at least kMinFramesToSend frames have been encoded, so that |
+ // we have reliable data. |
+ if (++frames_sent_ < kMinFramesToSend) |
+ return; |
+ |
+ if (in_init_phase_) { |
+ // We've sent kMinFramesToSend frames with default configuration, switch |
+ // to enabling screen content and setting min transmit bitrate. |
+ frames_sent_ = 0; |
+ encoder_config_.min_transmit_bitrate_bps = kMinTransmitBitrateBps; |
+ encoder_config_.content_type = VideoEncoderConfig::ContentType::kScreen; |
+ send_stream_->ReconfigureVideoEncoder(encoder_config_); |
+ in_init_phase_ = false; |
+ return; |
+ } |
+ |
+ // Make sure the pacer has been configured with a min transmit bitrate. |
+ if (call_->GetStats().min_transmit_bitrate_bps > 0) |
+ observation_complete_.Set(); |
+ } |
+ |
+ void PerformTest() override { |
+ ASSERT_TRUE(Wait()) << "Timed out waiting for a valid padding bitrate."; |
+ } |
+ |
+ private: |
+ rtc::CriticalSection crit_; |
+ Call* call_; |
+ VideoSendStream* send_stream_; |
+ VideoEncoderConfig encoder_config_; |
+ uint32_t frames_sent_ GUARDED_BY(crit_); |
+ bool in_init_phase_; |
+}; |
+ |
+TEST_F(EndToEndTest, RespectsMinTransmitBitrate) { |
+ MinTransmitBitrateTest test(false); |
+ RunBaseTest(&test); |
+} |
+ |
+TEST_F(EndToEndTest, RespectsMinTransmitBitrateAfterContentSwitch) { |
+ MinTransmitBitrateTest test(true); |
+ RunBaseTest(&test); |
+} |
+ |
TEST_F(EndToEndTest, GetStats) { |
static const int kStartBitrateBps = 3000000; |
static const int kExpectedRenderDelayMs = 20; |