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
3 // found in the LICENSE file.
5 #include "remoting/codec/video_decoder_verbatim.h"
7 #include "base/logging.h"
8 #include "remoting/base/util.h"
12 VideoDecoderVerbatim::VideoDecoderVerbatim() {}
14 VideoDecoderVerbatim::~VideoDecoderVerbatim() {}
16 bool VideoDecoderVerbatim::DecodePacket(const VideoPacket
& packet
) {
17 if (packet
.format().has_screen_width() &&
18 packet
.format().has_screen_height()) {
19 webrtc::DesktopSize
screen_size(packet
.format().screen_width(),
20 packet
.format().screen_height());
21 // Allocate the screen buffer, if necessary.
22 if (!screen_size
.equals(screen_size_
)) {
23 screen_size_
= screen_size
;
24 screen_buffer_
.reset(new uint8
[screen_size_
.width() *
25 screen_size_
.height() * kBytesPerPixel
]);
26 updated_region_
.Clear();
30 webrtc::DesktopRegion region
;
32 const char* in
= packet
.data().data();
33 int stride
= kBytesPerPixel
* screen_size_
.width();
34 for (int i
= 0; i
< packet
.dirty_rects_size(); ++i
) {
35 Rect proto_rect
= packet
.dirty_rects(i
);
36 webrtc::DesktopRect rect
=
37 webrtc::DesktopRect::MakeXYWH(proto_rect
.x(),
43 if (!DoesRectContain(webrtc::DesktopRect::MakeSize(screen_size_
), rect
)) {
44 LOG(ERROR
) << "Invalid packet received";
48 int rect_row_size
= kBytesPerPixel
* rect
.width();
49 uint8_t* out
= screen_buffer_
.get() + rect
.top() * stride
+
50 rect
.left() * kBytesPerPixel
;
51 for (int y
= rect
.top(); y
< rect
.top() + rect
.height(); ++y
) {
52 if (in
+ rect_row_size
> packet
.data().data() + packet
.data().size()) {
53 LOG(ERROR
) << "Invalid packet received";
56 memcpy(out
, in
, rect_row_size
);
62 if (in
!= packet
.data().data() + packet
.data().size()) {
63 LOG(ERROR
) << "Invalid packet received";
67 updated_region_
.AddRegion(region
);
72 void VideoDecoderVerbatim::Invalidate(const webrtc::DesktopSize
& view_size
,
73 const webrtc::DesktopRegion
& region
) {
74 updated_region_
.AddRegion(region
);
77 void VideoDecoderVerbatim::RenderFrame(const webrtc::DesktopSize
& view_size
,
78 const webrtc::DesktopRect
& clip_area
,
81 webrtc::DesktopRegion
* output_region
) {
82 output_region
->Clear();
84 // TODO(alexeypa): scaling is not implemented.
85 webrtc::DesktopRect clip_rect
= webrtc::DesktopRect::MakeSize(screen_size_
);
86 clip_rect
.IntersectWith(clip_area
);
87 if (clip_rect
.is_empty())
90 int screen_stride
= screen_size_
.width() * kBytesPerPixel
;
92 for (webrtc::DesktopRegion::Iterator
i(updated_region_
);
93 !i
.IsAtEnd(); i
.Advance()) {
94 webrtc::DesktopRect
rect(i
.rect());
95 rect
.IntersectWith(clip_rect
);
99 CopyRGB32Rect(screen_buffer_
.get(), screen_stride
,
101 image_buffer
, image_stride
,
104 output_region
->AddRect(rect
);
107 updated_region_
.Clear();
110 const webrtc::DesktopRegion
* VideoDecoderVerbatim::GetImageShape() {
114 } // namespace remoting