From a0021d168c110589e37fb8ef1bc7589b239ba8d6 Mon Sep 17 00:00:00 2001 From: Riza Sulistyo Date: Mon, 27 Jun 2016 11:09:01 +0000 Subject: Fixed #1939: Fixed crash when failed to initialize android jni dev (AudioRecord). git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@5357 74dad513-b988-da41-8d7b-12977e46ad98 --- pjmedia/src/pjmedia-audiodev/android_jni_dev.c | 115 +++++++++++++++---------- 1 file changed, 69 insertions(+), 46 deletions(-) (limited to 'pjmedia') diff --git a/pjmedia/src/pjmedia-audiodev/android_jni_dev.c b/pjmedia/src/pjmedia-audiodev/android_jni_dev.c index 24c204e7..610cd9ed 100644 --- a/pjmedia/src/pjmedia-audiodev/android_jni_dev.c +++ b/pjmedia/src/pjmedia-audiodev/android_jni_dev.c @@ -59,7 +59,7 @@ struct android_aud_stream pj_str_t name; pjmedia_dir dir; pjmedia_aud_param param; - + int bytes_per_sample; pj_uint32_t samples_per_sec; unsigned samples_per_frame; @@ -76,8 +76,8 @@ struct android_aud_stream pj_bool_t rec_thread_exited; pj_thread_t *rec_thread; pj_sem_t *rec_sem; - pj_timestamp rec_timestamp; - + pj_timestamp rec_timestamp; + /* Track */ jobject track; jclass track_class; @@ -86,7 +86,7 @@ struct android_aud_stream pj_bool_t play_thread_exited; pj_thread_t *play_thread; pj_sem_t *play_sem; - pj_timestamp play_timestamp; + pj_timestamp play_timestamp; }; /* Factory prototypes */ @@ -663,6 +663,7 @@ static pj_status_t android_create_stream(pjmedia_aud_dev_factory *f, if (stream->dir & PJMEDIA_DIR_CAPTURE) { jthrowable exc; + jobject record_obj; int mic_source = 0; /* DEFAULT: default audio source */ /* Get pointer to the constructor */ @@ -694,15 +695,15 @@ static pj_status_t android_create_stream(pjmedia_aud_dev_factory *f, PJ_LOG(4, (THIS_FILE, "Using audio input source : %d", mic_source)); do { - stream->record = (*jni_env)->NewObject(jni_env, - stream->record_class, - constructor_method, - mic_source, - param->clock_rate, - channelInCfg, - sampleFormat, - inputBuffSizeRec); - if (stream->record == 0) { + record_obj = (*jni_env)->NewObject(jni_env, + stream->record_class, + constructor_method, + mic_source, + param->clock_rate, + channelInCfg, + sampleFormat, + inputBuffSizeRec); + if (record_obj == 0) { PJ_LOG(3, (THIS_FILE, "Unable to create audio record object")); status = PJMEDIA_EAUD_INIT; goto on_error; @@ -731,8 +732,7 @@ static pj_status_t android_create_stream(pjmedia_aud_dev_factory *f, status = PJMEDIA_EAUD_SYSERR; goto on_error; } - state = (*jni_env)->CallIntMethod(jni_env, stream->record, - method_id); + state = (*jni_env)->CallIntMethod(jni_env, record_obj, method_id); if (state == 0) { /* STATE_UNINITIALIZED */ PJ_LOG(3, (THIS_FILE, "Failure in initializing audio record.")); if (mic_source == 0) { @@ -744,9 +744,16 @@ static pj_status_t android_create_stream(pjmedia_aud_dev_factory *f, } } while (state == 0); - stream->record = (*jni_env)->NewGlobalRef(jni_env, stream->record); + stream->record = (*jni_env)->NewGlobalRef(jni_env, record_obj); if (stream->record == 0) { - PJ_LOG(3, (THIS_FILE, "Unable to create audio record global ref.")); + jmethodID release_method=0; + + PJ_LOG(3, (THIS_FILE, "Unable to create audio record global ref.")); + release_method = (*jni_env)->GetMethodID(jni_env, + stream->record_class, + "release", "()V"); + (*jni_env)->CallVoidMethod(jni_env, record_obj, release_method); + status = PJMEDIA_EAUD_INIT; goto on_error; } @@ -766,6 +773,7 @@ static pj_status_t android_create_stream(pjmedia_aud_dev_factory *f, if (stream->dir & PJMEDIA_DIR_PLAYBACK) { jthrowable exc; + jobject track_obj; /* Get pointer to the constructor */ constructor_method = (*jni_env)->GetMethodID(jni_env, @@ -777,16 +785,16 @@ static pj_status_t android_create_stream(pjmedia_aud_dev_factory *f, goto on_error; } - stream->track = (*jni_env)->NewObject(jni_env, - stream->track_class, - constructor_method, - 0, /* STREAM_VOICE_CALL */ - param->clock_rate, - channelOutCfg, - sampleFormat, - inputBuffSizePlay, - 1 /* MODE_STREAM */); - if (stream->track == 0) { + track_obj = (*jni_env)->NewObject(jni_env, + stream->track_class, + constructor_method, + 0, /* STREAM_VOICE_CALL */ + param->clock_rate, + channelOutCfg, + sampleFormat, + inputBuffSizePlay, + 1 /* MODE_STREAM */); + if (track_obj == 0) { PJ_LOG(3, (THIS_FILE, "Unable to create audio track object.")); status = PJMEDIA_EAUD_INIT; goto on_error; @@ -801,8 +809,15 @@ static pj_status_t android_create_stream(pjmedia_aud_dev_factory *f, goto on_error; } - stream->track = (*jni_env)->NewGlobalRef(jni_env, stream->track); + stream->track = (*jni_env)->NewGlobalRef(jni_env, track_obj); if (stream->track == 0) { + jmethodID release_method=0; + + release_method = (*jni_env)->GetMethodID(jni_env, + stream->track_class, + "release", "()V"); + (*jni_env)->CallVoidMethod(jni_env, track_obj, release_method); + PJ_LOG(3, (THIS_FILE, "Unable to create audio track's global ref")); status = PJMEDIA_EAUD_INIT; goto on_error; @@ -972,14 +987,14 @@ static pj_status_t strm_destroy(pjmedia_aud_stream *s) pj_bool_t attached; PJ_LOG(4,(THIS_FILE, "Destroying Android JNI stream...")); - + stream->quit_flag = PJ_TRUE; /* Stop the stream */ strm_stop(s); attached = attach_jvm(&jni_env); - + if (stream->record){ if (stream->rec_thread) { pj_sem_post(stream->rec_sem); @@ -992,17 +1007,21 @@ static pj_status_t strm_destroy(pjmedia_aud_stream *s) pj_sem_destroy(stream->rec_sem); stream->rec_sem = NULL; } - - release_method = (*jni_env)->GetMethodID(jni_env, stream->record_class, - "release", "()V"); - (*jni_env)->CallVoidMethod(jni_env, stream->record, release_method); - + if (stream->record_class) { + release_method = (*jni_env)->GetMethodID(jni_env, + stream->record_class, + "release", "()V"); + (*jni_env)->CallVoidMethod(jni_env, stream->record, + release_method); + } (*jni_env)->DeleteGlobalRef(jni_env, stream->record); - (*jni_env)->DeleteGlobalRef(jni_env, stream->record_class); stream->record = NULL; - stream->record_class = NULL; PJ_LOG(4, (THIS_FILE, "Audio record released")); } + if (stream->record_class) { + (*jni_env)->DeleteGlobalRef(jni_env, stream->record_class); + stream->record_class = NULL; + } if (stream->track) { if (stream->play_thread) { @@ -1016,16 +1035,20 @@ static pj_status_t strm_destroy(pjmedia_aud_stream *s) pj_sem_destroy(stream->play_sem); stream->play_sem = NULL; } - - release_method = (*jni_env)->GetMethodID(jni_env, stream->track_class, - "release", "()V"); - (*jni_env)->CallVoidMethod(jni_env, stream->track, release_method); - + if (stream->track_class) { + release_method = (*jni_env)->GetMethodID(jni_env, + stream->track_class, + "release", "()V"); + (*jni_env)->CallVoidMethod(jni_env, stream->track, + release_method); + } (*jni_env)->DeleteGlobalRef(jni_env, stream->track); - (*jni_env)->DeleteGlobalRef(jni_env, stream->track_class); - stream->track = NULL; - stream->track_class = NULL; - PJ_LOG(3, (THIS_FILE, "Audio track released")); + stream->track = NULL; + PJ_LOG(4, (THIS_FILE, "Audio track released")); + } + if (stream->track_class) { + (*jni_env)->DeleteGlobalRef(jni_env, stream->track_class); + stream->track_class = NULL; } pj_pool_release(stream->pool); -- cgit v1.2.3