OLD | NEW |
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_verbatim.h" | 5 #include "remoting/codec/video_decoder_verbatim.h" |
6 | 6 |
7 #include "base/logging.h" | 7 #include "base/logging.h" |
8 #include "remoting/base/util.h" | 8 #include "remoting/base/util.h" |
9 | 9 |
10 namespace remoting { | 10 namespace remoting { |
11 | 11 |
12 namespace { | 12 namespace { |
13 // Both input and output data are assumed to be RGBA32. | 13 // Both input and output data are assumed to be RGBA32. |
14 const int kBytesPerPixel = 4; | 14 const int kBytesPerPixel = 4; |
15 } // namespace | 15 } // namespace |
16 | 16 |
17 VideoDecoderVerbatim::VideoDecoderVerbatim() {} | 17 VideoDecoderVerbatim::VideoDecoderVerbatim() |
| 18 : screen_size_(SkISize::Make(0, 0)) {} |
18 | 19 |
19 VideoDecoderVerbatim::~VideoDecoderVerbatim() {} | 20 VideoDecoderVerbatim::~VideoDecoderVerbatim() {} |
20 | 21 |
21 bool VideoDecoderVerbatim::IsReadyForData() { | 22 bool VideoDecoderVerbatim::IsReadyForData() { |
22 return true; | 23 return true; |
23 } | 24 } |
24 | 25 |
25 void VideoDecoderVerbatim::Initialize(const webrtc::DesktopSize& screen_size) { | 26 void VideoDecoderVerbatim::Initialize(const SkISize& screen_size) { |
26 updated_region_.Clear(); | 27 updated_region_.setEmpty(); |
27 screen_buffer_.reset(); | 28 screen_buffer_.reset(); |
28 | 29 |
29 screen_size_ = screen_size; | 30 screen_size_ = screen_size; |
30 // Allocate the screen buffer, if necessary. | 31 // Allocate the screen buffer, if necessary. |
31 if (!screen_size_.is_empty()) { | 32 if (!screen_size_.isEmpty()) { |
32 screen_buffer_.reset( | 33 screen_buffer_.reset( |
33 new uint8 | 34 new uint8 |
34 [screen_size_.width() * screen_size_.height() * kBytesPerPixel]); | 35 [screen_size_.width() * screen_size_.height() * kBytesPerPixel]); |
35 } | 36 } |
36 } | 37 } |
37 | 38 |
38 VideoDecoder::DecodeResult VideoDecoderVerbatim::DecodePacket( | 39 VideoDecoder::DecodeResult VideoDecoderVerbatim::DecodePacket( |
39 const VideoPacket* packet) { | 40 const VideoPacket* packet) { |
40 webrtc::DesktopRegion region; | 41 SkRegion region; |
41 | 42 |
42 const char* in = packet->data().data(); | 43 const char* in = packet->data().data(); |
43 int stride = kBytesPerPixel * screen_size_.width(); | 44 int stride = kBytesPerPixel * screen_size_.width(); |
44 for (int i = 0; i < packet->dirty_rects_size(); ++i) { | 45 for (int i = 0; i < packet->dirty_rects_size(); ++i) { |
45 Rect proto_rect = packet->dirty_rects(i); | 46 Rect proto_rect = packet->dirty_rects(i); |
46 webrtc::DesktopRect rect = | 47 SkIRect rect = SkIRect::MakeXYWH(proto_rect.x(), |
47 webrtc::DesktopRect::MakeXYWH(proto_rect.x(), proto_rect.y(), | 48 proto_rect.y(), |
48 proto_rect.width(), proto_rect.height()); | 49 proto_rect.width(), |
49 region.AddRect(rect); | 50 proto_rect.height()); |
| 51 region.op(rect, SkRegion::kUnion_Op); |
50 | 52 |
51 if (!DoesRectContain(webrtc::DesktopRect::MakeSize(screen_size_), rect)) { | 53 if (!SkIRect::MakeSize(screen_size_).contains(rect)) { |
52 LOG(ERROR) << "Invalid packet received"; | 54 LOG(ERROR) << "Invalid packet received"; |
53 return DECODE_ERROR; | 55 return DECODE_ERROR; |
54 } | 56 } |
55 | 57 |
56 int rect_row_size = kBytesPerPixel * rect.width(); | 58 int rect_row_size = kBytesPerPixel * rect.width(); |
57 uint8_t* out = screen_buffer_.get() + rect.top() * stride + | 59 uint8_t* out = screen_buffer_.get() + rect.y() * stride + |
58 rect.left() * kBytesPerPixel; | 60 rect.x() * kBytesPerPixel; |
59 for (int y = rect.top(); y < rect.top() + rect.height(); ++y) { | 61 for (int y = rect.y(); y < rect.y() + rect.height(); ++y) { |
60 if (in + rect_row_size > packet->data().data() + packet->data().size()) { | 62 if (in + rect_row_size > packet->data().data() + packet->data().size()) { |
61 LOG(ERROR) << "Invalid packet received"; | 63 LOG(ERROR) << "Invalid packet received"; |
62 return DECODE_ERROR; | 64 return DECODE_ERROR; |
63 } | 65 } |
64 memcpy(out, in, rect_row_size); | 66 memcpy(out, in, rect_row_size); |
65 in += rect_row_size; | 67 in += rect_row_size; |
66 out += stride; | 68 out += stride; |
67 } | 69 } |
68 } | 70 } |
69 | 71 |
70 if (in != packet->data().data() + packet->data().size()) { | 72 if (in != packet->data().data() + packet->data().size()) { |
71 LOG(ERROR) << "Invalid packet received"; | 73 LOG(ERROR) << "Invalid packet received"; |
72 return DECODE_ERROR; | 74 return DECODE_ERROR; |
73 } | 75 } |
74 | 76 |
75 updated_region_.AddRegion(region); | 77 updated_region_.op(region, SkRegion::kUnion_Op); |
76 | 78 |
77 return DECODE_DONE; | 79 return DECODE_DONE; |
78 } | 80 } |
79 | 81 |
80 VideoPacketFormat::Encoding VideoDecoderVerbatim::Encoding() { | 82 VideoPacketFormat::Encoding VideoDecoderVerbatim::Encoding() { |
81 return VideoPacketFormat::ENCODING_VERBATIM; | 83 return VideoPacketFormat::ENCODING_VERBATIM; |
82 } | 84 } |
83 | 85 |
84 void VideoDecoderVerbatim::Invalidate(const webrtc::DesktopSize& view_size, | 86 void VideoDecoderVerbatim::Invalidate(const SkISize& view_size, |
85 const webrtc::DesktopRegion& region) { | 87 const SkRegion& region) { |
86 updated_region_.AddRegion(region); | 88 updated_region_.op(region, SkRegion::kUnion_Op); |
87 } | 89 } |
88 | 90 |
89 void VideoDecoderVerbatim::RenderFrame(const webrtc::DesktopSize& view_size, | 91 void VideoDecoderVerbatim::RenderFrame(const SkISize& view_size, |
90 const webrtc::DesktopRect& clip_area, | 92 const SkIRect& clip_area, |
91 uint8* image_buffer, | 93 uint8* image_buffer, |
92 int image_stride, | 94 int image_stride, |
93 webrtc::DesktopRegion* output_region) { | 95 SkRegion* output_region) { |
94 output_region->Clear(); | 96 output_region->setEmpty(); |
95 | 97 |
96 // TODO(alexeypa): scaling is not implemented. | 98 // TODO(alexeypa): scaling is not implemented. |
97 webrtc::DesktopRect clip_rect = webrtc::DesktopRect::MakeSize(screen_size_); | 99 SkIRect clip_rect = SkIRect::MakeSize(screen_size_); |
98 clip_rect.IntersectWith(clip_area); | 100 if (!clip_rect.intersect(clip_area)) |
99 if (clip_rect.is_empty()) | |
100 return; | 101 return; |
101 | 102 |
102 int screen_stride = screen_size_.width() * kBytesPerPixel; | 103 int screen_stride = screen_size_.width() * kBytesPerPixel; |
103 | 104 |
104 for (webrtc::DesktopRegion::Iterator i(updated_region_); | 105 for (SkRegion::Iterator i(updated_region_); !i.done(); i.next()) { |
105 !i.IsAtEnd(); i.Advance()) { | 106 SkIRect rect(i.rect()); |
106 webrtc::DesktopRect rect(i.rect()); | 107 if (!rect.intersect(clip_rect)) |
107 rect.IntersectWith(clip_rect); | |
108 if (rect.is_empty()) | |
109 continue; | 108 continue; |
110 | 109 |
111 CopyRGB32Rect(screen_buffer_.get(), screen_stride, | 110 CopyRGB32Rect(screen_buffer_.get(), screen_stride, |
112 clip_rect, | 111 clip_rect, |
113 image_buffer, image_stride, | 112 image_buffer, image_stride, |
114 clip_area, | 113 clip_area, |
115 rect); | 114 rect); |
116 output_region->AddRect(rect); | 115 output_region->op(rect, SkRegion::kUnion_Op); |
117 } | 116 } |
118 | 117 |
119 updated_region_.Clear(); | 118 updated_region_.setEmpty(); |
120 } | 119 } |
121 | 120 |
122 const webrtc::DesktopRegion* VideoDecoderVerbatim::GetImageShape() { | 121 const SkRegion* VideoDecoderVerbatim::GetImageShape() { |
123 return NULL; | 122 return NULL; |
124 } | 123 } |
125 | 124 |
126 } // namespace remoting | 125 } // namespace remoting |
OLD | NEW |