diff options
Diffstat (limited to 'remoting/client/decoder_verbatim.cc')
-rw-r--r-- | remoting/client/decoder_verbatim.cc | 81 |
1 files changed, 61 insertions, 20 deletions
diff --git a/remoting/client/decoder_verbatim.cc b/remoting/client/decoder_verbatim.cc index e9b88ef..d27d265 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 |