Index: remoting/client/decoder_verbatim.cc |
diff --git a/remoting/client/decoder_verbatim.cc b/remoting/client/decoder_verbatim.cc |
index e9b88efdef4a5f16b44e7d122251267c90cb0d42..d27d265acbe6e694567eba1a7c44d37e831504d1 100644 |
--- a/remoting/client/decoder_verbatim.cc |
+++ b/remoting/client/decoder_verbatim.cc |
@@ -9,7 +9,13 @@ |
namespace remoting { |
DecoderVerbatim::DecoderVerbatim() |
- : updated_rects_(NULL), |
+ : state_(kWaitingForBeginRect), |
+ rect_x_(0), |
+ rect_y_(0), |
+ rect_width_(0), |
+ rect_height_(0), |
+ bytes_per_pixel_(0), |
+ updated_rects_(NULL), |
reverse_rows_(true) { |
} |
@@ -20,6 +26,7 @@ bool DecoderVerbatim::BeginDecode(scoped_refptr<media::VideoFrame> frame, |
DCHECK(!partial_decode_done_.get()); |
DCHECK(!decode_done_.get()); |
DCHECK(!updated_rects_); |
+ DCHECK_EQ(kWaitingForBeginRect, state_); |
partial_decode_done_.reset(partial_decode_done); |
decode_done_.reset(decode_done); |
@@ -33,54 +40,88 @@ bool DecoderVerbatim::BeginDecode(scoped_refptr<media::VideoFrame> frame, |
bool DecoderVerbatim::PartialDecode(HostMessage* message) { |
scoped_ptr<HostMessage> msg_deleter(message); |
+ DCHECK(message->has_update_stream_packet()); |
+ |
+ bool ret = true; |
+ if (message->update_stream_packet().has_begin_rect()) |
+ ret = HandleBeginRect(message); |
+ if (ret && message->update_stream_packet().has_rect_data()) |
+ ret = HandleRectData(message); |
+ if (ret && message->update_stream_packet().has_end_rect()) |
+ ret = HandleEndRect(message); |
+ return ret; |
+} |
+ |
+void DecoderVerbatim::EndDecode() { |
+ DCHECK_EQ(kWaitingForBeginRect, state_); |
+ decode_done_->Run(); |
+ |
+ partial_decode_done_.reset(); |
+ decode_done_.reset(); |
+ frame_ = NULL; |
+ updated_rects_ = NULL; |
+} |
+ |
+bool DecoderVerbatim::HandleBeginRect(HostMessage* message) { |
+ DCHECK_EQ(kWaitingForBeginRect, state_); |
+ state_ = kWaitingForRectData; |
+ |
+ rect_width_ = message->update_stream_packet().begin_rect().width(); |
+ rect_height_ = message->update_stream_packet().begin_rect().height(); |
+ rect_x_ = message->update_stream_packet().begin_rect().x(); |
+ rect_y_ = message->update_stream_packet().begin_rect().y(); |
- int width = message->update_stream_packet().header().width(); |
- int height = message->update_stream_packet().header().height(); |
- int x = message->update_stream_packet().header().x(); |
- int y = message->update_stream_packet().header().y(); |
PixelFormat pixel_format = |
- message->update_stream_packet().header().pixel_format(); |
+ message->update_stream_packet().begin_rect().pixel_format(); |
if (static_cast<PixelFormat>(frame_->format()) != pixel_format) { |
NOTREACHED() << "Pixel format of message doesn't match the video frame. " |
"Expected vs received = " |
<< frame_->format() << " vs " << pixel_format |
<< " Color space conversion required."; |
+ return false; |
} |
- int bytes_per_pixel = GetBytesPerPixel(pixel_format); |
+ bytes_per_pixel_ = GetBytesPerPixel(pixel_format); |
+ return true; |
+} |
+ |
+bool DecoderVerbatim::HandleRectData(HostMessage* message) { |
+ DCHECK_EQ(kWaitingForRectData, state_); |
+ DCHECK_EQ(0, |
+ message->update_stream_packet().rect_data().sequence_number()); |
+ |
// Copy the data line by line. |
- const int src_stride = bytes_per_pixel * width; |
- const char* src = message->update_stream_packet().data().c_str(); |
+ const int src_stride = bytes_per_pixel_ * rect_width_; |
+ const char* src = |
+ message->update_stream_packet().rect_data().data().c_str(); |
int src_stride_dir = src_stride; |
if (reverse_rows_) { |
// Copy rows from bottom to top to flip the image vertically. |
- src += (height - 1) * src_stride; |
+ src += (rect_height_ - 1) * src_stride; |
// Change the direction of the stride to work bottom to top. |
src_stride_dir *= -1; |
} |
const int dest_stride = frame_->stride(media::VideoFrame::kRGBPlane); |
uint8* dest = frame_->data(media::VideoFrame::kRGBPlane) + |
- dest_stride * y + bytes_per_pixel * x; |
- for (int i = 0; i < height; ++i) { |
+ dest_stride * rect_y_ + bytes_per_pixel_ * rect_x_; |
+ for (int i = 0; i < rect_height_; ++i) { |
memcpy(dest, src, src_stride); |
dest += dest_stride; |
src += src_stride_dir; |
} |
updated_rects_->clear(); |
- updated_rects_->push_back(gfx::Rect(x, y, width, height)); |
+ updated_rects_->push_back(gfx::Rect(rect_x_, rect_y_, |
+ rect_width_, rect_height_)); |
partial_decode_done_->Run(); |
return true; |
} |
-void DecoderVerbatim::EndDecode() { |
- decode_done_->Run(); |
- |
- partial_decode_done_.reset(); |
- decode_done_.reset(); |
- frame_ = NULL; |
- updated_rects_ = NULL; |
+bool DecoderVerbatim::HandleEndRect(HostMessage* message) { |
+ DCHECK_EQ(kWaitingForRectData, state_); |
+ state_ = kWaitingForBeginRect; |
+ return true; |
} |
} // namespace remoting |