blob: dcecd3a19d4cf8943108e1069eae6bd106ec4200 [file] [log] [blame]
Henrik Boströmce0ea492020-01-13 10:27:181/*
2 * Copyright 2020 The WebRTC Project Authors. All rights reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11#include "video/video_source_sink_controller.h"
12
13#include <algorithm>
14#include <limits>
15#include <utility>
16
Evan Shrubsole236e0ed2020-05-20 10:24:5717#include "rtc_base/logging.h"
Henrik Boströmce0ea492020-01-13 10:27:1818#include "rtc_base/numerics/safe_conversions.h"
Henrik Boströme2e8c172020-06-03 07:24:0619#include "rtc_base/strings/string_builder.h"
Henrik Boströmce0ea492020-01-13 10:27:1820
21namespace webrtc {
22
23VideoSourceSinkController::VideoSourceSinkController(
24 rtc::VideoSinkInterface<VideoFrame>* sink,
25 rtc::VideoSourceInterface<VideoFrame>* source)
Henrik Boström8234b922020-01-13 16:26:5026 : sink_(sink), source_(source) {
Henrik Boströmce0ea492020-01-13 10:27:1827 RTC_DCHECK(sink_);
28}
29
Tomas Gunnarsson612445e2020-09-21 12:31:2330VideoSourceSinkController::~VideoSourceSinkController() {
31 RTC_DCHECK_RUN_ON(&sequence_checker_);
32}
33
Henrik Boströmce0ea492020-01-13 10:27:1834void VideoSourceSinkController::SetSource(
Henrik Boström8234b922020-01-13 16:26:5035 rtc::VideoSourceInterface<VideoFrame>* source) {
Tomas Gunnarsson612445e2020-09-21 12:31:2336 RTC_DCHECK_RUN_ON(&sequence_checker_);
37
38 rtc::VideoSourceInterface<VideoFrame>* old_source = source_;
39 source_ = source;
40
Henrik Boströmce0ea492020-01-13 10:27:1841 if (old_source != source && old_source)
42 old_source->RemoveSink(sink_);
Tomas Gunnarsson612445e2020-09-21 12:31:2343
Henrik Boströmce0ea492020-01-13 10:27:1844 if (!source)
45 return;
Tomas Gunnarsson612445e2020-09-21 12:31:2346
47 source->AddOrUpdateSink(sink_, CurrentSettingsToSinkWants());
48}
49
50bool VideoSourceSinkController::HasSource() const {
51 RTC_DCHECK_RUN_ON(&sequence_checker_);
52 return source_ != nullptr;
Henrik Boströmce0ea492020-01-13 10:27:1853}
54
Markus Handell2e0f4f02021-12-21 18:14:5855void VideoSourceSinkController::RequestRefreshFrame() {
56 RTC_DCHECK_RUN_ON(&sequence_checker_);
57 if (source_)
58 source_->RequestRefreshFrame();
59}
60
Henrik Boströmce0ea492020-01-13 10:27:1861void VideoSourceSinkController::PushSourceSinkSettings() {
Tomas Gunnarsson612445e2020-09-21 12:31:2362 RTC_DCHECK_RUN_ON(&sequence_checker_);
Henrik Boströmce0ea492020-01-13 10:27:1863 if (!source_)
64 return;
Evan Shrubsole236e0ed2020-05-20 10:24:5765 rtc::VideoSinkWants wants = CurrentSettingsToSinkWants();
Evan Shrubsole236e0ed2020-05-20 10:24:5766 source_->AddOrUpdateSink(sink_, wants);
Henrik Boströmce0ea492020-01-13 10:27:1867}
68
69VideoSourceRestrictions VideoSourceSinkController::restrictions() const {
Tomas Gunnarsson612445e2020-09-21 12:31:2370 RTC_DCHECK_RUN_ON(&sequence_checker_);
Henrik Boströmce0ea492020-01-13 10:27:1871 return restrictions_;
72}
73
Florent Castelli8037fc62024-08-29 13:00:4074std::optional<size_t> VideoSourceSinkController::pixels_per_frame_upper_limit()
Henrik Boströmce0ea492020-01-13 10:27:1875 const {
Tomas Gunnarsson612445e2020-09-21 12:31:2376 RTC_DCHECK_RUN_ON(&sequence_checker_);
Henrik Boströmce0ea492020-01-13 10:27:1877 return pixels_per_frame_upper_limit_;
78}
79
Florent Castelli8037fc62024-08-29 13:00:4080std::optional<double> VideoSourceSinkController::frame_rate_upper_limit()
Henrik Boströmce0ea492020-01-13 10:27:1881 const {
Tomas Gunnarsson612445e2020-09-21 12:31:2382 RTC_DCHECK_RUN_ON(&sequence_checker_);
Henrik Boströmce0ea492020-01-13 10:27:1883 return frame_rate_upper_limit_;
84}
85
86bool VideoSourceSinkController::rotation_applied() const {
Tomas Gunnarsson612445e2020-09-21 12:31:2387 RTC_DCHECK_RUN_ON(&sequence_checker_);
Henrik Boströmce0ea492020-01-13 10:27:1888 return rotation_applied_;
89}
90
91int VideoSourceSinkController::resolution_alignment() const {
Tomas Gunnarsson612445e2020-09-21 12:31:2392 RTC_DCHECK_RUN_ON(&sequence_checker_);
Henrik Boströmce0ea492020-01-13 10:27:1893 return resolution_alignment_;
94}
95
Henrik Boström1124ed12021-02-25 09:30:3996const std::vector<rtc::VideoSinkWants::FrameSize>&
97VideoSourceSinkController::resolutions() const {
98 RTC_DCHECK_RUN_ON(&sequence_checker_);
99 return resolutions_;
100}
101
Jonas Oreland0deda152022-09-23 10:08:57102bool VideoSourceSinkController::active() const {
103 RTC_DCHECK_RUN_ON(&sequence_checker_);
104 return active_;
105}
106
Florent Castelli8037fc62024-08-29 13:00:40107std::optional<rtc::VideoSinkWants::FrameSize>
Henrik Boströme8c97c02024-10-25 07:51:44108VideoSourceSinkController::scale_resolution_down_to() const {
Jonas Oreland0deda152022-09-23 10:08:57109 RTC_DCHECK_RUN_ON(&sequence_checker_);
Henrik Boströme8c97c02024-10-25 07:51:44110 return scale_resolution_down_to_;
Jonas Oreland0deda152022-09-23 10:08:57111}
112
Henrik Boströmce0ea492020-01-13 10:27:18113void VideoSourceSinkController::SetRestrictions(
114 VideoSourceRestrictions restrictions) {
Tomas Gunnarsson612445e2020-09-21 12:31:23115 RTC_DCHECK_RUN_ON(&sequence_checker_);
Henrik Boströmce0ea492020-01-13 10:27:18116 restrictions_ = std::move(restrictions);
117}
118
119void VideoSourceSinkController::SetPixelsPerFrameUpperLimit(
Florent Castelli8037fc62024-08-29 13:00:40120 std::optional<size_t> pixels_per_frame_upper_limit) {
Tomas Gunnarsson612445e2020-09-21 12:31:23121 RTC_DCHECK_RUN_ON(&sequence_checker_);
Henrik Boströmce0ea492020-01-13 10:27:18122 pixels_per_frame_upper_limit_ = std::move(pixels_per_frame_upper_limit);
123}
124
125void VideoSourceSinkController::SetFrameRateUpperLimit(
Florent Castelli8037fc62024-08-29 13:00:40126 std::optional<double> frame_rate_upper_limit) {
Tomas Gunnarsson612445e2020-09-21 12:31:23127 RTC_DCHECK_RUN_ON(&sequence_checker_);
Henrik Boströmce0ea492020-01-13 10:27:18128 frame_rate_upper_limit_ = std::move(frame_rate_upper_limit);
129}
130
131void VideoSourceSinkController::SetRotationApplied(bool rotation_applied) {
Tomas Gunnarsson612445e2020-09-21 12:31:23132 RTC_DCHECK_RUN_ON(&sequence_checker_);
Henrik Boströmce0ea492020-01-13 10:27:18133 rotation_applied_ = rotation_applied;
134}
135
136void VideoSourceSinkController::SetResolutionAlignment(
137 int resolution_alignment) {
Tomas Gunnarsson612445e2020-09-21 12:31:23138 RTC_DCHECK_RUN_ON(&sequence_checker_);
Henrik Boströmce0ea492020-01-13 10:27:18139 resolution_alignment_ = resolution_alignment;
140}
141
Henrik Boström1124ed12021-02-25 09:30:39142void VideoSourceSinkController::SetResolutions(
143 std::vector<rtc::VideoSinkWants::FrameSize> resolutions) {
144 RTC_DCHECK_RUN_ON(&sequence_checker_);
145 resolutions_ = std::move(resolutions);
146}
147
Jonas Oreland0deda152022-09-23 10:08:57148void VideoSourceSinkController::SetActive(bool active) {
149 RTC_DCHECK_RUN_ON(&sequence_checker_);
150 active_ = active;
151}
152
Henrik Boströme8c97c02024-10-25 07:51:44153void VideoSourceSinkController::SetScaleResolutionDownTo(
154 std::optional<rtc::VideoSinkWants::FrameSize> scale_resolution_down_to) {
Jonas Oreland0deda152022-09-23 10:08:57155 RTC_DCHECK_RUN_ON(&sequence_checker_);
Henrik Boströme8c97c02024-10-25 07:51:44156 scale_resolution_down_to_ = std::move(scale_resolution_down_to);
Jonas Oreland0deda152022-09-23 10:08:57157}
158
Tomas Gunnarsson612445e2020-09-21 12:31:23159// RTC_EXCLUSIVE_LOCKS_REQUIRED(sequence_checker_)
Henrik Boströmce0ea492020-01-13 10:27:18160rtc::VideoSinkWants VideoSourceSinkController::CurrentSettingsToSinkWants()
161 const {
Henrik Boströmce0ea492020-01-13 10:27:18162 rtc::VideoSinkWants wants;
163 wants.rotation_applied = rotation_applied_;
Artem Titovcfea2182021-08-09 23:22:31164 // `wants.black_frames` is not used, it always has its default value false.
Henrik Boströmce0ea492020-01-13 10:27:18165 wants.max_pixel_count =
166 rtc::dchecked_cast<int>(restrictions_.max_pixels_per_frame().value_or(
167 std::numeric_limits<int>::max()));
168 wants.target_pixel_count =
169 restrictions_.target_pixels_per_frame().has_value()
Florent Castelli8037fc62024-08-29 13:00:40170 ? std::optional<int>(rtc::dchecked_cast<int>(
Henrik Boströmce0ea492020-01-13 10:27:18171 restrictions_.target_pixels_per_frame().value()))
Florent Castelli8037fc62024-08-29 13:00:40172 : std::nullopt;
Henrik Boströmce0ea492020-01-13 10:27:18173 wants.max_framerate_fps =
174 restrictions_.max_frame_rate().has_value()
175 ? static_cast<int>(restrictions_.max_frame_rate().value())
176 : std::numeric_limits<int>::max();
177 wants.resolution_alignment = resolution_alignment_;
Henrik Boströmce0ea492020-01-13 10:27:18178 wants.max_pixel_count =
179 std::min(wants.max_pixel_count,
180 rtc::dchecked_cast<int>(pixels_per_frame_upper_limit_.value_or(
181 std::numeric_limits<int>::max())));
182 wants.max_framerate_fps =
183 std::min(wants.max_framerate_fps,
184 frame_rate_upper_limit_.has_value()
185 ? static_cast<int>(frame_rate_upper_limit_.value())
186 : std::numeric_limits<int>::max());
Henrik Boström1124ed12021-02-25 09:30:39187 wants.resolutions = resolutions_;
Jonas Oreland0deda152022-09-23 10:08:57188 wants.is_active = active_;
Henrik Boströme8c97c02024-10-25 07:51:44189 wants.requested_resolution = scale_resolution_down_to_;
Henrik Boströmce0ea492020-01-13 10:27:18190 return wants;
191}
192
193} // namespace webrtc