summaryrefslogtreecommitdiffstats
path: root/remoting/base
diff options
context:
space:
mode:
Diffstat (limited to 'remoting/base')
-rw-r--r--remoting/base/decoder_vp8.cc34
-rw-r--r--remoting/base/decoder_vp8.h5
-rw-r--r--remoting/base/encoder_vp8.cc44
-rw-r--r--remoting/base/encoder_vp8.h11
-rw-r--r--remoting/base/util.cc70
-rw-r--r--remoting/base/util.h29
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_