[vlc-commits] mediacodec: fix jni LocalRef leaks
Thomas Guillem
git at videolan.org
Fri Dec 12 13:18:33 CET 2014
vlc | branch: master | Thomas Guillem <thomas at gllm.fr> | Fri Dec 12 12:38:54 2014 +0100| [2b670becb799a36398bb19a64b62dad22d21fc91] | committer: Jean-Baptiste Kempf
mediacodec: fix jni LocalRef leaks
We can only have 512 LocalRefs, so don't leak them.
Signed-off-by: Jean-Baptiste Kempf <jb at videolan.org>
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=2b670becb799a36398bb19a64b62dad22d21fc91
---
modules/codec/omxil/android_mediacodec.c | 59 +++++++++++++++++++-----------
1 file changed, 37 insertions(+), 22 deletions(-)
diff --git a/modules/codec/omxil/android_mediacodec.c b/modules/codec/omxil/android_mediacodec.c
index 2d0d346..a8e97fb 100644
--- a/modules/codec/omxil/android_mediacodec.c
+++ b/modules/codec/omxil/android_mediacodec.c
@@ -384,22 +384,27 @@ static int OpenDecoder(vlc_object_t *p_this)
jobject codec_name = NULL;
for (int i = 0; i < num_codecs; i++) {
- jobject info = (*env)->CallStaticObjectMethod(env, p_sys->media_codec_list_class,
- p_sys->get_codec_info_at, i);
- if ((*env)->CallBooleanMethod(env, info, p_sys->is_encoder)) {
- (*env)->DeleteLocalRef(env, info);
- continue;
- }
-
- jobject codec_capabilities = (*env)->CallObjectMethod(env, info, p_sys->get_capabilities_for_type,
- (*env)->NewStringUTF(env, mime));
+ jobject codec_capabilities = NULL;
jobject profile_levels = NULL;
- int profile_levels_len = 0;
+ jobject info = NULL;
+ jobject name = NULL;
+ jobject types = NULL;
+ jsize name_len = 0;
+ int profile_levels_len = 0, num_types = 0;
+ const char *name_ptr = NULL;
+ bool found = false;
+
+ info = (*env)->CallStaticObjectMethod(env, p_sys->media_codec_list_class,
+ p_sys->get_codec_info_at, i);
+ if ((*env)->CallBooleanMethod(env, info, p_sys->is_encoder))
+ goto loopclean;
+
+ codec_capabilities = (*env)->CallObjectMethod(env, info, p_sys->get_capabilities_for_type,
+ (*env)->NewStringUTF(env, mime));
if ((*env)->ExceptionOccurred(env)) {
msg_Warn(p_dec, "Exception occurred in MediaCodecInfo.getCapabilitiesForType");
(*env)->ExceptionClear(env);
- (*env)->DeleteLocalRef(env, info);
- continue;
+ goto loopclean;
} else if (codec_capabilities) {
profile_levels = (*env)->GetObjectField(env, codec_capabilities, p_sys->profile_levels_field);
if (profile_levels)
@@ -407,15 +412,15 @@ static int OpenDecoder(vlc_object_t *p_this)
}
msg_Dbg(p_dec, "Number of profile levels: %d", profile_levels_len);
- jobject types = (*env)->CallObjectMethod(env, info, p_sys->get_supported_types);
- int num_types = (*env)->GetArrayLength(env, types);
- jobject name = (*env)->CallObjectMethod(env, info, p_sys->get_name);
- jsize name_len = (*env)->GetStringUTFLength(env, name);
- const char *name_ptr = (*env)->GetStringUTFChars(env, name, NULL);
- bool found = false;
+ types = (*env)->CallObjectMethod(env, info, p_sys->get_supported_types);
+ num_types = (*env)->GetArrayLength(env, types);
+ name = (*env)->CallObjectMethod(env, info, p_sys->get_name);
+ name_len = (*env)->GetStringUTFLength(env, name);
+ name_ptr = (*env)->GetStringUTFChars(env, name, NULL);
+ found = false;
if (!strncmp(name_ptr, "OMX.google.", __MIN(11, name_len)))
- continue;
+ goto loopclean;
for (int j = 0; j < num_types && !found; j++) {
jobject type = (*env)->GetObjectArrayElement(env, types, j);
if (!jstrcmp(env, type, mime)) {
@@ -428,6 +433,7 @@ static int OpenDecoder(vlc_object_t *p_this)
int omx_profile = (*env)->GetIntField(env, profile_level, p_sys->profile_field);
size_t codec_profile = convert_omx_to_profile_idc(omx_profile);
+ (*env)->DeleteLocalRef(env, profile_level);
if (codec_profile != fmt_profile)
continue;
/* Some encoders set the level too high, thus we ignore it for the moment.
@@ -445,12 +451,21 @@ static int OpenDecoder(vlc_object_t *p_this)
p_sys->name = malloc(name_len + 1);
memcpy(p_sys->name, name_ptr, name_len);
p_sys->name[name_len] = '\0';
- (*env)->ReleaseStringUTFChars(env, name, name_ptr);
codec_name = name;
+ }
+loopclean:
+ if (name)
+ (*env)->ReleaseStringUTFChars(env, name, name_ptr);
+ if (profile_levels)
+ (*env)->DeleteLocalRef(env, profile_levels);
+ if (types)
+ (*env)->DeleteLocalRef(env, types);
+ if (codec_capabilities)
+ (*env)->DeleteLocalRef(env, codec_capabilities);
+ if (info)
(*env)->DeleteLocalRef(env, info);
+ if (found)
break;
- }
- (*env)->DeleteLocalRef(env, info);
}
if (!codec_name) {
More information about the vlc-commits
mailing list