13842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz// Copyright (c) 2012 The Chromium Authors. All rights reserved. 23842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz// Use of this source code is governed by a BSD-style license that can be 30613d4c6800dbd47c26c90eb49883f45bd1fd77cArun Sharma// found in the LICENSE file. 43842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz 53842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz#include "remoting/protocol/session_config.h" 63842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz 73842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz#include <algorithm> 83842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz 93842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitznamespace remoting { 103842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitznamespace protocol { 113842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz 123842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitzconst int kDefaultStreamVersion = 2; 133842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitzconst int kControlStreamVersion = 3; 143842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz 153842dac7333e42aa44531eda34ba55200b99ccf8Daniel JacobowitzChannelConfig ChannelConfig::None() { 163842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz return ChannelConfig(); 173842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz} 183842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz 193842dac7333e42aa44531eda34ba55200b99ccf8Daniel JacobowitzChannelConfig::ChannelConfig() 203842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz : transport(TRANSPORT_NONE), 213842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz version(0), 223842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz codec(CODEC_UNDEFINED) { 233842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz} 243842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz 253842dac7333e42aa44531eda34ba55200b99ccf8Daniel JacobowitzChannelConfig::ChannelConfig(TransportType transport, int version, Codec codec) 263842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz : transport(transport), 273842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz version(version), 283842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz codec(codec) { 29049e2ba1b9734ec027765cd9449cb29a9bc0d974Zachary T Welch} 3025aeae9adf3c55fb38752434d948ebc42f3ea465Ken Werner 3125aeae9adf3c55fb38752434d948ebc42f3ea465Ken Wernerbool ChannelConfig::operator==(const ChannelConfig& b) const { 3225aeae9adf3c55fb38752434d948ebc42f3ea465Ken Werner // If the transport field is set to NONE then all other fields are irrelevant. 33049e2ba1b9734ec027765cd9449cb29a9bc0d974Zachary T Welch if (transport == ChannelConfig::TRANSPORT_NONE) 349533ea1a6adc91276cd779c598f5718c773c44c9Ken Werner return transport == b.transport; 3525aeae9adf3c55fb38752434d948ebc42f3ea465Ken Werner return transport == b.transport && version == b.version && codec == b.codec; 3625aeae9adf3c55fb38752434d948ebc42f3ea465Ken Werner} 379533ea1a6adc91276cd779c598f5718c773c44c9Ken Werner 389533ea1a6adc91276cd779c598f5718c773c44c9Ken WernerSessionConfig::SessionConfig() { 3925aeae9adf3c55fb38752434d948ebc42f3ea465Ken Werner} 4025aeae9adf3c55fb38752434d948ebc42f3ea465Ken Werner 4125aeae9adf3c55fb38752434d948ebc42f3ea465Ken Werner// static 4225aeae9adf3c55fb38752434d948ebc42f3ea465Ken WernerSessionConfig SessionConfig::ForTest() { 439533ea1a6adc91276cd779c598f5718c773c44c9Ken Werner SessionConfig result; 449533ea1a6adc91276cd779c598f5718c773c44c9Ken Werner result.set_control_config(ChannelConfig(ChannelConfig::TRANSPORT_MUX_STREAM, 4525aeae9adf3c55fb38752434d948ebc42f3ea465Ken Werner kControlStreamVersion, 4625aeae9adf3c55fb38752434d948ebc42f3ea465Ken Werner ChannelConfig::CODEC_UNDEFINED)); 4725aeae9adf3c55fb38752434d948ebc42f3ea465Ken Werner result.set_event_config(ChannelConfig(ChannelConfig::TRANSPORT_MUX_STREAM, 483842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz kDefaultStreamVersion, 499533ea1a6adc91276cd779c598f5718c773c44c9Ken Werner ChannelConfig::CODEC_UNDEFINED)); 509533ea1a6adc91276cd779c598f5718c773c44c9Ken Werner result.set_video_config(ChannelConfig(ChannelConfig::TRANSPORT_STREAM, 513842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz kDefaultStreamVersion, 523842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz ChannelConfig::CODEC_VP8)); 533842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz result.set_audio_config(ChannelConfig(ChannelConfig::TRANSPORT_NONE, 54049e2ba1b9734ec027765cd9449cb29a9bc0d974Zachary T Welch kDefaultStreamVersion, 55049e2ba1b9734ec027765cd9449cb29a9bc0d974Zachary T Welch ChannelConfig::CODEC_UNDEFINED)); 56049e2ba1b9734ec027765cd9449cb29a9bc0d974Zachary T Welch return result; 57049e2ba1b9734ec027765cd9449cb29a9bc0d974Zachary T Welch} 58049e2ba1b9734ec027765cd9449cb29a9bc0d974Zachary T Welch 59049e2ba1b9734ec027765cd9449cb29a9bc0d974Zachary T WelchCandidateSessionConfig::CandidateSessionConfig() { } 60049e2ba1b9734ec027765cd9449cb29a9bc0d974Zachary T Welch 61049e2ba1b9734ec027765cd9449cb29a9bc0d974Zachary T WelchCandidateSessionConfig::CandidateSessionConfig( 62049e2ba1b9734ec027765cd9449cb29a9bc0d974Zachary T Welch const CandidateSessionConfig& config) 63049e2ba1b9734ec027765cd9449cb29a9bc0d974Zachary T Welch : control_configs_(config.control_configs_), 64049e2ba1b9734ec027765cd9449cb29a9bc0d974Zachary T Welch event_configs_(config.event_configs_), 65049e2ba1b9734ec027765cd9449cb29a9bc0d974Zachary T Welch video_configs_(config.video_configs_), 66049e2ba1b9734ec027765cd9449cb29a9bc0d974Zachary T Welch audio_configs_(config.audio_configs_) { 679533ea1a6adc91276cd779c598f5718c773c44c9Ken Werner} 68049e2ba1b9734ec027765cd9449cb29a9bc0d974Zachary T Welch 6923c6aa9a54d0a220fb2557197c555b2684c93876Christopher FerrisCandidateSessionConfig::~CandidateSessionConfig() { } 7023c6aa9a54d0a220fb2557197c555b2684c93876Christopher Ferris 7123c6aa9a54d0a220fb2557197c555b2684c93876Christopher Ferrisbool CandidateSessionConfig::Select( 729533ea1a6adc91276cd779c598f5718c773c44c9Ken Werner const CandidateSessionConfig* client_config, 739533ea1a6adc91276cd779c598f5718c773c44c9Ken Werner SessionConfig* result) { 749533ea1a6adc91276cd779c598f5718c773c44c9Ken Werner ChannelConfig control_config; 759533ea1a6adc91276cd779c598f5718c773c44c9Ken Werner ChannelConfig event_config; 769533ea1a6adc91276cd779c598f5718c773c44c9Ken Werner ChannelConfig video_config; 779533ea1a6adc91276cd779c598f5718c773c44c9Ken Werner ChannelConfig audio_config; 789533ea1a6adc91276cd779c598f5718c773c44c9Ken Werner 799533ea1a6adc91276cd779c598f5718c773c44c9Ken Werner if (!SelectCommonChannelConfig( 809533ea1a6adc91276cd779c598f5718c773c44c9Ken Werner control_configs_, client_config->control_configs_, &control_config) || 819533ea1a6adc91276cd779c598f5718c773c44c9Ken Werner !SelectCommonChannelConfig( 82eac65dc9b8cc18fa4c65c0485878a11c470357b6Matt Fischer event_configs_, client_config->event_configs_, &event_config) || 83eac65dc9b8cc18fa4c65c0485878a11c470357b6Matt Fischer !SelectCommonChannelConfig( 84eac65dc9b8cc18fa4c65c0485878a11c470357b6Matt Fischer video_configs_, client_config->video_configs_, &video_config) || 85049e2ba1b9734ec027765cd9449cb29a9bc0d974Zachary T Welch !SelectCommonChannelConfig( 863842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz audio_configs_, client_config->audio_configs_, &audio_config)) { 873842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz return false; 88049e2ba1b9734ec027765cd9449cb29a9bc0d974Zachary T Welch } 893842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz 90 result->set_control_config(control_config); 91 result->set_event_config(event_config); 92 result->set_video_config(video_config); 93 result->set_audio_config(audio_config); 94 95 return true; 96} 97 98bool CandidateSessionConfig::IsSupported( 99 const SessionConfig& config) const { 100 return 101 IsChannelConfigSupported(control_configs_, config.control_config()) && 102 IsChannelConfigSupported(event_configs_, config.event_config()) && 103 IsChannelConfigSupported(video_configs_, config.video_config()) && 104 IsChannelConfigSupported(audio_configs_, config.audio_config()); 105} 106 107bool CandidateSessionConfig::GetFinalConfig(SessionConfig* result) const { 108 if (control_configs_.size() != 1 || 109 event_configs_.size() != 1 || 110 video_configs_.size() != 1 || 111 audio_configs_.size() != 1) { 112 return false; 113 } 114 115 result->set_control_config(control_configs_.front()); 116 result->set_event_config(event_configs_.front()); 117 result->set_video_config(video_configs_.front()); 118 result->set_audio_config(audio_configs_.front()); 119 120 return true; 121} 122 123// static 124bool CandidateSessionConfig::SelectCommonChannelConfig( 125 const std::list<ChannelConfig>& host_configs, 126 const std::list<ChannelConfig>& client_configs, 127 ChannelConfig* config) { 128 // Usually each of these vectors will contain just several elements, 129 // so iterating over all of them is not a problem. 130 std::list<ChannelConfig>::const_iterator it; 131 for (it = client_configs.begin(); it != client_configs.end(); ++it) { 132 if (IsChannelConfigSupported(host_configs, *it)) { 133 *config = *it; 134 return true; 135 } 136 } 137 return false; 138} 139 140// static 141bool CandidateSessionConfig::IsChannelConfigSupported( 142 const std::list<ChannelConfig>& vector, 143 const ChannelConfig& value) { 144 return std::find(vector.begin(), vector.end(), value) != vector.end(); 145} 146 147scoped_ptr<CandidateSessionConfig> CandidateSessionConfig::Clone() const { 148 return scoped_ptr<CandidateSessionConfig>(new CandidateSessionConfig(*this)); 149} 150 151// static 152scoped_ptr<CandidateSessionConfig> CandidateSessionConfig::CreateEmpty() { 153 return scoped_ptr<CandidateSessionConfig>(new CandidateSessionConfig()); 154} 155 156// static 157scoped_ptr<CandidateSessionConfig> CandidateSessionConfig::CreateFrom( 158 const SessionConfig& config) { 159 scoped_ptr<CandidateSessionConfig> result = CreateEmpty(); 160 result->mutable_control_configs()->push_back(config.control_config()); 161 result->mutable_event_configs()->push_back(config.event_config()); 162 result->mutable_video_configs()->push_back(config.video_config()); 163 result->mutable_audio_configs()->push_back(config.audio_config()); 164 return result.Pass(); 165} 166 167// static 168scoped_ptr<CandidateSessionConfig> CandidateSessionConfig::CreateDefault() { 169 scoped_ptr<CandidateSessionConfig> result = CreateEmpty(); 170 171 // Control channel. 172 result->mutable_control_configs()->push_back( 173 ChannelConfig(ChannelConfig::TRANSPORT_MUX_STREAM, 174 kControlStreamVersion, 175 ChannelConfig::CODEC_UNDEFINED)); 176 177 // Event channel. 178 result->mutable_event_configs()->push_back( 179 ChannelConfig(ChannelConfig::TRANSPORT_MUX_STREAM, 180 kDefaultStreamVersion, 181 ChannelConfig::CODEC_UNDEFINED)); 182 183 // Video channel. 184#if !defined(MEDIA_DISABLE_LIBVPX) 185 result->mutable_video_configs()->push_back( 186 ChannelConfig(ChannelConfig::TRANSPORT_STREAM, 187 kDefaultStreamVersion, 188 ChannelConfig::CODEC_VP8)); 189#endif // !defined(MEDIA_DISABLE_LIBVPX) 190 191 // Audio channel. 192 result->mutable_audio_configs()->push_back( 193 ChannelConfig(ChannelConfig::TRANSPORT_MUX_STREAM, 194 kDefaultStreamVersion, 195 ChannelConfig::CODEC_OPUS)); 196 result->mutable_audio_configs()->push_back(ChannelConfig::None()); 197 198 return result.Pass(); 199} 200 201void CandidateSessionConfig::DisableAudioChannel() { 202 mutable_audio_configs()->clear(); 203 mutable_audio_configs()->push_back(ChannelConfig()); 204} 205 206void CandidateSessionConfig::EnableVideoCodec(ChannelConfig::Codec codec) { 207 mutable_video_configs()->push_front( 208 ChannelConfig(ChannelConfig::TRANSPORT_STREAM, 209 kDefaultStreamVersion, 210 codec)); 211} 212 213} // namespace protocol 214} // namespace remoting 215