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.
5 #ifndef REMOTING_HOST_VIDEO_SCHEDULER_H_
6 #define REMOTING_HOST_VIDEO_SCHEDULER_H_
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"
21 class SingleThreadTaskRunner
;
30 class CursorShapeInfo
;
33 class CursorShapeInfo
;
34 class CursorShapeStub
;
36 } // namespace protocol
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
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:
49 // | CAPTURE ENCODE NETWORK
55 // | ............. . .
56 // | . Capture . . Encode .
57 // | ............. . .
60 // | ............. ............ ..........
61 // | . Capture . . . . Send .
62 // | ............. . . ..........
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.
75 class VideoScheduler
: public base::RefCountedThreadSafe
<VideoScheduler
>,
76 public webrtc::DesktopCapturer::Callback
,
77 public webrtc::ScreenCapturer::MouseShapeObserver
{
79 // Enables timestamps for generated frames. Used for testing.
80 static void EnableTimestampsForTests();
82 // Creates a VideoScheduler running capture, encode and network tasks on the
83 // supplied TaskRunners. Video and cursor shape updates will be pumped to
84 // |video_stub| and |client_stub|, which must remain valid until Stop() is
85 // called. |capturer| is used to capture frames.
87 scoped_refptr
<base::SingleThreadTaskRunner
> capture_task_runner
,
88 scoped_refptr
<base::SingleThreadTaskRunner
> encode_task_runner
,
89 scoped_refptr
<base::SingleThreadTaskRunner
> network_task_runner
,
90 scoped_ptr
<webrtc::ScreenCapturer
> capturer
,
91 scoped_ptr
<VideoEncoder
> encoder
,
92 protocol::CursorShapeStub
* cursor_stub
,
93 protocol::VideoStub
* video_stub
);
95 // webrtc::DesktopCapturer::Callback implementation.
96 virtual webrtc::SharedMemory
* CreateSharedMemory(size_t size
) OVERRIDE
;
97 virtual void OnCaptureCompleted(webrtc::DesktopFrame
* frame
) OVERRIDE
;
99 // webrtc::ScreenCapturer::MouseShapeObserver implementation.
100 virtual void OnCursorShapeChanged(
101 webrtc::MouseCursorShape
* cursor_shape
) OVERRIDE
;
103 // Starts scheduling frame captures.
106 // Stop scheduling frame captures. This object cannot be re-used once
107 // it has been stopped.
110 // Pauses or resumes scheduling of frame captures. Pausing/resuming captures
111 // only affects capture scheduling and does not stop/start the capturer.
112 void Pause(bool pause
);
114 // Updates the sequence number embedded in VideoPackets.
115 // Sequence numbers are used for performance measurements.
116 void UpdateSequenceNumber(int64 sequence_number
);
118 // Sets whether the video encoder should be requested to encode losslessly,
119 // or to use a lossless color space (typically requiring higher bandwidth).
120 void SetLosslessEncode(bool want_lossless
);
121 void SetLosslessColor(bool want_lossless
);
124 friend class base::RefCountedThreadSafe
<VideoScheduler
>;
125 virtual ~VideoScheduler();
127 // Capturer thread ----------------------------------------------------------
129 // Starts the capturer on the capture thread.
130 void StartOnCaptureThread();
132 // Stops scheduling frame captures on the capture thread.
133 void StopOnCaptureThread();
135 // Schedules the next call to CaptureNextFrame.
136 void ScheduleNextCapture();
138 // Starts the next frame capture, unless there are already too many pending.
139 void CaptureNextFrame();
141 // Called when a frame capture has been encoded & sent to the client.
142 void FrameCaptureCompleted();
144 // Network thread -----------------------------------------------------------
146 // Send |packet| to the client, unless we are in the process of stopping.
147 void SendVideoPacket(scoped_ptr
<VideoPacket
> packet
);
149 // Callback passed to |video_stub_| for the last packet in each frame, to
150 // rate-limit frame captures to network throughput.
151 void OnVideoPacketSent();
153 // Called by |keep_alive_timer_|.
154 void SendKeepAlivePacket();
156 // Callback for |video_stub_| called after a keep-alive packet is sent.
157 void OnKeepAlivePacketSent();
159 // Send updated cursor shape to client.
160 void SendCursorShape(scoped_ptr
<protocol::CursorShapeInfo
> cursor_shape
);
162 // Encoder thread -----------------------------------------------------------
164 // Encode a frame, passing generated VideoPackets to SendVideoPacket().
165 void EncodeFrame(scoped_ptr
<webrtc::DesktopFrame
> frame
,
166 int64 sequence_number
,
167 base::TimeTicks timestamp
);
169 void EncodedDataAvailableCallback(int64 sequence_number
,
170 scoped_ptr
<VideoPacket
> packet
);
172 // Task runners used by this class.
173 scoped_refptr
<base::SingleThreadTaskRunner
> capture_task_runner_
;
174 scoped_refptr
<base::SingleThreadTaskRunner
> encode_task_runner_
;
175 scoped_refptr
<base::SingleThreadTaskRunner
> network_task_runner_
;
177 // Used to capture frames. Always accessed on the capture thread.
178 scoped_ptr
<webrtc::ScreenCapturer
> capturer_
;
180 // Used to encode captured frames. Always accessed on the encode thread.
181 scoped_ptr
<VideoEncoder
> encoder_
;
183 // Interfaces through which video frames and cursor shapes are passed to the
184 // client. These members are always accessed on the network thread.
185 protocol::CursorShapeStub
* cursor_stub_
;
186 protocol::VideoStub
* video_stub_
;
188 // Timer used to schedule CaptureNextFrame().
189 scoped_ptr
<base::OneShotTimer
<VideoScheduler
> > capture_timer_
;
191 // Timer used to ensure that we send empty keep-alive frames to the client
192 // even when the video stream is paused or encoder is busy.
193 scoped_ptr
<base::DelayTimer
<VideoScheduler
> > keep_alive_timer_
;
195 // The number of frames being processed, i.e. frames that we are currently
196 // capturing, encoding or sending. The value is capped at 2 to minimize
200 // Set when the capturer is capturing a frame.
201 bool capture_pending_
;
203 // True if the previous scheduled capture was skipped.
204 bool did_skip_frame_
;
206 // True if capture of video frames is paused.
209 // Number updated by the caller to trace performance.
210 int64 sequence_number_
;
212 // An object to schedule capturing.
213 CaptureScheduler scheduler_
;
215 DISALLOW_COPY_AND_ASSIGN(VideoScheduler
);
218 } // namespace remoting
220 #endif // REMOTING_HOST_VIDEO_SCHEDULER_H_