From 15e32ccd30992840f6a48c3e52cc979452eb5f0d Mon Sep 17 00:00:00 2001 From: "sergeyu@chromium.org" Date: Mon, 29 Apr 2013 20:10:57 +0000 Subject: [PATCH] Add DesktopCapturer interface for desktop capturers. The new DesktopCapturer interface will be used for screen and window captures. Beside DesktopCapturer itself also added classes/interfaces that it depends on. R=alexeypa@chromium.org, tommi@webrtc.org Review URL: https://webrtc-codereview.appspot.com/1322007 git-svn-id: http://webrtc.googlecode.com/svn/trunk@3917 4adac7df-926f-26a2-2b94-8c16560cd09d --- .../desktop_capture/desktop_capture.gypi | 37 +++++- .../desktop_capture/desktop_capturer.h | 58 ++++++++ .../modules/desktop_capture/desktop_frame.cc | 51 +++++++ .../modules/desktop_capture/desktop_frame.h | 106 +++++++++++++++ .../desktop_capture/desktop_frame_win.cc | 60 +++++++++ .../desktop_capture/desktop_frame_win.h | 49 +++++++ .../desktop_capture/desktop_geometry.cc | 38 ++++++ .../desktop_capture/desktop_geometry.h | 124 ++++++++++++++++++ .../modules/desktop_capture/desktop_region.cc | 83 ++++++++++++ .../modules/desktop_capture/desktop_region.h | 71 ++++++++++ .../modules/desktop_capture/shared_memory.cc | 28 ++++ .../modules/desktop_capture/shared_memory.h | 68 ++++++++++ webrtc/modules/modules.gyp | 1 + 13 files changed, 772 insertions(+), 2 deletions(-) create mode 100644 webrtc/modules/desktop_capture/desktop_capturer.h create mode 100644 webrtc/modules/desktop_capture/desktop_frame.cc create mode 100644 webrtc/modules/desktop_capture/desktop_frame.h create mode 100644 webrtc/modules/desktop_capture/desktop_frame_win.cc create mode 100644 webrtc/modules/desktop_capture/desktop_frame_win.h create mode 100644 webrtc/modules/desktop_capture/desktop_geometry.cc create mode 100644 webrtc/modules/desktop_capture/desktop_geometry.h create mode 100644 webrtc/modules/desktop_capture/desktop_region.cc create mode 100644 webrtc/modules/desktop_capture/desktop_region.h create mode 100644 webrtc/modules/desktop_capture/shared_memory.cc create mode 100644 webrtc/modules/desktop_capture/shared_memory.h diff --git a/webrtc/modules/desktop_capture/desktop_capture.gypi b/webrtc/modules/desktop_capture/desktop_capture.gypi index ad523a4fa8..b9778dcdcb 100644 --- a/webrtc/modules/desktop_capture/desktop_capture.gypi +++ b/webrtc/modules/desktop_capture/desktop_capture.gypi @@ -14,9 +14,42 @@ 'dependencies': [ '<(webrtc_root)/system_wrappers/source/system_wrappers.gyp:system_wrappers', ], + 'direct_dependent_settings': { + # Headers may use include path relative to webrtc root and depend on + # WEBRTC_WIN define, so we need to make sure dependent targets have + # these settings. + # + # TODO(sergeyu): Move these settings to common.gypi + 'include_dirs': [ + '../../..', + ], + 'conditions': [ + ['OS=="win"', { + 'defines': [ + 'WEBRTC_WIN', + ], + }], + ], + }, 'sources': [ - # TODO(sergeyu): Add source files here once they are moved from - # chromium. + "desktop_capturer.h", + "desktop_frame.cc", + "desktop_frame.h", + "desktop_frame_win.cc", + "desktop_frame_win.h", + "desktop_geometry.cc", + "desktop_geometry.h", + "desktop_region.cc", + "desktop_region.h", + "shared_memory.cc", + "shared_memory.h", + ], + 'conditions': [ + ['OS!="win"', { + 'sources/': [ + ['exclude', '_win(_unittest)?\\.(cc|h)$'], + ], + }], ], }, ], # targets diff --git a/webrtc/modules/desktop_capture/desktop_capturer.h b/webrtc/modules/desktop_capture/desktop_capturer.h new file mode 100644 index 0000000000..21a4210943 --- /dev/null +++ b/webrtc/modules/desktop_capture/desktop_capturer.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef WEBRTC_MODULES_DESKTOP_CAPTURE_DESKTOP_CAPTURER_H_ +#define WEBRTC_MODULES_DESKTOP_CAPTURE_DESKTOP_CAPTURER_H_ + +namespace webrtc { + +class DesktopFrame; +class DesktopRegion; +class SharedMemory; + +// Abstract interface for screen and window capturers. +class DesktopCapturer { + public: + // Interface that must be implemented by the DesktopCapturer consumers. + class Callback { + public: + // Creates a new shared memory buffer for a frame create by the capturer. + // Should return null shared memory is not used for captured frames (in that + // case the capturer will allocate memory on the heap). + virtual SharedMemory* CreateSharedMemory(size_t size) = 0; + + // Called after a frame has been captured. Handler must take ownership of + // |frame|. If capture has failed for any reason |frame| is set to NULL + // (e.g. the window has been closed). + virtual void OnCaptureCompleted(DesktopFrame* frame) = 0; + + protected: + virtual ~Callback() {} + }; + + virtual ~DesktopCapturer() {} + + // Called at the beginning of a capturing session. |callback| must remain + // valid until capturer is destroyed. + virtual void Start(Callback* callback) = 0; + + // Captures next frame. |region| specifies region of the capture target that + // should be fresh in the resulting frame. The frame may also include fresh + // data for areas outside |region|. In that case capturer will include these + // areas in updated_region() of the frame. |region| is specified relative to + // the top left corner of the capture target. Pending capture operations are + // canceled when DesktopCapturer is deleted. + virtual void Capture(const DesktopRegion& region) = 0; +}; + +} // namespace webrtc + +#endif // WEBRTC_MODULES_DESKTOP_CAPTURE_DESKTOP_CAPTURER_H_ + diff --git a/webrtc/modules/desktop_capture/desktop_frame.cc b/webrtc/modules/desktop_capture/desktop_frame.cc new file mode 100644 index 0000000000..90e1fbd3e3 --- /dev/null +++ b/webrtc/modules/desktop_capture/desktop_frame.cc @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include "webrtc/modules/desktop_capture/desktop_frame.h" + +namespace webrtc { + +DesktopFrame::DesktopFrame(DesktopSize size, + int stride, + uint8_t* data, + SharedMemory* shared_memory) + : size_(size), + stride_(stride), + data_(data), + shared_memory_(shared_memory), + capture_time_ms_(0) { +} + +DesktopFrame::~DesktopFrame() {} + +BasicDesktopFrame::BasicDesktopFrame(DesktopSize size) + : DesktopFrame(size, kBytesPerPixel * size.width(), + new uint8_t[kBytesPerPixel * size.width() * size.height()], + NULL) { +} + +BasicDesktopFrame::~BasicDesktopFrame() { + delete[] data_; +} + +SharedMemoryDesktopFrame::SharedMemoryDesktopFrame( + DesktopSize size, + int stride, + SharedMemory* shared_memory) + : DesktopFrame(size, stride, + reinterpret_cast(shared_memory->data()), + shared_memory) { +} + +SharedMemoryDesktopFrame::~SharedMemoryDesktopFrame() { + delete shared_memory_; +} + +} // namespace webrtc diff --git a/webrtc/modules/desktop_capture/desktop_frame.h b/webrtc/modules/desktop_capture/desktop_frame.h new file mode 100644 index 0000000000..a39eff7452 --- /dev/null +++ b/webrtc/modules/desktop_capture/desktop_frame.h @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef WEBRTC_MODULES_DESKTOP_CAPTURE_DESKTOP_FRAME_H_ +#define WEBRTC_MODULES_DESKTOP_CAPTURE_DESKTOP_FRAME_H_ + +#include "webrtc/modules/desktop_capture/desktop_geometry.h" +#include "webrtc/modules/desktop_capture/desktop_region.h" +#include "webrtc/modules/desktop_capture/shared_memory.h" +#include "webrtc/typedefs.h" + +namespace webrtc { + +// DesktopFrame represents a video frame captured from the screen. +class DesktopFrame { + public: + // DesktopFrame objects always hold RGBA data. + static const int kBytesPerPixel = 4; + + virtual ~DesktopFrame(); + + // Size of the frame. + const DesktopSize& size() const { return size_; } + + // Distance in the buffer between two neighboring rows in bytes. + int stride() const { return stride_; } + + // Data buffer used for the frame. + uint8_t* data() const { return data_; } + + // SharedMemory used for the buffer or NULL if memory is allocated on the + // heap. The result is guaranteed to be deleted only after the frame is + // deleted (classes that inherit from DesktopFrame must ensure it). + SharedMemory* shared_memory() const { return shared_memory_; } + + // Indicates region of the screen that has changed since the previous frame. + const DesktopRegion& updated_region() const { return updated_region_; } + DesktopRegion* mutable_updated_region() { return &updated_region_; } + + // DPI of the screen being captured. May be set to zero, e.g. if DPI is + // unknown. + const DesktopVector& dpi() const { return dpi_; } + void set_dpi(const DesktopVector& dpi) { dpi_ = dpi; } + + // Time taken to capture the frame in milliseconds. + int32_t capture_time_ms() const { return capture_time_ms_; } + void set_capture_time_ms(int32_t time_ms) { capture_time_ms_ = time_ms; } + + protected: + DesktopFrame(DesktopSize size, + int stride, + uint8_t* data, + SharedMemory* shared_memory); + + const DesktopSize size_; + const int stride_; + + // Ownership of the buffers is defined by the classes that inherit from this + // class. They must guarantee that the buffer is not deleted before the frame + // is deleted. + uint8_t* const data_; + SharedMemory* const shared_memory_; + + DesktopRegion updated_region_; + + DesktopVector dpi_; + int32_t capture_time_ms_; + + private: + DISALLOW_COPY_AND_ASSIGN(DesktopFrame); +}; + +// A DesktopFrame that stores data in the heap. +class BasicDesktopFrame : public DesktopFrame { + public: + explicit BasicDesktopFrame(DesktopSize size); + virtual ~BasicDesktopFrame(); + + private: + DISALLOW_COPY_AND_ASSIGN(BasicDesktopFrame); +}; + +// A DesktopFrame that stores data in shared memory. +class SharedMemoryDesktopFrame : public DesktopFrame { + public: + // Takes ownership of |shared_memory|. + SharedMemoryDesktopFrame(DesktopSize size, + int stride, + SharedMemory* shared_memory); + virtual ~SharedMemoryDesktopFrame(); + + private: + DISALLOW_COPY_AND_ASSIGN(SharedMemoryDesktopFrame); +}; + +} // namespace webrtc + +#endif // WEBRTC_MODULES_DESKTOP_CAPTURE_DESKTOP_FRAME_H_ + diff --git a/webrtc/modules/desktop_capture/desktop_frame_win.cc b/webrtc/modules/desktop_capture/desktop_frame_win.cc new file mode 100644 index 0000000000..261a90e9dc --- /dev/null +++ b/webrtc/modules/desktop_capture/desktop_frame_win.cc @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include "webrtc/modules/desktop_capture/desktop_frame_win.h" + +namespace webrtc { + +DesktopFrameWin::DesktopFrameWin(DesktopSize size, + int stride, + uint8_t* data, + SharedMemory* shared_memory, + HBITMAP bitmap) + : DesktopFrame(size, stride, data, shared_memory), + bitmap_(bitmap), + owned_shared_memory_(shared_memory_) { +} + +DesktopFrameWin::~DesktopFrameWin() { + DeleteObject(bitmap_); +} + +// static +DesktopFrameWin* DesktopFrameWin::Create(DesktopSize size, + SharedMemory* shared_memory, + HDC hdc) { + int bytes_per_row = size.width() * kBytesPerPixel; + + // Describe a device independent bitmap (DIB) that is the size of the desktop. + BITMAPINFO bmi = {0}; + bmi.bmiHeader.biHeight = -size.height(); + bmi.bmiHeader.biWidth = size.width(); + bmi.bmiHeader.biPlanes = 1; + bmi.bmiHeader.biBitCount = DesktopFrameWin::kBytesPerPixel * 8; + bmi.bmiHeader.biSize = sizeof(bmi.bmiHeader); + bmi.bmiHeader.biSizeImage = bytes_per_row * size.height(); + + HANDLE section_handle = NULL; + if (shared_memory) + section_handle = shared_memory->handle(); + void* data = NULL; + HBITMAP bitmap = CreateDIBSection(hdc, &bmi, DIB_RGB_COLORS, &data, + section_handle, 0); + if (!bitmap) { + delete shared_memory; + return NULL; + } + + return new DesktopFrameWin(size, bytes_per_row, + reinterpret_cast(data), + shared_memory, bitmap); +} + +} // namespace webrtc diff --git a/webrtc/modules/desktop_capture/desktop_frame_win.h b/webrtc/modules/desktop_capture/desktop_frame_win.h new file mode 100644 index 0000000000..eb9c5a3ff0 --- /dev/null +++ b/webrtc/modules/desktop_capture/desktop_frame_win.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef WEBRTC_MODULES_DESKTOP_CAPTURE_DESKTOP_FRAME_WIN_H_ +#define WEBRTC_MODULES_DESKTOP_CAPTURE_DESKTOP_FRAME_WIN_H_ + +#include + +#include "webrtc/modules/desktop_capture/desktop_frame.h" +#include "webrtc/system_wrappers/interface/scoped_ptr.h" +#include "webrtc/typedefs.h" + +namespace webrtc { + +// DesktopFrame implementation used by screen and window captures on Windows. +// Frame data is stored in a GDI bitmap. +class DesktopFrameWin : public DesktopFrame { + public: + virtual ~DesktopFrameWin(); + static DesktopFrameWin* Create(DesktopSize size, + SharedMemory* shared_memory, + HDC hdc); + + HBITMAP bitmap() { return bitmap_; } + + private: + DesktopFrameWin(DesktopSize size, + int stride, + uint8_t* data, + SharedMemory* shared_memory, + HBITMAP bitmap); + + HBITMAP bitmap_; + scoped_ptr owned_shared_memory_; + + DISALLOW_COPY_AND_ASSIGN(DesktopFrameWin); +}; + +} // namespace webrtc + +#endif // WEBRTC_MODULES_DESKTOP_CAPTURE_DESKTOP_FRAME_WIN_H_ + diff --git a/webrtc/modules/desktop_capture/desktop_geometry.cc b/webrtc/modules/desktop_capture/desktop_geometry.cc new file mode 100644 index 0000000000..051e626334 --- /dev/null +++ b/webrtc/modules/desktop_capture/desktop_geometry.cc @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include "webrtc/modules/desktop_capture/desktop_geometry.h" + +#include + +namespace webrtc { + +void DesktopRect::IntersectWith(const DesktopRect& rect) { + left_ = std::max(left(), rect.left()); + top_ = std::max(top(), rect.top()); + right_ = std::min(right(), rect.right()); + bottom_ = std::min(bottom(), rect.top()); + if (is_empty()) { + left_ = 0; + top_ = 0; + right_ = 0; + bottom_ = 0; + } +} + +void DesktopRect::Translate(int32_t dx, int32_t dy) { + left_ += dx; + top_ += dy; + right_ += dx; + bottom_ += dy; +} + +} // namespace webrtc + diff --git a/webrtc/modules/desktop_capture/desktop_geometry.h b/webrtc/modules/desktop_capture/desktop_geometry.h new file mode 100644 index 0000000000..2f87cfa065 --- /dev/null +++ b/webrtc/modules/desktop_capture/desktop_geometry.h @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef WEBRTC_MODULES_DESKTOP_CAPTURE_DESKTOP_GEOMETRY_H_ +#define WEBRTC_MODULES_DESKTOP_CAPTURE_DESKTOP_GEOMETRY_H_ + +#include "webrtc/typedefs.h" +#include "webrtc/system_wrappers/interface/constructor_magic.h" + +namespace webrtc { + +// A vector in the 2D integer space. E.g. can be used to represent screen DPI. +class DesktopVector { + public: + DesktopVector() : x_(0), y_(0) {} + DesktopVector(int32_t x, int32_t y) : x_(x), y_(y) {} + + int32_t x() const { return x_; } + int32_t y() const { return y_; } + bool is_zero() const { return x_ == 0 && y_ == 0; } + + bool equals(const DesktopVector& other) const { + return x_ == other.x_ && y_ == other.y_; + } + + void set(int32_t x, int32_t y) { + x_ = x; + y_ = y; + } + + private: + int32_t x_; + int32_t y_; +}; + +// Type used to represent screen/window size. +class DesktopSize { + public: + DesktopSize() : width_(0), height_(0) {} + DesktopSize(int32_t width, int32_t height) + : width_(width), height_(height) { + } + + int32_t width() const { return width_; } + int32_t height() const { return height_; } + + bool is_empty() const { return width_ <= 0 && height_ <= 0; } + + bool equals(const DesktopSize& other) const { + return width_ == other.width_ && height_ == other.height_; + } + + void set(int32_t width, int32_t height) { + width_ = width; + height_ = height; + } + + private: + int32_t width_; + int32_t height_; +}; + +// Represents a rectangle on the screen. +class DesktopRect { + public: + static DesktopRect MakeSize(const DesktopSize& size) { + return DesktopRect(0, 0, size.width(), size.height()); + } + static DesktopRect MakeWH(int32_t width, int32_t height) { + return DesktopRect(0, 0, width, height); + } + static DesktopRect MakeXYWH(int32_t x, int32_t y, + int32_t width, int32_t height) { + return DesktopRect(x, y, x + width, y + height); + } + static DesktopRect MakeLTRB(int32_t left, int32_t top, + int32_t right, int32_t bottom) { + return DesktopRect(left, top, right, bottom); + } + + DesktopRect() : left_(0), top_(0), right_(0), bottom_(0) {} + + int32_t left() const { return left_; } + int32_t top() const { return top_; } + int32_t right() const { return right_; } + int32_t bottom() const { return bottom_; } + int32_t width() const { return right_ - left_; } + int32_t height() const { return bottom_ - top_; } + + bool is_empty() const { return left_ >= right_ || top_ >= bottom_; } + + bool equals(const DesktopRect& other) const { + return left_ == other.left_ && top_ == other.top_ && + right_ == other.right_ && bottom_ == other.bottom_; + } + + // Finds intersection with |rect|. + void IntersectWith(const DesktopRect& rect); + + // Adds (dx, dy) to the position of the rectangle. + void Translate(int32_t dx, int32_t dy); + + private: + DesktopRect(int32_t left, int32_t top, int32_t right, int32_t bottom) + : left_(left), top_(top), right_(right), bottom_(bottom) { + } + + int32_t left_; + int32_t top_; + int32_t right_; + int32_t bottom_; +}; + +} // namespace webrtc + +#endif // WEBRTC_MODULES_DESKTOP_CAPTURE_DESKTOP_GEOMETRY_H_ + diff --git a/webrtc/modules/desktop_capture/desktop_region.cc b/webrtc/modules/desktop_capture/desktop_region.cc new file mode 100644 index 0000000000..b843034be2 --- /dev/null +++ b/webrtc/modules/desktop_capture/desktop_region.cc @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include "webrtc/modules/desktop_capture/desktop_region.h" + +namespace webrtc { + +DesktopRegion::DesktopRegion() {} + +DesktopRegion::DesktopRegion(const DesktopRegion& other) + : rects_(other.rects_) { +} + +DesktopRegion::~DesktopRegion() {} + +void DesktopRegion::Clear() { + rects_.clear(); +} + +void DesktopRegion::SetRect(const DesktopRect& rect) { + Clear(); + AddRect(rect); +} + +void DesktopRegion::AddRect(const DesktopRect& rect) { + if (!rect.is_empty()) + rects_.push_back(rect); +} + +void DesktopRegion::AddRegion(const DesktopRegion& region) { + for (Iterator it(region); !it.IsAtEnd(); it.Advance()) { + AddRect(it.rect()); + } +} + +void DesktopRegion::IntersectWith(const DesktopRect& rect) { + bool remove_empty_rects = false; + for (RectsList::iterator it = rects_.begin(); it != rects_.end(); ++it) { + it->IntersectWith(rect); + remove_empty_rects = remove_empty_rects | it->is_empty(); + } + if (remove_empty_rects) { + RectsList new_rects(rects_.size()); + for (RectsList::iterator it = rects_.begin(); it != rects_.end(); ++it) { + if (!it->is_empty()) + new_rects.push_back(*it); + } + rects_.swap(new_rects); + } +} + +void DesktopRegion::Translate(int32_t dx, int32_t dy) { + for (RectsList::iterator it = rects_.begin(); it != rects_.end(); ++it) { + it->Translate(dx, dy); + } +} + +void DesktopRegion::Swap(DesktopRegion* region) { + rects_.swap(region->rects_); +} + +DesktopRegion::Iterator::Iterator(const DesktopRegion& region) + : region_(region), + it_(region.rects_.begin()) { +} + +bool DesktopRegion::Iterator::IsAtEnd() const { + return it_ == region_.rects_.end(); +} + +void DesktopRegion::Iterator::Advance() { + ++it_; +} + +} // namespace webrtc + diff --git a/webrtc/modules/desktop_capture/desktop_region.h b/webrtc/modules/desktop_capture/desktop_region.h new file mode 100644 index 0000000000..9a9daa4dea --- /dev/null +++ b/webrtc/modules/desktop_capture/desktop_region.h @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef WEBRTC_MODULES_DESKTOP_CAPTURE_DESKTOP_REGION_H_ +#define WEBRTC_MODULES_DESKTOP_CAPTURE_DESKTOP_REGION_H_ + +#include + +#include "webrtc/modules/desktop_capture/desktop_geometry.h" +#include "webrtc/system_wrappers/interface/constructor_magic.h" +#include "webrtc/typedefs.h" + +namespace webrtc { + +// DesktopRegion represents a region of the screen or window. +// +// TODO(sergeyu): Current implementation just stores list of rectangles that may +// overlap. Optimize it. +class DesktopRegion { + public: + // Iterator that can be used to iterate over rectangles of a DesktopRegion. + // The region must not be mutated while the iterator is used. + class Iterator { + public: + explicit Iterator(const DesktopRegion& target); + + bool IsAtEnd() const; + void Advance(); + + const DesktopRect& rect() const { return *it_; } + + private: + const DesktopRegion& region_; + std::vector::const_iterator it_; + }; + + DesktopRegion(); + DesktopRegion(const DesktopRegion& other); + ~DesktopRegion(); + + bool is_empty() const { return rects_.empty(); } + + void Clear(); + void SetRect(const DesktopRect& rect); + void AddRect(const DesktopRect& rect); + void AddRegion(const DesktopRegion& region); + + // Clips the region by the |rect|. + void IntersectWith(const DesktopRect& rect); + + // Adds (dx, dy) to the position of the region. + void Translate(int32_t dx, int32_t dy); + + void Swap(DesktopRegion* region); + + private: + typedef std::vector RectsList; + RectsList rects_; +}; + +} // namespace webrtc + +#endif // WEBRTC_MODULES_DESKTOP_CAPTURE_DESKTOP_REGION_H_ + diff --git a/webrtc/modules/desktop_capture/shared_memory.cc b/webrtc/modules/desktop_capture/shared_memory.cc new file mode 100644 index 0000000000..872116eec9 --- /dev/null +++ b/webrtc/modules/desktop_capture/shared_memory.cc @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include "webrtc/modules/desktop_capture/shared_memory.h" + +namespace webrtc { + +#if defined(WEBRTC_WIN) +const SharedMemory::Handle SharedMemory::kInvalidHandle = NULL; +#else +const SharedMemory::Handle SharedMemory::kInvalidHandle = -1; +#endif + +SharedMemory::SharedMemory(void* data, size_t size, Handle handle, int id) + : data_(data), + size_(size), + handle_(handle), + id_(id) { +} + +} // namespace webrtc diff --git a/webrtc/modules/desktop_capture/shared_memory.h b/webrtc/modules/desktop_capture/shared_memory.h new file mode 100644 index 0000000000..bb43b28b1c --- /dev/null +++ b/webrtc/modules/desktop_capture/shared_memory.h @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef WEBRTC_MODULES_DESKTOP_CAPTURE_SHARED_MEMORY_H_ +#define WEBRTC_MODULES_DESKTOP_CAPTURE_SHARED_MEMORY_H_ + +#include + +#if defined(WEBRTC_WIN) +#include +#endif + +#include "webrtc/typedefs.h" +#include "webrtc/system_wrappers/interface/constructor_magic.h" + +namespace webrtc { + +// SharedMemory is a base class for shared memory. It stores all required +// parameters of the buffer, but doesn't have any logic to allocate or destroy +// the actual buffer. DesktopCapturer consumers that need to use shared memory +// for video frames must extend this class with creation and destruction logic +// specific for the target platform and then implement +// DesktopCapturer::Delegate::CreateSharedMemory() as appropriate. +class SharedMemory { + public: +#if defined(WEBRTC_WIN) + typedef HANDLE Handle; + static const Handle kInvalidHandle; +#else + typedef int Handle; + static const Handle kInvalidHandle; +#endif + + void* data() const { return data_; } + size_t size() const { return size_; } + + // Platform-specific handle of the buffer. + Handle handle() const { return handle_; } + + // Integer identifier that can be used used by consumers of DesktopCapturer + // interface to identify shared memory buffers it created. + int id() const { return id_; } + + virtual ~SharedMemory() {} + + protected: + SharedMemory(void* data, size_t size, Handle handle, int id); + + void* const data_; + const size_t size_; + const Handle handle_; + const int id_; + + private: + DISALLOW_COPY_AND_ASSIGN(SharedMemory); +}; + +} // namespace webrtc + +#endif // WEBRTC_MODULES_DESKTOP_CAPTURE_SHARED_MEMORY_H_ + diff --git a/webrtc/modules/modules.gyp b/webrtc/modules/modules.gyp index abf861faea..58a60fd917 100644 --- a/webrtc/modules/modules.gyp +++ b/webrtc/modules/modules.gyp @@ -23,6 +23,7 @@ 'audio_device/audio_device.gypi', 'audio_processing/audio_processing.gypi', 'bitrate_controller/bitrate_controller.gypi', + 'desktop_capture/desktop_capture.gypi', 'media_file/source/media_file.gypi', 'pacing/pacing.gypi', 'remote_bitrate_estimator/remote_bitrate_estimator.gypi',