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/skia/include/core/SkSize.h"
     19 #include "third_party/webrtc/modules/desktop_capture/screen_capturer.h"
     20 
     21 namespace base {
     22 class SingleThreadTaskRunner;
     23 }  // namespace base
     24 
     25 namespace media {
     26 class ScreenCapturer;
     27 }  // namespace media
     28 
     29 namespace remoting {
     30 
     31 class CursorShapeInfo;
     32 
     33 namespace protocol {
     34 class CursorShapeInfo;
     35 class CursorShapeStub;
     36 class VideoStub;
     37 }  // namespace protocol
     38 
     39 // Class responsible for scheduling frame captures from a
     40 // webrtc::ScreenCapturer, delivering them to a VideoEncoder to encode, and
     41 // finally passing the encoded video packets to the specified VideoStub to send
     42 // on the network.
     43 //
     44 // THREADING
     45 //
     46 // This class is supplied TaskRunners to use for capture, encode and network
     47 // operations.  Capture, encode and network transmission tasks are interleaved
     48 // as illustrated below:
     49 //
     50 // |       CAPTURE       ENCODE     NETWORK
     51 // |    .............
     52 // |    .  Capture  .
     53 // |    .............
     54 // |                  ............
     55 // |                  .          .
     56 // |    ............. .          .
     57 // |    .  Capture  . .  Encode  .
     58 // |    ............. .          .
     59 // |                  .          .
     60 // |                  ............
     61 // |    ............. ............ ..........
     62 // |    .  Capture  . .          . .  Send  .
     63 // |    ............. .          . ..........
     64 // |                  .  Encode  .
     65 // |                  .          .
     66 // |                  .          .
     67 // |                  ............
     68 // | Time
     69 // v
     70 //
     71 // VideoScheduler would ideally schedule captures so as to saturate the slowest
     72 // of the capture, encode and network processes.  However, it also needs to
     73 // rate-limit captures to avoid overloading the host system, either by consuming
     74 // too much CPU, or hogging the host's graphics subsystem.
     75 
     76 class VideoScheduler : public base::RefCountedThreadSafe<VideoScheduler>,
     77                        public webrtc::DesktopCapturer::Callback,
     78                        public webrtc::ScreenCapturer::MouseShapeObserver {
     79  public:
     80   // Creates a VideoScheduler running capture, encode and network tasks on the
     81   // supplied TaskRunners.  Video and cursor shape updates will be pumped to
     82   // |video_stub| and |client_stub|, which must remain valid until Stop() is
     83   // called. |capturer| is used to capture frames.
     84   VideoScheduler(
     85       scoped_refptr<base::SingleThreadTaskRunner> capture_task_runner,
     86       scoped_refptr<base::SingleThreadTaskRunner> encode_task_runner,
     87       scoped_refptr<base::SingleThreadTaskRunner> network_task_runner,
     88       scoped_ptr<webrtc::ScreenCapturer> capturer,
     89       scoped_ptr<VideoEncoder> encoder,
     90       protocol::CursorShapeStub* cursor_stub,
     91       protocol::VideoStub* video_stub);
     92 
     93   // webrtc::DesktopCapturer::Callback implementation.
     94   virtual webrtc::SharedMemory* CreateSharedMemory(size_t size) OVERRIDE;
     95   virtual void OnCaptureCompleted(webrtc::DesktopFrame* frame) OVERRIDE;
     96 
     97   // webrtc::ScreenCapturer::MouseShapeObserver implementation.
     98   virtual void OnCursorShapeChanged(
     99       webrtc::MouseCursorShape* cursor_shape) OVERRIDE;
    100 
    101   // Starts scheduling frame captures.
    102   void Start();
    103 
    104   // Stop scheduling frame captures. This object cannot be re-used once
    105   // it has been stopped.
    106   void Stop();
    107 
    108   // Pauses or resumes scheduling of frame captures.  Pausing/resuming captures
    109   // only affects capture scheduling and does not stop/start the capturer.
    110   void Pause(bool pause);
    111 
    112   // Updates the sequence number embedded in VideoPackets.
    113   // Sequence numbers are used for performance measurements.
    114   void UpdateSequenceNumber(int64 sequence_number);
    115 
    116  private:
    117   friend class base::RefCountedThreadSafe<VideoScheduler>;
    118   virtual ~VideoScheduler();
    119 
    120   // Capturer thread ----------------------------------------------------------
    121 
    122   // Starts the capturer on the capture thread.
    123   void StartOnCaptureThread();
    124 
    125   // Stops scheduling frame captures on the capture thread.
    126   void StopOnCaptureThread();
    127 
    128   // Schedules the next call to CaptureNextFrame.
    129   void ScheduleNextCapture();
    130 
    131   // Starts the next frame capture, unless there are already too many pending.
    132   void CaptureNextFrame();
    133 
    134   // Called when a frame capture has been encoded & sent to the client.
    135   void FrameCaptureCompleted();
    136 
    137   // Network thread -----------------------------------------------------------
    138 
    139   // Send |packet| to the client, unless we are in the process of stopping.
    140   void SendVideoPacket(scoped_ptr<VideoPacket> packet);
    141 
    142   // Callback passed to |video_stub_| for the last packet in each frame, to
    143   // rate-limit frame captures to network throughput.
    144   void VideoFrameSentCallback();
    145 
    146   // Send updated cursor shape to client.
    147   void SendCursorShape(scoped_ptr<protocol::CursorShapeInfo> cursor_shape);
    148 
    149   // Encoder thread -----------------------------------------------------------
    150 
    151   // Encode a frame, passing generated VideoPackets to SendVideoPacket().
    152   void EncodeFrame(scoped_ptr<webrtc::DesktopFrame> frame,
    153                    int64 sequence_number);
    154 
    155   void EncodedDataAvailableCallback(int64 sequence_number,
    156                                     scoped_ptr<VideoPacket> packet);
    157 
    158   // Task runners used by this class.
    159   scoped_refptr<base::SingleThreadTaskRunner> capture_task_runner_;
    160   scoped_refptr<base::SingleThreadTaskRunner> encode_task_runner_;
    161   scoped_refptr<base::SingleThreadTaskRunner> network_task_runner_;
    162 
    163   // Used to capture frames. Always accessed on the capture thread.
    164   scoped_ptr<webrtc::ScreenCapturer> capturer_;
    165 
    166   // Used to encode captured frames. Always accessed on the encode thread.
    167   scoped_ptr<VideoEncoder> encoder_;
    168 
    169   // Interfaces through which video frames and cursor shapes are passed to the
    170   // client. These members are always accessed on the network thread.
    171   protocol::CursorShapeStub* cursor_stub_;
    172   protocol::VideoStub* video_stub_;
    173 
    174   // Timer used to schedule CaptureNextFrame().
    175   scoped_ptr<base::OneShotTimer<VideoScheduler> > capture_timer_;
    176 
    177   // The number of frames being processed, i.e. frames that we are currently
    178   // capturing, encoding or sending. The value is capped at 2 to minimize
    179   // latency.
    180   int pending_frames_;
    181 
    182   // Set when the capturer is capturing a frame.
    183   bool capture_pending_;
    184 
    185   // True if the previous scheduled capture was skipped.
    186   bool did_skip_frame_;
    187 
    188   // True if capture of video frames is paused.
    189   bool is_paused_;
    190 
    191   // This is a number updated by client to trace performance.
    192   int64 sequence_number_;
    193 
    194   // An object to schedule capturing.
    195   CaptureScheduler scheduler_;
    196 
    197   DISALLOW_COPY_AND_ASSIGN(VideoScheduler);
    198 };
    199 
    200 }  // namespace remoting
    201 
    202 #endif  // REMOTING_HOST_VIDEO_SCHEDULER_H_
    203