From 60653ba3cc58aecdff594a1f72cfaefbad9c407b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20M=C3=B6ller?= Date: Wed, 2 Mar 2016 11:41:36 +0100 Subject: [PATCH] New flag is_screencast in VideoOptions. This cl copies the value of cricket::VideoCapturer::IsScreencast into a flag in VideoOptions. It is passed on via the chain VideortpSender::SetVideoSend WebRtcVideoChannel2::SetVideoSend WebRtcVideoChannel2::SetOptions WebRtcVideoChannel2::WebRtcVideoSendStream::SetOptions Where it's used, in WebRtcVideoChannel2::WebRtcVideoSendStream::OnFrame, we can look it up in parameters_, instead of calling capturer_->IsScreencast(). Doesn't touch screencast logic related to cpu adaptation, since that code is in flux in a different cl. Also drop the is_screencast flag from the Dimensions struct, and drop separate options argument from ConfigureVideoEncoderSettings and SetCodecAndOptions, instead always using the options recorded in VideoSendStreamParameters::options. In the tests, changed FakeVideoCapturer::is_screencast to be a construction time flag. Generally, unittests of screencast have to both use a capturer configured for screencast, and set the screencast flag using SetSendParameters. Since the automatic connection via VideoSource and VideoRtpSender isn't involved in the unit tests. Note that using SetSendParameters to set the screencast flag doesn't make sense, since it's not per-stream. SetVideoSend would be more appropriate. That should be fixed if/when we drop VideoOptions from SetSendParameters. BUG=webrtc:5426 R=pbos@webrtc.org, perkj@webrtc.org, pthatcher@webrtc.org Review URL: https://codereview.webrtc.org/1711763003 . Cr-Commit-Position: refs/heads/master@{#11837} --- webrtc/api/videosource.cc | 1 + webrtc/api/videosource_unittest.cc | 20 +- webrtc/media/base/fakevideocapturer.h | 11 +- webrtc/media/base/mediachannel.h | 10 +- webrtc/media/base/videocapturer_unittest.cc | 263 +++++++++--------- webrtc/media/base/videoengine_unittest.h | 13 +- webrtc/media/engine/webrtcvideoengine2.cc | 54 ++-- webrtc/media/engine/webrtcvideoengine2.h | 10 +- .../engine/webrtcvideoengine2_unittest.cc | 77 ++++- webrtc/video/video_send_stream.cc | 7 +- 10 files changed, 268 insertions(+), 198 deletions(-) diff --git a/webrtc/api/videosource.cc b/webrtc/api/videosource.cc index e073fae23a..4e28cec018 100644 --- a/webrtc/api/videosource.cc +++ b/webrtc/api/videosource.cc @@ -359,6 +359,7 @@ void VideoSource::Initialize( return; } options_.SetAll(options); + options_.is_screencast = rtc::Optional(video_capturer_->IsScreencast()); format_ = GetBestCaptureFormat(formats); // Start the camera with our best guess. diff --git a/webrtc/api/videosource_unittest.cc b/webrtc/api/videosource_unittest.cc index 2d163ef9a0..cd4ca3ae3d 100644 --- a/webrtc/api/videosource_unittest.cc +++ b/webrtc/api/videosource_unittest.cc @@ -42,7 +42,9 @@ const int kMaxWaitMs = 100; // file. class TestVideoCapturer : public cricket::FakeVideoCapturer { public: - TestVideoCapturer() : test_without_formats_(false) { + TestVideoCapturer(bool is_screencast) + : FakeVideoCapturer(is_screencast), + test_without_formats_(false) { std::vector formats; formats.push_back(cricket::VideoFormat(1280, 720, cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420)); @@ -110,11 +112,17 @@ class StateObserver : public ObserverInterface { class VideoSourceTest : public testing::Test { protected: VideoSourceTest() - : capturer_cleanup_(new TestVideoCapturer()), - capturer_(capturer_cleanup_.get()), - channel_manager_(new cricket::ChannelManager( + : channel_manager_(new cricket::ChannelManager( new cricket::FakeMediaEngine(), rtc::Thread::Current())) { + InitCapturer(false); } + void InitCapturer(bool is_screencast) { + capturer_cleanup_ = rtc::scoped_ptr( + new TestVideoCapturer(is_screencast)); + capturer_ = capturer_cleanup_.get(); + } + + void InitScreencast() { InitCapturer(true); } void SetUp() { ASSERT_TRUE(channel_manager_->Init()); @@ -473,8 +481,8 @@ TEST_F(VideoSourceTest, MixedOptionsAndConstraints) { // Tests that the source starts video with the default resolution for // screencast if no constraint is set. TEST_F(VideoSourceTest, ScreencastResolutionNoConstraint) { + InitScreencast(); capturer_->TestWithoutCameraFormats(); - capturer_->SetScreencast(true); CreateVideoSource(); EXPECT_EQ_WAIT(MediaSourceInterface::kLive, state_observer_->state(), @@ -493,8 +501,8 @@ TEST_F(VideoSourceTest, ScreencastResolutionWithConstraint) { constraints.AddMandatory(MediaConstraintsInterface::kMaxWidth, 480); constraints.AddMandatory(MediaConstraintsInterface::kMaxHeight, 270); + InitScreencast(); capturer_->TestWithoutCameraFormats(); - capturer_->SetScreencast(true); CreateVideoSource(&constraints); EXPECT_EQ_WAIT(MediaSourceInterface::kLive, state_observer_->state(), diff --git a/webrtc/media/base/fakevideocapturer.h b/webrtc/media/base/fakevideocapturer.h index 415862b96e..89dcf652f1 100644 --- a/webrtc/media/base/fakevideocapturer.h +++ b/webrtc/media/base/fakevideocapturer.h @@ -29,11 +29,11 @@ namespace cricket { // Fake video capturer that allows the test to manually pump in frames. class FakeVideoCapturer : public cricket::VideoCapturer { public: - FakeVideoCapturer() + FakeVideoCapturer(bool is_screencast) : running_(false), initial_unix_timestamp_(time(NULL) * rtc::kNumNanosecsPerSec), next_timestamp_(rtc::kNumNanosecsPerMillisec), - is_screencast_(false), + is_screencast_(is_screencast), rotation_(webrtc::kVideoRotation_0) { #ifdef HAVE_WEBRTC_VIDEO set_frame_factory(new cricket::WebRtcVideoFrameFactory()); @@ -52,6 +52,8 @@ class FakeVideoCapturer : public cricket::VideoCapturer { cricket::VideoFormat::FpsToInterval(60), cricket::FOURCC_I420)); ResetSupportedFormats(formats); } + FakeVideoCapturer() : FakeVideoCapturer(false) {} + ~FakeVideoCapturer() { SignalDestroyed(this); } @@ -136,9 +138,6 @@ class FakeVideoCapturer : public cricket::VideoCapturer { SetCaptureState(cricket::CS_STOPPED); } virtual bool IsRunning() { return running_; } - void SetScreencast(bool is_screencast) { - is_screencast_ = is_screencast; - } virtual bool IsScreencast() const { return is_screencast_; } bool GetPreferredFourccs(std::vector* fourccs) { fourccs->push_back(cricket::FOURCC_I420); @@ -156,7 +155,7 @@ class FakeVideoCapturer : public cricket::VideoCapturer { bool running_; int64_t initial_unix_timestamp_; int64_t next_timestamp_; - bool is_screencast_; + const bool is_screencast_; webrtc::VideoRotation rotation_; }; diff --git a/webrtc/media/base/mediachannel.h b/webrtc/media/base/mediachannel.h index 0d3cf3fa30..8b848d1a33 100644 --- a/webrtc/media/base/mediachannel.h +++ b/webrtc/media/base/mediachannel.h @@ -258,11 +258,13 @@ struct VideoOptions { void SetAll(const VideoOptions& change) { SetFrom(&video_noise_reduction, change.video_noise_reduction); SetFrom(&screencast_min_bitrate_kbps, change.screencast_min_bitrate_kbps); + SetFrom(&is_screencast, change.is_screencast); } bool operator==(const VideoOptions& o) const { return video_noise_reduction == o.video_noise_reduction && - screencast_min_bitrate_kbps == o.screencast_min_bitrate_kbps; + screencast_min_bitrate_kbps == o.screencast_min_bitrate_kbps && + is_screencast == o.is_screencast; } std::string ToString() const { @@ -271,6 +273,7 @@ struct VideoOptions { ost << ToStringIfSet("noise reduction", video_noise_reduction); ost << ToStringIfSet("screencast min bitrate kbps", screencast_min_bitrate_kbps); + ost << ToStringIfSet("is_screencast ", is_screencast); ost << "}"; return ost.str(); } @@ -283,6 +286,11 @@ struct VideoOptions { // the PeerConnection constraint 'googScreencastMinBitrate'. It is // copied to the encoder config by WebRtcVideoChannel2. rtc::Optional screencast_min_bitrate_kbps; + // Set by screencast sources. Implies selection of encoding settings + // suitable for screencast. Most likely not the right way to do + // things, e.g., screencast of a text document and screencast of a + // youtube video have different needs. + rtc::Optional is_screencast; private: template diff --git a/webrtc/media/base/videocapturer_unittest.cc b/webrtc/media/base/videocapturer_unittest.cc index ba8452358d..0d5a59e9b7 100644 --- a/webrtc/media/base/videocapturer_unittest.cc +++ b/webrtc/media/base/videocapturer_unittest.cc @@ -35,12 +35,19 @@ class VideoCapturerTest public: VideoCapturerTest() : capture_state_(cricket::CS_STOPPED), num_state_changes_(0) { - capturer_.SignalStateChange.connect(this, - &VideoCapturerTest::OnStateChange); - capturer_.AddOrUpdateSink(&renderer_, rtc::VideoSinkWants()); + InitCapturer(false); } protected: + void InitCapturer(bool is_screencast) { + capturer_ = rtc::scoped_ptr( + new FakeVideoCapturer(is_screencast)); + capturer_->SignalStateChange.connect(this, + &VideoCapturerTest::OnStateChange); + capturer_->AddOrUpdateSink(&renderer_, rtc::VideoSinkWants()); + } + void InitScreencast() { InitCapturer(true); } + void OnStateChange(cricket::VideoCapturer*, cricket::CaptureState capture_state) { capture_state_ = capture_state; @@ -49,7 +56,7 @@ class VideoCapturerTest cricket::CaptureState capture_state() { return capture_state_; } int num_state_changes() { return num_state_changes_; } - cricket::FakeVideoCapturer capturer_; + rtc::scoped_ptr capturer_; cricket::CaptureState capture_state_; int num_state_changes_; cricket::FakeVideoRenderer renderer_; @@ -57,25 +64,25 @@ class VideoCapturerTest }; TEST_F(VideoCapturerTest, CaptureState) { - EXPECT_TRUE(capturer_.enable_video_adapter()); - EXPECT_EQ(cricket::CS_RUNNING, capturer_.Start(cricket::VideoFormat( + EXPECT_TRUE(capturer_->enable_video_adapter()); + EXPECT_EQ(cricket::CS_RUNNING, capturer_->Start(cricket::VideoFormat( 640, 480, cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420))); - EXPECT_TRUE(capturer_.IsRunning()); + EXPECT_TRUE(capturer_->IsRunning()); EXPECT_EQ_WAIT(cricket::CS_RUNNING, capture_state(), kMsCallbackWait); EXPECT_EQ(1, num_state_changes()); - capturer_.Stop(); + capturer_->Stop(); EXPECT_EQ_WAIT(cricket::CS_STOPPED, capture_state(), kMsCallbackWait); EXPECT_EQ(2, num_state_changes()); - capturer_.Stop(); + capturer_->Stop(); rtc::Thread::Current()->ProcessMessages(100); EXPECT_EQ(2, num_state_changes()); } TEST_F(VideoCapturerTest, ScreencastScaledOddWidth) { - capturer_.SetScreencast(true); + InitScreencast(); int kWidth = 1281; int kHeight = 720; @@ -83,16 +90,16 @@ TEST_F(VideoCapturerTest, ScreencastScaledOddWidth) { std::vector formats; formats.push_back(cricket::VideoFormat(kWidth, kHeight, cricket::VideoFormat::FpsToInterval(5), cricket::FOURCC_ARGB)); - capturer_.ResetSupportedFormats(formats); + capturer_->ResetSupportedFormats(formats); - EXPECT_EQ(cricket::CS_RUNNING, capturer_.Start(cricket::VideoFormat( + EXPECT_EQ(cricket::CS_RUNNING, capturer_->Start(cricket::VideoFormat( kWidth, kHeight, cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_ARGB))); - EXPECT_TRUE(capturer_.IsRunning()); + EXPECT_TRUE(capturer_->IsRunning()); EXPECT_EQ(0, renderer_.num_rendered_frames()); - EXPECT_TRUE(capturer_.CaptureFrame()); + EXPECT_TRUE(capturer_->CaptureFrame()); EXPECT_EQ(1, renderer_.num_rendered_frames()); EXPECT_EQ(kWidth, renderer_.width()); EXPECT_EQ(kHeight, renderer_.height()); @@ -108,38 +115,38 @@ TEST_F(VideoCapturerTest, TestRotationAppliedBySource) { cricket::VideoFormat::FpsToInterval(5), cricket::FOURCC_I420)); - capturer_.ResetSupportedFormats(formats); + capturer_->ResetSupportedFormats(formats); // capturer_ should compensate rotation as default. EXPECT_EQ(cricket::CS_RUNNING, - capturer_.Start(cricket::VideoFormat( + capturer_->Start(cricket::VideoFormat( kWidth, kHeight, cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420))); - EXPECT_TRUE(capturer_.IsRunning()); + EXPECT_TRUE(capturer_->IsRunning()); EXPECT_EQ(0, renderer_.num_rendered_frames()); // If the frame's rotation is compensated anywhere in the pipeline based on // the rotation information, the renderer should be given the right dimension // such that the frame could be rendered. - capturer_.SetRotation(webrtc::kVideoRotation_90); - EXPECT_TRUE(capturer_.CaptureFrame()); + capturer_->SetRotation(webrtc::kVideoRotation_90); + EXPECT_TRUE(capturer_->CaptureFrame()); EXPECT_EQ(++frame_count, renderer_.num_rendered_frames()); // Swapped width and height EXPECT_EQ(kWidth, renderer_.height()); EXPECT_EQ(kHeight, renderer_.width()); EXPECT_EQ(webrtc::kVideoRotation_0, renderer_.rotation()); - capturer_.SetRotation(webrtc::kVideoRotation_270); - EXPECT_TRUE(capturer_.CaptureFrame()); + capturer_->SetRotation(webrtc::kVideoRotation_270); + EXPECT_TRUE(capturer_->CaptureFrame()); EXPECT_EQ(++frame_count, renderer_.num_rendered_frames()); // Swapped width and height EXPECT_EQ(kWidth, renderer_.height()); EXPECT_EQ(kHeight, renderer_.width()); EXPECT_EQ(webrtc::kVideoRotation_0, renderer_.rotation()); - capturer_.SetRotation(webrtc::kVideoRotation_180); - EXPECT_TRUE(capturer_.CaptureFrame()); + capturer_->SetRotation(webrtc::kVideoRotation_180); + EXPECT_TRUE(capturer_->CaptureFrame()); EXPECT_EQ(++frame_count, renderer_.num_rendered_frames()); // Back to normal width and height EXPECT_EQ(kWidth, renderer_.width()); @@ -156,17 +163,17 @@ TEST_F(VideoCapturerTest, TestRotationAppliedBySink) { cricket::VideoFormat::FpsToInterval(5), cricket::FOURCC_I420)); - capturer_.ResetSupportedFormats(formats); + capturer_->ResetSupportedFormats(formats); rtc::VideoSinkWants wants; // capturer_ should not compensate rotation. wants.rotation_applied = false; - capturer_.AddOrUpdateSink(&renderer_, wants); + capturer_->AddOrUpdateSink(&renderer_, wants); EXPECT_EQ(cricket::CS_RUNNING, - capturer_.Start(cricket::VideoFormat( + capturer_->Start(cricket::VideoFormat( kWidth, kHeight, cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420))); - EXPECT_TRUE(capturer_.IsRunning()); + EXPECT_TRUE(capturer_->IsRunning()); EXPECT_EQ(0, renderer_.num_rendered_frames()); // If the frame's rotation is compensated anywhere in the pipeline, the frame @@ -175,25 +182,25 @@ TEST_F(VideoCapturerTest, TestRotationAppliedBySink) { // resolution won't match anymore. int frame_count = 0; - capturer_.SetRotation(webrtc::kVideoRotation_0); - EXPECT_TRUE(capturer_.CaptureFrame()); + capturer_->SetRotation(webrtc::kVideoRotation_0); + EXPECT_TRUE(capturer_->CaptureFrame()); EXPECT_EQ(++frame_count, renderer_.num_rendered_frames()); - EXPECT_EQ(capturer_.GetRotation(), renderer_.rotation()); + EXPECT_EQ(capturer_->GetRotation(), renderer_.rotation()); - capturer_.SetRotation(webrtc::kVideoRotation_90); - EXPECT_TRUE(capturer_.CaptureFrame()); + capturer_->SetRotation(webrtc::kVideoRotation_90); + EXPECT_TRUE(capturer_->CaptureFrame()); EXPECT_EQ(++frame_count, renderer_.num_rendered_frames()); - EXPECT_EQ(capturer_.GetRotation(), renderer_.rotation()); + EXPECT_EQ(capturer_->GetRotation(), renderer_.rotation()); - capturer_.SetRotation(webrtc::kVideoRotation_180); - EXPECT_TRUE(capturer_.CaptureFrame()); + capturer_->SetRotation(webrtc::kVideoRotation_180); + EXPECT_TRUE(capturer_->CaptureFrame()); EXPECT_EQ(++frame_count, renderer_.num_rendered_frames()); - EXPECT_EQ(capturer_.GetRotation(), renderer_.rotation()); + EXPECT_EQ(capturer_->GetRotation(), renderer_.rotation()); - capturer_.SetRotation(webrtc::kVideoRotation_270); - EXPECT_TRUE(capturer_.CaptureFrame()); + capturer_->SetRotation(webrtc::kVideoRotation_270); + EXPECT_TRUE(capturer_->CaptureFrame()); EXPECT_EQ(++frame_count, renderer_.num_rendered_frames()); - EXPECT_EQ(capturer_.GetRotation(), renderer_.rotation()); + EXPECT_EQ(capturer_->GetRotation(), renderer_.rotation()); } TEST_F(VideoCapturerTest, TestRotationAppliedBySourceWhenDifferentWants) { @@ -205,31 +212,31 @@ TEST_F(VideoCapturerTest, TestRotationAppliedBySourceWhenDifferentWants) { cricket::VideoFormat::FpsToInterval(5), cricket::FOURCC_I420)); - capturer_.ResetSupportedFormats(formats); + capturer_->ResetSupportedFormats(formats); rtc::VideoSinkWants wants; // capturer_ should not compensate rotation. wants.rotation_applied = false; - capturer_.AddOrUpdateSink(&renderer_, wants); + capturer_->AddOrUpdateSink(&renderer_, wants); EXPECT_EQ(cricket::CS_RUNNING, - capturer_.Start(cricket::VideoFormat( + capturer_->Start(cricket::VideoFormat( kWidth, kHeight, cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420))); - EXPECT_TRUE(capturer_.IsRunning()); + EXPECT_TRUE(capturer_->IsRunning()); EXPECT_EQ(0, renderer_.num_rendered_frames()); int frame_count = 0; - capturer_.SetRotation(webrtc::kVideoRotation_90); - EXPECT_TRUE(capturer_.CaptureFrame()); + capturer_->SetRotation(webrtc::kVideoRotation_90); + EXPECT_TRUE(capturer_->CaptureFrame()); EXPECT_EQ(++frame_count, renderer_.num_rendered_frames()); - EXPECT_EQ(capturer_.GetRotation(), renderer_.rotation()); + EXPECT_EQ(capturer_->GetRotation(), renderer_.rotation()); // Add another sink that wants frames to be rotated. cricket::FakeVideoRenderer renderer2; wants.rotation_applied = true; - capturer_.AddOrUpdateSink(&renderer2, wants); + capturer_->AddOrUpdateSink(&renderer2, wants); - EXPECT_TRUE(capturer_.CaptureFrame()); + EXPECT_TRUE(capturer_->CaptureFrame()); EXPECT_EQ(++frame_count, renderer_.num_rendered_frames()); EXPECT_EQ(1, renderer2.num_rendered_frames()); EXPECT_EQ(webrtc::kVideoRotation_0, renderer_.rotation()); @@ -238,13 +245,13 @@ TEST_F(VideoCapturerTest, TestRotationAppliedBySourceWhenDifferentWants) { TEST_F(VideoCapturerTest, SinkWantsMaxPixelAndMaxPixelCountStepUp) { EXPECT_EQ(cricket::CS_RUNNING, - capturer_.Start(cricket::VideoFormat( + capturer_->Start(cricket::VideoFormat( 1280, 720, cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420))); - EXPECT_TRUE(capturer_.IsRunning()); + EXPECT_TRUE(capturer_->IsRunning()); EXPECT_EQ(0, renderer_.num_rendered_frames()); - EXPECT_TRUE(capturer_.CaptureFrame()); + EXPECT_TRUE(capturer_->CaptureFrame()); EXPECT_EQ(1, renderer_.num_rendered_frames()); EXPECT_EQ(1280, renderer_.width()); EXPECT_EQ(720, renderer_.height()); @@ -252,8 +259,8 @@ TEST_F(VideoCapturerTest, SinkWantsMaxPixelAndMaxPixelCountStepUp) { // Request a lower resolution. rtc::VideoSinkWants wants; wants.max_pixel_count = rtc::Optional(1280 * 720 / 2); - capturer_.AddOrUpdateSink(&renderer_, wants); - EXPECT_TRUE(capturer_.CaptureFrame()); + capturer_->AddOrUpdateSink(&renderer_, wants); + EXPECT_TRUE(capturer_->CaptureFrame()); EXPECT_EQ(2, renderer_.num_rendered_frames()); EXPECT_EQ(960, renderer_.width()); EXPECT_EQ(540, renderer_.height()); @@ -261,16 +268,16 @@ TEST_F(VideoCapturerTest, SinkWantsMaxPixelAndMaxPixelCountStepUp) { // Request a lower resolution. wants.max_pixel_count = rtc::Optional(renderer_.width() * renderer_.height() / 2); - capturer_.AddOrUpdateSink(&renderer_, wants); - EXPECT_TRUE(capturer_.CaptureFrame()); + capturer_->AddOrUpdateSink(&renderer_, wants); + EXPECT_TRUE(capturer_->CaptureFrame()); EXPECT_EQ(3, renderer_.num_rendered_frames()); EXPECT_EQ(640, renderer_.width()); EXPECT_EQ(360, renderer_.height()); // Adding a new renderer should not affect resolution. cricket::FakeVideoRenderer renderer2; - capturer_.AddOrUpdateSink(&renderer2, rtc::VideoSinkWants()); - EXPECT_TRUE(capturer_.CaptureFrame()); + capturer_->AddOrUpdateSink(&renderer2, rtc::VideoSinkWants()); + EXPECT_TRUE(capturer_->CaptureFrame()); EXPECT_EQ(4, renderer_.num_rendered_frames()); EXPECT_EQ(640, renderer_.width()); EXPECT_EQ(360, renderer_.height()); @@ -281,8 +288,8 @@ TEST_F(VideoCapturerTest, SinkWantsMaxPixelAndMaxPixelCountStepUp) { // Request higher resolution. wants.max_pixel_count_step_up = wants.max_pixel_count; wants.max_pixel_count = rtc::Optional(); - capturer_.AddOrUpdateSink(&renderer_, wants); - EXPECT_TRUE(capturer_.CaptureFrame()); + capturer_->AddOrUpdateSink(&renderer_, wants); + EXPECT_TRUE(capturer_->CaptureFrame()); EXPECT_EQ(5, renderer_.num_rendered_frames()); EXPECT_EQ(960, renderer_.width()); EXPECT_EQ(540, renderer_.height()); @@ -291,8 +298,8 @@ TEST_F(VideoCapturerTest, SinkWantsMaxPixelAndMaxPixelCountStepUp) { EXPECT_EQ(540, renderer2.height()); // Updating with no wants should not affect resolution. - capturer_.AddOrUpdateSink(&renderer2, rtc::VideoSinkWants()); - EXPECT_TRUE(capturer_.CaptureFrame()); + capturer_->AddOrUpdateSink(&renderer2, rtc::VideoSinkWants()); + EXPECT_TRUE(capturer_->CaptureFrame()); EXPECT_EQ(6, renderer_.num_rendered_frames()); EXPECT_EQ(960, renderer_.width()); EXPECT_EQ(540, renderer_.height()); @@ -302,7 +309,7 @@ TEST_F(VideoCapturerTest, SinkWantsMaxPixelAndMaxPixelCountStepUp) { } TEST_F(VideoCapturerTest, ScreencastScaledSuperLarge) { - capturer_.SetScreencast(true); + InitScreencast(); const int kMaxWidth = 4096; const int kMaxHeight = 3072; @@ -312,16 +319,16 @@ TEST_F(VideoCapturerTest, ScreencastScaledSuperLarge) { std::vector formats; formats.push_back(cricket::VideoFormat(kWidth, kHeight, cricket::VideoFormat::FpsToInterval(5), cricket::FOURCC_ARGB)); - capturer_.ResetSupportedFormats(formats); + capturer_->ResetSupportedFormats(formats); - EXPECT_EQ(cricket::CS_RUNNING, capturer_.Start(cricket::VideoFormat( + EXPECT_EQ(cricket::CS_RUNNING, capturer_->Start(cricket::VideoFormat( kWidth, kHeight, cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_ARGB))); - EXPECT_TRUE(capturer_.IsRunning()); + EXPECT_TRUE(capturer_->IsRunning()); EXPECT_EQ(0, renderer_.num_rendered_frames()); - EXPECT_TRUE(capturer_.CaptureFrame()); + EXPECT_TRUE(capturer_->CaptureFrame()); EXPECT_EQ(1, renderer_.num_rendered_frames()); EXPECT_EQ(kWidth / 2, renderer_.width()); EXPECT_EQ(kHeight / 2, renderer_.height()); @@ -332,16 +339,16 @@ TEST_F(VideoCapturerTest, TestFourccMatch) { cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_ANY); cricket::VideoFormat best; - EXPECT_TRUE(capturer_.GetBestCaptureFormat(desired, &best)); + EXPECT_TRUE(capturer_->GetBestCaptureFormat(desired, &best)); EXPECT_EQ(640, best.width); EXPECT_EQ(480, best.height); EXPECT_EQ(cricket::VideoFormat::FpsToInterval(30), best.interval); desired.fourcc = cricket::FOURCC_MJPG; - EXPECT_FALSE(capturer_.GetBestCaptureFormat(desired, &best)); + EXPECT_FALSE(capturer_->GetBestCaptureFormat(desired, &best)); desired.fourcc = cricket::FOURCC_I420; - EXPECT_TRUE(capturer_.GetBestCaptureFormat(desired, &best)); + EXPECT_TRUE(capturer_->GetBestCaptureFormat(desired, &best)); } TEST_F(VideoCapturerTest, TestResolutionMatch) { @@ -350,7 +357,7 @@ TEST_F(VideoCapturerTest, TestResolutionMatch) { cricket::FOURCC_ANY); cricket::VideoFormat best; // Ask for 1920x1080. Get HD 1280x720 which is the highest. - EXPECT_TRUE(capturer_.GetBestCaptureFormat(desired, &best)); + EXPECT_TRUE(capturer_->GetBestCaptureFormat(desired, &best)); EXPECT_EQ(1280, best.width); EXPECT_EQ(720, best.height); EXPECT_EQ(cricket::VideoFormat::FpsToInterval(30), best.interval); @@ -358,7 +365,7 @@ TEST_F(VideoCapturerTest, TestResolutionMatch) { desired.width = 360; desired.height = 250; // Ask for a little higher than QVGA. Get QVGA. - EXPECT_TRUE(capturer_.GetBestCaptureFormat(desired, &best)); + EXPECT_TRUE(capturer_->GetBestCaptureFormat(desired, &best)); EXPECT_EQ(320, best.width); EXPECT_EQ(240, best.height); EXPECT_EQ(cricket::VideoFormat::FpsToInterval(30), best.interval); @@ -366,7 +373,7 @@ TEST_F(VideoCapturerTest, TestResolutionMatch) { desired.width = 480; desired.height = 270; // Ask for HVGA. Get VGA. - EXPECT_TRUE(capturer_.GetBestCaptureFormat(desired, &best)); + EXPECT_TRUE(capturer_->GetBestCaptureFormat(desired, &best)); EXPECT_EQ(640, best.width); EXPECT_EQ(480, best.height); EXPECT_EQ(cricket::VideoFormat::FpsToInterval(30), best.interval); @@ -374,7 +381,7 @@ TEST_F(VideoCapturerTest, TestResolutionMatch) { desired.width = 320; desired.height = 240; // Ask for QVGA. Get QVGA. - EXPECT_TRUE(capturer_.GetBestCaptureFormat(desired, &best)); + EXPECT_TRUE(capturer_->GetBestCaptureFormat(desired, &best)); EXPECT_EQ(320, best.width); EXPECT_EQ(240, best.height); EXPECT_EQ(cricket::VideoFormat::FpsToInterval(30), best.interval); @@ -382,7 +389,7 @@ TEST_F(VideoCapturerTest, TestResolutionMatch) { desired.width = 80; desired.height = 60; // Ask for lower than QQVGA. Get QQVGA, which is the lowest. - EXPECT_TRUE(capturer_.GetBestCaptureFormat(desired, &best)); + EXPECT_TRUE(capturer_->GetBestCaptureFormat(desired, &best)); EXPECT_EQ(160, best.width); EXPECT_EQ(120, best.height); EXPECT_EQ(cricket::VideoFormat::FpsToInterval(30), best.interval); @@ -401,14 +408,14 @@ TEST_F(VideoCapturerTest, TestHDResolutionMatch) { cricket::VideoFormat::FpsToInterval(15), cricket::FOURCC_I420)); formats.push_back(cricket::VideoFormat(2592, 1944, cricket::VideoFormat::FpsToInterval(7), cricket::FOURCC_I420)); - capturer_.ResetSupportedFormats(formats); + capturer_->ResetSupportedFormats(formats); cricket::VideoFormat desired(960, 720, cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_ANY); cricket::VideoFormat best; // Ask for 960x720 30 fps. Get qHD 24 fps - EXPECT_TRUE(capturer_.GetBestCaptureFormat(desired, &best)); + EXPECT_TRUE(capturer_->GetBestCaptureFormat(desired, &best)); EXPECT_EQ(960, best.width); EXPECT_EQ(544, best.height); EXPECT_EQ(cricket::VideoFormat::FpsToInterval(24), best.interval); @@ -417,7 +424,7 @@ TEST_F(VideoCapturerTest, TestHDResolutionMatch) { desired.height = 544; desired.interval = cricket::VideoFormat::FpsToInterval(30); // Ask for qHD 30 fps. Get qHD 24 fps - EXPECT_TRUE(capturer_.GetBestCaptureFormat(desired, &best)); + EXPECT_TRUE(capturer_->GetBestCaptureFormat(desired, &best)); EXPECT_EQ(960, best.width); EXPECT_EQ(544, best.height); EXPECT_EQ(cricket::VideoFormat::FpsToInterval(24), best.interval); @@ -426,7 +433,7 @@ TEST_F(VideoCapturerTest, TestHDResolutionMatch) { desired.height = 250; desired.interval = cricket::VideoFormat::FpsToInterval(30); // Ask for a little higher than QVGA. Get QVGA. - EXPECT_TRUE(capturer_.GetBestCaptureFormat(desired, &best)); + EXPECT_TRUE(capturer_->GetBestCaptureFormat(desired, &best)); EXPECT_EQ(320, best.width); EXPECT_EQ(240, best.height); EXPECT_EQ(cricket::VideoFormat::FpsToInterval(30), best.interval); @@ -434,7 +441,7 @@ TEST_F(VideoCapturerTest, TestHDResolutionMatch) { desired.width = 480; desired.height = 270; // Ask for HVGA. Get VGA. - EXPECT_TRUE(capturer_.GetBestCaptureFormat(desired, &best)); + EXPECT_TRUE(capturer_->GetBestCaptureFormat(desired, &best)); EXPECT_EQ(640, best.width); EXPECT_EQ(480, best.height); EXPECT_EQ(cricket::VideoFormat::FpsToInterval(30), best.interval); @@ -442,7 +449,7 @@ TEST_F(VideoCapturerTest, TestHDResolutionMatch) { desired.width = 320; desired.height = 240; // Ask for QVGA. Get QVGA. - EXPECT_TRUE(capturer_.GetBestCaptureFormat(desired, &best)); + EXPECT_TRUE(capturer_->GetBestCaptureFormat(desired, &best)); EXPECT_EQ(320, best.width); EXPECT_EQ(240, best.height); EXPECT_EQ(cricket::VideoFormat::FpsToInterval(30), best.interval); @@ -450,7 +457,7 @@ TEST_F(VideoCapturerTest, TestHDResolutionMatch) { desired.width = 160; desired.height = 120; // Ask for lower than QVGA. Get QVGA, which is the lowest. - EXPECT_TRUE(capturer_.GetBestCaptureFormat(desired, &best)); + EXPECT_TRUE(capturer_->GetBestCaptureFormat(desired, &best)); EXPECT_EQ(320, best.width); EXPECT_EQ(240, best.height); EXPECT_EQ(cricket::VideoFormat::FpsToInterval(30), best.interval); @@ -458,7 +465,7 @@ TEST_F(VideoCapturerTest, TestHDResolutionMatch) { desired.width = 1280; desired.height = 720; // Ask for HD. 720p fps is too low. Get VGA which has 30 fps. - EXPECT_TRUE(capturer_.GetBestCaptureFormat(desired, &best)); + EXPECT_TRUE(capturer_->GetBestCaptureFormat(desired, &best)); EXPECT_EQ(640, best.width); EXPECT_EQ(480, best.height); EXPECT_EQ(cricket::VideoFormat::FpsToInterval(30), best.interval); @@ -467,7 +474,7 @@ TEST_F(VideoCapturerTest, TestHDResolutionMatch) { desired.height = 720; desired.interval = cricket::VideoFormat::FpsToInterval(15); // Ask for HD 15 fps. Fps matches. Get HD - EXPECT_TRUE(capturer_.GetBestCaptureFormat(desired, &best)); + EXPECT_TRUE(capturer_->GetBestCaptureFormat(desired, &best)); EXPECT_EQ(1280, best.width); EXPECT_EQ(720, best.height); EXPECT_EQ(cricket::VideoFormat::FpsToInterval(15), best.interval); @@ -476,7 +483,7 @@ TEST_F(VideoCapturerTest, TestHDResolutionMatch) { desired.height = 1080; desired.interval = cricket::VideoFormat::FpsToInterval(30); // Ask for 1080p. Fps of HD formats is too low. Get VGA which can do 30 fps. - EXPECT_TRUE(capturer_.GetBestCaptureFormat(desired, &best)); + EXPECT_TRUE(capturer_->GetBestCaptureFormat(desired, &best)); EXPECT_EQ(640, best.width); EXPECT_EQ(480, best.height); EXPECT_EQ(cricket::VideoFormat::FpsToInterval(30), best.interval); @@ -489,7 +496,7 @@ TEST_F(VideoCapturerTest, TestStrangeFormats) { cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420)); supported_formats.push_back(cricket::VideoFormat(320, 640, cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420)); - capturer_.ResetSupportedFormats(supported_formats); + capturer_->ResetSupportedFormats(supported_formats); std::vector required_formats; required_formats.push_back(cricket::VideoFormat(320, 240, @@ -500,7 +507,7 @@ TEST_F(VideoCapturerTest, TestStrangeFormats) { cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420)); cricket::VideoFormat best; for (size_t i = 0; i < required_formats.size(); ++i) { - EXPECT_TRUE(capturer_.GetBestCaptureFormat(required_formats[i], &best)); + EXPECT_TRUE(capturer_->GetBestCaptureFormat(required_formats[i], &best)); EXPECT_EQ(320, best.width); EXPECT_EQ(240, best.height); } @@ -510,10 +517,10 @@ TEST_F(VideoCapturerTest, TestStrangeFormats) { cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420)); supported_formats.push_back(cricket::VideoFormat(320, 240, cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420)); - capturer_.ResetSupportedFormats(supported_formats); + capturer_->ResetSupportedFormats(supported_formats); for (size_t i = 0; i < required_formats.size(); ++i) { - EXPECT_TRUE(capturer_.GetBestCaptureFormat(required_formats[i], &best)); + EXPECT_TRUE(capturer_->GetBestCaptureFormat(required_formats[i], &best)); EXPECT_EQ(320, best.width); EXPECT_EQ(240, best.height); } @@ -529,7 +536,7 @@ TEST_F(VideoCapturerTest, TestPoorFpsFormats) { cricket::VideoFormat::FpsToInterval(7), cricket::FOURCC_I420)); supported_formats.push_back(cricket::VideoFormat(1280, 720, cricket::VideoFormat::FpsToInterval(2), cricket::FOURCC_I420)); - capturer_.ResetSupportedFormats(supported_formats); + capturer_->ResetSupportedFormats(supported_formats); std::vector required_formats; required_formats.push_back(cricket::VideoFormat(320, 240, @@ -538,7 +545,7 @@ TEST_F(VideoCapturerTest, TestPoorFpsFormats) { cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420)); cricket::VideoFormat best; for (size_t i = 0; i < required_formats.size(); ++i) { - EXPECT_TRUE(capturer_.GetBestCaptureFormat(required_formats[i], &best)); + EXPECT_TRUE(capturer_->GetBestCaptureFormat(required_formats[i], &best)); EXPECT_EQ(required_formats[i].width, best.width); EXPECT_EQ(required_formats[i].height, best.height); } @@ -551,10 +558,10 @@ TEST_F(VideoCapturerTest, TestPoorFpsFormats) { cricket::VideoFormat::FpsToInterval(7), cricket::FOURCC_I420)); supported_formats.push_back(cricket::VideoFormat(1280, 720, cricket::VideoFormat::FpsToInterval(2), cricket::FOURCC_I420)); - capturer_.ResetSupportedFormats(supported_formats); + capturer_->ResetSupportedFormats(supported_formats); for (size_t i = 0; i < required_formats.size(); ++i) { - EXPECT_TRUE(capturer_.GetBestCaptureFormat(required_formats[i], &best)); + EXPECT_TRUE(capturer_->GetBestCaptureFormat(required_formats[i], &best)); EXPECT_EQ(320, best.width); EXPECT_EQ(240, best.height); } @@ -570,12 +577,12 @@ TEST_F(VideoCapturerTest, TestSameSizeDifferentFpsFormats) { cricket::VideoFormat::FpsToInterval(20), cricket::FOURCC_I420)); supported_formats.push_back(cricket::VideoFormat(320, 240, cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420)); - capturer_.ResetSupportedFormats(supported_formats); + capturer_->ResetSupportedFormats(supported_formats); std::vector required_formats = supported_formats; cricket::VideoFormat best; for (size_t i = 0; i < required_formats.size(); ++i) { - EXPECT_TRUE(capturer_.GetBestCaptureFormat(required_formats[i], &best)); + EXPECT_TRUE(capturer_->GetBestCaptureFormat(required_formats[i], &best)); EXPECT_EQ(320, best.width); EXPECT_EQ(240, best.height); EXPECT_EQ(required_formats[i].interval, best.interval); @@ -595,7 +602,7 @@ TEST_F(VideoCapturerTest, TestFpsFormats) { cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420)); supported_formats.push_back(cricket::VideoFormat(640, 360, cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420)); - capturer_.ResetSupportedFormats(supported_formats); + capturer_->ResetSupportedFormats(supported_formats); std::vector required_formats; required_formats.push_back(cricket::VideoFormat(640, 480, @@ -607,19 +614,19 @@ TEST_F(VideoCapturerTest, TestFpsFormats) { cricket::VideoFormat best; // Expect 30 fps to choose 30 fps format. - EXPECT_TRUE(capturer_.GetBestCaptureFormat(required_formats[0], &best)); + EXPECT_TRUE(capturer_->GetBestCaptureFormat(required_formats[0], &best)); EXPECT_EQ(640, best.width); EXPECT_EQ(400, best.height); EXPECT_EQ(cricket::VideoFormat::FpsToInterval(30), best.interval); // Expect 20 fps to choose 30 fps format. - EXPECT_TRUE(capturer_.GetBestCaptureFormat(required_formats[1], &best)); + EXPECT_TRUE(capturer_->GetBestCaptureFormat(required_formats[1], &best)); EXPECT_EQ(640, best.width); EXPECT_EQ(400, best.height); EXPECT_EQ(cricket::VideoFormat::FpsToInterval(30), best.interval); // Expect 10 fps to choose 15 fps format and set fps to 15. - EXPECT_TRUE(capturer_.GetBestCaptureFormat(required_formats[2], &best)); + EXPECT_TRUE(capturer_->GetBestCaptureFormat(required_formats[2], &best)); EXPECT_EQ(640, best.width); EXPECT_EQ(480, best.height); EXPECT_EQ(cricket::VideoFormat::FpsToInterval(15), best.interval); @@ -636,22 +643,22 @@ TEST_F(VideoCapturerTest, TestFpsFormats) { cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420)); supported_formats.push_back(cricket::VideoFormat(640, 360, cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420)); - capturer_.ResetSupportedFormats(supported_formats); + capturer_->ResetSupportedFormats(supported_formats); // Expect 30 fps to choose 60 fps format and will set best fps to 60. - EXPECT_TRUE(capturer_.GetBestCaptureFormat(required_formats[0], &best)); + EXPECT_TRUE(capturer_->GetBestCaptureFormat(required_formats[0], &best)); EXPECT_EQ(640, best.width); EXPECT_EQ(480, best.height); EXPECT_EQ(cricket::VideoFormat::FpsToInterval(60), best.interval); // Expect 20 fps to choose 60 fps format, and will set best fps to 60. - EXPECT_TRUE(capturer_.GetBestCaptureFormat(required_formats[1], &best)); + EXPECT_TRUE(capturer_->GetBestCaptureFormat(required_formats[1], &best)); EXPECT_EQ(640, best.width); EXPECT_EQ(480, best.height); EXPECT_EQ(cricket::VideoFormat::FpsToInterval(60), best.interval); // Expect 10 fps to choose 15 fps. - EXPECT_TRUE(capturer_.GetBestCaptureFormat(required_formats[2], &best)); + EXPECT_TRUE(capturer_->GetBestCaptureFormat(required_formats[2], &best)); EXPECT_EQ(640, best.width); EXPECT_EQ(480, best.height); EXPECT_EQ(cricket::VideoFormat::FpsToInterval(15), best.interval); @@ -666,13 +673,13 @@ TEST_F(VideoCapturerTest, TestRequest16x10_9) { cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420)); supported_formats.push_back(cricket::VideoFormat(640, 360, cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420)); - capturer_.ResetSupportedFormats(supported_formats); + capturer_->ResetSupportedFormats(supported_formats); std::vector required_formats = supported_formats; cricket::VideoFormat best; // Expect 4x3, 16x10, and 16x9 requests are respected. for (size_t i = 0; i < required_formats.size(); ++i) { - EXPECT_TRUE(capturer_.GetBestCaptureFormat(required_formats[i], &best)); + EXPECT_TRUE(capturer_->GetBestCaptureFormat(required_formats[i], &best)); EXPECT_EQ(required_formats[i].width, best.width); EXPECT_EQ(required_formats[i].height, best.height); } @@ -687,11 +694,11 @@ TEST_F(VideoCapturerTest, TestRequest16x10_9) { cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420)); supported_formats.push_back(cricket::VideoFormat(640, 360, cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420)); - capturer_.ResetSupportedFormats(supported_formats); + capturer_->ResetSupportedFormats(supported_formats); // Expect 4x3, 16x10, and 16x9 requests are respected. for (size_t i = 0; i < required_formats.size(); ++i) { - EXPECT_TRUE(capturer_.GetBestCaptureFormat(required_formats[i], &best)); + EXPECT_TRUE(capturer_->GetBestCaptureFormat(required_formats[i], &best)); EXPECT_EQ(required_formats[i].width, best.width); EXPECT_EQ(required_formats[i].height, best.height); } @@ -706,17 +713,17 @@ TEST_F(VideoCapturerTest, TestRequest16x10_9) { cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420)); supported_formats.push_back(cricket::VideoFormat(640, 360, cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420)); - capturer_.ResetSupportedFormats(supported_formats); + capturer_->ResetSupportedFormats(supported_formats); // Expect 4x3 for 4x3 and 16x10 requests. for (size_t i = 0; i < required_formats.size() - 1; ++i) { - EXPECT_TRUE(capturer_.GetBestCaptureFormat(required_formats[i], &best)); + EXPECT_TRUE(capturer_->GetBestCaptureFormat(required_formats[i], &best)); EXPECT_EQ(required_formats[i].width, best.width); EXPECT_EQ(required_formats[i].height, best.height); } // Expect 16x9 for 16x9 request. - EXPECT_TRUE(capturer_.GetBestCaptureFormat(required_formats[2], &best)); + EXPECT_TRUE(capturer_->GetBestCaptureFormat(required_formats[2], &best)); EXPECT_EQ(640, best.width); EXPECT_EQ(360, best.height); } @@ -742,22 +749,22 @@ TEST_F(VideoCapturerTest, Whitelist) { cricket::VideoFormat vga_format(640, 480, cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420); - std::vector formats = *capturer_.GetSupportedFormats(); + std::vector formats = *capturer_->GetSupportedFormats(); formats.push_back(hd_format); // Enable whitelist. Expect HD not in list. - capturer_.set_enable_camera_list(true); - capturer_.ResetSupportedFormats(formats); - EXPECT_TRUE(HdFormatInList(*capturer_.GetSupportedFormats())); - capturer_.ConstrainSupportedFormats(vga_format); - EXPECT_FALSE(HdFormatInList(*capturer_.GetSupportedFormats())); + capturer_->set_enable_camera_list(true); + capturer_->ResetSupportedFormats(formats); + EXPECT_TRUE(HdFormatInList(*capturer_->GetSupportedFormats())); + capturer_->ConstrainSupportedFormats(vga_format); + EXPECT_FALSE(HdFormatInList(*capturer_->GetSupportedFormats())); // Disable whitelist. Expect HD in list. - capturer_.set_enable_camera_list(false); - capturer_.ResetSupportedFormats(formats); - EXPECT_TRUE(HdFormatInList(*capturer_.GetSupportedFormats())); - capturer_.ConstrainSupportedFormats(vga_format); - EXPECT_TRUE(HdFormatInList(*capturer_.GetSupportedFormats())); + capturer_->set_enable_camera_list(false); + capturer_->ResetSupportedFormats(formats); + EXPECT_TRUE(HdFormatInList(*capturer_->GetSupportedFormats())); + capturer_->ConstrainSupportedFormats(vga_format); + EXPECT_TRUE(HdFormatInList(*capturer_->GetSupportedFormats())); } TEST_F(VideoCapturerTest, BlacklistAllFormats) { @@ -770,18 +777,18 @@ TEST_F(VideoCapturerTest, BlacklistAllFormats) { cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420)); supported_formats.push_back(cricket::VideoFormat(1920, 1080, cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420)); - capturer_.ResetSupportedFormats(supported_formats); - EXPECT_EQ(2u, capturer_.GetSupportedFormats()->size()); + capturer_->ResetSupportedFormats(supported_formats); + EXPECT_EQ(2u, capturer_->GetSupportedFormats()->size()); // Now, enable the list, which would exclude both formats. However, since // only HD formats are available, we refuse to filter at all, so we don't // break this camera. - capturer_.set_enable_camera_list(true); - capturer_.ConstrainSupportedFormats(vga_format); - EXPECT_EQ(2u, capturer_.GetSupportedFormats()->size()); + capturer_->set_enable_camera_list(true); + capturer_->ConstrainSupportedFormats(vga_format); + EXPECT_EQ(2u, capturer_->GetSupportedFormats()->size()); // To make sure it's not just the camera list being broken, add in VGA and // try again. This time, only the VGA format should be there. supported_formats.push_back(vga_format); - capturer_.ResetSupportedFormats(supported_formats); - ASSERT_EQ(1u, capturer_.GetSupportedFormats()->size()); - EXPECT_EQ(vga_format.height, capturer_.GetSupportedFormats()->at(0).height); + capturer_->ResetSupportedFormats(supported_formats); + ASSERT_EQ(1u, capturer_->GetSupportedFormats()->size()); + EXPECT_EQ(vga_format.height, capturer_->GetSupportedFormats()->at(0).height); } diff --git a/webrtc/media/base/videoengine_unittest.h b/webrtc/media/base/videoengine_unittest.h index 020336a167..2b4858e10f 100644 --- a/webrtc/media/base/videoengine_unittest.h +++ b/webrtc/media/base/videoengine_unittest.h @@ -560,7 +560,6 @@ class VideoMediaChannelTest : public testing::Test, cricket::FakeVideoRenderer renderer2; std::unique_ptr capturer( CreateFakeVideoCapturer()); - capturer->SetScreencast(true); const int kTestWidth = 160; const int kTestHeight = 120; cricket::VideoFormat format(kTestWidth, kTestHeight, @@ -771,7 +770,14 @@ class VideoMediaChannelTest : public testing::Test, EXPECT_FRAME_WAIT(1, codec.width, codec.height, kTimeout); std::unique_ptr capturer( CreateFakeVideoCapturer()); - capturer->SetScreencast(true); + + // TODO(nisse): This testcase fails if we don't configure + // screencast. It's unclear why, I see nothing obvious in this + // test which is related to screencast logic. + cricket::VideoOptions video_options; + video_options.is_screencast = rtc::Optional(true); + channel_->SetVideoSend(kSsrc, true, &video_options); + cricket::VideoFormat format(480, 360, cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420); @@ -868,7 +874,6 @@ class VideoMediaChannelTest : public testing::Test, cricket::StreamParams::CreateLegacy(1))); std::unique_ptr capturer1( CreateFakeVideoCapturer()); - capturer1->SetScreencast(true); EXPECT_EQ(cricket::CS_RUNNING, capturer1->Start(capture_format)); // Set up additional stream 2. cricket::FakeVideoRenderer renderer2; @@ -880,7 +885,6 @@ class VideoMediaChannelTest : public testing::Test, cricket::StreamParams::CreateLegacy(2))); std::unique_ptr capturer2( CreateFakeVideoCapturer()); - capturer2->SetScreencast(true); EXPECT_EQ(cricket::CS_RUNNING, capturer2->Start(capture_format)); // State for all the streams. EXPECT_TRUE(SetOneCodec(DefaultCodec())); @@ -936,7 +940,6 @@ class VideoMediaChannelTest : public testing::Test, // (update the test when this changes). std::unique_ptr capturer( CreateFakeVideoCapturer()); - capturer->SetScreencast(true); const std::vector* formats = capturer->GetSupportedFormats(); cricket::VideoFormat capture_format = (*formats)[0]; diff --git a/webrtc/media/engine/webrtcvideoengine2.cc b/webrtc/media/engine/webrtcvideoengine2.cc index 38d2e5670b..77e25812f3 100644 --- a/webrtc/media/engine/webrtcvideoengine2.cc +++ b/webrtc/media/engine/webrtcvideoengine2.cc @@ -411,9 +411,8 @@ WebRtcVideoChannel2::WebRtcVideoSendStream::CreateVideoStreams( } void* WebRtcVideoChannel2::WebRtcVideoSendStream::ConfigureVideoEncoderSettings( - const VideoCodec& codec, - const VideoOptions& options, - bool is_screencast) { + const VideoCodec& codec) { + bool is_screencast = parameters_.options.is_screencast.value_or(false); // No automatic resizing when using simulcast or screencast. bool automatic_resize = !is_screencast && parameters_.config.rtp.ssrcs.size() == 1; @@ -424,8 +423,8 @@ void* WebRtcVideoChannel2::WebRtcVideoSendStream::ConfigureVideoEncoderSettings( denoising = false; } else { // Use codec default if video_noise_reduction is unset. - codec_default_denoising = !options.video_noise_reduction; - denoising = options.video_noise_reduction.value_or(false); + codec_default_denoising = !parameters_.options.video_noise_reduction; + denoising = parameters_.options.video_noise_reduction.value_or(false); } if (CodecNamesEq(codec.name, kH264CodecName)) { @@ -1490,7 +1489,6 @@ WebRtcVideoChannel2::WebRtcVideoSendStream::WebRtcVideoSendStream( parameters_(config, send_params.options, max_bitrate_bps, codec_settings), pending_encoder_reconfiguration_(false), allocated_encoder_(nullptr, webrtc::kVideoCodecUnknown, false), - capturer_is_screencast_(false), sending_(false), muted_(false), first_frame_timestamp_ms_(0), @@ -1570,8 +1568,7 @@ void WebRtcVideoChannel2::WebRtcVideoSendStream::OnFrame( last_frame_timestamp_ms_ = first_frame_timestamp_ms_ + frame_delta_ms; video_frame.set_render_time_ms(last_frame_timestamp_ms_); // Reconfigure codec if necessary. - SetDimensions(video_frame.width(), video_frame.height(), - capturer_is_screencast_); + SetDimensions(video_frame.width(), video_frame.height()); last_rotation_ = video_frame.rotation(); stream_->Input()->IncomingCapturedFrame(video_frame); @@ -1613,7 +1610,6 @@ bool WebRtcVideoChannel2::WebRtcVideoSendStream::SetCapturer( capturer_ = NULL; return true; } - capturer_is_screencast_ = capturer->IsScreencast(); } capturer_ = capturer; capturer_->AddOrUpdateSink(this, sink_wants_); @@ -1649,6 +1645,7 @@ WebRtcVideoChannel2::WebRtcVideoSendStream::GetSsrcs() const { void WebRtcVideoChannel2::WebRtcVideoSendStream::SetOptions( const VideoOptions& options) { rtc::CritScope cs(&lock_); + parameters_.options.SetAll(options); // Reconfigure encoder settings on the next frame or stream // recreation. @@ -1743,6 +1740,8 @@ void WebRtcVideoChannel2::WebRtcVideoSendStream::SetCodec( parameters_.codec_settings = rtc::Optional(codec_settings); + + LOG(LS_INFO) << "RecreateWebRtcStream (send) because of SetCodec."; RecreateWebRtcStream(); if (allocated_encoder_.encoder != new_encoder.encoder) { DestroyVideoEncoder(&allocated_encoder_); @@ -1800,7 +1799,8 @@ WebRtcVideoChannel2::WebRtcVideoSendStream::CreateVideoEncoderConfig( const Dimensions& dimensions, const VideoCodec& codec) const { webrtc::VideoEncoderConfig encoder_config; - if (dimensions.is_screencast) { + bool is_screencast = parameters_.options.is_screencast.value_or(false); + if (is_screencast) { encoder_config.min_transmit_bitrate_bps = 1000 * parameters_.options.screencast_min_bitrate_kbps.value_or(0); encoder_config.content_type = @@ -1814,7 +1814,7 @@ WebRtcVideoChannel2::WebRtcVideoSendStream::CreateVideoEncoderConfig( // Restrict dimensions according to codec max. int width = dimensions.width; int height = dimensions.height; - if (!dimensions.is_screencast) { + if (!is_screencast) { if (codec.width < width) width = codec.width; if (codec.height < height) @@ -1829,7 +1829,7 @@ WebRtcVideoChannel2::WebRtcVideoSendStream::CreateVideoEncoderConfig( // number of negotiated ssrcs. But if the codec is blacklisted for simulcast // or a screencast, only configure a single stream. size_t stream_count = parameters_.config.rtp.ssrcs.size(); - if (IsCodecBlacklistedForSimulcast(codec.name) || dimensions.is_screencast) { + if (IsCodecBlacklistedForSimulcast(codec.name) || is_screencast) { stream_count = 1; } @@ -1838,7 +1838,7 @@ WebRtcVideoChannel2::WebRtcVideoSendStream::CreateVideoEncoderConfig( parameters_.max_bitrate_bps, stream_count); // Conference mode screencast uses 2 temporal layers split at 100kbit. - if (parameters_.conference_mode && dimensions.is_screencast && + if (parameters_.conference_mode && is_screencast && encoder_config.streams.size() == 1) { ScreenshareLayerConfig config = ScreenshareLayerConfig::GetDefault(); @@ -1857,20 +1857,15 @@ WebRtcVideoChannel2::WebRtcVideoSendStream::CreateVideoEncoderConfig( void WebRtcVideoChannel2::WebRtcVideoSendStream::SetDimensions( int width, - int height, - bool is_screencast) { + int height) { if (last_dimensions_.width == width && last_dimensions_.height == height && - last_dimensions_.is_screencast == is_screencast && !pending_encoder_reconfiguration_) { // Configured using the same parameters, do not reconfigure. return; } - LOG(LS_INFO) << "SetDimensions: " << width << "x" << height - << (is_screencast ? " (screencast)" : " (not screencast)"); last_dimensions_.width = width; last_dimensions_.height = height; - last_dimensions_.is_screencast = is_screencast; RTC_DCHECK(!parameters_.encoder_config.streams.empty()); @@ -1881,7 +1876,7 @@ void WebRtcVideoChannel2::WebRtcVideoSendStream::SetDimensions( CreateVideoEncoderConfig(last_dimensions_, codec_settings.codec); encoder_config.encoder_specific_settings = ConfigureVideoEncoderSettings( - codec_settings.codec, parameters_.options, is_screencast); + codec_settings.codec); bool stream_reconfigured = stream_->ReconfigureVideoEncoder(encoder_config); @@ -1889,8 +1884,6 @@ void WebRtcVideoChannel2::WebRtcVideoSendStream::SetDimensions( pending_encoder_reconfiguration_ = false; if (!stream_reconfigured) { - LOG(LS_WARNING) << "Failed to reconfigure video encoder for dimensions: " - << width << "x" << height; return; } @@ -1921,15 +1914,19 @@ void WebRtcVideoChannel2::WebRtcVideoSendStream::OnLoadUpdate(Load load) { return; } RTC_DCHECK(thread_checker_.CalledOnValidThread()); - LOG(LS_INFO) << "OnLoadUpdate " << load; if (!capturer_) { return; } { rtc::CritScope cs(&lock_); + LOG(LS_INFO) << "OnLoadUpdate " << load << ", is_screencast: " + << (parameters_.options.is_screencast + ? (*parameters_.options.is_screencast ? "true" + : "false") + : "unset"); // Do not adapt resolution for screen content as this will likely result in // blurry and unreadable text. - if (capturer_is_screencast_) + if (parameters_.options.is_screencast.value_or(false)) return; rtc::Optional max_pixel_count; @@ -2080,11 +2077,12 @@ void WebRtcVideoChannel2::WebRtcVideoSendStream::RecreateWebRtcStream() { } RTC_CHECK(parameters_.codec_settings); + RTC_DCHECK_EQ((parameters_.encoder_config.content_type == + webrtc::VideoEncoderConfig::ContentType::kScreen), + parameters_.options.is_screencast.value_or(false)) + << "encoder content type inconsistent with screencast option"; parameters_.encoder_config.encoder_specific_settings = - ConfigureVideoEncoderSettings( - parameters_.codec_settings->codec, parameters_.options, - parameters_.encoder_config.content_type == - webrtc::VideoEncoderConfig::ContentType::kScreen); + ConfigureVideoEncoderSettings(parameters_.codec_settings->codec); webrtc::VideoSendStream::Config config = parameters_.config; if (!config.rtp.rtx.ssrcs.empty() && config.rtp.rtx.payload_type == -1) { diff --git a/webrtc/media/engine/webrtcvideoengine2.h b/webrtc/media/engine/webrtcvideoengine2.h index 76c2fc0c18..ccf753e9fc 100644 --- a/webrtc/media/engine/webrtcvideoengine2.h +++ b/webrtc/media/engine/webrtcvideoengine2.h @@ -301,10 +301,9 @@ class WebRtcVideoChannel2 : public VideoMediaChannel, public webrtc::Transport { // the first frame to know that you gave a bad codec parameter could make // debugging hard). // TODO(pbos): Consider setting up encoders lazily. - Dimensions() : width(176), height(144), is_screencast(false) {} + Dimensions() : width(176), height(144) {} int width; int height; - bool is_screencast; }; union VideoEncoderSettings { @@ -324,9 +323,7 @@ class WebRtcVideoChannel2 : public VideoMediaChannel, public webrtc::Transport { int max_bitrate_bps, size_t num_streams); - void* ConfigureVideoEncoderSettings(const VideoCodec& codec, - const VideoOptions& options, - bool is_screencast) + void* ConfigureVideoEncoderSettings(const VideoCodec& codec) EXCLUSIVE_LOCKS_REQUIRED(lock_); AllocatedEncoder CreateVideoEncoder(const VideoCodec& codec) @@ -339,7 +336,7 @@ class WebRtcVideoChannel2 : public VideoMediaChannel, public webrtc::Transport { webrtc::VideoEncoderConfig CreateVideoEncoderConfig( const Dimensions& dimensions, const VideoCodec& codec) const EXCLUSIVE_LOCKS_REQUIRED(lock_); - void SetDimensions(int width, int height, bool is_screencast) + void SetDimensions(int width, int height) EXCLUSIVE_LOCKS_REQUIRED(lock_); rtc::ThreadChecker thread_checker_; @@ -369,7 +366,6 @@ class WebRtcVideoChannel2 : public VideoMediaChannel, public webrtc::Transport { webrtc::VideoRotation last_rotation_ GUARDED_BY(lock_) = webrtc::kVideoRotation_0; - bool capturer_is_screencast_ GUARDED_BY(lock_); bool sending_ GUARDED_BY(lock_); bool muted_ GUARDED_BY(lock_); diff --git a/webrtc/media/engine/webrtcvideoengine2_unittest.cc b/webrtc/media/engine/webrtcvideoengine2_unittest.cc index ea8a300395..04f726b464 100644 --- a/webrtc/media/engine/webrtcvideoengine2_unittest.cc +++ b/webrtc/media/engine/webrtcvideoengine2_unittest.cc @@ -1472,7 +1472,6 @@ TEST_F(WebRtcVideoChannel2Test, UsesCorrectSettingsForScreencast) { AddSendStream(); cricket::FakeVideoCapturer capturer; - capturer.SetScreencast(false); EXPECT_TRUE(channel_->SetCapturer(last_ssrc_, &capturer)); cricket::VideoFormat capture_format_hd = capturer.GetSupportedFormats()->front(); @@ -1500,9 +1499,12 @@ TEST_F(WebRtcVideoChannel2Test, UsesCorrectSettingsForScreencast) { EXPECT_TRUE(channel_->SetCapturer(last_ssrc_, nullptr)); // Removing a capturer triggers a black frame to be sent. EXPECT_EQ(2, send_stream->GetNumberOfSwappedFrames()); - capturer.SetScreencast(true); EXPECT_TRUE(channel_->SetCapturer(last_ssrc_, &capturer)); + parameters.options.is_screencast = rtc::Optional(true); + EXPECT_TRUE(channel_->SetSendParameters(parameters)); EXPECT_TRUE(capturer.CaptureFrame()); + // Send stream not recreated after option change. + ASSERT_EQ(send_stream, fake_call_->GetVideoSendStreams().front()); EXPECT_EQ(3, send_stream->GetNumberOfSwappedFrames()); // Verify screencast settings. @@ -1519,17 +1521,68 @@ TEST_F(WebRtcVideoChannel2Test, UsesCorrectSettingsForScreencast) { EXPECT_TRUE(channel_->SetCapturer(last_ssrc_, NULL)); } +TEST_F(WebRtcVideoChannel2Test, NoRecreateStreamForScreencast) { + EXPECT_TRUE(channel_->SetSendParameters(send_parameters_)); + ASSERT_TRUE( + channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc))); + EXPECT_TRUE(channel_->SetSend(true)); + + cricket::FakeVideoCapturer capturer; + EXPECT_TRUE(channel_->SetCapturer(kSsrc, &capturer)); + EXPECT_EQ(cricket::CS_RUNNING, + capturer.Start(capturer.GetSupportedFormats()->front())); + EXPECT_TRUE(capturer.CaptureFrame()); + + ASSERT_EQ(1, fake_call_->GetNumCreatedSendStreams()); + FakeVideoSendStream* stream = fake_call_->GetVideoSendStreams().front(); + webrtc::VideoEncoderConfig encoder_config = stream->GetEncoderConfig(); + EXPECT_EQ(webrtc::VideoEncoderConfig::ContentType::kRealtimeVideo, + encoder_config.content_type); + + EXPECT_EQ(1, stream->GetNumberOfSwappedFrames()); + + /* Switch to screencast source. We expect a reconfigure of the + * encoder, but no change of the send stream. */ + struct VideoOptions video_options; + video_options.is_screencast = rtc::Optional(true); + channel_->SetVideoSend(kSsrc, true, &video_options); + + EXPECT_TRUE(capturer.CaptureFrame()); + ASSERT_EQ(1, fake_call_->GetNumCreatedSendStreams()); + ASSERT_EQ(stream, fake_call_->GetVideoSendStreams().front()); + EXPECT_EQ(2, stream->GetNumberOfSwappedFrames()); + + encoder_config = stream->GetEncoderConfig(); + EXPECT_EQ(webrtc::VideoEncoderConfig::ContentType::kScreen, + encoder_config.content_type); + + /* Switch back. */ + video_options.is_screencast = rtc::Optional(false); + channel_->SetVideoSend(kSsrc, true, &video_options); + + EXPECT_TRUE(capturer.CaptureFrame()); + ASSERT_EQ(1, fake_call_->GetNumCreatedSendStreams()); + ASSERT_EQ(stream, fake_call_->GetVideoSendStreams().front()); + EXPECT_EQ(3, stream->GetNumberOfSwappedFrames()); + + encoder_config = stream->GetEncoderConfig(); + EXPECT_EQ(webrtc::VideoEncoderConfig::ContentType::kRealtimeVideo, + encoder_config.content_type); + + EXPECT_TRUE(channel_->SetCapturer(kSsrc, NULL)); +} + TEST_F(WebRtcVideoChannel2Test, ConferenceModeScreencastConfiguresTemporalLayer) { static const int kConferenceScreencastTemporalBitrateBps = ScreenshareLayerConfig::GetDefault().tl0_bitrate_kbps * 1000; send_parameters_.conference_mode = true; + send_parameters_.options.is_screencast = rtc::Optional(true); channel_->SetSendParameters(send_parameters_); AddSendStream(); cricket::FakeVideoCapturer capturer; - capturer.SetScreencast(true); EXPECT_TRUE(channel_->SetCapturer(last_ssrc_, &capturer)); cricket::VideoFormat capture_format_hd = capturer.GetSupportedFormats()->front(); @@ -1600,7 +1653,6 @@ TEST_F(WebRtcVideoChannel2Test, VerifyVp8SpecificSettings) { FakeVideoSendStream* stream = SetUpSimulcast(false, true); cricket::FakeVideoCapturer capturer; - capturer.SetScreencast(false); EXPECT_EQ(cricket::CS_RUNNING, capturer.Start(capturer.GetSupportedFormats()->front())); EXPECT_TRUE(channel_->SetCapturer(last_ssrc_, &capturer)); @@ -1640,10 +1692,9 @@ TEST_F(WebRtcVideoChannel2Test, VerifyVp8SpecificSettings) { EXPECT_TRUE(vp8_settings.frameDroppingOn); // In screen-share mode, denoising is forced off and simulcast disabled. - EXPECT_TRUE(channel_->SetCapturer(last_ssrc_, NULL)); - capturer.SetScreencast(true); - EXPECT_TRUE(channel_->SetCapturer(last_ssrc_, &capturer)); - EXPECT_TRUE(capturer.CaptureFrame()); + parameters.options.is_screencast = rtc::Optional(true); + EXPECT_TRUE(channel_->SetSendParameters(parameters)); + stream = SetDenoisingOption(parameters, &capturer, false); EXPECT_EQ(1, stream->GetVideoStreams().size()); @@ -1694,7 +1745,6 @@ TEST_F(Vp9SettingsTest, VerifyVp9SpecificSettings) { FakeVideoSendStream* stream = SetUpSimulcast(false, false); cricket::FakeVideoCapturer capturer; - capturer.SetScreencast(false); EXPECT_EQ(cricket::CS_RUNNING, capturer.Start(capturer.GetSupportedFormats()->front())); EXPECT_TRUE(channel_->SetCapturer(last_ssrc_, &capturer)); @@ -1721,11 +1771,9 @@ TEST_F(Vp9SettingsTest, VerifyVp9SpecificSettings) { EXPECT_TRUE(vp9_settings.frameDroppingOn); // In screen-share mode, denoising is forced off. - EXPECT_TRUE(channel_->SetCapturer(last_ssrc_, nullptr)); - capturer.SetScreencast(true); - EXPECT_TRUE(channel_->SetCapturer(last_ssrc_, &capturer)); + parameters.options.is_screencast = rtc::Optional(true); + EXPECT_TRUE(channel_->SetSendParameters(parameters)); - EXPECT_TRUE(capturer.CaptureFrame()); stream = SetDenoisingOption(parameters, &capturer, false); ASSERT_TRUE(stream->GetVp9Settings(&vp9_settings)) << "No VP9 config set."; @@ -1767,7 +1815,6 @@ TEST_F(WebRtcVideoChannel2Test, AdaptsOnOveruseAndChangeResolution) { AddSendStream(); cricket::FakeVideoCapturer capturer; - capturer.SetScreencast(false); ASSERT_TRUE(channel_->SetCapturer(last_ssrc_, &capturer)); ASSERT_EQ(cricket::CS_RUNNING, capturer.Start(capturer.GetSupportedFormats()->front())); @@ -1834,12 +1881,12 @@ void WebRtcVideoChannel2Test::TestCpuAdaptation(bool enable_overuse, channel_.reset( engine_.CreateChannel(fake_call_.get(), media_config, VideoOptions())); + parameters.options.is_screencast = rtc::Optional(is_screenshare); EXPECT_TRUE(channel_->SetSendParameters(parameters)); AddSendStream(); cricket::FakeVideoCapturer capturer; - capturer.SetScreencast(is_screenshare); EXPECT_TRUE(channel_->SetCapturer(last_ssrc_, &capturer)); EXPECT_EQ(cricket::CS_RUNNING, capturer.Start(capturer.GetSupportedFormats()->front())); diff --git a/webrtc/video/video_send_stream.cc b/webrtc/video/video_send_stream.cc index 798b494fdb..241a0de345 100644 --- a/webrtc/video/video_send_stream.cc +++ b/webrtc/video/video_send_stream.cc @@ -475,9 +475,12 @@ bool VideoSendStream::ReconfigureVideoEncoder( RTC_DCHECK_GT(streams[0].max_framerate, 0); video_codec.maxFramerate = streams[0].max_framerate; - if (!SetSendCodec(video_codec)) + if (!SetSendCodec(video_codec)) { + LOG(LS_WARNING) << "(Re)configureVideoEncoder: SetSendCodec failed " + "for config: " + << config.ToString(); return false; - + } // Clear stats for disabled layers. for (size_t i = video_codec.numberOfSimulcastStreams; i < config_.rtp.ssrcs.size(); ++i) {