xref: /aosp_15_r20/external/webrtc/sdk/media_constraints.cc (revision d9f758449e529ab9291ac668be2861e7a55c2422)
1*d9f75844SAndroid Build Coastguard Worker /*
2*d9f75844SAndroid Build Coastguard Worker  *  Copyright 2013 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 "sdk/media_constraints.h"
12*d9f75844SAndroid Build Coastguard Worker 
13*d9f75844SAndroid Build Coastguard Worker #include "absl/types/optional.h"
14*d9f75844SAndroid Build Coastguard Worker #include "api/peer_connection_interface.h"
15*d9f75844SAndroid Build Coastguard Worker 
16*d9f75844SAndroid Build Coastguard Worker namespace webrtc {
17*d9f75844SAndroid Build Coastguard Worker namespace {
18*d9f75844SAndroid Build Coastguard Worker 
19*d9f75844SAndroid Build Coastguard Worker // Find the highest-priority instance of the T-valued constraint named by
20*d9f75844SAndroid Build Coastguard Worker // `key` and return its value as `value`. `constraints` can be null.
21*d9f75844SAndroid Build Coastguard Worker // If `mandatory_constraints` is non-null, it is incremented if the key appears
22*d9f75844SAndroid Build Coastguard Worker // among the mandatory constraints.
23*d9f75844SAndroid Build Coastguard Worker // Returns true if the key was found and has a valid value for type T.
24*d9f75844SAndroid Build Coastguard Worker // If the key appears multiple times as an optional constraint, appearances
25*d9f75844SAndroid Build Coastguard Worker // after the first are ignored.
26*d9f75844SAndroid Build Coastguard Worker // Note: Because this uses FindFirst, repeated optional constraints whose
27*d9f75844SAndroid Build Coastguard Worker // first instance has an unrecognized value are not handled precisely in
28*d9f75844SAndroid Build Coastguard Worker // accordance with the specification.
29*d9f75844SAndroid Build Coastguard Worker template <typename T>
FindConstraint(const MediaConstraints * constraints,const std::string & key,T * value,size_t * mandatory_constraints)30*d9f75844SAndroid Build Coastguard Worker bool FindConstraint(const MediaConstraints* constraints,
31*d9f75844SAndroid Build Coastguard Worker                     const std::string& key,
32*d9f75844SAndroid Build Coastguard Worker                     T* value,
33*d9f75844SAndroid Build Coastguard Worker                     size_t* mandatory_constraints) {
34*d9f75844SAndroid Build Coastguard Worker   std::string string_value;
35*d9f75844SAndroid Build Coastguard Worker   if (!FindConstraint(constraints, key, &string_value, mandatory_constraints)) {
36*d9f75844SAndroid Build Coastguard Worker     return false;
37*d9f75844SAndroid Build Coastguard Worker   }
38*d9f75844SAndroid Build Coastguard Worker   return rtc::FromString(string_value, value);
39*d9f75844SAndroid Build Coastguard Worker }
40*d9f75844SAndroid Build Coastguard Worker 
41*d9f75844SAndroid Build Coastguard Worker // Specialization for std::string, since a string doesn't need conversion.
42*d9f75844SAndroid Build Coastguard Worker template <>
FindConstraint(const MediaConstraints * constraints,const std::string & key,std::string * value,size_t * mandatory_constraints)43*d9f75844SAndroid Build Coastguard Worker bool FindConstraint(const MediaConstraints* constraints,
44*d9f75844SAndroid Build Coastguard Worker                     const std::string& key,
45*d9f75844SAndroid Build Coastguard Worker                     std::string* value,
46*d9f75844SAndroid Build Coastguard Worker                     size_t* mandatory_constraints) {
47*d9f75844SAndroid Build Coastguard Worker   if (!constraints) {
48*d9f75844SAndroid Build Coastguard Worker     return false;
49*d9f75844SAndroid Build Coastguard Worker   }
50*d9f75844SAndroid Build Coastguard Worker   if (constraints->GetMandatory().FindFirst(key, value)) {
51*d9f75844SAndroid Build Coastguard Worker     if (mandatory_constraints) {
52*d9f75844SAndroid Build Coastguard Worker       ++*mandatory_constraints;
53*d9f75844SAndroid Build Coastguard Worker     }
54*d9f75844SAndroid Build Coastguard Worker     return true;
55*d9f75844SAndroid Build Coastguard Worker   }
56*d9f75844SAndroid Build Coastguard Worker   if (constraints->GetOptional().FindFirst(key, value)) {
57*d9f75844SAndroid Build Coastguard Worker     return true;
58*d9f75844SAndroid Build Coastguard Worker   }
59*d9f75844SAndroid Build Coastguard Worker   return false;
60*d9f75844SAndroid Build Coastguard Worker }
61*d9f75844SAndroid Build Coastguard Worker 
FindConstraint(const MediaConstraints * constraints,const std::string & key,bool * value,size_t * mandatory_constraints)62*d9f75844SAndroid Build Coastguard Worker bool FindConstraint(const MediaConstraints* constraints,
63*d9f75844SAndroid Build Coastguard Worker                     const std::string& key,
64*d9f75844SAndroid Build Coastguard Worker                     bool* value,
65*d9f75844SAndroid Build Coastguard Worker                     size_t* mandatory_constraints) {
66*d9f75844SAndroid Build Coastguard Worker   return FindConstraint<bool>(constraints, key, value, mandatory_constraints);
67*d9f75844SAndroid Build Coastguard Worker }
68*d9f75844SAndroid Build Coastguard Worker 
FindConstraint(const MediaConstraints * constraints,const std::string & key,int * value,size_t * mandatory_constraints)69*d9f75844SAndroid Build Coastguard Worker bool FindConstraint(const MediaConstraints* constraints,
70*d9f75844SAndroid Build Coastguard Worker                     const std::string& key,
71*d9f75844SAndroid Build Coastguard Worker                     int* value,
72*d9f75844SAndroid Build Coastguard Worker                     size_t* mandatory_constraints) {
73*d9f75844SAndroid Build Coastguard Worker   return FindConstraint<int>(constraints, key, value, mandatory_constraints);
74*d9f75844SAndroid Build Coastguard Worker }
75*d9f75844SAndroid Build Coastguard Worker 
76*d9f75844SAndroid Build Coastguard Worker // Converts a constraint (mandatory takes precedence over optional) to an
77*d9f75844SAndroid Build Coastguard Worker // absl::optional.
78*d9f75844SAndroid Build Coastguard Worker template <typename T>
ConstraintToOptional(const MediaConstraints * constraints,const std::string & key,absl::optional<T> * value_out)79*d9f75844SAndroid Build Coastguard Worker void ConstraintToOptional(const MediaConstraints* constraints,
80*d9f75844SAndroid Build Coastguard Worker                           const std::string& key,
81*d9f75844SAndroid Build Coastguard Worker                           absl::optional<T>* value_out) {
82*d9f75844SAndroid Build Coastguard Worker   T value;
83*d9f75844SAndroid Build Coastguard Worker   bool present = FindConstraint<T>(constraints, key, &value, nullptr);
84*d9f75844SAndroid Build Coastguard Worker   if (present) {
85*d9f75844SAndroid Build Coastguard Worker     *value_out = value;
86*d9f75844SAndroid Build Coastguard Worker   }
87*d9f75844SAndroid Build Coastguard Worker }
88*d9f75844SAndroid Build Coastguard Worker }  // namespace
89*d9f75844SAndroid Build Coastguard Worker 
90*d9f75844SAndroid Build Coastguard Worker const char MediaConstraints::kValueTrue[] = "true";
91*d9f75844SAndroid Build Coastguard Worker const char MediaConstraints::kValueFalse[] = "false";
92*d9f75844SAndroid Build Coastguard Worker 
93*d9f75844SAndroid Build Coastguard Worker // Constraints declared as static members in mediastreaminterface.h
94*d9f75844SAndroid Build Coastguard Worker 
95*d9f75844SAndroid Build Coastguard Worker // Audio constraints.
96*d9f75844SAndroid Build Coastguard Worker const char MediaConstraints::kGoogEchoCancellation[] = "googEchoCancellation";
97*d9f75844SAndroid Build Coastguard Worker const char MediaConstraints::kAutoGainControl[] = "googAutoGainControl";
98*d9f75844SAndroid Build Coastguard Worker const char MediaConstraints::kNoiseSuppression[] = "googNoiseSuppression";
99*d9f75844SAndroid Build Coastguard Worker const char MediaConstraints::kHighpassFilter[] = "googHighpassFilter";
100*d9f75844SAndroid Build Coastguard Worker const char MediaConstraints::kAudioMirroring[] = "googAudioMirroring";
101*d9f75844SAndroid Build Coastguard Worker const char MediaConstraints::kAudioNetworkAdaptorConfig[] =
102*d9f75844SAndroid Build Coastguard Worker     "googAudioNetworkAdaptorConfig";
103*d9f75844SAndroid Build Coastguard Worker const char MediaConstraints::kInitAudioRecordingOnSend[] =
104*d9f75844SAndroid Build Coastguard Worker     "InitAudioRecordingOnSend";
105*d9f75844SAndroid Build Coastguard Worker 
106*d9f75844SAndroid Build Coastguard Worker // Constraint keys for CreateOffer / CreateAnswer defined in W3C specification.
107*d9f75844SAndroid Build Coastguard Worker const char MediaConstraints::kOfferToReceiveAudio[] = "OfferToReceiveAudio";
108*d9f75844SAndroid Build Coastguard Worker const char MediaConstraints::kOfferToReceiveVideo[] = "OfferToReceiveVideo";
109*d9f75844SAndroid Build Coastguard Worker const char MediaConstraints::kVoiceActivityDetection[] =
110*d9f75844SAndroid Build Coastguard Worker     "VoiceActivityDetection";
111*d9f75844SAndroid Build Coastguard Worker const char MediaConstraints::kIceRestart[] = "IceRestart";
112*d9f75844SAndroid Build Coastguard Worker // Google specific constraint for BUNDLE enable/disable.
113*d9f75844SAndroid Build Coastguard Worker const char MediaConstraints::kUseRtpMux[] = "googUseRtpMUX";
114*d9f75844SAndroid Build Coastguard Worker 
115*d9f75844SAndroid Build Coastguard Worker // Below constraints should be used during PeerConnection construction.
116*d9f75844SAndroid Build Coastguard Worker // Google-specific constraint keys.
117*d9f75844SAndroid Build Coastguard Worker const char MediaConstraints::kEnableDscp[] = "googDscp";
118*d9f75844SAndroid Build Coastguard Worker const char MediaConstraints::kEnableVideoSuspendBelowMinBitrate[] =
119*d9f75844SAndroid Build Coastguard Worker     "googSuspendBelowMinBitrate";
120*d9f75844SAndroid Build Coastguard Worker const char MediaConstraints::kCombinedAudioVideoBwe[] =
121*d9f75844SAndroid Build Coastguard Worker     "googCombinedAudioVideoBwe";
122*d9f75844SAndroid Build Coastguard Worker const char MediaConstraints::kScreencastMinBitrate[] =
123*d9f75844SAndroid Build Coastguard Worker     "googScreencastMinBitrate";
124*d9f75844SAndroid Build Coastguard Worker // TODO(ronghuawu): Remove once cpu overuse detection is stable.
125*d9f75844SAndroid Build Coastguard Worker const char MediaConstraints::kCpuOveruseDetection[] = "googCpuOveruseDetection";
126*d9f75844SAndroid Build Coastguard Worker 
127*d9f75844SAndroid Build Coastguard Worker const char MediaConstraints::kRawPacketizationForVideoEnabled[] =
128*d9f75844SAndroid Build Coastguard Worker     "googRawPacketizationForVideoEnabled";
129*d9f75844SAndroid Build Coastguard Worker 
130*d9f75844SAndroid Build Coastguard Worker const char MediaConstraints::kNumSimulcastLayers[] = "googNumSimulcastLayers";
131*d9f75844SAndroid Build Coastguard Worker 
132*d9f75844SAndroid Build Coastguard Worker // Set `value` to the value associated with the first appearance of `key`, or
133*d9f75844SAndroid Build Coastguard Worker // return false if `key` is not found.
FindFirst(const std::string & key,std::string * value) const134*d9f75844SAndroid Build Coastguard Worker bool MediaConstraints::Constraints::FindFirst(const std::string& key,
135*d9f75844SAndroid Build Coastguard Worker                                               std::string* value) const {
136*d9f75844SAndroid Build Coastguard Worker   for (Constraints::const_iterator iter = begin(); iter != end(); ++iter) {
137*d9f75844SAndroid Build Coastguard Worker     if (iter->key == key) {
138*d9f75844SAndroid Build Coastguard Worker       *value = iter->value;
139*d9f75844SAndroid Build Coastguard Worker       return true;
140*d9f75844SAndroid Build Coastguard Worker     }
141*d9f75844SAndroid Build Coastguard Worker   }
142*d9f75844SAndroid Build Coastguard Worker   return false;
143*d9f75844SAndroid Build Coastguard Worker }
144*d9f75844SAndroid Build Coastguard Worker 
CopyConstraintsIntoRtcConfiguration(const MediaConstraints * constraints,PeerConnectionInterface::RTCConfiguration * configuration)145*d9f75844SAndroid Build Coastguard Worker void CopyConstraintsIntoRtcConfiguration(
146*d9f75844SAndroid Build Coastguard Worker     const MediaConstraints* constraints,
147*d9f75844SAndroid Build Coastguard Worker     PeerConnectionInterface::RTCConfiguration* configuration) {
148*d9f75844SAndroid Build Coastguard Worker   // Copy info from constraints into configuration, if present.
149*d9f75844SAndroid Build Coastguard Worker   if (!constraints) {
150*d9f75844SAndroid Build Coastguard Worker     return;
151*d9f75844SAndroid Build Coastguard Worker   }
152*d9f75844SAndroid Build Coastguard Worker 
153*d9f75844SAndroid Build Coastguard Worker   FindConstraint(constraints, MediaConstraints::kEnableDscp,
154*d9f75844SAndroid Build Coastguard Worker                  &configuration->media_config.enable_dscp, nullptr);
155*d9f75844SAndroid Build Coastguard Worker   FindConstraint(constraints, MediaConstraints::kCpuOveruseDetection,
156*d9f75844SAndroid Build Coastguard Worker                  &configuration->media_config.video.enable_cpu_adaptation,
157*d9f75844SAndroid Build Coastguard Worker                  nullptr);
158*d9f75844SAndroid Build Coastguard Worker   // Find Suspend Below Min Bitrate constraint.
159*d9f75844SAndroid Build Coastguard Worker   FindConstraint(
160*d9f75844SAndroid Build Coastguard Worker       constraints, MediaConstraints::kEnableVideoSuspendBelowMinBitrate,
161*d9f75844SAndroid Build Coastguard Worker       &configuration->media_config.video.suspend_below_min_bitrate, nullptr);
162*d9f75844SAndroid Build Coastguard Worker   ConstraintToOptional<int>(constraints,
163*d9f75844SAndroid Build Coastguard Worker                             MediaConstraints::kScreencastMinBitrate,
164*d9f75844SAndroid Build Coastguard Worker                             &configuration->screencast_min_bitrate);
165*d9f75844SAndroid Build Coastguard Worker   ConstraintToOptional<bool>(constraints,
166*d9f75844SAndroid Build Coastguard Worker                              MediaConstraints::kCombinedAudioVideoBwe,
167*d9f75844SAndroid Build Coastguard Worker                              &configuration->combined_audio_video_bwe);
168*d9f75844SAndroid Build Coastguard Worker }
169*d9f75844SAndroid Build Coastguard Worker 
CopyConstraintsIntoAudioOptions(const MediaConstraints * constraints,cricket::AudioOptions * options)170*d9f75844SAndroid Build Coastguard Worker void CopyConstraintsIntoAudioOptions(const MediaConstraints* constraints,
171*d9f75844SAndroid Build Coastguard Worker                                      cricket::AudioOptions* options) {
172*d9f75844SAndroid Build Coastguard Worker   if (!constraints) {
173*d9f75844SAndroid Build Coastguard Worker     return;
174*d9f75844SAndroid Build Coastguard Worker   }
175*d9f75844SAndroid Build Coastguard Worker 
176*d9f75844SAndroid Build Coastguard Worker   ConstraintToOptional<bool>(constraints,
177*d9f75844SAndroid Build Coastguard Worker                              MediaConstraints::kGoogEchoCancellation,
178*d9f75844SAndroid Build Coastguard Worker                              &options->echo_cancellation);
179*d9f75844SAndroid Build Coastguard Worker   ConstraintToOptional<bool>(constraints, MediaConstraints::kAutoGainControl,
180*d9f75844SAndroid Build Coastguard Worker                              &options->auto_gain_control);
181*d9f75844SAndroid Build Coastguard Worker   ConstraintToOptional<bool>(constraints, MediaConstraints::kNoiseSuppression,
182*d9f75844SAndroid Build Coastguard Worker                              &options->noise_suppression);
183*d9f75844SAndroid Build Coastguard Worker   ConstraintToOptional<bool>(constraints, MediaConstraints::kHighpassFilter,
184*d9f75844SAndroid Build Coastguard Worker                              &options->highpass_filter);
185*d9f75844SAndroid Build Coastguard Worker   ConstraintToOptional<bool>(constraints, MediaConstraints::kAudioMirroring,
186*d9f75844SAndroid Build Coastguard Worker                              &options->stereo_swapping);
187*d9f75844SAndroid Build Coastguard Worker   ConstraintToOptional<std::string>(
188*d9f75844SAndroid Build Coastguard Worker       constraints, MediaConstraints::kAudioNetworkAdaptorConfig,
189*d9f75844SAndroid Build Coastguard Worker       &options->audio_network_adaptor_config);
190*d9f75844SAndroid Build Coastguard Worker   // When `kAudioNetworkAdaptorConfig` is defined, it both means that audio
191*d9f75844SAndroid Build Coastguard Worker   // network adaptor is desired, and provides the config string.
192*d9f75844SAndroid Build Coastguard Worker   if (options->audio_network_adaptor_config) {
193*d9f75844SAndroid Build Coastguard Worker     options->audio_network_adaptor = true;
194*d9f75844SAndroid Build Coastguard Worker   }
195*d9f75844SAndroid Build Coastguard Worker   ConstraintToOptional<bool>(constraints,
196*d9f75844SAndroid Build Coastguard Worker                              MediaConstraints::kInitAudioRecordingOnSend,
197*d9f75844SAndroid Build Coastguard Worker                              &options->init_recording_on_send);
198*d9f75844SAndroid Build Coastguard Worker }
199*d9f75844SAndroid Build Coastguard Worker 
CopyConstraintsIntoOfferAnswerOptions(const MediaConstraints * constraints,PeerConnectionInterface::RTCOfferAnswerOptions * offer_answer_options)200*d9f75844SAndroid Build Coastguard Worker bool CopyConstraintsIntoOfferAnswerOptions(
201*d9f75844SAndroid Build Coastguard Worker     const MediaConstraints* constraints,
202*d9f75844SAndroid Build Coastguard Worker     PeerConnectionInterface::RTCOfferAnswerOptions* offer_answer_options) {
203*d9f75844SAndroid Build Coastguard Worker   if (!constraints) {
204*d9f75844SAndroid Build Coastguard Worker     return true;
205*d9f75844SAndroid Build Coastguard Worker   }
206*d9f75844SAndroid Build Coastguard Worker 
207*d9f75844SAndroid Build Coastguard Worker   bool value = false;
208*d9f75844SAndroid Build Coastguard Worker   size_t mandatory_constraints_satisfied = 0;
209*d9f75844SAndroid Build Coastguard Worker 
210*d9f75844SAndroid Build Coastguard Worker   if (FindConstraint(constraints, MediaConstraints::kOfferToReceiveAudio,
211*d9f75844SAndroid Build Coastguard Worker                      &value, &mandatory_constraints_satisfied)) {
212*d9f75844SAndroid Build Coastguard Worker     offer_answer_options->offer_to_receive_audio =
213*d9f75844SAndroid Build Coastguard Worker         value ? PeerConnectionInterface::RTCOfferAnswerOptions::
214*d9f75844SAndroid Build Coastguard Worker                     kOfferToReceiveMediaTrue
215*d9f75844SAndroid Build Coastguard Worker               : 0;
216*d9f75844SAndroid Build Coastguard Worker   }
217*d9f75844SAndroid Build Coastguard Worker 
218*d9f75844SAndroid Build Coastguard Worker   if (FindConstraint(constraints, MediaConstraints::kOfferToReceiveVideo,
219*d9f75844SAndroid Build Coastguard Worker                      &value, &mandatory_constraints_satisfied)) {
220*d9f75844SAndroid Build Coastguard Worker     offer_answer_options->offer_to_receive_video =
221*d9f75844SAndroid Build Coastguard Worker         value ? PeerConnectionInterface::RTCOfferAnswerOptions::
222*d9f75844SAndroid Build Coastguard Worker                     kOfferToReceiveMediaTrue
223*d9f75844SAndroid Build Coastguard Worker               : 0;
224*d9f75844SAndroid Build Coastguard Worker   }
225*d9f75844SAndroid Build Coastguard Worker   if (FindConstraint(constraints, MediaConstraints::kVoiceActivityDetection,
226*d9f75844SAndroid Build Coastguard Worker                      &value, &mandatory_constraints_satisfied)) {
227*d9f75844SAndroid Build Coastguard Worker     offer_answer_options->voice_activity_detection = value;
228*d9f75844SAndroid Build Coastguard Worker   }
229*d9f75844SAndroid Build Coastguard Worker   if (FindConstraint(constraints, MediaConstraints::kUseRtpMux, &value,
230*d9f75844SAndroid Build Coastguard Worker                      &mandatory_constraints_satisfied)) {
231*d9f75844SAndroid Build Coastguard Worker     offer_answer_options->use_rtp_mux = value;
232*d9f75844SAndroid Build Coastguard Worker   }
233*d9f75844SAndroid Build Coastguard Worker   if (FindConstraint(constraints, MediaConstraints::kIceRestart, &value,
234*d9f75844SAndroid Build Coastguard Worker                      &mandatory_constraints_satisfied)) {
235*d9f75844SAndroid Build Coastguard Worker     offer_answer_options->ice_restart = value;
236*d9f75844SAndroid Build Coastguard Worker   }
237*d9f75844SAndroid Build Coastguard Worker 
238*d9f75844SAndroid Build Coastguard Worker   if (FindConstraint(constraints,
239*d9f75844SAndroid Build Coastguard Worker                      MediaConstraints::kRawPacketizationForVideoEnabled, &value,
240*d9f75844SAndroid Build Coastguard Worker                      &mandatory_constraints_satisfied)) {
241*d9f75844SAndroid Build Coastguard Worker     offer_answer_options->raw_packetization_for_video = value;
242*d9f75844SAndroid Build Coastguard Worker   }
243*d9f75844SAndroid Build Coastguard Worker 
244*d9f75844SAndroid Build Coastguard Worker   int layers;
245*d9f75844SAndroid Build Coastguard Worker   if (FindConstraint(constraints, MediaConstraints::kNumSimulcastLayers,
246*d9f75844SAndroid Build Coastguard Worker                      &layers, &mandatory_constraints_satisfied)) {
247*d9f75844SAndroid Build Coastguard Worker     offer_answer_options->num_simulcast_layers = layers;
248*d9f75844SAndroid Build Coastguard Worker   }
249*d9f75844SAndroid Build Coastguard Worker 
250*d9f75844SAndroid Build Coastguard Worker   return mandatory_constraints_satisfied == constraints->GetMandatory().size();
251*d9f75844SAndroid Build Coastguard Worker }
252*d9f75844SAndroid Build Coastguard Worker 
253*d9f75844SAndroid Build Coastguard Worker }  // namespace webrtc
254