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 // 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.
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
);
92 // webrtc::DesktopCapturer::Callback implementation.
93 virtual webrtc::SharedMemory
* CreateSharedMemory(size_t size
) OVERRIDE
;
94 virtual void OnCaptureCompleted(webrtc::DesktopFrame
* frame
) OVERRIDE
;
96 // webrtc::ScreenCapturer::MouseShapeObserver implementation.
97 virtual void OnCursorShapeChanged(
98 webrtc::MouseCursorShape
* cursor_shape
) OVERRIDE
;
100 // Starts scheduling frame captures.
103 // Stop scheduling frame captures. This object cannot be re-used once
104 // it has been stopped.
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
);
111 // Updates the sequence number embedded in VideoPackets.
112 // Sequence numbers are used for performance measurements.
113 void UpdateSequenceNumber(int64 sequence_number
);
116 friend class base::RefCountedThreadSafe
<VideoScheduler
>;
117 virtual ~VideoScheduler();
119 // Capturer thread ----------------------------------------------------------
121 // Starts the capturer on the capture thread.
122 void StartOnCaptureThread();
124 // Stops scheduling frame captures on the capture thread.
125 void StopOnCaptureThread();
127 // Schedules the next call to CaptureNextFrame.
128 void ScheduleNextCapture();
130 // Starts the next frame capture, unless there are already too many pending.
131 void CaptureNextFrame();
133 // Called when a frame capture has been encoded & sent to the client.
134 void FrameCaptureCompleted();
136 // Network thread -----------------------------------------------------------
138 // Send |packet| to the client, unless we are in the process of stopping.
139 void SendVideoPacket(scoped_ptr
<VideoPacket
> packet
);
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();
145 // Send updated cursor shape to client.
146 void SendCursorShape(scoped_ptr
<protocol::CursorShapeInfo
> cursor_shape
);
148 // Encoder thread -----------------------------------------------------------
150 // Encode a frame, passing generated VideoPackets to SendVideoPacket().
151 void EncodeFrame(scoped_ptr
<webrtc::DesktopFrame
> frame
,
152 int64 sequence_number
);
154 void EncodedDataAvailableCallback(int64 sequence_number
,
155 scoped_ptr
<VideoPacket
> packet
);
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_
;
162 // Used to capture frames. Always accessed on the capture thread.
163 scoped_ptr
<webrtc::ScreenCapturer
> capturer_
;
165 // Used to encode captured frames. Always accessed on the encode thread.
166 scoped_ptr
<VideoEncoder
> encoder_
;
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_
;
173 // Timer used to schedule CaptureNextFrame().
174 scoped_ptr
<base::OneShotTimer
<VideoScheduler
> > capture_timer_
;
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
181 // Set when the capturer is capturing a frame.
182 bool capture_pending_
;
184 // True if the previous scheduled capture was skipped.
185 bool did_skip_frame_
;
187 // True if capture of video frames is paused.
190 // This is a number updated by client to trace performance.
191 int64 sequence_number_
;
193 // An object to schedule capturing.
194 CaptureScheduler scheduler_
;
196 DISALLOW_COPY_AND_ASSIGN(VideoScheduler
);
199 } // namespace remoting
201 #endif // REMOTING_HOST_VIDEO_SCHEDULER_H_