[FFmpeg-devel] [PATCH 2/5] lavu/jni: add more JNI helper
Michael Niedermayer
michael at niedermayer.cc
Sat Oct 10 03:18:38 CEST 2015
On Fri, Oct 09, 2015 at 06:26:50PM +0200, Matthieu Bouron wrote:
> From: Matthieu Bouron <matthieu.bouron at stupeflix.com>
>
> ---
> libavutil/jni_internal.c | 290 +++++++++++++++++++++++++++++++++++++++++++++++
> libavutil/jni_internal.h | 101 +++++++++++++++++
> 2 files changed, 391 insertions(+)
>
> diff --git a/libavutil/jni_internal.c b/libavutil/jni_internal.c
> index b17275d..2c1dc70 100644
> --- a/libavutil/jni_internal.c
> +++ b/libavutil/jni_internal.c
> @@ -18,6 +18,7 @@
> * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
> */
>
> +#include "bprint.h"
> #include "config.h"
> #include "jni.h"
> #include "jni_internal.h"
> @@ -67,3 +68,292 @@ int avpriv_jni_detach_env(void *log_ctx)
>
> return (*java_vm)->DetachCurrentThread(java_vm);
> }
> +
> +char *avpriv_jni_jstring_to_utf_chars(JNIEnv *env, jstring string, void *log_ctx)
> +{
> + char *ret = NULL;
> + const char *utf_chars = NULL;
> +
> + jboolean copy = 0;
> +
> + utf_chars = (*env)->GetStringUTFChars(env, string, ©);
> + if ((*env)->ExceptionCheck(env)) {
> + (*env)->ExceptionClear(env);
> + av_log(log_ctx, AV_LOG_ERROR, "String.getStringUTFChars() threw an exception\n");
> + return NULL;
> + }
> +
> + ret = av_strdup(utf_chars);
> +
> + (*env)->ReleaseStringUTFChars(env, string, utf_chars);
> + if ((*env)->ExceptionCheck(env)) {
> + (*env)->ExceptionClear(env);
> + av_log(log_ctx, AV_LOG_ERROR, "String.releaseStringUTFChars() threw an exception\n");
> + return NULL;;
> + }
> +
> + return ret;
> +}
> +
> +jstring avpriv_jni_utf_chars_to_jstring(JNIEnv *env, const char *utf_chars, void *log_ctx)
> +{
> + jstring ret;
> +
> + ret = (*env)->NewStringUTF(env, utf_chars);
> + if ((*env)->ExceptionCheck(env)) {
> + (*env)->ExceptionClear(env);
> + av_log(log_ctx, AV_LOG_ERROR, "NewStringUTF() threw an exception\n");
> + return NULL;
> + }
> +
> + return ret;
> +}
> +
> +int avpriv_jni_exception_get_summary(JNIEnv *env, jthrowable exception, char **error, void *log_ctx)
> +{
> + int ret = 0;
> +
> + AVBPrint bp;
> +
> + char *name = NULL;
> + char *message = NULL;
> +
> + jclass class_class = NULL;
> + jmethodID get_name_id = NULL;
> +
> + jclass exception_class = NULL;
> + jmethodID get_message_id = NULL;
> +
> + jstring string;
> +
> + av_bprint_init(&bp, 0, AV_BPRINT_SIZE_AUTOMATIC);
> +
> + exception_class = (*env)->GetObjectClass(env, exception);
> + if ((*env)->ExceptionCheck(env)) {
> + (*env)->ExceptionClear(env);
> + av_log(log_ctx, AV_LOG_ERROR, "Could not find Throwable class\n");
> + ret = AVERROR_EXTERNAL;
> + goto done;
> + }
> +
> + class_class = (*env)->GetObjectClass(env, exception_class);
> + if ((*env)->ExceptionCheck(env)) {
> + (*env)->ExceptionClear(env);
> + av_log(log_ctx, AV_LOG_ERROR, "Could not find Throwable class's class\n");
> + ret = AVERROR_EXTERNAL;
> + goto done;
> + }
> +
> + get_name_id = (*env)->GetMethodID(env, class_class, "getName", "()Ljava/lang/String;");
> + if ((*env)->ExceptionCheck(env)) {
> + (*env)->ExceptionClear(env);
> + av_log(log_ctx, AV_LOG_ERROR, "Could not find method Class.getName()\n");
> + ret = AVERROR_EXTERNAL;
> + goto done;
> + }
> +
> + string = (*env)->CallObjectMethod(env, exception_class, get_name_id);
> + if ((*env)->ExceptionCheck(env)) {
> + (*env)->ExceptionClear(env);
> + av_log(log_ctx, AV_LOG_ERROR, "Class.getName() threw an exception\n");
> + ret = AVERROR_EXTERNAL;
> + goto done;
> + }
> +
> + name = avpriv_jni_jstring_to_utf_chars(env, string, log_ctx);
> + if (!name) {
> + ret = AVERROR(ENOMEM);
> + goto done;
> + }
> +
> + (*env)->DeleteLocalRef(env, string);
> +
> + get_message_id = (*env)->GetMethodID(env, exception_class, "getMessage", "()Ljava/lang/String;");
> + if ((*env)->ExceptionCheck(env)) {
> + (*env)->ExceptionClear(env);
> + av_log(log_ctx, AV_LOG_ERROR, "Could not find method java/lang/Throwable.getMessage()\n");
> + ret = AVERROR_EXTERNAL;
> + goto done;
> + }
> +
> + string = (*env)->CallObjectMethod(env, exception, get_message_id);
> + if ((*env)->ExceptionCheck(env)) {
> + (*env)->ExceptionClear(env);
> + av_log(log_ctx, AV_LOG_ERROR, "Throwable.getMessage() threw an exception\n");
> + ret = AVERROR_EXTERNAL;
> + goto done;
> + }
> +
> + message = avpriv_jni_jstring_to_utf_chars(env, string, log_ctx);
> + if (!message) {
> + ret = AVERROR(ENOMEM);
> + goto done;
> + }
> +
> + (*env)->DeleteLocalRef(env, string);
> +
> + av_bprintf(&bp, "%s: %s", name, message);
> + ret = av_bprint_finalize(&bp, error);
> +
> +done:
> +
> + av_free(name);
> + av_free(message);
> +
> + if (class_class) {
> + (*env)->DeleteLocalRef(env, class_class);
> + }
> +
> + if (exception_class) {
> + (*env)->DeleteLocalRef(env, exception_class);
> + }
> +
> + return ret;
> +}
> +
> +int avpriv_jni_exception_check(JNIEnv *env, int log, void *log_ctx)
> +{
> + int ret;
> +
> + jthrowable exception;
> +
> + char *message;
> +
> + if (!(*(env))->ExceptionCheck((env))) {
> + return 0;
> + }
> +
> + if (!log) {
> + (*(env))->ExceptionClear((env));
> + return -1;
> + }
> +
> + exception = (*env)->ExceptionOccurred(env);
> + (*(env))->ExceptionClear((env));
> +
> + if ((ret = avpriv_jni_exception_get_summary(env, exception, &message, log_ctx)) < 0) {
> + return ret;
> + }
> +
> + (*env)->DeleteLocalRef(env, exception);
> +
> + av_log(log_ctx, AV_LOG_ERROR, "%s\n", message);
> + av_free(message);
> +
> + return -1;
probably should be a AVERROR code, same for the other -1
> +}
> +
> +int avpriv_jni_init_jfields(JNIEnv *env, void *jfields, const struct FFJniField *jfields_mapping, int global, void *log_ctx)
> +{
> + int i, ret = 0;
> + jclass last_clazz = NULL;
> +
> + for (i = 0; jfields_mapping[i].name; i++) {
> + int mandatory = jfields_mapping[i].mandatory;
> + enum FFJniFieldType type = jfields_mapping[i].type;
> +
> + if (type == FF_JNI_CLASS) {
> + jclass clazz;
> +
> + last_clazz = NULL;
> +
> + clazz = (*env)->FindClass(env, jfields_mapping[i].name);
> + if ((ret = avpriv_jni_exception_check(env, mandatory, log_ctx) && mandatory) < 0) {
the < 0 looks wrongly placed
[...]
--
Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB
Those who are best at talking, realize last or never when they are wrong.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 181 bytes
Desc: Digital signature
URL: <http://ffmpeg.org/pipermail/ffmpeg-devel/attachments/20151010/fbc3316c/attachment.sig>
More information about the ffmpeg-devel
mailing list