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"
12 const int kDefaultStreamVersion
= 2;
14 // The control channel version that supports the "capabilities" message.
15 const int kControlStreamVersion
= 3;
16 const int kControlStreamVersionNoCapabilities
= kDefaultStreamVersion
;
18 ChannelConfig
ChannelConfig::None() {
19 return ChannelConfig();
22 ChannelConfig::ChannelConfig()
23 : transport(TRANSPORT_NONE
),
25 codec(CODEC_UNDEFINED
) {
28 ChannelConfig::ChannelConfig(TransportType transport
, int version
, Codec codec
)
29 : transport(transport
),
34 bool ChannelConfig::operator==(const ChannelConfig
& b
) const {
35 // If the transport field is set to NONE then all other fields are irrelevant.
36 if (transport
== ChannelConfig::TRANSPORT_NONE
)
37 return transport
== b
.transport
;
38 return transport
== b
.transport
&& version
== b
.version
&& codec
== b
.codec
;
41 SessionConfig::SessionConfig() {
44 bool SessionConfig::SupportsCapabilities() const {
45 return control_config_
.version
>= kControlStreamVersion
;
49 SessionConfig
SessionConfig::ForTest() {
51 result
.set_control_config(ChannelConfig(ChannelConfig::TRANSPORT_MUX_STREAM
,
52 kControlStreamVersionNoCapabilities
,
53 ChannelConfig::CODEC_UNDEFINED
));
54 result
.set_event_config(ChannelConfig(ChannelConfig::TRANSPORT_MUX_STREAM
,
55 kDefaultStreamVersion
,
56 ChannelConfig::CODEC_UNDEFINED
));
57 result
.set_video_config(ChannelConfig(ChannelConfig::TRANSPORT_STREAM
,
58 kDefaultStreamVersion
,
59 ChannelConfig::CODEC_VP8
));
60 result
.set_audio_config(ChannelConfig(ChannelConfig::TRANSPORT_NONE
,
61 kDefaultStreamVersion
,
62 ChannelConfig::CODEC_UNDEFINED
));
66 CandidateSessionConfig::CandidateSessionConfig() { }
68 CandidateSessionConfig::CandidateSessionConfig(
69 const CandidateSessionConfig
& config
)
70 : control_configs_(config
.control_configs_
),
71 event_configs_(config
.event_configs_
),
72 video_configs_(config
.video_configs_
),
73 audio_configs_(config
.audio_configs_
) {
76 CandidateSessionConfig::~CandidateSessionConfig() { }
78 bool CandidateSessionConfig::Select(
79 const CandidateSessionConfig
* client_config
,
80 SessionConfig
* result
) {
81 ChannelConfig control_config
;
82 ChannelConfig event_config
;
83 ChannelConfig video_config
;
84 ChannelConfig audio_config
;
86 if (!SelectCommonChannelConfig(
87 control_configs_
, client_config
->control_configs_
, &control_config
) ||
88 !SelectCommonChannelConfig(
89 event_configs_
, client_config
->event_configs_
, &event_config
) ||
90 !SelectCommonChannelConfig(
91 video_configs_
, client_config
->video_configs_
, &video_config
) ||
92 !SelectCommonChannelConfig(
93 audio_configs_
, client_config
->audio_configs_
, &audio_config
)) {
97 result
->set_control_config(control_config
);
98 result
->set_event_config(event_config
);
99 result
->set_video_config(video_config
);
100 result
->set_audio_config(audio_config
);
105 bool CandidateSessionConfig::IsSupported(
106 const SessionConfig
& config
) const {
108 IsChannelConfigSupported(control_configs_
, config
.control_config()) &&
109 IsChannelConfigSupported(event_configs_
, config
.event_config()) &&
110 IsChannelConfigSupported(video_configs_
, config
.video_config()) &&
111 IsChannelConfigSupported(audio_configs_
, config
.audio_config());
114 bool CandidateSessionConfig::GetFinalConfig(SessionConfig
* result
) const {
115 if (control_configs_
.size() != 1 ||
116 event_configs_
.size() != 1 ||
117 video_configs_
.size() != 1 ||
118 audio_configs_
.size() != 1) {
122 result
->set_control_config(control_configs_
.front());
123 result
->set_event_config(event_configs_
.front());
124 result
->set_video_config(video_configs_
.front());
125 result
->set_audio_config(audio_configs_
.front());
131 bool CandidateSessionConfig::SelectCommonChannelConfig(
132 const std::vector
<ChannelConfig
>& host_configs
,
133 const std::vector
<ChannelConfig
>& client_configs
,
134 ChannelConfig
* config
) {
135 // Usually each of these vectors will contain just several elements,
136 // so iterating over all of them is not a problem.
137 std::vector
<ChannelConfig
>::const_iterator it
;
138 for (it
= client_configs
.begin(); it
!= client_configs
.end(); ++it
) {
139 if (IsChannelConfigSupported(host_configs
, *it
)) {
148 bool CandidateSessionConfig::IsChannelConfigSupported(
149 const std::vector
<ChannelConfig
>& vector
,
150 const ChannelConfig
& value
) {
151 return std::find(vector
.begin(), vector
.end(), value
) != vector
.end();
154 scoped_ptr
<CandidateSessionConfig
> CandidateSessionConfig::Clone() const {
155 return scoped_ptr
<CandidateSessionConfig
>(new CandidateSessionConfig(*this));
159 scoped_ptr
<CandidateSessionConfig
> CandidateSessionConfig::CreateEmpty() {
160 return scoped_ptr
<CandidateSessionConfig
>(new CandidateSessionConfig());
164 scoped_ptr
<CandidateSessionConfig
> CandidateSessionConfig::CreateFrom(
165 const SessionConfig
& config
) {
166 scoped_ptr
<CandidateSessionConfig
> result
= CreateEmpty();
167 result
->mutable_control_configs()->push_back(config
.control_config());
168 result
->mutable_event_configs()->push_back(config
.event_config());
169 result
->mutable_video_configs()->push_back(config
.video_config());
170 result
->mutable_audio_configs()->push_back(config
.audio_config());
171 return result
.Pass();
175 scoped_ptr
<CandidateSessionConfig
> CandidateSessionConfig::CreateDefault() {
176 scoped_ptr
<CandidateSessionConfig
> result
= CreateEmpty();
179 result
->mutable_control_configs()->push_back(
180 ChannelConfig(ChannelConfig::TRANSPORT_MUX_STREAM
,
181 kControlStreamVersion
,
182 ChannelConfig::CODEC_UNDEFINED
));
183 result
->mutable_control_configs()->push_back(
184 ChannelConfig(ChannelConfig::TRANSPORT_MUX_STREAM
,
185 kControlStreamVersionNoCapabilities
,
186 ChannelConfig::CODEC_UNDEFINED
));
189 result
->mutable_event_configs()->push_back(
190 ChannelConfig(ChannelConfig::TRANSPORT_MUX_STREAM
,
191 kDefaultStreamVersion
,
192 ChannelConfig::CODEC_UNDEFINED
));
195 result
->mutable_video_configs()->push_back(
196 ChannelConfig(ChannelConfig::TRANSPORT_STREAM
,
197 kDefaultStreamVersion
,
198 ChannelConfig::CODEC_VP9
));
199 result
->mutable_video_configs()->push_back(
200 ChannelConfig(ChannelConfig::TRANSPORT_STREAM
,
201 kDefaultStreamVersion
,
202 ChannelConfig::CODEC_VP8
));
205 result
->mutable_audio_configs()->push_back(
206 ChannelConfig(ChannelConfig::TRANSPORT_MUX_STREAM
,
207 kDefaultStreamVersion
,
208 ChannelConfig::CODEC_OPUS
));
209 result
->mutable_audio_configs()->push_back(ChannelConfig::None());
211 return result
.Pass();
215 void CandidateSessionConfig::DisableAudioChannel(
216 CandidateSessionConfig
* config
) {
217 config
->mutable_audio_configs()->clear();
218 config
->mutable_audio_configs()->push_back(ChannelConfig());
222 void CandidateSessionConfig::DisableVideoCodec(
223 CandidateSessionConfig
* config
,
224 ChannelConfig::Codec codec
) {
225 std ::vector
<ChannelConfig
>::iterator i
;
226 for (i
= config
->mutable_video_configs()->begin();
227 i
!= config
->mutable_video_configs()->end();) {
228 if (i
->codec
== codec
) {
229 i
= config
->mutable_video_configs()->erase(i
);
236 } // namespace protocol
237 } // namespace remoting