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  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