summaryrefslogtreecommitdiffstats
path: root/third_party/libwebrtc/video/video_source_sink_controller_unittest.cc
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/libwebrtc/video/video_source_sink_controller_unittest.cc')
-rw-r--r--third_party/libwebrtc/video/video_source_sink_controller_unittest.cc199
1 files changed, 199 insertions, 0 deletions
diff --git a/third_party/libwebrtc/video/video_source_sink_controller_unittest.cc b/third_party/libwebrtc/video/video_source_sink_controller_unittest.cc
new file mode 100644
index 0000000000..75cc52bdaf
--- /dev/null
+++ b/third_party/libwebrtc/video/video_source_sink_controller_unittest.cc
@@ -0,0 +1,199 @@
+/*
+ * Copyright 2020 The WebRTC Project Authors. All rights reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "video/video_source_sink_controller.h"
+
+#include <limits>
+
+#include "api/video/video_frame.h"
+#include "api/video/video_source_interface.h"
+#include "call/adaptation/video_source_restrictions.h"
+#include "test/gmock.h"
+#include "test/gtest.h"
+
+using testing::_;
+
+namespace webrtc {
+
+namespace {
+
+using FrameSize = rtc::VideoSinkWants::FrameSize;
+constexpr int kIntUnconstrained = std::numeric_limits<int>::max();
+
+class MockVideoSinkWithVideoFrame : public rtc::VideoSinkInterface<VideoFrame> {
+ public:
+ ~MockVideoSinkWithVideoFrame() override {}
+
+ MOCK_METHOD(void, OnFrame, (const VideoFrame& frame), (override));
+ MOCK_METHOD(void, OnDiscardedFrame, (), (override));
+};
+
+class MockVideoSourceWithVideoFrame
+ : public rtc::VideoSourceInterface<VideoFrame> {
+ public:
+ ~MockVideoSourceWithVideoFrame() override {}
+
+ MOCK_METHOD(void,
+ AddOrUpdateSink,
+ (rtc::VideoSinkInterface<VideoFrame>*,
+ const rtc::VideoSinkWants&),
+ (override));
+ MOCK_METHOD(void,
+ RemoveSink,
+ (rtc::VideoSinkInterface<VideoFrame>*),
+ (override));
+ MOCK_METHOD(void, RequestRefreshFrame, (), (override));
+};
+
+} // namespace
+
+TEST(VideoSourceSinkControllerTest, UnconstrainedByDefault) {
+ MockVideoSinkWithVideoFrame sink;
+ MockVideoSourceWithVideoFrame source;
+ VideoSourceSinkController controller(&sink, &source);
+ EXPECT_EQ(controller.restrictions(), VideoSourceRestrictions());
+ EXPECT_FALSE(controller.pixels_per_frame_upper_limit().has_value());
+ EXPECT_FALSE(controller.frame_rate_upper_limit().has_value());
+ EXPECT_FALSE(controller.rotation_applied());
+ EXPECT_FALSE(controller.requested_resolution().has_value());
+ EXPECT_EQ(controller.resolution_alignment(), 1);
+
+ EXPECT_CALL(source, AddOrUpdateSink(_, _))
+ .WillOnce([](rtc::VideoSinkInterface<VideoFrame>* sink,
+ const rtc::VideoSinkWants& wants) {
+ EXPECT_FALSE(wants.rotation_applied);
+ EXPECT_EQ(wants.max_pixel_count, kIntUnconstrained);
+ EXPECT_EQ(wants.target_pixel_count, absl::nullopt);
+ EXPECT_EQ(wants.max_framerate_fps, kIntUnconstrained);
+ EXPECT_EQ(wants.resolution_alignment, 1);
+ EXPECT_FALSE(wants.requested_resolution.has_value());
+ });
+ controller.PushSourceSinkSettings();
+}
+
+TEST(VideoSourceSinkControllerTest, VideoRestrictionsToSinkWants) {
+ MockVideoSinkWithVideoFrame sink;
+ MockVideoSourceWithVideoFrame source;
+ VideoSourceSinkController controller(&sink, &source);
+
+ VideoSourceRestrictions restrictions = controller.restrictions();
+ // max_pixels_per_frame() maps to `max_pixel_count`.
+ restrictions.set_max_pixels_per_frame(42u);
+ // target_pixels_per_frame() maps to `target_pixel_count`.
+ restrictions.set_target_pixels_per_frame(200u);
+ // max_frame_rate() maps to `max_framerate_fps`.
+ restrictions.set_max_frame_rate(30.0);
+ controller.SetRestrictions(restrictions);
+ EXPECT_CALL(source, AddOrUpdateSink(_, _))
+ .WillOnce([](rtc::VideoSinkInterface<VideoFrame>* sink,
+ const rtc::VideoSinkWants& wants) {
+ EXPECT_EQ(wants.max_pixel_count, 42);
+ EXPECT_EQ(wants.target_pixel_count, 200);
+ EXPECT_EQ(wants.max_framerate_fps, 30);
+ });
+ controller.PushSourceSinkSettings();
+
+ // pixels_per_frame_upper_limit() caps `max_pixel_count`.
+ controller.SetPixelsPerFrameUpperLimit(24);
+ // frame_rate_upper_limit() caps `max_framerate_fps`.
+ controller.SetFrameRateUpperLimit(10.0);
+
+ EXPECT_CALL(source, AddOrUpdateSink(_, _))
+ .WillOnce([](rtc::VideoSinkInterface<VideoFrame>* sink,
+ const rtc::VideoSinkWants& wants) {
+ EXPECT_EQ(wants.max_pixel_count, 24);
+ EXPECT_EQ(wants.max_framerate_fps, 10);
+ });
+ controller.PushSourceSinkSettings();
+}
+
+TEST(VideoSourceSinkControllerTest, RotationApplied) {
+ MockVideoSinkWithVideoFrame sink;
+ MockVideoSourceWithVideoFrame source;
+ VideoSourceSinkController controller(&sink, &source);
+ controller.SetRotationApplied(true);
+ EXPECT_TRUE(controller.rotation_applied());
+
+ EXPECT_CALL(source, AddOrUpdateSink(_, _))
+ .WillOnce([](rtc::VideoSinkInterface<VideoFrame>* sink,
+ const rtc::VideoSinkWants& wants) {
+ EXPECT_TRUE(wants.rotation_applied);
+ });
+ controller.PushSourceSinkSettings();
+}
+
+TEST(VideoSourceSinkControllerTest, ResolutionAlignment) {
+ MockVideoSinkWithVideoFrame sink;
+ MockVideoSourceWithVideoFrame source;
+ VideoSourceSinkController controller(&sink, &source);
+ controller.SetResolutionAlignment(13);
+ EXPECT_EQ(controller.resolution_alignment(), 13);
+
+ EXPECT_CALL(source, AddOrUpdateSink(_, _))
+ .WillOnce([](rtc::VideoSinkInterface<VideoFrame>* sink,
+ const rtc::VideoSinkWants& wants) {
+ EXPECT_EQ(wants.resolution_alignment, 13);
+ });
+ controller.PushSourceSinkSettings();
+}
+
+TEST(VideoSourceSinkControllerTest,
+ PushSourceSinkSettingsWithoutSourceDoesNotCrash) {
+ MockVideoSinkWithVideoFrame sink;
+ VideoSourceSinkController controller(&sink, nullptr);
+ controller.PushSourceSinkSettings();
+}
+
+TEST(VideoSourceSinkControllerTest, RequestsRefreshFrameWithSource) {
+ MockVideoSinkWithVideoFrame sink;
+ MockVideoSourceWithVideoFrame source;
+ VideoSourceSinkController controller(&sink, &source);
+ EXPECT_CALL(source, RequestRefreshFrame);
+ controller.RequestRefreshFrame();
+}
+
+TEST(VideoSourceSinkControllerTest,
+ RequestsRefreshFrameWithoutSourceDoesNotCrash) {
+ MockVideoSinkWithVideoFrame sink;
+ VideoSourceSinkController controller(&sink, nullptr);
+ controller.RequestRefreshFrame();
+}
+
+TEST(VideoSourceSinkControllerTest, RequestedResolutionPropagatesToWants) {
+ MockVideoSinkWithVideoFrame sink;
+ MockVideoSourceWithVideoFrame source;
+ VideoSourceSinkController controller(&sink, &source);
+ controller.SetRequestedResolution(FrameSize(640, 360));
+ EXPECT_TRUE(controller.requested_resolution().has_value());
+
+ EXPECT_CALL(source, AddOrUpdateSink(_, _))
+ .WillOnce([](rtc::VideoSinkInterface<VideoFrame>* sink,
+ const rtc::VideoSinkWants& wants) {
+ EXPECT_EQ(*wants.requested_resolution, FrameSize(640, 360));
+ });
+ controller.PushSourceSinkSettings();
+}
+
+TEST(VideoSourceSinkControllerTest, ActivePropagatesToWants) {
+ MockVideoSinkWithVideoFrame sink;
+ MockVideoSourceWithVideoFrame source;
+ VideoSourceSinkController controller(&sink, &source);
+ controller.SetActive(true);
+ EXPECT_TRUE(controller.active());
+
+ EXPECT_CALL(source, AddOrUpdateSink(_, _))
+ .WillOnce([](rtc::VideoSinkInterface<VideoFrame>* sink,
+ const rtc::VideoSinkWants& wants) {
+ EXPECT_TRUE(wants.is_active);
+ });
+ controller.PushSourceSinkSettings();
+}
+
+} // namespace webrtc