summaryrefslogtreecommitdiffstats
path: root/remoting/host/screen_recorder.h
blob: 2cd02b1cfe0cc37bed6262e436689e75e8c92727 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef REMOTING_HOST_SCREEN_RECORDER_H_
#define REMOTING_HOST_SCREEN_RECORDER_H_

#include <vector>

#include "base/basictypes.h"
#include "base/message_loop.h"
#include "base/ref_counted.h"
#include "base/scoped_ptr.h"
#include "base/time.h"
#include "remoting/base/encoder.h"
#include "remoting/host/capturer.h"
#include "remoting/proto/video.pb.h"

namespace remoting {

namespace protocol {
class ConnectionToClient;
}  // namespace protocol

class CaptureData;

// A class for controlling and coordinate Capturer, Encoder
// and NetworkChannel in a record session.
//
// THREADING
//
// This class works on three threads, namely capture, encode and network
// thread. The main function of this class is to coordinate and schedule
// capture, encode and transmission of data on different threads.
//
// The following is an example of timeline for operations scheduled.
//
// |       CAPTURE       ENCODE     NETWORK
// |    .............
// |    .  Capture  .
// |    .............
// |                  ............
// |                  .          .
// |    ............. .          .
// |    .  Capture  . .  Encode  .
// |    ............. .          .
// |                  .          .
// |                  ............
// |    ............. ............ ..........
// |    .  Capture  . .          . .  Send  .
// |    ............. .          . ..........
// |                  .  Encode  .
// |                  .          .
// |                  .          .
// |                  ............
// | Time
// v
//
// ScreenRecorder has the following responsibilities:
// 1. Make sure capture and encode occurs no more frequently than |rate|.
// 2. Make sure there is at most one outstanding capture not being encoded.
// 3. Distribute tasks on three threads on a timely fashion to minimize latency.
class ScreenRecorder : public base::RefCountedThreadSafe<ScreenRecorder> {
 public:

  // Construct a ScreenRecorder. Message loops and threads are provided.
  // This object does not own capturer and encoder.
  ScreenRecorder(MessageLoop* capture_loop,
                 MessageLoop* encode_loop,
                 MessageLoop* network_loop,
                 Capturer* capturer,
                 Encoder* encoder);

  virtual ~ScreenRecorder();

  // Start recording.
  void Start();

  // Pause the recording session.
  void Pause();

  // Set the maximum capture rate. This is denoted by number of updates
  // in one second. The actual system may run in a slower rate than the maximum
  // rate due to various factors, e.g. capture speed, encode speed and network
  // conditions.
  // This method should be called before Start() is called.
  void SetMaxRate(double rate);

  // Add a connection to this recording session.
  void AddConnection(scoped_refptr<protocol::ConnectionToClient> connection);

  // Remove a connection from receiving screen updates.
  void RemoveConnection(scoped_refptr<protocol::ConnectionToClient> connection);

  // Remove all connections.
  void RemoveAllConnections();

 private:
  // Getters for capturer and encoder.
  Capturer* capturer();
  Encoder* encoder();

  // Capturer thread ----------------------------------------------------------

  void DoStart();
  void DoPause();

  void DoSetRate(double rate);
  void DoSetMaxRate(double max_rate);

  // Hepler method to schedule next capture using the current rate.
  void ScheduleNextCapture();

  void DoCapture();
  void CaptureDoneCallback(scoped_refptr<CaptureData> capture_data);
  void DoFinishEncode();

  void DoGetInitInfo(scoped_refptr<protocol::ConnectionToClient> client);

  // Network thread -----------------------------------------------------------

  void DoStartRateControl();
  void DoPauseRateControl();

  // Helper method to schedule next rate regulation task.
  void ScheduleNextRateControl();

  void DoRateControl();

  // DoSendUpdate takes ownership of header and is responsible for deleting it.
  void DoSendVideoPacket(VideoPacket* packet);
  void DoSendInit(scoped_refptr<protocol::ConnectionToClient> connection,
                  int width, int height);

  void DoAddClient(scoped_refptr<protocol::ConnectionToClient> connection);
  void DoRemoveClient(scoped_refptr<protocol::ConnectionToClient> connection);
  void DoRemoveAllClients();

  // Encoder thread -----------------------------------------------------------

  void DoEncode(scoped_refptr<CaptureData> capture_data);

  // EncodeDataAvailableTask takes ownership of header and is responsible for
  // deleting it.
  void EncodeDataAvailableTask(VideoPacket* packet);

  // Message loops used by this class.
  MessageLoop* capture_loop_;
  MessageLoop* encode_loop_;
  MessageLoop* network_loop_;

  // Reference to the capturer. This member is always accessed on the capture
  // thread.
  scoped_ptr<Capturer> capturer_;

  // Reference to the encoder. This member is always accessed on the encode
  // thread.
  scoped_ptr<Encoder> encoder_;

  // A list of clients connected to this hosts.
  // This member is always accessed on the NETWORK thread.
  // TODO(hclam): Have to scoped_refptr the clients since they have a shorter
  // lifetime than this object.
  typedef std::vector<scoped_refptr<protocol::ConnectionToClient> >
      ConnectionToClientList;
  ConnectionToClientList connections_;

  // The following members are accessed on the capture thread.
  double rate_;  // Number of captures to perform every second.
  bool started_;
  base::Time last_capture_time_; // Saves the time last capture started.
  int recordings_; // Count the number of recordings
                   // (i.e. capture or encode) happening.

  // The maximum rate is written on the capture thread and read on the network
  // thread.
  double max_rate_;  // Number of captures to perform every second.

  // The following member is accessed on the network thread.
  bool rate_control_started_;

  DISALLOW_COPY_AND_ASSIGN(ScreenRecorder);
};

}  // namespace remoting

#endif  // REMOTING_HOST_SCREEN_RECORDER_H_