Home | History | Annotate | Download | only in host
      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