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 void ScreenCapturerFake::GenerateImage() {
     86   webrtc::DesktopFrame* frame = queue_.current_frame();
     87 
     88   const int kBytesPerPixel = webrtc::DesktopFrame::kBytesPerPixel;
     89 
     90   memset(frame->data(), 0xff,
     91          size_.width() * size_.height() * kBytesPerPixel);
     92 
     93   uint8* row = frame->data() +
     94       (box_pos_y_ * size_.width() + box_pos_x_) * kBytesPerPixel;
     95 
     96   box_pos_x_ += box_speed_x_;
     97   if (box_pos_x_ + kBoxWidth >= size_.width() || box_pos_x_ == 0)
     98     box_speed_x_ = -box_speed_x_;
     99 
    100   box_pos_y_ += box_speed_y_;
    101   if (box_pos_y_ + kBoxHeight >= size_.height() || box_pos_y_ == 0)
    102     box_speed_y_ = -box_speed_y_;
    103 
    104   // Draw rectangle with the following colors in its corners:
    105   //     cyan....yellow
    106   //     ..............
    107   //     blue.......red
    108   for (int y = 0; y < kBoxHeight; ++y) {
    109     for (int x = 0; x < kBoxWidth; ++x) {
    110       int r = x * 255 / kBoxWidth;
    111       int g = y * 255 / kBoxHeight;
    112       int b = 255 - (x * 255 / kBoxWidth);
    113       row[x * kBytesPerPixel] = r;
    114       row[x * kBytesPerPixel + 1] = g;
    115       row[x * kBytesPerPixel + 2] = b;
    116       row[x * kBytesPerPixel + 3] = 0xff;
    117     }
    118     row += bytes_per_row_;
    119   }
    120 }
    121 
    122 void ScreenCapturerFake::ScreenConfigurationChanged() {
    123   size_.set(kWidth, kHeight);
    124   queue_.Reset();
    125   bytes_per_row_ = size_.width() * webrtc::DesktopFrame::kBytesPerPixel;
    126 }
    127 
    128 }  // namespace remoting
    129