summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/service/service_process.cc6
-rw-r--r--remoting/base/decoder_vp8.cc4
-rw-r--r--remoting/base/encoder_vp8.cc3
-rw-r--r--remoting/client/chromoting_client.cc90
-rw-r--r--remoting/client/chromoting_client.h32
-rw-r--r--remoting/client/host_connection.h5
-rw-r--r--remoting/client/jingle_host_connection.cc19
-rw-r--r--remoting/client/jingle_host_connection.h15
-rw-r--r--remoting/host/chromoting_host.cc34
-rw-r--r--remoting/host/chromoting_host.h7
-rw-r--r--remoting/host/client_connection.cc16
-rw-r--r--remoting/host/client_connection.h4
-rw-r--r--remoting/host/mock_objects.h2
-rw-r--r--remoting/host/simple_host_process.cc25
-rw-r--r--remoting/proto/video.proto6
-rw-r--r--remoting/protocol/chromotocol_config.h3
-rw-r--r--remoting/protocol/message_decoder.h2
-rw-r--r--remoting/protocol/message_reader.h1
-rw-r--r--remoting/protocol/protobuf_video_reader.cc30
-rw-r--r--remoting/protocol/protobuf_video_reader.h35
-rw-r--r--remoting/protocol/protobuf_video_writer.cc36
-rw-r--r--remoting/protocol/protobuf_video_writer.h34
-rw-r--r--remoting/protocol/rtp_reader.cc2
-rw-r--r--remoting/protocol/rtp_reader.h2
-rw-r--r--remoting/protocol/rtp_utils.cc9
-rw-r--r--remoting/protocol/rtp_video_reader.cc41
-rw-r--r--remoting/protocol/rtp_video_reader.h35
-rw-r--r--remoting/protocol/rtp_video_writer.cc35
-rw-r--r--remoting/protocol/rtp_video_writer.h32
-rw-r--r--remoting/protocol/rtp_writer.cc18
-rw-r--r--remoting/protocol/rtp_writer.h7
-rw-r--r--remoting/protocol/stream_writer.cc7
-rw-r--r--remoting/protocol/stream_writer.h10
-rw-r--r--remoting/protocol/video_reader.cc26
-rw-r--r--remoting/protocol/video_reader.h43
-rw-r--r--remoting/protocol/video_stub.h33
-rw-r--r--remoting/protocol/video_writer.cc26
-rw-r--r--remoting/protocol/video_writer.h48
-rw-r--r--remoting/remoting.gyp13
39 files changed, 648 insertions, 148 deletions
diff --git a/chrome/service/service_process.cc b/chrome/service/service_process.cc
index 1ec4a83..2a6f069 100644
--- a/chrome/service/service_process.cc
+++ b/chrome/service/service_process.cc
@@ -25,7 +25,6 @@
#if defined(ENABLE_REMOTING)
#include "remoting/base/constants.h"
-#include "remoting/base/encoder_zlib.h"
#include "remoting/host/chromoting_host.h"
#include "remoting/host/chromoting_host_context.h"
#include "remoting/host/json_host_config.h"
@@ -282,10 +281,9 @@ bool ServiceProcess::StartChromotingHost() {
chromoting_context_.reset(new remoting::ChromotingHostContext());
chromoting_context_->Start();
- // Create capturer, encoder and executor. The ownership will be transfered
+ // Create capturer and executor. The ownership will be transfered
// to the chromoting host.
scoped_ptr<remoting::Capturer> capturer;
- scoped_ptr<remoting::Encoder> encoder;
scoped_ptr<remoting::EventExecutor> executor;
#if defined(OS_WIN)
@@ -298,13 +296,11 @@ bool ServiceProcess::StartChromotingHost() {
capturer.reset(new remoting::CapturerMac());
executor.reset(new remoting::EventExecutorMac(capturer.get()));
#endif
- encoder.reset(new remoting::EncoderZlib());
// Create a chromoting host object.
chromoting_host_ = new remoting::ChromotingHost(chromoting_context_.get(),
chromoting_config_,
capturer.release(),
- encoder.release(),
executor.release());
// Then start the chromoting host.
diff --git a/remoting/base/decoder_vp8.cc b/remoting/base/decoder_vp8.cc
index a8d5245..46a6d31 100644
--- a/remoting/base/decoder_vp8.cc
+++ b/remoting/base/decoder_vp8.cc
@@ -63,8 +63,6 @@ void DecoderVp8::DecodeBytes(const std::string& encoded_bytes) {
}
}
- LOG(WARNING) << "Decoding " << encoded_bytes.size();
-
// Do the actual decoding.
vpx_codec_err_t ret = vpx_codec_decode(
codec_, reinterpret_cast<const uint8*>(encoded_bytes.data()),
@@ -73,6 +71,7 @@ void DecoderVp8::DecodeBytes(const std::string& encoded_bytes) {
LOG(INFO) << "Decoding failed:" << vpx_codec_err_to_string(ret) << "\n"
<< "Details: " << vpx_codec_error(codec_) << "\n"
<< vpx_codec_error_detail(codec_);
+ return;
}
// Gets the decoded data.
@@ -80,6 +79,7 @@ void DecoderVp8::DecodeBytes(const std::string& encoded_bytes) {
vpx_image_t* image = vpx_codec_get_frame(codec_, &iter);
if (!image) {
LOG(INFO) << "No video frame decoded";
+ return;
}
// Perform YUV conversion.
diff --git a/remoting/base/encoder_vp8.cc b/remoting/base/encoder_vp8.cc
index 7a58f7b..3a0f75b 100644
--- a/remoting/base/encoder_vp8.cc
+++ b/remoting/base/encoder_vp8.cc
@@ -188,8 +188,7 @@ void EncoderVp8::Encode(scoped_refptr<CaptureData> capture_data,
switch (packet->kind) {
case VPX_CODEC_CX_FRAME_PKT:
got_data = true;
- message->set_data(
- packet->data.frame.buf, packet->data.frame.sz);
+ message->set_data(packet->data.frame.buf, packet->data.frame.sz);
break;
default:
break;
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_;
diff --git a/remoting/host/chromoting_host.cc b/remoting/host/chromoting_host.cc
index 21a95be..d77e23c 100644
--- a/remoting/host/chromoting_host.cc
+++ b/remoting/host/chromoting_host.cc
@@ -9,24 +9,26 @@
#include "build/build_config.h"
#include "remoting/base/constants.h"
#include "remoting/base/encoder.h"
+#include "remoting/base/encoder_verbatim.h"
+#include "remoting/base/encoder_vp8.h"
+#include "remoting/base/encoder_zlib.h"
#include "remoting/host/chromoting_host_context.h"
#include "remoting/host/capturer.h"
#include "remoting/host/event_executor.h"
#include "remoting/host/host_config.h"
#include "remoting/host/session_manager.h"
#include "remoting/protocol/jingle_chromotocol_server.h"
+#include "remoting/protocol/chromotocol_config.h"
namespace remoting {
ChromotingHost::ChromotingHost(ChromotingHostContext* context,
MutableHostConfig* config,
Capturer* capturer,
- Encoder* encoder,
EventExecutor* executor)
: context_(context),
config_(config),
capturer_(capturer),
- encoder_(encoder),
executor_(executor),
state_(kInitial) {
}
@@ -140,12 +142,14 @@ void ChromotingHost::OnClientConnected(ClientConnection* client) {
// Then we create a SessionManager passing the message loops that
// it should run on.
DCHECK(capturer_.get());
- DCHECK(encoder_.get());
+
+ Encoder* encoder = CreateEncoder(client->connection()->config());
+
session_ = new SessionManager(context_->capture_message_loop(),
context_->encode_message_loop(),
context_->main_message_loop(),
- capturer_.get(),
- encoder_.get());
+ capturer_.release(),
+ encoder);
}
// Immediately add the client and start the session.
@@ -285,4 +289,24 @@ void ChromotingHost::OnServerClosed() {
// Don't need to do anything here.
}
+// TODO(sergeyu): Move this to SessionManager?
+Encoder* ChromotingHost::CreateEncoder(const ChromotocolConfig* config) {
+ const ChannelConfig& video_config = config->video_config();
+
+ if (video_config.codec == ChannelConfig::CODEC_VERBATIM) {
+ return new remoting::EncoderVerbatim();
+ } else if (video_config.codec == ChannelConfig::CODEC_ZIP) {
+ return new remoting::EncoderZlib();
+ }
+ // TODO(sergeyu): Enable VP8 on ARM builds.
+#if !defined(ARCH_CPU_ARM_FAMILY)
+ else if (video_config.codec == ChannelConfig::CODEC_VP8) {
+ return new remoting::EncoderVp8();
+ }
+#endif
+
+ return NULL;
+}
+
+
} // namespace remoting
diff --git a/remoting/host/chromoting_host.h b/remoting/host/chromoting_host.h
index 158daa4..911a9d3 100644
--- a/remoting/host/chromoting_host.h
+++ b/remoting/host/chromoting_host.h
@@ -24,6 +24,7 @@ namespace remoting {
class Capturer;
class ChromotingHostContext;
+class ChromotocolConfig;
class Encoder;
class EventExecutor;
class MutableHostConfig;
@@ -59,7 +60,7 @@ class ChromotingHost : public base::RefCountedThreadSafe<ChromotingHost>,
public JingleClient::Callback {
public:
ChromotingHost(ChromotingHostContext* context, MutableHostConfig* config,
- Capturer* capturer, Encoder* encoder, EventExecutor* executor);
+ Capturer* capturer, EventExecutor* executor);
virtual ~ChromotingHost();
// Asynchronously start the host process.
@@ -113,6 +114,9 @@ class ChromotingHost : public base::RefCountedThreadSafe<ChromotingHost>,
// Callback for ChromotocolServer::Close().
void OnServerClosed();
+ // Creates encoder for the specified configuration.
+ Encoder* CreateEncoder(const ChromotocolConfig* config);
+
// The context that the chromoting host runs on.
ChromotingHostContext* context_;
@@ -122,7 +126,6 @@ class ChromotingHost : public base::RefCountedThreadSafe<ChromotingHost>,
// constructed this is set to NULL.
scoped_ptr<Capturer> capturer_;
- // Encoder to be used by the SessionManager. Once the SessionManager is
// constructed this is set to NULL.
scoped_ptr<Encoder> encoder_;
diff --git a/remoting/host/client_connection.cc b/remoting/host/client_connection.cc
index e325bf7..8d68d6d 100644
--- a/remoting/host/client_connection.cc
+++ b/remoting/host/client_connection.cc
@@ -52,7 +52,7 @@ void ClientConnection::SendInitClientMessage(int width, int height) {
msg.mutable_init_client()->set_width(width);
msg.mutable_init_client()->set_height(height);
DCHECK(msg.IsInitialized());
- video_writer_.SendMessage(msg);
+ control_writer_.SendMessage(msg);
}
void ClientConnection::SendVideoPacket(const VideoPacket& packet) {
@@ -62,18 +62,12 @@ void ClientConnection::SendVideoPacket(const VideoPacket& packet) {
if (!connection_)
return;
- ChromotingHostMessage* message = new ChromotingHostMessage();
- // TODO(sergeyu): avoid memcopy here.
- *message->mutable_video_packet() = packet;
-
- video_writer_.SendMessage(*message);
-
- delete message;
+ video_writer_->SendPacket(packet);
}
int ClientConnection::GetPendingUpdateStreamMessages() {
DCHECK_EQ(loop_, MessageLoop::current());
- return video_writer_.GetPendingMessages();
+ return video_writer_->GetPendingPackets();
}
void ClientConnection::Disconnect() {
@@ -91,10 +85,12 @@ ClientConnection::ClientConnection() {}
void ClientConnection::OnConnectionStateChange(
ChromotocolConnection::State state) {
if (state == ChromotocolConnection::CONNECTED) {
+ control_writer_.Init(connection_->control_channel());
event_reader_.Init<ChromotingClientMessage>(
connection_->event_channel(),
NewCallback(this, &ClientConnection::OnMessageReceived));
- video_writer_.Init(connection_->video_channel());
+ video_writer_.reset(VideoWriter::Create(connection_->config()));
+ video_writer_->Init(connection_);
}
loop_->PostTask(FROM_HERE,
diff --git a/remoting/host/client_connection.h b/remoting/host/client_connection.h
index 38e383c..6f9deca 100644
--- a/remoting/host/client_connection.h
+++ b/remoting/host/client_connection.h
@@ -15,6 +15,7 @@
#include "remoting/protocol/chromotocol_connection.h"
#include "remoting/protocol/message_reader.h"
#include "remoting/protocol/stream_writer.h"
+#include "remoting/protocol/video_writer.h"
namespace remoting {
@@ -100,8 +101,9 @@ class ClientConnection : public base::RefCountedThreadSafe<ClientConnection> {
// The libjingle channel used to send and receive data from the remote client.
scoped_refptr<ChromotocolConnection> connection_;
+ ControlStreamWriter control_writer_;
MessageReader event_reader_;
- VideoStreamWriter video_writer_;
+ scoped_ptr<VideoWriter> video_writer_;
// The message loop that this object runs on.
MessageLoop* loop_;
diff --git a/remoting/host/mock_objects.h b/remoting/host/mock_objects.h
index 428bd74..79b8d6f 100644
--- a/remoting/host/mock_objects.h
+++ b/remoting/host/mock_objects.h
@@ -45,7 +45,7 @@ class MockClientConnection : public ClientConnection {
public:
MockClientConnection(){}
- MOCK_METHOD1(Init, void(ChromotingConnection* connection));
+ MOCK_METHOD1(Init, void(ChromotocolConnection* connection));
MOCK_METHOD2(SendInitClientMessage, void(int width, int height));
MOCK_METHOD1(SendVideoPacket, void(const VideoPacket& packet));
MOCK_METHOD0(GetPendingUpdateStreamMessages, int());
diff --git a/remoting/host/simple_host_process.cc b/remoting/host/simple_host_process.cc
index 2733850..98d9303 100644
--- a/remoting/host/simple_host_process.cc
+++ b/remoting/host/simple_host_process.cc
@@ -28,9 +28,6 @@
#include "base/path_service.h"
#include "base/thread.h"
#include "media/base/media.h"
-#include "remoting/base/encoder_verbatim.h"
-#include "remoting/base/encoder_vp8.h"
-#include "remoting/base/encoder_zlib.h"
#include "remoting/base/tracer.h"
#include "remoting/host/capturer_fake.h"
#include "remoting/host/chromoting_host.h"
@@ -65,8 +62,6 @@ void ShutdownTask(MessageLoop* message_loop) {
const std::string kFakeSwitchName = "fake";
const std::string kConfigSwitchName = "config";
-const std::string kVerbatimSwitchName = "verbatim";
-const std::string kVp8SwitchName = "vp8";
int main(int argc, char** argv) {
// Needed for the Mac, so we don't leak objects when threads are created.
@@ -80,7 +75,6 @@ int main(int argc, char** argv) {
base::EnsureNSPRInit();
scoped_ptr<remoting::Capturer> capturer;
- scoped_ptr<remoting::Encoder> encoder;
scoped_ptr<remoting::EventExecutor> event_handler;
#if defined(OS_WIN)
capturer.reset(new remoting::CapturerGdi());
@@ -92,12 +86,9 @@ int main(int argc, char** argv) {
capturer.reset(new remoting::CapturerMac());
event_handler.reset(new remoting::EventExecutorMac(capturer.get()));
#endif
- encoder.reset(new remoting::EncoderZlib());
- // Check the argument to see if we should use a fake capturer and encoder.
+ // Check the argument to see if we should use a fake capturer.
bool fake = cmd_line->HasSwitch(kFakeSwitchName);
- bool verbatim = cmd_line->HasSwitch(kVerbatimSwitchName);
- bool vp8 = cmd_line->HasSwitch(kVp8SwitchName);
#if defined(OS_WIN)
std::wstring home_path = GetEnvironmentVar(kHomeDrive);
@@ -117,19 +108,6 @@ int main(int argc, char** argv) {
capturer.reset(new remoting::CapturerFake());
}
- if (verbatim) {
- LOG(INFO) << "Using the verbatim encoder.";
- encoder.reset(new remoting::EncoderVerbatim());
- }
-
- // TODO(sergeyu): Enable VP8 on ARM builds.
-#if !defined(ARCH_CPU_ARM_FAMILY)
- if (vp8) {
- LOG(INFO) << "Using the verbatim encoder.";
- encoder.reset(new remoting::EncoderVp8());
- }
-#endif
-
base::Thread file_io_thread("FileIO");
file_io_thread.Start();
@@ -156,7 +134,6 @@ int main(int argc, char** argv) {
new remoting::ChromotingHost(&context,
config,
capturer.release(),
- encoder.release(),
event_handler.release()));
// Let the chromoting host run until the shutdown task is executed.
diff --git a/remoting/proto/video.proto b/remoting/proto/video.proto
index c91a0a3..963c118 100644
--- a/remoting/proto/video.proto
+++ b/remoting/proto/video.proto
@@ -85,9 +85,11 @@ message VideoPacket {
// The sequence number of the partial data for updating a rectangle.
optional int32 sequence_number = 2 [default = 0];
+ optional int32 timestamp = 3 [default = 0];
+
// This is provided on the first packet of the rectangle data, when
// the flags has FIRST_PACKET set.
- optional VideoPacketFormat format = 3;
+ optional VideoPacketFormat format = 4;
- optional bytes data = 4;
+ optional bytes data = 5;
}
diff --git a/remoting/protocol/chromotocol_config.h b/remoting/protocol/chromotocol_config.h
index bd0bcbc..aef2ecc 100644
--- a/remoting/protocol/chromotocol_config.h
+++ b/remoting/protocol/chromotocol_config.h
@@ -25,8 +25,9 @@ struct ChannelConfig {
enum Codec {
CODEC_UNDEFINED, // Used for event and control channels.
- CODEC_VP8,
+ CODEC_VERBATIM,
CODEC_ZIP,
+ CODEC_VP8,
};
ChannelConfig();
diff --git a/remoting/protocol/message_decoder.h b/remoting/protocol/message_decoder.h
index d28d9e0..207dee5 100644
--- a/remoting/protocol/message_decoder.h
+++ b/remoting/protocol/message_decoder.h
@@ -11,6 +11,7 @@
#include "base/ref_counted.h"
#include "base/scoped_ptr.h"
#include "google/protobuf/message_lite.h"
+#include "remoting/base/multiple_array_input_stream.h"
namespace net {
class DrainableIOBuffer;
@@ -25,7 +26,6 @@ class ClientControlMessage;
class ClientEventMessage;
class HostControlMessage;
class HostEventMessage;
-class MultipleArrayInputStream;
// MessageDecoder uses MultipleArrayInputStream to decode bytes into
// protocol buffer messages. This can be used to decode bytes received from
diff --git a/remoting/protocol/message_reader.h b/remoting/protocol/message_reader.h
index d3540bb..44e6a5c 100644
--- a/remoting/protocol/message_reader.h
+++ b/remoting/protocol/message_reader.h
@@ -10,6 +10,7 @@
#include "base/scoped_ptr.h"
#include "base/task.h"
#include "net/base/completion_callback.h"
+#include "net/base/io_buffer.h"
#include "remoting/protocol/message_decoder.h"
namespace net {
diff --git a/remoting/protocol/protobuf_video_reader.cc b/remoting/protocol/protobuf_video_reader.cc
new file mode 100644
index 0000000..70ac3cf
--- /dev/null
+++ b/remoting/protocol/protobuf_video_reader.cc
@@ -0,0 +1,30 @@
+// 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/protobuf_video_reader.h"
+
+#include "base/task.h"
+#include "remoting/protocol/chromotocol_connection.h"
+
+namespace remoting {
+
+ProtobufVideoReader::ProtobufVideoReader() { }
+ProtobufVideoReader::~ProtobufVideoReader() { }
+
+void ProtobufVideoReader::Init(ChromotocolConnection* connection,
+ VideoStub* video_stub) {
+ reader_.Init<VideoPacket>(connection->video_channel(),
+ NewCallback(this, &ProtobufVideoReader::OnNewData));
+ video_stub_ = video_stub;
+}
+
+void ProtobufVideoReader::Close() {
+ reader_.Close();
+}
+
+void ProtobufVideoReader::OnNewData(VideoPacket* packet) {
+ video_stub_->ProcessVideoPacket(packet, new DeleteTask<VideoPacket>(packet));
+}
+
+} // namespace remoting
diff --git a/remoting/protocol/protobuf_video_reader.h b/remoting/protocol/protobuf_video_reader.h
new file mode 100644
index 0000000..cad98c5
--- /dev/null
+++ b/remoting/protocol/protobuf_video_reader.h
@@ -0,0 +1,35 @@
+// 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.
+
+#ifndef REMOTING_PROTOCOL_PROTOBUF_VIDEO_READER_H_
+#define REMOTING_PROTOCOL_PROTOBUF_VIDEO_READER_H_
+
+#include "remoting/protocol/message_reader.h"
+#include "remoting/protocol/video_reader.h"
+
+namespace remoting {
+
+class ProtobufVideoReader : public VideoReader {
+ public:
+ ProtobufVideoReader();
+ virtual ~ProtobufVideoReader();
+
+ // VideoReader interface.
+ virtual void Init(ChromotocolConnection* connection, VideoStub* video_stub);
+ virtual void Close();
+
+ private:
+ void OnNewData(VideoPacket* packet);
+
+ MessageReader reader_;
+
+ // The stub that processes all received packets.
+ VideoStub* video_stub_;
+
+ DISALLOW_COPY_AND_ASSIGN(ProtobufVideoReader);
+};
+
+} // namespace remoting
+
+#endif // REMOTING_PROTOCOL_PROTOBUF_VIDEO_READER_H_
diff --git a/remoting/protocol/protobuf_video_writer.cc b/remoting/protocol/protobuf_video_writer.cc
new file mode 100644
index 0000000..96b4e34
--- /dev/null
+++ b/remoting/protocol/protobuf_video_writer.cc
@@ -0,0 +1,36 @@
+// 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/protobuf_video_writer.h"
+
+#include "remoting/protocol/chromotocol_connection.h"
+#include "remoting/protocol/rtp_writer.h"
+#include "remoting/protocol/util.h"
+
+namespace remoting {
+
+ProtobufVideoWriter::ProtobufVideoWriter() { }
+
+ProtobufVideoWriter::~ProtobufVideoWriter() { }
+
+void ProtobufVideoWriter::Init(ChromotocolConnection* connection) {
+ buffered_writer_ = new BufferedSocketWriter();
+ // TODO(sergeyu): Provide WriteFailedCallback for the buffered writer.
+ buffered_writer_->Init(connection->video_channel(), NULL);
+}
+
+void ProtobufVideoWriter::SendPacket(const VideoPacket& packet) {
+ buffered_writer_->Write(SerializeAndFrameMessage(packet));
+}
+
+int ProtobufVideoWriter::GetPendingPackets() {
+ return buffered_writer_->GetBufferChunks();
+}
+
+
+void ProtobufVideoWriter::Close() {
+ buffered_writer_->Close();
+}
+
+} // namespace remoting
diff --git a/remoting/protocol/protobuf_video_writer.h b/remoting/protocol/protobuf_video_writer.h
new file mode 100644
index 0000000..02d3034
--- /dev/null
+++ b/remoting/protocol/protobuf_video_writer.h
@@ -0,0 +1,34 @@
+// 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.
+
+#ifndef REMOTING_PROTOCOL_PROTOBUF_VIDEO_WRITER_H_
+#define REMOTING_PROTOCOL_PROTOBUF_VIDEO_WRITER_H_
+
+#include "base/ref_counted.h"
+#include "remoting/protocol/video_writer.h"
+
+namespace remoting {
+
+class BufferedSocketWriter;
+
+class ProtobufVideoWriter : public VideoWriter {
+ public:
+ ProtobufVideoWriter();
+ virtual ~ProtobufVideoWriter();
+
+ // VideoWriter interface.
+ virtual void Init(ChromotocolConnection* connection);
+ virtual void SendPacket(const VideoPacket& packet);
+ virtual int GetPendingPackets();
+ virtual void Close();
+
+ private:
+ scoped_refptr<BufferedSocketWriter> buffered_writer_;
+
+ DISALLOW_COPY_AND_ASSIGN(ProtobufVideoWriter);
+};
+
+} // namespace remoting
+
+#endif // REMOTING_PROTOCOL_PROTOBUF_VIDEO_WRITER_H_
diff --git a/remoting/protocol/rtp_reader.cc b/remoting/protocol/rtp_reader.cc
index a3659fb..31b133e 100644
--- a/remoting/protocol/rtp_reader.cc
+++ b/remoting/protocol/rtp_reader.cc
@@ -34,7 +34,7 @@ void RtpReader::OnDataReceived(net::IOBuffer* buffer, int data_size) {
packet.payload = buffer->data() + header_size;
packet.payload_size = data_size - header_size;
- on_message_callback_->Run(&packet);
+ on_message_callback_->Run(packet);
}
} // namespace remoting
diff --git a/remoting/protocol/rtp_reader.h b/remoting/protocol/rtp_reader.h
index b9a12df..3fc3983 100644
--- a/remoting/protocol/rtp_reader.h
+++ b/remoting/protocol/rtp_reader.h
@@ -28,7 +28,7 @@ class RtpReader : public SocketReaderBase {
// The OnMessageCallback is called whenever a new message is received.
// Ownership of the message is passed the callback.
- typedef Callback1<RtpPacket*>::Type OnMessageCallback;
+ typedef Callback1<const RtpPacket&>::Type OnMessageCallback;
// Initialize the reader and start reading. Must be called on the thread
// |socket| belongs to. The callback will be called when a new message is
diff --git a/remoting/protocol/rtp_utils.cc b/remoting/protocol/rtp_utils.cc
index df10af2..25cbefc 100644
--- a/remoting/protocol/rtp_utils.cc
+++ b/remoting/protocol/rtp_utils.cc
@@ -48,13 +48,10 @@ void PackRtpHeader(uint8* buffer, int buffer_size,
}
static inline uint8 ExtractBits(uint8 byte, int bits_count, int shift) {
- return (byte >> shift) && ((1 << bits_count) - 1);
+ return (byte >> shift) & ((1 << bits_count) - 1);
}
int UnpackRtpHeader(const uint8* buffer, int buffer_size, RtpHeader* header) {
- DCHECK_LT(header->sources, 1 << 4);
- DCHECK_LT(header->payload_type, 1 << 7);
-
if (buffer_size < kRtpBaseHeaderSize) {
return -1;
}
@@ -69,13 +66,13 @@ int UnpackRtpHeader(const uint8* buffer, int buffer_size, RtpHeader* header) {
header->sources = ExtractBits(buffer[0], 4, 0);
header->marker = ExtractBits(buffer[1], 1, 7) != 0;
- header->sources = ExtractBits(buffer[1], 7, 0);
+ header->payload_type = ExtractBits(buffer[1], 7, 0);
header->sequence_number = GetBE16(buffer + 2);
header->timestamp = GetBE32(buffer + 4);
header->sync_source_id = GetBE32(buffer + 8);
- DCHECK_LE(header->sources, 16);
+ DCHECK_LT(header->sources, 16);
if (buffer_size < GetRtpHeaderSize(header->sources)) {
return -1;
diff --git a/remoting/protocol/rtp_video_reader.cc b/remoting/protocol/rtp_video_reader.cc
new file mode 100644
index 0000000..8de6d91
--- /dev/null
+++ b/remoting/protocol/rtp_video_reader.cc
@@ -0,0 +1,41 @@
+// 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/rtp_video_reader.h"
+
+#include "base/task.h"
+#include "remoting/protocol/chromotocol_connection.h"
+
+namespace remoting {
+
+RtpVideoReader::RtpVideoReader() { }
+RtpVideoReader::~RtpVideoReader() { }
+
+void RtpVideoReader::Init(ChromotocolConnection* connection,
+ VideoStub* video_stub) {
+ rtp_reader_.Init(connection->video_rtp_channel(),
+ NewCallback(this, &RtpVideoReader::OnRtpPacket));
+ video_stub_ = video_stub;
+}
+
+void RtpVideoReader::Close() {
+ rtp_reader_.Close();
+}
+
+void RtpVideoReader::OnRtpPacket(const RtpPacket& rtp_packet) {
+ VideoPacket* packet = new VideoPacket();
+ packet->set_data(rtp_packet.payload, rtp_packet.payload_size);
+
+ packet->mutable_format()->set_encoding(VideoPacketFormat::ENCODING_VP8);
+ packet->set_flags(rtp_packet.header.marker ? VideoPacket::LAST_PACKET : 0);
+ packet->mutable_format()->set_pixel_format(PIXEL_FORMAT_RGB32);
+ packet->mutable_format()->set_x(0);
+ packet->mutable_format()->set_y(0);
+ packet->mutable_format()->set_width(800);
+ packet->mutable_format()->set_height(600);
+
+ video_stub_->ProcessVideoPacket(packet, new DeleteTask<VideoPacket>(packet));
+}
+
+} // namespace remoting
diff --git a/remoting/protocol/rtp_video_reader.h b/remoting/protocol/rtp_video_reader.h
new file mode 100644
index 0000000..d7f526e
--- /dev/null
+++ b/remoting/protocol/rtp_video_reader.h
@@ -0,0 +1,35 @@
+// 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.
+
+#ifndef REMOTING_PROTOCOL_RTP_VIDEO_READER_H_
+#define REMOTING_PROTOCOL_RTP_VIDEO_READER_H_
+
+#include "remoting/protocol/rtp_reader.h"
+#include "remoting/protocol/video_reader.h"
+
+namespace remoting {
+
+class RtpVideoReader : public VideoReader {
+ public:
+ RtpVideoReader();
+ virtual ~RtpVideoReader();
+
+ // VideoReader interface.
+ virtual void Init(ChromotocolConnection* connection, VideoStub* video_stub);
+ virtual void Close();
+
+ private:
+ void OnRtpPacket(const RtpPacket& rtp_packet);
+
+ RtpReader rtp_reader_;
+
+ // The stub that processes all received packets.
+ VideoStub* video_stub_;
+
+ DISALLOW_COPY_AND_ASSIGN(RtpVideoReader);
+};
+
+} // namespace remoting
+
+#endif // REMOTING_PROTOCOL_RTP_VIDEO_READER_H_
diff --git a/remoting/protocol/rtp_video_writer.cc b/remoting/protocol/rtp_video_writer.cc
new file mode 100644
index 0000000..6307c0c
--- /dev/null
+++ b/remoting/protocol/rtp_video_writer.cc
@@ -0,0 +1,35 @@
+// 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/rtp_video_writer.h"
+
+#include "remoting/protocol/chromotocol_connection.h"
+#include "remoting/protocol/rtp_writer.h"
+
+namespace remoting {
+
+RtpVideoWriter::RtpVideoWriter() { }
+
+RtpVideoWriter::~RtpVideoWriter() { }
+
+void RtpVideoWriter::Init(ChromotocolConnection* connection) {
+ rtp_writer_.Init(connection->video_rtp_channel(),
+ connection->video_rtcp_channel());
+}
+
+void RtpVideoWriter::SendPacket(const VideoPacket& packet) {
+ rtp_writer_.SendPacket(packet.data().data(), packet.data().length(),
+ packet.timestamp());
+}
+
+int RtpVideoWriter::GetPendingPackets() {
+ return rtp_writer_.GetPendingPackets();
+}
+
+
+void RtpVideoWriter::Close() {
+ rtp_writer_.Close();
+}
+
+} // namespace remoting
diff --git a/remoting/protocol/rtp_video_writer.h b/remoting/protocol/rtp_video_writer.h
new file mode 100644
index 0000000..4084576
--- /dev/null
+++ b/remoting/protocol/rtp_video_writer.h
@@ -0,0 +1,32 @@
+// 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.
+
+#ifndef REMOTING_PROTOCOL_RTP_VIDEO_WRITER_H_
+#define REMOTING_PROTOCOL_RTP_VIDEO_WRITER_H_
+
+#include "remoting/protocol/rtp_writer.h"
+#include "remoting/protocol/video_writer.h"
+
+namespace remoting {
+
+class RtpVideoWriter : public VideoWriter {
+ public:
+ RtpVideoWriter();
+ virtual ~RtpVideoWriter();
+
+ // VideoWriter interface.
+ virtual void Init(ChromotocolConnection* connection);
+ virtual void SendPacket(const VideoPacket& packet);
+ virtual int GetPendingPackets();
+ virtual void Close();
+
+ private:
+ RtpWriter rtp_writer_;
+
+ DISALLOW_COPY_AND_ASSIGN(RtpVideoWriter);
+};
+
+} // namespace remoting
+
+#endif // REMOTING_PROTOCOL_RTP_VIDEO_WRITER_H_
diff --git a/remoting/protocol/rtp_writer.cc b/remoting/protocol/rtp_writer.cc
index a9df798..909a572 100644
--- a/remoting/protocol/rtp_writer.cc
+++ b/remoting/protocol/rtp_writer.cc
@@ -32,7 +32,7 @@ void RtpWriter::Init(net::Socket* rtp_socket, net::Socket* rtcp_socket) {
rtcp_socket_ = rtcp_socket;
}
-void RtpWriter::SendPacket(const char* data, int packet_size,
+void RtpWriter::SendPacket(const char* payload, int payload_size,
uint32 timestamp) {
RtpHeader header;
header.padding = false;
@@ -49,15 +49,15 @@ void RtpWriter::SendPacket(const char* data, int packet_size,
// TODO(sergeyu): Add VP8 payload header.
int position = 0;
- while (position < packet_size) {
+ while (position < payload_size) {
// Allocate buffer.
- int size = std::max(kMtu, packet_size - position);
- int header_size = GetRtpHeaderSize(header.sources) + size;
+ int size = std::min(kMtu, payload_size - position);
+ int header_size = GetRtpHeaderSize(header.sources);
int total_size = size + header_size;
net::IOBufferWithSize* buffer = new net::IOBufferWithSize(total_size);
// Set marker if this is the last frame.
- header.marker = (position + size) == packet_size;
+ header.marker = (position + size) == payload_size;
// TODO(sergeyu): Handle sequence number wrapping.
header.sequence_number = last_packet_number_;
@@ -68,7 +68,7 @@ void RtpWriter::SendPacket(const char* data, int packet_size,
header);
// Copy data to the buffer.
- memcpy(buffer->data() + header_size, data + position, size);
+ memcpy(buffer->data() + header_size, payload + position, size);
// Send it.
buffered_rtp_writer_->Write(buffer);
@@ -76,7 +76,11 @@ void RtpWriter::SendPacket(const char* data, int packet_size,
position += size;
}
- DCHECK_EQ(position, packet_size);
+ DCHECK_EQ(position, payload_size);
+}
+
+int RtpWriter::GetPendingPackets() {
+ return buffered_rtp_writer_->GetBufferChunks();
}
// Stop writing and drop pending data. Must be called from the same thread as
diff --git a/remoting/protocol/rtp_writer.h b/remoting/protocol/rtp_writer.h
index 5ba7501..6bcd7ec 100644
--- a/remoting/protocol/rtp_writer.h
+++ b/remoting/protocol/rtp_writer.h
@@ -19,8 +19,11 @@ class RtpWriter {
// to.
void Init(net::Socket* rtp_socket, net::Socket* rtcp_socket);
- void SendPacket(const char* buffer, int packet_size,
- uint32 timestamp);
+ // Sends next packet.
+ void SendPacket(const char* payload, int payload_size, uint32 timestamp);
+
+ // Returns number of packets queued in the buffer.
+ int GetPendingPackets();
// Stop writing and drop pending data. Must be called from the same thread as
// Init().
diff --git a/remoting/protocol/stream_writer.cc b/remoting/protocol/stream_writer.cc
index ce91650..9d1f2a7 100644
--- a/remoting/protocol/stream_writer.cc
+++ b/remoting/protocol/stream_writer.cc
@@ -5,6 +5,7 @@
#include "remoting/protocol/stream_writer.h"
#include "base/message_loop.h"
+#include "remoting/protocol/buffered_socket_writer.h"
#include "remoting/protocol/chromotocol_connection.h"
#include "remoting/protocol/util.h"
@@ -34,13 +35,11 @@ void StreamWriterBase::Close() {
buffered_writer_->Close();
}
-bool EventStreamWriter::SendMessage(
- const ChromotingClientMessage& message) {
+bool EventStreamWriter::SendMessage(const ChromotingClientMessage& message) {
return buffered_writer_->Write(SerializeAndFrameMessage(message));
}
-bool VideoStreamWriter::SendMessage(
- const ChromotingHostMessage& message) {
+bool ControlStreamWriter::SendMessage(const ChromotingHostMessage& message) {
return buffered_writer_->Write(SerializeAndFrameMessage(message));
}
diff --git a/remoting/protocol/stream_writer.h b/remoting/protocol/stream_writer.h
index 75f6180..f5b018b 100644
--- a/remoting/protocol/stream_writer.h
+++ b/remoting/protocol/stream_writer.h
@@ -5,12 +5,16 @@
#ifndef REMOTING_PROTOCOL_STREAM_WRITER_H_
#define REMOTING_PROTOCOL_STREAM_WRITER_H_
+#include "base/ref_counted.h"
#include "remoting/proto/internal.pb.h"
-#include "remoting/protocol/buffered_socket_writer.h"
+
+namespace net {
+class Socket;
+} // namespace net
namespace remoting {
-class ChromotingConnection;
+class BufferedSocketWriter;
class StreamWriterBase {
public:
@@ -41,7 +45,7 @@ class EventStreamWriter : public StreamWriterBase {
bool SendMessage(const ChromotingClientMessage& message);
};
-class VideoStreamWriter : public StreamWriterBase {
+class ControlStreamWriter : public StreamWriterBase {
public:
// Sends the |message| or returns false if called before Init().
// Can be called on any thread.
diff --git a/remoting/protocol/video_reader.cc b/remoting/protocol/video_reader.cc
new file mode 100644
index 0000000..63cdae3
--- /dev/null
+++ b/remoting/protocol/video_reader.cc
@@ -0,0 +1,26 @@
+// 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/video_reader.h"
+
+#include "remoting/protocol/chromotocol_config.h"
+#include "remoting/protocol/protobuf_video_reader.h"
+#include "remoting/protocol/rtp_video_reader.h"
+
+namespace remoting {
+
+VideoReader::~VideoReader() { }
+
+// static
+VideoReader* VideoReader::Create(const ChromotocolConfig* config) {
+ const ChannelConfig& video_config = config->video_config();
+ if (video_config.transport == ChannelConfig::TRANSPORT_SRTP) {
+ return new RtpVideoReader();
+ } else if (video_config.transport == ChannelConfig::TRANSPORT_STREAM) {
+ return new ProtobufVideoReader();
+ }
+ return NULL;
+}
+
+} // namespace remoting
diff --git a/remoting/protocol/video_reader.h b/remoting/protocol/video_reader.h
new file mode 100644
index 0000000..ca39619
--- /dev/null
+++ b/remoting/protocol/video_reader.h
@@ -0,0 +1,43 @@
+// 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.
+
+// VideoReader is a generic interface for a video stream reader. RtpVideoReader
+// and ProtobufVideoReader implement this interface for RTP and protobuf video
+// streams. VideoReader is used by ConnectionToHost to read video stream.
+
+#ifndef REMOTING_PROTOCOL_VIDEO_READER_H_
+#define REMOTING_PROTOCOL_VIDEO_READER_H_
+
+#include "base/callback.h"
+#include "remoting/protocol/video_stub.h"
+
+namespace remoting {
+
+class ChromotocolConfig;
+class ChromotocolConnection;
+
+class VideoReader {
+ public:
+ static VideoReader* Create(const ChromotocolConfig* config);
+
+ virtual ~VideoReader();
+
+ // Initializies the reader. Doesn't take ownership of either |connection|
+ // or |video_stub|.
+ virtual void Init(ChromotocolConnection* connection,
+ VideoStub* video_stub) = 0;
+
+ // Closes the reader. The stub should not be called after Close().
+ virtual void Close() = 0;
+
+ protected:
+ VideoReader() { }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(VideoReader);
+};
+
+} // namespace remoting
+
+#endif // REMOTING_PROTOCOL_VIDEO_READER_H_
diff --git a/remoting/protocol/video_stub.h b/remoting/protocol/video_stub.h
new file mode 100644
index 0000000..9f9657f
--- /dev/null
+++ b/remoting/protocol/video_stub.h
@@ -0,0 +1,33 @@
+// 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.
+
+#ifndef REMOTING_PROTOCOL_VIDEO_STUB_H_
+#define REMOTING_PROTOCOL_VIDEO_STUB_H_
+
+#include "remoting/proto/video.pb.h"
+
+class Task;
+
+namespace remoting {
+
+class VideoStub {
+ public:
+ virtual ~VideoStub() { }
+
+ // TODO(sergeyu): VideoPacket is the protobuf message that is used to send
+ // video packets in protobuf stream. It should not be used here. Add another
+ // struct and use it to represent video packets internally.
+ virtual void ProcessVideoPacket(const VideoPacket* video_packet,
+ Task* done) = 0;
+
+ protected:
+ VideoStub() { }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(VideoStub);
+};
+
+} // namespace remoting
+
+#endif // REMOTING_PROTOCOL_VIDEO_STUB_H_
diff --git a/remoting/protocol/video_writer.cc b/remoting/protocol/video_writer.cc
new file mode 100644
index 0000000..c451010
--- /dev/null
+++ b/remoting/protocol/video_writer.cc
@@ -0,0 +1,26 @@
+// 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/video_writer.h"
+
+#include "remoting/protocol/chromotocol_config.h"
+#include "remoting/protocol/protobuf_video_writer.h"
+#include "remoting/protocol/rtp_video_writer.h"
+
+namespace remoting {
+
+VideoWriter::~VideoWriter() { }
+
+// static
+VideoWriter* VideoWriter::Create(const ChromotocolConfig* config) {
+ const ChannelConfig& video_config = config->video_config();
+ if (video_config.transport == ChannelConfig::TRANSPORT_SRTP) {
+ return new RtpVideoWriter();
+ } else if (video_config.transport == ChannelConfig::TRANSPORT_STREAM) {
+ return new ProtobufVideoWriter();
+ }
+ return NULL;
+}
+
+} // namespace remoting
diff --git a/remoting/protocol/video_writer.h b/remoting/protocol/video_writer.h
new file mode 100644
index 0000000..9c98a8e
--- /dev/null
+++ b/remoting/protocol/video_writer.h
@@ -0,0 +1,48 @@
+// 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.
+
+// VideoWriter is a generic interface for a video stream writer. RtpVideoWriter
+// and ProtobufVideoWriter implement this interface for RTP and protobuf video
+// streams. VideoWriter is used by ConnectionToClient to write into the video
+// stream.
+
+#ifndef REMOTING_PROTOCOL_VIDEO_WRITER_H_
+#define REMOTING_PROTOCOL_VIDEO_WRITER_H_
+
+#include "base/basictypes.h"
+#include "remoting/proto/video.pb.h"
+
+namespace remoting {
+
+class ChromotocolConfig;
+class ChromotocolConnection;
+
+// TODO(sergeyu): VideoWriter should implement VideoStub interface.
+class VideoWriter {
+ public:
+ virtual ~VideoWriter();
+
+ static VideoWriter* Create(const ChromotocolConfig* config);
+
+ // Initializes the writer.
+ virtual void Init(ChromotocolConnection* connection) = 0;
+
+ // Sends the |packet|.
+ virtual void SendPacket(const VideoPacket& packet) = 0;
+
+ // Returns number of packets currently pending in the buffer.
+ virtual int GetPendingPackets() = 0;
+
+ virtual void Close() = 0;
+
+ protected:
+ VideoWriter() { }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(VideoWriter);
+};
+
+} // namespace remoting
+
+#endif // REMOTING_PROTOCOL_VIDEO_WRITER_H_
diff --git a/remoting/remoting.gyp b/remoting/remoting.gyp
index dc72d8b..80d8d5d 100644
--- a/remoting/remoting.gyp
+++ b/remoting/remoting.gyp
@@ -379,10 +379,18 @@
'protocol/jingle_chromotocol_connection.h',
'protocol/jingle_chromotocol_server.cc',
'protocol/jingle_chromotocol_server.h',
+ 'protocol/protobuf_video_reader.cc',
+ 'protocol/protobuf_video_reader.h',
+ 'protocol/protobuf_video_writer.cc',
+ 'protocol/protobuf_video_writer.h',
'protocol/rtp_reader.cc',
'protocol/rtp_reader.h',
'protocol/rtp_utils.cc',
'protocol/rtp_utils.h',
+ 'protocol/rtp_video_reader.cc',
+ 'protocol/rtp_video_reader.h',
+ 'protocol/rtp_video_writer.cc',
+ 'protocol/rtp_video_writer.h',
'protocol/rtp_writer.cc',
'protocol/rtp_writer.h',
'protocol/socket_reader_base.cc',
@@ -391,6 +399,11 @@
'protocol/stream_writer.h',
'protocol/util.cc',
'protocol/util.h',
+ 'protocol/video_reader.cc',
+ 'protocol/video_reader.h',
+ 'protocol/video_stub.h',
+ 'protocol/video_writer.cc',
+ 'protocol/video_writer.h',
],
}, # end of target 'chromoting_protocol'