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}
This commit is contained in:
magjed
2017-01-12 06:50:56 -08:00
committed by Commit bot
parent bca122e0d5
commit b66129a27e

View File

@ -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;