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