[FFmpeg-devel] [PATCH 1/7] avcodec: move ffjni to avutil/jniutils
Matthieu Bouron
matthieu.bouron at gmail.com
Wed Feb 14 00:50:09 EET 2024
This will allow to use the jni utils in libavformat. This will be mostly useful
to add Android content-uri support.
This deprecates avcodec/jni.h functions in favor of the ones from avutil/jni.h.
---
doc/APIchanges | 6 +
libavcodec/Makefile | 3 +-
libavcodec/jni.c | 48 +----
libavcodec/jni.h | 8 +
libavcodec/mediacodec.c | 6 +-
libavcodec/mediacodec_surface.c | 6 +-
libavcodec/mediacodec_wrapper.c | 200 ++++++++++-----------
libavcodec/mediacodecdec.c | 3 +-
libavutil/Makefile | 4 +
libavutil/jni.c | 78 ++++++++
libavutil/jni.h | 46 +++++
libavcodec/ffjni.c => libavutil/jniutils.c | 36 ++--
libavcodec/ffjni.h => libavutil/jniutils.h | 26 ++-
13 files changed, 283 insertions(+), 187 deletions(-)
create mode 100644 libavutil/jni.c
create mode 100644 libavutil/jni.h
rename libavcodec/ffjni.c => libavutil/jniutils.c (88%)
rename libavcodec/ffjni.h => libavutil/jniutils.h (84%)
diff --git a/doc/APIchanges b/doc/APIchanges
index 221fea30c2..45611ea7ea 100644
--- a/doc/APIchanges
+++ b/doc/APIchanges
@@ -2,6 +2,12 @@ The last version increases of all libraries were on 2023-02-09
API changes, most recent first:
+2024-02-xx - xxxxxxxxxx - lavu 58.39.100 - jni.h
+ Add av_jni_set_jvm() and av_jni_get_jvm().
+
+2024-02-xx - xxxxxxxxxx - lavc 60.40.100 - jni.h
+ Deprecate av_jni_set_java_vm() and av_jni_get_java_vm().
+
2024-02-xx - xxxxxxxxxx - lavu 58.38.100 - channel_layout.h
Add av_channel_layout_retype().
diff --git a/libavcodec/Makefile b/libavcodec/Makefile
index 470d7cb9b1..f8584d8dfd 100644
--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
@@ -117,7 +117,7 @@ OBJS-$(CONFIG_IIRFILTER) += iirfilter.o
OBJS-$(CONFIG_INFLATE_WRAPPER) += zlib_wrapper.o
OBJS-$(CONFIG_INTRAX8) += intrax8.o intrax8dsp.o msmpeg4data.o
OBJS-$(CONFIG_IVIDSP) += ivi_dsp.o
-OBJS-$(CONFIG_JNI) += ffjni.o jni.o
+OBJS-$(CONFIG_JNI) += jni.o
OBJS-$(CONFIG_JPEGTABLES) += jpegtables.o
OBJS-$(CONFIG_LCMS2) += fflcms2.o
OBJS-$(CONFIG_LLAUDDSP) += lossless_audiodsp.o
@@ -1269,7 +1269,6 @@ SKIPHEADERS-$(CONFIG_AMF) += amfenc.h
SKIPHEADERS-$(CONFIG_D3D11VA) += d3d11va.h dxva2_internal.h
SKIPHEADERS-$(CONFIG_D3D12VA) += d3d12va_decode.h
SKIPHEADERS-$(CONFIG_DXVA2) += dxva2.h dxva2_internal.h
-SKIPHEADERS-$(CONFIG_JNI) += ffjni.h
SKIPHEADERS-$(CONFIG_LCMS2) += fflcms2.h
SKIPHEADERS-$(CONFIG_LIBAOM) += libaom.h
SKIPHEADERS-$(CONFIG_LIBJXL) += libjxl.h
diff --git a/libavcodec/jni.c b/libavcodec/jni.c
index ae6490de9d..a98c27d73a 100644
--- a/libavcodec/jni.c
+++ b/libavcodec/jni.c
@@ -20,60 +20,18 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#include "config.h"
-
#include <stdlib.h>
#include "libavutil/error.h"
+#include "libavutil/jni.h"
#include "jni.h"
-#if CONFIG_JNI
-#include <jni.h>
-#include <pthread.h>
-
-#include "libavutil/log.h"
-#include "ffjni.h"
-
-static void *java_vm;
-static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
-
-int av_jni_set_java_vm(void *vm, void *log_ctx)
-{
- int ret = 0;
-
- pthread_mutex_lock(&lock);
- if (java_vm == NULL) {
- java_vm = vm;
- } else if (java_vm != vm) {
- ret = AVERROR(EINVAL);
- av_log(log_ctx, AV_LOG_ERROR, "A Java virtual machine has already been set");
- }
- pthread_mutex_unlock(&lock);
-
- return ret;
-}
-
-void *av_jni_get_java_vm(void *log_ctx)
-{
- void *vm;
-
- pthread_mutex_lock(&lock);
- vm = java_vm;
- pthread_mutex_unlock(&lock);
-
- return vm;
-}
-
-#else
-
int av_jni_set_java_vm(void *vm, void *log_ctx)
{
- return AVERROR(ENOSYS);
+ return av_jni_set_jvm(vm, log_ctx);
}
void *av_jni_get_java_vm(void *log_ctx)
{
- return NULL;
+ return av_jni_get_jvm(log_ctx);
}
-
-#endif
diff --git a/libavcodec/jni.h b/libavcodec/jni.h
index dd99e92611..49ddab4120 100644
--- a/libavcodec/jni.h
+++ b/libavcodec/jni.h
@@ -23,6 +23,8 @@
#ifndef AVCODEC_JNI_H
#define AVCODEC_JNI_H
+#include <libavutil/attributes.h>
+
/*
* Manually set a Java virtual machine which will be used to retrieve the JNI
* environment. Once a Java VM is set it cannot be changed afterwards, meaning
@@ -32,7 +34,10 @@
* @param vm Java virtual machine
* @param log_ctx context used for logging, can be NULL
* @return 0 on success, < 0 otherwise
+ *
+ * @deprecated use av_jni_set_jvm from libavutil/jni.h
*/
+attribute_deprecated
int av_jni_set_java_vm(void *vm, void *log_ctx);
/*
@@ -40,7 +45,10 @@ int av_jni_set_java_vm(void *vm, void *log_ctx);
*
* @param vm Java virtual machine
* @return a pointer to the Java virtual machine
+ *
+ * @deprecated use av_jni_get_jvm from libavutil/jni.h
*/
+attribute_deprecated
void *av_jni_get_java_vm(void *log_ctx);
#endif /* AVCODEC_JNI_H */
diff --git a/libavcodec/mediacodec.c b/libavcodec/mediacodec.c
index 33bde8112e..2f1ccaa480 100644
--- a/libavcodec/mediacodec.c
+++ b/libavcodec/mediacodec.c
@@ -31,9 +31,9 @@
#include <jni.h>
#include "libavcodec/avcodec.h"
+#include "libavutil/jniutils.h"
#include "libavutil/mem.h"
-#include "ffjni.h"
#include "mediacodecdec_common.h"
AVMediaCodecContext *av_mediacodec_alloc_context(void)
@@ -46,7 +46,7 @@ int av_mediacodec_default_init(AVCodecContext *avctx, AVMediaCodecContext *ctx,
int ret = 0;
JNIEnv *env = NULL;
- env = ff_jni_get_env(avctx);
+ env = avpriv_jni_get_env(avctx);
if (!env) {
return AVERROR_EXTERNAL;
}
@@ -72,7 +72,7 @@ void av_mediacodec_default_free(AVCodecContext *avctx)
return;
}
- env = ff_jni_get_env(avctx);
+ env = avpriv_jni_get_env(avctx);
if (!env) {
return;
}
diff --git a/libavcodec/mediacodec_surface.c b/libavcodec/mediacodec_surface.c
index ef41cdafa7..748f3e2804 100644
--- a/libavcodec/mediacodec_surface.c
+++ b/libavcodec/mediacodec_surface.c
@@ -24,7 +24,7 @@
#include <jni.h>
#include "libavutil/mem.h"
-#include "ffjni.h"
+#include "libavutil/jniutils.h"
#include "mediacodec_surface.h"
FFANativeWindow *ff_mediacodec_surface_ref(void *surface, void *native_window, void *log_ctx)
@@ -38,7 +38,7 @@ FFANativeWindow *ff_mediacodec_surface_ref(void *surface, void *native_window, v
if (surface) {
JNIEnv *env = NULL;
- env = ff_jni_get_env(log_ctx);
+ env = avpriv_jni_get_env(log_ctx);
if (env)
ret->surface = (*env)->NewGlobalRef(env, surface);
}
@@ -64,7 +64,7 @@ int ff_mediacodec_surface_unref(FFANativeWindow *window, void *log_ctx)
if (window->surface) {
JNIEnv *env = NULL;
- env = ff_jni_get_env(log_ctx);
+ env = avpriv_jni_get_env(log_ctx);
if (env)
(*env)->DeleteGlobalRef(env, window->surface);
}
diff --git a/libavcodec/mediacodec_wrapper.c b/libavcodec/mediacodec_wrapper.c
index 0880ddd3ef..bc3eb0a80d 100644
--- a/libavcodec/mediacodec_wrapper.c
+++ b/libavcodec/mediacodec_wrapper.c
@@ -30,9 +30,9 @@
#include "libavutil/avassert.h"
#include "libavutil/mem.h"
#include "libavutil/avstring.h"
+#include "libavutil/jniutils.h"
#include "avcodec.h"
-#include "ffjni.h"
#include "mediacodec_wrapper.h"
struct JNIAMediaCodecListFields {
@@ -287,14 +287,14 @@ typedef struct FFAMediaCodecJni {
static const FFAMediaCodec media_codec_jni;
#define JNI_GET_ENV_OR_RETURN(env, log_ctx, ret) do { \
- (env) = ff_jni_get_env(log_ctx); \
+ (env) = avpriv_jni_get_env(log_ctx); \
if (!(env)) { \
return ret; \
} \
} while (0)
#define JNI_GET_ENV_OR_RETURN_VOID(env, log_ctx) do { \
- (env) = ff_jni_get_env(log_ctx); \
+ (env) = avpriv_jni_get_env(log_ctx); \
if (!(env)) { \
return; \
} \
@@ -485,16 +485,16 @@ char *ff_AMediaCodecList_getCodecNameByType(const char *mime, int profile, int e
JNI_GET_ENV_OR_RETURN(env, log_ctx, NULL);
- if ((ret = ff_jni_init_jfields(env, &jfields, jni_amediacodeclist_mapping, 0, log_ctx)) < 0) {
+ if ((ret = avpriv_jni_init_jfields(env, &jfields, jni_amediacodeclist_mapping, 0, log_ctx)) < 0) {
goto done;
}
- if ((ret = ff_jni_init_jfields(env, &mediaformat_jfields, jni_amediaformat_mapping, 0, log_ctx)) < 0) {
+ if ((ret = avpriv_jni_init_jfields(env, &mediaformat_jfields, jni_amediaformat_mapping, 0, log_ctx)) < 0) {
goto done;
}
codec_count = (*env)->CallStaticIntMethod(env, jfields.mediacodec_list_class, jfields.get_codec_count_id);
- if (ff_jni_exception_check(env, 1, log_ctx) < 0) {
+ if (avpriv_jni_exception_check(env, 1, log_ctx) < 0) {
goto done;
}
@@ -504,17 +504,17 @@ char *ff_AMediaCodecList_getCodecNameByType(const char *mime, int profile, int e
int is_encoder;
info = (*env)->CallStaticObjectMethod(env, jfields.mediacodec_list_class, jfields.get_codec_info_at_id, i);
- if (ff_jni_exception_check(env, 1, log_ctx) < 0) {
+ if (avpriv_jni_exception_check(env, 1, log_ctx) < 0) {
goto done;
}
types = (*env)->CallObjectMethod(env, info, jfields.get_supported_types_id);
- if (ff_jni_exception_check(env, 1, log_ctx) < 0) {
+ if (avpriv_jni_exception_check(env, 1, log_ctx) < 0) {
goto done;
}
is_encoder = (*env)->CallBooleanMethod(env, info, jfields.is_encoder_id);
- if (ff_jni_exception_check(env, 1, log_ctx) < 0) {
+ if (avpriv_jni_exception_check(env, 1, log_ctx) < 0) {
goto done;
}
@@ -524,7 +524,7 @@ char *ff_AMediaCodecList_getCodecNameByType(const char *mime, int profile, int e
if (jfields.is_software_only_id) {
int is_software_only = (*env)->CallBooleanMethod(env, info, jfields.is_software_only_id);
- if (ff_jni_exception_check(env, 1, log_ctx) < 0) {
+ if (avpriv_jni_exception_check(env, 1, log_ctx) < 0) {
goto done;
}
@@ -534,11 +534,11 @@ char *ff_AMediaCodecList_getCodecNameByType(const char *mime, int profile, int e
}
codec_name = (*env)->CallObjectMethod(env, info, jfields.get_name_id);
- if (ff_jni_exception_check(env, 1, log_ctx) < 0) {
+ if (avpriv_jni_exception_check(env, 1, log_ctx) < 0) {
goto done;
}
- name = ff_jni_jstring_to_utf_chars(env, codec_name, log_ctx);
+ name = avpriv_jni_jstring_to_utf_chars(env, codec_name, log_ctx);
if (!name) {
goto done;
}
@@ -563,11 +563,11 @@ char *ff_AMediaCodecList_getCodecNameByType(const char *mime, int profile, int e
int profile_count;
type = (*env)->GetObjectArrayElement(env, types, j);
- if (ff_jni_exception_check(env, 1, log_ctx) < 0) {
+ if (avpriv_jni_exception_check(env, 1, log_ctx) < 0) {
goto done;
}
- supported_type = ff_jni_jstring_to_utf_chars(env, type, log_ctx);
+ supported_type = avpriv_jni_jstring_to_utf_chars(env, type, log_ctx);
if (!supported_type) {
goto done;
}
@@ -577,12 +577,12 @@ char *ff_AMediaCodecList_getCodecNameByType(const char *mime, int profile, int e
}
capabilities = (*env)->CallObjectMethod(env, info, jfields.get_codec_capabilities_id, type);
- if (ff_jni_exception_check(env, 1, log_ctx) < 0) {
+ if (avpriv_jni_exception_check(env, 1, log_ctx) < 0) {
goto done;
}
profile_levels = (*env)->GetObjectField(env, capabilities, jfields.profile_levels_id);
- if (ff_jni_exception_check(env, 1, log_ctx) < 0) {
+ if (avpriv_jni_exception_check(env, 1, log_ctx) < 0) {
goto done;
}
@@ -599,12 +599,12 @@ char *ff_AMediaCodecList_getCodecNameByType(const char *mime, int profile, int e
}
profile_level = (*env)->GetObjectArrayElement(env, profile_levels, k);
- if (ff_jni_exception_check(env, 1, log_ctx) < 0) {
+ if (avpriv_jni_exception_check(env, 1, log_ctx) < 0) {
goto done;
}
supported_profile = (*env)->GetIntField(env, profile_level, jfields.profile_id);
- if (ff_jni_exception_check(env, 1, log_ctx) < 0) {
+ if (avpriv_jni_exception_check(env, 1, log_ctx) < 0) {
goto done;
}
@@ -692,8 +692,8 @@ done:
av_freep(&supported_type);
- ff_jni_reset_jfields(env, &jfields, jni_amediacodeclist_mapping, 0, log_ctx);
- ff_jni_reset_jfields(env, &mediaformat_jfields, jni_amediaformat_mapping, 0, log_ctx);
+ avpriv_jni_reset_jfields(env, &jfields, jni_amediacodeclist_mapping, 0, log_ctx);
+ avpriv_jni_reset_jfields(env, &mediaformat_jfields, jni_amediaformat_mapping, 0, log_ctx);
if (!found_codec) {
av_freep(&name);
@@ -714,13 +714,13 @@ static FFAMediaFormat *mediaformat_jni_new(void)
}
format->api = media_format_jni;
- env = ff_jni_get_env(format);
+ env = avpriv_jni_get_env(format);
if (!env) {
av_freep(&format);
return NULL;
}
- if (ff_jni_init_jfields(env, &format->jfields, jni_amediaformat_mapping, 1, format) < 0) {
+ if (avpriv_jni_init_jfields(env, &format->jfields, jni_amediaformat_mapping, 1, format) < 0) {
goto fail;
}
@@ -740,7 +740,7 @@ fail:
}
if (!format->object) {
- ff_jni_reset_jfields(env, &format->jfields, jni_amediaformat_mapping, 1, format);
+ avpriv_jni_reset_jfields(env, &format->jfields, jni_amediaformat_mapping, 1, format);
av_freep(&format);
}
@@ -758,13 +758,13 @@ static FFAMediaFormat *mediaformat_jni_newFromObject(void *object)
}
format->api = media_format_jni;
- env = ff_jni_get_env(format);
+ env = avpriv_jni_get_env(format);
if (!env) {
av_freep(&format);
return NULL;
}
- if (ff_jni_init_jfields(env, &format->jfields, jni_amediaformat_mapping, 1, format) < 0) {
+ if (avpriv_jni_init_jfields(env, &format->jfields, jni_amediaformat_mapping, 1, format) < 0) {
goto fail;
}
@@ -775,7 +775,7 @@ static FFAMediaFormat *mediaformat_jni_newFromObject(void *object)
return (FFAMediaFormat *)format;
fail:
- ff_jni_reset_jfields(env, &format->jfields, jni_amediaformat_mapping, 1, format);
+ avpriv_jni_reset_jfields(env, &format->jfields, jni_amediaformat_mapping, 1, format);
av_freep(&format);
@@ -797,7 +797,7 @@ static int mediaformat_jni_delete(FFAMediaFormat* ctx)
(*env)->DeleteGlobalRef(env, format->object);
format->object = NULL;
- ff_jni_reset_jfields(env, &format->jfields, jni_amediaformat_mapping, 1, format);
+ avpriv_jni_reset_jfields(env, &format->jfields, jni_amediaformat_mapping, 1, format);
av_freep(&format);
@@ -816,11 +816,11 @@ static char* mediaformat_jni_toString(FFAMediaFormat* ctx)
JNI_GET_ENV_OR_RETURN(env, format, NULL);
description = (*env)->CallObjectMethod(env, format->object, format->jfields.to_string_id);
- if (ff_jni_exception_check(env, 1, NULL) < 0) {
+ if (avpriv_jni_exception_check(env, 1, NULL) < 0) {
goto fail;
}
- ret = ff_jni_jstring_to_utf_chars(env, description, format);
+ ret = avpriv_jni_jstring_to_utf_chars(env, description, format);
fail:
if (description) {
(*env)->DeleteLocalRef(env, description);
@@ -841,20 +841,20 @@ static int mediaformat_jni_getInt32(FFAMediaFormat* ctx, const char *name, int32
JNI_GET_ENV_OR_RETURN(env, format, 0);
- key = ff_jni_utf_chars_to_jstring(env, name, format);
+ key = avpriv_jni_utf_chars_to_jstring(env, name, format);
if (!key) {
ret = 0;
goto fail;
}
contains_key = (*env)->CallBooleanMethod(env, format->object, format->jfields.contains_key_id, key);
- if (!contains_key || (ret = ff_jni_exception_check(env, 1, format)) < 0) {
+ if (!contains_key || (ret = avpriv_jni_exception_check(env, 1, format)) < 0) {
ret = 0;
goto fail;
}
*out = (*env)->CallIntMethod(env, format->object, format->jfields.get_integer_id, key);
- if ((ret = ff_jni_exception_check(env, 1, format)) < 0) {
+ if ((ret = avpriv_jni_exception_check(env, 1, format)) < 0) {
ret = 0;
goto fail;
}
@@ -880,20 +880,20 @@ static int mediaformat_jni_getInt64(FFAMediaFormat* ctx, const char *name, int64
JNI_GET_ENV_OR_RETURN(env, format, 0);
- key = ff_jni_utf_chars_to_jstring(env, name, format);
+ key = avpriv_jni_utf_chars_to_jstring(env, name, format);
if (!key) {
ret = 0;
goto fail;
}
contains_key = (*env)->CallBooleanMethod(env, format->object, format->jfields.contains_key_id, key);
- if (!contains_key || (ret = ff_jni_exception_check(env, 1, format)) < 0) {
+ if (!contains_key || (ret = avpriv_jni_exception_check(env, 1, format)) < 0) {
ret = 0;
goto fail;
}
*out = (*env)->CallLongMethod(env, format->object, format->jfields.get_long_id, key);
- if ((ret = ff_jni_exception_check(env, 1, format)) < 0) {
+ if ((ret = avpriv_jni_exception_check(env, 1, format)) < 0) {
ret = 0;
goto fail;
}
@@ -919,20 +919,20 @@ static int mediaformat_jni_getFloat(FFAMediaFormat* ctx, const char *name, float
JNI_GET_ENV_OR_RETURN(env, format, 0);
- key = ff_jni_utf_chars_to_jstring(env, name, format);
+ key = avpriv_jni_utf_chars_to_jstring(env, name, format);
if (!key) {
ret = 0;
goto fail;
}
contains_key = (*env)->CallBooleanMethod(env, format->object, format->jfields.contains_key_id, key);
- if (!contains_key || (ret = ff_jni_exception_check(env, 1, format)) < 0) {
+ if (!contains_key || (ret = avpriv_jni_exception_check(env, 1, format)) < 0) {
ret = 0;
goto fail;
}
*out = (*env)->CallFloatMethod(env, format->object, format->jfields.get_float_id, key);
- if ((ret = ff_jni_exception_check(env, 1, format)) < 0) {
+ if ((ret = avpriv_jni_exception_check(env, 1, format)) < 0) {
ret = 0;
goto fail;
}
@@ -959,20 +959,20 @@ static int mediaformat_jni_getBuffer(FFAMediaFormat* ctx, const char *name, void
JNI_GET_ENV_OR_RETURN(env, format, 0);
- key = ff_jni_utf_chars_to_jstring(env, name, format);
+ key = avpriv_jni_utf_chars_to_jstring(env, name, format);
if (!key) {
ret = 0;
goto fail;
}
contains_key = (*env)->CallBooleanMethod(env, format->object, format->jfields.contains_key_id, key);
- if (!contains_key || (ret = ff_jni_exception_check(env, 1, format)) < 0) {
+ if (!contains_key || (ret = avpriv_jni_exception_check(env, 1, format)) < 0) {
ret = 0;
goto fail;
}
result = (*env)->CallObjectMethod(env, format->object, format->jfields.get_bytebuffer_id, key);
- if ((ret = ff_jni_exception_check(env, 1, format)) < 0) {
+ if ((ret = avpriv_jni_exception_check(env, 1, format)) < 0) {
ret = 0;
goto fail;
}
@@ -1017,25 +1017,25 @@ static int mediaformat_jni_getString(FFAMediaFormat* ctx, const char *name, cons
JNI_GET_ENV_OR_RETURN(env, format, 0);
- key = ff_jni_utf_chars_to_jstring(env, name, format);
+ key = avpriv_jni_utf_chars_to_jstring(env, name, format);
if (!key) {
ret = 0;
goto fail;
}
contains_key = (*env)->CallBooleanMethod(env, format->object, format->jfields.contains_key_id, key);
- if (!contains_key || (ret = ff_jni_exception_check(env, 1, format)) < 0) {
+ if (!contains_key || (ret = avpriv_jni_exception_check(env, 1, format)) < 0) {
ret = 0;
goto fail;
}
result = (*env)->CallObjectMethod(env, format->object, format->jfields.get_string_id, key);
- if ((ret = ff_jni_exception_check(env, 1, format)) < 0) {
+ if ((ret = avpriv_jni_exception_check(env, 1, format)) < 0) {
ret = 0;
goto fail;
}
- *out = ff_jni_jstring_to_utf_chars(env, result, format);
+ *out = avpriv_jni_jstring_to_utf_chars(env, result, format);
if (!*out) {
ret = 0;
goto fail;
@@ -1064,13 +1064,13 @@ static void mediaformat_jni_setInt32(FFAMediaFormat* ctx, const char* name, int3
JNI_GET_ENV_OR_RETURN_VOID(env, format);
- key = ff_jni_utf_chars_to_jstring(env, name, format);
+ key = avpriv_jni_utf_chars_to_jstring(env, name, format);
if (!key) {
goto fail;
}
(*env)->CallVoidMethod(env, format->object, format->jfields.set_integer_id, key, value);
- if (ff_jni_exception_check(env, 1, format) < 0) {
+ if (avpriv_jni_exception_check(env, 1, format) < 0) {
goto fail;
}
@@ -1090,13 +1090,13 @@ static void mediaformat_jni_setInt64(FFAMediaFormat* ctx, const char* name, int6
JNI_GET_ENV_OR_RETURN_VOID(env, format);
- key = ff_jni_utf_chars_to_jstring(env, name, format);
+ key = avpriv_jni_utf_chars_to_jstring(env, name, format);
if (!key) {
goto fail;
}
(*env)->CallVoidMethod(env, format->object, format->jfields.set_long_id, key, value);
- if (ff_jni_exception_check(env, 1, format) < 0) {
+ if (avpriv_jni_exception_check(env, 1, format) < 0) {
goto fail;
}
@@ -1116,13 +1116,13 @@ static void mediaformat_jni_setFloat(FFAMediaFormat* ctx, const char* name, floa
JNI_GET_ENV_OR_RETURN_VOID(env, format);
- key = ff_jni_utf_chars_to_jstring(env, name, format);
+ key = avpriv_jni_utf_chars_to_jstring(env, name, format);
if (!key) {
goto fail;
}
(*env)->CallVoidMethod(env, format->object, format->jfields.set_float_id, key, value);
- if (ff_jni_exception_check(env, 1, format) < 0) {
+ if (avpriv_jni_exception_check(env, 1, format) < 0) {
goto fail;
}
@@ -1143,18 +1143,18 @@ static void mediaformat_jni_setString(FFAMediaFormat* ctx, const char* name, con
JNI_GET_ENV_OR_RETURN_VOID(env, format);
- key = ff_jni_utf_chars_to_jstring(env, name, format);
+ key = avpriv_jni_utf_chars_to_jstring(env, name, format);
if (!key) {
goto fail;
}
- string = ff_jni_utf_chars_to_jstring(env, value, format);
+ string = avpriv_jni_utf_chars_to_jstring(env, value, format);
if (!string) {
goto fail;
}
(*env)->CallVoidMethod(env, format->object, format->jfields.set_string_id, key, string);
- if (ff_jni_exception_check(env, 1, format) < 0) {
+ if (avpriv_jni_exception_check(env, 1, format) < 0) {
goto fail;
}
@@ -1180,7 +1180,7 @@ static void mediaformat_jni_setBuffer(FFAMediaFormat* ctx, const char* name, voi
JNI_GET_ENV_OR_RETURN_VOID(env, format);
- key = ff_jni_utf_chars_to_jstring(env, name, format);
+ key = avpriv_jni_utf_chars_to_jstring(env, name, format);
if (!key) {
goto fail;
}
@@ -1202,7 +1202,7 @@ static void mediaformat_jni_setBuffer(FFAMediaFormat* ctx, const char* name, voi
}
(*env)->CallVoidMethod(env, format->object, format->jfields.set_bytebuffer_id, key, buffer);
- if (ff_jni_exception_check(env, 1, format) < 0) {
+ if (avpriv_jni_exception_check(env, 1, format) < 0) {
goto fail;
}
@@ -1224,44 +1224,44 @@ static int codec_init_static_fields(FFAMediaCodecJni *codec)
JNI_GET_ENV_OR_RETURN(env, codec, AVERROR_EXTERNAL);
codec->INFO_TRY_AGAIN_LATER = (*env)->GetStaticIntField(env, codec->jfields.mediacodec_class, codec->jfields.info_try_again_later_id);
- if ((ret = ff_jni_exception_check(env, 1, codec)) < 0) {
+ if ((ret = avpriv_jni_exception_check(env, 1, codec)) < 0) {
goto fail;
}
codec->BUFFER_FLAG_CODEC_CONFIG = (*env)->GetStaticIntField(env, codec->jfields.mediacodec_class, codec->jfields.buffer_flag_codec_config_id);
- if ((ret = ff_jni_exception_check(env, 1, codec)) < 0) {
+ if ((ret = avpriv_jni_exception_check(env, 1, codec)) < 0) {
goto fail;
}
codec->BUFFER_FLAG_END_OF_STREAM = (*env)->GetStaticIntField(env, codec->jfields.mediacodec_class, codec->jfields.buffer_flag_end_of_stream_id);
- if ((ret = ff_jni_exception_check(env, 1, codec)) < 0) {
+ if ((ret = avpriv_jni_exception_check(env, 1, codec)) < 0) {
goto fail;
}
if (codec->jfields.buffer_flag_key_frame_id) {
codec->BUFFER_FLAG_KEY_FRAME = (*env)->GetStaticIntField(env, codec->jfields.mediacodec_class, codec->jfields.buffer_flag_key_frame_id);
- if ((ret = ff_jni_exception_check(env, 1, codec)) < 0) {
+ if ((ret = avpriv_jni_exception_check(env, 1, codec)) < 0) {
goto fail;
}
}
codec->CONFIGURE_FLAG_ENCODE = (*env)->GetStaticIntField(env, codec->jfields.mediacodec_class, codec->jfields.configure_flag_encode_id);
- if ((ret = ff_jni_exception_check(env, 1, codec)) < 0) {
+ if ((ret = avpriv_jni_exception_check(env, 1, codec)) < 0) {
goto fail;
}
codec->INFO_TRY_AGAIN_LATER = (*env)->GetStaticIntField(env, codec->jfields.mediacodec_class, codec->jfields.info_try_again_later_id);
- if ((ret = ff_jni_exception_check(env, 1, codec)) < 0) {
+ if ((ret = avpriv_jni_exception_check(env, 1, codec)) < 0) {
goto fail;
}
codec->INFO_OUTPUT_BUFFERS_CHANGED = (*env)->GetStaticIntField(env, codec->jfields.mediacodec_class, codec->jfields.info_output_buffers_changed_id);
- if ((ret = ff_jni_exception_check(env, 1, codec)) < 0) {
+ if ((ret = avpriv_jni_exception_check(env, 1, codec)) < 0) {
goto fail;
}
codec->INFO_OUTPUT_FORMAT_CHANGED = (*env)->GetStaticIntField(env, codec->jfields.mediacodec_class, codec->jfields.info_output_format_changed_id);
- if ((ret = ff_jni_exception_check(env, 1, codec)) < 0) {
+ if ((ret = avpriv_jni_exception_check(env, 1, codec)) < 0) {
goto fail;
}
@@ -1290,17 +1290,17 @@ static inline FFAMediaCodec *codec_create(int method, const char *arg)
}
codec->api = media_codec_jni;
- env = ff_jni_get_env(codec);
+ env = avpriv_jni_get_env(codec);
if (!env) {
av_freep(&codec);
return NULL;
}
- if (ff_jni_init_jfields(env, &codec->jfields, jni_amediacodec_mapping, 1, codec) < 0) {
+ if (avpriv_jni_init_jfields(env, &codec->jfields, jni_amediacodec_mapping, 1, codec) < 0) {
goto fail;
}
- jarg = ff_jni_utf_chars_to_jstring(env, arg, codec);
+ jarg = avpriv_jni_utf_chars_to_jstring(env, arg, codec);
if (!jarg) {
goto fail;
}
@@ -1317,7 +1317,7 @@ static inline FFAMediaCodec *codec_create(int method, const char *arg)
codec->jfields.mediacodec_class,
create_id,
jarg);
- if (ff_jni_exception_check(env, 1, codec) < 0) {
+ if (avpriv_jni_exception_check(env, 1, codec) < 0) {
goto fail;
}
@@ -1335,7 +1335,7 @@ static inline FFAMediaCodec *codec_create(int method, const char *arg)
}
buffer_info = (*env)->NewObject(env, codec->jfields.mediainfo_class, codec->jfields.init_id);
- if (ff_jni_exception_check(env, 1, codec) < 0) {
+ if (avpriv_jni_exception_check(env, 1, codec) < 0) {
goto fail;
}
@@ -1367,7 +1367,7 @@ fail:
(*env)->DeleteGlobalRef(env, codec->buffer_info);
}
- ff_jni_reset_jfields(env, &codec->jfields, jni_amediacodec_mapping, 1, codec);
+ avpriv_jni_reset_jfields(env, &codec->jfields, jni_amediacodec_mapping, 1, codec);
av_freep(&codec);
}
@@ -1397,7 +1397,7 @@ static int mediacodec_jni_delete(FFAMediaCodec* ctx)
JNI_GET_ENV_OR_RETURN(env, codec, AVERROR_EXTERNAL);
(*env)->CallVoidMethod(env, codec->object, codec->jfields.release_id);
- if (ff_jni_exception_check(env, 1, codec) < 0) {
+ if (avpriv_jni_exception_check(env, 1, codec) < 0) {
ret = AVERROR_EXTERNAL;
}
@@ -1413,7 +1413,7 @@ static int mediacodec_jni_delete(FFAMediaCodec* ctx)
(*env)->DeleteGlobalRef(env, codec->buffer_info);
codec->buffer_info = NULL;
- ff_jni_reset_jfields(env, &codec->jfields, jni_amediacodec_mapping, 1, codec);
+ avpriv_jni_reset_jfields(env, &codec->jfields, jni_amediacodec_mapping, 1, codec);
av_freep(&codec);
@@ -1430,11 +1430,11 @@ static char *mediacodec_jni_getName(FFAMediaCodec *ctx)
JNI_GET_ENV_OR_RETURN(env, codec, NULL);
name = (*env)->CallObjectMethod(env, codec->object, codec->jfields.get_name_id);
- if (ff_jni_exception_check(env, 1, codec) < 0) {
+ if (avpriv_jni_exception_check(env, 1, codec) < 0) {
goto fail;
}
- ret = ff_jni_jstring_to_utf_chars(env, name, codec);
+ ret = avpriv_jni_jstring_to_utf_chars(env, name, codec);
fail:
if (name) {
@@ -1465,20 +1465,20 @@ static int mediacodec_jni_configure(FFAMediaCodec *ctx,
}
(*env)->CallVoidMethod(env, codec->object, codec->jfields.configure_id, format->object, NULL, NULL, flags);
- if (ff_jni_exception_check(env, 1, codec) < 0)
+ if (avpriv_jni_exception_check(env, 1, codec) < 0)
return AVERROR_EXTERNAL;
if (!surface)
return 0;
(*env)->CallVoidMethod(env, codec->object, codec->jfields.set_input_surface_id, surface);
- if (ff_jni_exception_check(env, 1, codec) < 0)
+ if (avpriv_jni_exception_check(env, 1, codec) < 0)
return AVERROR_EXTERNAL;
return 0;
} else {
(*env)->CallVoidMethod(env, codec->object, codec->jfields.configure_id, format->object, surface, NULL, flags);
}
- if (ff_jni_exception_check(env, 1, codec) < 0) {
+ if (avpriv_jni_exception_check(env, 1, codec) < 0) {
ret = AVERROR_EXTERNAL;
goto fail;
}
@@ -1496,7 +1496,7 @@ static int mediacodec_jni_start(FFAMediaCodec* ctx)
JNI_GET_ENV_OR_RETURN(env, codec, AVERROR_EXTERNAL);
(*env)->CallVoidMethod(env, codec->object, codec->jfields.start_id);
- if (ff_jni_exception_check(env, 1, codec) < 0) {
+ if (avpriv_jni_exception_check(env, 1, codec) < 0) {
ret = AVERROR_EXTERNAL;
goto fail;
}
@@ -1514,7 +1514,7 @@ static int mediacodec_jni_stop(FFAMediaCodec* ctx)
JNI_GET_ENV_OR_RETURN(env, codec, AVERROR_EXTERNAL);
(*env)->CallVoidMethod(env, codec->object, codec->jfields.stop_id);
- if (ff_jni_exception_check(env, 1, codec) < 0) {
+ if (avpriv_jni_exception_check(env, 1, codec) < 0) {
ret = AVERROR_EXTERNAL;
goto fail;
}
@@ -1532,7 +1532,7 @@ static int mediacodec_jni_flush(FFAMediaCodec* ctx)
JNI_GET_ENV_OR_RETURN(env, codec, AVERROR_EXTERNAL);
(*env)->CallVoidMethod(env, codec->object, codec->jfields.flush_id);
- if (ff_jni_exception_check(env, 1, codec) < 0) {
+ if (avpriv_jni_exception_check(env, 1, codec) < 0) {
ret = AVERROR_EXTERNAL;
goto fail;
}
@@ -1550,7 +1550,7 @@ static int mediacodec_jni_releaseOutputBuffer(FFAMediaCodec* ctx, size_t idx, in
JNI_GET_ENV_OR_RETURN(env, codec, AVERROR_EXTERNAL);
(*env)->CallVoidMethod(env, codec->object, codec->jfields.release_output_buffer_id, (jint)idx, (jboolean)render);
- if (ff_jni_exception_check(env, 1, codec) < 0) {
+ if (avpriv_jni_exception_check(env, 1, codec) < 0) {
ret = AVERROR_EXTERNAL;
goto fail;
}
@@ -1568,7 +1568,7 @@ static int mediacodec_jni_releaseOutputBufferAtTime(FFAMediaCodec *ctx, size_t i
JNI_GET_ENV_OR_RETURN(env, codec, AVERROR_EXTERNAL);
(*env)->CallVoidMethod(env, codec->object, codec->jfields.release_output_buffer_at_time_id, (jint)idx, (jlong)timestampNs);
- if (ff_jni_exception_check(env, 1, codec) < 0) {
+ if (avpriv_jni_exception_check(env, 1, codec) < 0) {
ret = AVERROR_EXTERNAL;
goto fail;
}
@@ -1586,7 +1586,7 @@ static ssize_t mediacodec_jni_dequeueInputBuffer(FFAMediaCodec* ctx, int64_t tim
JNI_GET_ENV_OR_RETURN(env, codec, AVERROR_EXTERNAL);
ret = (*env)->CallIntMethod(env, codec->object, codec->jfields.dequeue_input_buffer_id, timeoutUs);
- if (ff_jni_exception_check(env, 1, codec) < 0) {
+ if (avpriv_jni_exception_check(env, 1, codec) < 0) {
ret = AVERROR_EXTERNAL;
goto fail;
}
@@ -1604,7 +1604,7 @@ static int mediacodec_jni_queueInputBuffer(FFAMediaCodec* ctx, size_t idx, off_t
JNI_GET_ENV_OR_RETURN(env, codec, AVERROR_EXTERNAL);
(*env)->CallVoidMethod(env, codec->object, codec->jfields.queue_input_buffer_id, (jint)idx, (jint)offset, (jint)size, time, flags);
- if ((ret = ff_jni_exception_check(env, 1, codec)) < 0) {
+ if ((ret = avpriv_jni_exception_check(env, 1, codec)) < 0) {
ret = AVERROR_EXTERNAL;
goto fail;
}
@@ -1622,27 +1622,27 @@ static ssize_t mediacodec_jni_dequeueOutputBuffer(FFAMediaCodec* ctx, FFAMediaCo
JNI_GET_ENV_OR_RETURN(env, codec, AVERROR_EXTERNAL);
ret = (*env)->CallIntMethod(env, codec->object, codec->jfields.dequeue_output_buffer_id, codec->buffer_info, timeoutUs);
- if (ff_jni_exception_check(env, 1, codec) < 0) {
+ if (avpriv_jni_exception_check(env, 1, codec) < 0) {
return AVERROR_EXTERNAL;
}
info->flags = (*env)->GetIntField(env, codec->buffer_info, codec->jfields.flags_id);
- if (ff_jni_exception_check(env, 1, codec) < 0) {
+ if (avpriv_jni_exception_check(env, 1, codec) < 0) {
return AVERROR_EXTERNAL;
}
info->offset = (*env)->GetIntField(env, codec->buffer_info, codec->jfields.offset_id);
- if (ff_jni_exception_check(env, 1, codec) < 0) {
+ if (avpriv_jni_exception_check(env, 1, codec) < 0) {
return AVERROR_EXTERNAL;
}
info->presentationTimeUs = (*env)->GetLongField(env, codec->buffer_info, codec->jfields.presentation_time_us_id);
- if (ff_jni_exception_check(env, 1, codec) < 0) {
+ if (avpriv_jni_exception_check(env, 1, codec) < 0) {
return AVERROR_EXTERNAL;
}
info->size = (*env)->GetIntField(env, codec->buffer_info, codec->jfields.size_id);
- if (ff_jni_exception_check(env, 1, codec) < 0) {
+ if (avpriv_jni_exception_check(env, 1, codec) < 0) {
return AVERROR_EXTERNAL;
}
@@ -1661,24 +1661,24 @@ static uint8_t* mediacodec_jni_getInputBuffer(FFAMediaCodec* ctx, size_t idx, si
if (codec->has_get_i_o_buffer) {
buffer = (*env)->CallObjectMethod(env, codec->object, codec->jfields.get_input_buffer_id, (jint)idx);
- if (ff_jni_exception_check(env, 1, codec) < 0) {
+ if (avpriv_jni_exception_check(env, 1, codec) < 0) {
goto fail;
}
} else {
if (!codec->input_buffers) {
input_buffers = (*env)->CallObjectMethod(env, codec->object, codec->jfields.get_input_buffers_id);
- if (ff_jni_exception_check(env, 1, codec) < 0) {
+ if (avpriv_jni_exception_check(env, 1, codec) < 0) {
goto fail;
}
codec->input_buffers = (*env)->NewGlobalRef(env, input_buffers);
- if (ff_jni_exception_check(env, 1, codec) < 0) {
+ if (avpriv_jni_exception_check(env, 1, codec) < 0) {
goto fail;
}
}
buffer = (*env)->GetObjectArrayElement(env, codec->input_buffers, idx);
- if (ff_jni_exception_check(env, 1, codec) < 0) {
+ if (avpriv_jni_exception_check(env, 1, codec) < 0) {
goto fail;
}
}
@@ -1709,24 +1709,24 @@ static uint8_t* mediacodec_jni_getOutputBuffer(FFAMediaCodec* ctx, size_t idx, s
if (codec->has_get_i_o_buffer) {
buffer = (*env)->CallObjectMethod(env, codec->object, codec->jfields.get_output_buffer_id, (jint)idx);
- if (ff_jni_exception_check(env, 1, codec) < 0) {
+ if (avpriv_jni_exception_check(env, 1, codec) < 0) {
goto fail;
}
} else {
if (!codec->output_buffers) {
output_buffers = (*env)->CallObjectMethod(env, codec->object, codec->jfields.get_output_buffers_id);
- if (ff_jni_exception_check(env, 1, codec) < 0) {
+ if (avpriv_jni_exception_check(env, 1, codec) < 0) {
goto fail;
}
codec->output_buffers = (*env)->NewGlobalRef(env, output_buffers);
- if (ff_jni_exception_check(env, 1, codec) < 0) {
+ if (avpriv_jni_exception_check(env, 1, codec) < 0) {
goto fail;
}
}
buffer = (*env)->GetObjectArrayElement(env, codec->output_buffers, idx);
- if (ff_jni_exception_check(env, 1, codec) < 0) {
+ if (avpriv_jni_exception_check(env, 1, codec) < 0) {
goto fail;
}
}
@@ -1756,7 +1756,7 @@ static FFAMediaFormat* mediacodec_jni_getOutputFormat(FFAMediaCodec* ctx)
JNI_GET_ENV_OR_RETURN(env, codec, NULL);
mediaformat = (*env)->CallObjectMethod(env, codec->object, codec->jfields.get_output_format_id);
- if (ff_jni_exception_check(env, 1, codec) < 0) {
+ if (avpriv_jni_exception_check(env, 1, codec) < 0) {
goto fail;
}
@@ -1820,7 +1820,7 @@ static int mediacodec_jni_cleanOutputBuffers(FFAMediaCodec *ctx)
if (codec->output_buffers) {
JNIEnv *env = NULL;
- env = ff_jni_get_env(codec);
+ env = avpriv_jni_get_env(codec);
if (!env) {
ret = AVERROR_EXTERNAL;
goto fail;
@@ -1843,7 +1843,7 @@ static int mediacodec_jni_signalEndOfInputStream(FFAMediaCodec *ctx)
JNI_GET_ENV_OR_RETURN(env, codec, AVERROR_EXTERNAL);
(*env)->CallVoidMethod(env, codec->object, codec->jfields.signal_end_of_input_stream_id);
- if (ff_jni_exception_check(env, 1, codec) < 0) {
+ if (avpriv_jni_exception_check(env, 1, codec) < 0) {
return AVERROR_EXTERNAL;
}
diff --git a/libavcodec/mediacodecdec.c b/libavcodec/mediacodecdec.c
index b8587289a2..128a5bfef1 100644
--- a/libavcodec/mediacodecdec.c
+++ b/libavcodec/mediacodecdec.c
@@ -29,6 +29,7 @@
#include "libavutil/common.h"
#include "libavutil/opt.h"
#include "libavutil/intreadwrite.h"
+#include "libavutil/jni.h"
#include "libavutil/pixfmt.h"
#include "libavutil/internal.h"
@@ -314,7 +315,7 @@ static av_cold int mediacodec_decode_init(AVCodecContext *avctx)
MediaCodecH264DecContext *s = avctx->priv_data;
if (s->use_ndk_codec < 0)
- s->use_ndk_codec = !av_jni_get_java_vm(avctx);
+ s->use_ndk_codec = !av_jni_get_jvm(avctx);
format = ff_AMediaFormat_new(s->use_ndk_codec);
if (!format) {
diff --git a/libavutil/Makefile b/libavutil/Makefile
index e7709b97d0..e28944b1b6 100644
--- a/libavutil/Makefile
+++ b/libavutil/Makefile
@@ -56,6 +56,7 @@ HEADERS = adler32.h \
imgutils.h \
intfloat.h \
intreadwrite.h \
+ jni.h \
lfg.h \
log.h \
lzo.h \
@@ -146,6 +147,7 @@ OBJS = adler32.o \
imgutils.o \
integer.o \
intmath.o \
+ jni.o \
lfg.o \
lls.o \
log.o \
@@ -195,6 +197,7 @@ OBJS-$(CONFIG_CUDA) += hwcontext_cuda.o
OBJS-$(CONFIG_D3D11VA) += hwcontext_d3d11va.o
OBJS-$(CONFIG_D3D12VA) += hwcontext_d3d12va.o
OBJS-$(CONFIG_DXVA2) += hwcontext_dxva2.o
+OBJS-$(CONFIG_JNI) += jniutils.o
OBJS-$(CONFIG_LIBDRM) += hwcontext_drm.o
OBJS-$(CONFIG_MACOS_KPERF) += macos_kperf.o
OBJS-$(CONFIG_MEDIACODEC) += hwcontext_mediacodec.o
@@ -219,6 +222,7 @@ SKIPHEADERS-$(CONFIG_CUDA) += hwcontext_cuda_internal.h \
SKIPHEADERS-$(CONFIG_D3D11VA) += hwcontext_d3d11va.h
SKIPHEADERS-$(CONFIG_D3D12VA) += hwcontext_d3d12va.h
SKIPHEADERS-$(CONFIG_DXVA2) += hwcontext_dxva2.h
+SKIPHEADERS-$(CONFIG_JNI) += jniutils.h
SKIPHEADERS-$(CONFIG_QSV) += hwcontext_qsv.h
SKIPHEADERS-$(CONFIG_OPENCL) += hwcontext_opencl.h
SKIPHEADERS-$(CONFIG_VAAPI) += hwcontext_vaapi.h
diff --git a/libavutil/jni.c b/libavutil/jni.c
new file mode 100644
index 0000000000..541747cb20
--- /dev/null
+++ b/libavutil/jni.c
@@ -0,0 +1,78 @@
+/*
+ * JNI public API functions
+ *
+ * Copyright (c) 2015-2016 Matthieu Bouron <matthieu.bouron stupeflix.com>
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+
+#include <stdlib.h>
+
+#include "libavutil/error.h"
+
+#if CONFIG_JNI
+#include <jni.h>
+#include <pthread.h>
+
+#include "libavutil/log.h"
+#include "libavutil/jni.h"
+
+static void *java_vm;
+static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
+
+int av_jni_set_jvm(void *vm, void *log_ctx)
+{
+ int ret = 0;
+
+ pthread_mutex_lock(&lock);
+ if (java_vm == NULL) {
+ java_vm = vm;
+ } else if (java_vm != vm) {
+ ret = AVERROR(EINVAL);
+ av_log(log_ctx, AV_LOG_ERROR, "A Java virtual machine has already been set");
+ }
+ pthread_mutex_unlock(&lock);
+
+ return ret;
+}
+
+void *av_jni_get_jvm(void *log_ctx)
+{
+ void *vm;
+
+ pthread_mutex_lock(&lock);
+ vm = java_vm;
+ pthread_mutex_unlock(&lock);
+
+ return vm;
+}
+
+#else
+
+int av_jni_set_java_vm(void *vm, void *log_ctx)
+{
+ return AVERROR(ENOSYS);
+}
+
+void *av_jni_get_java_vm(void *log_ctx)
+{
+ return NULL;
+}
+
+#endif
diff --git a/libavutil/jni.h b/libavutil/jni.h
new file mode 100644
index 0000000000..700960dbb8
--- /dev/null
+++ b/libavutil/jni.h
@@ -0,0 +1,46 @@
+/*
+ * JNI public API functions
+ *
+ * Copyright (c) 2015-2016 Matthieu Bouron <matthieu.bouron stupeflix.com>
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVUTIL_JNI_H
+#define AVUTIL_JNI_H
+
+/*
+ * Manually set a Java virtual machine which will be used to retrieve the JNI
+ * environment. Once a Java VM is set it cannot be changed afterwards, meaning
+ * you can call multiple times av_jni_set_java_vm with the same Java VM pointer
+ * however it will error out if you try to set a different Java VM.
+ *
+ * @param vm Java virtual machine
+ * @param log_ctx context used for logging, can be NULL
+ * @return 0 on success, < 0 otherwise
+ */
+int av_jni_set_jvm(void *vm, void *log_ctx);
+
+/*
+ * Get the Java virtual machine which has been set with av_jni_set_java_vm.
+ *
+ * @param vm Java virtual machine
+ * @return a pointer to the Java virtual machine
+ */
+void *av_jni_get_jvm(void *log_ctx);
+
+#endif /* AVUTIL_JNI_H */
diff --git a/libavcodec/ffjni.c b/libavutil/jniutils.c
similarity index 88%
rename from libavcodec/ffjni.c
rename to libavutil/jniutils.c
index e3cf24d3e2..89623af3f8 100644
--- a/libavcodec/ffjni.c
+++ b/libavutil/jniutils.c
@@ -31,7 +31,7 @@
#include "config.h"
#include "jni.h"
-#include "ffjni.h"
+#include "jniutils.h"
static JavaVM *java_vm;
static pthread_key_t current_env;
@@ -50,14 +50,14 @@ static void jni_create_pthread_key(void)
pthread_key_create(¤t_env, jni_detach_env);
}
-JNIEnv *ff_jni_get_env(void *log_ctx)
+JNIEnv *avpriv_jni_get_env(void *log_ctx)
{
int ret = 0;
JNIEnv *env = NULL;
pthread_mutex_lock(&lock);
if (java_vm == NULL) {
- java_vm = av_jni_get_java_vm(log_ctx);
+ java_vm = av_jni_get_jvm(log_ctx);
}
if (!java_vm) {
@@ -96,7 +96,7 @@ done:
return env;
}
-char *ff_jni_jstring_to_utf_chars(JNIEnv *env, jstring string, void *log_ctx)
+char *avpriv_jni_jstring_to_utf_chars(JNIEnv *env, jstring string, void *log_ctx)
{
char *ret = NULL;
const char *utf_chars = NULL;
@@ -126,7 +126,7 @@ char *ff_jni_jstring_to_utf_chars(JNIEnv *env, jstring string, void *log_ctx)
return ret;
}
-jstring ff_jni_utf_chars_to_jstring(JNIEnv *env, const char *utf_chars, void *log_ctx)
+jstring avpriv_jni_utf_chars_to_jstring(JNIEnv *env, const char *utf_chars, void *log_ctx)
{
jstring ret;
@@ -140,7 +140,7 @@ jstring ff_jni_utf_chars_to_jstring(JNIEnv *env, const char *utf_chars, void *lo
return ret;
}
-int ff_jni_exception_get_summary(JNIEnv *env, jthrowable exception, char **error, void *log_ctx)
+int avpriv_jni_exception_get_summary(JNIEnv *env, jthrowable exception, char **error, void *log_ctx)
{
int ret = 0;
@@ -192,7 +192,7 @@ int ff_jni_exception_get_summary(JNIEnv *env, jthrowable exception, char **error
}
if (string) {
- name = ff_jni_jstring_to_utf_chars(env, string, log_ctx);
+ name = avpriv_jni_jstring_to_utf_chars(env, string, log_ctx);
(*env)->DeleteLocalRef(env, string);
string = NULL;
}
@@ -214,7 +214,7 @@ int ff_jni_exception_get_summary(JNIEnv *env, jthrowable exception, char **error
}
if (string) {
- message = ff_jni_jstring_to_utf_chars(env, string, log_ctx);
+ message = avpriv_jni_jstring_to_utf_chars(env, string, log_ctx);
(*env)->DeleteLocalRef(env, string);
string = NULL;
}
@@ -251,7 +251,7 @@ done:
return ret;
}
-int ff_jni_exception_check(JNIEnv *env, int log, void *log_ctx)
+int avpriv_jni_exception_check(JNIEnv *env, int log, void *log_ctx)
{
int ret;
@@ -271,7 +271,7 @@ int ff_jni_exception_check(JNIEnv *env, int log, void *log_ctx)
exception = (*env)->ExceptionOccurred(env);
(*(env))->ExceptionClear((env));
- if ((ret = ff_jni_exception_get_summary(env, exception, &message, log_ctx)) < 0) {
+ if ((ret = avpriv_jni_exception_get_summary(env, exception, &message, log_ctx)) < 0) {
(*env)->DeleteLocalRef(env, exception);
return ret;
}
@@ -284,7 +284,7 @@ int ff_jni_exception_check(JNIEnv *env, int log, void *log_ctx)
return -1;
}
-int ff_jni_init_jfields(JNIEnv *env, void *jfields, const struct FFJniField *jfields_mapping, int global, void *log_ctx)
+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;
@@ -299,7 +299,7 @@ int ff_jni_init_jfields(JNIEnv *env, void *jfields, const struct FFJniField *jfi
last_clazz = NULL;
clazz = (*env)->FindClass(env, jfields_mapping[i].name);
- if ((ret = ff_jni_exception_check(env, mandatory, log_ctx)) < 0 && mandatory) {
+ if ((ret = avpriv_jni_exception_check(env, mandatory, log_ctx)) < 0 && mandatory) {
goto done;
}
@@ -320,7 +320,7 @@ int ff_jni_init_jfields(JNIEnv *env, void *jfields, const struct FFJniField *jfi
switch(type) {
case FF_JNI_FIELD: {
jfieldID field_id = (*env)->GetFieldID(env, last_clazz, jfields_mapping[i].method, jfields_mapping[i].signature);
- if ((ret = ff_jni_exception_check(env, mandatory, log_ctx)) < 0 && mandatory) {
+ if ((ret = avpriv_jni_exception_check(env, mandatory, log_ctx)) < 0 && mandatory) {
goto done;
}
@@ -329,7 +329,7 @@ int ff_jni_init_jfields(JNIEnv *env, void *jfields, const struct FFJniField *jfi
}
case FF_JNI_STATIC_FIELD: {
jfieldID field_id = (*env)->GetStaticFieldID(env, last_clazz, jfields_mapping[i].method, jfields_mapping[i].signature);
- if ((ret = ff_jni_exception_check(env, mandatory, log_ctx)) < 0 && mandatory) {
+ if ((ret = avpriv_jni_exception_check(env, mandatory, log_ctx)) < 0 && mandatory) {
goto done;
}
@@ -338,7 +338,7 @@ int ff_jni_init_jfields(JNIEnv *env, void *jfields, const struct FFJniField *jfi
}
case FF_JNI_METHOD: {
jmethodID method_id = (*env)->GetMethodID(env, last_clazz, jfields_mapping[i].method, jfields_mapping[i].signature);
- if ((ret = ff_jni_exception_check(env, mandatory, log_ctx)) < 0 && mandatory) {
+ if ((ret = avpriv_jni_exception_check(env, mandatory, log_ctx)) < 0 && mandatory) {
goto done;
}
@@ -347,7 +347,7 @@ int ff_jni_init_jfields(JNIEnv *env, void *jfields, const struct FFJniField *jfi
}
case FF_JNI_STATIC_METHOD: {
jmethodID method_id = (*env)->GetStaticMethodID(env, last_clazz, jfields_mapping[i].method, jfields_mapping[i].signature);
- if ((ret = ff_jni_exception_check(env, mandatory, log_ctx)) < 0 && mandatory) {
+ if ((ret = avpriv_jni_exception_check(env, mandatory, log_ctx)) < 0 && mandatory) {
goto done;
}
@@ -367,13 +367,13 @@ int ff_jni_init_jfields(JNIEnv *env, void *jfields, const struct FFJniField *jfi
done:
if (ret < 0) {
/* reset jfields in case of failure so it does not leak references */
- ff_jni_reset_jfields(env, jfields, jfields_mapping, global, log_ctx);
+ avpriv_jni_reset_jfields(env, jfields, jfields_mapping, global, log_ctx);
}
return ret;
}
-int ff_jni_reset_jfields(JNIEnv *env, void *jfields, const struct FFJniField *jfields_mapping, int global, void *log_ctx)
+int avpriv_jni_reset_jfields(JNIEnv *env, void *jfields, const struct FFJniField *jfields_mapping, int global, void *log_ctx)
{
int i;
diff --git a/libavcodec/ffjni.h b/libavutil/jniutils.h
similarity index 84%
rename from libavcodec/ffjni.h
rename to libavutil/jniutils.h
index 6027bac0ab..2be401c974 100644
--- a/libavcodec/ffjni.h
+++ b/libavutil/jniutils.h
@@ -20,8 +20,8 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifndef AVCODEC_FFJNI_H
-#define AVCODEC_FFJNI_H
+#ifndef AVUTIL_JNIUTILS_H
+#define AVUTIL_JNIUTILS_H
#include <jni.h>
@@ -37,7 +37,7 @@
* @param log_ctx context used for logging, can be NULL
* @return the JNI environment on success, NULL otherwise
*/
-JNIEnv *ff_jni_get_env(void *log_ctx);
+JNIEnv *avpriv_jni_get_env(void *log_ctx);
/*
* Convert a jstring to its utf characters equivalent.
@@ -48,7 +48,7 @@ JNIEnv *ff_jni_get_env(void *log_ctx);
* @return a pointer to an array of unicode characters on success, NULL
* otherwise
*/
-char *ff_jni_jstring_to_utf_chars(JNIEnv *env, jstring string, void *log_ctx);
+char *avpriv_jni_jstring_to_utf_chars(JNIEnv *env, jstring string, void *log_ctx);
/*
* Convert utf chars to its jstring equivalent.
@@ -58,7 +58,7 @@ char *ff_jni_jstring_to_utf_chars(JNIEnv *env, jstring string, void *log_ctx);
* @param log_ctx context used for logging, can be NULL
* @return a Java string object on success, NULL otherwise
*/
-jstring ff_jni_utf_chars_to_jstring(JNIEnv *env, const char *utf_chars, void *log_ctx);
+jstring avpriv_jni_utf_chars_to_jstring(JNIEnv *env, const char *utf_chars, void *log_ctx);
/*
* Extract the error summary from a jthrowable in the form of "className: errorMessage"
@@ -70,7 +70,7 @@ jstring ff_jni_utf_chars_to_jstring(JNIEnv *env, const char *utf_chars, void *lo
* @param log_ctx context used for logging, can be NULL
* @return 0 on success, < 0 otherwise
*/
-int ff_jni_exception_get_summary(JNIEnv *env, jthrowable exception, char **error, void *log_ctx);
+int avpriv_jni_exception_get_summary(JNIEnv *env, jthrowable exception, char **error, void *log_ctx);
/*
* Check if an exception has occurred,log it using av_log and clear it.
@@ -80,34 +80,30 @@ int ff_jni_exception_get_summary(JNIEnv *env, jthrowable exception, char **error
* 0 disables logging, != 0 enables logging
* @param log_ctx context used for logging, can be NULL
*/
-int ff_jni_exception_check(JNIEnv *env, int log, void *log_ctx);
+int avpriv_jni_exception_check(JNIEnv *env, int log, void *log_ctx);
/*
* Jni field type.
*/
enum FFJniFieldType {
-
FF_JNI_CLASS,
FF_JNI_FIELD,
FF_JNI_STATIC_FIELD,
FF_JNI_METHOD,
FF_JNI_STATIC_METHOD
-
};
/*
* Jni field describing a class, a field or a method to be retrieved using
- * the ff_jni_init_jfields method.
+ * the avpriv_jni_init_jfields method.
*/
struct FFJniField {
-
const char *name;
const char *method;
const char *signature;
enum FFJniFieldType type;
int offset;
int mandatory;
-
};
/*
@@ -124,7 +120,7 @@ struct FFJniField {
* @param log_ctx context used for logging, can be NULL
* @return 0 on success, < 0 otherwise
*/
-int ff_jni_init_jfields(JNIEnv *env, void *jfields, const struct FFJniField *jfields_mapping, int global, void *log_ctx);
+int avpriv_jni_init_jfields(JNIEnv *env, void *jfields, const struct FFJniField *jfields_mapping, int global, void *log_ctx);
/*
* Delete class references, field ids and method ids of an arbitrary structure.
@@ -140,6 +136,6 @@ int ff_jni_init_jfields(JNIEnv *env, void *jfields, const struct FFJniField *jfi
* @param log_ctx context used for logging, can be NULL
* @return 0 on success, < 0 otherwise
*/
-int ff_jni_reset_jfields(JNIEnv *env, void *jfields, const struct FFJniField *jfields_mapping, int global, void *log_ctx);
+int avpriv_jni_reset_jfields(JNIEnv *env, void *jfields, const struct FFJniField *jfields_mapping, int global, void *log_ctx);
-#endif /* AVCODEC_FFJNI_H */
+#endif /* AVCODEC_JNIUTILS_H */
--
2.43.1
More information about the ffmpeg-devel
mailing list