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 20namespace base { 21class SingleThreadTaskRunner; 22} // namespace base 23 24namespace media { 25class ScreenCapturer; 26} // namespace media 27 28namespace remoting { 29 30class CursorShapeInfo; 31 32namespace protocol { 33class CursorShapeInfo; 34class CursorShapeStub; 35class 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 75class 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