diff options
Diffstat (limited to 'remoting/base')
-rw-r--r-- | remoting/base/decoder_vp8.cc | 34 | ||||
-rw-r--r-- | remoting/base/decoder_vp8.h | 5 | ||||
-rw-r--r-- | remoting/base/encoder_vp8.cc | 44 | ||||
-rw-r--r-- | remoting/base/encoder_vp8.h | 11 | ||||
-rw-r--r-- | remoting/base/util.cc | 70 | ||||
-rw-r--r-- | remoting/base/util.h | 29 |
6 files changed, 165 insertions, 28 deletions
diff --git a/remoting/base/decoder_vp8.cc b/remoting/base/decoder_vp8.cc index b150c4b..d7744a8 100644 --- a/remoting/base/decoder_vp8.cc +++ b/remoting/base/decoder_vp8.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -89,14 +89,38 @@ Decoder::DecodeResult DecoderVp8::DecodePacket(const VideoPacket* packet) { stride = -stride; } - media::ConvertYUVToRGB32(image->planes[0], image->planes[1], image->planes[2], - data_start, frame_->width(), frame_->height(), - image->stride[0], image->stride[1], stride, - media::YV12); + // Propogate updated rects. + updated_rects_.clear(); + for (int i = 0; i < packet->dirty_rects_size(); ++i) { + gfx::Rect r = gfx::Rect(packet->dirty_rects(i).x(), + packet->dirty_rects(i).y(), + packet->dirty_rects(i).width(), + packet->dirty_rects(i).height()); + + // Perform color space conversion only on the updated rectangle. + ConvertYUVToRGB32WithRect(image->planes[0], + image->planes[1], + image->planes[2], + data_start, + r.x(), + r.y(), + r.width(), + r.height(), + image->stride[0], + image->stride[1], + stride); + + // Since the image generated by client is upside-down we need to report + // updated rects as upside-down. + if (reverse_rows_) + r.set_y(image->d_h - r.bottom()); + updated_rects_.push_back(r); + } return DECODE_DONE; } void DecoderVp8::GetUpdatedRects(UpdatedRects* rects) { + rects->swap(updated_rects_); } void DecoderVp8::Reset() { diff --git a/remoting/base/decoder_vp8.h b/remoting/base/decoder_vp8.h index a59a601..6e15a0b 100644 --- a/remoting/base/decoder_vp8.h +++ b/remoting/base/decoder_vp8.h @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -42,6 +42,9 @@ class DecoderVp8 : public Decoder { vpx_codec_ctx_t* codec_; + // Record the updated rects in the last decode. + UpdatedRects updated_rects_; + DISALLOW_COPY_AND_ASSIGN(DecoderVp8); }; diff --git a/remoting/base/encoder_vp8.cc b/remoting/base/encoder_vp8.cc index 7ac75d3..fe12110 100644 --- a/remoting/base/encoder_vp8.cc +++ b/remoting/base/encoder_vp8.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -8,6 +8,7 @@ #include "media/base/callback.h" #include "media/base/yuv_convert.h" #include "remoting/base/capture_data.h" +#include "remoting/base/util.h" #include "remoting/proto/video.pb.h" extern "C" { @@ -94,7 +95,8 @@ static gfx::Rect AlignRect(const gfx::Rect& rect, int width, int height) { return r; } -bool EncoderVp8::PrepareImage(scoped_refptr<CaptureData> capture_data) { +bool EncoderVp8::PrepareImage(scoped_refptr<CaptureData> capture_data, + std::vector<gfx::Rect>* updated_rects) { const int plane_size = capture_data->width() * capture_data->height(); if (!yuv_image_.get()) { @@ -138,21 +140,23 @@ bool EncoderVp8::PrepareImage(scoped_refptr<CaptureData> capture_data) { const int y_stride = image_->stride[0]; const int uv_stride = image_->stride[1]; + DCHECK(updated_rects->empty()); for (InvalidRects::const_iterator r = rects.begin(); r != rects.end(); ++r) { + // Align the rectangle report it as updated. gfx::Rect rect = AlignRect(*r, image_->w, image_->h); - int in_offset = in_stride * rect.y() + 4 * rect.x(); - int y_offset = y_stride * rect.y() + rect.x(); - int uv_offset = (uv_stride * rect.y() + rect.x()) / 2; - - media::ConvertRGB32ToYUV(in + in_offset, - y_out + y_offset, - u_out + uv_offset, - v_out + uv_offset, - rect.width(), - rect.height(), - in_stride, - y_stride, - uv_stride); + updated_rects->push_back(rect); + + ConvertRGB32ToYUVWithRect(in, + y_out, + u_out, + v_out, + rect.x(), + rect.y(), + rect.width(), + rect.height(), + in_stride, + y_stride, + uv_stride); } return true; } @@ -167,7 +171,8 @@ void EncoderVp8::Encode(scoped_refptr<CaptureData> capture_data, initialized_ = ret; } - if (!PrepareImage(capture_data)) { + std::vector<gfx::Rect> updated_rects; + if (!PrepareImage(capture_data, &updated_rects)) { NOTREACHED() << "Can't image data for encoding"; } @@ -211,6 +216,13 @@ void EncoderVp8::Encode(scoped_refptr<CaptureData> capture_data, message->mutable_format()->set_encoding(VideoPacketFormat::ENCODING_VP8); message->set_flags(VideoPacket::FIRST_PACKET | VideoPacket::LAST_PACKET | VideoPacket::LAST_PARTITION); + for (size_t i = 0; i < updated_rects.size(); ++i) { + Rect* rect = message->add_dirty_rects(); + rect->set_x(updated_rects[i].x()); + rect->set_y(updated_rects[i].y()); + rect->set_width(updated_rects[i].width()); + rect->set_height(updated_rects[i].height()); + } data_available_callback->Run(message); delete data_available_callback; diff --git a/remoting/base/encoder_vp8.h b/remoting/base/encoder_vp8.h index 6c3357c..8a11cda 100644 --- a/remoting/base/encoder_vp8.h +++ b/remoting/base/encoder_vp8.h @@ -1,10 +1,13 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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_BASE_ENCODER_VP8_H_ #define REMOTING_BASE_ENCODER_VP8_H_ +#include <vector> + +#include "gfx/rect.h" #include "remoting/base/encoder.h" typedef struct vpx_codec_ctx vpx_codec_ctx_t; @@ -26,8 +29,10 @@ class EncoderVp8 : public Encoder { // Initialize the encoder. Returns true if successful. bool Init(int width, int height); - // Prepare |image_| for encoding. Returns true if successful. - bool PrepareImage(scoped_refptr<CaptureData> capture_data); + // Prepare |image_| for encoding. Write updated rectangles into + // |updated_rects|. Returns true if successful. + bool PrepareImage(scoped_refptr<CaptureData> capture_data, + std::vector<gfx::Rect>* updated_rects); // True if the encoder is initialized. bool initialized_; diff --git a/remoting/base/util.cc b/remoting/base/util.cc index 5cf70fe..9341050 100644 --- a/remoting/base/util.cc +++ b/remoting/base/util.cc @@ -1,7 +1,9 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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 "media/base/video_frame.h" +#include "media/base/yuv_convert.h" #include "remoting/base/util.h" #include "base/logging.h" @@ -25,4 +27,70 @@ int GetBytesPerPixel(VideoFrame::Format format) { } } +// Helper methods to calculate plane offset given the coordinates. +static int CalculateRGBOffset(int x, int y, int stride) { + return stride * y + GetBytesPerPixel(media::VideoFrame::RGB32) * x; +} + +static int CalculateYOffset(int x, int y, int stride) { + return stride * y + x; +} + +static int CalculateUVOffset(int x, int y, int stride) { + return stride * y / 2 + x / 2; +} + +void ConvertYUVToRGB32WithRect(const uint8* y_plane, + const uint8* u_plane, + const uint8* v_plane, + uint8* rgb_plane, + int x, + int y, + int width, + int height, + int y_stride, + int uv_stride, + int rgb_stride) { + int rgb_offset = CalculateRGBOffset(x, y, rgb_stride); + int y_offset = CalculateYOffset(x, y, y_stride); + int uv_offset = CalculateUVOffset(x, y, uv_stride);; + + media::ConvertYUVToRGB32(y_plane + y_offset, + u_plane + uv_offset, + v_plane + uv_offset, + rgb_plane + rgb_offset, + width, + height, + y_stride, + uv_stride, + rgb_stride, + media::YV12); +} + +void ConvertRGB32ToYUVWithRect(const uint8* rgb_plane, + uint8* y_plane, + uint8* u_plane, + uint8* v_plane, + int x, + int y, + int width, + int height, + int rgb_stride, + int y_stride, + int uv_stride) { + int rgb_offset = CalculateRGBOffset(x, y, rgb_stride); + int y_offset = CalculateYOffset(x, y, y_stride); + int uv_offset = CalculateUVOffset(x, y, uv_stride);; + + media::ConvertRGB32ToYUV(rgb_plane + rgb_offset, + y_plane + y_offset, + u_plane + uv_offset, + v_plane + uv_offset, + width, + height, + rgb_stride, + y_stride, + uv_stride); +} + } // namespace remoting diff --git a/remoting/base/util.h b/remoting/base/util.h index bf5cff5..51a8d10 100644 --- a/remoting/base/util.h +++ b/remoting/base/util.h @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -9,9 +9,34 @@ namespace remoting { -// TODO(sergeyu): Move this to media::VideoFrame. +// TODO(sergeyu): Move these methods to media. int GetBytesPerPixel(media::VideoFrame::Format format); +// Convert YUV to RGB32 on a specific rectangle. +void ConvertYUVToRGB32WithRect(const uint8* y_plane, + const uint8* u_plane, + const uint8* v_plane, + uint8* rgb_plane, + int x, + int y, + int width, + int height, + int y_stride, + int uv_stride, + int rgb_stride); + +void ConvertRGB32ToYUVWithRect(const uint8* rgb_plane, + uint8* y_plane, + uint8* u_plane, + uint8* v_plane, + int x, + int y, + int width, + int height, + int rgb_stride, + int y_stride, + int uv_stride); + } // namespace remoting #endif // REMOTING_BASE_UTIL_H_ |