summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRiza Sulistyo <riza@teluu.com>2016-06-27 11:09:01 +0000
committerRiza Sulistyo <riza@teluu.com>2016-06-27 11:09:01 +0000
commita0021d168c110589e37fb8ef1bc7589b239ba8d6 (patch)
treecfd607c53146482807b14faefeff71826c05a1a0
parentb6286dbe1a6fef17f94c0483bd20c5dab1212bd8 (diff)
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
-rw-r--r--pjmedia/src/pjmedia-audiodev/android_jni_dev.c115
1 files changed, 69 insertions, 46 deletions
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);