From b66129a27efd44198e4a73a27268ae17032bb617 Mon Sep 17 00:00:00 2001 From: magjed Date: Thu, 12 Jan 2017 06:50:56 -0800 Subject: [PATCH] Fix JNI reference leak in MediaCodecVideoEncoder We currently leak one local reference to MediaCodecVideoEncoder in every call to MediaCodecVideoEncoderFactory::CreateVideoEncoder. After the encoder has been re-initialized 512 times, JNI will crash due to local reference table overflow (max=512). The actual leak is in the member initializer list of MediaCodecVideoEncoder. This CL fixes the leak by adding a ScopedLocalRefFrame outside of the ctor. All JNI code that originate from a C++ thread (i.e. the entry point is not a Java thread) must use a ScopedLocalRefFrame in order to avoid leaking local references. BUG=webrtc:6969,b/34056152 Review-Url: https://codereview.webrtc.org/2627973004 Cr-Commit-Position: refs/heads/master@{#16034} --- webrtc/sdk/android/src/jni/androidmediaencoder_jni.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/webrtc/sdk/android/src/jni/androidmediaencoder_jni.cc b/webrtc/sdk/android/src/jni/androidmediaencoder_jni.cc index 9efe53c396..17c6a1833c 100644 --- a/webrtc/sdk/android/src/jni/androidmediaencoder_jni.cc +++ b/webrtc/sdk/android/src/jni/androidmediaencoder_jni.cc @@ -314,7 +314,6 @@ MediaCodecVideoEncoder::MediaCodecVideoEncoder(JNIEnv* jni, picture_id_(0), egl_context_(egl_context), sw_fallback_required_(false) { - ScopedLocalRefFrame local_ref_frame(jni); // It would be nice to avoid spinning up a new thread per MediaCodec, and // instead re-use e.g. the PeerConnectionFactory's |worker_thread_|, but bug // 2732 means that deadlocks abound. This class synchronously trampolines @@ -1267,8 +1266,9 @@ webrtc::VideoEncoder* MediaCodecVideoEncoderFactory::CreateVideoEncoder( } if (FindMatchingCodec(supported_codecs_, codec)) { ALOGD << "Create HW video encoder for " << codec.name; - return new MediaCodecVideoEncoder(AttachCurrentThreadIfNeeded(), codec, - egl_context_); + JNIEnv* jni = AttachCurrentThreadIfNeeded(); + ScopedLocalRefFrame local_ref_frame(jni); + return new MediaCodecVideoEncoder(jni, codec, egl_context_); } ALOGW << "Can not find HW video encoder for type " << codec.name; return nullptr;