blob: 2f7b37585d7c84d3641a3e0d97f2918b6573f9a8 [file] [log] [blame]
Henrik Boströmce0ea492020-01-13 11:27:18 +01001/*
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 12:24:57 +020017#include "rtc_base/logging.h"
Henrik Boströmce0ea492020-01-13 11:27:18 +010018#include "rtc_base/numerics/safe_conversions.h"
Henrik Boströme2e8c172020-06-03 09:24:06 +020019#include "rtc_base/strings/string_builder.h"
Henrik Boströmce0ea492020-01-13 11:27:18 +010020
21namespace webrtc {
22
23VideoSourceSinkController::VideoSourceSinkController(
24 rtc::VideoSinkInterface<VideoFrame>* sink,
25 rtc::VideoSourceInterface<VideoFrame>* source)
Henrik Boström8234b922020-01-13 17:26:50 +010026 : sink_(sink), source_(source) {
Henrik Boströmce0ea492020-01-13 11:27:18 +010027 RTC_DCHECK(sink_);
28}
29
Tomas Gunnarsson612445e2020-09-21 14:31:23 +020030VideoSourceSinkController::~VideoSourceSinkController() {
31 RTC_DCHECK_RUN_ON(&sequence_checker_);
32}
33
Henrik Boströmce0ea492020-01-13 11:27:18 +010034void VideoSourceSinkController::SetSource(
Henrik Boström8234b922020-01-13 17:26:50 +010035 rtc::VideoSourceInterface<VideoFrame>* source) {
Tomas Gunnarsson612445e2020-09-21 14:31:23 +020036 RTC_DCHECK_RUN_ON(&sequence_checker_);
37
38 rtc::VideoSourceInterface<VideoFrame>* old_source = source_;
39 source_ = source;
40
Henrik Boströmce0ea492020-01-13 11:27:18 +010041 if (old_source != source && old_source)
42 old_source->RemoveSink(sink_);
Tomas Gunnarsson612445e2020-09-21 14:31:23 +020043
Henrik Boströmce0ea492020-01-13 11:27:18 +010044 if (!source)
45 return;
Tomas Gunnarsson612445e2020-09-21 14:31:23 +020046
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 11:27:18 +010053}
54
Markus Handell2e0f4f02021-12-21 19:14:58 +010055void VideoSourceSinkController::RequestRefreshFrame() {
56 RTC_DCHECK_RUN_ON(&sequence_checker_);
57 if (source_)
58 source_->RequestRefreshFrame();
59}
60
Henrik Boströmce0ea492020-01-13 11:27:18 +010061void VideoSourceSinkController::PushSourceSinkSettings() {
Tomas Gunnarsson612445e2020-09-21 14:31:23 +020062 RTC_DCHECK_RUN_ON(&sequence_checker_);
Henrik Boströmce0ea492020-01-13 11:27:18 +010063 if (!source_)
64 return;
Evan Shrubsole236e0ed2020-05-20 12:24:57 +020065 rtc::VideoSinkWants wants = CurrentSettingsToSinkWants();
Evan Shrubsole236e0ed2020-05-20 12:24:57 +020066 source_->AddOrUpdateSink(sink_, wants);
Henrik Boströmce0ea492020-01-13 11:27:18 +010067}
68
69VideoSourceRestrictions VideoSourceSinkController::restrictions() const {
Tomas Gunnarsson612445e2020-09-21 14:31:23 +020070 RTC_DCHECK_RUN_ON(&sequence_checker_);
Henrik Boströmce0ea492020-01-13 11:27:18 +010071 return restrictions_;
72}
73
74absl::optional<size_t> VideoSourceSinkController::pixels_per_frame_upper_limit()
75 const {
Tomas Gunnarsson612445e2020-09-21 14:31:23 +020076 RTC_DCHECK_RUN_ON(&sequence_checker_);
Henrik Boströmce0ea492020-01-13 11:27:18 +010077 return pixels_per_frame_upper_limit_;
78}
79
80absl::optional<double> VideoSourceSinkController::frame_rate_upper_limit()
81 const {
Tomas Gunnarsson612445e2020-09-21 14:31:23 +020082 RTC_DCHECK_RUN_ON(&sequence_checker_);
Henrik Boströmce0ea492020-01-13 11:27:18 +010083 return frame_rate_upper_limit_;
84}
85
86bool VideoSourceSinkController::rotation_applied() const {
Tomas Gunnarsson612445e2020-09-21 14:31:23 +020087 RTC_DCHECK_RUN_ON(&sequence_checker_);
Henrik Boströmce0ea492020-01-13 11:27:18 +010088 return rotation_applied_;
89}
90
91int VideoSourceSinkController::resolution_alignment() const {
Tomas Gunnarsson612445e2020-09-21 14:31:23 +020092 RTC_DCHECK_RUN_ON(&sequence_checker_);
Henrik Boströmce0ea492020-01-13 11:27:18 +010093 return resolution_alignment_;
94}
95
Henrik Boström1124ed12021-02-25 10:30:39 +010096const std::vector<rtc::VideoSinkWants::FrameSize>&
97VideoSourceSinkController::resolutions() const {
98 RTC_DCHECK_RUN_ON(&sequence_checker_);
99 return resolutions_;
100}
101
Jonas Oreland0deda152022-09-23 12:08:57 +0200102bool VideoSourceSinkController::active() const {
103 RTC_DCHECK_RUN_ON(&sequence_checker_);
104 return active_;
105}
106
107absl::optional<rtc::VideoSinkWants::FrameSize>
108VideoSourceSinkController::requested_resolution() const {
109 RTC_DCHECK_RUN_ON(&sequence_checker_);
110 return requested_resolution_;
111}
112
Henrik Boströmce0ea492020-01-13 11:27:18 +0100113void VideoSourceSinkController::SetRestrictions(
114 VideoSourceRestrictions restrictions) {
Tomas Gunnarsson612445e2020-09-21 14:31:23 +0200115 RTC_DCHECK_RUN_ON(&sequence_checker_);
Henrik Boströmce0ea492020-01-13 11:27:18 +0100116 restrictions_ = std::move(restrictions);
117}
118
119void VideoSourceSinkController::SetPixelsPerFrameUpperLimit(
120 absl::optional<size_t> pixels_per_frame_upper_limit) {
Tomas Gunnarsson612445e2020-09-21 14:31:23 +0200121 RTC_DCHECK_RUN_ON(&sequence_checker_);
Henrik Boströmce0ea492020-01-13 11:27:18 +0100122 pixels_per_frame_upper_limit_ = std::move(pixels_per_frame_upper_limit);
123}
124
125void VideoSourceSinkController::SetFrameRateUpperLimit(
126 absl::optional<double> frame_rate_upper_limit) {
Tomas Gunnarsson612445e2020-09-21 14:31:23 +0200127 RTC_DCHECK_RUN_ON(&sequence_checker_);
Henrik Boströmce0ea492020-01-13 11:27:18 +0100128 frame_rate_upper_limit_ = std::move(frame_rate_upper_limit);
129}
130
131void VideoSourceSinkController::SetRotationApplied(bool rotation_applied) {
Tomas Gunnarsson612445e2020-09-21 14:31:23 +0200132 RTC_DCHECK_RUN_ON(&sequence_checker_);
Henrik Boströmce0ea492020-01-13 11:27:18 +0100133 rotation_applied_ = rotation_applied;
134}
135
136void VideoSourceSinkController::SetResolutionAlignment(
137 int resolution_alignment) {
Tomas Gunnarsson612445e2020-09-21 14:31:23 +0200138 RTC_DCHECK_RUN_ON(&sequence_checker_);
Henrik Boströmce0ea492020-01-13 11:27:18 +0100139 resolution_alignment_ = resolution_alignment;
140}
141
Henrik Boström1124ed12021-02-25 10:30:39 +0100142void 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 12:08:57 +0200148void VideoSourceSinkController::SetActive(bool active) {
149 RTC_DCHECK_RUN_ON(&sequence_checker_);
150 active_ = active;
151}
152
153void VideoSourceSinkController::SetRequestedResolution(
154 absl::optional<rtc::VideoSinkWants::FrameSize> requested_resolution) {
155 RTC_DCHECK_RUN_ON(&sequence_checker_);
156 requested_resolution_ = std::move(requested_resolution);
157}
158
Tomas Gunnarsson612445e2020-09-21 14:31:23 +0200159// RTC_EXCLUSIVE_LOCKS_REQUIRED(sequence_checker_)
Henrik Boströmce0ea492020-01-13 11:27:18 +0100160rtc::VideoSinkWants VideoSourceSinkController::CurrentSettingsToSinkWants()
161 const {
Henrik Boströmce0ea492020-01-13 11:27:18 +0100162 rtc::VideoSinkWants wants;
163 wants.rotation_applied = rotation_applied_;
Artem Titovcfea2182021-08-10 01:22:31 +0200164 // `wants.black_frames` is not used, it always has its default value false.
Henrik Boströmce0ea492020-01-13 11:27:18 +0100165 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()
170 ? absl::optional<int>(rtc::dchecked_cast<int>(
171 restrictions_.target_pixels_per_frame().value()))
172 : absl::nullopt;
173 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 11:27:18 +0100178 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 10:30:39 +0100187 wants.resolutions = resolutions_;
Jonas Oreland0deda152022-09-23 12:08:57 +0200188 wants.is_active = active_;
189 wants.requested_resolution = requested_resolution_;
Henrik Boströmce0ea492020-01-13 11:27:18 +0100190 return wants;
191}
192
193} // namespace webrtc