diff options
author | sergeyu@chromium.org <sergeyu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-11-03 04:17:09 +0000 |
---|---|---|
committer | sergeyu@chromium.org <sergeyu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-11-03 04:17:09 +0000 |
commit | 14fd1a60acdd439f80bdfc0aeb86761ba649db79 (patch) | |
tree | 5bfbcefbd8776ca6a4d810a75601d8bf62d91a7c /remoting/client | |
parent | 07f1ceeabc0cf63ed8d7ae7aa8d1ff04dda02584 (diff) | |
download | chromium_src-14fd1a60acdd439f80bdfc0aeb86761ba649db79.zip chromium_src-14fd1a60acdd439f80bdfc0aeb86761ba649db79.tar.gz chromium_src-14fd1a60acdd439f80bdfc0aeb86761ba649db79.tar.bz2 |
Add VideoReader and VideoWriter interfaces.
Implemented VideoReader and VideoWriter for RTP and Protobuf.
BUG=53986
TEST=None
Review URL: http://codereview.chromium.org/4229003
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@64878 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'remoting/client')
-rw-r--r-- | remoting/client/chromoting_client.cc | 90 | ||||
-rw-r--r-- | remoting/client/chromoting_client.h | 32 | ||||
-rw-r--r-- | remoting/client/host_connection.h | 5 | ||||
-rw-r--r-- | remoting/client/jingle_host_connection.cc | 19 | ||||
-rw-r--r-- | remoting/client/jingle_host_connection.h | 15 |
5 files changed, 93 insertions, 68 deletions
diff --git a/remoting/client/chromoting_client.cc b/remoting/client/chromoting_client.cc index 8b46a9d..c47ecd8 100644 --- a/remoting/client/chromoting_client.cc +++ b/remoting/client/chromoting_client.cc @@ -30,7 +30,7 @@ ChromotingClient::ChromotingClient(const ClientConfig& config, input_handler_(input_handler), client_done_(client_done), state_(CREATED), - message_being_processed_(false) { + packet_being_processed_(false) { } ChromotingClient::~ChromotingClient() { @@ -44,7 +44,7 @@ void ChromotingClient::Start() { return; } - connection_->Connect(config_, this); + connection_->Connect(config_, this, this); if (!view_->Initialize()) { ClientDone(); @@ -103,51 +103,47 @@ void ChromotingClient::HandleMessage(HostConnection* conn, return; } - // Put all messages in the queue. - received_messages_.push_back(msg); - - if (!message_being_processed_) { - DispatchMessage(); - } -} - -void ChromotingClient::DispatchMessage() { - DCHECK_EQ(message_loop(), MessageLoop::current()); - CHECK(!message_being_processed_); - - if (received_messages_.empty()) { - // Nothing to do! - return; - } - - ChromotingHostMessage* msg = received_messages_.front(); - received_messages_.pop_front(); - message_being_processed_ = true; - // TODO(ajwong): Consider creating a macro similar to the IPC message // mappings. Also reconsider the lifetime of the message object. if (msg->has_init_client()) { ScopedTracer tracer("Handle Init Client"); - // TODO(ajwong): Change this to use a done callback. - InitClient(msg->init_client(), - NewTracedMethod(this, &ChromotingClient::OnMessageDone, msg)); - } else if (msg->has_video_packet()) { - ScopedTracer tracer("Handle Rectangle Update"); - rectangle_decoder_->DecodePacket( - msg->video_packet(), - NewTracedMethod(this, &ChromotingClient::OnMessageDone, msg)); + InitClient(msg->init_client()); + delete msg; } else { NOTREACHED() << "Unknown message received"; + } +} - // We have an unknown message. Drop it, and schedule another dispatch. - // Call DispatchMessage as a continuation to avoid growing the stack. - delete msg; - message_being_processed_ = false; +void ChromotingClient::ProcessVideoPacket(const VideoPacket* packet, + Task* done) { + if (message_loop() != MessageLoop::current()) { message_loop()->PostTask( FROM_HERE, - NewTracedMethod(this, &ChromotingClient::DispatchMessage)); + NewRunnableMethod(this, &ChromotingClient::ProcessVideoPacket, + packet, done)); + return; + } + + received_packets_.push_back(QueuedVideoPacket(packet, done)); + if (!packet_being_processed_) + DispatchPacket(); +} + +void ChromotingClient::DispatchPacket() { + DCHECK_EQ(message_loop(), MessageLoop::current()); + CHECK(!packet_being_processed_); + + if (received_packets_.empty()) { + // Nothing to do! return; } + + const VideoPacket* packet = received_packets_.front().packet; + packet_being_processed_ = true; + + ScopedTracer tracer("Handle video packet"); + rectangle_decoder_->DecodePacket( + *packet, NewTracedMethod(this, &ChromotingClient::OnPacketDone)); } void ChromotingClient::OnConnectionOpened(HostConnection* conn) { @@ -185,23 +181,26 @@ void ChromotingClient::SetConnectionState(ConnectionState s) { Repaint(); } -void ChromotingClient::OnMessageDone(ChromotingHostMessage* message) { +void ChromotingClient::OnPacketDone() { if (message_loop() != MessageLoop::current()) { message_loop()->PostTask( FROM_HERE, - NewTracedMethod(this, &ChromotingClient::OnMessageDone, message)); + NewTracedMethod(this, &ChromotingClient::OnPacketDone)); return; } - TraceContext::tracer()->PrintString("Message done"); + TraceContext::tracer()->PrintString("Packet done"); - message_being_processed_ = false; - delete message; - DispatchMessage(); + received_packets_.front().done->Run(); + delete received_packets_.front().done; + received_packets_.pop_front(); + + packet_being_processed_ = false; + + DispatchPacket(); } -void ChromotingClient::InitClient(const InitClientMessage& init_client, - Task* done) { +void ChromotingClient::InitClient(const InitClientMessage& init_client) { DCHECK_EQ(message_loop(), MessageLoop::current()); TraceContext::tracer()->PrintString("Init received"); @@ -217,9 +216,6 @@ void ChromotingClient::InitClient(const InitClientMessage& init_client, // Schedule the input handler to process the event queue. input_handler_->Initialize(); - - done->Run(); - delete done; } } // namespace remoting diff --git a/remoting/client/chromoting_client.h b/remoting/client/chromoting_client.h index e476f31..57e799c 100644 --- a/remoting/client/chromoting_client.h +++ b/remoting/client/chromoting_client.h @@ -13,6 +13,7 @@ #include "remoting/client/host_connection.h" #include "remoting/client/client_config.h" #include "remoting/client/chromoting_view.h" +#include "remoting/protocol/video_stub.h" class MessageLoop; @@ -24,7 +25,9 @@ class InitClientMessage; class InputHandler; class RectangleUpdateDecoder; -class ChromotingClient : public HostConnection::HostEventCallback { +// TODO(sergeyu): Move VideoStub implementation to RectangleUpdateDecoder. +class ChromotingClient : public HostConnection::HostEventCallback, + public VideoStub { public: // Objects passed in are not owned by this class. ChromotingClient(const ClientConfig& config, @@ -58,20 +61,31 @@ class ChromotingClient : public HostConnection::HostEventCallback { virtual void OnConnectionClosed(HostConnection* conn); virtual void OnConnectionFailed(HostConnection* conn); + // VideoStub implementation. + virtual void ProcessVideoPacket(const VideoPacket* packet, Task* done); + private: + struct QueuedVideoPacket { + QueuedVideoPacket(const VideoPacket* packet, Task* done) + : packet(packet), done(done) { + } + const VideoPacket* packet; + Task* done; + }; + MessageLoop* message_loop(); // Convenience method for modifying the state on this object's message loop. void SetConnectionState(ConnectionState s); - // If a message is not being processed, dispatches a single message from the - // |received_messages_| queue. - void DispatchMessage(); + // If a packet is not being processed, dispatches a single message from the + // |received_packets_| queue. + void DispatchPacket(); - void OnMessageDone(ChromotingHostMessage* msg); + void OnPacketDone(); // Handles for chromotocol messages. - void InitClient(const InitClientMessage& msg, Task* done); + void InitClient(const InitClientMessage& msg); // The following are not owned by this class. ClientConfig config_; @@ -86,15 +100,15 @@ class ChromotingClient : public HostConnection::HostEventCallback { ConnectionState state_; - // Contains all messages that have been received, but have not yet been + // Contains all video packets that have been received, but have not yet been // processed. // // Used to serialize sending of messages to the client. - std::list<ChromotingHostMessage*> received_messages_; + std::list<QueuedVideoPacket> received_packets_; // True if a message is being processed. Can be used to determine if it is // safe to dispatch another message. - bool message_being_processed_; + bool packet_being_processed_; DISALLOW_COPY_AND_ASSIGN(ChromotingClient); }; diff --git a/remoting/client/host_connection.h b/remoting/client/host_connection.h index 7121025..3d27ceb 100644 --- a/remoting/client/host_connection.h +++ b/remoting/client/host_connection.h @@ -12,6 +12,8 @@ namespace remoting { +class VideoStub; + struct ClientConfig; class HostConnection { @@ -39,7 +41,8 @@ class HostConnection { // TODO(ajwong): We need to generalize this API. virtual void Connect(const ClientConfig& config, - HostEventCallback* event_callback) = 0; + HostEventCallback* event_callback, + VideoStub* video_stub) = 0; virtual void Disconnect() = 0; // Send an input event to the host. diff --git a/remoting/client/jingle_host_connection.cc b/remoting/client/jingle_host_connection.cc index 9a5fe65..c48ea61 100644 --- a/remoting/client/jingle_host_connection.cc +++ b/remoting/client/jingle_host_connection.cc @@ -11,6 +11,7 @@ #include "remoting/client/jingle_host_connection.h" #include "remoting/jingle_glue/jingle_thread.h" #include "remoting/protocol/jingle_chromotocol_server.h" +#include "remoting/protocol/video_stub.h" #include "remoting/protocol/util.h" namespace remoting { @@ -24,8 +25,10 @@ JingleHostConnection::~JingleHostConnection() { } void JingleHostConnection::Connect(const ClientConfig& config, - HostEventCallback* event_callback) { + HostEventCallback* event_callback, + VideoStub* video_stub) { event_callback_ = event_callback; + video_stub_ = video_stub; // Initialize |jingle_client_|. jingle_client_ = new JingleClient(context_->jingle_thread()); @@ -45,8 +48,9 @@ void JingleHostConnection::Disconnect() { return; } + control_reader_.Close(); event_writer_.Close(); - video_reader_.Close(); + video_reader_->Close(); if (connection_) { connection_->Close( @@ -56,8 +60,7 @@ void JingleHostConnection::Disconnect() { } } -void JingleHostConnection::OnVideoMessage( - ChromotingHostMessage* msg) { +void JingleHostConnection::OnControlMessage(ChromotingHostMessage* msg) { event_callback_->HandleMessage(this, msg); } @@ -150,10 +153,12 @@ void JingleHostConnection::OnConnectionStateChange( case ChromotocolConnection::CONNECTED: // Initialize reader and writer. + control_reader_.Init<ChromotingHostMessage>( + connection_->control_channel(), + NewCallback(this, &JingleHostConnection::OnControlMessage)); event_writer_.Init(connection_->event_channel()); - video_reader_.Init<ChromotingHostMessage>( - connection_->video_channel(), - NewCallback(this, &JingleHostConnection::OnVideoMessage)); + video_reader_.reset(VideoReader::Create(connection_->config())); + video_reader_->Init(connection_, video_stub_); event_callback_->OnConnectionOpened(this); break; diff --git a/remoting/client/jingle_host_connection.h b/remoting/client/jingle_host_connection.h index df37702..f45c27a 100644 --- a/remoting/client/jingle_host_connection.h +++ b/remoting/client/jingle_host_connection.h @@ -29,12 +29,14 @@ #include "remoting/protocol/chromotocol_connection.h" #include "remoting/protocol/chromotocol_server.h" #include "remoting/protocol/stream_writer.h" +#include "remoting/protocol/video_reader.h" class MessageLoop; namespace remoting { class JingleThread; +class VideoStub; struct ClientConfig; @@ -45,7 +47,8 @@ class JingleHostConnection : public HostConnection, virtual ~JingleHostConnection(); virtual void Connect(const ClientConfig& config, - HostEventCallback* event_callback); + HostEventCallback* event_callback, + VideoStub* video_stub); virtual void Disconnect(); virtual void SendEvent(const ChromotingClientMessage& msg); @@ -69,9 +72,11 @@ class JingleHostConnection : public HostConnection, // P2P connection to the host. void InitConnection(); + // Callback for |control_reader_|. + void OnControlMessage(ChromotingHostMessage* msg); + // Callback for |video_reader_|. - // TODO(sergeyu): This should be replaced with RTP/RTCP handler. - void OnVideoMessage(ChromotingHostMessage* msg); + void OnVideoPacket(VideoPacket* packet); // Used by Disconnect() to disconnect chromoting connection, stop chromoting // server, and then disconnect XMPP connection. @@ -84,10 +89,12 @@ class JingleHostConnection : public HostConnection, scoped_refptr<ChromotocolServer> chromotocol_server_; scoped_refptr<ChromotocolConnection> connection_; + MessageReader control_reader_; EventStreamWriter event_writer_; - MessageReader video_reader_; + scoped_ptr<VideoReader> video_reader_; HostEventCallback* event_callback_; + VideoStub* video_stub_; std::string host_jid_; |