LCOV - code coverage report
Current view: top level - media/webrtc/trunk/webrtc/modules/desktop_capture - desktop_and_cursor_composer.cc (source / functions) Hit Total Coverage
Test: output.info Lines: 0 98 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 15 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  *  Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
       3             :  *
       4             :  *  Use of this source code is governed by a BSD-style license
       5             :  *  that can be found in the LICENSE file in the root of the source
       6             :  *  tree. An additional intellectual property rights grant can be found
       7             :  *  in the file PATENTS.  All contributing project authors may
       8             :  *  be found in the AUTHORS file in the root of the source tree.
       9             :  */
      10             : 
      11             : #include "webrtc/modules/desktop_capture/desktop_and_cursor_composer.h"
      12             : 
      13             : #include <string.h>
      14             : 
      15             : #include "webrtc/base/constructormagic.h"
      16             : #include "webrtc/modules/desktop_capture/desktop_capturer.h"
      17             : #include "webrtc/modules/desktop_capture/desktop_frame.h"
      18             : #include "webrtc/modules/desktop_capture/mouse_cursor.h"
      19             : 
      20             : namespace webrtc {
      21             : 
      22             : namespace {
      23             : 
      24             : // Helper function that blends one image into another. Source image must be
      25             : // pre-multiplied with the alpha channel. Destination is assumed to be opaque.
      26           0 : void AlphaBlend(uint8_t* dest, int dest_stride,
      27             :                 const uint8_t* src, int src_stride,
      28             :                 const DesktopSize& size) {
      29           0 :   for (int y = 0; y < size.height(); ++y) {
      30           0 :     for (int x = 0; x < size.width(); ++x) {
      31           0 :       uint32_t base_alpha = 255 - src[x * DesktopFrame::kBytesPerPixel + 3];
      32           0 :       if (base_alpha == 255) {
      33           0 :         continue;
      34           0 :       } else if (base_alpha == 0) {
      35           0 :         memcpy(dest + x * DesktopFrame::kBytesPerPixel,
      36           0 :                src + x * DesktopFrame::kBytesPerPixel,
      37           0 :                DesktopFrame::kBytesPerPixel);
      38             :       } else {
      39           0 :         dest[x * DesktopFrame::kBytesPerPixel] =
      40           0 :             dest[x * DesktopFrame::kBytesPerPixel] * base_alpha / 255 +
      41           0 :             src[x * DesktopFrame::kBytesPerPixel];
      42           0 :         dest[x * DesktopFrame::kBytesPerPixel + 1] =
      43           0 :             dest[x * DesktopFrame::kBytesPerPixel + 1] * base_alpha / 255 +
      44           0 :             src[x * DesktopFrame::kBytesPerPixel + 1];
      45           0 :         dest[x * DesktopFrame::kBytesPerPixel + 2] =
      46           0 :             dest[x * DesktopFrame::kBytesPerPixel + 2] * base_alpha / 255 +
      47           0 :             src[x * DesktopFrame::kBytesPerPixel + 2];
      48             :       }
      49             :     }
      50           0 :     src += src_stride;
      51           0 :     dest += dest_stride;
      52             :   }
      53           0 : }
      54             : 
      55             : // DesktopFrame wrapper that draws mouse on a frame and restores original
      56             : // content before releasing the underlying frame.
      57             : class DesktopFrameWithCursor : public DesktopFrame {
      58             :  public:
      59             :   // Takes ownership of |frame|.
      60             :   DesktopFrameWithCursor(std::unique_ptr<DesktopFrame> frame,
      61             :                          const MouseCursor& cursor,
      62             :                          const DesktopVector& position);
      63             :   ~DesktopFrameWithCursor() override;
      64             : 
      65             :  private:
      66             :   std::unique_ptr<DesktopFrame> original_frame_;
      67             : 
      68             :   DesktopVector restore_position_;
      69             :   std::unique_ptr<DesktopFrame> restore_frame_;
      70             : 
      71             :   RTC_DISALLOW_COPY_AND_ASSIGN(DesktopFrameWithCursor);
      72             : };
      73             : 
      74           0 : DesktopFrameWithCursor::DesktopFrameWithCursor(
      75             :     std::unique_ptr<DesktopFrame> frame,
      76             :     const MouseCursor& cursor,
      77           0 :     const DesktopVector& position)
      78           0 :     : DesktopFrame(frame->size(),
      79             :                    frame->stride(),
      80             :                    frame->data(),
      81           0 :                    frame->shared_memory()) {
      82           0 :   set_dpi(frame->dpi());
      83           0 :   set_capture_time_ms(frame->capture_time_ms());
      84           0 :   mutable_updated_region()->Swap(frame->mutable_updated_region());
      85           0 :   original_frame_ = std::move(frame);
      86             : 
      87           0 :   DesktopVector image_pos = position.subtract(cursor.hotspot());
      88           0 :   DesktopRect target_rect = DesktopRect::MakeSize(cursor.image()->size());
      89           0 :   target_rect.Translate(image_pos);
      90           0 :   DesktopVector target_origin = target_rect.top_left();
      91           0 :   target_rect.IntersectWith(DesktopRect::MakeSize(size()));
      92             : 
      93           0 :   if (target_rect.is_empty())
      94           0 :     return;
      95             : 
      96             :   // Copy original screen content under cursor to |restore_frame_|.
      97           0 :   restore_position_ = target_rect.top_left();
      98           0 :   restore_frame_.reset(new BasicDesktopFrame(target_rect.size()));
      99           0 :   restore_frame_->CopyPixelsFrom(*this, target_rect.top_left(),
     100           0 :                                  DesktopRect::MakeSize(restore_frame_->size()));
     101             : 
     102             :   // Blit the cursor.
     103           0 :   uint8_t* target_rect_data = reinterpret_cast<uint8_t*>(data()) +
     104           0 :                               target_rect.top() * stride() +
     105           0 :                               target_rect.left() * DesktopFrame::kBytesPerPixel;
     106           0 :   DesktopVector origin_shift = target_rect.top_left().subtract(target_origin);
     107           0 :   AlphaBlend(target_rect_data, stride(),
     108           0 :              cursor.image()->data() +
     109           0 :                  origin_shift.y() * cursor.image()->stride() +
     110           0 :                  origin_shift.x() * DesktopFrame::kBytesPerPixel,
     111             :              cursor.image()->stride(),
     112           0 :              target_rect.size());
     113             : }
     114             : 
     115           0 : DesktopFrameWithCursor::~DesktopFrameWithCursor() {
     116             :   // Restore original content of the frame.
     117           0 :   if (restore_frame_.get()) {
     118           0 :     DesktopRect target_rect = DesktopRect::MakeSize(restore_frame_->size());
     119           0 :     target_rect.Translate(restore_position_);
     120           0 :     CopyPixelsFrom(restore_frame_->data(), restore_frame_->stride(),
     121           0 :                    target_rect);
     122             :   }
     123           0 : }
     124             : 
     125             : }  // namespace
     126             : 
     127           0 : DesktopAndCursorComposer::DesktopAndCursorComposer(
     128             :     DesktopCapturer* desktop_capturer,
     129           0 :     MouseCursorMonitor* mouse_monitor)
     130             :     : desktop_capturer_(desktop_capturer),
     131           0 :       mouse_monitor_(mouse_monitor) {
     132           0 : }
     133             : 
     134           0 : DesktopAndCursorComposer::~DesktopAndCursorComposer() {}
     135             : 
     136           0 : void DesktopAndCursorComposer::Start(DesktopCapturer::Callback* callback) {
     137           0 :   callback_ = callback;
     138           0 :   if (mouse_monitor_.get())
     139           0 :     mouse_monitor_->Start(this, MouseCursorMonitor::SHAPE_AND_POSITION);
     140           0 :   desktop_capturer_->Start(this);
     141           0 : }
     142             : 
     143           0 : void DesktopAndCursorComposer::Stop() {
     144           0 :   desktop_capturer_->Stop();
     145           0 :   if (mouse_monitor_.get())
     146           0 :     mouse_monitor_->Stop();
     147           0 :   callback_ = NULL;
     148           0 : }
     149             : 
     150           0 : void DesktopAndCursorComposer::SetSharedMemoryFactory(
     151             :     std::unique_ptr<SharedMemoryFactory> shared_memory_factory) {
     152           0 :   desktop_capturer_->SetSharedMemoryFactory(std::move(shared_memory_factory));
     153           0 : }
     154             : 
     155           0 : void DesktopAndCursorComposer::CaptureFrame() {
     156           0 :   if (mouse_monitor_.get())
     157           0 :     mouse_monitor_->Capture();
     158           0 :   desktop_capturer_->CaptureFrame();
     159           0 : }
     160             : 
     161           0 : void DesktopAndCursorComposer::SetExcludedWindow(WindowId window) {
     162           0 :   desktop_capturer_->SetExcludedWindow(window);
     163           0 : }
     164             : 
     165           0 : void DesktopAndCursorComposer::OnCaptureResult(
     166             :     DesktopCapturer::Result result,
     167             :     std::unique_ptr<DesktopFrame> frame) {
     168           0 :   if (frame && cursor_ && cursor_state_ == MouseCursorMonitor::INSIDE) {
     169           0 :     frame = std::unique_ptr<DesktopFrameWithCursor>(new DesktopFrameWithCursor(
     170           0 :         std::move(frame), *cursor_, cursor_position_));
     171             :   }
     172             : 
     173           0 :   callback_->OnCaptureResult(result, std::move(frame));
     174           0 : }
     175             : 
     176           0 : void DesktopAndCursorComposer::OnMouseCursor(MouseCursor* cursor) {
     177           0 :   cursor_.reset(cursor);
     178           0 : }
     179             : 
     180           0 : void DesktopAndCursorComposer::OnMouseCursorPosition(
     181             :     MouseCursorMonitor::CursorState state,
     182             :     const DesktopVector& position) {
     183           0 :   cursor_state_ = state;
     184           0 :   cursor_position_ = position;
     185           0 : }
     186             : 
     187             : }  // namespace webrtc

Generated by: LCOV version 1.13