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