Updating XTBs based on .GRDs from branch master
[chromium-blink-merge.git] / remoting / protocol / session_config.cc
blob6fef6045eb1c2ae3ec21a6c562dd6ec1cdfd5963
1 // Copyright (c) 2012 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.
5 #include "remoting/protocol/session_config.h"
7 #include <algorithm>
9 #include "base/logging.h"
11 namespace remoting {
12 namespace protocol {
14 namespace {
16 bool IsChannelConfigSupported(const std::list<ChannelConfig>& list,
17 const ChannelConfig& value) {
18 return std::find(list.begin(), list.end(), value) != list.end();
21 bool SelectCommonChannelConfig(const std::list<ChannelConfig>& host_configs,
22 const std::list<ChannelConfig>& client_configs,
23 ChannelConfig* config) {
24 // Usually each of these lists will contain just a few elements, so iterating
25 // over all of them is not a problem.
26 std::list<ChannelConfig>::const_iterator it;
27 for (it = client_configs.begin(); it != client_configs.end(); ++it) {
28 if (IsChannelConfigSupported(host_configs, *it)) {
29 *config = *it;
30 return true;
33 return false;
36 } // namespace
38 const int kDefaultStreamVersion = 2;
39 const int kControlStreamVersion = 3;
41 ChannelConfig ChannelConfig::None() {
42 return ChannelConfig();
45 ChannelConfig::ChannelConfig(TransportType transport, int version, Codec codec)
46 : transport(transport),
47 version(version),
48 codec(codec) {
51 bool ChannelConfig::operator==(const ChannelConfig& b) const {
52 // If the transport field is set to NONE then all other fields are irrelevant.
53 if (transport == ChannelConfig::TRANSPORT_NONE)
54 return transport == b.transport;
55 return transport == b.transport && version == b.version && codec == b.codec;
58 // static
59 scoped_ptr<SessionConfig> SessionConfig::SelectCommon(
60 const CandidateSessionConfig* client_config,
61 const CandidateSessionConfig* host_config) {
62 scoped_ptr<SessionConfig> result(new SessionConfig());
63 ChannelConfig control_config;
64 ChannelConfig event_config;
65 ChannelConfig video_config;
66 ChannelConfig audio_config;
68 DCHECK(host_config->standard_ice());
70 // Reject connection if the peer doesn't support ICE.
71 if (!client_config->standard_ice())
72 return nullptr;
74 // If neither host nor the client have VP9 experiment enabled then remove it
75 // from the list of host video configs.
76 std::list<ChannelConfig> host_video_configs = host_config->video_configs();
77 if (!client_config->vp9_experiment_enabled() &&
78 !host_config->vp9_experiment_enabled()) {
79 host_video_configs.remove_if([](const ChannelConfig& config) {
80 return config.codec == ChannelConfig::CODEC_VP9;
81 });
84 if (!SelectCommonChannelConfig(host_config->control_configs(),
85 client_config->control_configs(),
86 &result->control_config_) ||
87 !SelectCommonChannelConfig(host_config->event_configs(),
88 client_config->event_configs(),
89 &result->event_config_) ||
90 !SelectCommonChannelConfig(host_video_configs,
91 client_config->video_configs(),
92 &result->video_config_) ||
93 !SelectCommonChannelConfig(host_config->audio_configs(),
94 client_config->audio_configs(),
95 &result->audio_config_)) {
96 return nullptr;
99 return result;
102 // static
103 scoped_ptr<SessionConfig> SessionConfig::GetFinalConfig(
104 const CandidateSessionConfig* candidate_config) {
105 if (candidate_config->control_configs().size() != 1 ||
106 candidate_config->event_configs().size() != 1 ||
107 candidate_config->video_configs().size() != 1 ||
108 candidate_config->audio_configs().size() != 1) {
109 return nullptr;
112 scoped_ptr<SessionConfig> result(new SessionConfig());
113 result->standard_ice_ = candidate_config->standard_ice();
114 result->control_config_ = candidate_config->control_configs().front();
115 result->event_config_ = candidate_config->event_configs().front();
116 result->video_config_ = candidate_config->video_configs().front();
117 result->audio_config_ = candidate_config->audio_configs().front();
119 return result.Pass();
122 // static
123 scoped_ptr<SessionConfig> SessionConfig::ForTest() {
124 scoped_ptr<SessionConfig> result(new SessionConfig());
125 result->control_config_ = ChannelConfig(ChannelConfig::TRANSPORT_MUX_STREAM,
126 kControlStreamVersion,
127 ChannelConfig::CODEC_UNDEFINED);
128 result->event_config_ = ChannelConfig(ChannelConfig::TRANSPORT_MUX_STREAM,
129 kDefaultStreamVersion,
130 ChannelConfig::CODEC_UNDEFINED);
131 result->video_config_ = ChannelConfig(ChannelConfig::TRANSPORT_STREAM,
132 kDefaultStreamVersion,
133 ChannelConfig::CODEC_VP8);
134 result->audio_config_ = ChannelConfig(ChannelConfig::TRANSPORT_NONE,
135 kDefaultStreamVersion,
136 ChannelConfig::CODEC_UNDEFINED);
137 return result.Pass();
140 SessionConfig::SessionConfig() {}
142 CandidateSessionConfig::CandidateSessionConfig() {}
143 CandidateSessionConfig::CandidateSessionConfig(
144 const CandidateSessionConfig& config) = default;
145 CandidateSessionConfig::~CandidateSessionConfig() {}
147 bool CandidateSessionConfig::IsSupported(const SessionConfig& config) const {
148 return config.standard_ice() &&
149 IsChannelConfigSupported(control_configs_, config.control_config()) &&
150 IsChannelConfigSupported(event_configs_, config.event_config()) &&
151 IsChannelConfigSupported(video_configs_, config.video_config()) &&
152 IsChannelConfigSupported(audio_configs_, config.audio_config());
155 scoped_ptr<CandidateSessionConfig> CandidateSessionConfig::Clone() const {
156 return make_scoped_ptr(new CandidateSessionConfig(*this));
159 // static
160 scoped_ptr<CandidateSessionConfig> CandidateSessionConfig::CreateEmpty() {
161 return make_scoped_ptr(new CandidateSessionConfig());
164 // static
165 scoped_ptr<CandidateSessionConfig> CandidateSessionConfig::CreateFrom(
166 const SessionConfig& config) {
167 scoped_ptr<CandidateSessionConfig> result = CreateEmpty();
168 result->set_standard_ice(config.standard_ice());
169 result->mutable_control_configs()->push_back(config.control_config());
170 result->mutable_event_configs()->push_back(config.event_config());
171 result->mutable_video_configs()->push_back(config.video_config());
172 result->mutable_audio_configs()->push_back(config.audio_config());
173 return result.Pass();
176 // static
177 scoped_ptr<CandidateSessionConfig> CandidateSessionConfig::CreateDefault() {
178 scoped_ptr<CandidateSessionConfig> result = CreateEmpty();
180 // Control channel.
181 result->mutable_control_configs()->push_back(
182 ChannelConfig(ChannelConfig::TRANSPORT_MUX_STREAM,
183 kControlStreamVersion,
184 ChannelConfig::CODEC_UNDEFINED));
186 // Event channel.
187 result->mutable_event_configs()->push_back(
188 ChannelConfig(ChannelConfig::TRANSPORT_MUX_STREAM,
189 kDefaultStreamVersion,
190 ChannelConfig::CODEC_UNDEFINED));
192 // Video channel.
193 result->mutable_video_configs()->push_back(
194 ChannelConfig(ChannelConfig::TRANSPORT_STREAM,
195 kDefaultStreamVersion,
196 ChannelConfig::CODEC_VP9));
197 result->mutable_video_configs()->push_back(
198 ChannelConfig(ChannelConfig::TRANSPORT_STREAM,
199 kDefaultStreamVersion,
200 ChannelConfig::CODEC_VP8));
202 // Audio channel.
203 result->mutable_audio_configs()->push_back(
204 ChannelConfig(ChannelConfig::TRANSPORT_MUX_STREAM,
205 kDefaultStreamVersion,
206 ChannelConfig::CODEC_OPUS));
207 result->mutable_audio_configs()->push_back(ChannelConfig::None());
209 return result.Pass();
212 void CandidateSessionConfig::DisableAudioChannel() {
213 mutable_audio_configs()->clear();
214 mutable_audio_configs()->push_back(ChannelConfig());
217 } // namespace protocol
218 } // namespace remoting