summaryrefslogtreecommitdiffstats
path: root/remoting/host
diff options
context:
space:
mode:
Diffstat (limited to 'remoting/host')
-rw-r--r--remoting/host/client_connection.cc21
-rw-r--r--remoting/host/client_connection.h17
-rw-r--r--remoting/host/client_connection_unittest.cc17
-rw-r--r--remoting/host/encoder.h12
-rw-r--r--remoting/host/encoder_verbatim.cc45
-rw-r--r--remoting/host/encoder_verbatim.h8
-rw-r--r--remoting/host/mock_objects.h5
-rw-r--r--remoting/host/session_manager.cc29
-rw-r--r--remoting/host/session_manager.h6
-rw-r--r--remoting/host/session_manager_unittest.cc19
10 files changed, 83 insertions, 96 deletions
diff --git a/remoting/host/client_connection.cc b/remoting/host/client_connection.cc
index d69a326..6c8516a 100644
--- a/remoting/host/client_connection.cc
+++ b/remoting/host/client_connection.cc
@@ -35,6 +35,16 @@ ClientConnection::~ClientConnection() {
// jingle channel.
}
+// static
+scoped_refptr<media::DataBuffer>
+ ClientConnection::CreateWireFormatDataBuffer(
+ const HostMessage* msg) {
+ // TODO(hclam): Instead of serializing |msg| create an DataBuffer
+ // object that wraps around it.
+ scoped_ptr<const HostMessage> message_deleter(msg);
+ return SerializeAndFrameMessage(*msg);
+}
+
void ClientConnection::SendInitClientMessage(int width, int height) {
DCHECK_EQ(loop_, MessageLoop::current());
DCHECK(!update_stream_size_);
@@ -68,7 +78,6 @@ void ClientConnection::SendBeginUpdateStreamMessage() {
}
void ClientConnection::SendUpdateStreamPacketMessage(
- const UpdateStreamPacketHeader* header,
scoped_refptr<DataBuffer> data) {
DCHECK_EQ(loop_, MessageLoop::current());
@@ -76,16 +85,8 @@ void ClientConnection::SendUpdateStreamPacketMessage(
if (!channel_)
return;
- HostMessage msg;
- msg.mutable_update_stream_packet()->mutable_header()->CopyFrom(*header);
- // TODO(hclam): This introduce one memory copy. Eliminate it.
- msg.mutable_update_stream_packet()->set_data(
- data->GetData(), data->GetDataSize());
- DCHECK(msg.IsInitialized());
-
- scoped_refptr<DataBuffer> encoded_data = SerializeAndFrameMessage(msg);
update_stream_size_ += data->GetDataSize();
- channel_->Write(encoded_data);
+ channel_->Write(data);
}
void ClientConnection::SendEndUpdateStreamMessage() {
diff --git a/remoting/host/client_connection.h b/remoting/host/client_connection.h
index 3e85cc9..c647eb6 100644
--- a/remoting/host/client_connection.h
+++ b/remoting/host/client_connection.h
@@ -62,6 +62,12 @@ class ClientConnection : public base::RefCountedThreadSafe<ClientConnection>,
virtual ~ClientConnection();
+ // Creates a DataBuffer object that wraps around HostMessage. The DataBuffer
+ // object will be responsible for serializing and framing the message.
+ // DataBuffer will also own |msg| after this call.
+ static scoped_refptr<media::DataBuffer> CreateWireFormatDataBuffer(
+ const HostMessage* msg);
+
virtual void set_jingle_channel(JingleChannel* channel) {
channel_ = channel;
}
@@ -75,10 +81,15 @@ class ClientConnection : public base::RefCountedThreadSafe<ClientConnection>,
// Notifies the viewer the start of an update stream.
virtual void SendBeginUpdateStreamMessage();
- // Send encoded update stream data to the viewer. The viewer
- // should not take ownership of the data.
+ // Send encoded update stream data to the viewer.
+ //
+ // |data| is the actual bytes in wire format. That means it is fully framed
+ // and serialized from a HostMessage. This is a special case only for
+ // UpdateStreamPacket to reduce the amount of memory copies.
+ //
+ // |data| should be created by calling to
+ // CreateWireFormatDataBuffer(HostMessage).
virtual void SendUpdateStreamPacketMessage(
- const UpdateStreamPacketHeader* header,
scoped_refptr<media::DataBuffer> data);
// Notifies the viewer the update stream has ended.
diff --git a/remoting/host/client_connection_unittest.cc b/remoting/host/client_connection_unittest.cc
index b7cb10c..9c3bcb3 100644
--- a/remoting/host/client_connection_unittest.cc
+++ b/remoting/host/client_connection_unittest.cc
@@ -55,14 +55,8 @@ TEST_F(ClientConnectionTest, SendUpdateStream) {
// Then send the actual data.
EXPECT_CALL(*channel_, Write(_));
- scoped_ptr<UpdateStreamPacketHeader> header(new UpdateStreamPacketHeader);
- header->set_x(0);
- header->set_y(0);
- header->set_width(640);
- header->set_height(480);
-
scoped_refptr<media::DataBuffer> data = new media::DataBuffer(10);
- viewer_->SendUpdateStreamPacketMessage(header.get(), data);
+ viewer_->SendUpdateStreamPacketMessage(data);
// Send the end of update message.
EXPECT_CALL(*channel_, Write(_));
@@ -105,15 +99,8 @@ TEST_F(ClientConnectionTest, Close) {
EXPECT_CALL(*channel_, Close());
viewer_->Disconnect();
- viewer_->SendBeginUpdateStreamMessage();
- scoped_ptr<UpdateStreamPacketHeader> header(new UpdateStreamPacketHeader);
- header->set_x(0);
- header->set_y(0);
- header->set_width(640);
- header->set_height(480);
-
scoped_refptr<media::DataBuffer> data = new media::DataBuffer(10);
- viewer_->SendUpdateStreamPacketMessage(header.get(), data);
+ viewer_->SendUpdateStreamPacketMessage(data);
viewer_->SendEndUpdateStreamMessage();
viewer_->Disconnect();
}
diff --git a/remoting/host/encoder.h b/remoting/host/encoder.h
index 09cbdde..ee43c94 100644
--- a/remoting/host/encoder.h
+++ b/remoting/host/encoder.h
@@ -17,6 +17,8 @@ namespace media {
namespace remoting {
+class HostMessage;
+
// A class to perform the task of encoding a continous stream of
// images.
// This class operates asynchronously to enable maximum throughput.
@@ -34,11 +36,11 @@ class Encoder {
typedef int EncodingState;
// DataAvailableCallback is called as blocks of data are made available
- // from the encoder. The callback takes ownership of header and is
- // responsible for deleting it.
- typedef Callback3<const UpdateStreamPacketHeader*,
- const scoped_refptr<media::DataBuffer>&,
- EncodingState>::Type DataAvailableCallback;
+ // from the encoder. Data made available by the encoder is in the form
+ // of HostMessage to reduce the amount of memory copies.
+ // The callback takes ownership of the HostMessage and is responsible for
+ // deleting it.
+ typedef Callback2<HostMessage*, EncodingState>::Type DataAvailableCallback;
virtual ~Encoder() {}
diff --git a/remoting/host/encoder_verbatim.cc b/remoting/host/encoder_verbatim.cc
index f1e2b46..fd9dadf 100644
--- a/remoting/host/encoder_verbatim.cc
+++ b/remoting/host/encoder_verbatim.cc
@@ -7,6 +7,7 @@
#include "gfx/rect.h"
#include "media/base/data_buffer.h"
#include "remoting/base/protocol_util.h"
+#include "remoting/base/protocol/chromotocol.pb.h"
namespace remoting {
@@ -17,13 +18,14 @@ void EncoderVerbatim::Encode(scoped_refptr<Capturer::CaptureData> capture_data,
DataAvailableCallback* data_available_callback) {
int num_rects = capture_data->dirty_rects().size();
for (int i = 0; i < num_rects; i++) {
- scoped_refptr<DataBuffer> data;
const gfx::Rect& dirty_rect = capture_data->dirty_rects()[i];
- scoped_ptr<UpdateStreamPacketHeader> header(new UpdateStreamPacketHeader);
- if (EncodeRect(dirty_rect,
- capture_data,
- header.get(),
- &data)) {
+ HostMessage* msg = new HostMessage();
+ UpdateStreamPacketMessage* packet = msg->mutable_update_stream_packet();
+
+ if (EncodeRect(dirty_rect, capture_data, packet)) {
+ // Prepare the end rect content.
+ packet->mutable_end_rect();
+
EncodingState state = EncodingInProgress;
if (i == 0) {
state |= EncodingStarting;
@@ -31,9 +33,7 @@ void EncoderVerbatim::Encode(scoped_refptr<Capturer::CaptureData> capture_data,
if (i == num_rects - 1) {
state |= EncodingEnded;
}
- data_available_callback->Run(header.release(),
- data,
- state);
+ data_available_callback->Run(msg, state);
}
}
@@ -43,12 +43,18 @@ void EncoderVerbatim::Encode(scoped_refptr<Capturer::CaptureData> capture_data,
bool EncoderVerbatim::EncodeRect(
const gfx::Rect& dirty,
const scoped_refptr<Capturer::CaptureData>& capture_data,
- UpdateStreamPacketHeader* header,
- scoped_refptr<DataBuffer>* output_data) {
- int bytes_per_pixel = GetBytesPerPixel(capture_data->pixel_format());
- int row_size = bytes_per_pixel * dirty.width();
+ UpdateStreamPacketMessage* packet) {
+ // Prepare the begin rect content.
+ packet->mutable_begin_rect()->set_x(dirty.x());
+ packet->mutable_begin_rect()->set_y(dirty.y());
+ packet->mutable_begin_rect()->set_width(dirty.width());
+ packet->mutable_begin_rect()->set_height(dirty.height());
+ packet->mutable_begin_rect()->set_encoding(EncodingNone);
+ packet->mutable_begin_rect()->set_pixel_format(capture_data->pixel_format());
// Calculate the size of output.
+ int bytes_per_pixel = GetBytesPerPixel(capture_data->pixel_format());
+ int row_size = bytes_per_pixel * dirty.width();
int output_size = 0;
for (int i = 0; i < Capturer::DataPlanes::kPlaneCount; ++i) {
// TODO(hclam): Handle YUV since the height would be different.
@@ -57,15 +63,10 @@ bool EncoderVerbatim::EncodeRect(
output_size += row_size * dirty.height();
}
- header->set_x(dirty.x());
- header->set_y(dirty.y());
- header->set_width(dirty.width());
- header->set_height(dirty.height());
- header->set_encoding(EncodingNone);
- header->set_pixel_format(capture_data->pixel_format());
-
- *output_data = new DataBuffer(new uint8[output_size], output_size);
- uint8* out = (*output_data)->GetWritableData();
+ // Resize the output data buffer.
+ packet->mutable_rect_data()->mutable_data()->resize(output_size);
+ uint8* out = reinterpret_cast<uint8*>(
+ &((*packet->mutable_rect_data()->mutable_data())[0]));
for (int i = 0; i < Capturer::DataPlanes::kPlaneCount; ++i) {
const uint8* in = capture_data->data_planes().data[i];
diff --git a/remoting/host/encoder_verbatim.h b/remoting/host/encoder_verbatim.h
index 745d544..175b954 100644
--- a/remoting/host/encoder_verbatim.h
+++ b/remoting/host/encoder_verbatim.h
@@ -9,6 +9,8 @@
namespace remoting {
+class UpdateStreamPacket;
+
// EncoderVerbatim implements Encoder and simply copies input to the output
// buffer verbatim.
class EncoderVerbatim : public Encoder {
@@ -21,12 +23,12 @@ class EncoderVerbatim : public Encoder {
DataAvailableCallback* data_available_callback);
private:
- // Encode a single dirty rect. Called by Encode().
+ // Encode a single dirty rect. Called by Encode(). Output is written
+ // to |msg|.
// Returns false if there is an error.
bool EncodeRect(const gfx::Rect& dirty,
const scoped_refptr<Capturer::CaptureData>& capture_data,
- UpdateStreamPacketHeader* header,
- scoped_refptr<media::DataBuffer>* output_data);
+ UpdateStreamPacketMessage* msg);
};
} // namespace remoting
diff --git a/remoting/host/mock_objects.h b/remoting/host/mock_objects.h
index 0585864..f4135f2 100644
--- a/remoting/host/mock_objects.h
+++ b/remoting/host/mock_objects.h
@@ -61,9 +61,8 @@ class MockClientConnection : public ClientConnection {
MOCK_METHOD2(SendInitClientMessage, void(int width, int height));
MOCK_METHOD0(SendBeginUpdateStreamMessage, void());
- MOCK_METHOD2(SendUpdateStreamPacketMessage,
- void(const UpdateStreamPacketHeader* header,
- scoped_refptr<media::DataBuffer> data));
+ MOCK_METHOD1(SendUpdateStreamPacketMessage,
+ void(scoped_refptr<media::DataBuffer> data));
MOCK_METHOD0(SendEndUpdateStreamMessage, void());
MOCK_METHOD0(GetPendingUpdateStreamMessages, int());
diff --git a/remoting/host/session_manager.cc b/remoting/host/session_manager.cc
index 8e1dd86..5be8b56d 100644
--- a/remoting/host/session_manager.cc
+++ b/remoting/host/session_manager.cc
@@ -322,25 +322,26 @@ void SessionManager::DoRateControl() {
ScheduleNextRateControl();
}
-void SessionManager::DoSendUpdate(const UpdateStreamPacketHeader* header,
- const scoped_refptr<media::DataBuffer> data,
+void SessionManager::DoSendUpdate(HostMessage* message,
Encoder::EncodingState state) {
- // Take ownership of header.
- scoped_ptr<const UpdateStreamPacketHeader> header_owner(header);
DCHECK_EQ(network_loop_, MessageLoop::current());
+ // Create a data buffer in wire format from |message|.
+ scoped_refptr<media::DataBuffer> data =
+ ClientConnection::CreateWireFormatDataBuffer(message);
+
for (ClientConnectionList::const_iterator i = clients_.begin();
- i < clients_.end();
- ++i) {
+ i < clients_.end(); ++i) {
+ // TODO(hclam): Merge BeginUpdateStreamMessage into |message|.
if (state & Encoder::EncodingStarting) {
(*i)->SendBeginUpdateStreamMessage();
}
- (*i)->SendUpdateStreamPacketMessage(header, data);
+ (*i)->SendUpdateStreamPacketMessage(data);
- if (state & Encoder::EncodingEnded) {
+ // TODO(hclam): Merge EndUpdateStreamMessage into |message|.
+ if (state & Encoder::EncodingEnded)
(*i)->SendEndUpdateStreamMessage();
- }
}
}
@@ -390,9 +391,7 @@ void SessionManager::DoEncode(
}
void SessionManager::EncodeDataAvailableTask(
- const UpdateStreamPacketHeader *header,
- const scoped_refptr<media::DataBuffer>& data,
- Encoder::EncodingState state) {
+ HostMessage* message, Encoder::EncodingState state) {
DCHECK_EQ(encode_loop_, MessageLoop::current());
// Before a new encode task starts, notify clients a new update
@@ -401,11 +400,7 @@ void SessionManager::EncodeDataAvailableTask(
// task. The ownership will eventually pass to the ClientConnections.
network_loop_->PostTask(
FROM_HERE,
- NewRunnableMethod(this,
- &SessionManager::DoSendUpdate,
- header,
- data,
- state));
+ NewRunnableMethod(this, &SessionManager::DoSendUpdate, message, state));
if (state & Encoder::EncodingEnded) {
capture_loop_->PostTask(
diff --git a/remoting/host/session_manager.h b/remoting/host/session_manager.h
index b56564f..c2a2149 100644
--- a/remoting/host/session_manager.h
+++ b/remoting/host/session_manager.h
@@ -131,8 +131,7 @@ class SessionManager : public base::RefCountedThreadSafe<SessionManager> {
void DoRateControl();
// DoSendUpdate takes ownership of header and is responsible for deleting it.
- void DoSendUpdate(const UpdateStreamPacketHeader* header,
- const scoped_refptr<media::DataBuffer> data,
+ void DoSendUpdate(HostMessage* message,
Encoder::EncodingState state);
void DoSendInit(scoped_refptr<ClientConnection> client,
int width, int height);
@@ -147,8 +146,7 @@ class SessionManager : public base::RefCountedThreadSafe<SessionManager> {
// EncodeDataAvailableTask takes ownership of header and is responsible for
// deleting it.
- void EncodeDataAvailableTask(const UpdateStreamPacketHeader *header,
- const scoped_refptr<media::DataBuffer>& data,
+ void EncodeDataAvailableTask(HostMessage* message,
Encoder::EncodingState state);
// Message loops used by this class.
diff --git a/remoting/host/session_manager_unittest.cc b/remoting/host/session_manager_unittest.cc
index 5a4e4eb..e6d8114 100644
--- a/remoting/host/session_manager_unittest.cc
+++ b/remoting/host/session_manager_unittest.cc
@@ -58,18 +58,11 @@ ACTION_P2(RunCallback, rects, data) {
delete arg0;
}
-ACTION_P3(FinishDecode, rects, buffer, header) {
- gfx::Rect& rect = (*rects)[0];
+ACTION_P(FinishEncode, msg) {
Encoder::EncodingState state = (Encoder::EncodingStarting |
Encoder::EncodingInProgress |
Encoder::EncodingEnded);
- header->set_x(rect.x());
- header->set_y(rect.y());
- header->set_width(rect.width());
- header->set_height(rect.height());
- header->set_encoding(kEncoding);
- header->set_pixel_format(kFormat);
- arg2->Run(header, *buffer, state);
+ arg2->Run(msg, state);
}
ACTION_P(AssignCaptureData, data) {
@@ -111,15 +104,13 @@ TEST_F(SessionManagerTest, OneRecordCycle) {
.WillOnce(RunCallback(update_rects, data));
// Expect the encoder be called.
- scoped_refptr<media::DataBuffer> buffer = new media::DataBuffer(0);
- UpdateStreamPacketHeader *header = new UpdateStreamPacketHeader;
+ HostMessage* msg = new HostMessage();
EXPECT_CALL(*encoder_, Encode(data, false, NotNull()))
- .WillOnce(FinishDecode(&update_rects, &buffer, header));
+ .WillOnce(FinishEncode(msg));
// Expect the client be notified.
EXPECT_CALL(*client_, SendBeginUpdateStreamMessage());
-
- EXPECT_CALL(*client_, SendUpdateStreamPacketMessage(header ,buffer));
+ EXPECT_CALL(*client_, SendUpdateStreamPacketMessage(_));
EXPECT_CALL(*client_, SendEndUpdateStreamMessage());
EXPECT_CALL(*client_, GetPendingUpdateStreamMessages())
.Times(AtLeast(0))