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