/* API: destroy stream. */ static pj_status_t strm_destroy(pjmedia_aud_stream *s) { struct opensl_aud_stream *stream = (struct opensl_aud_stream*)s; /* Stop the stream */ strm_stop(s); if (stream->playerObj) { /* Destroy the player */ (*stream->playerObj)->Destroy(stream->playerObj); /* Invalidate all associated interfaces */ stream->playerObj = NULL; stream->playerPlay = NULL; stream->playerBufQ = NULL; stream->playerVol = NULL; } if (stream->recordObj) { /* Destroy the recorder */ (*stream->recordObj)->Destroy(stream->recordObj); /* Invalidate all associated interfaces */ stream->recordObj = NULL; stream->recordRecord = NULL; stream->recordBufQ = NULL; } pj_pool_release(stream->pool); PJ_LOG(4, (THIS_FILE, "OpenSL stream destroyed")); on_teardown_audio_wrapper(); return PJ_SUCCESS; }
/* API: start stream. */ static pj_status_t strm_start(pjmedia_aud_stream *s) { struct opensl_aud_stream *stream = (struct opensl_aud_stream*)s; int i; SLresult result = SL_RESULT_SUCCESS; PJ_LOG(4, (THIS_FILE, "Starting %s stream..", stream->name.ptr)); stream->quit_flag = 0; if (stream->recordBufQ && stream->recordRecord) { /* Enqueue an empty buffer to be filled by the recorder * (for streaming recording, we need to enqueue at least 2 empty * buffers to start things off) */ for (i = 0; i < NUM_BUFFERS; i++) { result = (*stream->recordBufQ)->Enqueue(stream->recordBufQ, stream->recordBuffer[i], stream->recordBufferSize); /* The most likely other result is SL_RESULT_BUFFER_INSUFFICIENT, * which for this code would indicate a programming error */ pj_assert(result == SL_RESULT_SUCCESS); } result = (*stream->recordRecord)->SetRecordState( stream->recordRecord, SL_RECORDSTATE_RECORDING); if (result != SL_RESULT_SUCCESS) { PJ_LOG(3, (THIS_FILE, "Cannot start recorder")); goto on_error; } } if (stream->playerPlay && stream->playerBufQ) { /* Set the player's state to playing */ result = (*stream->playerPlay)->SetPlayState(stream->playerPlay, SL_PLAYSTATE_PLAYING); if (result != SL_RESULT_SUCCESS) { PJ_LOG(3, (THIS_FILE, "Cannot start player")); goto on_error; } for (i = 0; i < NUM_BUFFERS; i++) { pj_bzero(stream->playerBuffer[i], stream->playerBufferSize/100); result = (*stream->playerBufQ)->Enqueue(stream->playerBufQ, stream->playerBuffer[i], stream->playerBufferSize/100); pj_assert(result == SL_RESULT_SUCCESS); } } PJ_LOG(4, (THIS_FILE, "%s stream started", stream->name.ptr)); return PJ_SUCCESS; on_error: if (result != SL_RESULT_SUCCESS) strm_stop(&stream->base); return opensl_to_pj_error(result); }
/* API: destroy stream. */ static pj_status_t strm_destroy(pjmedia_aud_stream *s) { PJ_LOG(4,(THIS_FILE, "Destroying stream")); //Stop the stream strm_stop(s); struct android_aud_stream *stream = (struct android_aud_stream*)s; JNIEnv *jni_env = 0; ATTACH_JVM(jni_env); jmethodID release_method=0; if(stream->record){ //release recording - we assume the release method exists release_method = jni_env->GetMethodID(stream->record_class,"release", "()V"); jni_env->CallVoidMethod(stream->record, release_method); jni_env->DeleteGlobalRef(stream->record); jni_env->DeleteGlobalRef(stream->record_class); stream->record = NULL; stream->record_class = NULL; PJ_LOG(3,(THIS_FILE, "---> Released recorder")); }else{ PJ_LOG(2,(THIS_FILE, "Nothing to release !!! rec")); } if(stream->track){ //release recording - we assume the release method exists release_method = jni_env->GetMethodID(stream->track_class,"release", "()V"); jni_env->CallVoidMethod(stream->track, release_method); jni_env->DeleteGlobalRef(stream->track); jni_env->DeleteGlobalRef(stream->track_class); stream->track = NULL; stream->track_class = NULL; PJ_LOG(3,(THIS_FILE, "---> Released track")); }else{ PJ_LOG(2,(THIS_FILE, "Nothing to release !!! track")); } //Unset media in call on_teardown_audio_wrapper(); // pj_sem_destroy(stream->audio_launch_sem); pj_pool_release(stream->pool); PJ_LOG(3,(THIS_FILE, "Stream is destroyed")); DETACH_JVM(jni_env); return PJ_SUCCESS; }
/* API: destroy stream. */ static pj_status_t strm_destroy(pjmedia_aud_stream *s) { struct android_aud_stream *stream = (struct android_aud_stream*)s; JNIEnv *jni_env = 0; jmethodID release_method=0; 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); pj_thread_join(stream->rec_thread); pj_thread_destroy(stream->rec_thread); stream->rec_thread = NULL; } if (stream->rec_sem) { 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); (*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->track) { if (stream->play_thread) { pj_sem_post(stream->play_sem); pj_thread_join(stream->play_thread); pj_thread_destroy(stream->play_thread); stream->play_thread = NULL; } if (stream->play_sem) { 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); (*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")); } pj_pool_release(stream->pool); PJ_LOG(4, (THIS_FILE, "Android JNI stream destroyed")); detach_jvm(attached); return PJ_SUCCESS; }