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 "call/adaptation/video_source_restrictions.h"
12
13 #include <algorithm>
14 #include <limits>
15
16 #include "rtc_base/checks.h"
17 #include "rtc_base/strings/string_builder.h"
18
19 namespace webrtc {
20
VideoSourceRestrictions()21 VideoSourceRestrictions::VideoSourceRestrictions()
22 : max_pixels_per_frame_(absl::nullopt),
23 target_pixels_per_frame_(absl::nullopt),
24 max_frame_rate_(absl::nullopt) {}
25
VideoSourceRestrictions(absl::optional<size_t> max_pixels_per_frame,absl::optional<size_t> target_pixels_per_frame,absl::optional<double> max_frame_rate)26 VideoSourceRestrictions::VideoSourceRestrictions(
27 absl::optional<size_t> max_pixels_per_frame,
28 absl::optional<size_t> target_pixels_per_frame,
29 absl::optional<double> max_frame_rate)
30 : max_pixels_per_frame_(std::move(max_pixels_per_frame)),
31 target_pixels_per_frame_(std::move(target_pixels_per_frame)),
32 max_frame_rate_(std::move(max_frame_rate)) {
33 RTC_DCHECK(!max_pixels_per_frame_.has_value() ||
34 max_pixels_per_frame_.value() <
35 static_cast<size_t>(std::numeric_limits<int>::max()));
36 RTC_DCHECK(!max_frame_rate_.has_value() ||
37 max_frame_rate_.value() < std::numeric_limits<int>::max());
38 RTC_DCHECK(!max_frame_rate_.has_value() || max_frame_rate_.value() > 0.0);
39 }
40
ToString() const41 std::string VideoSourceRestrictions::ToString() const {
42 rtc::StringBuilder ss;
43 ss << "{";
44 if (max_frame_rate_)
45 ss << " max_fps=" << max_frame_rate_.value();
46 if (max_pixels_per_frame_)
47 ss << " max_pixels_per_frame=" << max_pixels_per_frame_.value();
48 if (target_pixels_per_frame_)
49 ss << " target_pixels_per_frame=" << target_pixels_per_frame_.value();
50 ss << " }";
51 return ss.Release();
52 }
53
max_pixels_per_frame() const54 const absl::optional<size_t>& VideoSourceRestrictions::max_pixels_per_frame()
55 const {
56 return max_pixels_per_frame_;
57 }
58
target_pixels_per_frame() const59 const absl::optional<size_t>& VideoSourceRestrictions::target_pixels_per_frame()
60 const {
61 return target_pixels_per_frame_;
62 }
63
max_frame_rate() const64 const absl::optional<double>& VideoSourceRestrictions::max_frame_rate() const {
65 return max_frame_rate_;
66 }
67
set_max_pixels_per_frame(absl::optional<size_t> max_pixels_per_frame)68 void VideoSourceRestrictions::set_max_pixels_per_frame(
69 absl::optional<size_t> max_pixels_per_frame) {
70 max_pixels_per_frame_ = std::move(max_pixels_per_frame);
71 }
72
set_target_pixels_per_frame(absl::optional<size_t> target_pixels_per_frame)73 void VideoSourceRestrictions::set_target_pixels_per_frame(
74 absl::optional<size_t> target_pixels_per_frame) {
75 target_pixels_per_frame_ = std::move(target_pixels_per_frame);
76 }
77
set_max_frame_rate(absl::optional<double> max_frame_rate)78 void VideoSourceRestrictions::set_max_frame_rate(
79 absl::optional<double> max_frame_rate) {
80 max_frame_rate_ = std::move(max_frame_rate);
81 }
82
UpdateMin(const VideoSourceRestrictions & other)83 void VideoSourceRestrictions::UpdateMin(const VideoSourceRestrictions& other) {
84 if (max_pixels_per_frame_.has_value()) {
85 max_pixels_per_frame_ = std::min(*max_pixels_per_frame_,
86 other.max_pixels_per_frame().value_or(
87 std::numeric_limits<size_t>::max()));
88 } else {
89 max_pixels_per_frame_ = other.max_pixels_per_frame();
90 }
91 if (target_pixels_per_frame_.has_value()) {
92 target_pixels_per_frame_ = std::min(
93 *target_pixels_per_frame_, other.target_pixels_per_frame().value_or(
94 std::numeric_limits<size_t>::max()));
95 } else {
96 target_pixels_per_frame_ = other.target_pixels_per_frame();
97 }
98 if (max_frame_rate_.has_value()) {
99 max_frame_rate_ = std::min(
100 *max_frame_rate_,
101 other.max_frame_rate().value_or(std::numeric_limits<double>::max()));
102 } else {
103 max_frame_rate_ = other.max_frame_rate();
104 }
105 }
106
DidRestrictionsIncrease(VideoSourceRestrictions before,VideoSourceRestrictions after)107 bool DidRestrictionsIncrease(VideoSourceRestrictions before,
108 VideoSourceRestrictions after) {
109 bool decreased_resolution = DidDecreaseResolution(before, after);
110 bool decreased_framerate = DidDecreaseFrameRate(before, after);
111 bool same_resolution =
112 before.max_pixels_per_frame() == after.max_pixels_per_frame();
113 bool same_framerate = before.max_frame_rate() == after.max_frame_rate();
114
115 return (decreased_resolution && decreased_framerate) ||
116 (decreased_resolution && same_framerate) ||
117 (same_resolution && decreased_framerate);
118 }
119
DidRestrictionsDecrease(VideoSourceRestrictions before,VideoSourceRestrictions after)120 bool DidRestrictionsDecrease(VideoSourceRestrictions before,
121 VideoSourceRestrictions after) {
122 bool increased_resolution = DidIncreaseResolution(before, after);
123 bool increased_framerate = DidIncreaseFrameRate(before, after);
124 bool same_resolution =
125 before.max_pixels_per_frame() == after.max_pixels_per_frame();
126 bool same_framerate = before.max_frame_rate() == after.max_frame_rate();
127
128 return (increased_resolution && increased_framerate) ||
129 (increased_resolution && same_framerate) ||
130 (same_resolution && increased_framerate);
131 }
132
DidIncreaseResolution(VideoSourceRestrictions restrictions_before,VideoSourceRestrictions restrictions_after)133 bool DidIncreaseResolution(VideoSourceRestrictions restrictions_before,
134 VideoSourceRestrictions restrictions_after) {
135 if (!restrictions_before.max_pixels_per_frame().has_value())
136 return false;
137 if (!restrictions_after.max_pixels_per_frame().has_value())
138 return true;
139 return restrictions_after.max_pixels_per_frame().value() >
140 restrictions_before.max_pixels_per_frame().value();
141 }
142
DidDecreaseResolution(VideoSourceRestrictions restrictions_before,VideoSourceRestrictions restrictions_after)143 bool DidDecreaseResolution(VideoSourceRestrictions restrictions_before,
144 VideoSourceRestrictions restrictions_after) {
145 if (!restrictions_after.max_pixels_per_frame().has_value())
146 return false;
147 if (!restrictions_before.max_pixels_per_frame().has_value())
148 return true;
149 return restrictions_after.max_pixels_per_frame().value() <
150 restrictions_before.max_pixels_per_frame().value();
151 }
152
DidIncreaseFrameRate(VideoSourceRestrictions restrictions_before,VideoSourceRestrictions restrictions_after)153 bool DidIncreaseFrameRate(VideoSourceRestrictions restrictions_before,
154 VideoSourceRestrictions restrictions_after) {
155 if (!restrictions_before.max_frame_rate().has_value())
156 return false;
157 if (!restrictions_after.max_frame_rate().has_value())
158 return true;
159 return restrictions_after.max_frame_rate().value() >
160 restrictions_before.max_frame_rate().value();
161 }
162
DidDecreaseFrameRate(VideoSourceRestrictions restrictions_before,VideoSourceRestrictions restrictions_after)163 bool DidDecreaseFrameRate(VideoSourceRestrictions restrictions_before,
164 VideoSourceRestrictions restrictions_after) {
165 if (!restrictions_after.max_frame_rate().has_value())
166 return false;
167 if (!restrictions_before.max_frame_rate().has_value())
168 return true;
169 return restrictions_after.max_frame_rate().value() <
170 restrictions_before.max_frame_rate().value();
171 }
172
173 } // namespace webrtc
174