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