• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
4 
5 #include "remoting/protocol/session_config.h"
6 
7 #include <algorithm>
8 
9 namespace remoting {
10 namespace protocol {
11 
12 const int kDefaultStreamVersion = 2;
13 
14 // The control channel version that supports the "capabilities" message.
15 const int kControlStreamVersion = 3;
16 const int kControlStreamVersionNoCapabilities = kDefaultStreamVersion;
17 
None()18 ChannelConfig ChannelConfig::None() {
19   return ChannelConfig();
20 }
21 
ChannelConfig()22 ChannelConfig::ChannelConfig()
23     : transport(TRANSPORT_NONE),
24       version(0),
25       codec(CODEC_UNDEFINED) {
26 }
27 
ChannelConfig(TransportType transport,int version,Codec codec)28 ChannelConfig::ChannelConfig(TransportType transport, int version, Codec codec)
29     : transport(transport),
30       version(version),
31       codec(codec) {
32 }
33 
operator ==(const ChannelConfig & b) const34 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;
39 }
40 
SessionConfig()41 SessionConfig::SessionConfig() {
42 }
43 
SupportsCapabilities() const44 bool SessionConfig::SupportsCapabilities() const {
45   return control_config_.version >= kControlStreamVersion;
46 }
47 
48 // static
ForTest()49 SessionConfig SessionConfig::ForTest() {
50   SessionConfig result;
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));
63   return result;
64 }
65 
CandidateSessionConfig()66 CandidateSessionConfig::CandidateSessionConfig() { }
67 
CandidateSessionConfig(const CandidateSessionConfig & config)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_) {
74 }
75 
~CandidateSessionConfig()76 CandidateSessionConfig::~CandidateSessionConfig() { }
77 
Select(const CandidateSessionConfig * client_config,SessionConfig * result)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;
85 
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)) {
94     return false;
95   }
96 
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);
101 
102   return true;
103 }
104 
IsSupported(const SessionConfig & config) const105 bool CandidateSessionConfig::IsSupported(
106     const SessionConfig& config) const {
107   return
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());
112 }
113 
GetFinalConfig(SessionConfig * result) const114 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) {
119     return false;
120   }
121 
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());
126 
127   return true;
128 }
129 
130 // static
SelectCommonChannelConfig(const std::vector<ChannelConfig> & host_configs,const std::vector<ChannelConfig> & client_configs,ChannelConfig * config)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)) {
140       *config = *it;
141       return true;
142     }
143   }
144   return false;
145 }
146 
147 // static
IsChannelConfigSupported(const std::vector<ChannelConfig> & vector,const ChannelConfig & value)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();
152 }
153 
Clone() const154 scoped_ptr<CandidateSessionConfig> CandidateSessionConfig::Clone() const {
155   return scoped_ptr<CandidateSessionConfig>(new CandidateSessionConfig(*this));
156 }
157 
158 // static
CreateEmpty()159 scoped_ptr<CandidateSessionConfig> CandidateSessionConfig::CreateEmpty() {
160   return scoped_ptr<CandidateSessionConfig>(new CandidateSessionConfig());
161 }
162 
163 // static
CreateFrom(const SessionConfig & config)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();
172 }
173 
174 // static
CreateDefault()175 scoped_ptr<CandidateSessionConfig> CandidateSessionConfig::CreateDefault() {
176   scoped_ptr<CandidateSessionConfig> result = CreateEmpty();
177 
178   // Control channel.
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));
187 
188   // Event channel.
189   result->mutable_event_configs()->push_back(
190       ChannelConfig(ChannelConfig::TRANSPORT_MUX_STREAM,
191                     kDefaultStreamVersion,
192                     ChannelConfig::CODEC_UNDEFINED));
193 
194   // Video channel.
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));
203 
204   // Audio channel.
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());
210 
211   return result.Pass();
212 }
213 
214 // static
DisableAudioChannel(CandidateSessionConfig * config)215 void CandidateSessionConfig::DisableAudioChannel(
216     CandidateSessionConfig* config) {
217   config->mutable_audio_configs()->clear();
218   config->mutable_audio_configs()->push_back(ChannelConfig());
219 }
220 
221 // static
DisableVideoCodec(CandidateSessionConfig * config,ChannelConfig::Codec codec)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);
230     } else {
231       ++i;
232     }
233   }
234 }
235 
236 }  // namespace protocol
237 }  // namespace remoting
238