OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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/protocol/webrtc_video_stream.h" | 5 #include "remoting/protocol/webrtc_video_stream.h" |
6 | 6 |
7 #include "base/logging.h" | 7 #include "base/logging.h" |
8 #include "base/single_thread_task_runner.h" | 8 #include "base/single_thread_task_runner.h" |
9 #include "base/task_runner_util.h" | 9 #include "base/task_runner_util.h" |
10 #include "base/threading/thread_task_runner_handle.h" | 10 #include "base/threading/thread_task_runner_handle.h" |
11 #include "remoting/base/constants.h" | 11 #include "remoting/base/constants.h" |
12 #include "remoting/proto/video.pb.h" | 12 #include "remoting/codec/webrtc_video_encoder_vpx.h" |
13 #include "remoting/protocol/frame_stats.h" | 13 #include "remoting/protocol/frame_stats.h" |
14 #include "remoting/protocol/host_video_stats_dispatcher.h" | 14 #include "remoting/protocol/host_video_stats_dispatcher.h" |
15 #include "remoting/protocol/webrtc_dummy_video_capturer.h" | 15 #include "remoting/protocol/webrtc_dummy_video_capturer.h" |
16 #include "remoting/protocol/webrtc_transport.h" | 16 #include "remoting/protocol/webrtc_transport.h" |
17 #include "third_party/webrtc/api/mediastreaminterface.h" | 17 #include "third_party/webrtc/api/mediastreaminterface.h" |
18 #include "third_party/webrtc/api/peerconnectioninterface.h" | 18 #include "third_party/webrtc/api/peerconnectioninterface.h" |
19 #include "third_party/webrtc/api/test/fakeconstraints.h" | 19 #include "third_party/webrtc/api/test/fakeconstraints.h" |
20 #include "third_party/webrtc/media/base/videocapturer.h" | 20 #include "third_party/webrtc/media/base/videocapturer.h" |
21 | 21 |
22 namespace remoting { | 22 namespace remoting { |
(...skipping 29 matching lines...) Expand all Loading... |
52 base::TimeTicks input_event_received_time; | 52 base::TimeTicks input_event_received_time; |
53 | 53 |
54 base::TimeTicks capture_started_time; | 54 base::TimeTicks capture_started_time; |
55 base::TimeTicks capture_ended_time; | 55 base::TimeTicks capture_ended_time; |
56 base::TimeDelta capture_delay; | 56 base::TimeDelta capture_delay; |
57 base::TimeTicks encode_started_time; | 57 base::TimeTicks encode_started_time; |
58 base::TimeTicks encode_ended_time; | 58 base::TimeTicks encode_ended_time; |
59 }; | 59 }; |
60 | 60 |
61 struct WebrtcVideoStream::EncodedFrameWithTimestamps { | 61 struct WebrtcVideoStream::EncodedFrameWithTimestamps { |
62 std::unique_ptr<VideoPacket> frame; | 62 std::unique_ptr<WebrtcVideoEncoder::EncodedFrame> frame; |
63 std::unique_ptr<FrameTimestamps> timestamps; | 63 std::unique_ptr<FrameTimestamps> timestamps; |
64 }; | 64 }; |
65 | 65 |
66 WebrtcVideoStream::WebrtcVideoStream() | 66 WebrtcVideoStream::WebrtcVideoStream() |
67 : video_stats_dispatcher_(kStreamLabel), weak_factory_(this) {} | 67 : video_stats_dispatcher_(kStreamLabel), weak_factory_(this) {} |
68 | 68 |
69 WebrtcVideoStream::~WebrtcVideoStream() { | 69 WebrtcVideoStream::~WebrtcVideoStream() { |
70 if (stream_) { | 70 if (stream_) { |
71 for (const auto& track : stream_->GetVideoTracks()) { | 71 for (const auto& track : stream_->GetVideoTracks()) { |
72 stream_->RemoveTrack(track.get()); | 72 stream_->RemoveTrack(track.get()); |
73 } | 73 } |
74 peer_connection_->RemoveStream(stream_.get()); | 74 peer_connection_->RemoveStream(stream_.get()); |
75 } | 75 } |
76 encode_task_runner_->DeleteSoon(FROM_HERE, encoder_.release()); | 76 encode_task_runner_->DeleteSoon(FROM_HERE, encoder_.release()); |
77 } | 77 } |
78 | 78 |
79 bool WebrtcVideoStream::Start( | 79 bool WebrtcVideoStream::Start( |
80 std::unique_ptr<webrtc::DesktopCapturer> desktop_capturer, | 80 std::unique_ptr<webrtc::DesktopCapturer> desktop_capturer, |
81 WebrtcTransport* webrtc_transport, | 81 WebrtcTransport* webrtc_transport, |
82 scoped_refptr<base::SingleThreadTaskRunner> encode_task_runner, | 82 scoped_refptr<base::SingleThreadTaskRunner> encode_task_runner) { |
83 std::unique_ptr<VideoEncoder> video_encoder) { | |
84 DCHECK(thread_checker_.CalledOnValidThread()); | 83 DCHECK(thread_checker_.CalledOnValidThread()); |
85 DCHECK(webrtc_transport); | 84 DCHECK(webrtc_transport); |
86 DCHECK(desktop_capturer); | 85 DCHECK(desktop_capturer); |
87 DCHECK(encode_task_runner); | 86 DCHECK(encode_task_runner); |
88 DCHECK(video_encoder); | |
89 | 87 |
90 scoped_refptr<webrtc::PeerConnectionFactoryInterface> peer_connection_factory( | 88 scoped_refptr<webrtc::PeerConnectionFactoryInterface> peer_connection_factory( |
91 webrtc_transport->peer_connection_factory()); | 89 webrtc_transport->peer_connection_factory()); |
92 peer_connection_ = webrtc_transport->peer_connection(); | 90 peer_connection_ = webrtc_transport->peer_connection(); |
93 DCHECK(peer_connection_factory); | 91 DCHECK(peer_connection_factory); |
94 DCHECK(peer_connection_); | 92 DCHECK(peer_connection_); |
95 | 93 |
96 encode_task_runner_ = encode_task_runner; | 94 encode_task_runner_ = encode_task_runner; |
97 capturer_ = std::move(desktop_capturer); | 95 capturer_ = std::move(desktop_capturer); |
98 webrtc_transport_ = webrtc_transport; | 96 webrtc_transport_ = webrtc_transport; |
99 encoder_ = std::move(video_encoder); | 97 // TODO(isheriff): make this codec independent |
| 98 encoder_ = WebrtcVideoEncoderVpx::CreateForVP8(); |
100 capturer_->Start(this); | 99 capturer_->Start(this); |
101 | 100 |
102 // Set video stream constraints. | 101 // Set video stream constraints. |
103 webrtc::FakeConstraints video_constraints; | 102 webrtc::FakeConstraints video_constraints; |
104 video_constraints.AddMandatory( | 103 video_constraints.AddMandatory( |
105 webrtc::MediaConstraintsInterface::kMinFrameRate, 5); | 104 webrtc::MediaConstraintsInterface::kMinFrameRate, 5); |
106 | 105 |
107 rtc::scoped_refptr<webrtc::VideoTrackSourceInterface> src = | 106 rtc::scoped_refptr<webrtc::VideoTrackSourceInterface> src = |
108 peer_connection_factory->CreateVideoSource(new WebrtcDummyVideoCapturer(), | 107 peer_connection_factory->CreateVideoSource(new WebrtcDummyVideoCapturer(), |
109 &video_constraints); | 108 &video_constraints); |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
230 frame_dpi_ = dpi; | 229 frame_dpi_ = dpi; |
231 if (observer_) | 230 if (observer_) |
232 observer_->OnVideoSizeChanged(this, frame_size_, frame_dpi_); | 231 observer_->OnVideoSizeChanged(this, frame_size_, frame_dpi_); |
233 } | 232 } |
234 | 233 |
235 captured_frame_timestamps_->capture_ended_time = base::TimeTicks::Now(); | 234 captured_frame_timestamps_->capture_ended_time = base::TimeTicks::Now(); |
236 captured_frame_timestamps_->capture_delay = | 235 captured_frame_timestamps_->capture_delay = |
237 base::TimeDelta::FromMilliseconds(frame->capture_time_ms()); | 236 base::TimeDelta::FromMilliseconds(frame->capture_time_ms()); |
238 | 237 |
239 encode_pending_ = true; | 238 encode_pending_ = true; |
| 239 |
| 240 // TODO(sergeyu): Currently frame_duration is always set to 1/15 of a second. |
| 241 // Experiment with different values, and try changing it dynamically. |
| 242 WebrtcVideoEncoder::FrameParams frame_params; |
| 243 frame_params.bitrate_kbps = target_bitrate_kbps_; |
| 244 frame_params.duration = base::TimeDelta::FromSeconds(1) / 15; |
| 245 frame_params.key_frame = ClearAndGetKeyFrameRequest(); |
| 246 |
240 base::PostTaskAndReplyWithResult( | 247 base::PostTaskAndReplyWithResult( |
241 encode_task_runner_.get(), FROM_HERE, | 248 encode_task_runner_.get(), FROM_HERE, |
242 base::Bind(&WebrtcVideoStream::EncodeFrame, encoder_.get(), | 249 base::Bind(&WebrtcVideoStream::EncodeFrame, encoder_.get(), |
243 base::Passed(std::move(frame)), | 250 base::Passed(std::move(frame)), frame_params, |
244 base::Passed(std::move(captured_frame_timestamps_)), | 251 base::Passed(std::move(captured_frame_timestamps_))), |
245 target_bitrate_kbps_, ClearAndGetKeyFrameRequest()), | |
246 base::Bind(&WebrtcVideoStream::OnFrameEncoded, | 252 base::Bind(&WebrtcVideoStream::OnFrameEncoded, |
247 weak_factory_.GetWeakPtr())); | 253 weak_factory_.GetWeakPtr())); |
248 } | 254 } |
249 | 255 |
250 void WebrtcVideoStream::OnChannelInitialized( | 256 void WebrtcVideoStream::OnChannelInitialized( |
251 ChannelDispatcherBase* channel_dispatcher) { | 257 ChannelDispatcherBase* channel_dispatcher) { |
252 DCHECK(&video_stats_dispatcher_ == channel_dispatcher); | 258 DCHECK(&video_stats_dispatcher_ == channel_dispatcher); |
253 } | 259 } |
254 void WebrtcVideoStream::OnChannelClosed( | 260 void WebrtcVideoStream::OnChannelClosed( |
255 ChannelDispatcherBase* channel_dispatcher) { | 261 ChannelDispatcherBase* channel_dispatcher) { |
(...skipping 25 matching lines...) Expand all Loading... |
281 next_frame_timestamps_.reset(new FrameTimestamps()); | 287 next_frame_timestamps_.reset(new FrameTimestamps()); |
282 | 288 |
283 captured_frame_timestamps_ = std::move(next_frame_timestamps_); | 289 captured_frame_timestamps_ = std::move(next_frame_timestamps_); |
284 captured_frame_timestamps_->capture_started_time = now; | 290 captured_frame_timestamps_->capture_started_time = now; |
285 | 291 |
286 capturer_->Capture(webrtc::DesktopRegion()); | 292 capturer_->Capture(webrtc::DesktopRegion()); |
287 } | 293 } |
288 | 294 |
289 // static | 295 // static |
290 WebrtcVideoStream::EncodedFrameWithTimestamps WebrtcVideoStream::EncodeFrame( | 296 WebrtcVideoStream::EncodedFrameWithTimestamps WebrtcVideoStream::EncodeFrame( |
291 VideoEncoder* encoder, | 297 WebrtcVideoEncoder* encoder, |
292 std::unique_ptr<webrtc::DesktopFrame> frame, | 298 std::unique_ptr<webrtc::DesktopFrame> frame, |
293 std::unique_ptr<WebrtcVideoStream::FrameTimestamps> timestamps, | 299 WebrtcVideoEncoder::FrameParams params, |
294 uint32_t target_bitrate_kbps, | 300 std::unique_ptr<WebrtcVideoStream::FrameTimestamps> timestamps) { |
295 bool key_frame_request) { | |
296 EncodedFrameWithTimestamps result; | 301 EncodedFrameWithTimestamps result; |
297 result.timestamps = std::move(timestamps); | 302 result.timestamps = std::move(timestamps); |
298 result.timestamps->encode_started_time = base::TimeTicks::Now(); | 303 result.timestamps->encode_started_time = base::TimeTicks::Now(); |
299 | 304 result.frame = encoder->Encode(*frame, params); |
300 encoder->UpdateTargetBitrate(target_bitrate_kbps); | |
301 result.frame = encoder->Encode( | |
302 *frame, key_frame_request ? VideoEncoder::REQUEST_KEY_FRAME : 0); | |
303 | |
304 result.timestamps->encode_ended_time = base::TimeTicks::Now(); | 305 result.timestamps->encode_ended_time = base::TimeTicks::Now(); |
305 | |
306 return result; | 306 return result; |
307 } | 307 } |
308 | 308 |
309 void WebrtcVideoStream::OnFrameEncoded(EncodedFrameWithTimestamps frame) { | 309 void WebrtcVideoStream::OnFrameEncoded(EncodedFrameWithTimestamps frame) { |
310 DCHECK(thread_checker_.CalledOnValidThread()); | 310 DCHECK(thread_checker_.CalledOnValidThread()); |
311 | 311 |
312 encode_pending_ = false; | 312 encode_pending_ = false; |
313 | 313 |
314 size_t frame_size = frame.frame ? frame.frame->data().size() : 0; | 314 size_t frame_size = frame.frame ? frame.frame->data.size() : 0; |
315 | 315 |
316 // Generate HostFrameStats. | 316 // Generate HostFrameStats. |
317 HostFrameStats stats; | 317 HostFrameStats stats; |
318 stats.frame_size = frame_size; | 318 stats.frame_size = frame_size; |
319 | 319 |
320 if (!frame.timestamps->input_event_received_time.is_null()) { | 320 if (!frame.timestamps->input_event_received_time.is_null()) { |
321 stats.capture_pending_delay = frame.timestamps->capture_started_time - | 321 stats.capture_pending_delay = frame.timestamps->capture_started_time - |
322 frame.timestamps->input_event_received_time; | 322 frame.timestamps->input_event_received_time; |
323 stats.latest_event_timestamp = base::TimeTicks::FromInternalValue( | 323 stats.latest_event_timestamp = base::TimeTicks::FromInternalValue( |
324 frame.timestamps->input_event_client_timestamp); | 324 frame.timestamps->input_event_client_timestamp); |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
364 float encoded_bits = frame_size * 8.0; | 364 float encoded_bits = frame_size * 8.0; |
365 uint32_t next_sched_ms = std::max( | 365 uint32_t next_sched_ms = std::max( |
366 33, std::min(static_cast<int>(encoded_bits / target_bitrate_kbps_), 200)); | 366 33, std::min(static_cast<int>(encoded_bits / target_bitrate_kbps_), 200)); |
367 capture_timer_.Start(FROM_HERE, | 367 capture_timer_.Start(FROM_HERE, |
368 base::TimeDelta::FromMilliseconds(next_sched_ms), this, | 368 base::TimeDelta::FromMilliseconds(next_sched_ms), this, |
369 &WebrtcVideoStream::CaptureNextFrame); | 369 &WebrtcVideoStream::CaptureNextFrame); |
370 } | 370 } |
371 | 371 |
372 } // namespace protocol | 372 } // namespace protocol |
373 } // namespace remoting | 373 } // namespace remoting |
OLD | NEW |