• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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 
17 #include "rtc_base/logging.h"
18 #include "rtc_base/numerics/safe_conversions.h"
19 #include "rtc_base/strings/string_builder.h"
20 
21 namespace webrtc {
22 
VideoSourceSinkController(rtc::VideoSinkInterface<VideoFrame> * sink,rtc::VideoSourceInterface<VideoFrame> * source)23 VideoSourceSinkController::VideoSourceSinkController(
24     rtc::VideoSinkInterface<VideoFrame>* sink,
25     rtc::VideoSourceInterface<VideoFrame>* source)
26     : sink_(sink), source_(source) {
27   RTC_DCHECK(sink_);
28 }
29 
~VideoSourceSinkController()30 VideoSourceSinkController::~VideoSourceSinkController() {
31   RTC_DCHECK_RUN_ON(&sequence_checker_);
32 }
33 
SetSource(rtc::VideoSourceInterface<VideoFrame> * source)34 void VideoSourceSinkController::SetSource(
35     rtc::VideoSourceInterface<VideoFrame>* source) {
36   RTC_DCHECK_RUN_ON(&sequence_checker_);
37 
38   rtc::VideoSourceInterface<VideoFrame>* old_source = source_;
39   source_ = source;
40 
41   if (old_source != source && old_source)
42     old_source->RemoveSink(sink_);
43 
44   if (!source)
45     return;
46 
47   source->AddOrUpdateSink(sink_, CurrentSettingsToSinkWants());
48 }
49 
HasSource() const50 bool VideoSourceSinkController::HasSource() const {
51   RTC_DCHECK_RUN_ON(&sequence_checker_);
52   return source_ != nullptr;
53 }
54 
RequestRefreshFrame()55 void VideoSourceSinkController::RequestRefreshFrame() {
56   RTC_DCHECK_RUN_ON(&sequence_checker_);
57   if (source_)
58     source_->RequestRefreshFrame();
59 }
60 
PushSourceSinkSettings()61 void VideoSourceSinkController::PushSourceSinkSettings() {
62   RTC_DCHECK_RUN_ON(&sequence_checker_);
63   if (!source_)
64     return;
65   rtc::VideoSinkWants wants = CurrentSettingsToSinkWants();
66   source_->AddOrUpdateSink(sink_, wants);
67 }
68 
restrictions() const69 VideoSourceRestrictions VideoSourceSinkController::restrictions() const {
70   RTC_DCHECK_RUN_ON(&sequence_checker_);
71   return restrictions_;
72 }
73 
pixels_per_frame_upper_limit() const74 absl::optional<size_t> VideoSourceSinkController::pixels_per_frame_upper_limit()
75     const {
76   RTC_DCHECK_RUN_ON(&sequence_checker_);
77   return pixels_per_frame_upper_limit_;
78 }
79 
frame_rate_upper_limit() const80 absl::optional<double> VideoSourceSinkController::frame_rate_upper_limit()
81     const {
82   RTC_DCHECK_RUN_ON(&sequence_checker_);
83   return frame_rate_upper_limit_;
84 }
85 
rotation_applied() const86 bool VideoSourceSinkController::rotation_applied() const {
87   RTC_DCHECK_RUN_ON(&sequence_checker_);
88   return rotation_applied_;
89 }
90 
resolution_alignment() const91 int VideoSourceSinkController::resolution_alignment() const {
92   RTC_DCHECK_RUN_ON(&sequence_checker_);
93   return resolution_alignment_;
94 }
95 
96 const std::vector<rtc::VideoSinkWants::FrameSize>&
resolutions() const97 VideoSourceSinkController::resolutions() const {
98   RTC_DCHECK_RUN_ON(&sequence_checker_);
99   return resolutions_;
100 }
101 
active() const102 bool VideoSourceSinkController::active() const {
103   RTC_DCHECK_RUN_ON(&sequence_checker_);
104   return active_;
105 }
106 
107 absl::optional<rtc::VideoSinkWants::FrameSize>
requested_resolution() const108 VideoSourceSinkController::requested_resolution() const {
109   RTC_DCHECK_RUN_ON(&sequence_checker_);
110   return requested_resolution_;
111 }
112 
SetRestrictions(VideoSourceRestrictions restrictions)113 void VideoSourceSinkController::SetRestrictions(
114     VideoSourceRestrictions restrictions) {
115   RTC_DCHECK_RUN_ON(&sequence_checker_);
116   restrictions_ = std::move(restrictions);
117 }
118 
SetPixelsPerFrameUpperLimit(absl::optional<size_t> pixels_per_frame_upper_limit)119 void VideoSourceSinkController::SetPixelsPerFrameUpperLimit(
120     absl::optional<size_t> pixels_per_frame_upper_limit) {
121   RTC_DCHECK_RUN_ON(&sequence_checker_);
122   pixels_per_frame_upper_limit_ = std::move(pixels_per_frame_upper_limit);
123 }
124 
SetFrameRateUpperLimit(absl::optional<double> frame_rate_upper_limit)125 void VideoSourceSinkController::SetFrameRateUpperLimit(
126     absl::optional<double> frame_rate_upper_limit) {
127   RTC_DCHECK_RUN_ON(&sequence_checker_);
128   frame_rate_upper_limit_ = std::move(frame_rate_upper_limit);
129 }
130 
SetRotationApplied(bool rotation_applied)131 void VideoSourceSinkController::SetRotationApplied(bool rotation_applied) {
132   RTC_DCHECK_RUN_ON(&sequence_checker_);
133   rotation_applied_ = rotation_applied;
134 }
135 
SetResolutionAlignment(int resolution_alignment)136 void VideoSourceSinkController::SetResolutionAlignment(
137     int resolution_alignment) {
138   RTC_DCHECK_RUN_ON(&sequence_checker_);
139   resolution_alignment_ = resolution_alignment;
140 }
141 
SetResolutions(std::vector<rtc::VideoSinkWants::FrameSize> resolutions)142 void VideoSourceSinkController::SetResolutions(
143     std::vector<rtc::VideoSinkWants::FrameSize> resolutions) {
144   RTC_DCHECK_RUN_ON(&sequence_checker_);
145   resolutions_ = std::move(resolutions);
146 }
147 
SetActive(bool active)148 void VideoSourceSinkController::SetActive(bool active) {
149   RTC_DCHECK_RUN_ON(&sequence_checker_);
150   active_ = active;
151 }
152 
SetRequestedResolution(absl::optional<rtc::VideoSinkWants::FrameSize> requested_resolution)153 void 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 
159 // RTC_EXCLUSIVE_LOCKS_REQUIRED(sequence_checker_)
CurrentSettingsToSinkWants() const160 rtc::VideoSinkWants VideoSourceSinkController::CurrentSettingsToSinkWants()
161     const {
162   rtc::VideoSinkWants wants;
163   wants.rotation_applied = rotation_applied_;
164   // `wants.black_frames` is not used, it always has its default value false.
165   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_;
178   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());
187   wants.resolutions = resolutions_;
188   wants.is_active = active_;
189   wants.requested_resolution = requested_resolution_;
190   return wants;
191 }
192 
193 }  // namespace webrtc
194