Home | History | Annotate | Download | only in protocol
      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 const int kControlStreamVersion = 3;
     14 
     15 ChannelConfig ChannelConfig::None() {
     16   return ChannelConfig();
     17 }
     18 
     19 ChannelConfig::ChannelConfig()
     20     : transport(TRANSPORT_NONE),
     21       version(0),
     22       codec(CODEC_UNDEFINED) {
     23 }
     24 
     25 ChannelConfig::ChannelConfig(TransportType transport, int version, Codec codec)
     26     : transport(transport),
     27       version(version),
     28       codec(codec) {
     29 }
     30 
     31 bool ChannelConfig::operator==(const ChannelConfig& b) const {
     32   // If the transport field is set to NONE then all other fields are irrelevant.
     33   if (transport == ChannelConfig::TRANSPORT_NONE)
     34     return transport == b.transport;
     35   return transport == b.transport && version == b.version && codec == b.codec;
     36 }
     37 
     38 SessionConfig::SessionConfig() {
     39 }
     40 
     41 // static
     42 SessionConfig SessionConfig::ForTest() {
     43   SessionConfig result;
     44   result.set_control_config(ChannelConfig(ChannelConfig::TRANSPORT_MUX_STREAM,
     45                                           kControlStreamVersion,
     46                                           ChannelConfig::CODEC_UNDEFINED));
     47   result.set_event_config(ChannelConfig(ChannelConfig::TRANSPORT_MUX_STREAM,
     48                                         kDefaultStreamVersion,
     49                                         ChannelConfig::CODEC_UNDEFINED));
     50   result.set_video_config(ChannelConfig(ChannelConfig::TRANSPORT_STREAM,
     51                                         kDefaultStreamVersion,
     52                                         ChannelConfig::CODEC_VP8));
     53   result.set_audio_config(ChannelConfig(ChannelConfig::TRANSPORT_NONE,
     54                                         kDefaultStreamVersion,
     55                                         ChannelConfig::CODEC_UNDEFINED));
     56   return result;
     57 }
     58 
     59 CandidateSessionConfig::CandidateSessionConfig() { }
     60 
     61 CandidateSessionConfig::CandidateSessionConfig(
     62     const CandidateSessionConfig& config)
     63     : control_configs_(config.control_configs_),
     64       event_configs_(config.event_configs_),
     65       video_configs_(config.video_configs_),
     66       audio_configs_(config.audio_configs_) {
     67 }
     68 
     69 CandidateSessionConfig::~CandidateSessionConfig() { }
     70 
     71 bool CandidateSessionConfig::Select(
     72     const CandidateSessionConfig* client_config,
     73     SessionConfig* result) {
     74   ChannelConfig control_config;
     75   ChannelConfig event_config;
     76   ChannelConfig video_config;
     77   ChannelConfig audio_config;
     78 
     79   if (!SelectCommonChannelConfig(
     80           control_configs_, client_config->control_configs_, &control_config) ||
     81       !SelectCommonChannelConfig(
     82           event_configs_, client_config->event_configs_, &event_config) ||
     83       !SelectCommonChannelConfig(
     84           video_configs_, client_config->video_configs_, &video_config) ||
     85       !SelectCommonChannelConfig(
     86           audio_configs_, client_config->audio_configs_, &audio_config)) {
     87     return false;
     88   }
     89 
     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 
     98 bool 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 
    107 bool 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
    124 bool 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
    141 bool 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 
    147 scoped_ptr<CandidateSessionConfig> CandidateSessionConfig::Clone() const {
    148   return scoped_ptr<CandidateSessionConfig>(new CandidateSessionConfig(*this));
    149 }
    150 
    151 // static
    152 scoped_ptr<CandidateSessionConfig> CandidateSessionConfig::CreateEmpty() {
    153   return scoped_ptr<CandidateSessionConfig>(new CandidateSessionConfig());
    154 }
    155 
    156 // static
    157 scoped_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
    168 scoped_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 
    201 void CandidateSessionConfig::DisableAudioChannel() {
    202   mutable_audio_configs()->clear();
    203   mutable_audio_configs()->push_back(ChannelConfig());
    204 }
    205 
    206 void 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