diff options
author | kxing@chromium.org <kxing@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-06-25 19:26:33 +0000 |
---|---|---|
committer | kxing@chromium.org <kxing@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-06-25 19:26:33 +0000 |
commit | ebfe432a5339014e8ce9741d997bbbd58655a0e9 (patch) | |
tree | 963e7a78aaf718725fcfa0f375c1c226f0c7821d /remoting | |
parent | 38db35e819136b2c6f5951f7aef072e962935b12 (diff) | |
download | chromium_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.cc | 9 | ||||
-rw-r--r-- | remoting/client/chromoting_client.h | 8 | ||||
-rw-r--r-- | remoting/protocol/audio_reader.cc | 2 | ||||
-rw-r--r-- | remoting/protocol/audio_writer.cc | 2 | ||||
-rw-r--r-- | remoting/protocol/connection_to_client.cc | 26 | ||||
-rw-r--r-- | remoting/protocol/connection_to_client.h | 6 | ||||
-rw-r--r-- | remoting/protocol/connection_to_host.cc | 38 | ||||
-rw-r--r-- | remoting/protocol/connection_to_host.h | 7 | ||||
-rw-r--r-- | remoting/protocol/content_description.cc | 36 | ||||
-rw-r--r-- | remoting/protocol/jingle_messages_unittest.cc | 95 | ||||
-rw-r--r-- | remoting/protocol/session_config.cc | 35 | ||||
-rw-r--r-- | remoting/protocol/session_config.h | 22 |
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 |