xref: /aosp_15_r20/external/webrtc/video/video_source_sink_controller.cc (revision d9f758449e529ab9291ac668be2861e7a55c2422)
1*d9f75844SAndroid Build Coastguard Worker /*
2*d9f75844SAndroid Build Coastguard Worker  *  Copyright 2020 The WebRTC Project Authors. All rights reserved.
3*d9f75844SAndroid Build Coastguard Worker  *
4*d9f75844SAndroid Build Coastguard Worker  *  Use of this source code is governed by a BSD-style license
5*d9f75844SAndroid Build Coastguard Worker  *  that can be found in the LICENSE file in the root of the source
6*d9f75844SAndroid Build Coastguard Worker  *  tree. An additional intellectual property rights grant can be found
7*d9f75844SAndroid Build Coastguard Worker  *  in the file PATENTS.  All contributing project authors may
8*d9f75844SAndroid Build Coastguard Worker  *  be found in the AUTHORS file in the root of the source tree.
9*d9f75844SAndroid Build Coastguard Worker  */
10*d9f75844SAndroid Build Coastguard Worker 
11*d9f75844SAndroid Build Coastguard Worker #include "video/video_source_sink_controller.h"
12*d9f75844SAndroid Build Coastguard Worker 
13*d9f75844SAndroid Build Coastguard Worker #include <algorithm>
14*d9f75844SAndroid Build Coastguard Worker #include <limits>
15*d9f75844SAndroid Build Coastguard Worker #include <utility>
16*d9f75844SAndroid Build Coastguard Worker 
17*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/logging.h"
18*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/numerics/safe_conversions.h"
19*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/strings/string_builder.h"
20*d9f75844SAndroid Build Coastguard Worker 
21*d9f75844SAndroid Build Coastguard Worker namespace webrtc {
22*d9f75844SAndroid Build Coastguard Worker 
VideoSourceSinkController(rtc::VideoSinkInterface<VideoFrame> * sink,rtc::VideoSourceInterface<VideoFrame> * source)23*d9f75844SAndroid Build Coastguard Worker VideoSourceSinkController::VideoSourceSinkController(
24*d9f75844SAndroid Build Coastguard Worker     rtc::VideoSinkInterface<VideoFrame>* sink,
25*d9f75844SAndroid Build Coastguard Worker     rtc::VideoSourceInterface<VideoFrame>* source)
26*d9f75844SAndroid Build Coastguard Worker     : sink_(sink), source_(source) {
27*d9f75844SAndroid Build Coastguard Worker   RTC_DCHECK(sink_);
28*d9f75844SAndroid Build Coastguard Worker }
29*d9f75844SAndroid Build Coastguard Worker 
~VideoSourceSinkController()30*d9f75844SAndroid Build Coastguard Worker VideoSourceSinkController::~VideoSourceSinkController() {
31*d9f75844SAndroid Build Coastguard Worker   RTC_DCHECK_RUN_ON(&sequence_checker_);
32*d9f75844SAndroid Build Coastguard Worker }
33*d9f75844SAndroid Build Coastguard Worker 
SetSource(rtc::VideoSourceInterface<VideoFrame> * source)34*d9f75844SAndroid Build Coastguard Worker void VideoSourceSinkController::SetSource(
35*d9f75844SAndroid Build Coastguard Worker     rtc::VideoSourceInterface<VideoFrame>* source) {
36*d9f75844SAndroid Build Coastguard Worker   RTC_DCHECK_RUN_ON(&sequence_checker_);
37*d9f75844SAndroid Build Coastguard Worker 
38*d9f75844SAndroid Build Coastguard Worker   rtc::VideoSourceInterface<VideoFrame>* old_source = source_;
39*d9f75844SAndroid Build Coastguard Worker   source_ = source;
40*d9f75844SAndroid Build Coastguard Worker 
41*d9f75844SAndroid Build Coastguard Worker   if (old_source != source && old_source)
42*d9f75844SAndroid Build Coastguard Worker     old_source->RemoveSink(sink_);
43*d9f75844SAndroid Build Coastguard Worker 
44*d9f75844SAndroid Build Coastguard Worker   if (!source)
45*d9f75844SAndroid Build Coastguard Worker     return;
46*d9f75844SAndroid Build Coastguard Worker 
47*d9f75844SAndroid Build Coastguard Worker   source->AddOrUpdateSink(sink_, CurrentSettingsToSinkWants());
48*d9f75844SAndroid Build Coastguard Worker }
49*d9f75844SAndroid Build Coastguard Worker 
HasSource() const50*d9f75844SAndroid Build Coastguard Worker bool VideoSourceSinkController::HasSource() const {
51*d9f75844SAndroid Build Coastguard Worker   RTC_DCHECK_RUN_ON(&sequence_checker_);
52*d9f75844SAndroid Build Coastguard Worker   return source_ != nullptr;
53*d9f75844SAndroid Build Coastguard Worker }
54*d9f75844SAndroid Build Coastguard Worker 
RequestRefreshFrame()55*d9f75844SAndroid Build Coastguard Worker void VideoSourceSinkController::RequestRefreshFrame() {
56*d9f75844SAndroid Build Coastguard Worker   RTC_DCHECK_RUN_ON(&sequence_checker_);
57*d9f75844SAndroid Build Coastguard Worker   if (source_)
58*d9f75844SAndroid Build Coastguard Worker     source_->RequestRefreshFrame();
59*d9f75844SAndroid Build Coastguard Worker }
60*d9f75844SAndroid Build Coastguard Worker 
PushSourceSinkSettings()61*d9f75844SAndroid Build Coastguard Worker void VideoSourceSinkController::PushSourceSinkSettings() {
62*d9f75844SAndroid Build Coastguard Worker   RTC_DCHECK_RUN_ON(&sequence_checker_);
63*d9f75844SAndroid Build Coastguard Worker   if (!source_)
64*d9f75844SAndroid Build Coastguard Worker     return;
65*d9f75844SAndroid Build Coastguard Worker   rtc::VideoSinkWants wants = CurrentSettingsToSinkWants();
66*d9f75844SAndroid Build Coastguard Worker   source_->AddOrUpdateSink(sink_, wants);
67*d9f75844SAndroid Build Coastguard Worker }
68*d9f75844SAndroid Build Coastguard Worker 
restrictions() const69*d9f75844SAndroid Build Coastguard Worker VideoSourceRestrictions VideoSourceSinkController::restrictions() const {
70*d9f75844SAndroid Build Coastguard Worker   RTC_DCHECK_RUN_ON(&sequence_checker_);
71*d9f75844SAndroid Build Coastguard Worker   return restrictions_;
72*d9f75844SAndroid Build Coastguard Worker }
73*d9f75844SAndroid Build Coastguard Worker 
pixels_per_frame_upper_limit() const74*d9f75844SAndroid Build Coastguard Worker absl::optional<size_t> VideoSourceSinkController::pixels_per_frame_upper_limit()
75*d9f75844SAndroid Build Coastguard Worker     const {
76*d9f75844SAndroid Build Coastguard Worker   RTC_DCHECK_RUN_ON(&sequence_checker_);
77*d9f75844SAndroid Build Coastguard Worker   return pixels_per_frame_upper_limit_;
78*d9f75844SAndroid Build Coastguard Worker }
79*d9f75844SAndroid Build Coastguard Worker 
frame_rate_upper_limit() const80*d9f75844SAndroid Build Coastguard Worker absl::optional<double> VideoSourceSinkController::frame_rate_upper_limit()
81*d9f75844SAndroid Build Coastguard Worker     const {
82*d9f75844SAndroid Build Coastguard Worker   RTC_DCHECK_RUN_ON(&sequence_checker_);
83*d9f75844SAndroid Build Coastguard Worker   return frame_rate_upper_limit_;
84*d9f75844SAndroid Build Coastguard Worker }
85*d9f75844SAndroid Build Coastguard Worker 
rotation_applied() const86*d9f75844SAndroid Build Coastguard Worker bool VideoSourceSinkController::rotation_applied() const {
87*d9f75844SAndroid Build Coastguard Worker   RTC_DCHECK_RUN_ON(&sequence_checker_);
88*d9f75844SAndroid Build Coastguard Worker   return rotation_applied_;
89*d9f75844SAndroid Build Coastguard Worker }
90*d9f75844SAndroid Build Coastguard Worker 
resolution_alignment() const91*d9f75844SAndroid Build Coastguard Worker int VideoSourceSinkController::resolution_alignment() const {
92*d9f75844SAndroid Build Coastguard Worker   RTC_DCHECK_RUN_ON(&sequence_checker_);
93*d9f75844SAndroid Build Coastguard Worker   return resolution_alignment_;
94*d9f75844SAndroid Build Coastguard Worker }
95*d9f75844SAndroid Build Coastguard Worker 
96*d9f75844SAndroid Build Coastguard Worker const std::vector<rtc::VideoSinkWants::FrameSize>&
resolutions() const97*d9f75844SAndroid Build Coastguard Worker VideoSourceSinkController::resolutions() const {
98*d9f75844SAndroid Build Coastguard Worker   RTC_DCHECK_RUN_ON(&sequence_checker_);
99*d9f75844SAndroid Build Coastguard Worker   return resolutions_;
100*d9f75844SAndroid Build Coastguard Worker }
101*d9f75844SAndroid Build Coastguard Worker 
active() const102*d9f75844SAndroid Build Coastguard Worker bool VideoSourceSinkController::active() const {
103*d9f75844SAndroid Build Coastguard Worker   RTC_DCHECK_RUN_ON(&sequence_checker_);
104*d9f75844SAndroid Build Coastguard Worker   return active_;
105*d9f75844SAndroid Build Coastguard Worker }
106*d9f75844SAndroid Build Coastguard Worker 
107*d9f75844SAndroid Build Coastguard Worker absl::optional<rtc::VideoSinkWants::FrameSize>
requested_resolution() const108*d9f75844SAndroid Build Coastguard Worker VideoSourceSinkController::requested_resolution() const {
109*d9f75844SAndroid Build Coastguard Worker   RTC_DCHECK_RUN_ON(&sequence_checker_);
110*d9f75844SAndroid Build Coastguard Worker   return requested_resolution_;
111*d9f75844SAndroid Build Coastguard Worker }
112*d9f75844SAndroid Build Coastguard Worker 
SetRestrictions(VideoSourceRestrictions restrictions)113*d9f75844SAndroid Build Coastguard Worker void VideoSourceSinkController::SetRestrictions(
114*d9f75844SAndroid Build Coastguard Worker     VideoSourceRestrictions restrictions) {
115*d9f75844SAndroid Build Coastguard Worker   RTC_DCHECK_RUN_ON(&sequence_checker_);
116*d9f75844SAndroid Build Coastguard Worker   restrictions_ = std::move(restrictions);
117*d9f75844SAndroid Build Coastguard Worker }
118*d9f75844SAndroid Build Coastguard Worker 
SetPixelsPerFrameUpperLimit(absl::optional<size_t> pixels_per_frame_upper_limit)119*d9f75844SAndroid Build Coastguard Worker void VideoSourceSinkController::SetPixelsPerFrameUpperLimit(
120*d9f75844SAndroid Build Coastguard Worker     absl::optional<size_t> pixels_per_frame_upper_limit) {
121*d9f75844SAndroid Build Coastguard Worker   RTC_DCHECK_RUN_ON(&sequence_checker_);
122*d9f75844SAndroid Build Coastguard Worker   pixels_per_frame_upper_limit_ = std::move(pixels_per_frame_upper_limit);
123*d9f75844SAndroid Build Coastguard Worker }
124*d9f75844SAndroid Build Coastguard Worker 
SetFrameRateUpperLimit(absl::optional<double> frame_rate_upper_limit)125*d9f75844SAndroid Build Coastguard Worker void VideoSourceSinkController::SetFrameRateUpperLimit(
126*d9f75844SAndroid Build Coastguard Worker     absl::optional<double> frame_rate_upper_limit) {
127*d9f75844SAndroid Build Coastguard Worker   RTC_DCHECK_RUN_ON(&sequence_checker_);
128*d9f75844SAndroid Build Coastguard Worker   frame_rate_upper_limit_ = std::move(frame_rate_upper_limit);
129*d9f75844SAndroid Build Coastguard Worker }
130*d9f75844SAndroid Build Coastguard Worker 
SetRotationApplied(bool rotation_applied)131*d9f75844SAndroid Build Coastguard Worker void VideoSourceSinkController::SetRotationApplied(bool rotation_applied) {
132*d9f75844SAndroid Build Coastguard Worker   RTC_DCHECK_RUN_ON(&sequence_checker_);
133*d9f75844SAndroid Build Coastguard Worker   rotation_applied_ = rotation_applied;
134*d9f75844SAndroid Build Coastguard Worker }
135*d9f75844SAndroid Build Coastguard Worker 
SetResolutionAlignment(int resolution_alignment)136*d9f75844SAndroid Build Coastguard Worker void VideoSourceSinkController::SetResolutionAlignment(
137*d9f75844SAndroid Build Coastguard Worker     int resolution_alignment) {
138*d9f75844SAndroid Build Coastguard Worker   RTC_DCHECK_RUN_ON(&sequence_checker_);
139*d9f75844SAndroid Build Coastguard Worker   resolution_alignment_ = resolution_alignment;
140*d9f75844SAndroid Build Coastguard Worker }
141*d9f75844SAndroid Build Coastguard Worker 
SetResolutions(std::vector<rtc::VideoSinkWants::FrameSize> resolutions)142*d9f75844SAndroid Build Coastguard Worker void VideoSourceSinkController::SetResolutions(
143*d9f75844SAndroid Build Coastguard Worker     std::vector<rtc::VideoSinkWants::FrameSize> resolutions) {
144*d9f75844SAndroid Build Coastguard Worker   RTC_DCHECK_RUN_ON(&sequence_checker_);
145*d9f75844SAndroid Build Coastguard Worker   resolutions_ = std::move(resolutions);
146*d9f75844SAndroid Build Coastguard Worker }
147*d9f75844SAndroid Build Coastguard Worker 
SetActive(bool active)148*d9f75844SAndroid Build Coastguard Worker void VideoSourceSinkController::SetActive(bool active) {
149*d9f75844SAndroid Build Coastguard Worker   RTC_DCHECK_RUN_ON(&sequence_checker_);
150*d9f75844SAndroid Build Coastguard Worker   active_ = active;
151*d9f75844SAndroid Build Coastguard Worker }
152*d9f75844SAndroid Build Coastguard Worker 
SetRequestedResolution(absl::optional<rtc::VideoSinkWants::FrameSize> requested_resolution)153*d9f75844SAndroid Build Coastguard Worker void VideoSourceSinkController::SetRequestedResolution(
154*d9f75844SAndroid Build Coastguard Worker     absl::optional<rtc::VideoSinkWants::FrameSize> requested_resolution) {
155*d9f75844SAndroid Build Coastguard Worker   RTC_DCHECK_RUN_ON(&sequence_checker_);
156*d9f75844SAndroid Build Coastguard Worker   requested_resolution_ = std::move(requested_resolution);
157*d9f75844SAndroid Build Coastguard Worker }
158*d9f75844SAndroid Build Coastguard Worker 
159*d9f75844SAndroid Build Coastguard Worker // RTC_EXCLUSIVE_LOCKS_REQUIRED(sequence_checker_)
CurrentSettingsToSinkWants() const160*d9f75844SAndroid Build Coastguard Worker rtc::VideoSinkWants VideoSourceSinkController::CurrentSettingsToSinkWants()
161*d9f75844SAndroid Build Coastguard Worker     const {
162*d9f75844SAndroid Build Coastguard Worker   rtc::VideoSinkWants wants;
163*d9f75844SAndroid Build Coastguard Worker   wants.rotation_applied = rotation_applied_;
164*d9f75844SAndroid Build Coastguard Worker   // `wants.black_frames` is not used, it always has its default value false.
165*d9f75844SAndroid Build Coastguard Worker   wants.max_pixel_count =
166*d9f75844SAndroid Build Coastguard Worker       rtc::dchecked_cast<int>(restrictions_.max_pixels_per_frame().value_or(
167*d9f75844SAndroid Build Coastguard Worker           std::numeric_limits<int>::max()));
168*d9f75844SAndroid Build Coastguard Worker   wants.target_pixel_count =
169*d9f75844SAndroid Build Coastguard Worker       restrictions_.target_pixels_per_frame().has_value()
170*d9f75844SAndroid Build Coastguard Worker           ? absl::optional<int>(rtc::dchecked_cast<int>(
171*d9f75844SAndroid Build Coastguard Worker                 restrictions_.target_pixels_per_frame().value()))
172*d9f75844SAndroid Build Coastguard Worker           : absl::nullopt;
173*d9f75844SAndroid Build Coastguard Worker   wants.max_framerate_fps =
174*d9f75844SAndroid Build Coastguard Worker       restrictions_.max_frame_rate().has_value()
175*d9f75844SAndroid Build Coastguard Worker           ? static_cast<int>(restrictions_.max_frame_rate().value())
176*d9f75844SAndroid Build Coastguard Worker           : std::numeric_limits<int>::max();
177*d9f75844SAndroid Build Coastguard Worker   wants.resolution_alignment = resolution_alignment_;
178*d9f75844SAndroid Build Coastguard Worker   wants.max_pixel_count =
179*d9f75844SAndroid Build Coastguard Worker       std::min(wants.max_pixel_count,
180*d9f75844SAndroid Build Coastguard Worker                rtc::dchecked_cast<int>(pixels_per_frame_upper_limit_.value_or(
181*d9f75844SAndroid Build Coastguard Worker                    std::numeric_limits<int>::max())));
182*d9f75844SAndroid Build Coastguard Worker   wants.max_framerate_fps =
183*d9f75844SAndroid Build Coastguard Worker       std::min(wants.max_framerate_fps,
184*d9f75844SAndroid Build Coastguard Worker                frame_rate_upper_limit_.has_value()
185*d9f75844SAndroid Build Coastguard Worker                    ? static_cast<int>(frame_rate_upper_limit_.value())
186*d9f75844SAndroid Build Coastguard Worker                    : std::numeric_limits<int>::max());
187*d9f75844SAndroid Build Coastguard Worker   wants.resolutions = resolutions_;
188*d9f75844SAndroid Build Coastguard Worker   wants.is_active = active_;
189*d9f75844SAndroid Build Coastguard Worker   wants.requested_resolution = requested_resolution_;
190*d9f75844SAndroid Build Coastguard Worker   return wants;
191*d9f75844SAndroid Build Coastguard Worker }
192*d9f75844SAndroid Build Coastguard Worker 
193*d9f75844SAndroid Build Coastguard Worker }  // namespace webrtc
194