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

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

Issue 2366053002: Account for expected capture and encode latency in WebrtcFrameSchedulerSimple (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
« no previous file with comments | « remoting/protocol/webrtc_frame_scheduler_simple.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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
11 namespace remoting { 11 namespace remoting {
12 namespace protocol { 12 namespace protocol {
13 13
14 namespace { 14 namespace {
15 15
16 // Number of samples used to estimate processing time for the next frame.
17 const int kStatsWindow = 5;
18
16 const int kTargetFrameRate = 30; 19 const int kTargetFrameRate = 30;
17 constexpr base::TimeDelta kTargetFrameInterval = 20 constexpr base::TimeDelta kTargetFrameInterval =
18 base::TimeDelta::FromMilliseconds(1000 / kTargetFrameRate); 21 base::TimeDelta::FromMilliseconds(1000 / kTargetFrameRate);
19 22
20 // Target quantizer at which stop the encoding top-off. 23 // Target quantizer at which stop the encoding top-off.
21 const int kTargetQuantizerForVp8TopOff = 30; 24 const int kTargetQuantizerForVp8TopOff = 30;
22 25
23 } // namespace 26 } // namespace
24 27
25 WebrtcFrameSchedulerSimple::WebrtcFrameSchedulerSimple() {} 28 WebrtcFrameSchedulerSimple::WebrtcFrameSchedulerSimple()
29 : frame_processing_delay_us_(kStatsWindow) {}
26 WebrtcFrameSchedulerSimple::~WebrtcFrameSchedulerSimple() {} 30 WebrtcFrameSchedulerSimple::~WebrtcFrameSchedulerSimple() {}
27 31
28 void WebrtcFrameSchedulerSimple::Start(const base::Closure& capture_callback) { 32 void WebrtcFrameSchedulerSimple::Start(const base::Closure& capture_callback) {
29 capture_callback_ = capture_callback; 33 capture_callback_ = capture_callback;
30 ScheduleNextFrame(); 34 ScheduleNextFrame();
31 } 35 }
32 36
33 void WebrtcFrameSchedulerSimple::Pause(bool pause) { 37 void WebrtcFrameSchedulerSimple::Pause(bool pause) {
34 paused_ = pause; 38 paused_ = pause;
35 if (paused_) { 39 if (paused_) {
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
75 79
76 void WebrtcFrameSchedulerSimple::OnFrameEncoded( 80 void WebrtcFrameSchedulerSimple::OnFrameEncoded(
77 const WebrtcVideoEncoder::EncodedFrame& encoded_frame, 81 const WebrtcVideoEncoder::EncodedFrame& encoded_frame,
78 const webrtc::EncodedImageCallback::Result& send_result) { 82 const webrtc::EncodedImageCallback::Result& send_result) {
79 if (encoded_frame.data.empty()) { 83 if (encoded_frame.data.empty()) {
80 top_off_is_active_ = false; 84 top_off_is_active_ = false;
81 ScheduleNextFrame(); 85 ScheduleNextFrame();
82 return; 86 return;
83 } 87 }
84 88
89 frame_processing_delay_us_.Record(
90 (base::TimeTicks::Now() - last_capture_started_time_).InMicroseconds());
91
85 // Top-off until the target quantizer value is reached. 92 // Top-off until the target quantizer value is reached.
86 top_off_is_active_ = encoded_frame.quantizer > kTargetQuantizerForVp8TopOff; 93 top_off_is_active_ = encoded_frame.quantizer > kTargetQuantizerForVp8TopOff;
87 94
88 // Capture next frame after we finish sending the current one. 95 // Capture next frame after we finish sending the current one.
89 const double kKiloBitsPerByte = 8.0 / 1000.0; 96 const double kKiloBitsPerByte = 8.0 / 1000.0;
90 base::TimeDelta expected_send_delay = base::TimeDelta::FromSecondsD( 97 base::TimeDelta expected_send_delay = base::TimeDelta::FromSecondsD(
91 encoded_frame.data.size() * kKiloBitsPerByte / target_bitrate_kbps_); 98 encoded_frame.data.size() * kKiloBitsPerByte / target_bitrate_kbps_);
92 last_frame_send_finish_time_ = base::TimeTicks::Now() + expected_send_delay; 99 last_frame_send_finish_time_ = base::TimeTicks::Now() + expected_send_delay;
93 100
94 ScheduleNextFrame(); 101 ScheduleNextFrame();
95 } 102 }
96 103
97 void WebrtcFrameSchedulerSimple::ScheduleNextFrame() { 104 void WebrtcFrameSchedulerSimple::ScheduleNextFrame() {
98 if (paused_) 105 if (paused_)
99 return; 106 return;
100 107
101 base::TimeTicks now = base::TimeTicks::Now(); 108 base::TimeTicks now = base::TimeTicks::Now();
102 base::TimeDelta delay; 109 base::TimeDelta delay;
103 110
104 // If this is not the first frame then capture next frame after the previous 111 // If this is not the first frame then capture next frame after the previous
105 // one has finished sending. 112 // one has finished sending.
106 if (!last_frame_send_finish_time_.is_null()) { 113 if (!last_frame_send_finish_time_.is_null()) {
107 delay = std::max(base::TimeDelta(), last_frame_send_finish_time_ - now); 114 base::TimeDelta expected_processing_time =
115 base::TimeDelta::FromMicroseconds(frame_processing_delay_us_.Max());
Irfan 2016/09/27 18:04:51 assigning expected value to Max() seems confusing.
Sergey Ulanov 2016/09/27 18:49:09 I think we want to approximate the upper bound of
116 delay = std::max(base::TimeDelta(), last_frame_send_finish_time_ -
117 expected_processing_time - now);
108 } 118 }
109 119
110 // Cap interval between frames to kTargetFrameInterval. 120 // Cap interval between frames to kTargetFrameInterval.
111 if (!last_capture_started_time_.is_null()) { 121 if (!last_capture_started_time_.is_null()) {
112 delay = std::max(delay, 122 delay = std::max(delay,
113 last_capture_started_time_ + kTargetFrameInterval - now); 123 last_capture_started_time_ + kTargetFrameInterval - now);
114 } 124 }
115 125
116 capture_timer_.Start(FROM_HERE, delay, 126 capture_timer_.Start(FROM_HERE, delay,
117 base::Bind(&WebrtcFrameSchedulerSimple::CaptureNextFrame, 127 base::Bind(&WebrtcFrameSchedulerSimple::CaptureNextFrame,
118 base::Unretained(this))); 128 base::Unretained(this)));
119 } 129 }
120 130
121 void WebrtcFrameSchedulerSimple::CaptureNextFrame() { 131 void WebrtcFrameSchedulerSimple::CaptureNextFrame() {
122 last_capture_started_time_ = base::TimeTicks::Now(); 132 last_capture_started_time_ = base::TimeTicks::Now();
123 capture_callback_.Run(); 133 capture_callback_.Run();
124 } 134 }
125 135
126 } // namespace protocol 136 } // namespace protocol
127 } // namespace remoting 137 } // namespace remoting
OLDNEW
« no previous file with comments | « remoting/protocol/webrtc_frame_scheduler_simple.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698