Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(145)

Side by Side Diff: remoting/protocol/webrtc_capture_scheduler_simple.cc

Issue 2335923002: Add WebrtcCaptureScheduler interface. (Closed)
Patch Set: Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2016 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 #include "remoting/protocol/webrtc_capture_scheduler_simple.h"
6
7 #include "third_party/webrtc/modules/desktop_capture/desktop_frame.h"
8
9 namespace remoting {
10 namespace protocol {
11
12 namespace {
13
14 const int kTargetFrameRate = 30;
15 constexpr base::TimeDelta kTargetFrameInterval =
16 base::TimeDelta::FromMilliseconds(1000 / kTargetFrameRate);
17
18 // Target quantizer at which stop the encoding top-off.
19 const int kTargetQuantizerForVp8TopOff = 30;
20
21 } // namespace
22
23 WebrtcCaptureSchedulerSimple::WebrtcCaptureSchedulerSimple() {}
24 WebrtcCaptureSchedulerSimple::~WebrtcCaptureSchedulerSimple() {}
25
26 void WebrtcCaptureSchedulerSimple::Start(
27 const base::Closure& capture_callback) {
28 capture_callback_ = capture_callback;
29 ScheduleNextFrame();
30 }
31
32 void WebrtcCaptureSchedulerSimple::Pause(bool pause) {
33 paused_ = pause;
34 if (paused_) {
35 capture_timer_.Stop();
36 } else if (!capture_callback_.is_null()) {
37 ScheduleNextFrame();
38 }
39 }
40
41 void WebrtcCaptureSchedulerSimple::SetKeyFrameRequest() {
42 key_frame_request_ = true;
43 }
44
45 void WebrtcCaptureSchedulerSimple::SetTargetBitrate(int bitrate_kbps) {
46 target_bitrate_kbps_ = bitrate_kbps;
47 }
48
49 bool WebrtcCaptureSchedulerSimple::GetEncoderFrameParams(
50 const webrtc::DesktopFrame& frame,
51 WebrtcVideoEncoder::FrameParams* params_out) {
52 if (frame.updated_region().is_empty() && !top_off_is_active_ &&
53 !key_frame_request_) {
54 ScheduleNextFrame();
55 return false;
56 }
57
58 params_out->bitrate_kbps = target_bitrate_kbps_;
59
60 // TODO(sergeyu): Currently duration is always set to 1/15 of a second.
61 // Experiment with different values, and try changing it dynamically.
62 params_out->duration = base::TimeDelta::FromSeconds(1) / 15;
63
64 params_out->key_frame = key_frame_request_;
65 key_frame_request_ = false;
66
67 params_out->vpx_min_quantizer = 10;
68 params_out->vpx_max_quantizer = 63;
69
70 params_out->clear_active_map = !top_off_is_active_;
71
72 return true;
73 }
74
75 void WebrtcCaptureSchedulerSimple::OnFrameEncoded(
76 const WebrtcVideoEncoder::EncodedFrame& encoded_frame,
77 const webrtc::EncodedImageCallback::Result& send_result) {
78 if (encoded_frame.data.empty()) {
79 top_off_is_active_ = false;
80 ScheduleNextFrame();
81 return;
82 }
83
84 // Top-off until the target quantizer value is reached.
85 top_off_is_active_ = encoded_frame.quantizer > kTargetQuantizerForVp8TopOff;
86
87 // Capture next frame after we finish sending the current one.
88 const double kKiloBitsPerByte = 8.0 / 1000.0;
89 base::TimeDelta expected_send_delay = base::TimeDelta::FromSecondsD(
90 encoded_frame.data.size() * kKiloBitsPerByte / target_bitrate_kbps_);
91 last_frame_send_finish_time_ = base::TimeTicks::Now() + expected_send_delay;
92
93 ScheduleNextFrame();
94 }
95
96 void WebrtcCaptureSchedulerSimple::ScheduleNextFrame() {
97 if (paused_)
98 return;
99
100 base::TimeTicks now = base::TimeTicks::Now();
101 base::TimeDelta delay;
102
103 // If this is not the first frame then capture next frame after the previous
104 // one has finished sending.
105 if (!last_frame_send_finish_time_.is_null()) {
106 delay = std::max(base::TimeDelta(), last_frame_send_finish_time_ - now);
107 }
108
109 // Cap interval between frames to kTargetFrameInterval.
110 if (!last_capture_started_time_.is_null()) {
111 delay = std::max(delay,
112 last_capture_started_time_ + kTargetFrameInterval - now);
113 }
114
115 capture_timer_.Start(
116 FROM_HERE, delay,
117 base::Bind(&WebrtcCaptureSchedulerSimple::CaptureNextFrame,
118 base::Unretained(this)));
119 }
120
121 void WebrtcCaptureSchedulerSimple::CaptureNextFrame() {
122 last_capture_started_time_ = base::TimeTicks::Now();
123 capture_callback_.Run();
124 }
125
126 } // namespace protocol
127 } // namespace remoting
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698