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

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

Issue 2480293002: New jitter buffer experiment. (Closed)
Patch Set: Nit fix. Created 4 years, 1 month 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) 2013 The WebRTC project authors. All Rights Reserved. 2 * Copyright (c) 2013 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
11 #include "webrtc/video/video_receive_stream.h" 11 #include "webrtc/video/video_receive_stream.h"
12 12
13 #include <stdlib.h> 13 #include <stdlib.h>
14 14
15 #include <set> 15 #include <set>
16 #include <string> 16 #include <string>
17 #include <utility> 17 #include <utility>
18 18
19 #include "webrtc/base/checks.h" 19 #include "webrtc/base/checks.h"
20 #include "webrtc/base/logging.h" 20 #include "webrtc/base/logging.h"
21 #include "webrtc/base/optional.h"
21 #include "webrtc/common_video/libyuv/include/webrtc_libyuv.h" 22 #include "webrtc/common_video/libyuv/include/webrtc_libyuv.h"
22 #include "webrtc/modules/congestion_controller/include/congestion_controller.h" 23 #include "webrtc/modules/congestion_controller/include/congestion_controller.h"
23 #include "webrtc/modules/utility/include/process_thread.h" 24 #include "webrtc/modules/utility/include/process_thread.h"
25 #include "webrtc/modules/video_coding/frame_object.h"
24 #include "webrtc/modules/video_coding/include/video_coding.h" 26 #include "webrtc/modules/video_coding/include/video_coding.h"
27 #include "webrtc/modules/video_coding/jitter_estimator.h"
28 #include "webrtc/modules/video_coding/timing.h"
25 #include "webrtc/modules/video_coding/utility/ivf_file_writer.h" 29 #include "webrtc/modules/video_coding/utility/ivf_file_writer.h"
26 #include "webrtc/system_wrappers/include/clock.h" 30 #include "webrtc/system_wrappers/include/clock.h"
31 #include "webrtc/system_wrappers/include/field_trial.h"
27 #include "webrtc/video/call_stats.h" 32 #include "webrtc/video/call_stats.h"
28 #include "webrtc/video/receive_statistics_proxy.h" 33 #include "webrtc/video/receive_statistics_proxy.h"
29 #include "webrtc/video_receive_stream.h" 34 #include "webrtc/video_receive_stream.h"
30 #include "webrtc/voice_engine/include/voe_video_sync.h" 35 #include "webrtc/voice_engine/include/voe_video_sync.h"
31 36
32 namespace webrtc { 37 namespace webrtc {
33 38
34 static bool UseSendSideBwe(const VideoReceiveStream::Config& config) { 39 static bool UseSendSideBwe(const VideoReceiveStream::Config& config) {
35 if (!config.rtp.transport_cc) 40 if (!config.rtp.transport_cc)
36 return false; 41 return false;
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
190 : transport_adapter_(config.rtcp_send_transport), 195 : transport_adapter_(config.rtcp_send_transport),
191 config_(std::move(config)), 196 config_(std::move(config)),
192 num_cpu_cores_(num_cpu_cores), 197 num_cpu_cores_(num_cpu_cores),
193 process_thread_(process_thread), 198 process_thread_(process_thread),
194 clock_(Clock::GetRealTimeClock()), 199 clock_(Clock::GetRealTimeClock()),
195 decode_thread_(DecodeThreadFunction, this, "DecodingThread"), 200 decode_thread_(DecodeThreadFunction, this, "DecodingThread"),
196 congestion_controller_(congestion_controller), 201 congestion_controller_(congestion_controller),
197 call_stats_(call_stats), 202 call_stats_(call_stats),
198 video_receiver_(clock_, nullptr, this, this, this), 203 video_receiver_(clock_, nullptr, this, this, this),
199 stats_proxy_(&config_, clock_), 204 stats_proxy_(&config_, clock_),
205 timing_(new VCMTiming(clock_)),
200 rtp_stream_receiver_( 206 rtp_stream_receiver_(
201 &video_receiver_, 207 &video_receiver_,
202 congestion_controller_->GetRemoteBitrateEstimator( 208 congestion_controller_->GetRemoteBitrateEstimator(
203 UseSendSideBwe(config_)), 209 UseSendSideBwe(config_)),
204 &transport_adapter_, 210 &transport_adapter_,
205 call_stats_->rtcp_rtt_stats(), 211 call_stats_->rtcp_rtt_stats(),
206 congestion_controller_->pacer(), 212 congestion_controller_->pacer(),
207 congestion_controller_->packet_router(), 213 congestion_controller_->packet_router(),
208 remb, 214 remb,
209 &config_, 215 &config_,
210 &stats_proxy_, 216 &stats_proxy_,
211 process_thread_, 217 process_thread_,
212 congestion_controller_->GetRetransmissionRateLimiter()), 218 congestion_controller_->GetRetransmissionRateLimiter(),
213 rtp_stream_sync_(&video_receiver_, &rtp_stream_receiver_) { 219 this, // NackSender
220 this, // KeyFrameRequestSender
221 this, // OnCompleteFrameCallback
222 timing_.get()),
223 rtp_stream_sync_(&video_receiver_, &rtp_stream_receiver_),
224 jitter_buffer_experiment_(
225 field_trial::FindFullName("WebRTC-NewVideoJitterBuffer") ==
226 "Enabled") {
214 LOG(LS_INFO) << "VideoReceiveStream: " << config_.ToString(); 227 LOG(LS_INFO) << "VideoReceiveStream: " << config_.ToString();
215 228
216 RTC_DCHECK(process_thread_); 229 RTC_DCHECK(process_thread_);
217 RTC_DCHECK(congestion_controller_); 230 RTC_DCHECK(congestion_controller_);
218 RTC_DCHECK(call_stats_); 231 RTC_DCHECK(call_stats_);
219 232
220 RTC_DCHECK(!config_.decoders.empty()); 233 RTC_DCHECK(!config_.decoders.empty());
221 std::set<int> decoder_payload_types; 234 std::set<int> decoder_payload_types;
222 for (const Decoder& decoder : config_.decoders) { 235 for (const Decoder& decoder : config_.decoders) {
223 RTC_CHECK(decoder.decoder); 236 RTC_CHECK(decoder.decoder);
224 RTC_CHECK(decoder_payload_types.find(decoder.payload_type) == 237 RTC_CHECK(decoder_payload_types.find(decoder.payload_type) ==
225 decoder_payload_types.end()) 238 decoder_payload_types.end())
226 << "Duplicate payload type (" << decoder.payload_type 239 << "Duplicate payload type (" << decoder.payload_type
227 << ") for different decoders."; 240 << ") for different decoders.";
228 decoder_payload_types.insert(decoder.payload_type); 241 decoder_payload_types.insert(decoder.payload_type);
229 } 242 }
230 243
231 video_receiver_.SetRenderDelay(config.render_delay_ms); 244 video_receiver_.SetRenderDelay(config.render_delay_ms);
232 245
246 if (jitter_buffer_experiment_) {
247 jitter_estimator_.reset(new VCMJitterEstimator(clock_));
248 frame_buffer_.reset(new video_coding::FrameBuffer(
249 clock_, jitter_estimator_.get(), timing_.get()));
250 }
251
233 process_thread_->RegisterModule(&video_receiver_); 252 process_thread_->RegisterModule(&video_receiver_);
234 process_thread_->RegisterModule(&rtp_stream_sync_); 253 process_thread_->RegisterModule(&rtp_stream_sync_);
235 } 254 }
236 255
237 VideoReceiveStream::~VideoReceiveStream() { 256 VideoReceiveStream::~VideoReceiveStream() {
238 LOG(LS_INFO) << "~VideoReceiveStream: " << config_.ToString(); 257 LOG(LS_INFO) << "~VideoReceiveStream: " << config_.ToString();
239 Stop(); 258 Stop();
240 259
241 process_thread_->DeRegisterModule(&rtp_stream_sync_); 260 process_thread_->DeRegisterModule(&rtp_stream_sync_);
242 process_thread_->DeRegisterModule(&video_receiver_); 261 process_thread_->DeRegisterModule(&video_receiver_);
(...skipping 18 matching lines...) Expand all
261 } 280 }
262 281
263 bool VideoReceiveStream::OnRecoveredPacket(const uint8_t* packet, 282 bool VideoReceiveStream::OnRecoveredPacket(const uint8_t* packet,
264 size_t length) { 283 size_t length) {
265 return rtp_stream_receiver_.OnRecoveredPacket(packet, length); 284 return rtp_stream_receiver_.OnRecoveredPacket(packet, length);
266 } 285 }
267 286
268 void VideoReceiveStream::Start() { 287 void VideoReceiveStream::Start() {
269 if (decode_thread_.IsRunning()) 288 if (decode_thread_.IsRunning())
270 return; 289 return;
290 if (jitter_buffer_experiment_) {
291 frame_buffer_->Start();
292 call_stats_->RegisterStatsObserver(&rtp_stream_receiver_);
293
294 if (rtp_stream_receiver_.IsRetransmissionsEnabled() &&
295 rtp_stream_receiver_.IsFecEnabled()) {
296 frame_buffer_->SetProtectionMode(kProtectionNackFEC);
297 }
298 }
271 transport_adapter_.Enable(); 299 transport_adapter_.Enable();
272 rtc::VideoSinkInterface<VideoFrame>* renderer = nullptr; 300 rtc::VideoSinkInterface<VideoFrame>* renderer = nullptr;
273 if (config_.renderer) { 301 if (config_.renderer) {
274 if (config_.disable_prerenderer_smoothing) { 302 if (config_.disable_prerenderer_smoothing) {
275 renderer = this; 303 renderer = this;
276 } else { 304 } else {
277 incoming_video_stream_.reset( 305 incoming_video_stream_.reset(
278 new IncomingVideoStream(config_.render_delay_ms, this)); 306 new IncomingVideoStream(config_.render_delay_ms, this));
279 renderer = incoming_video_stream_.get(); 307 renderer = incoming_video_stream_.get();
280 } 308 }
(...skipping 22 matching lines...) Expand all
303 decode_thread_.SetPriority(rtc::kHighestPriority); 331 decode_thread_.SetPriority(rtc::kHighestPriority);
304 rtp_stream_receiver_.StartReceive(); 332 rtp_stream_receiver_.StartReceive();
305 } 333 }
306 334
307 void VideoReceiveStream::Stop() { 335 void VideoReceiveStream::Stop() {
308 rtp_stream_receiver_.StopReceive(); 336 rtp_stream_receiver_.StopReceive();
309 // TriggerDecoderShutdown will release any waiting decoder thread and make it 337 // TriggerDecoderShutdown will release any waiting decoder thread and make it
310 // stop immediately, instead of waiting for a timeout. Needs to be called 338 // stop immediately, instead of waiting for a timeout. Needs to be called
311 // before joining the decoder thread thread. 339 // before joining the decoder thread thread.
312 video_receiver_.TriggerDecoderShutdown(); 340 video_receiver_.TriggerDecoderShutdown();
341
342 if (jitter_buffer_experiment_) {
343 frame_buffer_->Stop();
344 call_stats_->DeregisterStatsObserver(&rtp_stream_receiver_);
345 }
346
313 if (decode_thread_.IsRunning()) { 347 if (decode_thread_.IsRunning()) {
314 decode_thread_.Stop(); 348 decode_thread_.Stop();
315 // Deregister external decoders so they are no longer running during 349 // Deregister external decoders so they are no longer running during
316 // destruction. This effectively stops the VCM since the decoder thread is 350 // destruction. This effectively stops the VCM since the decoder thread is
317 // stopped, the VCM is deregistered and no asynchronous decoder threads are 351 // stopped, the VCM is deregistered and no asynchronous decoder threads are
318 // running. 352 // running.
319 for (const Decoder& decoder : config_.decoders) 353 for (const Decoder& decoder : config_.decoders)
320 video_receiver_.RegisterExternalDecoder(nullptr, decoder.payload_type); 354 video_receiver_.RegisterExternalDecoder(nullptr, decoder.payload_type);
321 } 355 }
356
322 call_stats_->DeregisterStatsObserver(video_stream_decoder_.get()); 357 call_stats_->DeregisterStatsObserver(video_stream_decoder_.get());
323 video_stream_decoder_.reset(); 358 video_stream_decoder_.reset();
324 incoming_video_stream_.reset(); 359 incoming_video_stream_.reset();
325 transport_adapter_.Disable(); 360 transport_adapter_.Disable();
326 } 361 }
327 362
328 void VideoReceiveStream::SetSyncChannel(VoiceEngine* voice_engine, 363 void VideoReceiveStream::SetSyncChannel(VoiceEngine* voice_engine,
329 int audio_channel_id) { 364 int audio_channel_id) {
330 if (voice_engine && audio_channel_id != -1) { 365 if (voice_engine && audio_channel_id != -1) {
331 VoEVideoSync* voe_sync_interface = VoEVideoSync::GetInterface(voice_engine); 366 VoEVideoSync* voe_sync_interface = VoEVideoSync::GetInterface(voice_engine);
(...skipping 26 matching lines...) Expand all
358 stats_proxy_.OnSyncOffsetUpdated(sync_offset_ms, estimated_freq_khz); 393 stats_proxy_.OnSyncOffsetUpdated(sync_offset_ms, estimated_freq_khz);
359 } 394 }
360 395
361 // config_.renderer must never be null if we're getting this callback. 396 // config_.renderer must never be null if we're getting this callback.
362 config_.renderer->OnFrame(video_frame); 397 config_.renderer->OnFrame(video_frame);
363 398
364 // TODO(tommi): OnRenderFrame grabs a lock too. 399 // TODO(tommi): OnRenderFrame grabs a lock too.
365 stats_proxy_.OnRenderedFrame(video_frame); 400 stats_proxy_.OnRenderedFrame(video_frame);
366 } 401 }
367 402
403 void VideoReceiveStream::OnCompleteFrame(
404 std::unique_ptr<video_coding::FrameObject> frame) {
405 int last_continuous_pid = frame_buffer_->InsertFrame(std::move(frame));
406 if (last_continuous_pid != -1)
407 rtp_stream_receiver_.FrameContinuous(last_continuous_pid);
408 }
409
368 // TODO(asapersson): Consider moving callback from video_encoder.h or 410 // TODO(asapersson): Consider moving callback from video_encoder.h or
369 // creating a different callback. 411 // creating a different callback.
370 EncodedImageCallback::Result VideoReceiveStream::OnEncodedImage( 412 EncodedImageCallback::Result VideoReceiveStream::OnEncodedImage(
371 const EncodedImage& encoded_image, 413 const EncodedImage& encoded_image,
372 const CodecSpecificInfo* codec_specific_info, 414 const CodecSpecificInfo* codec_specific_info,
373 const RTPFragmentationHeader* fragmentation) { 415 const RTPFragmentationHeader* fragmentation) {
374 stats_proxy_.OnPreDecode(encoded_image, codec_specific_info); 416 stats_proxy_.OnPreDecode(encoded_image, codec_specific_info);
375 if (config_.pre_decode_callback) { 417 if (config_.pre_decode_callback) {
376 config_.pre_decode_callback->EncodedFrameCallback( 418 config_.pre_decode_callback->EncodedFrameCallback(
377 EncodedFrame(encoded_image._buffer, encoded_image._length, 419 EncodedFrame(encoded_image._buffer, encoded_image._length,
(...skipping 12 matching lines...) Expand all
390 return Result(Result::OK, encoded_image._timeStamp); 432 return Result(Result::OK, encoded_image._timeStamp);
391 } 433 }
392 434
393 bool VideoReceiveStream::DecodeThreadFunction(void* ptr) { 435 bool VideoReceiveStream::DecodeThreadFunction(void* ptr) {
394 static_cast<VideoReceiveStream*>(ptr)->Decode(); 436 static_cast<VideoReceiveStream*>(ptr)->Decode();
395 return true; 437 return true;
396 } 438 }
397 439
398 void VideoReceiveStream::Decode() { 440 void VideoReceiveStream::Decode() {
399 static const int kMaxDecodeWaitTimeMs = 50; 441 static const int kMaxDecodeWaitTimeMs = 50;
400 video_receiver_.Decode(kMaxDecodeWaitTimeMs); 442 if (jitter_buffer_experiment_) {
443 static const int kMaxWaitForFrameMs = 3000;
444 std::unique_ptr<video_coding::FrameObject> frame;
445 video_coding::FrameBuffer::ReturnReason res =
446 frame_buffer_->NextFrame(kMaxWaitForFrameMs, &frame);
447
448 if (res == video_coding::FrameBuffer::ReturnReason::kStopped)
449 return;
450
451 if (frame) {
452 if (video_receiver_.Decode(frame.get()) == VCM_OK)
453 rtp_stream_receiver_.FrameDecoded(frame->picture_id);
454 } else {
455 LOG(LS_WARNING) << "No decodable frame in " << kMaxWaitForFrameMs
456 << " ms, requesting keyframe.";
457 RequestKeyFrame();
458 }
459 } else {
460 video_receiver_.Decode(kMaxDecodeWaitTimeMs);
461 }
401 } 462 }
402 463
403 void VideoReceiveStream::SendNack( 464 void VideoReceiveStream::SendNack(
404 const std::vector<uint16_t>& sequence_numbers) { 465 const std::vector<uint16_t>& sequence_numbers) {
405 rtp_stream_receiver_.RequestPacketRetransmit(sequence_numbers); 466 rtp_stream_receiver_.RequestPacketRetransmit(sequence_numbers);
406 } 467 }
407 468
408 void VideoReceiveStream::EnableEncodedFrameRecording(rtc::PlatformFile file, 469 void VideoReceiveStream::EnableEncodedFrameRecording(rtc::PlatformFile file,
409 size_t byte_limit) { 470 size_t byte_limit) {
410 { 471 {
(...skipping 11 matching lines...) Expand all
422 RequestKeyFrame(); 483 RequestKeyFrame();
423 } 484 }
424 } 485 }
425 486
426 void VideoReceiveStream::RequestKeyFrame() { 487 void VideoReceiveStream::RequestKeyFrame() {
427 rtp_stream_receiver_.RequestKeyFrame(); 488 rtp_stream_receiver_.RequestKeyFrame();
428 } 489 }
429 490
430 } // namespace internal 491 } // namespace internal
431 } // namespace webrtc 492 } // namespace webrtc
OLDNEW
« webrtc/modules/video_coding/packet_buffer.cc ('K') | « webrtc/video/video_receive_stream.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698