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) {