Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(601)

Unified Diff: remoting/codec/video_decoder_vp8.cc

Issue 17511004: Added the desktop shape fields to VideoPacket. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: remoting/codec/video_decoder_vp8.cc
diff --git a/remoting/codec/video_decoder_vp8.cc b/remoting/codec/video_decoder_vp8.cc
index d87154214ab10fd1c2ed5c31763c7e0dd8a6293c..d92aab44927775db8ac226a5422b7462c16b0015 100644
--- a/remoting/codec/video_decoder_vp8.cc
+++ b/remoting/codec/video_decoder_vp8.cc
@@ -6,6 +6,8 @@
#include <math.h>
+#include <algorithm>
+
#include "base/logging.h"
#include "media/base/media.h"
#include "media/base/yuv_convert.h"
@@ -19,6 +21,10 @@ extern "C" {
namespace remoting {
+enum { kBytesPerPixelRGB32 = 4 };
+
+const uint32 kTransparent = 0;
+
VideoDecoderVp8::VideoDecoderVp8()
: state_(kUninitialized),
codec_(NULL),
@@ -39,6 +45,8 @@ void VideoDecoderVp8::Initialize(const SkISize& screen_size) {
screen_size_ = screen_size;
state_ = kReady;
+
+ transparent_region_.setRect(SkIRect::MakeSize(screen_size_));
}
VideoDecoder::DecodeResult VideoDecoderVp8::DecodePacket(
@@ -98,6 +106,26 @@ VideoDecoder::DecodeResult VideoDecoderVp8::DecodePacket(
}
updated_region_.op(region, SkRegion::kUnion_Op);
+
+ // Update the desktop shape region.
+ SkRegion desktop_shape_region;
+ if (packet->has_use_desktop_shape()) {
+ for (int i = 0; i < packet->desktop_shape_rects_size(); ++i) {
+ Rect remoting_rect = packet->desktop_shape_rects(i);
+ SkIRect rect = SkIRect::MakeXYWH(remoting_rect.x(),
+ remoting_rect.y(),
+ remoting_rect.width(),
+ remoting_rect.height());
+ desktop_shape_region.op(rect, SkRegion::kUnion_Op);
+ }
+ } else {
+ // Fallback for the case when the host didn't include the desktop shape
+ // region.
+ desktop_shape_region = SkRegion(SkIRect::MakeSize(screen_size_));
+ }
+
+ UpdateDesktopShapeRegion(&desktop_shape_region);
+
return DECODE_DONE;
}
@@ -119,6 +147,13 @@ void VideoDecoderVp8::Invalidate(const SkISize& view_size,
rect = ScaleRect(rect, view_size, screen_size_);
updated_region_.op(rect, SkRegion::kUnion_Op);
}
+
+ // Updated areas outside of the new desktop shape region should be made
+ // transparent, not repainted.
+ SkRegion diff_region = updated_region_;
+ diff_region.op(desktop_shape_region_, SkRegion::kDifference_Op);
+ updated_region_.op(diff_region, SkRegion::kDifference_Op);
+ transparent_region_.op(diff_region, SkRegion::kUnion_Op);
}
void VideoDecoderVp8::RenderFrame(const SkISize& view_size,
@@ -208,6 +243,65 @@ void VideoDecoderVp8::RenderFrame(const SkISize& view_size,
updated_region_.op(ScaleRect(clip_area, view_size, screen_size_),
SkRegion::kDifference_Op);
+
+ for (SkRegion::Iterator i(transparent_region_); !i.done(); i.next()) {
+ // Determine the scaled area affected by this rectangle changing.
+ SkIRect rect = i.rect();
+ if (!rect.intersect(source_clip))
+ continue;
+ rect = ScaleRect(rect, screen_size_, view_size);
+ if (!rect.intersect(clip_area))
+ continue;
+
+ // Fill the rectange with transparent pixels.
+ FillRect(image_buffer, image_stride, rect, kTransparent);
+ output_region->op(rect, SkRegion::kUnion_Op);
+ }
+
+ SkIRect scaled_clip_area = ScaleRect(clip_area, view_size, screen_size_);
+ updated_region_.op(scaled_clip_area, SkRegion::kDifference_Op);
+ transparent_region_.op(scaled_clip_area, SkRegion::kDifference_Op);
+}
+
+const SkRegion* VideoDecoderVp8::GetImageShape() {
+ return &desktop_shape_region_;
+}
+
+void VideoDecoderVp8::FillRect(uint8* buffer,
+ int stride,
+ const SkIRect& rect,
+ uint32 color) {
+ uint32* ptr = reinterpret_cast<uint32*>(buffer + (rect.top() * stride) +
+ (rect.left() * kBytesPerPixelRGB32));
+ int width = rect.width();
+ for (int height = rect.height(); height > 0; --height) {
+ std::fill(ptr, ptr + width, color);
+ ptr += stride / kBytesPerPixelRGB32;
+ }
+}
+
+void VideoDecoderVp8::UpdateDesktopShapeRegion(
+ SkRegion* new_desktop_shape_region) {
+ // Areas that previously were within the desktop shape region and now are
+ // outside of it should be made transparent.
+ transparent_region_.op(desktop_shape_region_, SkRegion::kUnion_Op);
Jamie 2013/06/20 21:15:57 It took me a while to understand what was going on
alexeypa (please no reviews) 2013/06/20 22:05:11 Done.
+ transparent_region_.op(*new_desktop_shape_region, SkRegion::kDifference_Op);
+
+ // Areas that previously were outside of the desktop shape region and now are
+ // within the region should be repainted.
+ SkRegion region = *new_desktop_shape_region;
Jamie 2013/06/20 21:15:57 Can you use a more descriptive name for this? Mayb
alexeypa (please no reviews) 2013/06/20 22:05:11 Done.
+ region.op(desktop_shape_region_, SkRegion::kDifference_Op);
+ updated_region_.op(region, SkRegion::kUnion_Op);
+
+ // Set the new desktop shape region.
+ desktop_shape_region_.swap(*new_desktop_shape_region);
+
+ // Updated areas outside of the new desktop shape region should be made
+ // transparent, not repainted.
+ region = updated_region_;
+ region.op(desktop_shape_region_, SkRegion::kDifference_Op);
+ updated_region_.op(region, SkRegion::kDifference_Op);
+ transparent_region_.op(region, SkRegion::kUnion_Op);
}
} // namespace remoting

Powered by Google App Engine
This is Rietveld 408576698