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
This commit is contained in:
pbos@webrtc.org
2015-02-17 13:22:43 +00:00
parent 0a7d4eed98
commit 4dd40d6b88
8 changed files with 36 additions and 12 deletions

View File

@ -582,6 +582,8 @@ public:
EncodedImageCallback* observer) = 0; EncodedImageCallback* observer) = 0;
virtual void RegisterPostEncodeImageCallback( virtual void RegisterPostEncodeImageCallback(
EncodedImageCallback* post_encode_callback) = 0; EncodedImageCallback* post_encode_callback) = 0;
// Releases pending decode calls, permitting faster thread shutdown.
virtual void TriggerDecoderShutdown() = 0;
}; };
} // namespace webrtc } // namespace webrtc

View File

@ -54,7 +54,6 @@ void VCMReceiver::Reset() {
int32_t VCMReceiver::Initialize() { int32_t VCMReceiver::Initialize() {
Reset(); Reset();
CriticalSectionScoped cs(crit_sect_);
return VCM_OK; return VCM_OK;
} }
@ -86,6 +85,11 @@ int32_t VCMReceiver::InsertPacket(const VCMPacket& packet,
return VCM_OK; return VCM_OK;
} }
void VCMReceiver::TriggerDecoderShutdown() {
jitter_buffer_.Stop();
render_wait_event_->Set();
}
VCMEncodedFrame* VCMReceiver::FrameForDecoding(uint16_t max_wait_time_ms, VCMEncodedFrame* VCMReceiver::FrameForDecoding(uint16_t max_wait_time_ms,
int64_t& next_render_time_ms, int64_t& next_render_time_ms,
bool render_timing) { bool render_timing) {

View File

@ -81,11 +81,13 @@ class VCMReceiver {
void RegisterStatsCallback(VCMReceiveStatisticsCallback* callback); void RegisterStatsCallback(VCMReceiveStatisticsCallback* callback);
void TriggerDecoderShutdown();
private: private:
static int32_t GenerateReceiverId(); static int32_t GenerateReceiverId();
CriticalSectionWrapper* crit_sect_; CriticalSectionWrapper* crit_sect_;
Clock* clock_; Clock* const clock_;
VCMJitterBuffer jitter_buffer_; VCMJitterBuffer jitter_buffer_;
VCMTiming* timing_; VCMTiming* timing_;
scoped_ptr<EventWrapper> render_wait_event_; scoped_ptr<EventWrapper> render_wait_event_;

View File

@ -345,6 +345,10 @@ class VideoCodingModuleImpl : public VideoCodingModule {
post_encode_callback_.Register(observer); post_encode_callback_.Register(observer);
} }
void TriggerDecoderShutdown() override {
receiver_->TriggerDecoderShutdown();
}
private: private:
EncodedImageCallbackWrapper post_encode_callback_; EncodedImageCallbackWrapper post_encode_callback_;
scoped_ptr<vcm::VideoSender> sender_; scoped_ptr<vcm::VideoSender> sender_;

View File

@ -182,6 +182,7 @@ class VideoReceiver {
int32_t Process(); int32_t Process();
void RegisterPreDecodeImageCallback(EncodedImageCallback* observer); void RegisterPreDecodeImageCallback(EncodedImageCallback* observer);
void TriggerDecoderShutdown();
protected: protected:
int32_t Decode(const webrtc::VCMEncodedFrame& frame) int32_t Decode(const webrtc::VCMEncodedFrame& frame)

View File

@ -335,6 +335,10 @@ int VideoReceiver::RegisterRenderBufferSizeCallback(
return VCM_OK; return VCM_OK;
} }
void VideoReceiver::TriggerDecoderShutdown() {
_receiver.TriggerDecoderShutdown();
}
// Decode next frame, blocking. // Decode next frame, blocking.
// Should be called as often as possible to get the most out of the decoder. // Should be called as often as possible to get the most out of the decoder.
int32_t VideoReceiver::Decode(uint16_t maxWaitTimeMs) { int32_t VideoReceiver::Decode(uint16_t maxWaitTimeMs) {

View File

@ -246,14 +246,21 @@ int32_t IncomingVideoStream::Stop() {
return 0; return 0;
} }
thread_critsect_.Enter(); ThreadWrapper* thread = NULL;
if (incoming_render_thread_) { {
ThreadWrapper* thread = incoming_render_thread_; CriticalSectionScoped cs_thread(&thread_critsect_);
incoming_render_thread_ = NULL; if (incoming_render_thread_ != NULL) {
#ifndef WIN32_ thread = incoming_render_thread_;
deliver_buffer_event_.StopTimer(); // Setting the incoming render thread to NULL marks that we're performing
#endif // a shutdown and will make IncomingVideoStreamProcess abort after wakeup.
thread_critsect_.Leave(); 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()) { if (thread->Stop()) {
delete thread; delete thread;
} else { } else {
@ -261,8 +268,6 @@ int32_t IncomingVideoStream::Stop() {
WEBRTC_TRACE(kTraceWarning, kTraceVideoRenderer, module_id_, WEBRTC_TRACE(kTraceWarning, kTraceVideoRenderer, module_id_,
"%s: Not able to stop thread, leaking", __FUNCTION__); "%s: Not able to stop thread, leaking", __FUNCTION__);
} }
} else {
thread_critsect_.Leave();
} }
running_ = false; running_ = false;
return 0; return 0;

View File

@ -1733,6 +1733,8 @@ int32_t ViEChannel::StopDecodeThread() {
return 0; return 0;
} }
vcm_->TriggerDecoderShutdown();
if (decode_thread_->Stop()) { if (decode_thread_->Stop()) {
delete decode_thread_; delete decode_thread_;
} else { } else {