• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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