Home | History | Annotate | Download | only in host
      1 // Copyright 2013 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/host/screen_capturer_fake.h"
      6 
      7 #include "base/logging.h"
      8 #include "base/time/time.h"
      9 #include "third_party/webrtc/modules/desktop_capture/desktop_frame.h"
     10 
     11 namespace remoting {
     12 
     13 // ScreenCapturerFake generates a white picture of size kWidth x kHeight
     14 // with a rectangle of size kBoxWidth x kBoxHeight. The rectangle moves kSpeed
     15 // pixels per frame along both axes, and bounces off the sides of the screen.
     16 static const int kWidth = ScreenCapturerFake::kWidth;
     17 static const int kHeight = ScreenCapturerFake::kHeight;
     18 static const int kBoxWidth = 140;
     19 static const int kBoxHeight = 140;
     20 static const int kSpeed = 20;
     21 
     22 COMPILE_ASSERT(kBoxWidth < kWidth && kBoxHeight < kHeight, bad_box_size);
     23 COMPILE_ASSERT((kBoxWidth % kSpeed == 0) && (kWidth % kSpeed == 0) &&
     24                (kBoxHeight % kSpeed == 0) && (kHeight % kSpeed == 0),
     25                sizes_must_be_multiple_of_kSpeed);
     26 
     27 ScreenCapturerFake::ScreenCapturerFake()
     28     : callback_(NULL),
     29       mouse_shape_observer_(NULL),
     30       bytes_per_row_(0),
     31       box_pos_x_(0),
     32       box_pos_y_(0),
     33       box_speed_x_(kSpeed),
     34       box_speed_y_(kSpeed) {
     35   ScreenConfigurationChanged();
     36 }
     37 
     38 ScreenCapturerFake::~ScreenCapturerFake() {
     39 }
     40 
     41 void ScreenCapturerFake::Start(Callback* callback) {
     42   DCHECK(!callback_);
     43   DCHECK(callback);
     44   callback_ = callback;
     45 }
     46 
     47 void ScreenCapturerFake::Capture(const webrtc::DesktopRegion& region) {
     48   base::Time capture_start_time = base::Time::Now();
     49 
     50   queue_.MoveToNextFrame();
     51 
     52   if (!queue_.current_frame()) {
     53     int buffer_size = size_.height() * bytes_per_row_;
     54     webrtc::SharedMemory* shared_memory =
     55         callback_->CreateSharedMemory(buffer_size);
     56     scoped_ptr<webrtc::DesktopFrame> frame;
     57     webrtc::DesktopSize frame_size(size_.width(), size_.height());
     58     if (shared_memory) {
     59       frame.reset(new webrtc::SharedMemoryDesktopFrame(
     60           frame_size, bytes_per_row_, shared_memory));
     61     } else {
     62       frame.reset(new webrtc::BasicDesktopFrame(frame_size));
     63     }
     64     queue_.ReplaceCurrentFrame(frame.release());
     65   }
     66 
     67   DCHECK(queue_.current_frame());
     68   GenerateImage();
     69 
     70   queue_.current_frame()->mutable_updated_region()->SetRect(
     71       webrtc::DesktopRect::MakeSize(size_));
     72   queue_.current_frame()->set_capture_time_ms(
     73       (base::Time::Now() - capture_start_time).InMillisecondsRoundedUp());
     74 
     75   callback_->OnCaptureCompleted(queue_.current_frame()->Share());
     76 }
     77 
     78 void ScreenCapturerFake::SetMouseShapeObserver(
     79       MouseShapeObserver* mouse_shape_observer) {
     80   DCHECK(!mouse_shape_observer_);
     81   DCHECK(mouse_shape_observer);
     82   mouse_shape_observer_ = mouse_shape_observer;
     83 }
     84 
     85 bool ScreenCapturerFake::GetScreenList(ScreenList* screens) {
     86   NOTIMPLEMENTED();
     87   return false;
     88 }
     89 
     90 bool ScreenCapturerFake::SelectScreen(webrtc::ScreenId id) {
     91   NOTIMPLEMENTED();
     92   return false;
     93 }
     94 
     95 void ScreenCapturerFake::GenerateImage() {
     96   webrtc::DesktopFrame* frame = queue_.current_frame();
     97 
     98   const int kBytesPerPixel = webrtc::DesktopFrame::kBytesPerPixel;
     99 
    100   memset(frame->data(), 0xff,
    101          size_.width() * size_.height() * kBytesPerPixel);
    102 
    103   uint8* row = frame->data() +
    104       (box_pos_y_ * size_.width() + box_pos_x_) * kBytesPerPixel;
    105 
    106   box_pos_x_ += box_speed_x_;
    107   if (box_pos_x_ + kBoxWidth >= size_.width() || box_pos_x_ == 0)
    108     box_speed_x_ = -box_speed_x_;
    109 
    110   box_pos_y_ += box_speed_y_;
    111   if (box_pos_y_ + kBoxHeight >= size_.height() || box_pos_y_ == 0)
    112     box_speed_y_ = -box_speed_y_;
    113 
    114   // Draw rectangle with the following colors in its corners:
    115   //     cyan....yellow
    116   //     ..............
    117   //     blue.......red
    118   for (int y = 0; y < kBoxHeight; ++y) {
    119     for (int x = 0; x < kBoxWidth; ++x) {
    120       int r = x * 255 / kBoxWidth;
    121       int g = y * 255 / kBoxHeight;
    122       int b = 255 - (x * 255 / kBoxWidth);
    123       row[x * kBytesPerPixel] = r;
    124       row[x * kBytesPerPixel + 1] = g;
    125       row[x * kBytesPerPixel + 2] = b;
    126       row[x * kBytesPerPixel + 3] = 0xff;
    127     }
    128     row += bytes_per_row_;
    129   }
    130 }
    131 
    132 void ScreenCapturerFake::ScreenConfigurationChanged() {
    133   size_.set(kWidth, kHeight);
    134   queue_.Reset();
    135   bytes_per_row_ = size_.width() * webrtc::DesktopFrame::kBytesPerPixel;
    136 }
    137 
    138 }  // namespace remoting
    139