From 4dd40d6b88beb7e4e5dd6afe0a2d02f7ced9fff4 Mon Sep 17 00:00:00 2001 From: "pbos@webrtc.org" Date: Tue, 17 Feb 2015 13:22:43 +0000 Subject: [PATCH] Signal threads for faster receiver destruction. Unblocks pending threads (render thread + decoder thread) when destroying renderers and shutting down decoders. Speeds up SetLocalDescription significantly (10x or so) under WebRtcVideoEngine2 but also shutdown times in ~ViEChannel and ~ViEReceiver in general. BUG=1788 R=mflodman@webrtc.org, stefan@webrtc.org Review URL: https://webrtc-codereview.appspot.com/41959004 Cr-Commit-Position: refs/heads/master@{#8387} git-svn-id: http://webrtc.googlecode.com/svn/trunk@8387 4adac7df-926f-26a2-2b94-8c16560cd09d --- .../main/interface/video_coding.h | 2 ++ .../video_coding/main/source/receiver.cc | 6 ++++- .../video_coding/main/source/receiver.h | 4 ++- .../main/source/video_coding_impl.cc | 4 +++ .../main/source/video_coding_impl.h | 1 + .../main/source/video_receiver.cc | 4 +++ .../video_render/incoming_video_stream.cc | 25 +++++++++++-------- webrtc/video_engine/vie_channel.cc | 2 ++ 8 files changed, 36 insertions(+), 12 deletions(-) diff --git a/webrtc/modules/video_coding/main/interface/video_coding.h b/webrtc/modules/video_coding/main/interface/video_coding.h index f1ce2ec5a3..02b36b14bb 100644 --- a/webrtc/modules/video_coding/main/interface/video_coding.h +++ b/webrtc/modules/video_coding/main/interface/video_coding.h @@ -582,6 +582,8 @@ public: EncodedImageCallback* observer) = 0; virtual void RegisterPostEncodeImageCallback( EncodedImageCallback* post_encode_callback) = 0; + // Releases pending decode calls, permitting faster thread shutdown. + virtual void TriggerDecoderShutdown() = 0; }; } // namespace webrtc diff --git a/webrtc/modules/video_coding/main/source/receiver.cc b/webrtc/modules/video_coding/main/source/receiver.cc index dad2b6f479..6ab9e29173 100644 --- a/webrtc/modules/video_coding/main/source/receiver.cc +++ b/webrtc/modules/video_coding/main/source/receiver.cc @@ -54,7 +54,6 @@ void VCMReceiver::Reset() { int32_t VCMReceiver::Initialize() { Reset(); - CriticalSectionScoped cs(crit_sect_); return VCM_OK; } @@ -86,6 +85,11 @@ int32_t VCMReceiver::InsertPacket(const VCMPacket& packet, return VCM_OK; } +void VCMReceiver::TriggerDecoderShutdown() { + jitter_buffer_.Stop(); + render_wait_event_->Set(); +} + VCMEncodedFrame* VCMReceiver::FrameForDecoding(uint16_t max_wait_time_ms, int64_t& next_render_time_ms, bool render_timing) { diff --git a/webrtc/modules/video_coding/main/source/receiver.h b/webrtc/modules/video_coding/main/source/receiver.h index f531ac8ea4..0e1f01af77 100644 --- a/webrtc/modules/video_coding/main/source/receiver.h +++ b/webrtc/modules/video_coding/main/source/receiver.h @@ -81,11 +81,13 @@ class VCMReceiver { void RegisterStatsCallback(VCMReceiveStatisticsCallback* callback); + void TriggerDecoderShutdown(); + private: static int32_t GenerateReceiverId(); CriticalSectionWrapper* crit_sect_; - Clock* clock_; + Clock* const clock_; VCMJitterBuffer jitter_buffer_; VCMTiming* timing_; scoped_ptr render_wait_event_; diff --git a/webrtc/modules/video_coding/main/source/video_coding_impl.cc b/webrtc/modules/video_coding/main/source/video_coding_impl.cc index 7289e2f0bd..a90ab0709e 100644 --- a/webrtc/modules/video_coding/main/source/video_coding_impl.cc +++ b/webrtc/modules/video_coding/main/source/video_coding_impl.cc @@ -345,6 +345,10 @@ class VideoCodingModuleImpl : public VideoCodingModule { post_encode_callback_.Register(observer); } + void TriggerDecoderShutdown() override { + receiver_->TriggerDecoderShutdown(); + } + private: EncodedImageCallbackWrapper post_encode_callback_; scoped_ptr sender_; diff --git a/webrtc/modules/video_coding/main/source/video_coding_impl.h b/webrtc/modules/video_coding/main/source/video_coding_impl.h index cf4a986264..39e763fc07 100644 --- a/webrtc/modules/video_coding/main/source/video_coding_impl.h +++ b/webrtc/modules/video_coding/main/source/video_coding_impl.h @@ -182,6 +182,7 @@ class VideoReceiver { int32_t Process(); void RegisterPreDecodeImageCallback(EncodedImageCallback* observer); + void TriggerDecoderShutdown(); protected: int32_t Decode(const webrtc::VCMEncodedFrame& frame) diff --git a/webrtc/modules/video_coding/main/source/video_receiver.cc b/webrtc/modules/video_coding/main/source/video_receiver.cc index 46fa399b37..3e20ed3757 100644 --- a/webrtc/modules/video_coding/main/source/video_receiver.cc +++ b/webrtc/modules/video_coding/main/source/video_receiver.cc @@ -335,6 +335,10 @@ int VideoReceiver::RegisterRenderBufferSizeCallback( return VCM_OK; } +void VideoReceiver::TriggerDecoderShutdown() { + _receiver.TriggerDecoderShutdown(); +} + // Decode next frame, blocking. // Should be called as often as possible to get the most out of the decoder. int32_t VideoReceiver::Decode(uint16_t maxWaitTimeMs) { diff --git a/webrtc/modules/video_render/incoming_video_stream.cc b/webrtc/modules/video_render/incoming_video_stream.cc index 4a95622bc6..256c21cfab 100644 --- a/webrtc/modules/video_render/incoming_video_stream.cc +++ b/webrtc/modules/video_render/incoming_video_stream.cc @@ -246,14 +246,21 @@ int32_t IncomingVideoStream::Stop() { return 0; } - thread_critsect_.Enter(); - if (incoming_render_thread_) { - ThreadWrapper* thread = incoming_render_thread_; - incoming_render_thread_ = NULL; -#ifndef WIN32_ - deliver_buffer_event_.StopTimer(); -#endif - thread_critsect_.Leave(); + ThreadWrapper* thread = NULL; + { + CriticalSectionScoped cs_thread(&thread_critsect_); + if (incoming_render_thread_ != NULL) { + thread = incoming_render_thread_; + // Setting the incoming render thread to NULL marks that we're performing + // a shutdown and will make IncomingVideoStreamProcess abort after wakeup. + incoming_render_thread_ = NULL; + deliver_buffer_event_.StopTimer(); + // Set the event to allow the thread to wake up and shut down without + // waiting for a timeout. + deliver_buffer_event_.Set(); + } + } + if (thread) { if (thread->Stop()) { delete thread; } else { @@ -261,8 +268,6 @@ int32_t IncomingVideoStream::Stop() { WEBRTC_TRACE(kTraceWarning, kTraceVideoRenderer, module_id_, "%s: Not able to stop thread, leaking", __FUNCTION__); } - } else { - thread_critsect_.Leave(); } running_ = false; return 0; diff --git a/webrtc/video_engine/vie_channel.cc b/webrtc/video_engine/vie_channel.cc index 0278fe3312..dcb9596d09 100644 --- a/webrtc/video_engine/vie_channel.cc +++ b/webrtc/video_engine/vie_channel.cc @@ -1733,6 +1733,8 @@ int32_t ViEChannel::StopDecodeThread() { return 0; } + vcm_->TriggerDecoderShutdown(); + if (decode_thread_->Stop()) { delete decode_thread_; } else {