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