1// Copyright 2014 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_encoder_helper.h"
6
7#include "remoting/proto/video.pb.h"
8#include "third_party/webrtc/modules/desktop_capture/desktop_frame.h"
9#include "third_party/webrtc/modules/desktop_capture/desktop_geometry.h"
10#include "third_party/webrtc/modules/desktop_capture/desktop_region.h"
11
12namespace remoting {
13
14VideoEncoderHelper::VideoEncoderHelper() {}
15
16scoped_ptr<VideoPacket> VideoEncoderHelper::CreateVideoPacket(
17    const webrtc::DesktopFrame& frame) {
18  return CreateVideoPacketWithUpdatedRegion(frame, frame.updated_region());
19}
20
21scoped_ptr<VideoPacket>
22VideoEncoderHelper::CreateVideoPacketWithUpdatedRegion(
23    const webrtc::DesktopFrame& frame,
24    const webrtc::DesktopRegion& updated_region) {
25  scoped_ptr<VideoPacket> packet(new VideoPacket());
26
27  // Set |screen_width| and |screen_height| iff they have changed.
28  if (!frame.size().equals(screen_size_)) {
29    screen_size_ = frame.size();
30
31    VideoPacketFormat* format = packet->mutable_format();
32    format->set_screen_width(screen_size_.width());
33    format->set_screen_height(screen_size_.height());
34  }
35
36  // Record the list of changed rectangles.
37  for (webrtc::DesktopRegion::Iterator iter(updated_region);
38       !iter.IsAtEnd(); iter.Advance()) {
39    const webrtc::DesktopRect& rect = iter.rect();
40    Rect* dirty_rect = packet->add_dirty_rects();
41    dirty_rect->set_x(rect.left());
42    dirty_rect->set_y(rect.top());
43    dirty_rect->set_width(rect.width());
44    dirty_rect->set_height(rect.height());
45  }
46
47  // Record the shape of the frame, if specified.
48  if (frame.shape()) {
49    packet->set_use_desktop_shape(true);
50    for (webrtc::DesktopRegion::Iterator r(*frame.shape());
51         !r.IsAtEnd(); r.Advance()) {
52      Rect* rect = packet->add_desktop_shape_rects();
53      rect->set_x(r.rect().left());
54      rect->set_y(r.rect().top());
55      rect->set_width(r.rect().width());
56      rect->set_height(r.rect().height());
57    }
58  }
59
60  // Store the capture time and frame DPI.
61  packet->set_capture_time_ms(frame.capture_time_ms());
62  if (!frame.dpi().is_zero()) {
63    packet->mutable_format()->set_x_dpi(frame.dpi().x());
64    packet->mutable_format()->set_y_dpi(frame.dpi().y());
65  }
66
67  return packet.Pass();
68}
69
70}  // namespace remoting
71