1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef REMOTING_HOST_VIDEO_SCHEDULER_H_ 6 #define REMOTING_HOST_VIDEO_SCHEDULER_H_ 7 8 #include <vector> 9 10 #include "base/basictypes.h" 11 #include "base/memory/ref_counted.h" 12 #include "base/memory/scoped_ptr.h" 13 #include "base/time/time.h" 14 #include "base/timer/timer.h" 15 #include "remoting/codec/video_encoder.h" 16 #include "remoting/host/capture_scheduler.h" 17 #include "remoting/proto/video.pb.h" 18 #include "third_party/webrtc/modules/desktop_capture/desktop_capturer.h" 19 #include "third_party/webrtc/modules/desktop_capture/mouse_cursor_monitor.h" 20 21 namespace base { 22 class SingleThreadTaskRunner; 23 } // namespace base 24 25 namespace media { 26 class DesktopCapturer; 27 } // namespace media 28 29 namespace remoting { 30 31 class CursorShapeInfo; 32 33 namespace protocol { 34 class CursorShapeInfo; 35 class CursorShapeStub; 36 class VideoStub; 37 } // namespace protocol 38 39 // Class responsible for scheduling frame captures from a 40 // webrtc::DesktopCapturer, delivering them to a VideoEncoder to encode, and 41 // finally passing the encoded video packets to the specified VideoStub to send 42 // on the network. 43 // 44 // THREADING 45 // 46 // This class is supplied TaskRunners to use for capture, encode and network 47 // operations. Capture, encode and network transmission tasks are interleaved 48 // as illustrated below: 49 // 50 // | CAPTURE ENCODE NETWORK 51 // | ............. 52 // | . Capture . 53 // | ............. 54 // | ............ 55 // | . . 56 // | ............. . . 57 // | . Capture . . Encode . 58 // | ............. . . 59 // | . . 60 // | ............ 61 // | ............. ............ .......... 62 // | . Capture . . . . Send . 63 // | ............. . . .......... 64 // | . Encode . 65 // | . . 66 // | . . 67 // | ............ 68 // | Time 69 // v 70 // 71 // VideoScheduler would ideally schedule captures so as to saturate the slowest 72 // of the capture, encode and network processes. However, it also needs to 73 // rate-limit captures to avoid overloading the host system, either by consuming 74 // too much CPU, or hogging the host's graphics subsystem. 75 76 class VideoScheduler : public base::RefCountedThreadSafe<VideoScheduler>, 77 public webrtc::DesktopCapturer::Callback, 78 public webrtc::MouseCursorMonitor::Callback { 79 public: 80 // Enables timestamps for generated frames. Used for testing. 81 static void EnableTimestampsForTests(); 82 83 // Creates a VideoScheduler running capture, encode and network tasks on the 84 // supplied TaskRunners. Video and cursor shape updates will be pumped to 85 // |video_stub| and |client_stub|, which must remain valid until Stop() is 86 // called. |capturer| is used to capture frames. 87 VideoScheduler( 88 scoped_refptr<base::SingleThreadTaskRunner> capture_task_runner, 89 scoped_refptr<base::SingleThreadTaskRunner> encode_task_runner, 90 scoped_refptr<base::SingleThreadTaskRunner> network_task_runner, 91 scoped_ptr<webrtc::DesktopCapturer> capturer, 92 scoped_ptr<webrtc::MouseCursorMonitor> mouse_cursor_monitor, 93 scoped_ptr<VideoEncoder> encoder, 94 protocol::CursorShapeStub* cursor_stub, 95 protocol::VideoStub* video_stub); 96 97 // webrtc::DesktopCapturer::Callback implementation. 98 virtual webrtc::SharedMemory* CreateSharedMemory(size_t size) OVERRIDE; 99 virtual void OnCaptureCompleted(webrtc::DesktopFrame* frame) OVERRIDE; 100 101 // webrtc::MouseCursorMonitor::Callback implementation. 102 virtual void OnMouseCursor( 103 webrtc::MouseCursor* mouse_cursor) OVERRIDE; 104 virtual void OnMouseCursorPosition( 105 webrtc::MouseCursorMonitor::CursorState state, 106 const webrtc::DesktopVector& position) OVERRIDE; 107 108 // Starts scheduling frame captures. 109 void Start(); 110 111 // Stop scheduling frame captures. This object cannot be re-used once 112 // it has been stopped. 113 void Stop(); 114 115 // Pauses or resumes scheduling of frame captures. Pausing/resuming captures 116 // only affects capture scheduling and does not stop/start the capturer. 117 void Pause(bool pause); 118 119 // Updates the sequence number embedded in VideoPackets. 120 // Sequence numbers are used for performance measurements. 121 void UpdateSequenceNumber(int64 sequence_number); 122 123 // Sets whether the video encoder should be requested to encode losslessly, 124 // or to use a lossless color space (typically requiring higher bandwidth). 125 void SetLosslessEncode(bool want_lossless); 126 void SetLosslessColor(bool want_lossless); 127 128 private: 129 friend class base::RefCountedThreadSafe<VideoScheduler>; 130 virtual ~VideoScheduler(); 131 132 // Capturer thread ---------------------------------------------------------- 133 134 // Starts the capturer on the capture thread. 135 void StartOnCaptureThread(); 136 137 // Stops scheduling frame captures on the capture thread. 138 void StopOnCaptureThread(); 139 140 // Schedules the next call to CaptureNextFrame. 141 void ScheduleNextCapture(); 142 143 // Starts the next frame capture, unless there are already too many pending. 144 void CaptureNextFrame(); 145 146 // Called when a frame capture has been encoded & sent to the client. 147 void FrameCaptureCompleted(); 148 149 // Network thread ----------------------------------------------------------- 150 151 // Send |packet| to the client, unless we are in the process of stopping. 152 void SendVideoPacket(scoped_ptr<VideoPacket> packet); 153 154 // Callback passed to |video_stub_| for the last packet in each frame, to 155 // rate-limit frame captures to network throughput. 156 void OnVideoPacketSent(); 157 158 // Called by |keep_alive_timer_|. 159 void SendKeepAlivePacket(); 160 161 // Callback for |video_stub_| called after a keep-alive packet is sent. 162 void OnKeepAlivePacketSent(); 163 164 // Send updated cursor shape to client. 165 void SendCursorShape(scoped_ptr<protocol::CursorShapeInfo> cursor_shape); 166 167 // Encoder thread ----------------------------------------------------------- 168 169 // Encode a frame, passing generated VideoPackets to SendVideoPacket(). 170 void EncodeFrame(scoped_ptr<webrtc::DesktopFrame> frame, 171 int64 sequence_number, 172 base::TimeTicks timestamp); 173 174 void EncodedDataAvailableCallback(int64 sequence_number, 175 scoped_ptr<VideoPacket> packet); 176 177 // Task runners used by this class. 178 scoped_refptr<base::SingleThreadTaskRunner> capture_task_runner_; 179 scoped_refptr<base::SingleThreadTaskRunner> encode_task_runner_; 180 scoped_refptr<base::SingleThreadTaskRunner> network_task_runner_; 181 182 // Used to capture frames. Always accessed on the capture thread. 183 scoped_ptr<webrtc::DesktopCapturer> capturer_; 184 185 // Used to capture mouse cursor shapes. Always accessed on the capture thread. 186 scoped_ptr<webrtc::MouseCursorMonitor> mouse_cursor_monitor_; 187 188 // Used to encode captured frames. Always accessed on the encode thread. 189 scoped_ptr<VideoEncoder> encoder_; 190 191 // Interfaces through which video frames and cursor shapes are passed to the 192 // client. These members are always accessed on the network thread. 193 protocol::CursorShapeStub* cursor_stub_; 194 protocol::VideoStub* video_stub_; 195 196 // Timer used to schedule CaptureNextFrame(). 197 scoped_ptr<base::OneShotTimer<VideoScheduler> > capture_timer_; 198 199 // Timer used to ensure that we send empty keep-alive frames to the client 200 // even when the video stream is paused or encoder is busy. 201 scoped_ptr<base::DelayTimer<VideoScheduler> > keep_alive_timer_; 202 203 // The number of frames being processed, i.e. frames that we are currently 204 // capturing, encoding or sending. The value is capped at 2 to minimize 205 // latency. 206 int pending_frames_; 207 208 // Set when the capturer is capturing a frame. 209 bool capture_pending_; 210 211 // True if the previous scheduled capture was skipped. 212 bool did_skip_frame_; 213 214 // True if capture of video frames is paused. 215 bool is_paused_; 216 217 // Number updated by the caller to trace performance. 218 int64 sequence_number_; 219 220 // An object to schedule capturing. 221 CaptureScheduler scheduler_; 222 223 DISALLOW_COPY_AND_ASSIGN(VideoScheduler); 224 }; 225 226 } // namespace remoting 227 228 #endif // REMOTING_HOST_VIDEO_SCHEDULER_H_ 229