xref: /aosp_15_r20/external/openscreen/cast/streaming/capture_recommendations.h (revision 3f982cf4871df8771c9d4abe6e9a6f8d829b2736)
1 // Copyright 2020 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef CAST_STREAMING_CAPTURE_RECOMMENDATIONS_H_
6 #define CAST_STREAMING_CAPTURE_RECOMMENDATIONS_H_
7 
8 #include <chrono>
9 #include <cmath>
10 #include <memory>
11 #include <tuple>
12 
13 #include "cast/streaming/constants.h"
14 #include "cast/streaming/resolution.h"
15 namespace openscreen {
16 namespace cast {
17 
18 struct Answer;
19 
20 // This namespace contains classes and functions to be used by senders for
21 // determining what constraints are recommended for the capture device, based on
22 // the limits reported by the receiver.
23 //
24 // A general note about recommendations: they are NOT maximum operational
25 // limits, instead they are targeted to provide a delightful cast experience.
26 // For example, if a receiver is connected to a 1080P display but cannot provide
27 // 1080P at a stable FPS with a good experience, 1080P will not be recommended.
28 namespace capture_recommendations {
29 
30 // Default maximum delay for both audio and video. Used if the sender fails
31 // to provide any constraints.
32 constexpr std::chrono::milliseconds kDefaultMaxDelayMs(400);
33 
34 // Bit rate limits, used for both audio and video streams.
35 struct BitRateLimits {
36   bool operator==(const BitRateLimits& other) const;
37 
38   // Minimum bit rate, in bits per second.
39   int minimum;
40 
41   // Maximum bit rate, in bits per second.
42   int maximum;
43 };
44 
45 // The mirroring control protocol specifies 32kbps as the absolute minimum
46 // for audio. Depending on the type of audio content (narrowband, fullband,
47 // etc.) Opus specifically can perform very well at this bitrate.
48 // See: https://research.google/pubs/pub41650/
49 constexpr int kDefaultAudioMinBitRate = 32 * 1000;
50 
51 // Opus generally sees little improvement above 192kbps, but some older codecs
52 // that we may consider supporting improve at up to 256kbps.
53 constexpr int kDefaultAudioMaxBitRate = 256 * 1000;
54 constexpr BitRateLimits kDefaultAudioBitRateLimits{kDefaultAudioMinBitRate,
55                                                    kDefaultAudioMaxBitRate};
56 
57 // While generally audio should be captured at the maximum sample rate, 16kHz is
58 // the recommended absolute minimum.
59 constexpr int kDefaultAudioMinSampleRate = 16000;
60 
61 // Audio capture recommendations. Maximum delay is determined by buffer
62 // constraints, and capture bit rate may vary between limits as appropriate.
63 struct Audio {
64   bool operator==(const Audio& other) const;
65 
66   // Represents the recommended bit rate range.
67   BitRateLimits bit_rate_limits = kDefaultAudioBitRateLimits;
68 
69   // Represents the maximum audio delay, in milliseconds.
70   std::chrono::milliseconds max_delay = kDefaultMaxDelayMs;
71 
72   // Represents the maximum number of audio channels.
73   int max_channels = kDefaultAudioChannels;
74 
75   // Represents the maximum samples per second.
76   int max_sample_rate = kDefaultAudioSampleRate;
77 
78   // Represents the absolute minimum samples per second. Generally speaking,
79   // audio should be captured at the maximum samples per second rate.
80   int min_sample_rate = kDefaultAudioMinSampleRate;
81 };
82 
83 // The minimum dimensions are as close as possible to low-definition
84 // television, factoring in the receiver's aspect ratio if provided.
85 constexpr Resolution kDefaultMinResolution{kMinVideoWidth, kMinVideoHeight};
86 
87 // Currently mirroring only supports 1080P.
88 constexpr Dimensions kDefaultMaxResolution{1920, 1080, kDefaultFrameRate};
89 
90 // The mirroring spec suggests 300kbps as the absolute minimum bitrate.
91 constexpr int kDefaultVideoMinBitRate = 300 * 1000;
92 
93 // The theoretical maximum pixels per second is the maximum bit rate
94 // divided by 8 (the max byte rate). In practice it should generally be
95 // less.
96 constexpr int kDefaultVideoMaxPixelsPerSecond =
97     kDefaultMaxResolution.effective_bit_rate() / 8;
98 
99 // Our default limits are merely the product of the minimum and maximum
100 // dimensions, and are only used if the receiver fails to give better
101 // constraint information.
102 const BitRateLimits kDefaultVideoBitRateLimits{
103     kDefaultVideoMinBitRate, kDefaultMaxResolution.effective_bit_rate()};
104 
105 // Video capture recommendations.
106 struct Video {
107   bool operator==(const Video& other) const;
108 
109   // Represents the recommended bit rate range.
110   BitRateLimits bit_rate_limits = kDefaultVideoBitRateLimits;
111 
112   // Represents the recommended minimum resolution.
113   Resolution minimum = kDefaultMinResolution;
114 
115   // Represents the recommended maximum resolution.
116   Dimensions maximum = kDefaultMaxResolution;
117 
118   // Indicates whether the receiver can scale frames from a different aspect
119   // ratio, or if it needs to be done by the sender. Default is false, meaning
120   // that the sender is responsible for letterboxing.
121   bool supports_scaling = false;
122 
123   // Represents the maximum video delay, in milliseconds.
124   std::chrono::milliseconds max_delay = kDefaultMaxDelayMs;
125 
126   // Represents the maximum pixels per second, not necessarily correlated
127   // to bit rate.
128   int max_pixels_per_second = kDefaultVideoMaxPixelsPerSecond;
129 };
130 
131 // Outputted recommendations for usage by capture devices. Note that we always
132 // return both audio and video (it is up to the sender to determine what
133 // streams actually get created). If the receiver doesn't give us any
134 // information for making recommendations, the defaults are used.
135 struct Recommendations {
136   bool operator==(const Recommendations& other) const;
137 
138   // Audio specific recommendations.
139   Audio audio;
140 
141   // Video specific recommendations.
142   Video video;
143 };
144 
145 Recommendations GetRecommendations(const Answer& answer);
146 
147 }  // namespace capture_recommendations
148 }  // namespace cast
149 }  // namespace openscreen
150 
151 #endif  // CAST_STREAMING_CAPTURE_RECOMMENDATIONS_H_
152