• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
4 
5 #include "remoting/codec/video_decoder_verbatim.h"
6 
7 #include "base/logging.h"
8 #include "remoting/base/util.h"
9 
10 namespace remoting {
11 
VideoDecoderVerbatim()12 VideoDecoderVerbatim::VideoDecoderVerbatim() {}
13 
~VideoDecoderVerbatim()14 VideoDecoderVerbatim::~VideoDecoderVerbatim() {}
15 
Initialize(const webrtc::DesktopSize & screen_size)16 void VideoDecoderVerbatim::Initialize(const webrtc::DesktopSize& screen_size) {
17   updated_region_.Clear();
18   screen_buffer_.reset();
19 
20   screen_size_ = screen_size;
21   // Allocate the screen buffer, if necessary.
22   if (!screen_size_.is_empty()) {
23     screen_buffer_.reset(
24         new uint8[screen_size_.width() * screen_size_.height() *
25                   kBytesPerPixel]);
26   }
27 }
28 
DecodePacket(const VideoPacket & packet)29 bool VideoDecoderVerbatim::DecodePacket(const VideoPacket& packet) {
30   webrtc::DesktopRegion region;
31 
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(),
38                                       proto_rect.y(),
39                                       proto_rect.width(),
40                                       proto_rect.height());
41     region.AddRect(rect);
42 
43     if (!DoesRectContain(webrtc::DesktopRect::MakeSize(screen_size_), rect)) {
44       LOG(ERROR) << "Invalid packet received";
45       return false;
46     }
47 
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";
54         return false;
55       }
56       memcpy(out, in, rect_row_size);
57       in += rect_row_size;
58       out += stride;
59     }
60   }
61 
62   if (in != packet.data().data() + packet.data().size()) {
63     LOG(ERROR) << "Invalid packet received";
64     return false;
65   }
66 
67   updated_region_.AddRegion(region);
68 
69   return true;
70 }
71 
Invalidate(const webrtc::DesktopSize & view_size,const webrtc::DesktopRegion & region)72 void VideoDecoderVerbatim::Invalidate(const webrtc::DesktopSize& view_size,
73                                       const webrtc::DesktopRegion& region) {
74   updated_region_.AddRegion(region);
75 }
76 
RenderFrame(const webrtc::DesktopSize & view_size,const webrtc::DesktopRect & clip_area,uint8 * image_buffer,int image_stride,webrtc::DesktopRegion * output_region)77 void VideoDecoderVerbatim::RenderFrame(const webrtc::DesktopSize& view_size,
78                                        const webrtc::DesktopRect& clip_area,
79                                        uint8* image_buffer,
80                                        int image_stride,
81                                        webrtc::DesktopRegion* output_region) {
82   output_region->Clear();
83 
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())
88     return;
89 
90   int screen_stride = screen_size_.width() * kBytesPerPixel;
91 
92   for (webrtc::DesktopRegion::Iterator i(updated_region_);
93        !i.IsAtEnd(); i.Advance()) {
94     webrtc::DesktopRect rect(i.rect());
95     rect.IntersectWith(clip_rect);
96     if (rect.is_empty())
97       continue;
98 
99     CopyRGB32Rect(screen_buffer_.get(), screen_stride,
100                   clip_rect,
101                   image_buffer, image_stride,
102                   clip_area,
103                   rect);
104     output_region->AddRect(rect);
105   }
106 
107   updated_region_.Clear();
108 }
109 
GetImageShape()110 const webrtc::DesktopRegion* VideoDecoderVerbatim::GetImageShape() {
111   return NULL;
112 }
113 
114 }  // namespace remoting
115