1 /*
2  *  Copyright (c) 2014 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 WEBRTC_MODULES_DESKTOP_CAPTURE_MAIN_SOURCE_DESKTOP_CAPTURE_IMPL_H_
12 #define WEBRTC_MODULES_DESKTOP_CAPTURE_MAIN_SOURCE_DESKTOP_CAPTURE_IMPL_H_
13 
14 /*
15  * video_capture_impl.h
16  */
17 
18 #include <string>
19 
20 #include "webrtc/common_video/interface/i420_video_frame.h"
21 #include "webrtc/common_video/libyuv/include/webrtc_libyuv.h"
22 #include "webrtc/modules/desktop_capture/screen_capturer.h"
23 #include "webrtc/system_wrappers/interface/tick_util.h"
24 #include "webrtc/modules/video_capture/video_capture_config.h"
25 #include "webrtc/modules/desktop_capture/shared_memory.h"
26 #include "webrtc/system_wrappers/interface/thread_wrapper.h"
27 #include "webrtc/system_wrappers/interface/event_wrapper.h"
28 #include "webrtc/modules/desktop_capture/mouse_cursor_shape.h"
29 #include "webrtc/modules/desktop_capture/desktop_device_info.h"
30 #include "webrtc/modules/desktop_capture/desktop_and_cursor_composer.h"
31 #include "webrtc/video_engine/include/vie_capture.h"
32 
33 using namespace webrtc::videocapturemodule;
34 
35 namespace webrtc {
36 
37 class CriticalSectionWrapper;
38 class VideoCaptureEncodeInterface;
39 
40 
41 //simulate deviceInfo interface for video engine, bridge screen/application and real screen/application device info
42 
43 class ScreenDeviceInfoImpl : public VideoCaptureModule::DeviceInfo {
44 public:
45   ScreenDeviceInfoImpl(const int32_t id);
46   virtual ~ScreenDeviceInfoImpl(void);
47 
48   int32_t Init();
49   int32_t Refresh();
50 
51   virtual uint32_t NumberOfDevices();
52   virtual int32_t GetDeviceName(uint32_t deviceNumber,
53                                 char* deviceNameUTF8,
54                                 uint32_t deviceNameLength,
55                                 char* deviceUniqueIdUTF8,
56                                 uint32_t deviceUniqueIdUTF8Length,
57                                 char* productUniqueIdUTF8,
58                                 uint32_t productUniqueIdUTF8Length,
59                                 pid_t* pid);
60 
61   virtual int32_t DisplayCaptureSettingsDialogBox(const char* deviceUniqueIdUTF8,
62                                                   const char* dialogTitleUTF8,
63                                                   void* parentWindow,
64                                                   uint32_t positionX,
65                                                   uint32_t positionY);
66   virtual int32_t NumberOfCapabilities(const char* deviceUniqueIdUTF8);
67   virtual int32_t GetCapability(const char* deviceUniqueIdUTF8,
68                                 const uint32_t deviceCapabilityNumber,
69                                 VideoCaptureCapability& capability);
70 
71   virtual int32_t GetBestMatchedCapability(const char* deviceUniqueIdUTF8,
72                                            const VideoCaptureCapability& requested,
73                                            VideoCaptureCapability& resulting);
74   virtual int32_t GetOrientation(const char* deviceUniqueIdUTF8,
75                                  VideoRotation& orientation);
76 protected:
77   int32_t _id;
78   rtc::scoped_ptr<DesktopDeviceInfo> desktop_device_info_;
79 
80 };
81 
82 class AppDeviceInfoImpl : public VideoCaptureModule::DeviceInfo {
83 public:
84   AppDeviceInfoImpl(const int32_t id);
85   virtual ~AppDeviceInfoImpl(void);
86 
87   int32_t Init();
88   int32_t Refresh();
89 
90   virtual uint32_t NumberOfDevices();
91   virtual int32_t GetDeviceName(uint32_t deviceNumber,
92                                 char* deviceNameUTF8,
93                                 uint32_t deviceNameLength,
94                                 char* deviceUniqueIdUTF8,
95                                 uint32_t deviceUniqueIdUTF8Length,
96                                 char* productUniqueIdUTF8,
97                                 uint32_t productUniqueIdUTF8Length,
98                                 pid_t* pid);
99 
100   virtual int32_t DisplayCaptureSettingsDialogBox(const char* deviceUniqueIdUTF8,
101                                                   const char* dialogTitleUTF8,
102                                                   void* parentWindow,
103                                                   uint32_t positionX,
104                                                   uint32_t positionY);
105   virtual int32_t NumberOfCapabilities(const char* deviceUniqueIdUTF8);
106   virtual int32_t GetCapability(const char* deviceUniqueIdUTF8,
107                                 const uint32_t deviceCapabilityNumber,
108                                 VideoCaptureCapability& capability);
109 
110   virtual int32_t GetBestMatchedCapability(const char* deviceUniqueIdUTF8,
111                                            const VideoCaptureCapability& requested,
112                                            VideoCaptureCapability& resulting);
113   virtual int32_t GetOrientation(const char* deviceUniqueIdUTF8,
114                                  VideoRotation& orientation);
115 protected:
116   int32_t _id;
117   rtc::scoped_ptr<DesktopDeviceInfo> desktop_device_info_;
118 };
119 
120 class WindowDeviceInfoImpl : public VideoCaptureModule::DeviceInfo {
121 public:
WindowDeviceInfoImpl(const int32_t id)122   WindowDeviceInfoImpl(const int32_t id) : _id(id) {};
~WindowDeviceInfoImpl(void)123   virtual ~WindowDeviceInfoImpl(void) {};
124 
125   int32_t Init();
126   int32_t Refresh();
127 
128   virtual uint32_t NumberOfDevices();
129   virtual int32_t GetDeviceName(uint32_t deviceNumber,
130                                 char* deviceNameUTF8,
131                                 uint32_t deviceNameLength,
132                                 char* deviceUniqueIdUTF8,
133                                 uint32_t deviceUniqueIdUTF8Length,
134                                 char* productUniqueIdUTF8,
135                                 uint32_t productUniqueIdUTF8Length,
136                                 pid_t* pid);
137 
138   virtual int32_t DisplayCaptureSettingsDialogBox(const char* deviceUniqueIdUTF8,
139                                                   const char* dialogTitleUTF8,
140                                                   void* parentWindow,
141                                                   uint32_t positionX,
142                                                   uint32_t positionY);
143   virtual int32_t NumberOfCapabilities(const char* deviceUniqueIdUTF8);
144   virtual int32_t GetCapability(const char* deviceUniqueIdUTF8,
145                                 const uint32_t deviceCapabilityNumber,
146                                 VideoCaptureCapability& capability);
147 
148   virtual int32_t GetBestMatchedCapability(const char* deviceUniqueIdUTF8,
149                                            const VideoCaptureCapability& requested,
150                                            VideoCaptureCapability& resulting);
151   virtual int32_t GetOrientation(const char* deviceUniqueIdUTF8,
152                                  VideoRotation& orientation);
153 protected:
154   int32_t _id;
155   rtc::scoped_ptr<DesktopDeviceInfo> desktop_device_info_;
156 
157 };
158 
159 // Reuses the video engine pipeline for screen sharing.
160 // As with video, DesktopCaptureImpl is a proxy for screen sharing
161 // and follows the video pipeline design
162 class DesktopCaptureImpl: public VideoCaptureModule,
163                           public VideoCaptureExternal,
164                           public ScreenCapturer::Callback,
165                           public ScreenCapturer::MouseShapeObserver
166 {
167 public:
168   /* Create a screen capture modules object
169    */
170   static VideoCaptureModule* Create(const int32_t id, const char* uniqueId, const CaptureDeviceType type);
171   static VideoCaptureModule::DeviceInfo* CreateDeviceInfo(const int32_t id, const CaptureDeviceType type);
172 
173   int32_t Init(const char* uniqueId, const CaptureDeviceType type);
174 
175   //Call backs
176   virtual void RegisterCaptureDataCallback(VideoCaptureDataCallback& dataCallback) override;
177   virtual void DeRegisterCaptureDataCallback() override;
178   virtual void RegisterCaptureCallback(VideoCaptureFeedBack& callBack) override;
179   virtual void DeRegisterCaptureCallback() override;
180 
181   virtual void SetCaptureDelay(int32_t delayMS) override;
182   virtual int32_t CaptureDelay() override;
183   virtual int32_t SetCaptureRotation(VideoRotation rotation) override;
184   virtual bool SetApplyRotation(bool enable) override;
GetApplyRotation()185   virtual bool GetApplyRotation() { return true; }
186 
187   virtual void EnableFrameRateCallback(const bool enable) override;
188   virtual void EnableNoPictureAlarm(const bool enable) override;
189 
190   virtual const char* CurrentDeviceName() const override;
191 
192   // Module handling
193   virtual int64_t TimeUntilNextProcess() override;
194   virtual int32_t Process() override;
195 
196   // Implement VideoCaptureExternal
197   // |capture_time| must be specified in the NTP time format in milliseconds.
198   virtual int32_t IncomingFrame(uint8_t* videoFrame,
199                                 size_t videoFrameLength,
200                                 const VideoCaptureCapability& frameInfo,
201                                 int64_t captureTime = 0) override;
202 
203   // Platform dependent
204   virtual int32_t StartCapture(const VideoCaptureCapability& capability) override;
205   virtual int32_t StopCapture() override;
206   virtual bool CaptureStarted() override;
207   virtual int32_t CaptureSettings(VideoCaptureCapability& settings) override;
GetEncodeInterface(const VideoCodec & codec)208   VideoCaptureEncodeInterface* GetEncodeInterface(const VideoCodec& codec) override { return NULL; }
209 
210   //ScreenCapturer::Callback
211   virtual SharedMemory* CreateSharedMemory(size_t size) override;
212   virtual void OnCaptureCompleted(DesktopFrame* frame) override;
213 
214 protected:
215   DesktopCaptureImpl(const int32_t id);
216   virtual ~DesktopCaptureImpl();
217   int32_t DeliverCapturedFrame(I420VideoFrame& captureFrame,
218                                int64_t capture_time);
219 
220   static const uint32_t kMaxDesktopCaptureCpuUsage = 50; // maximum CPU usage in %
221 
222   int32_t _id; // Module ID
223   std::string _deviceUniqueId; // current Device unique name;
224   CriticalSectionWrapper& _apiCs;
225   int32_t _captureDelay; // Current capture delay. May be changed of platform dependent parts.
226   VideoCaptureCapability _requestedCapability; // Should be set by platform dependent code in StartCapture.
227 
228 private:
229   void UpdateFrameCount();
230   uint32_t CalculateFrameRate(const TickTime& now);
231 
232   CriticalSectionWrapper& _callBackCs;
233 
234   TickTime _lastProcessTime; // last time the module process function was called.
235   TickTime _lastFrameRateCallbackTime; // last time the frame rate callback function was called.
236   bool _frameRateCallBack; // true if EnableFrameRateCallback
237   bool _noPictureAlarmCallBack; // true if EnableNoPictureAlarm
238   VideoCaptureAlarm _captureAlarm; // current value of the noPictureAlarm
239 
240   int32_t _setCaptureDelay; // The currently used capture delay
241   VideoCaptureDataCallback* _dataCallBack;
242   VideoCaptureFeedBack* _captureCallBack;
243 
244   TickTime _lastProcessFrameCount;
245   TickTime _incomingFrameTimes[kFrameRateCountHistorySize];// timestamp for local captured frames
246   VideoRotation _rotateFrame; //Set if the frame should be rotated by the capture module.
247 
248   I420VideoFrame _captureFrame;
249 
250   // Used to make sure incoming timestamp is increasing for every frame.
251   int64_t last_capture_time_;
252 
253   // Delta used for translating between NTP and internal timestamps.
254   const int64_t delta_ntp_internal_ms_;
255 
256 public:
Run(void * obj)257   static bool Run(void*obj) {
258     static_cast<DesktopCaptureImpl*>(obj)->process();
259     return true;
260   };
261   void process();
262 
263 private:
264   rtc::scoped_ptr<DesktopAndCursorComposer> desktop_capturer_cursor_composer_;
265   rtc::scoped_ptr<EventWrapper> time_event_;
266   rtc::scoped_ptr<ThreadWrapper> capturer_thread_;
267   bool started_;
268 };
269 
270 }  // namespace webrtc
271 
272 #endif  // WEBRTC_MODULES_DESKTOP_CAPTURE_MAIN_SOURCE_DESKTOP_CAPTURE_IMPL_H_
273