blob: a649adc68c10156946047609a6ce73903735d01f [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
17#include "rtc_base/numerics/safe_conversions.h"
18
19namespace webrtc {
20
21VideoSourceSinkController::VideoSourceSinkController(
22 rtc::VideoSinkInterface<VideoFrame>* sink,
23 rtc::VideoSourceInterface<VideoFrame>* source)
Henrik Boström8234b922020-01-13 17:26:50 +010024 : sink_(sink), source_(source) {
Henrik Boströmce0ea492020-01-13 11:27:18 +010025 RTC_DCHECK(sink_);
26}
27
28void VideoSourceSinkController::SetSource(
Henrik Boström8234b922020-01-13 17:26:50 +010029 rtc::VideoSourceInterface<VideoFrame>* source) {
Henrik Boströmce0ea492020-01-13 11:27:18 +010030 rtc::VideoSourceInterface<VideoFrame>* old_source;
31 rtc::VideoSinkWants wants;
32 {
33 rtc::CritScope lock(&crit_);
34 old_source = source_;
35 source_ = source;
Henrik Boström8234b922020-01-13 17:26:50 +010036 wants = CurrentSettingsToSinkWants();
Henrik Boströmce0ea492020-01-13 11:27:18 +010037 }
38 if (old_source != source && old_source)
39 old_source->RemoveSink(sink_);
40 if (!source)
41 return;
42 source->AddOrUpdateSink(sink_, wants);
43}
44
45void VideoSourceSinkController::PushSourceSinkSettings() {
46 rtc::CritScope lock(&crit_);
47 if (!source_)
48 return;
Henrik Boström8234b922020-01-13 17:26:50 +010049 source_->AddOrUpdateSink(sink_, CurrentSettingsToSinkWants());
Henrik Boströmce0ea492020-01-13 11:27:18 +010050}
51
52VideoSourceRestrictions VideoSourceSinkController::restrictions() const {
53 rtc::CritScope lock(&crit_);
54 return restrictions_;
55}
56
57absl::optional<size_t> VideoSourceSinkController::pixels_per_frame_upper_limit()
58 const {
59 rtc::CritScope lock(&crit_);
60 return pixels_per_frame_upper_limit_;
61}
62
63absl::optional<double> VideoSourceSinkController::frame_rate_upper_limit()
64 const {
65 rtc::CritScope lock(&crit_);
66 return frame_rate_upper_limit_;
67}
68
69bool VideoSourceSinkController::rotation_applied() const {
70 rtc::CritScope lock(&crit_);
71 return rotation_applied_;
72}
73
74int VideoSourceSinkController::resolution_alignment() const {
75 rtc::CritScope lock(&crit_);
76 return resolution_alignment_;
77}
78
79void VideoSourceSinkController::SetRestrictions(
80 VideoSourceRestrictions restrictions) {
81 rtc::CritScope lock(&crit_);
82 restrictions_ = std::move(restrictions);
83}
84
85void VideoSourceSinkController::SetPixelsPerFrameUpperLimit(
86 absl::optional<size_t> pixels_per_frame_upper_limit) {
87 rtc::CritScope lock(&crit_);
88 pixels_per_frame_upper_limit_ = std::move(pixels_per_frame_upper_limit);
89}
90
91void VideoSourceSinkController::SetFrameRateUpperLimit(
92 absl::optional<double> frame_rate_upper_limit) {
93 rtc::CritScope lock(&crit_);
94 frame_rate_upper_limit_ = std::move(frame_rate_upper_limit);
95}
96
97void VideoSourceSinkController::SetRotationApplied(bool rotation_applied) {
98 rtc::CritScope lock(&crit_);
99 rotation_applied_ = rotation_applied;
100}
101
102void VideoSourceSinkController::SetResolutionAlignment(
103 int resolution_alignment) {
104 rtc::CritScope lock(&crit_);
105 resolution_alignment_ = resolution_alignment;
106}
107
Henrik Boström8234b922020-01-13 17:26:50 +0100108// RTC_EXCLUSIVE_LOCKS_REQUIRED(crit_)
Henrik Boströmce0ea492020-01-13 11:27:18 +0100109rtc::VideoSinkWants VideoSourceSinkController::CurrentSettingsToSinkWants()
110 const {
Henrik Boströmce0ea492020-01-13 11:27:18 +0100111 rtc::VideoSinkWants wants;
112 wants.rotation_applied = rotation_applied_;
113 // |wants.black_frames| is not used, it always has its default value false.
114 wants.max_pixel_count =
115 rtc::dchecked_cast<int>(restrictions_.max_pixels_per_frame().value_or(
116 std::numeric_limits<int>::max()));
117 wants.target_pixel_count =
118 restrictions_.target_pixels_per_frame().has_value()
119 ? absl::optional<int>(rtc::dchecked_cast<int>(
120 restrictions_.target_pixels_per_frame().value()))
121 : absl::nullopt;
122 wants.max_framerate_fps =
123 restrictions_.max_frame_rate().has_value()
124 ? static_cast<int>(restrictions_.max_frame_rate().value())
125 : std::numeric_limits<int>::max();
126 wants.resolution_alignment = resolution_alignment_;
Henrik Boströmce0ea492020-01-13 11:27:18 +0100127 wants.max_pixel_count =
128 std::min(wants.max_pixel_count,
129 rtc::dchecked_cast<int>(pixels_per_frame_upper_limit_.value_or(
130 std::numeric_limits<int>::max())));
131 wants.max_framerate_fps =
132 std::min(wants.max_framerate_fps,
133 frame_rate_upper_limit_.has_value()
134 ? static_cast<int>(frame_rate_upper_limit_.value())
135 : std::numeric_limits<int>::max());
136 return wants;
137}
138
139} // namespace webrtc