Commit 95bf6302 authored by Thomas Guillem's avatar Thomas Guillem Committed by Jean-Baptiste Kempf

mediacodec: fix jni LocalRef leaks

We can only have 512 LocalRefs, so don't leak them.
Signed-off-by: default avatarJean-Baptiste Kempf <jb@videolan.org>
(cherry picked from commit 2b670becb799a36398bb19a64b62dad22d21fc91)
Signed-off-by: default avatarJean-Baptiste Kempf <jb@videolan.org>
parent 1b6b699c
...@@ -381,22 +381,27 @@ static int OpenDecoder(vlc_object_t *p_this) ...@@ -381,22 +381,27 @@ static int OpenDecoder(vlc_object_t *p_this)
jobject codec_name = NULL; jobject codec_name = NULL;
for (int i = 0; i < num_codecs; i++) { for (int i = 0; i < num_codecs; i++) {
jobject info = (*env)->CallStaticObjectMethod(env, p_sys->media_codec_list_class, jobject codec_capabilities = NULL;
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 profile_levels = 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)) { if ((*env)->ExceptionOccurred(env)) {
msg_Warn(p_dec, "Exception occurred in MediaCodecInfo.getCapabilitiesForType"); msg_Warn(p_dec, "Exception occurred in MediaCodecInfo.getCapabilitiesForType");
(*env)->ExceptionClear(env); (*env)->ExceptionClear(env);
(*env)->DeleteLocalRef(env, info); goto loopclean;
continue;
} else if (codec_capabilities) { } else if (codec_capabilities) {
profile_levels = (*env)->GetObjectField(env, codec_capabilities, p_sys->profile_levels_field); profile_levels = (*env)->GetObjectField(env, codec_capabilities, p_sys->profile_levels_field);
if (profile_levels) if (profile_levels)
...@@ -404,15 +409,15 @@ static int OpenDecoder(vlc_object_t *p_this) ...@@ -404,15 +409,15 @@ static int OpenDecoder(vlc_object_t *p_this)
} }
msg_Dbg(p_dec, "Number of profile levels: %d", profile_levels_len); msg_Dbg(p_dec, "Number of profile levels: %d", profile_levels_len);
jobject types = (*env)->CallObjectMethod(env, info, p_sys->get_supported_types); types = (*env)->CallObjectMethod(env, info, p_sys->get_supported_types);
int num_types = (*env)->GetArrayLength(env, types); num_types = (*env)->GetArrayLength(env, types);
jobject name = (*env)->CallObjectMethod(env, info, p_sys->get_name); name = (*env)->CallObjectMethod(env, info, p_sys->get_name);
jsize name_len = (*env)->GetStringUTFLength(env, name); name_len = (*env)->GetStringUTFLength(env, name);
const char *name_ptr = (*env)->GetStringUTFChars(env, name, NULL); name_ptr = (*env)->GetStringUTFChars(env, name, NULL);
bool found = false; found = false;
if (!strncmp(name_ptr, "OMX.google.", __MIN(11, name_len))) if (!strncmp(name_ptr, "OMX.google.", __MIN(11, name_len)))
continue; goto loopclean;
for (int j = 0; j < num_types && !found; j++) { for (int j = 0; j < num_types && !found; j++) {
jobject type = (*env)->GetObjectArrayElement(env, types, j); jobject type = (*env)->GetObjectArrayElement(env, types, j);
if (!jstrcmp(env, type, mime)) { if (!jstrcmp(env, type, mime)) {
...@@ -425,6 +430,7 @@ static int OpenDecoder(vlc_object_t *p_this) ...@@ -425,6 +430,7 @@ static int OpenDecoder(vlc_object_t *p_this)
int omx_profile = (*env)->GetIntField(env, profile_level, p_sys->profile_field); int omx_profile = (*env)->GetIntField(env, profile_level, p_sys->profile_field);
size_t codec_profile = convert_omx_to_profile_idc(omx_profile); size_t codec_profile = convert_omx_to_profile_idc(omx_profile);
(*env)->DeleteLocalRef(env, profile_level);
if (codec_profile != fmt_profile) if (codec_profile != fmt_profile)
continue; continue;
/* Some encoders set the level too high, thus we ignore it for the moment. /* Some encoders set the level too high, thus we ignore it for the moment.
...@@ -442,12 +448,21 @@ static int OpenDecoder(vlc_object_t *p_this) ...@@ -442,12 +448,21 @@ static int OpenDecoder(vlc_object_t *p_this)
p_sys->name = malloc(name_len + 1); p_sys->name = malloc(name_len + 1);
memcpy(p_sys->name, name_ptr, name_len); memcpy(p_sys->name, name_ptr, name_len);
p_sys->name[name_len] = '\0'; p_sys->name[name_len] = '\0';
(*env)->ReleaseStringUTFChars(env, name, name_ptr);
codec_name = name; 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); (*env)->DeleteLocalRef(env, info);
if (found)
break; break;
}
(*env)->DeleteLocalRef(env, info);
} }
if (!codec_name) { if (!codec_name) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment