mirror of https://github.com/mpv-player/mpv
ao_audiotrack: make audiotrack jni multi-instance and multi-thread safe
The detailed issue is here: #15212 problem: Since The AudioTrack is not an mpv instance level but a global object, it cannot support multiple mpv instances at the same time. For example, if you create two instances and then destroy one of them, the other instance may crash. Add jni usage count to fix this.
This commit is contained in:
parent
f8db474090
commit
46fe3cded0
|
@ -30,6 +30,9 @@
|
||||||
#include "osdep/timer.h"
|
#include "osdep/timer.h"
|
||||||
#include "misc/jni.h"
|
#include "misc/jni.h"
|
||||||
|
|
||||||
|
static mp_static_mutex jni_static_lock = MP_STATIC_MUTEX_INITIALIZER;
|
||||||
|
static int jni_static_use_count = 0;
|
||||||
|
|
||||||
struct priv {
|
struct priv {
|
||||||
jobject audiotrack;
|
jobject audiotrack;
|
||||||
jint samplerate;
|
jint samplerate;
|
||||||
|
@ -524,26 +527,40 @@ static int AudioTrack_write(struct ao *ao, int len)
|
||||||
|
|
||||||
static void uninit_jni(struct ao *ao)
|
static void uninit_jni(struct ao *ao)
|
||||||
{
|
{
|
||||||
|
mp_mutex_lock(&jni_static_lock);
|
||||||
|
jni_static_use_count--;
|
||||||
|
if (jni_static_use_count == 0) {
|
||||||
JNIEnv *env = MP_JNI_GET_ENV(ao);
|
JNIEnv *env = MP_JNI_GET_ENV(ao);
|
||||||
for (int i = 0; i < MP_ARRAY_SIZE(jclass_list); i++) {
|
for (int i = 0; i < MP_ARRAY_SIZE(jclass_list); i++) {
|
||||||
mp_jni_reset_jfields(env, jclass_list[i].fields,
|
mp_jni_reset_jfields(env, jclass_list[i].fields,
|
||||||
jclass_list[i].mapping, 1, ao->log);
|
jclass_list[i].mapping, 1, ao->log);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
mp_mutex_unlock(&jni_static_lock);
|
||||||
|
}
|
||||||
|
|
||||||
static int init_jni(struct ao *ao)
|
static int init_jni(struct ao *ao)
|
||||||
{
|
{
|
||||||
|
mp_mutex_lock(&jni_static_lock);
|
||||||
JNIEnv *env = MP_JNI_GET_ENV(ao);
|
JNIEnv *env = MP_JNI_GET_ENV(ao);
|
||||||
|
if (jni_static_use_count == 0) {
|
||||||
for (int i = 0; i < MP_ARRAY_SIZE(jclass_list); i++) {
|
for (int i = 0; i < MP_ARRAY_SIZE(jclass_list); i++) {
|
||||||
if (mp_jni_init_jfields(env, jclass_list[i].fields,
|
if (mp_jni_init_jfields(env, jclass_list[i].fields,
|
||||||
jclass_list[i].mapping, 1, ao->log) < 0) {
|
jclass_list[i].mapping, 1, ao->log) < 0) {
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
jni_static_use_count++;
|
||||||
|
mp_mutex_unlock(&jni_static_lock);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
uninit_jni(ao);
|
for (int i = 0; i < MP_ARRAY_SIZE(jclass_list); i++) {
|
||||||
|
mp_jni_reset_jfields(env, jclass_list[i].fields,
|
||||||
|
jclass_list[i].mapping, 1, ao->log);
|
||||||
|
}
|
||||||
|
mp_mutex_unlock(&jni_static_lock);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue