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

Side by Side 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "remoting/codec/video_decoder_vp8.h" 5 #include "remoting/codec/video_decoder_vp8.h"
6 6
7 #include <math.h> 7 #include <math.h>
8 8
9 #include <algorithm>
10
9 #include "base/logging.h" 11 #include "base/logging.h"
10 #include "media/base/media.h" 12 #include "media/base/media.h"
11 #include "media/base/yuv_convert.h" 13 #include "media/base/yuv_convert.h"
12 #include "remoting/base/util.h" 14 #include "remoting/base/util.h"
13 15
14 extern "C" { 16 extern "C" {
15 #define VPX_CODEC_DISABLE_COMPAT 1 17 #define VPX_CODEC_DISABLE_COMPAT 1
16 #include "third_party/libvpx/source/libvpx/vpx/vpx_decoder.h" 18 #include "third_party/libvpx/source/libvpx/vpx/vpx_decoder.h"
17 #include "third_party/libvpx/source/libvpx/vpx/vp8dx.h" 19 #include "third_party/libvpx/source/libvpx/vpx/vp8dx.h"
18 } 20 }
19 21
20 namespace remoting { 22 namespace remoting {
21 23
24 enum { kBytesPerPixelRGB32 = 4 };
25
26 const uint32 kTransparent = 0;
27
22 VideoDecoderVp8::VideoDecoderVp8() 28 VideoDecoderVp8::VideoDecoderVp8()
23 : state_(kUninitialized), 29 : state_(kUninitialized),
24 codec_(NULL), 30 codec_(NULL),
25 last_image_(NULL), 31 last_image_(NULL),
26 screen_size_(SkISize::Make(0, 0)) { 32 screen_size_(SkISize::Make(0, 0)) {
27 } 33 }
28 34
29 VideoDecoderVp8::~VideoDecoderVp8() { 35 VideoDecoderVp8::~VideoDecoderVp8() {
30 if (codec_) { 36 if (codec_) {
31 vpx_codec_err_t ret = vpx_codec_destroy(codec_); 37 vpx_codec_err_t ret = vpx_codec_destroy(codec_);
32 CHECK(ret == VPX_CODEC_OK) << "Failed to destroy codec"; 38 CHECK(ret == VPX_CODEC_OK) << "Failed to destroy codec";
33 } 39 }
34 delete codec_; 40 delete codec_;
35 } 41 }
36 42
37 void VideoDecoderVp8::Initialize(const SkISize& screen_size) { 43 void VideoDecoderVp8::Initialize(const SkISize& screen_size) {
38 DCHECK(!screen_size.isEmpty()); 44 DCHECK(!screen_size.isEmpty());
39 45
40 screen_size_ = screen_size; 46 screen_size_ = screen_size;
41 state_ = kReady; 47 state_ = kReady;
48
49 transparent_region_.setRect(SkIRect::MakeSize(screen_size_));
42 } 50 }
43 51
44 VideoDecoder::DecodeResult VideoDecoderVp8::DecodePacket( 52 VideoDecoder::DecodeResult VideoDecoderVp8::DecodePacket(
45 const VideoPacket* packet) { 53 const VideoPacket* packet) {
46 DCHECK_EQ(kReady, state_); 54 DCHECK_EQ(kReady, state_);
47 55
48 // Initialize the codec as needed. 56 // Initialize the codec as needed.
49 if (!codec_) { 57 if (!codec_) {
50 codec_ = new vpx_codec_ctx_t(); 58 codec_ = new vpx_codec_ctx_t();
51 59
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
91 for (int i = 0; i < packet->dirty_rects_size(); ++i) { 99 for (int i = 0; i < packet->dirty_rects_size(); ++i) {
92 Rect remoting_rect = packet->dirty_rects(i); 100 Rect remoting_rect = packet->dirty_rects(i);
93 SkIRect rect = SkIRect::MakeXYWH(remoting_rect.x(), 101 SkIRect rect = SkIRect::MakeXYWH(remoting_rect.x(),
94 remoting_rect.y(), 102 remoting_rect.y(),
95 remoting_rect.width(), 103 remoting_rect.width(),
96 remoting_rect.height()); 104 remoting_rect.height());
97 region.op(rect, SkRegion::kUnion_Op); 105 region.op(rect, SkRegion::kUnion_Op);
98 } 106 }
99 107
100 updated_region_.op(region, SkRegion::kUnion_Op); 108 updated_region_.op(region, SkRegion::kUnion_Op);
109
110 // Update the desktop shape region.
111 SkRegion desktop_shape_region;
112 if (packet->has_use_desktop_shape()) {
113 for (int i = 0; i < packet->desktop_shape_rects_size(); ++i) {
114 Rect remoting_rect = packet->desktop_shape_rects(i);
115 SkIRect rect = SkIRect::MakeXYWH(remoting_rect.x(),
116 remoting_rect.y(),
117 remoting_rect.width(),
118 remoting_rect.height());
119 desktop_shape_region.op(rect, SkRegion::kUnion_Op);
120 }
121 } else {
122 // Fallback for the case when the host didn't include the desktop shape
123 // region.
124 desktop_shape_region = SkRegion(SkIRect::MakeSize(screen_size_));
125 }
126
127 UpdateDesktopShapeRegion(&desktop_shape_region);
128
101 return DECODE_DONE; 129 return DECODE_DONE;
102 } 130 }
103 131
104 bool VideoDecoderVp8::IsReadyForData() { 132 bool VideoDecoderVp8::IsReadyForData() {
105 return state_ == kReady; 133 return state_ == kReady;
106 } 134 }
107 135
108 VideoPacketFormat::Encoding VideoDecoderVp8::Encoding() { 136 VideoPacketFormat::Encoding VideoDecoderVp8::Encoding() {
109 return VideoPacketFormat::ENCODING_VP8; 137 return VideoPacketFormat::ENCODING_VP8;
110 } 138 }
111 139
112 void VideoDecoderVp8::Invalidate(const SkISize& view_size, 140 void VideoDecoderVp8::Invalidate(const SkISize& view_size,
113 const SkRegion& region) { 141 const SkRegion& region) {
114 DCHECK_EQ(kReady, state_); 142 DCHECK_EQ(kReady, state_);
115 DCHECK(!view_size.isEmpty()); 143 DCHECK(!view_size.isEmpty());
116 144
117 for (SkRegion::Iterator i(region); !i.done(); i.next()) { 145 for (SkRegion::Iterator i(region); !i.done(); i.next()) {
118 SkIRect rect = i.rect(); 146 SkIRect rect = i.rect();
119 rect = ScaleRect(rect, view_size, screen_size_); 147 rect = ScaleRect(rect, view_size, screen_size_);
120 updated_region_.op(rect, SkRegion::kUnion_Op); 148 updated_region_.op(rect, SkRegion::kUnion_Op);
121 } 149 }
150
151 // Updated areas outside of the new desktop shape region should be made
152 // transparent, not repainted.
153 SkRegion diff_region = updated_region_;
154 diff_region.op(desktop_shape_region_, SkRegion::kDifference_Op);
155 updated_region_.op(diff_region, SkRegion::kDifference_Op);
156 transparent_region_.op(diff_region, SkRegion::kUnion_Op);
122 } 157 }
123 158
124 void VideoDecoderVp8::RenderFrame(const SkISize& view_size, 159 void VideoDecoderVp8::RenderFrame(const SkISize& view_size,
125 const SkIRect& clip_area, 160 const SkIRect& clip_area,
126 uint8* image_buffer, 161 uint8* image_buffer,
127 int image_stride, 162 int image_stride,
128 SkRegion* output_region) { 163 SkRegion* output_region) {
129 DCHECK_EQ(kReady, state_); 164 DCHECK_EQ(kReady, state_);
130 DCHECK(!view_size.isEmpty()); 165 DCHECK(!view_size.isEmpty());
131 166
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
201 image_stride, 236 image_stride,
202 view_size, 237 view_size,
203 clip_area, 238 clip_area,
204 rect); 239 rect);
205 240
206 output_region->op(rect, SkRegion::kUnion_Op); 241 output_region->op(rect, SkRegion::kUnion_Op);
207 } 242 }
208 243
209 updated_region_.op(ScaleRect(clip_area, view_size, screen_size_), 244 updated_region_.op(ScaleRect(clip_area, view_size, screen_size_),
210 SkRegion::kDifference_Op); 245 SkRegion::kDifference_Op);
246
247 for (SkRegion::Iterator i(transparent_region_); !i.done(); i.next()) {
248 // Determine the scaled area affected by this rectangle changing.
249 SkIRect rect = i.rect();
250 if (!rect.intersect(source_clip))
251 continue;
252 rect = ScaleRect(rect, screen_size_, view_size);
253 if (!rect.intersect(clip_area))
254 continue;
255
256 // Fill the rectange with transparent pixels.
257 FillRect(image_buffer, image_stride, rect, kTransparent);
258 output_region->op(rect, SkRegion::kUnion_Op);
259 }
260
261 SkIRect scaled_clip_area = ScaleRect(clip_area, view_size, screen_size_);
262 updated_region_.op(scaled_clip_area, SkRegion::kDifference_Op);
263 transparent_region_.op(scaled_clip_area, SkRegion::kDifference_Op);
264 }
265
266 const SkRegion* VideoDecoderVp8::GetImageShape() {
267 return &desktop_shape_region_;
268 }
269
270 void VideoDecoderVp8::FillRect(uint8* buffer,
271 int stride,
272 const SkIRect& rect,
273 uint32 color) {
274 uint32* ptr = reinterpret_cast<uint32*>(buffer + (rect.top() * stride) +
275 (rect.left() * kBytesPerPixelRGB32));
276 int width = rect.width();
277 for (int height = rect.height(); height > 0; --height) {
278 std::fill(ptr, ptr + width, color);
279 ptr += stride / kBytesPerPixelRGB32;
280 }
281 }
282
283 void VideoDecoderVp8::UpdateDesktopShapeRegion(
284 SkRegion* new_desktop_shape_region) {
285 // Areas that previously were within the desktop shape region and now are
286 // outside of it should be made transparent.
287 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.
288 transparent_region_.op(*new_desktop_shape_region, SkRegion::kDifference_Op);
289
290 // Areas that previously were outside of the desktop shape region and now are
291 // within the region should be repainted.
292 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.
293 region.op(desktop_shape_region_, SkRegion::kDifference_Op);
294 updated_region_.op(region, SkRegion::kUnion_Op);
295
296 // Set the new desktop shape region.
297 desktop_shape_region_.swap(*new_desktop_shape_region);
298
299 // Updated areas outside of the new desktop shape region should be made
300 // transparent, not repainted.
301 region = updated_region_;
302 region.op(desktop_shape_region_, SkRegion::kDifference_Op);
303 updated_region_.op(region, SkRegion::kDifference_Op);
304 transparent_region_.op(region, SkRegion::kUnion_Op);
211 } 305 }
212 306
213 } // namespace remoting 307 } // namespace remoting
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698