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 private: 116 friend class base::RefCountedThreadSafe<VideoScheduler>; 117 virtual ~VideoScheduler(); 118 119 // Capturer thread ---------------------------------------------------------- 120 121 // Starts the capturer on the capture thread. 122 void StartOnCaptureThread(); 123 124 // Stops scheduling frame captures on the capture thread. 125 void StopOnCaptureThread(); 126 127 // Schedules the next call to CaptureNextFrame. 128 void ScheduleNextCapture(); 129 130 // Starts the next frame capture, unless there are already too many pending. 131 void CaptureNextFrame(); 132 133 // Called when a frame capture has been encoded & sent to the client. 134 void FrameCaptureCompleted(); 135 136 // Network thread ----------------------------------------------------------- 137 138 // Send |packet| to the client, unless we are in the process of stopping. 139 void SendVideoPacket(scoped_ptr<VideoPacket> packet); 140 141 // Callback passed to |video_stub_| for the last packet in each frame, to 142 // rate-limit frame captures to network throughput. 143 void VideoFrameSentCallback(); 144 145 // Send updated cursor shape to client. 146 void SendCursorShape(scoped_ptr<protocol::CursorShapeInfo> cursor_shape); 147 148 // Encoder thread ----------------------------------------------------------- 149 150 // Encode a frame, passing generated VideoPackets to SendVideoPacket(). 151 void EncodeFrame(scoped_ptr<webrtc::DesktopFrame> frame, 152 int64 sequence_number); 153 154 void EncodedDataAvailableCallback(int64 sequence_number, 155 scoped_ptr<VideoPacket> packet); 156 157 // Task runners used by this class. 158 scoped_refptr<base::SingleThreadTaskRunner> capture_task_runner_; 159 scoped_refptr<base::SingleThreadTaskRunner> encode_task_runner_; 160 scoped_refptr<base::SingleThreadTaskRunner> network_task_runner_; 161 162 // Used to capture frames. Always accessed on the capture thread. 163 scoped_ptr<webrtc::ScreenCapturer> capturer_; 164 165 // Used to encode captured frames. Always accessed on the encode thread. 166 scoped_ptr<VideoEncoder> encoder_; 167 168 // Interfaces through which video frames and cursor shapes are passed to the 169 // client. These members are always accessed on the network thread. 170 protocol::CursorShapeStub* cursor_stub_; 171 protocol::VideoStub* video_stub_; 172 173 // Timer used to schedule CaptureNextFrame(). 174 scoped_ptr<base::OneShotTimer<VideoScheduler> > capture_timer_; 175 176 // The number of frames being processed, i.e. frames that we are currently 177 // capturing, encoding or sending. The value is capped at 2 to minimize 178 // latency. 179 int pending_frames_; 180 181 // Set when the capturer is capturing a frame. 182 bool capture_pending_; 183 184 // True if the previous scheduled capture was skipped. 185 bool did_skip_frame_; 186 187 // True if capture of video frames is paused. 188 bool is_paused_; 189 190 // This is a number updated by client to trace performance. 191 int64 sequence_number_; 192 193 // An object to schedule capturing. 194 CaptureScheduler scheduler_; 195 196 DISALLOW_COPY_AND_ASSIGN(VideoScheduler); 197 }; 198 199 } // namespace remoting 200 201 #endif // REMOTING_HOST_VIDEO_SCHEDULER_H_ 202