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

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

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

Powered by Google App Engine
This is Rietveld 408576698