blob: db4f071c43cbdb32fd51c9934695568ddeeb6262 [file] [log] [blame]
// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "remoting/protocol/session_config.h"
#include <algorithm>
namespace remoting {
namespace protocol {
const int kDefaultStreamVersion = 1;
namespace {
const int kDefaultWidth = 800;
const int kDefaultHeight = 600;
} // namespace
ChannelConfig::ChannelConfig() {
Reset();
}
ChannelConfig::ChannelConfig(TransportType transport, int version, Codec codec)
: transport(transport),
version(version),
codec(codec) {
}
bool ChannelConfig::operator==(const ChannelConfig& b) const {
return transport == b.transport && version == b.version && codec == b.codec;
}
void ChannelConfig::Reset() {
transport = TRANSPORT_STREAM;
version = kDefaultStreamVersion;
codec = CODEC_UNDEFINED;
}
ScreenResolution::ScreenResolution()
: width(kDefaultWidth),
height(kDefaultHeight) {
}
ScreenResolution::ScreenResolution(int width, int height)
: width(width),
height(height) {
}
bool ScreenResolution::IsValid() const {
return width > 0 && height > 0;
}
SessionConfig::SessionConfig() { }
SessionConfig::SessionConfig(const SessionConfig& config)
: control_config_(config.control_config_),
event_config_(config.event_config_),
video_config_(config.video_config_),
initial_resolution_(config.initial_resolution_) {
}
SessionConfig::~SessionConfig() { }
void SessionConfig::SetControlConfig(const ChannelConfig& control_config) {
control_config_ = control_config;
}
void SessionConfig::SetEventConfig(const ChannelConfig& event_config) {
event_config_ = event_config;
}
void SessionConfig::SetVideoConfig(const ChannelConfig& video_config) {
video_config_ = video_config;
}
void SessionConfig::SetInitialResolution(const ScreenResolution& resolution) {
initial_resolution_ = resolution;
}
SessionConfig* SessionConfig::Clone() const {
return new SessionConfig(*this);
}
// static
SessionConfig* SessionConfig::CreateDefault() {
SessionConfig* result = new SessionConfig();
result->SetControlConfig(ChannelConfig(ChannelConfig::TRANSPORT_STREAM,
kDefaultStreamVersion,
ChannelConfig::CODEC_UNDEFINED));
result->SetEventConfig(ChannelConfig(ChannelConfig::TRANSPORT_STREAM,
kDefaultStreamVersion,
ChannelConfig::CODEC_UNDEFINED));
result->SetVideoConfig(ChannelConfig(ChannelConfig::TRANSPORT_STREAM,
kDefaultStreamVersion,
ChannelConfig::CODEC_ZIP));
return result;
}
CandidateSessionConfig::CandidateSessionConfig() { }
CandidateSessionConfig::CandidateSessionConfig(
const CandidateSessionConfig& config)
: control_configs_(config.control_configs_),
event_configs_(config.event_configs_),
video_configs_(config.video_configs_),
initial_resolution_(config.initial_resolution_) {
}
CandidateSessionConfig::~CandidateSessionConfig() { }
SessionConfig* CandidateSessionConfig::Select(
const CandidateSessionConfig* client_config,
bool force_host_resolution) {
ChannelConfig control_config;
ChannelConfig event_config;
ChannelConfig video_config;
if (!SelectCommonChannelConfig(
control_configs_, client_config->control_configs_, &control_config) ||
!SelectCommonChannelConfig(
event_configs_, client_config->event_configs_, &event_config) ||
!SelectCommonChannelConfig(
video_configs_, client_config->video_configs_, &video_config)) {
return NULL;
}
SessionConfig* result = SessionConfig::CreateDefault();
result->SetControlConfig(control_config);
result->SetEventConfig(event_config);
result->SetVideoConfig(video_config);
if (force_host_resolution) {
result->SetInitialResolution(initial_resolution());
} else {
result->SetInitialResolution(client_config->initial_resolution());
}
return result;
}
bool CandidateSessionConfig::IsSupported(
const SessionConfig* config) const {
return
IsChannelConfigSupported(control_configs_, config->control_config()) &&
IsChannelConfigSupported(event_configs_, config->event_config()) &&
IsChannelConfigSupported(video_configs_, config->video_config()) &&
config->initial_resolution().IsValid();
}
SessionConfig* CandidateSessionConfig::GetFinalConfig() const {
if (control_configs_.size() != 1 ||
event_configs_.size() != 1 ||
video_configs_.size() != 1) {
return NULL;
}
SessionConfig* result = SessionConfig::CreateDefault();
result->SetControlConfig(control_configs_.front());
result->SetEventConfig(event_configs_.front());
result->SetVideoConfig(video_configs_.front());
result->SetInitialResolution(initial_resolution_);
return result;
}
// static
bool CandidateSessionConfig::SelectCommonChannelConfig(
const std::vector<ChannelConfig>& host_configs,
const std::vector<ChannelConfig>& client_configs,
ChannelConfig* config) {
// Usually each of these vectors will contain just several elements,
// so iterating over all of them is not a problem.
std::vector<ChannelConfig>::const_iterator it;
for (it = client_configs.begin(); it != client_configs.end(); ++it) {
if (IsChannelConfigSupported(host_configs, *it)) {
*config = *it;
return true;
}
}
return false;
}
// static
bool CandidateSessionConfig::IsChannelConfigSupported(
const std::vector<ChannelConfig>& vector,
const ChannelConfig& value) {
return std::find(vector.begin(), vector.end(), value) != vector.end();
}
CandidateSessionConfig* CandidateSessionConfig::Clone() const {
return new CandidateSessionConfig(*this);
}
// static
CandidateSessionConfig* CandidateSessionConfig::CreateEmpty() {
return new CandidateSessionConfig();
}
// static
CandidateSessionConfig* CandidateSessionConfig::CreateFrom(
const SessionConfig* config) {
CandidateSessionConfig* result = CreateEmpty();
result->mutable_control_configs()->push_back(config->control_config());
result->mutable_event_configs()->push_back(config->event_config());
result->mutable_video_configs()->push_back(config->video_config());
*result->mutable_initial_resolution() = (config->initial_resolution());
return result;
}
// static
CandidateSessionConfig* CandidateSessionConfig::CreateDefault() {
CandidateSessionConfig* result = CreateEmpty();
result->mutable_control_configs()->push_back(
ChannelConfig(ChannelConfig::TRANSPORT_STREAM,
kDefaultStreamVersion,
ChannelConfig::CODEC_UNDEFINED));
result->mutable_event_configs()->push_back(
ChannelConfig(ChannelConfig::TRANSPORT_STREAM,
kDefaultStreamVersion,
ChannelConfig::CODEC_UNDEFINED));
result->mutable_video_configs()->push_back(
ChannelConfig(ChannelConfig::TRANSPORT_STREAM,
kDefaultStreamVersion,
ChannelConfig::CODEC_VP8));
result->mutable_video_configs()->push_back(
ChannelConfig(ChannelConfig::TRANSPORT_STREAM,
kDefaultStreamVersion,
ChannelConfig::CODEC_ZIP));
result->mutable_video_configs()->push_back(
ChannelConfig(ChannelConfig::TRANSPORT_SRTP,
kDefaultStreamVersion,
ChannelConfig::CODEC_VP8));
return result;
}
} // namespace protocol
} // namespace remoting