OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "remoting/host/video_frame_recorder.h" | 5 #include "remoting/host/video_frame_recorder.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/location.h" | 8 #include "base/location.h" |
9 #include "base/single_thread_task_runner.h" | 9 #include "base/single_thread_task_runner.h" |
10 #include "base/stl_util.h" | 10 #include "base/stl_util.h" |
(...skipping 16 matching lines...) Expand all Loading... |
27 public: | 27 public: |
28 RecordingVideoEncoder(scoped_ptr<VideoEncoder> encoder, | 28 RecordingVideoEncoder(scoped_ptr<VideoEncoder> encoder, |
29 scoped_refptr<base::TaskRunner> recorder_task_runner, | 29 scoped_refptr<base::TaskRunner> recorder_task_runner, |
30 base::WeakPtr<VideoFrameRecorder> recorder) | 30 base::WeakPtr<VideoFrameRecorder> recorder) |
31 : encoder_(encoder.Pass()), | 31 : encoder_(encoder.Pass()), |
32 recorder_task_runner_(recorder_task_runner), | 32 recorder_task_runner_(recorder_task_runner), |
33 recorder_(recorder), | 33 recorder_(recorder), |
34 enable_recording_(false), | 34 enable_recording_(false), |
35 weak_factory_(this) { | 35 weak_factory_(this) { |
36 DCHECK(encoder_); | 36 DCHECK(encoder_); |
37 DCHECK(recorder_task_runner_); | 37 DCHECK(recorder_task_runner_.get()); |
38 } | 38 } |
39 | 39 |
40 base::WeakPtr<RecordingVideoEncoder> AsWeakPtr() { | 40 base::WeakPtr<RecordingVideoEncoder> AsWeakPtr() { |
41 return weak_factory_.GetWeakPtr(); | 41 return weak_factory_.GetWeakPtr(); |
42 } | 42 } |
43 | 43 |
44 void SetEnableRecording(bool enable_recording) { | 44 void SetEnableRecording(bool enable_recording) { |
45 DCHECK(!encoder_task_runner_ || | 45 DCHECK(!encoder_task_runner_.get() || |
46 encoder_task_runner_->BelongsToCurrentThread()); | 46 encoder_task_runner_->BelongsToCurrentThread()); |
47 enable_recording_ = enable_recording; | 47 enable_recording_ = enable_recording; |
48 } | 48 } |
49 | 49 |
50 // remoting::VideoEncoder interface. | 50 // remoting::VideoEncoder interface. |
51 virtual void SetLosslessEncode(bool want_lossless) OVERRIDE { | 51 virtual void SetLosslessEncode(bool want_lossless) OVERRIDE { |
52 encoder_->SetLosslessEncode(want_lossless); | 52 encoder_->SetLosslessEncode(want_lossless); |
53 } | 53 } |
54 virtual void SetLosslessColor(bool want_lossless) OVERRIDE { | 54 virtual void SetLosslessColor(bool want_lossless) OVERRIDE { |
55 encoder_->SetLosslessColor(want_lossless); | 55 encoder_->SetLosslessColor(want_lossless); |
56 } | 56 } |
57 virtual scoped_ptr<VideoPacket> Encode( | 57 virtual scoped_ptr<VideoPacket> Encode( |
58 const webrtc::DesktopFrame& frame) OVERRIDE { | 58 const webrtc::DesktopFrame& frame) OVERRIDE { |
59 // If this is the first Encode() then store the TaskRunner and inform the | 59 // If this is the first Encode() then store the TaskRunner and inform the |
60 // VideoFrameRecorder so it can post SetEnableRecording() on it. | 60 // VideoFrameRecorder so it can post SetEnableRecording() on it. |
61 if (!encoder_task_runner_) { | 61 if (!encoder_task_runner_.get()) { |
62 encoder_task_runner_ = base::ThreadTaskRunnerHandle::Get(); | 62 encoder_task_runner_ = base::ThreadTaskRunnerHandle::Get(); |
63 recorder_task_runner_->PostTask(FROM_HERE, | 63 recorder_task_runner_->PostTask(FROM_HERE, |
64 base::Bind(&VideoFrameRecorder::SetEncoderTaskRunner, | 64 base::Bind(&VideoFrameRecorder::SetEncoderTaskRunner, |
65 recorder_, | 65 recorder_, |
66 encoder_task_runner_)); | 66 encoder_task_runner_)); |
67 } | 67 } |
68 | 68 |
69 DCHECK(encoder_task_runner_->BelongsToCurrentThread()); | 69 DCHECK(encoder_task_runner_->BelongsToCurrentThread()); |
70 | 70 |
71 if (enable_recording_) { | 71 if (enable_recording_) { |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
105 enable_recording_(false), | 105 enable_recording_(false), |
106 weak_factory_(this) { | 106 weak_factory_(this) { |
107 } | 107 } |
108 | 108 |
109 VideoFrameRecorder::~VideoFrameRecorder() { | 109 VideoFrameRecorder::~VideoFrameRecorder() { |
110 DetachVideoEncoderWrapper(); | 110 DetachVideoEncoderWrapper(); |
111 } | 111 } |
112 | 112 |
113 scoped_ptr<VideoEncoder> VideoFrameRecorder::WrapVideoEncoder( | 113 scoped_ptr<VideoEncoder> VideoFrameRecorder::WrapVideoEncoder( |
114 scoped_ptr<VideoEncoder> encoder) { | 114 scoped_ptr<VideoEncoder> encoder) { |
115 DCHECK(!encoder_task_runner_); | 115 DCHECK(!encoder_task_runner_.get()); |
116 DCHECK(!caller_task_runner_); | 116 DCHECK(!caller_task_runner_.get()); |
117 caller_task_runner_ = base::ThreadTaskRunnerHandle::Get(); | 117 caller_task_runner_ = base::ThreadTaskRunnerHandle::Get(); |
118 | 118 |
119 scoped_ptr<RecordingVideoEncoder> recording_encoder( | 119 scoped_ptr<RecordingVideoEncoder> recording_encoder( |
120 new RecordingVideoEncoder(encoder.Pass(), | 120 new RecordingVideoEncoder(encoder.Pass(), |
121 caller_task_runner_, | 121 caller_task_runner_, |
122 weak_factory_.GetWeakPtr())); | 122 weak_factory_.GetWeakPtr())); |
123 recording_encoder_ = recording_encoder->AsWeakPtr(); | 123 recording_encoder_ = recording_encoder->AsWeakPtr(); |
124 | 124 |
125 return recording_encoder.PassAs<VideoEncoder>(); | 125 return recording_encoder.PassAs<VideoEncoder>(); |
126 } | 126 } |
127 | 127 |
128 void VideoFrameRecorder::DetachVideoEncoderWrapper() { | 128 void VideoFrameRecorder::DetachVideoEncoderWrapper() { |
129 DCHECK(!caller_task_runner_ || caller_task_runner_->BelongsToCurrentThread()); | 129 DCHECK(!caller_task_runner_.get() || |
| 130 caller_task_runner_->BelongsToCurrentThread()); |
130 | 131 |
131 // Immediately detach the wrapper from this recorder. | 132 // Immediately detach the wrapper from this recorder. |
132 weak_factory_.InvalidateWeakPtrs(); | 133 weak_factory_.InvalidateWeakPtrs(); |
133 | 134 |
134 // Clean up any pending recorded frames. | 135 // Clean up any pending recorded frames. |
135 STLDeleteElements(&recorded_frames_); | 136 STLDeleteElements(&recorded_frames_); |
136 content_bytes_ = 0; | 137 content_bytes_ = 0; |
137 | 138 |
138 // Tell the wrapper to stop recording and posting frames to us. | 139 // Tell the wrapper to stop recording and posting frames to us. |
139 if (encoder_task_runner_) { | 140 if (encoder_task_runner_.get()) { |
140 encoder_task_runner_->PostTask(FROM_HERE, | 141 encoder_task_runner_->PostTask(FROM_HERE, |
141 base::Bind(&RecordingVideoEncoder::SetEnableRecording, | 142 base::Bind(&RecordingVideoEncoder::SetEnableRecording, |
142 recording_encoder_, false)); | 143 recording_encoder_, false)); |
143 } | 144 } |
144 | 145 |
145 // Detach this recorder from the calling and encode threads. | 146 // Detach this recorder from the calling and encode threads. |
146 caller_task_runner_ = NULL; | 147 caller_task_runner_ = NULL; |
147 encoder_task_runner_ = NULL; | 148 encoder_task_runner_ = NULL; |
148 } | 149 } |
149 | 150 |
150 void VideoFrameRecorder::SetEnableRecording(bool enable_recording) { | 151 void VideoFrameRecorder::SetEnableRecording(bool enable_recording) { |
151 DCHECK(!caller_task_runner_ || caller_task_runner_->BelongsToCurrentThread()); | 152 DCHECK(!caller_task_runner_.get() || |
| 153 caller_task_runner_->BelongsToCurrentThread()); |
152 | 154 |
153 if (enable_recording_ == enable_recording) { | 155 if (enable_recording_ == enable_recording) { |
154 return; | 156 return; |
155 } | 157 } |
156 enable_recording_ = enable_recording; | 158 enable_recording_ = enable_recording; |
157 | 159 |
158 if (encoder_task_runner_) { | 160 if (encoder_task_runner_.get()) { |
159 encoder_task_runner_->PostTask(FROM_HERE, | 161 encoder_task_runner_->PostTask(FROM_HERE, |
160 base::Bind(&RecordingVideoEncoder::SetEnableRecording, | 162 base::Bind(&RecordingVideoEncoder::SetEnableRecording, |
161 recording_encoder_, | 163 recording_encoder_, |
162 enable_recording_)); | 164 enable_recording_)); |
163 } | 165 } |
164 } | 166 } |
165 | 167 |
166 void VideoFrameRecorder::SetMaxContentBytes(int64_t max_content_bytes) { | 168 void VideoFrameRecorder::SetMaxContentBytes(int64_t max_content_bytes) { |
167 DCHECK(!caller_task_runner_ || caller_task_runner_->BelongsToCurrentThread()); | 169 DCHECK(!caller_task_runner_.get() || |
| 170 caller_task_runner_->BelongsToCurrentThread()); |
168 DCHECK_GE(max_content_bytes, 0); | 171 DCHECK_GE(max_content_bytes, 0); |
169 | 172 |
170 max_content_bytes_ = max_content_bytes; | 173 max_content_bytes_ = max_content_bytes; |
171 } | 174 } |
172 | 175 |
173 scoped_ptr<webrtc::DesktopFrame> VideoFrameRecorder::NextFrame() { | 176 scoped_ptr<webrtc::DesktopFrame> VideoFrameRecorder::NextFrame() { |
174 DCHECK(caller_task_runner_->BelongsToCurrentThread()); | 177 DCHECK(caller_task_runner_->BelongsToCurrentThread()); |
175 | 178 |
176 scoped_ptr<webrtc::DesktopFrame> frame; | 179 scoped_ptr<webrtc::DesktopFrame> frame; |
177 if (!recorded_frames_.empty()) { | 180 if (!recorded_frames_.empty()) { |
178 frame.reset(recorded_frames_.front()); | 181 frame.reset(recorded_frames_.front()); |
179 recorded_frames_.pop_front(); | 182 recorded_frames_.pop_front(); |
180 content_bytes_ -= FrameContentSize(frame.get()); | 183 content_bytes_ -= FrameContentSize(frame.get()); |
181 DCHECK_GE(content_bytes_, 0); | 184 DCHECK_GE(content_bytes_, 0); |
182 } | 185 } |
183 | 186 |
184 return frame.Pass(); | 187 return frame.Pass(); |
185 } | 188 } |
186 | 189 |
187 void VideoFrameRecorder::SetEncoderTaskRunner( | 190 void VideoFrameRecorder::SetEncoderTaskRunner( |
188 scoped_refptr<base::TaskRunner> task_runner) { | 191 scoped_refptr<base::TaskRunner> task_runner) { |
189 DCHECK(caller_task_runner_->BelongsToCurrentThread()); | 192 DCHECK(caller_task_runner_->BelongsToCurrentThread()); |
190 DCHECK(!encoder_task_runner_); | 193 DCHECK(!encoder_task_runner_.get()); |
191 DCHECK(task_runner); | 194 DCHECK(task_runner.get()); |
192 | 195 |
193 encoder_task_runner_ = task_runner; | 196 encoder_task_runner_ = task_runner; |
194 | 197 |
195 // If the caller already enabled recording, inform the recording encoder. | 198 // If the caller already enabled recording, inform the recording encoder. |
196 if (enable_recording_ && encoder_task_runner_) { | 199 if (enable_recording_ && encoder_task_runner_.get()) { |
197 encoder_task_runner_->PostTask(FROM_HERE, | 200 encoder_task_runner_->PostTask(FROM_HERE, |
198 base::Bind(&RecordingVideoEncoder::SetEnableRecording, | 201 base::Bind(&RecordingVideoEncoder::SetEnableRecording, |
199 recording_encoder_, | 202 recording_encoder_, |
200 enable_recording_)); | 203 enable_recording_)); |
201 } | 204 } |
202 } | 205 } |
203 | 206 |
204 void VideoFrameRecorder::RecordFrame(scoped_ptr<webrtc::DesktopFrame> frame) { | 207 void VideoFrameRecorder::RecordFrame(scoped_ptr<webrtc::DesktopFrame> frame) { |
205 DCHECK(caller_task_runner_->BelongsToCurrentThread()); | 208 DCHECK(caller_task_runner_->BelongsToCurrentThread()); |
206 | 209 |
(...skipping 13 matching lines...) Expand all Loading... |
220 if (content_bytes_ + frame_bytes > max_content_bytes_) { | 223 if (content_bytes_ + frame_bytes > max_content_bytes_) { |
221 return; | 224 return; |
222 } | 225 } |
223 | 226 |
224 // Store the frame and update the content byte count. | 227 // Store the frame and update the content byte count. |
225 recorded_frames_.push_back(frame.release()); | 228 recorded_frames_.push_back(frame.release()); |
226 content_bytes_ += frame_bytes; | 229 content_bytes_ += frame_bytes; |
227 } | 230 } |
228 | 231 |
229 } // namespace remoting | 232 } // namespace remoting |
OLD | NEW |