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