JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *jvm, void *reserved) { JNIEnv *env = NULL; cached_jvm = jvm; if (jvm->GetEnv((void **) &env, JNI_VERSION) != JNI_OK) return JNI_ERR; if (pthread_key_create(&jni_env_key, jni_detach_thread) != 0) return JNI_ERR; #define GET_CLASS(clazz, str, globlal) do { \ (clazz) = env->FindClass((str)); \ if (!(clazz)) { \ E("FindClass(%s) failed", (str)); \ return -1; \ } \ if (globlal) { \ (clazz) = (jclass) env->NewGlobalRef((clazz)); \ if (!(clazz)) { \ E("NewGlobalRef(%s) failed", (str)); \ return -1; \ } \ } \ } while (0) #define GET_ID(get, id, clazz, str, args) do { \ (id) = env->get((clazz), (str), (args)); \ if (!(id)) { \ E(#get"(%s) failed", (str)); \ return -1; \ } \ } while (0) GET_CLASS(gfq.clazz, "com/dxyh/libfqrtmp/LibFQRtmp", 1); GET_CLASS(gfq.IllegalArgumentException.clazz, "java/lang/IllegalArgumentException", 1); GET_CLASS(gfq.String.clazz, "java/lang/String", 1); GET_ID(GetStaticMethodID, gfq.onNativeCrashID, gfq.clazz, "onNativeCrash", "()V"); GET_ID(GetMethodID, gfq.dispatchEventFromNativeID, gfq.clazz, "dispatchEventFromNative", "(IJLjava/lang/String;)V"); env->RegisterNatives(gfq.clazz, method, NELEM(method)); init_native_crash_handler(); I("JNI interface loaded."); return JNI_VERSION; }
void Java_org_videolan_libvlc_LibVLC_nativeInit(JNIEnv *env, jobject thiz) { //only use OpenSLES if java side says we can jclass cls = (*env)->GetObjectClass(env, thiz); jmethodID methodId = (*env)->GetMethodID(env, cls, "getAout", "()I"); bool use_opensles = (*env)->CallIntMethod(env, thiz, methodId) == AOUT_OPENSLES; methodId = (*env)->GetMethodID(env, cls, "getVout", "()I"); bool use_opengles2 = (*env)->CallIntMethod(env, thiz, methodId) == VOUT_OPENGLES2; methodId = (*env)->GetMethodID(env, cls, "timeStretchingEnabled", "()Z"); bool enable_time_stretch = (*env)->CallBooleanMethod(env, thiz, methodId); methodId = (*env)->GetMethodID(env, cls, "frameSkipEnabled", "()Z"); bool enable_frame_skip = (*env)->CallBooleanMethod(env, thiz, methodId); methodId = (*env)->GetMethodID(env, cls, "getDeblocking", "()I"); int deblocking = (*env)->CallIntMethod(env, thiz, methodId); char deblockstr[2]; snprintf(deblockstr, sizeof(deblockstr), "%d", deblocking); LOGD("Using deblocking level %d", deblocking); methodId = (*env)->GetMethodID(env, cls, "getNetworkCaching", "()I"); int networkCaching = (*env)->CallIntMethod(env, thiz, methodId); char networkCachingstr[25]; if(networkCaching > 0) { snprintf(networkCachingstr, sizeof(networkCachingstr), "--network-caching=%d", networkCaching); LOGD("Using network caching of %d ms", networkCaching); } methodId = (*env)->GetMethodID(env, cls, "getChroma", "()Ljava/lang/String;"); jstring chroma = (*env)->CallObjectMethod(env, thiz, methodId); const char *chromastr = (*env)->GetStringUTFChars(env, chroma, 0); LOGD("Chroma set to \"%s\"", chromastr); methodId = (*env)->GetMethodID(env, cls, "getSubtitlesEncoding", "()Ljava/lang/String;"); jstring subsencoding = (*env)->CallObjectMethod(env, thiz, methodId); const char *subsencodingstr = (*env)->GetStringUTFChars(env, subsencoding, 0); LOGD("Subtitle encoding set to \"%s\"", subsencodingstr); methodId = (*env)->GetMethodID(env, cls, "isVerboseMode", "()Z"); verbosity = (*env)->CallBooleanMethod(env, thiz, methodId); methodId = (*env)->GetMethodID(env, cls, "getHardwareAcceleration", "()I"); int hardwareAcceleration = (*env)->CallIntMethod(env, thiz, methodId); /* With the MediaCodec opaque mode we cannot use the OpenGL ES vout. */ if (hardwareAcceleration == HW_ACCELERATION_FULL) use_opengles2 = false; /* Don't add any invalid options, otherwise it causes LibVLC to crash */ const char *argv[] = { /* CPU intensive plugin, setting for slow devices */ enable_time_stretch ? "--audio-time-stretch" : "--no-audio-time-stretch", /* avcodec speed settings for slow devices */ //"--avcodec-fast", // non-spec-compliant speedup tricks "--avcodec-skiploopfilter", deblockstr, "--avcodec-skip-frame", enable_frame_skip ? "2" : "0", "--avcodec-skip-idct", enable_frame_skip ? "2" : "0", /* Remove me when UTF-8 is enforced by law */ "--subsdec-encoding", subsencodingstr, /* XXX: why can't the default be fine ? #7792 */ (networkCaching > 0) ? networkCachingstr : "", /* Android audio API is a mess */ use_opensles ? "--aout=opensles" : "--aout=android_audiotrack", /* Android video API is a mess */ use_opengles2 ? "--vout=gles2" : "--vout=androidsurface", "--androidsurface-chroma", chromastr != NULL && chromastr[0] != 0 ? chromastr : "RV32", /* XXX: we can't recover from direct rendering failure */ (hardwareAcceleration == HW_ACCELERATION_FULL) ? "" : "--no-mediacodec-dr", }; libvlc_instance_t *instance = libvlc_new(sizeof(argv) / sizeof(*argv), argv); setLong(env, thiz, "mLibVlcInstance", (jlong)(intptr_t) instance); (*env)->ReleaseStringUTFChars(env, chroma, chromastr); (*env)->ReleaseStringUTFChars(env, subsencoding, subsencodingstr); if (!instance) { jclass exc = (*env)->FindClass(env, "org/videolan/libvlc/LibVlcException"); (*env)->ThrowNew(env, exc, "Unable to instantiate LibVLC"); } LOGI("LibVLC initialized: %p", instance); libvlc_log_set(instance, debug_log, &verbosity); init_native_crash_handler(env, thiz); }
void Java_org_videolan_libvlc_LibVLC_nativeInit(JNIEnv *env, jobject thiz) { //only use OpenSLES if java side says we can jclass cls = (*env)->GetObjectClass(env, thiz); jmethodID methodId = (*env)->GetMethodID(env, cls, "getAout", "()I"); int aout = (*env)->CallIntMethod(env, thiz, methodId); methodId = (*env)->GetMethodID(env, cls, "getVout", "()I"); int vout = (*env)->CallIntMethod(env, thiz, methodId); methodId = (*env)->GetMethodID(env, cls, "timeStretchingEnabled", "()Z"); bool enable_time_stretch = (*env)->CallBooleanMethod(env, thiz, methodId); methodId = (*env)->GetMethodID(env, cls, "frameSkipEnabled", "()Z"); bool enable_frame_skip = (*env)->CallBooleanMethod(env, thiz, methodId); methodId = (*env)->GetMethodID(env, cls, "getDeblocking", "()I"); int deblocking = (*env)->CallIntMethod(env, thiz, methodId); char deblockstr[2]; snprintf(deblockstr, sizeof(deblockstr), "%d", deblocking); LOGD("Using deblocking level %d", deblocking); methodId = (*env)->GetMethodID(env, cls, "getNetworkCaching", "()I"); int networkCaching = (*env)->CallIntMethod(env, thiz, methodId); char networkCachingstr[25]; if(networkCaching > 0) { snprintf(networkCachingstr, sizeof(networkCachingstr), "--network-caching=%d", networkCaching); LOGD("Using network caching of %d ms", networkCaching); } methodId = (*env)->GetMethodID(env, cls, "getHttpReconnect", "()Z"); bool enable_http_reconnect = (*env)->CallBooleanMethod(env, thiz, methodId); methodId = (*env)->GetMethodID(env, cls, "getChroma", "()Ljava/lang/String;"); jstring chroma = (*env)->CallObjectMethod(env, thiz, methodId); const char *chromastr = (*env)->GetStringUTFChars(env, chroma, 0); LOGD("Chroma set to \"%s\"", chromastr); methodId = (*env)->GetMethodID(env, cls, "getSubtitlesEncoding", "()Ljava/lang/String;"); jstring subsencoding = (*env)->CallObjectMethod(env, thiz, methodId); const char *subsencodingstr = (*env)->GetStringUTFChars(env, subsencoding, 0); LOGD("Subtitle encoding set to \"%s\"", subsencodingstr); methodId = (*env)->GetMethodID(env, cls, "isVerboseMode", "()Z"); verbosity = (*env)->CallBooleanMethod(env, thiz, methodId); methodId = (*env)->GetMethodID(env, cls, "isDirectRendering", "()Z"); bool direct_rendering = (*env)->CallBooleanMethod(env, thiz, methodId); /* With the MediaCodec opaque mode we cannot use the OpenGL ES vout. */ if (direct_rendering) vout = VOUT_ANDROID_WINDOW; methodId = (*env)->GetMethodID(env, cls, "getCachePath", "()Ljava/lang/String;"); jstring cachePath = (*env)->CallObjectMethod(env, thiz, methodId); if (cachePath) { const char *cache_path = (*env)->GetStringUTFChars(env, cachePath, 0); setenv("DVDCSS_CACHE", cache_path, 1); (*env)->ReleaseStringUTFChars(env, cachePath, cache_path); } #define MAX_ARGV 18 const char *argv[MAX_ARGV]; int argc = 0; /* CPU intensive plugin, setting for slow devices */ argv[argc++] = enable_time_stretch ? "--audio-time-stretch" : "--no-audio-time-stretch"; /* avcodec-skiploopfilter */ argv[argc++] = "--avcodec-skiploopfilter"; argv[argc++] = deblockstr; /* avcodec-skip-frame */ argv[argc++] = "--avcodec-skip-frame"; argv[argc++] = enable_frame_skip ? "2" : "0"; /* avcodec-skip-idct */ argv[argc++] = "--avcodec-skip-idct"; argv[argc++] = enable_frame_skip ? "2" : "0"; /* Remove me when UTF-8 is enforced by law */ argv[argc++] = "--subsdec-encoding"; argv[argc++] = subsencodingstr; /* Enable statistics */ argv[argc++] = "--stats"; /* XXX: why can't the default be fine ? #7792 */ if (networkCaching > 0) argv[argc++] = networkCachingstr; /* Android audio API */ argv[argc++] = aout == AOUT_OPENSLES ? "--aout=opensles" : (aout == AOUT_AUDIOTRACK ? "--aout=android_audiotrack" : "--aout=dummy"); /* Android video API */ argv[argc++] = vout == VOUT_ANDROID_WINDOW ? "--vout=androidwindow" : (vout == VOUT_OPENGLES2 ? "--vout=gles2" : "--vout=androidsurface"); /* chroma */ argv[argc++] = "--androidsurface-chroma"; argv[argc++] = chromastr != NULL && chromastr[0] != 0 ? chromastr : "RV32"; /* direct rendering */ if (!direct_rendering) { argv[argc++] = "--no-mediacodec-dr"; #ifdef HAVE_IOMX_DR argv[argc++] = "--no-omxil-dr"; #endif } /* Reconnect on lost HTTP streams, e.g. network change */ if (enable_http_reconnect) argv[argc++] = "--http-reconnect"; assert(MAX_ARGV >= argc); libvlc_instance_t *instance = libvlc_new(argc, argv); setLong(env, thiz, "mLibVlcInstance", (jlong)(intptr_t) instance); (*env)->ReleaseStringUTFChars(env, chroma, chromastr); (*env)->ReleaseStringUTFChars(env, subsencoding, subsencodingstr); if (!instance) { jclass exc = (*env)->FindClass(env, "org/videolan/libvlc/LibVlcException"); (*env)->ThrowNew(env, exc, "Unable to instantiate LibVLC"); } LOGI("LibVLC initialized: %p", instance); libvlc_log_set(instance, debug_log, &verbosity); init_native_crash_handler(env, thiz); }