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