From ac4b87c2588e4e2b51e0677849ed482ea490d30d Mon Sep 17 00:00:00 2001 From: "wuchengli@chromium.org" Date: Wed, 19 Mar 2014 03:44:20 +0000 Subject: [PATCH] Fix a deadlock in ViEEncoder::DeliverFrame. The deadlock can happen when using HW encoder. HW encoder calls the encode complete callback on libjingle worker thread instead of ViECaptureThread. The capture thread can hold VieEncoder::|data_cs_| and wait for ModuleRtpRtcpImpl::|critical_section_module_ptrs_|. When libjingle worker thread runs encode complete callback, it can hold ModuleRtpRtcpImpl::|critical_section_module_ptrs_| and wait for VieEncoder::|data_cs_|. |default_rtp_rtcp_| is not guarded by |data_cs|. So move it out of the critical section to avoid the deadlock. BUG=chromium:352567 TEST=Run apprtc loopback on CrOS. Run apprtc between CrOS and Linux. Run vie_auto_test. R=henrik.lundin@webrtc.org, pbos@webrtc.org, stefan@webrtc.org Review URL: https://webrtc-codereview.appspot.com/10039004 git-svn-id: http://webrtc.googlecode.com/svn/trunk@5721 4adac7df-926f-26a2-2b94-8c16560cd09d --- webrtc/video_engine/vie_encoder.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/webrtc/video_engine/vie_encoder.cc b/webrtc/video_engine/vie_encoder.cc index 22a74fb7b..5583c7585 100644 --- a/webrtc/video_engine/vie_encoder.cc +++ b/webrtc/video_engine/vie_encoder.cc @@ -575,13 +575,13 @@ void ViEEncoder::DeliverFrame(int id, ViEId(engine_id_, channel_id_), "%s: %llu", __FUNCTION__, video_frame->timestamp()); + if (default_rtp_rtcp_->SendingMedia() == false) { + // We've paused or we have no channels attached, don't encode. + return; + } { CriticalSectionScoped cs(data_cs_.get()); time_of_last_incoming_frame_ms_ = TickTime::MillisecondTimestamp(); - if (default_rtp_rtcp_->SendingMedia() == false) { - // We've paused or we have no channels attached, don't encode. - return; - } if (EncoderPaused()) { if (!encoder_paused_and_dropped_frame_) { TRACE_EVENT_ASYNC_BEGIN0("webrtc", "EncoderPaused", this);