普通文本  |  139行  |  4.23 KB

// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "remoting/host/screen_capturer_fake.h"

#include "base/logging.h"
#include "base/time/time.h"
#include "third_party/webrtc/modules/desktop_capture/desktop_frame.h"

namespace remoting {

// ScreenCapturerFake generates a white picture of size kWidth x kHeight
// with a rectangle of size kBoxWidth x kBoxHeight. The rectangle moves kSpeed
// pixels per frame along both axes, and bounces off the sides of the screen.
static const int kWidth = ScreenCapturerFake::kWidth;
static const int kHeight = ScreenCapturerFake::kHeight;
static const int kBoxWidth = 140;
static const int kBoxHeight = 140;
static const int kSpeed = 20;

COMPILE_ASSERT(kBoxWidth < kWidth && kBoxHeight < kHeight, bad_box_size);
COMPILE_ASSERT((kBoxWidth % kSpeed == 0) && (kWidth % kSpeed == 0) &&
               (kBoxHeight % kSpeed == 0) && (kHeight % kSpeed == 0),
               sizes_must_be_multiple_of_kSpeed);

ScreenCapturerFake::ScreenCapturerFake()
    : callback_(NULL),
      mouse_shape_observer_(NULL),
      bytes_per_row_(0),
      box_pos_x_(0),
      box_pos_y_(0),
      box_speed_x_(kSpeed),
      box_speed_y_(kSpeed) {
  ScreenConfigurationChanged();
}

ScreenCapturerFake::~ScreenCapturerFake() {
}

void ScreenCapturerFake::Start(Callback* callback) {
  DCHECK(!callback_);
  DCHECK(callback);
  callback_ = callback;
}

void ScreenCapturerFake::Capture(const webrtc::DesktopRegion& region) {
  base::Time capture_start_time = base::Time::Now();

  queue_.MoveToNextFrame();

  if (!queue_.current_frame()) {
    int buffer_size = size_.height() * bytes_per_row_;
    webrtc::SharedMemory* shared_memory =
        callback_->CreateSharedMemory(buffer_size);
    scoped_ptr<webrtc::DesktopFrame> frame;
    webrtc::DesktopSize frame_size(size_.width(), size_.height());
    if (shared_memory) {
      frame.reset(new webrtc::SharedMemoryDesktopFrame(
          frame_size, bytes_per_row_, shared_memory));
    } else {
      frame.reset(new webrtc::BasicDesktopFrame(frame_size));
    }
    queue_.ReplaceCurrentFrame(frame.release());
  }

  DCHECK(queue_.current_frame());
  GenerateImage();

  queue_.current_frame()->mutable_updated_region()->SetRect(
      webrtc::DesktopRect::MakeSize(size_));
  queue_.current_frame()->set_capture_time_ms(
      (base::Time::Now() - capture_start_time).InMillisecondsRoundedUp());

  callback_->OnCaptureCompleted(queue_.current_frame()->Share());
}

void ScreenCapturerFake::SetMouseShapeObserver(
      MouseShapeObserver* mouse_shape_observer) {
  DCHECK(!mouse_shape_observer_);
  DCHECK(mouse_shape_observer);
  mouse_shape_observer_ = mouse_shape_observer;
}

bool ScreenCapturerFake::GetScreenList(ScreenList* screens) {
  NOTIMPLEMENTED();
  return false;
}

bool ScreenCapturerFake::SelectScreen(webrtc::ScreenId id) {
  NOTIMPLEMENTED();
  return false;
}

void ScreenCapturerFake::GenerateImage() {
  webrtc::DesktopFrame* frame = queue_.current_frame();

  const int kBytesPerPixel = webrtc::DesktopFrame::kBytesPerPixel;

  memset(frame->data(), 0xff,
         size_.width() * size_.height() * kBytesPerPixel);

  uint8* row = frame->data() +
      (box_pos_y_ * size_.width() + box_pos_x_) * kBytesPerPixel;

  box_pos_x_ += box_speed_x_;
  if (box_pos_x_ + kBoxWidth >= size_.width() || box_pos_x_ == 0)
    box_speed_x_ = -box_speed_x_;

  box_pos_y_ += box_speed_y_;
  if (box_pos_y_ + kBoxHeight >= size_.height() || box_pos_y_ == 0)
    box_speed_y_ = -box_speed_y_;

  // Draw rectangle with the following colors in its corners:
  //     cyan....yellow
  //     ..............
  //     blue.......red
  for (int y = 0; y < kBoxHeight; ++y) {
    for (int x = 0; x < kBoxWidth; ++x) {
      int r = x * 255 / kBoxWidth;
      int g = y * 255 / kBoxHeight;
      int b = 255 - (x * 255 / kBoxWidth);
      row[x * kBytesPerPixel] = r;
      row[x * kBytesPerPixel + 1] = g;
      row[x * kBytesPerPixel + 2] = b;
      row[x * kBytesPerPixel + 3] = 0xff;
    }
    row += bytes_per_row_;
  }
}

void ScreenCapturerFake::ScreenConfigurationChanged() {
  size_.set(kWidth, kHeight);
  queue_.Reset();
  bytes_per_row_ = size_.width() * webrtc::DesktopFrame::kBytesPerPixel;
}

}  // namespace remoting