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

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

Issue 2405333002: Add remoting::protocol::NetworkStateObserver interface. (Closed)
Patch Set: Created 4 years, 2 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
1 // Copyright 2016 The Chromium Authors. All rights reserved. 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 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_frame_scheduler_simple.h" 5 #include "remoting/protocol/webrtc_frame_scheduler_simple.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "third_party/webrtc/modules/desktop_capture/desktop_frame.h" 9 #include "third_party/webrtc/modules/desktop_capture/desktop_frame.h"
10 10
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
49 result += r.rect().width() * r.rect().height(); 49 result += r.rect().width() * r.rect().height();
50 } 50 }
51 return result; 51 return result;
52 } 52 }
53 53
54 } // namespace 54 } // namespace
55 55
56 WebrtcFrameSchedulerSimple::WebrtcFrameSchedulerSimple() 56 WebrtcFrameSchedulerSimple::WebrtcFrameSchedulerSimple()
57 : pacing_bucket_(LeakyBucket::kUnlimitedDepth, 0), 57 : pacing_bucket_(LeakyBucket::kUnlimitedDepth, 0),
58 frame_processing_delay_us_(kStatsWindow), 58 frame_processing_delay_us_(kStatsWindow),
59 updated_region_area_(kStatsWindow) {} 59 updated_region_area_(kStatsWindow),
60 weak_factory_(this) {}
60 WebrtcFrameSchedulerSimple::~WebrtcFrameSchedulerSimple() {} 61 WebrtcFrameSchedulerSimple::~WebrtcFrameSchedulerSimple() {}
61 62
63 void WebrtcFrameSchedulerSimple::OnKeyFrameRequested() {
64 DCHECK(thread_checker_.CalledOnValidThread());
65 key_frame_request_ = true;
66 if (!capture_timer_.IsRunning())
67 ScheduleNextFrame(base::TimeTicks::Now());
68 }
69
70 void WebrtcFrameSchedulerSimple::OnChannelParameters(int packet_loss,
71 base::TimeDelta rtt) {
72 DCHECK(thread_checker_.CalledOnValidThread());
73 }
74
75 void WebrtcFrameSchedulerSimple::OnTargetBitrateChanged(int bitrate_kbps) {
76 DCHECK(thread_checker_.CalledOnValidThread());
77 base::TimeTicks now = base::TimeTicks::Now();
78 pacing_bucket_.UpdateRate(bitrate_kbps * 1000 / 8, now);
79 ScheduleNextFrame(now);
80 }
81
82 base::WeakPtr<NetworkStateObserver>
83 WebrtcFrameSchedulerSimple::GetNetworkStateObserver() {
84 DCHECK(thread_checker_.CalledOnValidThread());
85 return weak_factory_.GetWeakPtr();
86 }
87
62 void WebrtcFrameSchedulerSimple::Start(const base::Closure& capture_callback) { 88 void WebrtcFrameSchedulerSimple::Start(const base::Closure& capture_callback) {
89 DCHECK(thread_checker_.CalledOnValidThread());
63 capture_callback_ = capture_callback; 90 capture_callback_ = capture_callback;
64 ScheduleNextFrame(base::TimeTicks::Now()); 91 ScheduleNextFrame(base::TimeTicks::Now());
65 } 92 }
66 93
67 void WebrtcFrameSchedulerSimple::Pause(bool pause) { 94 void WebrtcFrameSchedulerSimple::Pause(bool pause) {
95 DCHECK(thread_checker_.CalledOnValidThread());
96
68 paused_ = pause; 97 paused_ = pause;
69 if (paused_) { 98 if (paused_) {
70 capture_timer_.Stop(); 99 capture_timer_.Stop();
71 } else { 100 } else {
72 ScheduleNextFrame(base::TimeTicks::Now()); 101 ScheduleNextFrame(base::TimeTicks::Now());
73 } 102 }
74 } 103 }
75 104
76 void WebrtcFrameSchedulerSimple::SetKeyFrameRequest() {
77 key_frame_request_ = true;
78 }
79
80 void WebrtcFrameSchedulerSimple::SetTargetBitrate(int bitrate_kbps) {
81 base::TimeTicks now = base::TimeTicks::Now();
82 pacing_bucket_.UpdateRate(bitrate_kbps * 1000 / 8, now);
83 ScheduleNextFrame(now);
84 }
85
86 bool WebrtcFrameSchedulerSimple::GetEncoderFrameParams( 105 bool WebrtcFrameSchedulerSimple::GetEncoderFrameParams(
87 const webrtc::DesktopFrame& frame, 106 const webrtc::DesktopFrame& frame,
88 WebrtcVideoEncoder::FrameParams* params_out) { 107 WebrtcVideoEncoder::FrameParams* params_out) {
108 DCHECK(thread_checker_.CalledOnValidThread());
109
89 base::TimeTicks now = base::TimeTicks::Now(); 110 base::TimeTicks now = base::TimeTicks::Now();
90 111
91 if (frame.updated_region().is_empty() && !top_off_is_active_ && 112 if (frame.updated_region().is_empty() && !top_off_is_active_ &&
92 !key_frame_request_) { 113 !key_frame_request_) {
93 ScheduleNextFrame(now); 114 ScheduleNextFrame(now);
94 return false; 115 return false;
95 } 116 }
96 117
97 // TODO(sergeyu): This logic is applicable only to VP8. Reconsider it for VP9. 118 // TODO(sergeyu): This logic is applicable only to VP8. Reconsider it for VP9.
98 int minimum_bitrate = 119 int minimum_bitrate =
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
130 params_out->vpx_max_quantizer = 63; 151 params_out->vpx_max_quantizer = 63;
131 152
132 params_out->clear_active_map = !top_off_is_active_; 153 params_out->clear_active_map = !top_off_is_active_;
133 154
134 return true; 155 return true;
135 } 156 }
136 157
137 void WebrtcFrameSchedulerSimple::OnFrameEncoded( 158 void WebrtcFrameSchedulerSimple::OnFrameEncoded(
138 const WebrtcVideoEncoder::EncodedFrame& encoded_frame, 159 const WebrtcVideoEncoder::EncodedFrame& encoded_frame,
139 const webrtc::EncodedImageCallback::Result& send_result) { 160 const webrtc::EncodedImageCallback::Result& send_result) {
161 DCHECK(thread_checker_.CalledOnValidThread());
162
140 base::TimeTicks now = base::TimeTicks::Now(); 163 base::TimeTicks now = base::TimeTicks::Now();
141 pacing_bucket_.RefillOrSpill(encoded_frame.data.size(), now); 164 pacing_bucket_.RefillOrSpill(encoded_frame.data.size(), now);
142 165
143 if (encoded_frame.data.empty()) { 166 if (encoded_frame.data.empty()) {
144 top_off_is_active_ = false; 167 top_off_is_active_ = false;
145 } else { 168 } else {
146 frame_processing_delay_us_.Record( 169 frame_processing_delay_us_.Record(
147 (now - last_capture_started_time_).InMicroseconds()); 170 (now - last_capture_started_time_).InMicroseconds());
148 171
149 // Top-off until the target quantizer value is reached. 172 // Top-off until the target quantizer value is reached.
150 top_off_is_active_ = encoded_frame.quantizer > kTargetQuantizerForVp8TopOff; 173 top_off_is_active_ = encoded_frame.quantizer > kTargetQuantizerForVp8TopOff;
151 } 174 }
152 175
153 ScheduleNextFrame(now); 176 ScheduleNextFrame(now);
154 } 177 }
155 178
156 void WebrtcFrameSchedulerSimple::ScheduleNextFrame(base::TimeTicks now) { 179 void WebrtcFrameSchedulerSimple::ScheduleNextFrame(base::TimeTicks now) {
180 DCHECK(thread_checker_.CalledOnValidThread());
181
157 // Don't capture frames when paused or target bitrate is 0 or there is 182 // Don't capture frames when paused or target bitrate is 0 or there is
158 // no capture callback set. 183 // no capture callback set.
159 if (paused_ || pacing_bucket_.rate() == 0 || capture_callback_.is_null()) 184 if (paused_ || pacing_bucket_.rate() == 0 || capture_callback_.is_null())
160 return; 185 return;
161 186
162 // If this is not the first frame then capture next frame after the previous 187 // If this is not the first frame then capture next frame after the previous
163 // one has finished sending. 188 // one has finished sending.
164 base::TimeDelta expected_processing_time = 189 base::TimeDelta expected_processing_time =
165 base::TimeDelta::FromMicroseconds(frame_processing_delay_us_.Max()); 190 base::TimeDelta::FromMicroseconds(frame_processing_delay_us_.Max());
166 base::TimeTicks target_capture_time = 191 base::TimeTicks target_capture_time =
167 pacing_bucket_.GetEmptyTime() - expected_processing_time; 192 pacing_bucket_.GetEmptyTime() - expected_processing_time;
168 193
169 // Cap interval between frames to kTargetFrameInterval. 194 // Cap interval between frames to kTargetFrameInterval.
170 if (!last_capture_started_time_.is_null()) { 195 if (!last_capture_started_time_.is_null()) {
171 target_capture_time = std::max( 196 target_capture_time = std::max(
172 target_capture_time, last_capture_started_time_ + kTargetFrameInterval); 197 target_capture_time, last_capture_started_time_ + kTargetFrameInterval);
173 } 198 }
174 199
175 if (target_capture_time < now) 200 if (target_capture_time < now)
176 target_capture_time = now; 201 target_capture_time = now;
177 202
178 capture_timer_.Start(FROM_HERE, target_capture_time - now, 203 capture_timer_.Start(FROM_HERE, target_capture_time - now,
179 base::Bind(&WebrtcFrameSchedulerSimple::CaptureNextFrame, 204 base::Bind(&WebrtcFrameSchedulerSimple::CaptureNextFrame,
180 base::Unretained(this))); 205 base::Unretained(this)));
181 } 206 }
182 207
183 void WebrtcFrameSchedulerSimple::CaptureNextFrame() { 208 void WebrtcFrameSchedulerSimple::CaptureNextFrame() {
209 DCHECK(thread_checker_.CalledOnValidThread());
210
184 last_capture_started_time_ = base::TimeTicks::Now(); 211 last_capture_started_time_ = base::TimeTicks::Now();
185 capture_callback_.Run(); 212 capture_callback_.Run();
186 } 213 }
187 214
188 } // namespace protocol 215 } // namespace protocol
189 } // namespace remoting 216 } // namespace remoting
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698