• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #ifndef MODULES_DESKTOP_CAPTURE_DESKTOP_FRAME_H_
12 #define MODULES_DESKTOP_CAPTURE_DESKTOP_FRAME_H_
13 
14 #include <stdint.h>
15 
16 #include <memory>
17 #include <vector>
18 
19 #include "modules/desktop_capture/desktop_geometry.h"
20 #include "modules/desktop_capture/desktop_region.h"
21 #include "modules/desktop_capture/shared_memory.h"
22 #include "rtc_base/system/rtc_export.h"
23 
24 namespace webrtc {
25 
26 const float kStandardDPI = 96.0f;
27 
28 // DesktopFrame represents a video frame captured from the screen.
29 class RTC_EXPORT DesktopFrame {
30  public:
31   // DesktopFrame objects always hold BGRA data.
32   static const int kBytesPerPixel = 4;
33 
34   virtual ~DesktopFrame();
35 
36   DesktopFrame(const DesktopFrame&) = delete;
37   DesktopFrame& operator=(const DesktopFrame&) = delete;
38 
39   // Returns the rectangle in full desktop coordinates to indicate it covers
40   // the area of top_left() to top_letf() + size() / scale_factor().
41   DesktopRect rect() const;
42 
43   // Returns the scale factor from DIPs to physical pixels of the frame.
44   // Assumes same scale in both X and Y directions at present.
45   float scale_factor() const;
46 
47   // Size of the frame. In physical coordinates, mapping directly from the
48   // underlying buffer.
size()49   const DesktopSize& size() const { return size_; }
50 
51   // The top-left of the frame in full desktop coordinates. E.g. the top left
52   // monitor should start from (0, 0). The desktop coordinates may be scaled by
53   // OS, but this is always consistent with the MouseCursorMonitor.
top_left()54   const DesktopVector& top_left() const { return top_left_; }
set_top_left(const DesktopVector & top_left)55   void set_top_left(const DesktopVector& top_left) { top_left_ = top_left; }
56 
57   // Distance in the buffer between two neighboring rows in bytes.
stride()58   int stride() const { return stride_; }
59 
60   // Data buffer used for the frame.
data()61   uint8_t* data() const { return data_; }
62 
63   // SharedMemory used for the buffer or NULL if memory is allocated on the
64   // heap. The result is guaranteed to be deleted only after the frame is
65   // deleted (classes that inherit from DesktopFrame must ensure it).
shared_memory()66   SharedMemory* shared_memory() const { return shared_memory_; }
67 
68   // Indicates region of the screen that has changed since the previous frame.
updated_region()69   const DesktopRegion& updated_region() const { return updated_region_; }
mutable_updated_region()70   DesktopRegion* mutable_updated_region() { return &updated_region_; }
71 
72   // DPI of the screen being captured. May be set to zero, e.g. if DPI is
73   // unknown.
dpi()74   const DesktopVector& dpi() const { return dpi_; }
set_dpi(const DesktopVector & dpi)75   void set_dpi(const DesktopVector& dpi) { dpi_ = dpi; }
76 
77   // Indicates if this frame may have the mouse cursor in it. Capturers that
78   // support cursor capture may set this to true. If the cursor was
79   // outside of the captured area, this may be true even though the cursor is
80   // not in the image.
may_contain_cursor()81   bool may_contain_cursor() const { return may_contain_cursor_; }
set_may_contain_cursor(bool may_contain_cursor)82   void set_may_contain_cursor(bool may_contain_cursor) {
83     may_contain_cursor_ = may_contain_cursor;
84   }
85 
86   // Time taken to capture the frame in milliseconds.
capture_time_ms()87   int64_t capture_time_ms() const { return capture_time_ms_; }
set_capture_time_ms(int64_t time_ms)88   void set_capture_time_ms(int64_t time_ms) { capture_time_ms_ = time_ms; }
89 
90   // Copies pixels from a buffer or another frame. `dest_rect` rect must lay
91   // within bounds of this frame.
92   void CopyPixelsFrom(const uint8_t* src_buffer,
93                       int src_stride,
94                       const DesktopRect& dest_rect);
95   void CopyPixelsFrom(const DesktopFrame& src_frame,
96                       const DesktopVector& src_pos,
97                       const DesktopRect& dest_rect);
98 
99   // Copies pixels from another frame, with the copied & overwritten regions
100   // representing the intersection between the two frames. Returns true if
101   // pixels were copied, or false if there's no intersection. The scale factors
102   // represent the ratios between pixel space & offset coordinate space (e.g.
103   // 2.0 would indicate the frames are scaled down by 50% for display, so any
104   // offset between their origins should be doubled).
105   bool CopyIntersectingPixelsFrom(const DesktopFrame& src_frame,
106                                   double horizontal_scale,
107                                   double vertical_scale);
108 
109   // A helper to return the data pointer of a frame at the specified position.
110   uint8_t* GetFrameDataAtPos(const DesktopVector& pos) const;
111 
112   // The DesktopCapturer implementation which generates current DesktopFrame.
113   // Not all DesktopCapturer implementations set this field; it's set to
114   // kUnknown by default.
capturer_id()115   uint32_t capturer_id() const { return capturer_id_; }
set_capturer_id(uint32_t capturer_id)116   void set_capturer_id(uint32_t capturer_id) { capturer_id_ = capturer_id; }
117 
118   // Copies various information from `other`. Anything initialized in
119   // constructor are not copied.
120   // This function is usually used when sharing a source DesktopFrame with
121   // several clients: the original DesktopFrame should be kept unchanged. For
122   // example, BasicDesktopFrame::CopyOf() and SharedDesktopFrame::Share().
123   void CopyFrameInfoFrom(const DesktopFrame& other);
124 
125   // Copies various information from `other`. Anything initialized in
126   // constructor are not copied. Not like CopyFrameInfoFrom() function, this
127   // function uses swap or move constructor to avoid data copy. It won't break
128   // the `other`, but some of its information may be missing after this
129   // operation. E.g. other->updated_region_;
130   // This function is usually used when wrapping a DesktopFrame: the wrapper
131   // instance takes the ownership of `other`, so other components cannot access
132   // `other` anymore. For example, CroppedDesktopFrame and
133   // DesktopFrameWithCursor.
134   void MoveFrameInfoFrom(DesktopFrame* other);
135 
136   // Set and get the ICC profile of the frame data pixels. Useful to build the
137   // a ColorSpace object from clients of webrtc library like chromium. The
138   // format of an ICC profile is defined in the following specification
139   // http://www.color.org/specification/ICC1v43_2010-12.pdf.
icc_profile()140   const std::vector<uint8_t>& icc_profile() const { return icc_profile_; }
set_icc_profile(const std::vector<uint8_t> & icc_profile)141   void set_icc_profile(const std::vector<uint8_t>& icc_profile) {
142     icc_profile_ = icc_profile;
143   }
144 
145  protected:
146   DesktopFrame(DesktopSize size,
147                int stride,
148                uint8_t* data,
149                SharedMemory* shared_memory);
150 
151   // Ownership of the buffers is defined by the classes that inherit from this
152   // class. They must guarantee that the buffer is not deleted before the frame
153   // is deleted.
154   uint8_t* const data_;
155   SharedMemory* const shared_memory_;
156 
157  private:
158   const DesktopSize size_;
159   const int stride_;
160 
161   DesktopRegion updated_region_;
162   DesktopVector top_left_;
163   DesktopVector dpi_;
164   bool may_contain_cursor_ = false;
165   int64_t capture_time_ms_;
166   uint32_t capturer_id_;
167   std::vector<uint8_t> icc_profile_;
168 };
169 
170 // A DesktopFrame that stores data in the heap.
171 class RTC_EXPORT BasicDesktopFrame : public DesktopFrame {
172  public:
173   // The entire data buffer used for the frame is initialized with zeros.
174   explicit BasicDesktopFrame(DesktopSize size);
175 
176   ~BasicDesktopFrame() override;
177 
178   BasicDesktopFrame(const BasicDesktopFrame&) = delete;
179   BasicDesktopFrame& operator=(const BasicDesktopFrame&) = delete;
180 
181   // Creates a BasicDesktopFrame that contains copy of `frame`.
182   // TODO(zijiehe): Return std::unique_ptr<DesktopFrame>
183   static DesktopFrame* CopyOf(const DesktopFrame& frame);
184 };
185 
186 // A DesktopFrame that stores data in shared memory.
187 class RTC_EXPORT SharedMemoryDesktopFrame : public DesktopFrame {
188  public:
189   // May return nullptr if `shared_memory_factory` failed to create a
190   // SharedMemory instance.
191   // `shared_memory_factory` should not be nullptr.
192   static std::unique_ptr<DesktopFrame> Create(
193       DesktopSize size,
194       SharedMemoryFactory* shared_memory_factory);
195 
196   // Takes ownership of `shared_memory`.
197   // Deprecated, use the next constructor.
198   SharedMemoryDesktopFrame(DesktopSize size,
199                            int stride,
200                            SharedMemory* shared_memory);
201 
202   // Preferred.
203   SharedMemoryDesktopFrame(DesktopSize size,
204                            int stride,
205                            std::unique_ptr<SharedMemory> shared_memory);
206 
207   ~SharedMemoryDesktopFrame() override;
208 
209   SharedMemoryDesktopFrame(const SharedMemoryDesktopFrame&) = delete;
210   SharedMemoryDesktopFrame& operator=(const SharedMemoryDesktopFrame&) = delete;
211 
212  private:
213   // Avoid unexpected order of parameter evaluation.
214   // Executing both std::unique_ptr<T>::operator->() and
215   // std::unique_ptr<T>::release() in the member initializer list is not safe.
216   // Depends on the order of parameter evaluation,
217   // std::unique_ptr<T>::operator->() may trigger assertion failure if it has
218   // been evaluated after std::unique_ptr<T>::release(). By using this
219   // constructor, std::unique_ptr<T>::operator->() won't be involved anymore.
220   SharedMemoryDesktopFrame(DesktopRect rect,
221                            int stride,
222                            SharedMemory* shared_memory);
223 };
224 
225 }  // namespace webrtc
226 
227 #endif  // MODULES_DESKTOP_CAPTURE_DESKTOP_FRAME_H_
228