Implement screencast settings for WebRtcVideoEngine2.

Adds support for screencast_min_bitrate and sets content type
corresponding to the capture type.

R=stefan@webrtc.org
BUG=1788

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

git-svn-id: http://webrtc.googlecode.com/svn/trunk@7529 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
pbos@webrtc.org 2014-10-27 13:58:00 +00:00
parent a37f1dd6b8
commit efc82c2c73
4 changed files with 97 additions and 15 deletions

View File

@ -778,6 +778,7 @@ void WebRtcVideoChannel2::SetDefaultOptions() {
options_.video_noise_reduction.Set(true);
options_.video_start_bitrate.Set(
webrtc::Call::Config::kDefaultStartBitrateBps / 1000);
options_.screencast_min_bitrate.Set(0);
}
WebRtcVideoChannel2::~WebRtcVideoChannel2() {
@ -1672,30 +1673,47 @@ void WebRtcVideoChannel2::WebRtcVideoSendStream::SetRtpExtensions(
void WebRtcVideoChannel2::WebRtcVideoSendStream::SetDimensions(
int width,
int height,
bool override_max) {
bool is_screencast) {
if (last_dimensions_.width == width && last_dimensions_.height == height &&
last_dimensions_.is_screencast == is_screencast) {
// Configured using the same parameters, do not reconfigure.
return;
}
last_dimensions_.width = width;
last_dimensions_.height = height;
last_dimensions_.is_screencast = is_screencast;
assert(!parameters_.encoder_config.streams.empty());
LOG(LS_VERBOSE) << "SetDimensions: " << width << "x" << height;
VideoCodecSettings codec_settings;
parameters_.codec_settings.Get(&codec_settings);
// Restrict dimensions according to codec max.
if (!override_max) {
if (!is_screencast) {
if (codec_settings.codec.width < width)
width = codec_settings.codec.width;
if (codec_settings.codec.height < height)
height = codec_settings.codec.height;
}
if (parameters_.encoder_config.streams.back().width == width &&
parameters_.encoder_config.streams.back().height == height) {
return;
}
webrtc::VideoEncoderConfig encoder_config = parameters_.encoder_config;
encoder_config.encoder_specific_settings =
encoder_factory_->CreateVideoEncoderSettings(codec_settings.codec,
parameters_.options);
if (is_screencast) {
int screencast_min_bitrate_kbps;
parameters_.options.screencast_min_bitrate.Get(
&screencast_min_bitrate_kbps);
encoder_config.min_transmit_bitrate_bps =
screencast_min_bitrate_kbps * 1000;
encoder_config.content_type = webrtc::VideoEncoderConfig::kScreenshare;
} else {
encoder_config.min_transmit_bitrate_bps = 0;
encoder_config.content_type = webrtc::VideoEncoderConfig::kRealtimeVideo;
}
VideoCodec codec = codec_settings.codec;
codec.width = width;
codec.height = height;

View File

@ -346,6 +346,13 @@ class WebRtcVideoChannel2 : public rtc::MessageHandler,
bool external;
};
struct LastDimensions {
LastDimensions() : width(-1), height(-1), is_screencast(false) {}
int width;
int height;
bool is_screencast;
};
AllocatedEncoder CreateVideoEncoder(const VideoCodec& codec)
EXCLUSIVE_LOCKS_REQUIRED(lock_);
void DestroyVideoEncoder(AllocatedEncoder* encoder);
@ -353,8 +360,7 @@ class WebRtcVideoChannel2 : public rtc::MessageHandler,
const VideoOptions& options)
EXCLUSIVE_LOCKS_REQUIRED(lock_);
void RecreateWebRtcStream() EXCLUSIVE_LOCKS_REQUIRED(lock_);
// When |override_max| is false constrain width/height to codec dimensions.
void SetDimensions(int width, int height, bool override_max)
void SetDimensions(int width, int height, bool is_screencast)
EXCLUSIVE_LOCKS_REQUIRED(lock_);
webrtc::Call* const call_;
@ -365,6 +371,7 @@ class WebRtcVideoChannel2 : public rtc::MessageHandler,
webrtc::VideoSendStream* stream_ GUARDED_BY(lock_);
VideoSendStreamParameters parameters_ GUARDED_BY(lock_);
AllocatedEncoder allocated_encoder_ GUARDED_BY(lock_);
LastDimensions last_dimensions_ GUARDED_BY(lock_);
VideoCapturer* capturer_ GUARDED_BY(lock_);
bool sending_ GUARDED_BY(lock_);

View File

@ -79,10 +79,14 @@ FakeVideoSendStream::FakeVideoSendStream(
ReconfigureVideoEncoder(encoder_config);
}
webrtc::VideoSendStream::Config FakeVideoSendStream::GetConfig() {
webrtc::VideoSendStream::Config FakeVideoSendStream::GetConfig() const {
return config_;
}
webrtc::VideoEncoderConfig FakeVideoSendStream::GetEncoderConfig() const {
return encoder_config_;
}
std::vector<webrtc::VideoStream> FakeVideoSendStream::GetVideoStreams() {
return encoder_config_.streams;
}
@ -725,7 +729,7 @@ TEST_F(WebRtcVideoChannel2BaseTest, DISABLED_SendVp8HdAndReceiveAdaptedVp8Vga) {
EXPECT_TRUE(channel_->SetCapturer(kSsrc, video_capturer_.get()));
// Capture format HD -> adapt (OnOutputFormatRequest VGA) -> VGA.
cricket::VideoCodec codec(100, "VP8", 1280, 720, 30, 0);
cricket::VideoCodec codec = kVp8Codec720p;
EXPECT_TRUE(SetOneCodec(codec));
codec.width /= 2;
codec.height /= 2;
@ -1189,8 +1193,60 @@ TEST_F(WebRtcVideoChannel2Test, DISABLED_SetBandwidthInConference) {
FAIL() << "Not implemented."; // TODO(pbos): Implement.
}
TEST_F(WebRtcVideoChannel2Test, DISABLED_SetBandwidthScreencast) {
FAIL() << "Not implemented."; // TODO(pbos): Implement.
TEST_F(WebRtcVideoChannel2Test, UsesCorrectSettingsForScreencast) {
static const int kScreenshareMinBitrateKbps = 800;
cricket::VideoCodec codec = kVp8Codec360p;
std::vector<cricket::VideoCodec> codecs;
codecs.push_back(codec);
EXPECT_TRUE(channel_->SetSendCodecs(codecs));
VideoOptions options;
options.screencast_min_bitrate.Set(kScreenshareMinBitrateKbps);
channel_->SetOptions(options);
AddSendStream();
cricket::FakeVideoCapturer capturer;
capturer.SetScreencast(false);
EXPECT_TRUE(channel_->SetCapturer(last_ssrc_, &capturer));
cricket::VideoFormat capture_format_hd =
capturer.GetSupportedFormats()->front();
EXPECT_EQ(1280, capture_format_hd.width);
EXPECT_EQ(720, capture_format_hd.height);
EXPECT_EQ(cricket::CS_RUNNING, capturer.Start(capture_format_hd));
EXPECT_TRUE(channel_->SetSend(true));
EXPECT_TRUE(capturer.CaptureFrame());
ASSERT_EQ(1u, fake_call_->GetVideoSendStreams().size());
FakeVideoSendStream* send_stream = fake_call_->GetVideoSendStreams().front();
EXPECT_EQ(1, send_stream->GetNumberOfSwappedFrames());
// Verify non-screencast settings.
webrtc::VideoEncoderConfig encoder_config = send_stream->GetEncoderConfig();
EXPECT_EQ(webrtc::VideoEncoderConfig::kRealtimeVideo,
encoder_config.content_type);
EXPECT_EQ(codec.width, encoder_config.streams.front().width);
EXPECT_EQ(codec.height, encoder_config.streams.front().height);
EXPECT_EQ(0, encoder_config.min_transmit_bitrate_bps)
<< "Non-screenshare shouldn't use min-transmit bitrate.";
capturer.SetScreencast(true);
EXPECT_TRUE(capturer.CaptureFrame());
EXPECT_EQ(2, send_stream->GetNumberOfSwappedFrames());
// Verify screencast settings.
encoder_config = send_stream->GetEncoderConfig();
EXPECT_EQ(webrtc::VideoEncoderConfig::kScreenshare,
encoder_config.content_type);
EXPECT_EQ(kScreenshareMinBitrateKbps * 1000,
encoder_config.min_transmit_bitrate_bps);
EXPECT_EQ(capture_format_hd.width, encoder_config.streams.front().width);
EXPECT_EQ(capture_format_hd.height, encoder_config.streams.front().height);
EXPECT_TRUE(channel_->SetCapturer(last_ssrc_, NULL));
}
TEST_F(WebRtcVideoChannel2Test, DISABLED_SetSendSsrcAndCname) {
@ -1290,7 +1346,7 @@ TEST_F(WebRtcVideoChannel2Test, DoesNotAdaptOnOveruseWhenDisabled) {
}
void WebRtcVideoChannel2Test::TestCpuAdaptation(bool enable_overuse) {
cricket::VideoCodec codec(100, "VP8", 1280, 720, 30, 0);
cricket::VideoCodec codec = kVp8Codec720p;
std::vector<cricket::VideoCodec> codecs;
codecs.push_back(codec);
EXPECT_TRUE(channel_->SetSendCodecs(codecs));

View File

@ -41,7 +41,8 @@ class FakeVideoSendStream : public webrtc::VideoSendStream,
public:
FakeVideoSendStream(const webrtc::VideoSendStream::Config& config,
const webrtc::VideoEncoderConfig& encoder_config);
webrtc::VideoSendStream::Config GetConfig();
webrtc::VideoSendStream::Config GetConfig() const;
webrtc::VideoEncoderConfig GetEncoderConfig() const;
std::vector<webrtc::VideoStream> GetVideoStreams();
bool IsSending() const;