summaryrefslogtreecommitdiffstats
path: root/remoting
diff options
context:
space:
mode:
authorkxing@chromium.org <kxing@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-06-25 19:26:33 +0000
committerkxing@chromium.org <kxing@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-06-25 19:26:33 +0000
commitebfe432a5339014e8ce9741d997bbbd58655a0e9 (patch)
tree963e7a78aaf718725fcfa0f375c1c226f0c7821d /remoting
parent38db35e819136b2c6f5951f7aef072e962935b12 (diff)
downloadchromium_src-ebfe432a5339014e8ce9741d997bbbd58655a0e9.zip
chromium_src-ebfe432a5339014e8ce9741d997bbbd58655a0e9.tar.gz
chromium_src-ebfe432a5339014e8ce9741d997bbbd58655a0e9.tar.bz2
Added piping for sending audio packets from host to client.
Review URL: https://chromiumcodereview.appspot.com/10532211 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@143977 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'remoting')
-rw-r--r--remoting/client/chromoting_client.cc9
-rw-r--r--remoting/client/chromoting_client.h8
-rw-r--r--remoting/protocol/audio_reader.cc2
-rw-r--r--remoting/protocol/audio_writer.cc2
-rw-r--r--remoting/protocol/connection_to_client.cc26
-rw-r--r--remoting/protocol/connection_to_client.h6
-rw-r--r--remoting/protocol/connection_to_host.cc38
-rw-r--r--remoting/protocol/connection_to_host.h7
-rw-r--r--remoting/protocol/content_description.cc36
-rw-r--r--remoting/protocol/jingle_messages_unittest.cc95
-rw-r--r--remoting/protocol/session_config.cc35
-rw-r--r--remoting/protocol/session_config.h22
12 files changed, 232 insertions, 54 deletions
diff --git a/remoting/client/chromoting_client.cc b/remoting/client/chromoting_client.cc
index 8b25885..a150b67 100644
--- a/remoting/client/chromoting_client.cc
+++ b/remoting/client/chromoting_client.cc
@@ -8,6 +8,7 @@
#include "remoting/client/chromoting_view.h"
#include "remoting/client/client_context.h"
#include "remoting/client/rectangle_update_decoder.h"
+#include "remoting/proto/audio.pb.h"
#include "remoting/protocol/authentication_method.h"
#include "remoting/protocol/connection_to_host.h"
#include "remoting/protocol/negotiating_authenticator.h"
@@ -60,7 +61,7 @@ void ChromotingClient::Start(
connection_->Connect(xmpp_proxy, config_.local_jid, config_.host_jid,
config_.host_public_key, transport_factory.Pass(),
- authenticator.Pass(), this, this, this, this);
+ authenticator.Pass(), this, this, this, this, this);
view_->Initialize();
}
@@ -140,6 +141,12 @@ int ChromotingClient::GetPendingPackets() {
return received_packets_.size();
}
+void ChromotingClient::ProcessAudioPacket(scoped_ptr<AudioPacket> packet,
+ const base::Closure& done) {
+ // TODO(kxing): Playback audio.
+ done.Run();
+}
+
void ChromotingClient::DispatchPacket() {
DCHECK(task_runner_->BelongsToCurrentThread());
CHECK(!packet_being_processed_);
diff --git a/remoting/client/chromoting_client.h b/remoting/client/chromoting_client.h
index 9bfada3..3199da1 100644
--- a/remoting/client/chromoting_client.h
+++ b/remoting/client/chromoting_client.h
@@ -15,6 +15,7 @@
#include "remoting/client/client_config.h"
#include "remoting/client/chromoting_stats.h"
#include "remoting/client/chromoting_view.h"
+#include "remoting/protocol/audio_stub.h"
#include "remoting/protocol/client_stub.h"
#include "remoting/protocol/clipboard_stub.h"
#include "remoting/protocol/connection_to_host.h"
@@ -37,7 +38,8 @@ class RectangleUpdateDecoder;
// TODO(sergeyu): Move VideoStub implementation to RectangleUpdateDecoder.
class ChromotingClient : public protocol::ConnectionToHost::HostEventCallback,
public protocol::ClientStub,
- public protocol::VideoStub {
+ public protocol::VideoStub,
+ public protocol::AudioStub {
public:
// Objects passed in are not owned by this class.
ChromotingClient(const ClientConfig& config,
@@ -73,6 +75,10 @@ class ChromotingClient : public protocol::ConnectionToHost::HostEventCallback,
const base::Closure& done) OVERRIDE;
virtual int GetPendingPackets() OVERRIDE;
+ // AudioStub implementation.
+ virtual void ProcessAudioPacket(scoped_ptr<AudioPacket> packet,
+ const base::Closure& done) OVERRIDE;
+
private:
struct QueuedVideoPacket {
QueuedVideoPacket(scoped_ptr<VideoPacket> packet,
diff --git a/remoting/protocol/audio_reader.cc b/remoting/protocol/audio_reader.cc
index 6a607bd..4269176 100644
--- a/remoting/protocol/audio_reader.cc
+++ b/remoting/protocol/audio_reader.cc
@@ -26,6 +26,8 @@ AudioReader::~AudioReader() {
// static
scoped_ptr<AudioReader> AudioReader::Create(const SessionConfig& config) {
+ if (!config.is_audio_enabled())
+ return scoped_ptr<AudioReader>(NULL);
// TODO(kxing): Support different session configurations.
return scoped_ptr<AudioReader>(new AudioReader(AudioPacket::ENCODING_RAW));
}
diff --git a/remoting/protocol/audio_writer.cc b/remoting/protocol/audio_writer.cc
index 05ae0c2..4b786a1 100644
--- a/remoting/protocol/audio_writer.cc
+++ b/remoting/protocol/audio_writer.cc
@@ -68,6 +68,8 @@ void AudioWriter::ProcessAudioPacket(scoped_ptr<AudioPacket> packet,
// static
scoped_ptr<AudioWriter> AudioWriter::Create(const SessionConfig& config) {
+ if (!config.is_audio_enabled())
+ return scoped_ptr<AudioWriter>(NULL);
// TODO(kxing): Support different session configurations.
return scoped_ptr<AudioWriter>(new AudioWriter());
}
diff --git a/remoting/protocol/connection_to_client.cc b/remoting/protocol/connection_to_client.cc
index 03ee1fe..3441f49 100644
--- a/remoting/protocol/connection_to_client.cc
+++ b/remoting/protocol/connection_to_client.cc
@@ -68,6 +68,11 @@ VideoStub* ConnectionToClient::video_stub() {
return video_writer_.get();
}
+AudioStub* ConnectionToClient::audio_stub() {
+ DCHECK(CalledOnValidThread());
+ return audio_writer_.get();
+}
+
// Return pointer to ClientStub.
ClientStub* ConnectionToClient::client_stub() {
DCHECK(CalledOnValidThread());
@@ -120,6 +125,12 @@ void ConnectionToClient::OnSessionStateChange(Session::State state) {
video_writer_->Init(session_.get(), base::Bind(
&ConnectionToClient::OnChannelInitialized, base::Unretained(this)));
+ audio_writer_ = AudioWriter::Create(session_->config());
+ if (audio_writer_.get()) {
+ audio_writer_->Init(session_.get(), base::Bind(
+ &ConnectionToClient::OnChannelInitialized, base::Unretained(this)));
+ }
+
// Notify the handler after initializing the channels, so that
// ClientSession can get a client clipboard stub.
handler_->OnConnectionAuthenticated(this);
@@ -156,11 +167,17 @@ void ConnectionToClient::OnChannelInitialized(bool successful) {
void ConnectionToClient::NotifyIfChannelsReady() {
DCHECK(CalledOnValidThread());
- if (control_dispatcher_.get() && control_dispatcher_->is_connected() &&
- event_dispatcher_.get() && event_dispatcher_->is_connected() &&
- video_writer_.get() && video_writer_->is_connected()) {
- handler_->OnConnectionChannelsConnected(this);
+ if (!control_dispatcher_.get() || !control_dispatcher_->is_connected())
+ return;
+ if (!event_dispatcher_.get() || !event_dispatcher_->is_connected())
+ return;
+ if (!video_writer_.get() || !video_writer_->is_connected())
+ return;
+ if ((!audio_writer_.get() || !audio_writer_->is_connected()) &&
+ session_->config().is_audio_enabled()) {
+ return;
}
+ handler_->OnConnectionChannelsConnected(this);
}
void ConnectionToClient::Close(ErrorCode error) {
@@ -172,6 +189,7 @@ void ConnectionToClient::CloseChannels() {
control_dispatcher_.reset();
event_dispatcher_.reset();
video_writer_.reset();
+ audio_writer_.reset();
}
} // namespace protocol
diff --git a/remoting/protocol/connection_to_client.h b/remoting/protocol/connection_to_client.h
index f786e54..715b800 100644
--- a/remoting/protocol/connection_to_client.h
+++ b/remoting/protocol/connection_to_client.h
@@ -12,6 +12,7 @@
#include "base/memory/scoped_ptr.h"
#include "base/synchronization/lock.h"
#include "base/threading/non_thread_safe.h"
+#include "remoting/protocol/audio_writer.h"
#include "remoting/protocol/session.h"
#include "remoting/protocol/video_writer.h"
@@ -83,6 +84,10 @@ class ConnectionToClient : public base::NonThreadSafe {
// Send encoded update stream data to the viewer.
virtual VideoStub* video_stub();
+ // Send audio stream data to the viewer.
+ // Returns NULL if audio is not enabled.
+ virtual AudioStub* audio_stub();
+
// Send control data to the viewer/client.
virtual ClientStub* client_stub();
@@ -123,6 +128,7 @@ class ConnectionToClient : public base::NonThreadSafe {
scoped_ptr<HostControlDispatcher> control_dispatcher_;
scoped_ptr<HostEventDispatcher> event_dispatcher_;
scoped_ptr<VideoWriter> video_writer_;
+ scoped_ptr<AudioWriter> audio_writer_;
DISALLOW_COPY_AND_ASSIGN(ConnectionToClient);
};
diff --git a/remoting/protocol/connection_to_host.cc b/remoting/protocol/connection_to_host.cc
index 296439b..6b785bb 100644
--- a/remoting/protocol/connection_to_host.cc
+++ b/remoting/protocol/connection_to_host.cc
@@ -10,6 +10,8 @@
#include "remoting/base/constants.h"
#include "remoting/jingle_glue/javascript_signal_strategy.h"
#include "remoting/jingle_glue/xmpp_signal_strategy.h"
+#include "remoting/protocol/audio_reader.h"
+#include "remoting/protocol/audio_stub.h"
#include "remoting/protocol/auth_util.h"
#include "remoting/protocol/authenticator.h"
#include "remoting/protocol/client_control_dispatcher.h"
@@ -33,6 +35,7 @@ ConnectionToHost::ConnectionToHost(
client_stub_(NULL),
clipboard_stub_(NULL),
video_stub_(NULL),
+ audio_stub_(NULL),
state_(CONNECTING),
error_(OK) {
}
@@ -62,11 +65,13 @@ void ConnectionToHost::Connect(scoped_refptr<XmppProxy> xmpp_proxy,
HostEventCallback* event_callback,
ClientStub* client_stub,
ClipboardStub* clipboard_stub,
- VideoStub* video_stub) {
+ VideoStub* video_stub,
+ AudioStub* audio_stub) {
event_callback_ = event_callback;
client_stub_ = client_stub;
clipboard_stub_ = clipboard_stub;
video_stub_ = video_stub;
+ audio_stub_ = audio_stub;
authenticator_ = authenticator.Pass();
// Save jid of the host. The actual connection is created later after
@@ -162,6 +167,12 @@ void ConnectionToHost::OnSessionStateChange(
video_reader_->Init(session_.get(), video_stub_, base::Bind(
&ConnectionToHost::OnChannelInitialized, base::Unretained(this)));
+ audio_reader_ = AudioReader::Create(session_->config());
+ if (audio_reader_.get()) {
+ audio_reader_->Init(session_.get(), audio_stub_, base::Bind(
+ &ConnectionToHost::OnChannelInitialized, base::Unretained(this)));
+ }
+
control_dispatcher_.reset(new ClientControlDispatcher());
control_dispatcher_->Init(session_.get(), base::Bind(
&ConnectionToHost::OnChannelInitialized, base::Unretained(this)));
@@ -208,15 +219,23 @@ void ConnectionToHost::OnChannelInitialized(bool successful) {
}
void ConnectionToHost::NotifyIfChannelsReady() {
- if (control_dispatcher_.get() && control_dispatcher_->is_connected() &&
- event_dispatcher_.get() && event_dispatcher_->is_connected() &&
- video_reader_.get() && video_reader_->is_connected() &&
- state_ == CONNECTING) {
- // Start forwarding clipboard and input events.
- clipboard_forwarder_.set_clipboard_stub(control_dispatcher_.get());
- event_forwarder_.set_input_stub(event_dispatcher_.get());
- SetState(CONNECTED, OK);
+ if (!control_dispatcher_.get() || !control_dispatcher_->is_connected())
+ return;
+ if (!event_dispatcher_.get() || !event_dispatcher_->is_connected())
+ return;
+ if (!video_reader_.get() || !video_reader_->is_connected())
+ return;
+ if ((!audio_reader_.get() || !audio_reader_->is_connected()) &&
+ session_->config().is_audio_enabled()) {
+ return;
}
+ if (state_ != CONNECTING)
+ return;
+
+ // Start forwarding clipboard and input events.
+ clipboard_forwarder_.set_clipboard_stub(control_dispatcher_.get());
+ event_forwarder_.set_input_stub(event_dispatcher_.get());
+ SetState(CONNECTED, OK);
}
void ConnectionToHost::CloseOnError(ErrorCode error) {
@@ -230,6 +249,7 @@ void ConnectionToHost::CloseChannels() {
clipboard_forwarder_.set_clipboard_stub(NULL);
event_forwarder_.set_input_stub(NULL);
video_reader_.reset();
+ audio_reader_.reset();
}
void ConnectionToHost::SetState(State state, ErrorCode error) {
diff --git a/remoting/protocol/connection_to_host.h b/remoting/protocol/connection_to_host.h
index 8524c72..45b6a31a 100644
--- a/remoting/protocol/connection_to_host.h
+++ b/remoting/protocol/connection_to_host.h
@@ -31,6 +31,8 @@ class VideoPacket;
namespace protocol {
+class AudioReader;
+class AudioStub;
class Authenticator;
class ClientControlDispatcher;
class ClientEventDispatcher;
@@ -74,7 +76,8 @@ class ConnectionToHost : public SignalStrategy::Listener,
HostEventCallback* event_callback,
ClientStub* client_stub,
ClipboardStub* clipboard_stub,
- VideoStub* video_stub);
+ VideoStub* video_stub,
+ AudioStub* audio_stub);
virtual void Disconnect(const base::Closure& shutdown_task);
@@ -129,12 +132,14 @@ class ConnectionToHost : public SignalStrategy::Listener,
ClientStub* client_stub_;
ClipboardStub* clipboard_stub_;
VideoStub* video_stub_;
+ AudioStub* audio_stub_;
scoped_ptr<SignalStrategy> signal_strategy_;
scoped_ptr<SessionManager> session_manager_;
scoped_ptr<Session> session_;
scoped_ptr<VideoReader> video_reader_;
+ scoped_ptr<AudioReader> audio_reader_;
scoped_ptr<ClientControlDispatcher> control_dispatcher_;
scoped_ptr<ClientEventDispatcher> event_dispatcher_;
ClipboardFilter clipboard_forwarder_;
diff --git a/remoting/protocol/content_description.cc b/remoting/protocol/content_description.cc
index c88a362..d55163f 100644
--- a/remoting/protocol/content_description.cc
+++ b/remoting/protocol/content_description.cc
@@ -27,6 +27,7 @@ const char kDescriptionTag[] = "description";
const char kControlTag[] = "control";
const char kEventTag[] = "event";
const char kVideoTag[] = "video";
+const char kAudioTag[] = "audio";
const char kDeprecatedResolutionTag[] = "initial-resolution";
const char kTransportAttr[] = "transport";
@@ -37,10 +38,12 @@ const char kDeprecatedHeightAttr[] = "height";
const char kStreamTransport[] = "stream";
const char kDatagramTransport[] = "datagram";
+const char kNoneTransport[] = "none";
const char kVerbatimCodec[] = "verbatim";
const char kVp8Codec[] = "vp8";
const char kZipCodec[] = "zip";
+const char kVorbisCodec[] = "vorbis";
const char* GetTransportName(ChannelConfig::TransportType type) {
switch (type) {
@@ -48,6 +51,8 @@ const char* GetTransportName(ChannelConfig::TransportType type) {
return kStreamTransport;
case ChannelConfig::TRANSPORT_DATAGRAM:
return kDatagramTransport;
+ case ChannelConfig::TRANSPORT_NONE:
+ return kNoneTransport;
}
NOTREACHED();
return NULL;
@@ -61,6 +66,8 @@ const char* GetCodecName(ChannelConfig::Codec type) {
return kVp8Codec;
case ChannelConfig::CODEC_ZIP:
return kZipCodec;
+ case ChannelConfig::CODEC_VORBIS:
+ return kVorbisCodec;
default:
break;
}
@@ -97,6 +104,8 @@ bool ParseTransportName(const std::string& value,
*transport = ChannelConfig::TRANSPORT_STREAM;
} else if (value == kDatagramTransport) {
*transport = ChannelConfig::TRANSPORT_DATAGRAM;
+ } else if (value == kNoneTransport) {
+ *transport = ChannelConfig::TRANSPORT_NONE;
} else {
return false;
}
@@ -110,6 +119,8 @@ bool ParseCodecName(const std::string& value, ChannelConfig::Codec* codec) {
*codec = ChannelConfig::CODEC_VP8;
} else if (value == kZipCodec) {
*codec = ChannelConfig::CODEC_ZIP;
+ } else if (value == kVorbisCodec) {
+ *codec = ChannelConfig::CODEC_VORBIS;
} else {
return false;
}
@@ -163,6 +174,7 @@ ContentDescription* ContentDescription::Copy() const {
// <control transport="stream" version="1" />
// <event transport="datagram" version="1" />
// <video transport="stream" codec="vp8" version="1" />
+// <audio transport="stream" codec="vorbis" version="1" />
// <authentication>
// Message created by Authenticator implementation.
// </authentication>
@@ -189,6 +201,11 @@ XmlElement* ContentDescription::ToXml() const {
root->AddElement(FormatChannelConfig(*it, kVideoTag));
}
+ for (it = config()->audio_configs().begin();
+ it != config()->audio_configs().end(); ++it) {
+ root->AddElement(FormatChannelConfig(*it, kAudioTag));
+ }
+
// Older endpoints require an initial-resolution tag, but otherwise ignore it.
XmlElement* resolution_tag = new XmlElement(
QName(kChromotingXmlNamespace, kDeprecatedResolutionTag));
@@ -245,6 +262,25 @@ ContentDescription* ContentDescription::ParseXml(
child = child->NextNamed(video_tag);
}
+ // <audio> tags.
+ QName audio_tag(kChromotingXmlNamespace, kAudioTag);
+ child = element->FirstNamed(audio_tag);
+ if (!child) {
+ // If there's no mention of audio, implicitly assume
+ // TRANSPORT_NONE for the audio_channel.
+ ChannelConfig no_audio(ChannelConfig::TRANSPORT_NONE,
+ kDefaultStreamVersion,
+ ChannelConfig::CODEC_VERBATIM);
+ config->mutable_audio_configs()->push_back(no_audio);
+ }
+ while (child) {
+ ChannelConfig channel_config;
+ if (!ParseChannelConfig(child, true, &channel_config))
+ return NULL;
+ config->mutable_audio_configs()->push_back(channel_config);
+ child = child->NextNamed(audio_tag);
+ }
+
scoped_ptr<XmlElement> authenticator_message;
child = Authenticator::FindAuthenticatorMessage(element);
if (child)
diff --git a/remoting/protocol/jingle_messages_unittest.cc b/remoting/protocol/jingle_messages_unittest.cc
index 228886b..d8ed4dc 100644
--- a/remoting/protocol/jingle_messages_unittest.cc
+++ b/remoting/protocol/jingle_messages_unittest.cc
@@ -98,17 +98,25 @@ bool VerifyXml(const XmlElement* exp,
TEST(JingleMessageTest, SessionInitiate) {
const char* kTestSessionInitiateMessage =
"<iq to='user@gmail.com/chromoting016DBB07' type='set' "
- "from='user@gmail.com/chromiumsy5C6A652D' "
- "xmlns='jabber:client'><jingle xmlns='urn:xmpp:jingle:1' "
- "action='session-initiate' sid='2227053353' "
- "initiator='user@gmail.com/chromiumsy5C6A652D'><content "
- "name='chromoting' creator='initiator'><description "
- "xmlns='google:remoting'><control transport='stream' version='2'/><event "
- "transport='stream' version='2'/><video transport='stream' version='2' "
- "codec='vp8'/><initial-resolution width='640' height='480'/>"
- "<authentication><auth-token>j7whCMii0Z0AAPwj7whCM/j7whCMii0Z0AAPw="
- "</auth-token></authentication></description><transport "
- "xmlns='http://www.google.com/transport/p2p'/></content></jingle>"
+ "from='user@gmail.com/chromiumsy5C6A652D' "
+ "xmlns='jabber:client'>"
+ "<jingle xmlns='urn:xmpp:jingle:1' "
+ "action='session-initiate' sid='2227053353' "
+ "initiator='user@gmail.com/chromiumsy5C6A652D'>"
+ "<content name='chromoting' creator='initiator'>"
+ "<description xmlns='google:remoting'>"
+ "<control transport='stream' version='2'/>"
+ "<event transport='stream' version='2'/>"
+ "<video transport='stream' version='2' codec='vp8'/>"
+ "<audio transport='stream' version='2' codec='verbatim'/>"
+ "<initial-resolution width='640' height='480'/>"
+ "<authentication><auth-token>"
+ "j7whCMii0Z0AAPwj7whCM/j7whCMii0Z0AAPw="
+ "</auth-token></authentication>"
+ "</description>"
+ "<transport xmlns='http://www.google.com/transport/p2p'/>"
+ "</content>"
+ "</jingle>"
"</iq>";
scoped_ptr<XmlElement> source_message(
XmlElement::ForStr(kTestSessionInitiateMessage));
@@ -131,16 +139,25 @@ TEST(JingleMessageTest, SessionInitiate) {
TEST(JingleMessageTest, SessionAccept) {
const char* kTestSessionAcceptMessage =
"<cli:iq from='user@gmail.com/chromoting016DBB07' "
- "to='user@gmail.com/chromiumsy5C6A652D' type='set' "
- "xmlns:cli='jabber:client'><jingle action='session-accept' "
- "sid='2227053353' xmlns='urn:xmpp:jingle:1'><content creator='initiator' "
- "name='chromoting'><description xmlns='google:remoting'><control "
- "transport='stream' version='2'/><event transport='stream' version='2'/>"
- "<video codec='vp8' transport='stream' version='2'/><initial-resolution "
- "height='480' width='640'/><authentication><certificate>"
- "MIICpjCCAY6gW0Cert0TANBgkqhkiG9w0BAQUFA=</certificate>"
- "</authentication></description><transport xmlns="
- "'http://www.google.com/transport/p2p'/></content></jingle></cli:iq>";
+ "to='user@gmail.com/chromiumsy5C6A652D' type='set' "
+ "xmlns:cli='jabber:client'>"
+ "<jingle action='session-accept' sid='2227053353' "
+ "xmlns='urn:xmpp:jingle:1'>i"
+ "<content creator='initiator' name='chromoting'>"
+ "<description xmlns='google:remoting'>"
+ "<control transport='stream' version='2'/>"
+ "<event transport='stream' version='2'/>"
+ "<video codec='vp8' transport='stream' version='2'/>"
+ "<audio transport='stream' version='2' codec='verbatim'/>"
+ "<initial-resolution height='480' width='640'/>"
+ "<authentication><certificate>"
+ "MIICpjCCAY6gW0Cert0TANBgkqhkiG9w0BAQUFA="
+ "</certificate></authentication>"
+ "</description>"
+ "<transport xmlns='http://www.google.com/transport/p2p'/>"
+ "</content>"
+ "</jingle>"
+ "</cli:iq>";
scoped_ptr<XmlElement> source_message(
XmlElement::ForStr(kTestSessionAcceptMessage));
@@ -317,19 +334,29 @@ TEST(JingleMessageReplyTest, ToXml) {
TEST(JingleMessageTest, ErrorMessage) {
const char* kTestSessionInitiateErrorMessage =
"<iq to='user@gmail.com/chromoting016DBB07' type='error' "
- "from='user@gmail.com/chromiumsy5C6A652D' "
- "xmlns='jabber:client'><jingle xmlns='urn:xmpp:jingle:1' "
- "action='session-initiate' sid='2227053353' "
- "initiator='user@gmail.com/chromiumsy5C6A652D'><content "
- "name='chromoting' creator='initiator'><description "
- "xmlns='google:remoting'><control transport='stream' version='2'/><event "
- "transport='stream' version='2'/><video transport='stream' version='2' "
- "codec='vp8'/><initial-resolution width='800' height='600'/>"
- "<authentication><auth-token>j7whCMii0Z0AAPwj7whCM/j7whCMii0Z0AAPw="
- "</auth-token></authentication></description><transport "
- "xmlns='http://www.google.com/transport/p2p'/></content></jingle>"
- "<error code='501' type='cancel'><feature-not-implemented "
- "xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/></error>"
+ "from='user@gmail.com/chromiumsy5C6A652D' "
+ "xmlns='jabber:client'>"
+ "<jingle xmlns='urn:xmpp:jingle:1' "
+ "action='session-initiate' sid='2227053353' "
+ "initiator='user@gmail.com/chromiumsy5C6A652D'>"
+ "<content name='chromoting' creator='initiator'>"
+ "<description xmlns='google:remoting'>"
+ "<control transport='stream' version='2'/>"
+ "<event transport='stream' version='2'/>"
+ "<video transport='stream' version='2' codec='vp8'/>"
+ "<audio transport='stream' version='2' codec='verbatim'/>"
+ "<initial-resolution width='800' height='600'/>"
+ "<authentication><auth-token>"
+ "j7whCMii0Z0AAPwj7whCM/j7whCMii0Z0AAPw="
+ "</auth-token></authentication>"
+ "</description>"
+ "<transport xmlns='http://www.google.com/transport/p2p'/>"
+ "</content>"
+ "</jingle>"
+ "<error code='501' type='cancel'>"
+ "<feature-not-implemented "
+ "xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>"
+ "</error>"
"</iq>";
scoped_ptr<XmlElement> source_message(
XmlElement::ForStr(kTestSessionInitiateErrorMessage));
diff --git a/remoting/protocol/session_config.cc b/remoting/protocol/session_config.cc
index 528d96c..8479a04 100644
--- a/remoting/protocol/session_config.cc
+++ b/remoting/protocol/session_config.cc
@@ -31,6 +31,9 @@ void ChannelConfig::Reset() {
codec = CODEC_UNDEFINED;
}
+SessionConfig::SessionConfig() {
+}
+
// static
SessionConfig SessionConfig::GetDefault() {
SessionConfig result;
@@ -43,6 +46,9 @@ SessionConfig SessionConfig::GetDefault() {
result.set_video_config(ChannelConfig(ChannelConfig::TRANSPORT_STREAM,
kDefaultStreamVersion,
ChannelConfig::CODEC_VP8));
+ result.set_audio_config(ChannelConfig(ChannelConfig::TRANSPORT_STREAM,
+ kDefaultStreamVersion,
+ ChannelConfig::CODEC_VERBATIM));
return result;
}
@@ -52,7 +58,8 @@ CandidateSessionConfig::CandidateSessionConfig(
const CandidateSessionConfig& config)
: control_configs_(config.control_configs_),
event_configs_(config.event_configs_),
- video_configs_(config.video_configs_) {
+ video_configs_(config.video_configs_),
+ audio_configs_(config.audio_configs_) {
}
CandidateSessionConfig::~CandidateSessionConfig() { }
@@ -63,19 +70,23 @@ bool CandidateSessionConfig::Select(
ChannelConfig control_config;
ChannelConfig event_config;
ChannelConfig video_config;
+ ChannelConfig audio_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)) {
+ video_configs_, client_config->video_configs_, &video_config) ||
+ !SelectCommonChannelConfig(
+ audio_configs_, client_config->audio_configs_, &audio_config)) {
return false;
}
result->set_control_config(control_config);
result->set_event_config(event_config);
result->set_video_config(video_config);
+ result->set_audio_config(audio_config);
return true;
}
@@ -85,19 +96,22 @@ bool CandidateSessionConfig::IsSupported(
return
IsChannelConfigSupported(control_configs_, config.control_config()) &&
IsChannelConfigSupported(event_configs_, config.event_config()) &&
- IsChannelConfigSupported(video_configs_, config.video_config());
+ IsChannelConfigSupported(video_configs_, config.video_config()) &&
+ IsChannelConfigSupported(audio_configs_, config.audio_config());
}
bool CandidateSessionConfig::GetFinalConfig(SessionConfig* result) const {
if (control_configs_.size() != 1 ||
event_configs_.size() != 1 ||
- video_configs_.size() != 1) {
+ video_configs_.size() != 1 ||
+ audio_configs_.size() != 1) {
return false;
}
result->set_control_config(control_configs_.front());
result->set_event_config(event_configs_.front());
result->set_video_config(video_configs_.front());
+ result->set_audio_config(audio_configs_.front());
return true;
}
@@ -142,6 +156,7 @@ scoped_ptr<CandidateSessionConfig> CandidateSessionConfig::CreateFrom(
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_audio_configs()->push_back(config.audio_config());
return result.Pass();
}
@@ -160,6 +175,18 @@ scoped_ptr<CandidateSessionConfig> CandidateSessionConfig::CreateDefault() {
ChannelConfig(ChannelConfig::TRANSPORT_STREAM,
kDefaultStreamVersion,
ChannelConfig::CODEC_VP8));
+ result->mutable_audio_configs()->push_back(
+ ChannelConfig(ChannelConfig::TRANSPORT_NONE,
+ kDefaultStreamVersion,
+ ChannelConfig::CODEC_VERBATIM));
+ result->mutable_audio_configs()->push_back(
+ ChannelConfig(ChannelConfig::TRANSPORT_STREAM,
+ kDefaultStreamVersion,
+ ChannelConfig::CODEC_VERBATIM));
+ result->mutable_audio_configs()->push_back(
+ ChannelConfig(ChannelConfig::TRANSPORT_STREAM,
+ kDefaultStreamVersion,
+ ChannelConfig::CODEC_VORBIS));
return result.Pass();
}
diff --git a/remoting/protocol/session_config.h b/remoting/protocol/session_config.h
index e1cd39e..02ee7f1 100644
--- a/remoting/protocol/session_config.h
+++ b/remoting/protocol/session_config.h
@@ -23,6 +23,7 @@ struct ChannelConfig {
enum TransportType {
TRANSPORT_STREAM,
TRANSPORT_DATAGRAM,
+ TRANSPORT_NONE,
};
enum Codec {
@@ -30,6 +31,7 @@ struct ChannelConfig {
CODEC_VERBATIM,
CODEC_ZIP,
CODEC_VP8,
+ CODEC_VORBIS,
};
ChannelConfig();
@@ -50,6 +52,8 @@ struct ChannelConfig {
// chromotocol configuration.
class SessionConfig {
public:
+ SessionConfig();
+
void set_control_config(const ChannelConfig& control_config) {
control_config_ = control_config;
}
@@ -62,6 +66,14 @@ class SessionConfig {
video_config_ = video_config;
}
const ChannelConfig& video_config() const { return video_config_; }
+ void set_audio_config(const ChannelConfig& audio_config) {
+ audio_config_ = audio_config;
+ }
+ const ChannelConfig& audio_config() const { return audio_config_; }
+
+ bool is_audio_enabled() const {
+ return audio_config_.transport != ChannelConfig::TRANSPORT_NONE;
+ }
static SessionConfig GetDefault();
@@ -69,6 +81,7 @@ class SessionConfig {
ChannelConfig control_config_;
ChannelConfig event_config_;
ChannelConfig video_config_;
+ ChannelConfig audio_config_;
};
// Defines session description that is sent from client to the host in the
@@ -102,6 +115,14 @@ class CandidateSessionConfig {
return &video_configs_;
}
+ const std::vector<ChannelConfig>& audio_configs() const {
+ return audio_configs_;
+ }
+
+ std::vector<ChannelConfig>* mutable_audio_configs() {
+ return &audio_configs_;
+ }
+
// Selects session configuration that is supported by both participants.
// NULL is returned if such configuration doesn't exist. When selecting
// channel configuration priority is given to the configs listed first
@@ -140,6 +161,7 @@ class CandidateSessionConfig {
std::vector<ChannelConfig> control_configs_;
std::vector<ChannelConfig> event_configs_;
std::vector<ChannelConfig> video_configs_;
+ std::vector<ChannelConfig> audio_configs_;
};
} // namespace protocol