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"
9 #include "base/logging.h"
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
)) {
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
),
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
;
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())
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
;
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_
)) {
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) {
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();
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));
160 scoped_ptr
<CandidateSessionConfig
> CandidateSessionConfig::CreateEmpty() {
161 return make_scoped_ptr(new CandidateSessionConfig());
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();
177 scoped_ptr
<CandidateSessionConfig
> CandidateSessionConfig::CreateDefault() {
178 scoped_ptr
<CandidateSessionConfig
> result
= CreateEmpty();
181 result
->mutable_control_configs()->push_back(
182 ChannelConfig(ChannelConfig::TRANSPORT_MUX_STREAM
,
183 kControlStreamVersion
,
184 ChannelConfig::CODEC_UNDEFINED
));
187 result
->mutable_event_configs()->push_back(
188 ChannelConfig(ChannelConfig::TRANSPORT_MUX_STREAM
,
189 kDefaultStreamVersion
,
190 ChannelConfig::CODEC_UNDEFINED
));
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
));
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