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

Side by Side Diff: webrtc/video/vie_encoder.cc

Issue 1993113003: Refactor how padding is calculated. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Fixed unitialized memory. Created 4 years, 6 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 /* 1 /*
2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source 5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 10
(...skipping 10 matching lines...) Expand all
21 #include "webrtc/modules/pacing/paced_sender.h" 21 #include "webrtc/modules/pacing/paced_sender.h"
22 #include "webrtc/modules/video_coding/include/video_coding.h" 22 #include "webrtc/modules/video_coding/include/video_coding.h"
23 #include "webrtc/modules/video_coding/include/video_coding_defines.h" 23 #include "webrtc/modules/video_coding/include/video_coding_defines.h"
24 #include "webrtc/system_wrappers/include/metrics.h" 24 #include "webrtc/system_wrappers/include/metrics.h"
25 #include "webrtc/video/overuse_frame_detector.h" 25 #include "webrtc/video/overuse_frame_detector.h"
26 #include "webrtc/video/send_statistics_proxy.h" 26 #include "webrtc/video/send_statistics_proxy.h"
27 #include "webrtc/video_frame.h" 27 #include "webrtc/video_frame.h"
28 28
29 namespace webrtc { 29 namespace webrtc {
30 30
31 static const float kStopPaddingThresholdMs = 2000;
32
33 ViEEncoder::ViEEncoder(uint32_t number_of_cores, 31 ViEEncoder::ViEEncoder(uint32_t number_of_cores,
34 ProcessThread* module_process_thread, 32 ProcessThread* module_process_thread,
35 SendStatisticsProxy* stats_proxy, 33 SendStatisticsProxy* stats_proxy,
36 OveruseFrameDetector* overuse_detector, 34 OveruseFrameDetector* overuse_detector,
37 EncodedImageCallback* sink) 35 VideoEncoderSink* sink)
38 : number_of_cores_(number_of_cores), 36 : number_of_cores_(number_of_cores),
39 sink_(sink), 37 sink_(sink),
40 vp_(VideoProcessing::Create()), 38 vp_(VideoProcessing::Create()),
41 video_sender_(Clock::GetRealTimeClock(), this, this, this), 39 video_sender_(Clock::GetRealTimeClock(), this, this, this),
42 stats_proxy_(stats_proxy), 40 stats_proxy_(stats_proxy),
43 overuse_detector_(overuse_detector), 41 overuse_detector_(overuse_detector),
44 time_of_last_frame_activity_ms_(0), 42 time_of_last_frame_activity_ms_(0),
45 encoder_config_(), 43 encoder_config_(),
46 min_transmit_bitrate_bps_(0),
47 last_observed_bitrate_bps_(0), 44 last_observed_bitrate_bps_(0),
48 encoder_paused_(true), 45 encoder_paused_(true),
49 encoder_paused_and_dropped_frame_(false), 46 encoder_paused_and_dropped_frame_(false),
47 reported_timeout_(false),
50 module_process_thread_(module_process_thread), 48 module_process_thread_(module_process_thread),
51 has_received_sli_(false), 49 has_received_sli_(false),
52 picture_id_sli_(0), 50 picture_id_sli_(0),
53 has_received_rpsi_(false), 51 has_received_rpsi_(false),
54 picture_id_rpsi_(0), 52 picture_id_rpsi_(0),
55 video_suspended_(false) { 53 video_suspended_(false) {
56 module_process_thread_->RegisterModule(&video_sender_); 54 module_process_thread_->RegisterModule(&video_sender_);
57 vp_->EnableTemporalDecimation(true); 55 vp_->EnableTemporalDecimation(true);
58 } 56 }
59 57
(...skipping 21 matching lines...) Expand all
81 video_sender_.RegisterExternalEncoder(encoder, pl_type, internal_source); 79 video_sender_.RegisterExternalEncoder(encoder, pl_type, internal_source);
82 return 0; 80 return 0;
83 } 81 }
84 82
85 int32_t ViEEncoder::DeRegisterExternalEncoder(uint8_t pl_type) { 83 int32_t ViEEncoder::DeRegisterExternalEncoder(uint8_t pl_type) {
86 video_sender_.RegisterExternalEncoder(nullptr, pl_type, false); 84 video_sender_.RegisterExternalEncoder(nullptr, pl_type, false);
87 return 0; 85 return 0;
88 } 86 }
89 87
90 void ViEEncoder::SetEncoder(const webrtc::VideoCodec& video_codec, 88 void ViEEncoder::SetEncoder(const webrtc::VideoCodec& video_codec,
91 int min_transmit_bitrate_bps,
92 size_t max_data_payload_length) { 89 size_t max_data_payload_length) {
93 // Setting target width and height for VPM. 90 // Setting target width and height for VPM.
94 RTC_CHECK_EQ(VPM_OK, 91 RTC_CHECK_EQ(VPM_OK,
95 vp_->SetTargetResolution(video_codec.width, video_codec.height, 92 vp_->SetTargetResolution(video_codec.width, video_codec.height,
96 video_codec.maxFramerate)); 93 video_codec.maxFramerate));
97 94
98 // Cache codec before calling AddBitrateObserver (which calls OnBitrateUpdated 95 // Cache codec before calling AddBitrateObserver (which calls OnBitrateUpdated
99 // that makes use of the number of simulcast streams configured). 96 // that makes use of the number of simulcast streams configured).
100 { 97 {
101 rtc::CritScope lock(&data_cs_); 98 rtc::CritScope lock(&data_cs_);
102 encoder_config_ = video_codec; 99 encoder_config_ = video_codec;
103 min_transmit_bitrate_bps_ = min_transmit_bitrate_bps;
104 } 100 }
105 101
106 bool success = video_sender_.RegisterSendCodec( 102 bool success = video_sender_.RegisterSendCodec(
107 &video_codec, number_of_cores_, 103 &video_codec, number_of_cores_,
108 static_cast<uint32_t>(max_data_payload_length)) == VCM_OK; 104 static_cast<uint32_t>(max_data_payload_length)) == VCM_OK;
109 if (!success) { 105 if (!success) {
110 LOG(LS_ERROR) << "Failed to configure encoder."; 106 LOG(LS_ERROR) << "Failed to configure encoder.";
111 RTC_DCHECK(success); 107 RTC_DCHECK(success);
112 } 108 }
113 109
114 if (stats_proxy_) { 110 if (stats_proxy_) {
115 VideoEncoderConfig::ContentType content_type = 111 VideoEncoderConfig::ContentType content_type =
116 VideoEncoderConfig::ContentType::kRealtimeVideo; 112 VideoEncoderConfig::ContentType::kRealtimeVideo;
117 switch (video_codec.mode) { 113 switch (video_codec.mode) {
118 case kRealtimeVideo: 114 case kRealtimeVideo:
119 content_type = VideoEncoderConfig::ContentType::kRealtimeVideo; 115 content_type = VideoEncoderConfig::ContentType::kRealtimeVideo;
120 break; 116 break;
121 case kScreensharing: 117 case kScreensharing:
122 content_type = VideoEncoderConfig::ContentType::kScreen; 118 content_type = VideoEncoderConfig::ContentType::kScreen;
123 break; 119 break;
124 default: 120 default:
125 RTC_NOTREACHED(); 121 RTC_NOTREACHED();
126 break; 122 break;
127 } 123 }
128 stats_proxy_->SetContentType(content_type); 124 stats_proxy_->SetContentType(content_type);
129 } 125 }
130 } 126 }
131 127
132 int ViEEncoder::GetPaddingNeededBps() const {
133 int64_t time_of_last_frame_activity_ms;
134 int min_transmit_bitrate_bps;
135 int bitrate_bps;
136 VideoCodec send_codec;
137 {
138 rtc::CritScope lock(&data_cs_);
139 bool send_padding = encoder_config_.numberOfSimulcastStreams > 1 ||
140 video_suspended_ || min_transmit_bitrate_bps_ > 0;
141 if (!send_padding)
142 return 0;
143 time_of_last_frame_activity_ms = time_of_last_frame_activity_ms_;
144 min_transmit_bitrate_bps = min_transmit_bitrate_bps_;
145 bitrate_bps = last_observed_bitrate_bps_;
146 send_codec = encoder_config_;
147 }
148
149 bool video_is_suspended = video_sender_.VideoSuspended();
150
151 // Find the max amount of padding we can allow ourselves to send at this
152 // point, based on which streams are currently active and what our current
153 // available bandwidth is.
154 int pad_up_to_bitrate_bps = 0;
155 if (send_codec.numberOfSimulcastStreams == 0) {
156 pad_up_to_bitrate_bps = send_codec.minBitrate * 1000;
157 } else {
158 SimulcastStream* stream_configs = send_codec.simulcastStream;
159 pad_up_to_bitrate_bps =
160 stream_configs[send_codec.numberOfSimulcastStreams - 1].minBitrate *
161 1000;
162 for (int i = 0; i < send_codec.numberOfSimulcastStreams - 1; ++i) {
163 pad_up_to_bitrate_bps += stream_configs[i].targetBitrate * 1000;
164 }
165 }
166
167 // Disable padding if only sending one stream and video isn't suspended and
168 // min-transmit bitrate isn't used (applied later).
169 if (!video_is_suspended && send_codec.numberOfSimulcastStreams <= 1)
170 pad_up_to_bitrate_bps = 0;
171
172 // The amount of padding should decay to zero if no frames are being
173 // captured/encoded unless a min-transmit bitrate is used.
174 int64_t now_ms = rtc::TimeMillis();
175 if (now_ms - time_of_last_frame_activity_ms > kStopPaddingThresholdMs)
176 pad_up_to_bitrate_bps = 0;
177
178 // Pad up to min bitrate.
179 if (pad_up_to_bitrate_bps < min_transmit_bitrate_bps)
180 pad_up_to_bitrate_bps = min_transmit_bitrate_bps;
181
182 // Padding may never exceed bitrate estimate.
183 if (pad_up_to_bitrate_bps > bitrate_bps)
184 pad_up_to_bitrate_bps = bitrate_bps;
185
186 return pad_up_to_bitrate_bps;
187 }
188
189 bool ViEEncoder::EncoderPaused() const { 128 bool ViEEncoder::EncoderPaused() const {
190 // Pause video if paused by caller or as long as the network is down or the 129 // Pause video if paused by caller or as long as the network is down or the
191 // pacer queue has grown too large in buffered mode. 130 // pacer queue has grown too large in buffered mode.
192 // If the pacer queue has grown to large or the network is down, 131 // If the pacer queue has grown to large or the network is down,
193 // last_observed_bitrate_bps_ will be 0. 132 // last_observed_bitrate_bps_ will be 0.
194 return encoder_paused_ || video_suspended_ || last_observed_bitrate_bps_ == 0; 133 return encoder_paused_ || video_suspended_ || last_observed_bitrate_bps_ == 0;
195 } 134 }
196 135
197 void ViEEncoder::TraceFrameDropStart() { 136 void ViEEncoder::TraceFrameDropStart() {
198 // Start trace event only on the first frame after encoder is paused. 137 // Start trace event only on the first frame after encoder is paused.
199 if (!encoder_paused_and_dropped_frame_) { 138 if (!encoder_paused_and_dropped_frame_) {
200 TRACE_EVENT_ASYNC_BEGIN0("webrtc", "EncoderPaused", this); 139 TRACE_EVENT_ASYNC_BEGIN0("webrtc", "EncoderPaused", this);
201 } 140 }
202 encoder_paused_and_dropped_frame_ = true; 141 encoder_paused_and_dropped_frame_ = true;
203 return; 142 return;
204 } 143 }
205 144
206 void ViEEncoder::TraceFrameDropEnd() { 145 void ViEEncoder::TraceFrameDropEnd() {
207 // End trace event on first frame after encoder resumes, if frame was dropped. 146 // End trace event on first frame after encoder resumes, if frame was dropped.
208 if (encoder_paused_and_dropped_frame_) { 147 if (encoder_paused_and_dropped_frame_) {
209 TRACE_EVENT_ASYNC_END0("webrtc", "EncoderPaused", this); 148 TRACE_EVENT_ASYNC_END0("webrtc", "EncoderPaused", this);
210 } 149 }
211 encoder_paused_and_dropped_frame_ = false; 150 encoder_paused_and_dropped_frame_ = false;
212 } 151 }
213 152
214 void ViEEncoder::EncodeVideoFrame(const VideoFrame& video_frame) { 153 void ViEEncoder::EncodeVideoFrame(const VideoFrame& video_frame) {
215 VideoCodecType codec_type; 154 VideoCodecType codec_type;
155 bool do_report_active = false;
216 { 156 {
217 rtc::CritScope lock(&data_cs_); 157 rtc::CritScope lock(&data_cs_);
218 time_of_last_frame_activity_ms_ = rtc::TimeMillis(); 158 time_of_last_frame_activity_ms_ = rtc::TimeMillis();
219 if (EncoderPaused()) { 159 if (EncoderPaused()) {
220 TraceFrameDropStart(); 160 TraceFrameDropStart();
221 return; 161 return;
222 } 162 }
223 TraceFrameDropEnd(); 163 TraceFrameDropEnd();
164 do_report_active = reported_timeout_;
165 reported_timeout_ = false;
224 codec_type = encoder_config_.codecType; 166 codec_type = encoder_config_.codecType;
225 } 167 }
226 168
169 if (do_report_active) {
170 // We have previously reported that the encoder is inactive and we need to
171 // report the state change.
172 LOG(LS_INFO) << "ViEncoder is active.";
173 sink_->OnEncoderActivityChanged(true);
174 }
175
227 TRACE_EVENT_ASYNC_STEP0("webrtc", "Video", video_frame.render_time_ms(), 176 TRACE_EVENT_ASYNC_STEP0("webrtc", "Video", video_frame.render_time_ms(),
228 "Encode"); 177 "Encode");
229 const VideoFrame* frame_to_send = &video_frame; 178 const VideoFrame* frame_to_send = &video_frame;
230 // TODO(wuchengli): support texture frames. 179 // TODO(wuchengli): support texture frames.
231 if (!video_frame.video_frame_buffer()->native_handle()) { 180 if (!video_frame.video_frame_buffer()->native_handle()) {
232 // Pass frame via preprocessor. 181 // Pass frame via preprocessor.
233 frame_to_send = vp_->PreprocessFrame(video_frame); 182 frame_to_send = vp_->PreprocessFrame(video_frame);
234 if (!frame_to_send) { 183 if (!frame_to_send) {
235 // Drop this frame, or there was an error processing it. 184 // Drop this frame, or there was an error processing it.
236 return; 185 return;
(...skipping 20 matching lines...) Expand all
257 video_sender_.AddVideoFrame(*frame_to_send, &codec_specific_info); 206 video_sender_.AddVideoFrame(*frame_to_send, &codec_specific_info);
258 return; 207 return;
259 } 208 }
260 video_sender_.AddVideoFrame(*frame_to_send, nullptr); 209 video_sender_.AddVideoFrame(*frame_to_send, nullptr);
261 } 210 }
262 211
263 void ViEEncoder::SendKeyFrame() { 212 void ViEEncoder::SendKeyFrame() {
264 video_sender_.IntraFrameRequest(0); 213 video_sender_.IntraFrameRequest(0);
265 } 214 }
266 215
216 void ViEEncoder::CheckForActivity() {
217 bool do_report_timeout = false;
218 {
219 rtc::CritScope lock(&data_cs_);
220 // TODO(perkj): Refactor this monitoring once we use TaskQueues and use a
221 // timer instead.
222 // This monitoring was previously achieved by that
223 // VieEncoder::GetPaddingBitrate was by Call for each OnBitrateUpdated.
stefan-webrtc 2016/06/08 09:25:13 This comment needs to be rewritten
perkj_webrtc 2016/06/08 15:35:27 Acknowledged.
224 int64_t now_ms = rtc::TimeMillis();
225 if (!reported_timeout_ && !EncoderPaused() &&
226 (now_ms - time_of_last_frame_activity_ms_ >
227 VideoEncoderSink::TimeOutMs)) {
228 do_report_timeout = true;
229 reported_timeout_ = true;
230 }
231 }
232
233 if (do_report_timeout) {
234 LOG(LS_INFO) << "ViEncoder timed out.";
stefan-webrtc 2016/06/08 09:25:13 ViEEncoder
perkj_webrtc 2016/06/08 15:35:27 Acknowledged.
235 sink_->OnEncoderActivityChanged(false);
236 }
237 }
238
267 void ViEEncoder::OnSetRates(uint32_t bitrate_bps, int framerate) { 239 void ViEEncoder::OnSetRates(uint32_t bitrate_bps, int framerate) {
268 if (stats_proxy_) 240 if (stats_proxy_)
269 stats_proxy_->OnSetRates(bitrate_bps, framerate); 241 stats_proxy_->OnSetRates(bitrate_bps, framerate);
270 } 242 }
271 243
272 int32_t ViEEncoder::Encoded(const EncodedImage& encoded_image, 244 int32_t ViEEncoder::Encoded(const EncodedImage& encoded_image,
273 const CodecSpecificInfo* codec_specific_info, 245 const CodecSpecificInfo* codec_specific_info,
274 const RTPFragmentationHeader* fragmentation) { 246 const RTPFragmentationHeader* fragmentation) {
275 { 247 {
276 rtc::CritScope lock(&data_cs_); 248 rtc::CritScope lock(&data_cs_);
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
314 286
315 void ViEEncoder::OnBitrateUpdated(uint32_t bitrate_bps, 287 void ViEEncoder::OnBitrateUpdated(uint32_t bitrate_bps,
316 uint8_t fraction_lost, 288 uint8_t fraction_lost,
317 int64_t round_trip_time_ms) { 289 int64_t round_trip_time_ms) {
318 LOG(LS_VERBOSE) << "OnBitrateUpdated, bitrate " << bitrate_bps 290 LOG(LS_VERBOSE) << "OnBitrateUpdated, bitrate " << bitrate_bps
319 << " packet loss " << static_cast<int>(fraction_lost) 291 << " packet loss " << static_cast<int>(fraction_lost)
320 << " rtt " << round_trip_time_ms; 292 << " rtt " << round_trip_time_ms;
321 video_sender_.SetChannelParameters(bitrate_bps, fraction_lost, 293 video_sender_.SetChannelParameters(bitrate_bps, fraction_lost,
322 round_trip_time_ms); 294 round_trip_time_ms);
323 bool video_is_suspended = video_sender_.VideoSuspended(); 295 bool video_is_suspended = video_sender_.VideoSuspended();
296
324 bool video_suspension_changed; 297 bool video_suspension_changed;
325 { 298 {
326 rtc::CritScope lock(&data_cs_); 299 rtc::CritScope lock(&data_cs_);
327 last_observed_bitrate_bps_ = bitrate_bps; 300 last_observed_bitrate_bps_ = bitrate_bps;
328 video_suspension_changed = video_suspended_ != video_is_suspended; 301 video_suspension_changed = video_suspended_ != video_is_suspended;
329 video_suspended_ = video_is_suspended; 302 video_suspended_ = video_is_suspended;
330 } 303 }
331 304
332 if (!video_suspension_changed) 305 if (!video_suspension_changed)
333 return; 306 return;
334 // Video suspend-state changed, inform codec observer. 307 // Video suspend-state changed, inform codec observer.
335 LOG(LS_INFO) << "Video suspend state changed " << video_is_suspended; 308 LOG(LS_INFO) << "Video suspend state changed " << video_is_suspended;
336 309
337 if (stats_proxy_) 310 if (stats_proxy_)
338 stats_proxy_->OnSuspendChange(video_is_suspended); 311 stats_proxy_->OnSuspendChange(video_is_suspended);
339 } 312 }
340 313
341 } // namespace webrtc 314 } // namespace webrtc
OLDNEW
« webrtc/video/video_send_stream.cc ('K') | « webrtc/video/vie_encoder.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698