* [FFmpeg-devel] Add protocol for Android content providers
@ 2024-02-13 22:50 Matthieu Bouron
2024-02-13 22:50 ` [FFmpeg-devel] [PATCH 1/7] avcodec: move ffjni to avutil/jniutils Matthieu Bouron
` (8 more replies)
0 siblings, 9 replies; 51+ messages in thread
From: Matthieu Bouron @ 2024-02-13 22:50 UTC (permalink / raw)
To: ffmpeg-devel
Hi,
On Android, content providers are used for accessing files through shared
mechanisms. One typical case would be an app willing to open a video from
Google Photos, gallery apps, TikTok, Instagram or some other providers.
A content URI looks something like "content://authority/path/id", see:
https://developer.android.com/reference/android/content/ContentUris
https://developer.android.com/guide/topics/providers/content-provider-basics
It can currently be somehow managed through clumsy means such as using a "fd:"
filename and crafting a special AVOption, which also has the drawback of
requiring the third party to carry around opened file descriptors (with the
multiple opened file limitations implied). Custom AVIOContexts are also an
option. Both options will have to deal with the JNI though and end users will
have to re-implement the same exact thing.
This patchset addresses this by adding a content provider protocol, which has
an API fairly similar to fopen. Android 11 appears to provide something
transparent within fopen(), but FFmpeg doesn't use it in the file protocol, and
Android < 11 are still widely used.
The first part move the JNI infrastructure from avcodec to avutil (it remains
internally shared, there is little user implication), and then the URLProtocol
is added, along with a few cleanups.
Regards,
--
Matthieu
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 51+ messages in thread
* [FFmpeg-devel] [PATCH 1/7] avcodec: move ffjni to avutil/jniutils
2024-02-13 22:50 [FFmpeg-devel] Add protocol for Android content providers Matthieu Bouron
@ 2024-02-13 22:50 ` Matthieu Bouron
2024-02-14 18:18 ` Michael Niedermayer
2024-02-14 23:31 ` Mark Thompson
2024-02-13 22:50 ` [FFmpeg-devel] [PATCH 2/7] avutil: add av_jni_{get, set}_android_app_ctx helper Matthieu Bouron
` (7 subsequent siblings)
8 siblings, 2 replies; 51+ messages in thread
From: Matthieu Bouron @ 2024-02-13 22:50 UTC (permalink / raw)
To: ffmpeg-devel; +Cc: Matthieu Bouron
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
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 51+ messages in thread
* [FFmpeg-devel] [PATCH 2/7] avutil: add av_jni_{get, set}_android_app_ctx helper
2024-02-13 22:50 [FFmpeg-devel] Add protocol for Android content providers Matthieu Bouron
2024-02-13 22:50 ` [FFmpeg-devel] [PATCH 1/7] avcodec: move ffjni to avutil/jniutils Matthieu Bouron
@ 2024-02-13 22:50 ` Matthieu Bouron
2024-02-27 13:42 ` Andreas Rheinhardt
2024-02-13 22:50 ` [FFmpeg-devel] [PATCH 3/7] avformat: add Android content resolver protocol support Matthieu Bouron
` (6 subsequent siblings)
8 siblings, 1 reply; 51+ messages in thread
From: Matthieu Bouron @ 2024-02-13 22:50 UTC (permalink / raw)
To: ffmpeg-devel; +Cc: Matthieu Bouron
This will allow users to pass the Android ApplicationContext which is mandatory
to retrieve the ContentResolver responsible to resolve/open Android content-uri.
---
libavutil/jni.c | 28 ++++++++++++++++++++++++++++
libavutil/jni.h | 17 +++++++++++++++++
2 files changed, 45 insertions(+)
diff --git a/libavutil/jni.c b/libavutil/jni.c
index 541747cb20..d6f96717b0 100644
--- a/libavutil/jni.c
+++ b/libavutil/jni.c
@@ -34,6 +34,7 @@
#include "libavutil/jni.h"
static void *java_vm;
+static void *android_app_ctx;
static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
int av_jni_set_jvm(void *vm, void *log_ctx)
@@ -63,6 +64,24 @@ void *av_jni_get_jvm(void *log_ctx)
return vm;
}
+void av_jni_set_android_app_ctx(void *app_ctx)
+{
+ pthread_mutex_lock(&lock);
+ android_app_ctx = app_ctx;
+ pthread_mutex_unlock(&lock);
+}
+
+void *av_jni_get_android_app_ctx(void)
+{
+ void *ctx;
+
+ pthread_mutex_lock(&lock);
+ ctx = android_app_ctx;
+ pthread_mutex_unlock(&lock);
+
+ return ctx;
+}
+
#else
int av_jni_set_java_vm(void *vm, void *log_ctx)
@@ -75,4 +94,13 @@ void *av_jni_get_java_vm(void *log_ctx)
return NULL;
}
+void av_jni_set_android_app_ctx(void *app_ctx)
+{
+}
+
+void *av_jni_get_android_app_ctx(void)
+{
+ return NULL;
+}
+
#endif
diff --git a/libavutil/jni.h b/libavutil/jni.h
index 700960dbb8..630f4074a1 100644
--- a/libavutil/jni.h
+++ b/libavutil/jni.h
@@ -43,4 +43,21 @@ int av_jni_set_jvm(void *vm, void *log_ctx);
*/
void *av_jni_get_jvm(void *log_ctx);
+/*
+ * Set the Android application context which will be used to retrieve the Android
+ * content resolver to resolve content uris.
+ *
+ * @param app_ctx global JNI reference to the Android application context
+ */
+void av_jni_set_android_app_ctx(void *app_ctx);
+
+/*
+ * Get the Android application context that has been set with
+ * av_jni_set_android_app_ctx.
+ *
+ * @return a pointer the the Android application context
+ */
+void *av_jni_get_android_app_ctx(void);
+
+
#endif /* AVUTIL_JNI_H */
--
2.43.1
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 51+ messages in thread
* [FFmpeg-devel] [PATCH 3/7] avformat: add Android content resolver protocol support
2024-02-13 22:50 [FFmpeg-devel] Add protocol for Android content providers Matthieu Bouron
2024-02-13 22:50 ` [FFmpeg-devel] [PATCH 1/7] avcodec: move ffjni to avutil/jniutils Matthieu Bouron
2024-02-13 22:50 ` [FFmpeg-devel] [PATCH 2/7] avutil: add av_jni_{get, set}_android_app_ctx helper Matthieu Bouron
@ 2024-02-13 22:50 ` Matthieu Bouron
2024-02-13 22:50 ` [FFmpeg-devel] [PATCH 4/7] avutil/jni: use size_t to store structure offsets Matthieu Bouron
` (5 subsequent siblings)
8 siblings, 0 replies; 51+ messages in thread
From: Matthieu Bouron @ 2024-02-13 22:50 UTC (permalink / raw)
To: ffmpeg-devel; +Cc: Matthieu Bouron
Handles Android content-uri starting with content://.
---
configure | 2 +
doc/APIchanges | 3 +
libavformat/Makefile | 1 +
libavformat/file.c | 157 ++++++++++++++++++++++++++++++++++++++++
libavformat/protocols.c | 1 +
5 files changed, 164 insertions(+)
diff --git a/configure b/configure
index f72533b7d2..a3593dc200 100755
--- a/configure
+++ b/configure
@@ -3651,6 +3651,8 @@ xcbgrab_indev_suggest="libxcb_shm libxcb_shape libxcb_xfixes"
xv_outdev_deps="xlib_xv xlib_x11 xlib_xext"
# protocols
+android_content_protocol_deps="jni"
+android_content_protocol_select="file_protocol"
async_protocol_deps="threads"
bluray_protocol_deps="libbluray"
ffrtmpcrypt_protocol_conflict="librtmp_protocol"
diff --git a/doc/APIchanges b/doc/APIchanges
index 45611ea7ea..7f6631b3d3 100644
--- a/doc/APIchanges
+++ b/doc/APIchanges
@@ -2,6 +2,9 @@ The last version increases of all libraries were on 2023-02-09
API changes, most recent first:
+2024-02-xx - xxxxxxxxxx - lavu 58.40.100 - jni.h
+ Add av_jni_set_android_app_ctx() and av_jni_get_android_app_ctx().
+
2024-02-xx - xxxxxxxxxx - lavu 58.39.100 - jni.h
Add av_jni_set_jvm() and av_jni_get_jvm().
diff --git a/libavformat/Makefile b/libavformat/Makefile
index 05b9b8a115..788d4e4135 100644
--- a/libavformat/Makefile
+++ b/libavformat/Makefile
@@ -655,6 +655,7 @@ OBJS-$(CONFIG_LIBOPENMPT_DEMUXER) += libopenmpt.o
OBJS-$(CONFIG_VAPOURSYNTH_DEMUXER) += vapoursynth.o
# protocols I/O
+OBJS-$(CONFIG_ANDROID_CONTENT_PROTOCOL) += file.o
OBJS-$(CONFIG_ASYNC_PROTOCOL) += async.o
OBJS-$(CONFIG_APPLEHTTP_PROTOCOL) += hlsproto.o
OBJS-$(CONFIG_BLURAY_PROTOCOL) += bluray.o
diff --git a/libavformat/file.c b/libavformat/file.c
index 64df7ff6fb..c7c7a5073f 100644
--- a/libavformat/file.c
+++ b/libavformat/file.c
@@ -40,6 +40,12 @@
#include <stdlib.h>
#include "os_support.h"
#include "url.h"
+#if CONFIG_ANDROID_CONTENT_PROTOCOL
+#include <jni.h>
+#include "libavutil/jni.h"
+#include "libavutil/jniutils.h"
+#endif
+
/* Some systems may not have S_ISFIFO */
#ifndef S_ISFIFO
@@ -101,6 +107,21 @@ typedef struct FileContext {
int64_t initial_pos;
} FileContext;
+
+#if CONFIG_ANDROID_CONTENT_PROTOCOL
+static const AVOption android_content_options[] = {
+ { "blocksize", "set I/O operation maximum block size", offsetof(FileContext, blocksize), AV_OPT_TYPE_INT, { .i64 = INT_MAX }, 1, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM },
+ { NULL }
+};
+
+static const AVClass android_content_class = {
+ .class_name = "android_content",
+ .item_name = av_default_item_name,
+ .option = android_content_options,
+ .version = LIBAVUTIL_VERSION_INT,
+};
+#endif
+
static const AVOption file_options[] = {
{ "truncate", "truncate existing files on write", offsetof(FileContext, trunc), AV_OPT_TYPE_BOOL, { .i64 = 1 }, 0, 1, AV_OPT_FLAG_ENCODING_PARAM },
{ "blocksize", "set I/O operation maximum block size", offsetof(FileContext, blocksize), AV_OPT_TYPE_INT, { .i64 = INT_MAX }, 1, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM },
@@ -524,3 +545,139 @@ const URLProtocol ff_fd_protocol = {
};
#endif /* CONFIG_FD_PROTOCOL */
+
+#if CONFIG_ANDROID_CONTENT_PROTOCOL
+
+struct JFields {
+ jclass uri_class;
+ jmethodID parse_id;
+
+ jclass context_class;
+ jmethodID get_content_resolver_id;
+
+ jclass content_resolver_class;
+ jmethodID open_file_descriptor_id;
+
+ jclass parcel_file_descriptor_class;
+ jmethodID detach_fd_id;
+};
+
+#define OFFSET(x) offsetof(struct JFields, x)
+static const struct FFJniField jfields_mapping[] = {
+ { "android/net/Uri", NULL, NULL, FF_JNI_CLASS, OFFSET(uri_class), 1 },
+ { "android/net/Uri", "parse", "(Ljava/lang/String;)Landroid/net/Uri;", FF_JNI_STATIC_METHOD, OFFSET(parse_id), 1 },
+
+ { "android/content/Context", NULL, NULL, FF_JNI_CLASS, OFFSET(context_class), 1 },
+ { "android/content/Context", "getContentResolver", "()Landroid/content/ContentResolver;", FF_JNI_METHOD, OFFSET(get_content_resolver_id), 1 },
+
+ { "android/content/ContentResolver", NULL, NULL, FF_JNI_CLASS, OFFSET(content_resolver_class), 1 },
+ { "android/content/ContentResolver", "openFileDescriptor", "(Landroid/net/Uri;Ljava/lang/String;)Landroid/os/ParcelFileDescriptor;", FF_JNI_METHOD, OFFSET(open_file_descriptor_id), 1 },
+
+ { "android/os/ParcelFileDescriptor", NULL, NULL, FF_JNI_CLASS, OFFSET(parcel_file_descriptor_class), 1 },
+ { "android/os/ParcelFileDescriptor", "detachFd", "()I", FF_JNI_METHOD, OFFSET(detach_fd_id), 1 },
+
+ { NULL }
+};
+#undef OFFSET
+
+static int android_content_open(URLContext *h, const char *filename, int flags)
+{
+ FileContext *c = h->priv_data;
+ int fd, ret;
+ const char *mode_str = "r";
+
+ JNIEnv *env;
+ struct JFields jfields = { 0 };
+ jobject application_context = NULL;
+ jobject url = NULL;
+ jobject mode = NULL;
+ jobject uri = NULL;
+ jobject content_resolver = NULL;
+ jobject parcel_file_descriptor = NULL;
+
+ env = avpriv_jni_get_env(c);
+ if (!env) {
+ return AVERROR(EINVAL);
+ }
+
+ ret = avpriv_jni_init_jfields(env, &jfields, jfields_mapping, 0, c);
+ if (ret < 0) {
+ av_log(c, AV_LOG_ERROR, "failed to initialize jni fields\n");
+ return ret;
+ }
+
+ application_context = av_jni_get_android_app_ctx();
+ if (!application_context) {
+ av_log(c, AV_LOG_ERROR, "application context is not set\n");
+ ret = AVERROR_EXTERNAL;
+ goto done;
+ }
+
+ url = avpriv_jni_utf_chars_to_jstring(env, filename, c);
+ if (!url) {
+ ret = AVERROR_EXTERNAL;
+ goto done;
+ }
+
+ if (flags & AVIO_FLAG_WRITE && flags & AVIO_FLAG_READ)
+ mode_str = "rw";
+ else if (flags & AVIO_FLAG_WRITE)
+ mode_str = "w";
+
+ mode = avpriv_jni_utf_chars_to_jstring(env, mode_str, c);
+ if (!mode) {
+ ret = AVERROR_EXTERNAL;
+ goto done;
+ }
+
+ uri = (*env)->CallStaticObjectMethod(env, jfields.uri_class, jfields.parse_id, url);
+ ret = avpriv_jni_exception_check(env, 1, c);
+ if (ret < 0)
+ goto done;
+
+ content_resolver = (*env)->CallObjectMethod(env, application_context, jfields.get_content_resolver_id);
+ ret = avpriv_jni_exception_check(env, 1, c);
+ if (ret < 0)
+ goto done;
+
+ parcel_file_descriptor = (*env)->CallObjectMethod(env, content_resolver, jfields.open_file_descriptor_id, uri, mode);
+ ret = avpriv_jni_exception_check(env, 1, c);
+ if (ret < 0)
+ goto done;
+
+ fd = (*env)->CallIntMethod(env, parcel_file_descriptor, jfields.detach_fd_id);
+ ret = avpriv_jni_exception_check(env, 1, c);
+ if (ret < 0)
+ goto done;
+
+#if HAVE_SETMODE
+ setmode(fd, O_BINARY);
+#endif
+ c->fd = fd;
+ h->is_streamed = 0;
+
+done:
+ (*env)->DeleteLocalRef(env, url);
+ (*env)->DeleteLocalRef(env, mode);
+ (*env)->DeleteLocalRef(env, uri);
+ (*env)->DeleteLocalRef(env, content_resolver);
+ (*env)->DeleteLocalRef(env, parcel_file_descriptor);
+ avpriv_jni_reset_jfields(env, &jfields, jfields_mapping, 0, c);
+
+ return ret;
+}
+
+URLProtocol ff_android_content_protocol = {
+ .name = "content",
+ .url_open = android_content_open,
+ .url_read = file_read,
+ .url_write = file_write,
+ .url_seek = file_seek,
+ .url_close = file_close,
+ .url_get_file_handle = file_get_handle,
+ .url_check = NULL,
+ .priv_data_size = sizeof(FileContext),
+ .priv_data_class = &android_content_class,
+};
+
+#endif /* CONFIG_ANDROID_CONTENT_PROTOCOL */
diff --git a/libavformat/protocols.c b/libavformat/protocols.c
index 360018b17c..93a6d67261 100644
--- a/libavformat/protocols.c
+++ b/libavformat/protocols.c
@@ -24,6 +24,7 @@
#include "url.h"
+extern const URLProtocol ff_android_content_protocol;
extern const URLProtocol ff_async_protocol;
extern const URLProtocol ff_bluray_protocol;
extern const URLProtocol ff_cache_protocol;
--
2.43.1
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 51+ messages in thread
* [FFmpeg-devel] [PATCH 4/7] avutil/jni: use size_t to store structure offsets
2024-02-13 22:50 [FFmpeg-devel] Add protocol for Android content providers Matthieu Bouron
` (2 preceding siblings ...)
2024-02-13 22:50 ` [FFmpeg-devel] [PATCH 3/7] avformat: add Android content resolver protocol support Matthieu Bouron
@ 2024-02-13 22:50 ` Matthieu Bouron
2024-02-13 22:50 ` [FFmpeg-devel] [PATCH 5/7] avutil/jni: remove unnecessary NULL checks before calling DeleteLocalRef() Matthieu Bouron
` (4 subsequent siblings)
8 siblings, 0 replies; 51+ messages in thread
From: Matthieu Bouron @ 2024-02-13 22:50 UTC (permalink / raw)
To: ffmpeg-devel; +Cc: Matthieu Bouron
---
libavutil/jniutils.h | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/libavutil/jniutils.h b/libavutil/jniutils.h
index 2be401c974..01f3acb88d 100644
--- a/libavutil/jniutils.h
+++ b/libavutil/jniutils.h
@@ -24,6 +24,7 @@
#define AVUTIL_JNIUTILS_H
#include <jni.h>
+#include <stdlib.h>
/*
* Attach permanently a JNI environment to the current thread and retrieve it.
@@ -102,7 +103,7 @@ struct FFJniField {
const char *method;
const char *signature;
enum FFJniFieldType type;
- int offset;
+ size_t offset;
int mandatory;
};
--
2.43.1
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 51+ messages in thread
* [FFmpeg-devel] [PATCH 5/7] avutil/jni: remove unnecessary NULL checks before calling DeleteLocalRef()
2024-02-13 22:50 [FFmpeg-devel] Add protocol for Android content providers Matthieu Bouron
` (3 preceding siblings ...)
2024-02-13 22:50 ` [FFmpeg-devel] [PATCH 4/7] avutil/jni: use size_t to store structure offsets Matthieu Bouron
@ 2024-02-13 22:50 ` Matthieu Bouron
2024-02-13 22:50 ` [FFmpeg-devel] [PATCH 6/7] avcodec/mediacodec_wrapper: use an OFFSET() macro where relevant Matthieu Bouron
` (3 subsequent siblings)
8 siblings, 0 replies; 51+ messages in thread
From: Matthieu Bouron @ 2024-02-13 22:50 UTC (permalink / raw)
To: ffmpeg-devel; +Cc: Matthieu Bouron
Delete{Global,Local}Ref() already handle NULL.
---
libavutil/jniutils.c | 14 +++-----------
1 file changed, 3 insertions(+), 11 deletions(-)
diff --git a/libavutil/jniutils.c b/libavutil/jniutils.c
index 89623af3f8..beedf24c0d 100644
--- a/libavutil/jniutils.c
+++ b/libavutil/jniutils.c
@@ -236,17 +236,9 @@ done:
av_free(name);
av_free(message);
- if (class_class) {
- (*env)->DeleteLocalRef(env, class_class);
- }
-
- if (exception_class) {
- (*env)->DeleteLocalRef(env, exception_class);
- }
-
- if (string) {
- (*env)->DeleteLocalRef(env, string);
- }
+ (*env)->DeleteLocalRef(env, class_class);
+ (*env)->DeleteLocalRef(env, exception_class);
+ (*env)->DeleteLocalRef(env, string);
return ret;
}
--
2.43.1
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 51+ messages in thread
* [FFmpeg-devel] [PATCH 6/7] avcodec/mediacodec_wrapper: use an OFFSET() macro where relevant
2024-02-13 22:50 [FFmpeg-devel] Add protocol for Android content providers Matthieu Bouron
` (4 preceding siblings ...)
2024-02-13 22:50 ` [FFmpeg-devel] [PATCH 5/7] avutil/jni: remove unnecessary NULL checks before calling DeleteLocalRef() Matthieu Bouron
@ 2024-02-13 22:50 ` Matthieu Bouron
2024-02-13 22:50 ` [FFmpeg-devel] [PATCH 7/7] avcodec/mediacodec_wrapper: remove unnecessary NULL checks before calling Delete{Global, Local}Ref() Matthieu Bouron
` (2 subsequent siblings)
8 siblings, 0 replies; 51+ messages in thread
From: Matthieu Bouron @ 2024-02-13 22:50 UTC (permalink / raw)
To: ffmpeg-devel; +Cc: Matthieu Bouron
Reduces a bit the horizontal spacing.
---
libavcodec/mediacodec_wrapper.c | 138 +++++++++++++++++---------------
1 file changed, 72 insertions(+), 66 deletions(-)
diff --git a/libavcodec/mediacodec_wrapper.c b/libavcodec/mediacodec_wrapper.c
index bc3eb0a80d..536b5b8e81 100644
--- a/libavcodec/mediacodec_wrapper.c
+++ b/libavcodec/mediacodec_wrapper.c
@@ -60,31 +60,33 @@ struct JNIAMediaCodecListFields {
jfieldID level_id;
};
+#define OFFSET(x) offsetof(struct JNIAMediaCodecListFields, x)
static const struct FFJniField jni_amediacodeclist_mapping[] = {
- { "android/media/MediaCodecList", NULL, NULL, FF_JNI_CLASS, offsetof(struct JNIAMediaCodecListFields, mediacodec_list_class), 1 },
- { "android/media/MediaCodecList", "<init>", "(I)V", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecListFields, init_id), 0 },
- { "android/media/MediaCodecList", "findDecoderForFormat", "(Landroid/media/MediaFormat;)Ljava/lang/String;", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecListFields, find_decoder_for_format_id), 0 },
+ { "android/media/MediaCodecList", NULL, NULL, FF_JNI_CLASS, OFFSET(mediacodec_list_class), 1 },
+ { "android/media/MediaCodecList", "<init>", "(I)V", FF_JNI_METHOD, OFFSET(init_id), 0 },
+ { "android/media/MediaCodecList", "findDecoderForFormat", "(Landroid/media/MediaFormat;)Ljava/lang/String;", FF_JNI_METHOD, OFFSET(find_decoder_for_format_id), 0 },
- { "android/media/MediaCodecList", "getCodecCount", "()I", FF_JNI_STATIC_METHOD, offsetof(struct JNIAMediaCodecListFields, get_codec_count_id), 1 },
- { "android/media/MediaCodecList", "getCodecInfoAt", "(I)Landroid/media/MediaCodecInfo;", FF_JNI_STATIC_METHOD, offsetof(struct JNIAMediaCodecListFields, get_codec_info_at_id), 1 },
+ { "android/media/MediaCodecList", "getCodecCount", "()I", FF_JNI_STATIC_METHOD, OFFSET(get_codec_count_id), 1 },
+ { "android/media/MediaCodecList", "getCodecInfoAt", "(I)Landroid/media/MediaCodecInfo;", FF_JNI_STATIC_METHOD, OFFSET(get_codec_info_at_id), 1 },
- { "android/media/MediaCodecInfo", NULL, NULL, FF_JNI_CLASS, offsetof(struct JNIAMediaCodecListFields, mediacodec_info_class), 1 },
- { "android/media/MediaCodecInfo", "getName", "()Ljava/lang/String;", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecListFields, get_name_id), 1 },
- { "android/media/MediaCodecInfo", "getCapabilitiesForType", "(Ljava/lang/String;)Landroid/media/MediaCodecInfo$CodecCapabilities;", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecListFields, get_codec_capabilities_id), 1 },
- { "android/media/MediaCodecInfo", "getSupportedTypes", "()[Ljava/lang/String;", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecListFields, get_supported_types_id), 1 },
- { "android/media/MediaCodecInfo", "isEncoder", "()Z", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecListFields, is_encoder_id), 1 },
- { "android/media/MediaCodecInfo", "isSoftwareOnly", "()Z", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecListFields, is_software_only_id), 0 },
+ { "android/media/MediaCodecInfo", NULL, NULL, FF_JNI_CLASS, OFFSET(mediacodec_info_class), 1 },
+ { "android/media/MediaCodecInfo", "getName", "()Ljava/lang/String;", FF_JNI_METHOD, OFFSET(get_name_id), 1 },
+ { "android/media/MediaCodecInfo", "getCapabilitiesForType", "(Ljava/lang/String;)Landroid/media/MediaCodecInfo$CodecCapabilities;", FF_JNI_METHOD, OFFSET(get_codec_capabilities_id), 1 },
+ { "android/media/MediaCodecInfo", "getSupportedTypes", "()[Ljava/lang/String;", FF_JNI_METHOD, OFFSET(get_supported_types_id), 1 },
+ { "android/media/MediaCodecInfo", "isEncoder", "()Z", FF_JNI_METHOD, OFFSET(is_encoder_id), 1 },
+ { "android/media/MediaCodecInfo", "isSoftwareOnly", "()Z", FF_JNI_METHOD, OFFSET(is_software_only_id), 0 },
- { "android/media/MediaCodecInfo$CodecCapabilities", NULL, NULL, FF_JNI_CLASS, offsetof(struct JNIAMediaCodecListFields, codec_capabilities_class), 1 },
- { "android/media/MediaCodecInfo$CodecCapabilities", "colorFormats", "[I", FF_JNI_FIELD, offsetof(struct JNIAMediaCodecListFields, color_formats_id), 1 },
- { "android/media/MediaCodecInfo$CodecCapabilities", "profileLevels", "[Landroid/media/MediaCodecInfo$CodecProfileLevel;", FF_JNI_FIELD, offsetof(struct JNIAMediaCodecListFields, profile_levels_id), 1 },
+ { "android/media/MediaCodecInfo$CodecCapabilities", NULL, NULL, FF_JNI_CLASS, OFFSET(codec_capabilities_class), 1 },
+ { "android/media/MediaCodecInfo$CodecCapabilities", "colorFormats", "[I", FF_JNI_FIELD, OFFSET(color_formats_id), 1 },
+ { "android/media/MediaCodecInfo$CodecCapabilities", "profileLevels", "[Landroid/media/MediaCodecInfo$CodecProfileLevel;", FF_JNI_FIELD, OFFSET(profile_levels_id), 1 },
- { "android/media/MediaCodecInfo$CodecProfileLevel", NULL, NULL, FF_JNI_CLASS, offsetof(struct JNIAMediaCodecListFields, codec_profile_level_class), 1 },
- { "android/media/MediaCodecInfo$CodecProfileLevel", "profile", "I", FF_JNI_FIELD, offsetof(struct JNIAMediaCodecListFields, profile_id), 1 },
- { "android/media/MediaCodecInfo$CodecProfileLevel", "level", "I", FF_JNI_FIELD, offsetof(struct JNIAMediaCodecListFields, level_id), 1 },
+ { "android/media/MediaCodecInfo$CodecProfileLevel", NULL, NULL, FF_JNI_CLASS, OFFSET(codec_profile_level_class), 1 },
+ { "android/media/MediaCodecInfo$CodecProfileLevel", "profile", "I", FF_JNI_FIELD, OFFSET(profile_id), 1 },
+ { "android/media/MediaCodecInfo$CodecProfileLevel", "level", "I", FF_JNI_FIELD, OFFSET(level_id), 1 },
{ NULL }
};
+#undef OFFSET
struct JNIAMediaFormatFields {
@@ -110,29 +112,31 @@ struct JNIAMediaFormatFields {
};
+#define OFFSET(x) offsetof(struct JNIAMediaFormatFields, x)
static const struct FFJniField jni_amediaformat_mapping[] = {
- { "android/media/MediaFormat", NULL, NULL, FF_JNI_CLASS, offsetof(struct JNIAMediaFormatFields, mediaformat_class), 1 },
+ { "android/media/MediaFormat", NULL, NULL, FF_JNI_CLASS, OFFSET(mediaformat_class), 1 },
- { "android/media/MediaFormat", "<init>", "()V", FF_JNI_METHOD, offsetof(struct JNIAMediaFormatFields, init_id), 1 },
+ { "android/media/MediaFormat", "<init>", "()V", FF_JNI_METHOD, OFFSET(init_id), 1 },
- { "android/media/MediaFormat", "containsKey", "(Ljava/lang/String;)Z", FF_JNI_METHOD,offsetof(struct JNIAMediaFormatFields, contains_key_id), 1 },
+ { "android/media/MediaFormat", "containsKey", "(Ljava/lang/String;)Z", FF_JNI_METHOD, OFFSET(contains_key_id), 1 },
- { "android/media/MediaFormat", "getInteger", "(Ljava/lang/String;)I", FF_JNI_METHOD, offsetof(struct JNIAMediaFormatFields, get_integer_id), 1 },
- { "android/media/MediaFormat", "getLong", "(Ljava/lang/String;)J", FF_JNI_METHOD, offsetof(struct JNIAMediaFormatFields, get_long_id), 1 },
- { "android/media/MediaFormat", "getFloat", "(Ljava/lang/String;)F", FF_JNI_METHOD, offsetof(struct JNIAMediaFormatFields, get_float_id), 1 },
- { "android/media/MediaFormat", "getByteBuffer", "(Ljava/lang/String;)Ljava/nio/ByteBuffer;", FF_JNI_METHOD, offsetof(struct JNIAMediaFormatFields, get_bytebuffer_id), 1 },
- { "android/media/MediaFormat", "getString", "(Ljava/lang/String;)Ljava/lang/String;", FF_JNI_METHOD, offsetof(struct JNIAMediaFormatFields, get_string_id), 1 },
+ { "android/media/MediaFormat", "getInteger", "(Ljava/lang/String;)I", FF_JNI_METHOD, OFFSET(get_integer_id), 1 },
+ { "android/media/MediaFormat", "getLong", "(Ljava/lang/String;)J", FF_JNI_METHOD, OFFSET(get_long_id), 1 },
+ { "android/media/MediaFormat", "getFloat", "(Ljava/lang/String;)F", FF_JNI_METHOD, OFFSET(get_float_id), 1 },
+ { "android/media/MediaFormat", "getByteBuffer", "(Ljava/lang/String;)Ljava/nio/ByteBuffer;", FF_JNI_METHOD, OFFSET(get_bytebuffer_id), 1 },
+ { "android/media/MediaFormat", "getString", "(Ljava/lang/String;)Ljava/lang/String;", FF_JNI_METHOD, OFFSET(get_string_id), 1 },
- { "android/media/MediaFormat", "setInteger", "(Ljava/lang/String;I)V", FF_JNI_METHOD, offsetof(struct JNIAMediaFormatFields, set_integer_id), 1 },
- { "android/media/MediaFormat", "setLong", "(Ljava/lang/String;J)V", FF_JNI_METHOD, offsetof(struct JNIAMediaFormatFields, set_long_id), 1 },
- { "android/media/MediaFormat", "setFloat", "(Ljava/lang/String;F)V", FF_JNI_METHOD, offsetof(struct JNIAMediaFormatFields, set_float_id), 1 },
- { "android/media/MediaFormat", "setByteBuffer", "(Ljava/lang/String;Ljava/nio/ByteBuffer;)V", FF_JNI_METHOD, offsetof(struct JNIAMediaFormatFields, set_bytebuffer_id), 1 },
- { "android/media/MediaFormat", "setString", "(Ljava/lang/String;Ljava/lang/String;)V", FF_JNI_METHOD, offsetof(struct JNIAMediaFormatFields, set_string_id), 1 },
+ { "android/media/MediaFormat", "setInteger", "(Ljava/lang/String;I)V", FF_JNI_METHOD, OFFSET(set_integer_id), 1 },
+ { "android/media/MediaFormat", "setLong", "(Ljava/lang/String;J)V", FF_JNI_METHOD, OFFSET(set_long_id), 1 },
+ { "android/media/MediaFormat", "setFloat", "(Ljava/lang/String;F)V", FF_JNI_METHOD, OFFSET(set_float_id), 1 },
+ { "android/media/MediaFormat", "setByteBuffer", "(Ljava/lang/String;Ljava/nio/ByteBuffer;)V", FF_JNI_METHOD, OFFSET(set_bytebuffer_id), 1 },
+ { "android/media/MediaFormat", "setString", "(Ljava/lang/String;Ljava/lang/String;)V", FF_JNI_METHOD, OFFSET(set_string_id), 1 },
- { "android/media/MediaFormat", "toString", "()Ljava/lang/String;", FF_JNI_METHOD, offsetof(struct JNIAMediaFormatFields, to_string_id), 1 },
+ { "android/media/MediaFormat", "toString", "()Ljava/lang/String;", FF_JNI_METHOD, OFFSET(to_string_id), 1 },
{ NULL }
};
+#undef OFFSET
static const AVClass amediaformat_class = {
.class_name = "amediaformat",
@@ -202,57 +206,59 @@ struct JNIAMediaCodecFields {
};
+#define OFFSET(x) offsetof(struct JNIAMediaCodecFields, x)
static const struct FFJniField jni_amediacodec_mapping[] = {
- { "android/media/MediaCodec", NULL, NULL, FF_JNI_CLASS, offsetof(struct JNIAMediaCodecFields, mediacodec_class), 1 },
+ { "android/media/MediaCodec", NULL, NULL, FF_JNI_CLASS, OFFSET(mediacodec_class), 1 },
- { "android/media/MediaCodec", "INFO_TRY_AGAIN_LATER", "I", FF_JNI_STATIC_FIELD, offsetof(struct JNIAMediaCodecFields, info_try_again_later_id), 1 },
- { "android/media/MediaCodec", "INFO_OUTPUT_BUFFERS_CHANGED", "I", FF_JNI_STATIC_FIELD, offsetof(struct JNIAMediaCodecFields, info_output_buffers_changed_id), 1 },
- { "android/media/MediaCodec", "INFO_OUTPUT_FORMAT_CHANGED", "I", FF_JNI_STATIC_FIELD, offsetof(struct JNIAMediaCodecFields, info_output_format_changed_id), 1 },
+ { "android/media/MediaCodec", "INFO_TRY_AGAIN_LATER", "I", FF_JNI_STATIC_FIELD, OFFSET(info_try_again_later_id), 1 },
+ { "android/media/MediaCodec", "INFO_OUTPUT_BUFFERS_CHANGED", "I", FF_JNI_STATIC_FIELD, OFFSET(info_output_buffers_changed_id), 1 },
+ { "android/media/MediaCodec", "INFO_OUTPUT_FORMAT_CHANGED", "I", FF_JNI_STATIC_FIELD, OFFSET(info_output_format_changed_id), 1 },
- { "android/media/MediaCodec", "BUFFER_FLAG_CODEC_CONFIG", "I", FF_JNI_STATIC_FIELD, offsetof(struct JNIAMediaCodecFields, buffer_flag_codec_config_id), 1 },
- { "android/media/MediaCodec", "BUFFER_FLAG_END_OF_STREAM", "I", FF_JNI_STATIC_FIELD, offsetof(struct JNIAMediaCodecFields, buffer_flag_end_of_stream_id), 1 },
- { "android/media/MediaCodec", "BUFFER_FLAG_KEY_FRAME", "I", FF_JNI_STATIC_FIELD, offsetof(struct JNIAMediaCodecFields, buffer_flag_key_frame_id), 0 },
+ { "android/media/MediaCodec", "BUFFER_FLAG_CODEC_CONFIG", "I", FF_JNI_STATIC_FIELD, OFFSET(buffer_flag_codec_config_id), 1 },
+ { "android/media/MediaCodec", "BUFFER_FLAG_END_OF_STREAM", "I", FF_JNI_STATIC_FIELD, OFFSET(buffer_flag_end_of_stream_id), 1 },
+ { "android/media/MediaCodec", "BUFFER_FLAG_KEY_FRAME", "I", FF_JNI_STATIC_FIELD, OFFSET(buffer_flag_key_frame_id), 0 },
- { "android/media/MediaCodec", "CONFIGURE_FLAG_ENCODE", "I", FF_JNI_STATIC_FIELD, offsetof(struct JNIAMediaCodecFields, configure_flag_encode_id), 1 },
+ { "android/media/MediaCodec", "CONFIGURE_FLAG_ENCODE", "I", FF_JNI_STATIC_FIELD, OFFSET(configure_flag_encode_id), 1 },
- { "android/media/MediaCodec", "createByCodecName", "(Ljava/lang/String;)Landroid/media/MediaCodec;", FF_JNI_STATIC_METHOD, offsetof(struct JNIAMediaCodecFields, create_by_codec_name_id), 1 },
- { "android/media/MediaCodec", "createDecoderByType", "(Ljava/lang/String;)Landroid/media/MediaCodec;", FF_JNI_STATIC_METHOD, offsetof(struct JNIAMediaCodecFields, create_decoder_by_type_id), 1 },
- { "android/media/MediaCodec", "createEncoderByType", "(Ljava/lang/String;)Landroid/media/MediaCodec;", FF_JNI_STATIC_METHOD, offsetof(struct JNIAMediaCodecFields, create_encoder_by_type_id), 1 },
+ { "android/media/MediaCodec", "createByCodecName", "(Ljava/lang/String;)Landroid/media/MediaCodec;", FF_JNI_STATIC_METHOD, OFFSET(create_by_codec_name_id), 1 },
+ { "android/media/MediaCodec", "createDecoderByType", "(Ljava/lang/String;)Landroid/media/MediaCodec;", FF_JNI_STATIC_METHOD, OFFSET(create_decoder_by_type_id), 1 },
+ { "android/media/MediaCodec", "createEncoderByType", "(Ljava/lang/String;)Landroid/media/MediaCodec;", FF_JNI_STATIC_METHOD, OFFSET(create_encoder_by_type_id), 1 },
- { "android/media/MediaCodec", "getName", "()Ljava/lang/String;", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecFields, get_name_id), 1 },
+ { "android/media/MediaCodec", "getName", "()Ljava/lang/String;", FF_JNI_METHOD, OFFSET(get_name_id), 1 },
- { "android/media/MediaCodec", "configure", "(Landroid/media/MediaFormat;Landroid/view/Surface;Landroid/media/MediaCrypto;I)V", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecFields, configure_id), 1 },
- { "android/media/MediaCodec", "start", "()V", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecFields, start_id), 1 },
- { "android/media/MediaCodec", "flush", "()V", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecFields, flush_id), 1 },
- { "android/media/MediaCodec", "stop", "()V", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecFields, stop_id), 1 },
- { "android/media/MediaCodec", "release", "()V", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecFields, release_id), 1 },
+ { "android/media/MediaCodec", "configure", "(Landroid/media/MediaFormat;Landroid/view/Surface;Landroid/media/MediaCrypto;I)V", FF_JNI_METHOD, OFFSET(configure_id), 1 },
+ { "android/media/MediaCodec", "start", "()V", FF_JNI_METHOD, OFFSET(start_id), 1 },
+ { "android/media/MediaCodec", "flush", "()V", FF_JNI_METHOD, OFFSET(flush_id), 1 },
+ { "android/media/MediaCodec", "stop", "()V", FF_JNI_METHOD, OFFSET(stop_id), 1 },
+ { "android/media/MediaCodec", "release", "()V", FF_JNI_METHOD, OFFSET(release_id), 1 },
- { "android/media/MediaCodec", "getOutputFormat", "()Landroid/media/MediaFormat;", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecFields, get_output_format_id), 1 },
+ { "android/media/MediaCodec", "getOutputFormat", "()Landroid/media/MediaFormat;", FF_JNI_METHOD, OFFSET(get_output_format_id), 1 },
- { "android/media/MediaCodec", "dequeueInputBuffer", "(J)I", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecFields, dequeue_input_buffer_id), 1 },
- { "android/media/MediaCodec", "queueInputBuffer", "(IIIJI)V", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecFields, queue_input_buffer_id), 1 },
- { "android/media/MediaCodec", "getInputBuffer", "(I)Ljava/nio/ByteBuffer;", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecFields, get_input_buffer_id), 0 },
- { "android/media/MediaCodec", "getInputBuffers", "()[Ljava/nio/ByteBuffer;", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecFields, get_input_buffers_id), 1 },
+ { "android/media/MediaCodec", "dequeueInputBuffer", "(J)I", FF_JNI_METHOD, OFFSET(dequeue_input_buffer_id), 1 },
+ { "android/media/MediaCodec", "queueInputBuffer", "(IIIJI)V", FF_JNI_METHOD, OFFSET(queue_input_buffer_id), 1 },
+ { "android/media/MediaCodec", "getInputBuffer", "(I)Ljava/nio/ByteBuffer;", FF_JNI_METHOD, OFFSET(get_input_buffer_id), 0 },
+ { "android/media/MediaCodec", "getInputBuffers", "()[Ljava/nio/ByteBuffer;", FF_JNI_METHOD, OFFSET(get_input_buffers_id), 1 },
- { "android/media/MediaCodec", "dequeueOutputBuffer", "(Landroid/media/MediaCodec$BufferInfo;J)I", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecFields, dequeue_output_buffer_id), 1 },
- { "android/media/MediaCodec", "getOutputBuffer", "(I)Ljava/nio/ByteBuffer;", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecFields, get_output_buffer_id), 0 },
- { "android/media/MediaCodec", "getOutputBuffers", "()[Ljava/nio/ByteBuffer;", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecFields, get_output_buffers_id), 1 },
- { "android/media/MediaCodec", "releaseOutputBuffer", "(IZ)V", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecFields, release_output_buffer_id), 1 },
- { "android/media/MediaCodec", "releaseOutputBuffer", "(IJ)V", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecFields, release_output_buffer_at_time_id), 0 },
+ { "android/media/MediaCodec", "dequeueOutputBuffer", "(Landroid/media/MediaCodec$BufferInfo;J)I", FF_JNI_METHOD, OFFSET(dequeue_output_buffer_id), 1 },
+ { "android/media/MediaCodec", "getOutputBuffer", "(I)Ljava/nio/ByteBuffer;", FF_JNI_METHOD, OFFSET(get_output_buffer_id), 0 },
+ { "android/media/MediaCodec", "getOutputBuffers", "()[Ljava/nio/ByteBuffer;", FF_JNI_METHOD, OFFSET(get_output_buffers_id), 1 },
+ { "android/media/MediaCodec", "releaseOutputBuffer", "(IZ)V", FF_JNI_METHOD, OFFSET(release_output_buffer_id), 1 },
+ { "android/media/MediaCodec", "releaseOutputBuffer", "(IJ)V", FF_JNI_METHOD, OFFSET(release_output_buffer_at_time_id), 0 },
- { "android/media/MediaCodec", "setInputSurface", "(Landroid/view/Surface;)V", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecFields, set_input_surface_id), 0 },
- { "android/media/MediaCodec", "signalEndOfInputStream", "()V", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecFields, signal_end_of_input_stream_id), 0 },
+ { "android/media/MediaCodec", "setInputSurface", "(Landroid/view/Surface;)V", FF_JNI_METHOD, OFFSET(set_input_surface_id), 0 },
+ { "android/media/MediaCodec", "signalEndOfInputStream", "()V", FF_JNI_METHOD, OFFSET(signal_end_of_input_stream_id), 0 },
- { "android/media/MediaCodec$BufferInfo", NULL, NULL, FF_JNI_CLASS, offsetof(struct JNIAMediaCodecFields, mediainfo_class), 1 },
+ { "android/media/MediaCodec$BufferInfo", NULL, NULL, FF_JNI_CLASS, OFFSET(mediainfo_class), 1 },
- { "android/media/MediaCodec.BufferInfo", "<init>", "()V", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecFields, init_id), 1 },
- { "android/media/MediaCodec.BufferInfo", "flags", "I", FF_JNI_FIELD, offsetof(struct JNIAMediaCodecFields, flags_id), 1 },
- { "android/media/MediaCodec.BufferInfo", "offset", "I", FF_JNI_FIELD, offsetof(struct JNIAMediaCodecFields, offset_id), 1 },
- { "android/media/MediaCodec.BufferInfo", "presentationTimeUs", "J", FF_JNI_FIELD, offsetof(struct JNIAMediaCodecFields, presentation_time_us_id), 1 },
- { "android/media/MediaCodec.BufferInfo", "size", "I", FF_JNI_FIELD, offsetof(struct JNIAMediaCodecFields, size_id), 1 },
+ { "android/media/MediaCodec.BufferInfo", "<init>", "()V", FF_JNI_METHOD, OFFSET(init_id), 1 },
+ { "android/media/MediaCodec.BufferInfo", "flags", "I", FF_JNI_FIELD, OFFSET(flags_id), 1 },
+ { "android/media/MediaCodec.BufferInfo", "offset", "I", FF_JNI_FIELD, OFFSET(offset_id), 1 },
+ { "android/media/MediaCodec.BufferInfo", "presentationTimeUs", "J", FF_JNI_FIELD, OFFSET(presentation_time_us_id), 1 },
+ { "android/media/MediaCodec.BufferInfo", "size", "I", FF_JNI_FIELD, OFFSET(size_id), 1 },
{ NULL }
};
+#undef OFFSET
static const AVClass amediacodec_class = {
.class_name = "amediacodec",
--
2.43.1
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 51+ messages in thread
* [FFmpeg-devel] [PATCH 7/7] avcodec/mediacodec_wrapper: remove unnecessary NULL checks before calling Delete{Global, Local}Ref()
2024-02-13 22:50 [FFmpeg-devel] Add protocol for Android content providers Matthieu Bouron
` (5 preceding siblings ...)
2024-02-13 22:50 ` [FFmpeg-devel] [PATCH 6/7] avcodec/mediacodec_wrapper: use an OFFSET() macro where relevant Matthieu Bouron
@ 2024-02-13 22:50 ` Matthieu Bouron
2024-02-15 4:13 ` [FFmpeg-devel] Add protocol for Android content providers Zhao Zhili
2024-02-27 14:50 ` [FFmpeg-devel] Add protocol for Android content providers (v2) Matthieu Bouron
8 siblings, 0 replies; 51+ messages in thread
From: Matthieu Bouron @ 2024-02-13 22:50 UTC (permalink / raw)
To: ffmpeg-devel; +Cc: Matthieu Bouron
Delete{Global,Local}Ref already handle NULL.
---
libavcodec/mediacodec_wrapper.c | 189 ++++++++------------------------
1 file changed, 47 insertions(+), 142 deletions(-)
diff --git a/libavcodec/mediacodec_wrapper.c b/libavcodec/mediacodec_wrapper.c
index 536b5b8e81..19d63e2ba0 100644
--- a/libavcodec/mediacodec_wrapper.c
+++ b/libavcodec/mediacodec_wrapper.c
@@ -549,10 +549,8 @@ char *ff_AMediaCodecList_getCodecNameByType(const char *mime, int profile, int e
goto done;
}
- if (codec_name) {
- (*env)->DeleteLocalRef(env, codec_name);
- codec_name = NULL;
- }
+ (*env)->DeleteLocalRef(env, codec_name);
+ codec_name = NULL;
/* Skip software decoders */
if (
@@ -616,10 +614,8 @@ char *ff_AMediaCodecList_getCodecNameByType(const char *mime, int profile, int e
found_codec = profile == supported_profile;
- if (profile_level) {
- (*env)->DeleteLocalRef(env, profile_level);
- profile_level = NULL;
- }
+ (*env)->DeleteLocalRef(env, profile_level);
+ profile_level = NULL;
if (found_codec) {
break;
@@ -627,20 +623,14 @@ char *ff_AMediaCodecList_getCodecNameByType(const char *mime, int profile, int e
}
done_with_type:
- if (profile_levels) {
- (*env)->DeleteLocalRef(env, profile_levels);
- profile_levels = NULL;
- }
+ (*env)->DeleteLocalRef(env, profile_levels);
+ profile_levels = NULL;
- if (capabilities) {
- (*env)->DeleteLocalRef(env, capabilities);
- capabilities = NULL;
- }
+ (*env)->DeleteLocalRef(env, capabilities);
+ capabilities = NULL;
- if (type) {
- (*env)->DeleteLocalRef(env, type);
- type = NULL;
- }
+ (*env)->DeleteLocalRef(env, type);
+ type = NULL;
av_freep(&supported_type);
@@ -650,15 +640,11 @@ done_with_type:
}
done_with_info:
- if (info) {
- (*env)->DeleteLocalRef(env, info);
- info = NULL;
- }
+ (*env)->DeleteLocalRef(env, info);
+ info = NULL;
- if (types) {
- (*env)->DeleteLocalRef(env, types);
- types = NULL;
- }
+ (*env)->DeleteLocalRef(env, types);
+ types = NULL;
if (found_codec) {
break;
@@ -668,33 +654,13 @@ done_with_info:
}
done:
- if (codec_name) {
- (*env)->DeleteLocalRef(env, codec_name);
- }
-
- if (info) {
- (*env)->DeleteLocalRef(env, info);
- }
-
- if (type) {
- (*env)->DeleteLocalRef(env, type);
- }
-
- if (types) {
- (*env)->DeleteLocalRef(env, types);
- }
-
- if (capabilities) {
- (*env)->DeleteLocalRef(env, capabilities);
- }
-
- if (profile_level) {
- (*env)->DeleteLocalRef(env, profile_level);
- }
-
- if (profile_levels) {
- (*env)->DeleteLocalRef(env, profile_levels);
- }
+ (*env)->DeleteLocalRef(env, codec_name);
+ (*env)->DeleteLocalRef(env, info);
+ (*env)->DeleteLocalRef(env, type);
+ (*env)->DeleteLocalRef(env, types);
+ (*env)->DeleteLocalRef(env, capabilities);
+ (*env)->DeleteLocalRef(env, profile_level);
+ (*env)->DeleteLocalRef(env, profile_levels);
av_freep(&supported_type);
@@ -741,9 +707,7 @@ static FFAMediaFormat *mediaformat_jni_new(void)
}
fail:
- if (object) {
- (*env)->DeleteLocalRef(env, object);
- }
+ (*env)->DeleteLocalRef(env, object);
if (!format->object) {
avpriv_jni_reset_jfields(env, &format->jfields, jni_amediaformat_mapping, 1, format);
@@ -828,9 +792,7 @@ static char* mediaformat_jni_toString(FFAMediaFormat* ctx)
ret = avpriv_jni_jstring_to_utf_chars(env, description, format);
fail:
- if (description) {
- (*env)->DeleteLocalRef(env, description);
- }
+ (*env)->DeleteLocalRef(env, description);
return ret;
}
@@ -867,9 +829,7 @@ static int mediaformat_jni_getInt32(FFAMediaFormat* ctx, const char *name, int32
ret = 1;
fail:
- if (key) {
- (*env)->DeleteLocalRef(env, key);
- }
+ (*env)->DeleteLocalRef(env, key);
return ret;
}
@@ -906,9 +866,7 @@ static int mediaformat_jni_getInt64(FFAMediaFormat* ctx, const char *name, int64
ret = 1;
fail:
- if (key) {
- (*env)->DeleteLocalRef(env, key);
- }
+ (*env)->DeleteLocalRef(env, key);
return ret;
}
@@ -945,9 +903,7 @@ static int mediaformat_jni_getFloat(FFAMediaFormat* ctx, const char *name, float
ret = 1;
fail:
- if (key) {
- (*env)->DeleteLocalRef(env, key);
- }
+ (*env)->DeleteLocalRef(env, key);
return ret;
}
@@ -999,13 +955,8 @@ static int mediaformat_jni_getBuffer(FFAMediaFormat* ctx, const char *name, void
ret = 1;
fail:
- if (key) {
- (*env)->DeleteLocalRef(env, key);
- }
-
- if (result) {
- (*env)->DeleteLocalRef(env, result);
- }
+ (*env)->DeleteLocalRef(env, key);
+ (*env)->DeleteLocalRef(env, result);
return ret;
}
@@ -1049,13 +1000,8 @@ static int mediaformat_jni_getString(FFAMediaFormat* ctx, const char *name, cons
ret = 1;
fail:
- if (key) {
- (*env)->DeleteLocalRef(env, key);
- }
-
- if (result) {
- (*env)->DeleteLocalRef(env, result);
- }
+ (*env)->DeleteLocalRef(env, key);
+ (*env)->DeleteLocalRef(env, result);
return ret;
}
@@ -1081,9 +1027,7 @@ static void mediaformat_jni_setInt32(FFAMediaFormat* ctx, const char* name, int3
}
fail:
- if (key) {
- (*env)->DeleteLocalRef(env, key);
- }
+ (*env)->DeleteLocalRef(env, key);
}
static void mediaformat_jni_setInt64(FFAMediaFormat* ctx, const char* name, int64_t value)
@@ -1107,9 +1051,7 @@ static void mediaformat_jni_setInt64(FFAMediaFormat* ctx, const char* name, int6
}
fail:
- if (key) {
- (*env)->DeleteLocalRef(env, key);
- }
+ (*env)->DeleteLocalRef(env, key);
}
static void mediaformat_jni_setFloat(FFAMediaFormat* ctx, const char* name, float value)
@@ -1133,9 +1075,7 @@ static void mediaformat_jni_setFloat(FFAMediaFormat* ctx, const char* name, floa
}
fail:
- if (key) {
- (*env)->DeleteLocalRef(env, key);
- }
+ (*env)->DeleteLocalRef(env, key);
}
static void mediaformat_jni_setString(FFAMediaFormat* ctx, const char* name, const char* value)
@@ -1165,13 +1105,8 @@ static void mediaformat_jni_setString(FFAMediaFormat* ctx, const char* name, con
}
fail:
- if (key) {
- (*env)->DeleteLocalRef(env, key);
- }
-
- if (string) {
- (*env)->DeleteLocalRef(env, string);
- }
+ (*env)->DeleteLocalRef(env, key);
+ (*env)->DeleteLocalRef(env, string);
}
static void mediaformat_jni_setBuffer(FFAMediaFormat* ctx, const char* name, void* data, size_t size)
@@ -1213,13 +1148,8 @@ static void mediaformat_jni_setBuffer(FFAMediaFormat* ctx, const char* name, voi
}
fail:
- if (key) {
- (*env)->DeleteLocalRef(env, key);
- }
-
- if (buffer) {
- (*env)->DeleteLocalRef(env, buffer);
- }
+ (*env)->DeleteLocalRef(env, key);
+ (*env)->DeleteLocalRef(env, buffer);
}
static int codec_init_static_fields(FFAMediaCodecJni *codec)
@@ -1352,26 +1282,13 @@ static inline FFAMediaCodec *codec_create(int method, const char *arg)
ret = 0;
fail:
- if (jarg) {
- (*env)->DeleteLocalRef(env, jarg);
- }
-
- if (object) {
- (*env)->DeleteLocalRef(env, object);
- }
-
- if (buffer_info) {
- (*env)->DeleteLocalRef(env, buffer_info);
- }
+ (*env)->DeleteLocalRef(env, jarg);
+ (*env)->DeleteLocalRef(env, object);
+ (*env)->DeleteLocalRef(env, buffer_info);
if (ret < 0) {
- if (codec->object) {
- (*env)->DeleteGlobalRef(env, codec->object);
- }
-
- if (codec->buffer_info) {
- (*env)->DeleteGlobalRef(env, codec->buffer_info);
- }
+ (*env)->DeleteGlobalRef(env, codec->object);
+ (*env)->DeleteGlobalRef(env, codec->buffer_info);
avpriv_jni_reset_jfields(env, &codec->jfields, jni_amediacodec_mapping, 1, codec);
av_freep(&codec);
@@ -1692,13 +1609,8 @@ static uint8_t* mediacodec_jni_getInputBuffer(FFAMediaCodec* ctx, size_t idx, si
ret = (*env)->GetDirectBufferAddress(env, buffer);
*out_size = (*env)->GetDirectBufferCapacity(env, buffer);
fail:
- if (buffer) {
- (*env)->DeleteLocalRef(env, buffer);
- }
-
- if (input_buffers) {
- (*env)->DeleteLocalRef(env, input_buffers);
- }
+ (*env)->DeleteLocalRef(env, buffer);
+ (*env)->DeleteLocalRef(env, input_buffers);
return ret;
}
@@ -1740,13 +1652,8 @@ static uint8_t* mediacodec_jni_getOutputBuffer(FFAMediaCodec* ctx, size_t idx, s
ret = (*env)->GetDirectBufferAddress(env, buffer);
*out_size = (*env)->GetDirectBufferCapacity(env, buffer);
fail:
- if (buffer) {
- (*env)->DeleteLocalRef(env, buffer);
- }
-
- if (output_buffers) {
- (*env)->DeleteLocalRef(env, output_buffers);
- }
+ (*env)->DeleteLocalRef(env, buffer);
+ (*env)->DeleteLocalRef(env, output_buffers);
return ret;
}
@@ -1768,9 +1675,7 @@ static FFAMediaFormat* mediacodec_jni_getOutputFormat(FFAMediaCodec* ctx)
ret = mediaformat_jni_newFromObject(mediaformat);
fail:
- if (mediaformat) {
- (*env)->DeleteLocalRef(env, mediaformat);
- }
+ (*env)->DeleteLocalRef(env, mediaformat);
return ret;
}
--
2.43.1
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 51+ messages in thread
* Re: [FFmpeg-devel] [PATCH 1/7] avcodec: move ffjni to avutil/jniutils
2024-02-13 22:50 ` [FFmpeg-devel] [PATCH 1/7] avcodec: move ffjni to avutil/jniutils Matthieu Bouron
@ 2024-02-14 18:18 ` Michael Niedermayer
2024-02-14 22:23 ` Matthieu Bouron
2024-02-14 23:31 ` Mark Thompson
1 sibling, 1 reply; 51+ messages in thread
From: Michael Niedermayer @ 2024-02-14 18:18 UTC (permalink / raw)
To: FFmpeg development discussions and patches
[-- Attachment #1.1: Type: text/plain, Size: 2095 bytes --]
On Tue, Feb 13, 2024 at 11:50:09PM +0100, Matthieu Bouron wrote:
> 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%)
this breaks build
make
CC libavutil/jni.o
libavutil/jni.c:68:5: error: no previous prototype for ‘av_jni_set_java_vm’ [-Werror=missing-prototypes]
int av_jni_set_java_vm(void *vm, void *log_ctx)
^~~~~~~~~~~~~~~~~~
libavutil/jni.c:73:7: error: no previous prototype for ‘av_jni_get_java_vm’ [-Werror=missing-prototypes]
void *av_jni_get_java_vm(void *log_ctx)
^~~~~~~~~~~~~~~~~~
cc1: some warnings being treated as errors
ffbuild/common.mak:81: recipe for target 'libavutil/jni.o' failed
make: *** [libavutil/jni.o] Error 1
[...]
--
Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB
Complexity theory is the science of finding the exact solution to an
approximation. Benchmarking OTOH is finding an approximation of the exact
[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 195 bytes --]
[-- Attachment #2: Type: text/plain, Size: 251 bytes --]
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 51+ messages in thread
* Re: [FFmpeg-devel] [PATCH 1/7] avcodec: move ffjni to avutil/jniutils
2024-02-14 18:18 ` Michael Niedermayer
@ 2024-02-14 22:23 ` Matthieu Bouron
0 siblings, 0 replies; 51+ messages in thread
From: Matthieu Bouron @ 2024-02-14 22:23 UTC (permalink / raw)
To: FFmpeg development discussions and patches
[-- Attachment #1: Type: text/plain, Size: 2002 bytes --]
On Wed, Feb 14, 2024 at 07:18:04PM +0100, Michael Niedermayer wrote:
> On Tue, Feb 13, 2024 at 11:50:09PM +0100, Matthieu Bouron wrote:
> > 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%)
>
> this breaks build
>
> make
> CC libavutil/jni.o
> libavutil/jni.c:68:5: error: no previous prototype for ‘av_jni_set_java_vm’ [-Werror=missing-prototypes]
> int av_jni_set_java_vm(void *vm, void *log_ctx)
> ^~~~~~~~~~~~~~~~~~
> libavutil/jni.c:73:7: error: no previous prototype for ‘av_jni_get_java_vm’ [-Werror=missing-prototypes]
> void *av_jni_get_java_vm(void *log_ctx)
> ^~~~~~~~~~~~~~~~~~
> cc1: some warnings being treated as errors
> ffbuild/common.mak:81: recipe for target 'libavutil/jni.o' failed
> make: *** [libavutil/jni.o] Error 1
Thanks, new patch attached.
[...]
[-- Attachment #2: 0001-avcodec-move-ffjni-to-avutil-jniutils.patch --]
[-- Type: text/plain, Size: 56996 bytes --]
From 5b6a127143d8a3d111f7bef1a3e3bc9aab60a8ea Mon Sep 17 00:00:00 2001
From: Matthieu Bouron <matthieu.bouron@gmail.com>
Date: Mon, 12 Feb 2024 18:33:41 +0100
Subject: [PATCH 1/7] avcodec: move ffjni to avutil/jniutils
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 | 49 +----
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, 284 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..f301307202 100644
--- a/libavcodec/jni.c
+++ b/libavcodec/jni.c
@@ -20,60 +20,19 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#include "config.h"
-
#include <stdlib.h>
#include "libavutil/error.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;
+#include "libavutil/jni.h"
-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
+#include "jni.h"
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..553d5aa759
--- /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/jni.h"
+#include "libavutil/error.h"
+
+#if CONFIG_JNI
+#include <jni.h>
+#include <pthread.h>
+
+#include "libavutil/log.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_jvm(void *vm, void *log_ctx)
+{
+ return AVERROR(ENOSYS);
+}
+
+void *av_jni_get_jvm(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
[-- Attachment #3: Type: text/plain, Size: 251 bytes --]
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 51+ messages in thread
* Re: [FFmpeg-devel] [PATCH 1/7] avcodec: move ffjni to avutil/jniutils
2024-02-13 22:50 ` [FFmpeg-devel] [PATCH 1/7] avcodec: move ffjni to avutil/jniutils Matthieu Bouron
2024-02-14 18:18 ` Michael Niedermayer
@ 2024-02-14 23:31 ` Mark Thompson
2024-02-15 7:40 ` Matthieu Bouron
1 sibling, 1 reply; 51+ messages in thread
From: Mark Thompson @ 2024-02-14 23:31 UTC (permalink / raw)
To: ffmpeg-devel
On 13/02/2024 22:50, Matthieu Bouron wrote:
> 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%)
Why?
libavformat already depends on libavcodec.
Thanks,
- Mark
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 51+ messages in thread
* Re: [FFmpeg-devel] Add protocol for Android content providers
2024-02-13 22:50 [FFmpeg-devel] Add protocol for Android content providers Matthieu Bouron
` (6 preceding siblings ...)
2024-02-13 22:50 ` [FFmpeg-devel] [PATCH 7/7] avcodec/mediacodec_wrapper: remove unnecessary NULL checks before calling Delete{Global, Local}Ref() Matthieu Bouron
@ 2024-02-15 4:13 ` Zhao Zhili
2024-02-15 7:57 ` Matthieu Bouron
2024-02-27 14:50 ` [FFmpeg-devel] Add protocol for Android content providers (v2) Matthieu Bouron
8 siblings, 1 reply; 51+ messages in thread
From: Zhao Zhili @ 2024-02-15 4:13 UTC (permalink / raw)
To: FFmpeg development discussions and patches
> On Feb 14, 2024, at 06:50, Matthieu Bouron <matthieu.bouron@gmail.com> wrote:
>
> Hi,
>
> On Android, content providers are used for accessing files through shared
> mechanisms. One typical case would be an app willing to open a video from
> Google Photos, gallery apps, TikTok, Instagram or some other providers.
> A content URI looks something like "content://authority/path/id", see:
> https://developer.android.com/reference/android/content/ContentUris
> https://developer.android.com/guide/topics/providers/content-provider-basics
>
> It can currently be somehow managed through clumsy means such as using a "fd:"
> filename and crafting a special AVOption, which also has the drawback of
> requiring the third party to carry around opened file descriptors (with the
> multiple opened file limitations implied). Custom AVIOContexts are also an
File descriptor is a general abstraction layer, it target more platforms than
Android specific content provider. Android provided getFd() API since API
level 12, I guess that’s the default method to deal with content provider in
native code. It’s a few lines of code to get native fd in Java, but dozens of code
in C with JNI, which is what this patchset done.
For multiple opened file limitations issue, they can close the file descriptor after
open. It’s unlikely to reach the limit in normal case without leak.
I’m OK to provide this android_content_protocol helper if user requests.
> option. Both options will have to deal with the JNI though and end users will
> have to re-implement the same exact thing.
User still need to deal with JNI with the new android_content_protocol, more or
less, it’s unavoidable.
>
> This patchset addresses this by adding a content provider protocol, which has
> an API fairly similar to fopen. Android 11 appears to provide something
> transparent within fopen(), but FFmpeg doesn't use it in the file protocol, and
> Android < 11 are still widely used.
>
> The first part move the JNI infrastructure from avcodec to avutil (it remains
> internally shared, there is little user implication),
OK. JNI infrastructure should belong to avutil at the first place, so hwcontext_mediacodec
and so on can use it. Unfortunately for those new avpriv_.
> and then the URLProtocol
> is added, along with a few cleanups.
>
> Regards,
>
> --
> Matthieu
>
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
> To unsubscribe, visit link above, or email
> ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 51+ messages in thread
* Re: [FFmpeg-devel] [PATCH 1/7] avcodec: move ffjni to avutil/jniutils
2024-02-14 23:31 ` Mark Thompson
@ 2024-02-15 7:40 ` Matthieu Bouron
0 siblings, 0 replies; 51+ messages in thread
From: Matthieu Bouron @ 2024-02-15 7:40 UTC (permalink / raw)
To: FFmpeg development discussions and patches
On Wed, Feb 14, 2024 at 11:31:21PM +0000, Mark Thompson wrote:
> On 13/02/2024 22:50, Matthieu Bouron wrote:
> > 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%)
>
> Why?
>
> libavformat already depends on libavcodec.
Since both libavformat and libavcodec will use it, it seems more
logical to put the code in libavutil. It could also benefits
libavutil/hwcontext_mediacodec.
[...]
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 51+ messages in thread
* Re: [FFmpeg-devel] Add protocol for Android content providers
2024-02-15 4:13 ` [FFmpeg-devel] Add protocol for Android content providers Zhao Zhili
@ 2024-02-15 7:57 ` Matthieu Bouron
2024-02-15 8:46 ` Zhao Zhili
0 siblings, 1 reply; 51+ messages in thread
From: Matthieu Bouron @ 2024-02-15 7:57 UTC (permalink / raw)
To: FFmpeg development discussions and patches
On Thu, Feb 15, 2024 at 12:13:59PM +0800, Zhao Zhili wrote:
>
>
> > On Feb 14, 2024, at 06:50, Matthieu Bouron <matthieu.bouron@gmail.com> wrote:
> >
> > Hi,
> >
> > On Android, content providers are used for accessing files through shared
> > mechanisms. One typical case would be an app willing to open a video from
> > Google Photos, gallery apps, TikTok, Instagram or some other providers.
> > A content URI looks something like "content://authority/path/id", see:
> > https://developer.android.com/reference/android/content/ContentUris
> > https://developer.android.com/guide/topics/providers/content-provider-basics
> >
> > It can currently be somehow managed through clumsy means such as using a "fd:"
> > filename and crafting a special AVOption, which also has the drawback of
> > requiring the third party to carry around opened file descriptors (with the
> > multiple opened file limitations implied). Custom AVIOContexts are also an
>
> File descriptor is a general abstraction layer, it target more platforms than
> Android specific content provider. Android provided getFd() API since API
> level 12, I guess that’s the default method to deal with content provider in
> native code. It’s a few lines of code to get native fd in Java, but dozens of code
> in C with JNI, which is what this patchset done.
>
> For multiple opened file limitations issue, they can close the file descriptor after
> open. It’s unlikely to reach the limit in normal case without leak.
>
> I’m OK to provide this android_content_protocol helper if user requests.
I've been doing this kind of work for 3/4 users (including myself) at this
point and have to do it another time, this is what motivated me to propose
this patchset.
>
> > option. Both options will have to deal with the JNI though and end users will
> > have to re-implement the same exact thing.
>
> User still need to deal with JNI with the new android_content_protocol, more or
> less, it’s unavoidable.
The advantage I see of using this protocol is that the user only need to
call av_jni_set_jvm() + av_jni_set_android_app_ctx() at the start of the
application and FFmpeg will handle the content-uri transparently. This is
especially helpful if the Android application rely on multiple libraries
that in turn rely on FFmpeg to read medias.
>
> >
> > This patchset addresses this by adding a content provider protocol, which has
> > an API fairly similar to fopen. Android 11 appears to provide something
> > transparent within fopen(), but FFmpeg doesn't use it in the file protocol, and
> > Android < 11 are still widely used.
> >
> > The first part move the JNI infrastructure from avcodec to avutil (it remains
> > internally shared, there is little user implication),
>
> OK. JNI infrastructure should belong to avutil at the first place, so hwcontext_mediacodec
> and so on can use it. Unfortunately for those new avpriv_.
What do you mean by "Unfortunately" ? Would you like to make the JNI API
public ?
[...]
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 51+ messages in thread
* Re: [FFmpeg-devel] Add protocol for Android content providers
2024-02-15 7:57 ` Matthieu Bouron
@ 2024-02-15 8:46 ` Zhao Zhili
2024-02-15 9:13 ` Matthieu Bouron
0 siblings, 1 reply; 51+ messages in thread
From: Zhao Zhili @ 2024-02-15 8:46 UTC (permalink / raw)
To: FFmpeg development discussions and patches
> 在 2024年2月15日,下午3:57,Matthieu Bouron <matthieu.bouron@gmail.com> 写道:
>
> On Thu, Feb 15, 2024 at 12:13:59PM +0800, Zhao Zhili wrote:
>>
>>
>>>> On Feb 14, 2024, at 06:50, Matthieu Bouron <matthieu.bouron@gmail.com> wrote:
>>>
>>> Hi,
>>>
>>> On Android, content providers are used for accessing files through shared
>>> mechanisms. One typical case would be an app willing to open a video from
>>> Google Photos, gallery apps, TikTok, Instagram or some other providers.
>>> A content URI looks something like "content://authority/path/id", see:
>>> https://developer.android.com/reference/android/content/ContentUris
>>> https://developer.android.com/guide/topics/providers/content-provider-basics
>>>
>>> It can currently be somehow managed through clumsy means such as using a "fd:"
>>> filename and crafting a special AVOption, which also has the drawback of
>>> requiring the third party to carry around opened file descriptors (with the
>>> multiple opened file limitations implied). Custom AVIOContexts are also an
>>
>> File descriptor is a general abstraction layer, it target more platforms than
>> Android specific content provider. Android provided getFd() API since API
>> level 12, I guess that’s the default method to deal with content provider in
>> native code. It’s a few lines of code to get native fd in Java, but dozens of code
>> in C with JNI, which is what this patchset done.
>>
>> For multiple opened file limitations issue, they can close the file descriptor after
>> open. It’s unlikely to reach the limit in normal case without leak.
>>
>> I’m OK to provide this android_content_protocol helper if user requests.
>
> I've been doing this kind of work for 3/4 users (including myself) at this
> point and have to do it another time, this is what motivated me to propose
> this patchset.
>
>>
>>> option. Both options will have to deal with the JNI though and end users will
>>> have to re-implement the same exact thing.
>>
>> User still need to deal with JNI with the new android_content_protocol, more or
>> less, it’s unavoidable.
>
> The advantage I see of using this protocol is that the user only need to
> call av_jni_set_jvm() + av_jni_set_android_app_ctx() at the start of the
> application and FFmpeg will handle the content-uri transparently. This is
> especially helpful if the Android application rely on multiple libraries
> that in turn rely on FFmpeg to read medias.
The url still need to be passed from Java to C via JNI, it’s not much different compared to pass fd.
>
>>
>>>
>>> This patchset addresses this by adding a content provider protocol, which has
>>> an API fairly similar to fopen. Android 11 appears to provide something
>>> transparent within fopen(), but FFmpeg doesn't use it in the file protocol, and
>>> Android < 11 are still widely used.
>>>
>>> The first part move the JNI infrastructure from avcodec to avutil (it remains
>>> internally shared, there is little user implication),
>>
>> OK. JNI infrastructure should belong to avutil at the first place, so hwcontext_mediacodec
>> and so on can use it. Unfortunately for those new avpriv_.
>
> What do you mean by "Unfortunately" ? Would you like to make the JNI API
> public ?
I think it’s our target to reduce the number of avpriv API, not increase it. Does duplicate the compile unit work in this case so we don’t need to export the symbols?
>
> [...]
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
> To unsubscribe, visit link above, or email
> ffmpeg-devel-request@ffmpeg.org with subject "unsubscri
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 51+ messages in thread
* Re: [FFmpeg-devel] Add protocol for Android content providers
2024-02-15 8:46 ` Zhao Zhili
@ 2024-02-15 9:13 ` Matthieu Bouron
2024-02-24 11:29 ` Matthieu Bouron
0 siblings, 1 reply; 51+ messages in thread
From: Matthieu Bouron @ 2024-02-15 9:13 UTC (permalink / raw)
To: FFmpeg development discussions and patches
Le jeu. 15 févr. 2024, 9:46 AM, Zhao Zhili <quinkblack@foxmail.com> a
écrit :
>
> > 在 2024年2月15日,下午3:57,Matthieu Bouron <matthieu.bouron@gmail.com> 写道:
> >
> > On Thu, Feb 15, 2024 at 12:13:59PM +0800, Zhao Zhili wrote:
> >>
> >>
> >>>> On Feb 14, 2024, at 06:50, Matthieu Bouron <matthieu.bouron@gmail.com>
> wrote:
> >>>
> >>> Hi,
> >>>
> >>> On Android, content providers are used for accessing files through
> shared
> >>> mechanisms. One typical case would be an app willing to open a video
> from
> >>> Google Photos, gallery apps, TikTok, Instagram or some other providers.
> >>> A content URI looks something like "content://authority/path/id", see:
> >>> https://developer.android.com/reference/android/content/ContentUris
> >>>
> https://developer.android.com/guide/topics/providers/content-provider-basics
> >>>
> >>> It can currently be somehow managed through clumsy means such as using
> a "fd:"
> >>> filename and crafting a special AVOption, which also has the drawback
> of
> >>> requiring the third party to carry around opened file descriptors
> (with the
> >>> multiple opened file limitations implied). Custom AVIOContexts are
> also an
> >>
> >> File descriptor is a general abstraction layer, it target more
> platforms than
> >> Android specific content provider. Android provided getFd() API since
> API
> >> level 12, I guess that’s the default method to deal with content
> provider in
> >> native code. It’s a few lines of code to get native fd in Java, but
> dozens of code
> >> in C with JNI, which is what this patchset done.
> >>
> >> For multiple opened file limitations issue, they can close the file
> descriptor after
> >> open. It’s unlikely to reach the limit in normal case without leak.
> >>
> >> I’m OK to provide this android_content_protocol helper if user requests.
> >
> > I've been doing this kind of work for 3/4 users (including myself) at
> this
> > point and have to do it another time, this is what motivated me to
> propose
> > this patchset.
> >
> >>
> >>> option. Both options will have to deal with the JNI though and end
> users will
> >>> have to re-implement the same exact thing.
> >>
> >> User still need to deal with JNI with the new android_content_protocol,
> more or
> >> less, it’s unavoidable.
> >
> > The advantage I see of using this protocol is that the user only need to
> > call av_jni_set_jvm() + av_jni_set_android_app_ctx() at the start of the
> > application and FFmpeg will handle the content-uri transparently. This is
> > especially helpful if the Android application rely on multiple libraries
> > that in turn rely on FFmpeg to read medias.
>
> The url still need to be passed from Java to C via JNI, it’s not much
> different compared to pass fd.
>
It's not that much different I agree. But let's say you have a rendering
engine (in C) where you need to pass hundreds of media (from the user) to
render a scene, each media is used at different time during the rendering.
And Ffmpeg is not a direct dependency and can be called from different
libraries/places used by the rendering engine. Calling
av_jni_set_android_app_ctx() and you're done, you can pass the content URI
to the engine (passing fd at this stage is not an option imho). You still
need to convert the uri from java string to c before calling the c code,
but it's a direct translation which is typically part of a binding.
> >
> >>
> >>>
> >>> This patchset addresses this by adding a content provider protocol,
> which has
> >>> an API fairly similar to fopen. Android 11 appears to provide something
> >>> transparent within fopen(), but FFmpeg doesn't use it in the file
> protocol, and
> >>> Android < 11 are still widely used.
> >>>
> >>> The first part move the JNI infrastructure from avcodec to avutil (it
> remains
> >>> internally shared, there is little user implication),
> >>
> >> OK. JNI infrastructure should belong to avutil at the first place, so
> hwcontext_mediacodec
> >> and so on can use it. Unfortunately for those new avpriv_.
> >
> > What do you mean by "Unfortunately" ? Would you like to make the JNI API
> > public ?
>
> I think it’s our target to reduce the number of avpriv API, not increase
> it. Does duplicate the compile unit work in this case so we don’t need to
> export the symbols?
>
Directly including ffjni.c from libavformat/file.c works. We still need to
pass the application context though (could be added to avcodec/jni.h)
> >
> > [...]
> > _______________________________________________
> > ffmpeg-devel mailing list
> > ffmpeg-devel@ffmpeg.org
> > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
> >
> > To unsubscribe, visit link above, or email
> > ffmpeg-devel-request@ffmpeg.org with subject "unsubscri
>
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
> To unsubscribe, visit link above, or email
> ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
>
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 51+ messages in thread
* Re: [FFmpeg-devel] Add protocol for Android content providers
2024-02-15 9:13 ` Matthieu Bouron
@ 2024-02-24 11:29 ` Matthieu Bouron
2024-02-27 7:17 ` Matthieu Bouron
0 siblings, 1 reply; 51+ messages in thread
From: Matthieu Bouron @ 2024-02-24 11:29 UTC (permalink / raw)
To: FFmpeg development discussions and patches
On Thu, Feb 15, 2024 at 10:13:03AM +0100, Matthieu Bouron wrote:
> Le jeu. 15 févr. 2024, 9:46 AM, Zhao Zhili <quinkblack@foxmail.com> a
> écrit :
>
> >
> > > 在 2024年2月15日,下午3:57,Matthieu Bouron <matthieu.bouron@gmail.com> 写道:
> > >
> > > On Thu, Feb 15, 2024 at 12:13:59PM +0800, Zhao Zhili wrote:
> > >>
> > >>
> > >>>> On Feb 14, 2024, at 06:50, Matthieu Bouron <matthieu.bouron@gmail.com>
> > wrote:
> > >>>
> > >>> Hi,
> > >>>
> > >>> On Android, content providers are used for accessing files through
> > shared
> > >>> mechanisms. One typical case would be an app willing to open a video
> > from
> > >>> Google Photos, gallery apps, TikTok, Instagram or some other providers.
> > >>> A content URI looks something like "content://authority/path/id", see:
> > >>> https://developer.android.com/reference/android/content/ContentUris
> > >>>
> > https://developer.android.com/guide/topics/providers/content-provider-basics
> > >>>
> > >>> It can currently be somehow managed through clumsy means such as using
> > a "fd:"
> > >>> filename and crafting a special AVOption, which also has the drawback
> > of
> > >>> requiring the third party to carry around opened file descriptors
> > (with the
> > >>> multiple opened file limitations implied). Custom AVIOContexts are
> > also an
> > >>
> > >> File descriptor is a general abstraction layer, it target more
> > platforms than
> > >> Android specific content provider. Android provided getFd() API since
> > API
> > >> level 12, I guess that’s the default method to deal with content
> > provider in
> > >> native code. It’s a few lines of code to get native fd in Java, but
> > dozens of code
> > >> in C with JNI, which is what this patchset done.
> > >>
> > >> For multiple opened file limitations issue, they can close the file
> > descriptor after
> > >> open. It’s unlikely to reach the limit in normal case without leak.
> > >>
> > >> I’m OK to provide this android_content_protocol helper if user requests.
> > >
> > > I've been doing this kind of work for 3/4 users (including myself) at
> > this
> > > point and have to do it another time, this is what motivated me to
> > propose
> > > this patchset.
> > >
> > >>
> > >>> option. Both options will have to deal with the JNI though and end
> > users will
> > >>> have to re-implement the same exact thing.
> > >>
> > >> User still need to deal with JNI with the new android_content_protocol,
> > more or
> > >> less, it’s unavoidable.
> > >
> > > The advantage I see of using this protocol is that the user only need to
> > > call av_jni_set_jvm() + av_jni_set_android_app_ctx() at the start of the
> > > application and FFmpeg will handle the content-uri transparently. This is
> > > especially helpful if the Android application rely on multiple libraries
> > > that in turn rely on FFmpeg to read medias.
> >
> > The url still need to be passed from Java to C via JNI, it’s not much
> > different compared to pass fd.
> >
>
> It's not that much different I agree. But let's say you have a rendering
> engine (in C) where you need to pass hundreds of media (from the user) to
> render a scene, each media is used at different time during the rendering.
> And Ffmpeg is not a direct dependency and can be called from different
> libraries/places used by the rendering engine. Calling
> av_jni_set_android_app_ctx() and you're done, you can pass the content URI
> to the engine (passing fd at this stage is not an option imho). You still
> need to convert the uri from java string to c before calling the c code,
> but it's a direct translation which is typically part of a binding.
>
>
>
> > >
> > >>
> > >>>
> > >>> This patchset addresses this by adding a content provider protocol,
> > which has
> > >>> an API fairly similar to fopen. Android 11 appears to provide something
> > >>> transparent within fopen(), but FFmpeg doesn't use it in the file
> > protocol, and
> > >>> Android < 11 are still widely used.
> > >>>
> > >>> The first part move the JNI infrastructure from avcodec to avutil (it
> > remains
> > >>> internally shared, there is little user implication),
> > >>
> > >> OK. JNI infrastructure should belong to avutil at the first place, so
> > hwcontext_mediacodec
> > >> and so on can use it. Unfortunately for those new avpriv_.
> > >
> > > What do you mean by "Unfortunately" ? Would you like to make the JNI API
> > > public ?
> >
> > I think it’s our target to reduce the number of avpriv API, not increase
> > it. Does duplicate the compile unit work in this case so we don’t need to
> > export the symbols?
> >
>
> Directly including ffjni.c from libavformat/file.c works. We still need to
> pass the application context though (could be added to avcodec/jni.h)
So what would be the preferred way forward ? including libavformat/file.c or
migrating the code to avutil (avpriv_*) ?
[...]
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 51+ messages in thread
* Re: [FFmpeg-devel] Add protocol for Android content providers
2024-02-24 11:29 ` Matthieu Bouron
@ 2024-02-27 7:17 ` Matthieu Bouron
2024-02-27 13:14 ` Zhao Zhili
0 siblings, 1 reply; 51+ messages in thread
From: Matthieu Bouron @ 2024-02-27 7:17 UTC (permalink / raw)
To: FFmpeg development discussions and patches
On Sat, Feb 24, 2024 at 12:29:24PM +0100, Matthieu Bouron wrote:
> On Thu, Feb 15, 2024 at 10:13:03AM +0100, Matthieu Bouron wrote:
> > Le jeu. 15 févr. 2024, 9:46 AM, Zhao Zhili <quinkblack@foxmail.com> a
> > écrit :
> >
> > >
> > > > 在 2024年2月15日,下午3:57,Matthieu Bouron <matthieu.bouron@gmail.com> 写道:
> > > >
> > > > On Thu, Feb 15, 2024 at 12:13:59PM +0800, Zhao Zhili wrote:
> > > >>
> > > >>
> > > >>>> On Feb 14, 2024, at 06:50, Matthieu Bouron <matthieu.bouron@gmail.com>
> > > wrote:
> > > >>>
> > > >>> Hi,
> > > >>>
> > > >>> On Android, content providers are used for accessing files through
> > > shared
> > > >>> mechanisms. One typical case would be an app willing to open a video
> > > from
> > > >>> Google Photos, gallery apps, TikTok, Instagram or some other providers.
> > > >>> A content URI looks something like "content://authority/path/id", see:
> > > >>> https://developer.android.com/reference/android/content/ContentUris
> > > >>>
> > > https://developer.android.com/guide/topics/providers/content-provider-basics
> > > >>>
> > > >>> It can currently be somehow managed through clumsy means such as using
> > > a "fd:"
> > > >>> filename and crafting a special AVOption, which also has the drawback
> > > of
> > > >>> requiring the third party to carry around opened file descriptors
> > > (with the
> > > >>> multiple opened file limitations implied). Custom AVIOContexts are
> > > also an
> > > >>
> > > >> File descriptor is a general abstraction layer, it target more
> > > platforms than
> > > >> Android specific content provider. Android provided getFd() API since
> > > API
> > > >> level 12, I guess that’s the default method to deal with content
> > > provider in
> > > >> native code. It’s a few lines of code to get native fd in Java, but
> > > dozens of code
> > > >> in C with JNI, which is what this patchset done.
> > > >>
> > > >> For multiple opened file limitations issue, they can close the file
> > > descriptor after
> > > >> open. It’s unlikely to reach the limit in normal case without leak.
> > > >>
> > > >> I’m OK to provide this android_content_protocol helper if user requests.
> > > >
> > > > I've been doing this kind of work for 3/4 users (including myself) at
> > > this
> > > > point and have to do it another time, this is what motivated me to
> > > propose
> > > > this patchset.
> > > >
> > > >>
> > > >>> option. Both options will have to deal with the JNI though and end
> > > users will
> > > >>> have to re-implement the same exact thing.
> > > >>
> > > >> User still need to deal with JNI with the new android_content_protocol,
> > > more or
> > > >> less, it’s unavoidable.
> > > >
> > > > The advantage I see of using this protocol is that the user only need to
> > > > call av_jni_set_jvm() + av_jni_set_android_app_ctx() at the start of the
> > > > application and FFmpeg will handle the content-uri transparently. This is
> > > > especially helpful if the Android application rely on multiple libraries
> > > > that in turn rely on FFmpeg to read medias.
> > >
> > > The url still need to be passed from Java to C via JNI, it’s not much
> > > different compared to pass fd.
> > >
> >
> > It's not that much different I agree. But let's say you have a rendering
> > engine (in C) where you need to pass hundreds of media (from the user) to
> > render a scene, each media is used at different time during the rendering.
> > And Ffmpeg is not a direct dependency and can be called from different
> > libraries/places used by the rendering engine. Calling
> > av_jni_set_android_app_ctx() and you're done, you can pass the content URI
> > to the engine (passing fd at this stage is not an option imho). You still
> > need to convert the uri from java string to c before calling the c code,
> > but it's a direct translation which is typically part of a binding.
> >
> >
> >
> > > >
> > > >>
> > > >>>
> > > >>> This patchset addresses this by adding a content provider protocol,
> > > which has
> > > >>> an API fairly similar to fopen. Android 11 appears to provide something
> > > >>> transparent within fopen(), but FFmpeg doesn't use it in the file
> > > protocol, and
> > > >>> Android < 11 are still widely used.
> > > >>>
> > > >>> The first part move the JNI infrastructure from avcodec to avutil (it
> > > remains
> > > >>> internally shared, there is little user implication),
> > > >>
> > > >> OK. JNI infrastructure should belong to avutil at the first place, so
> > > hwcontext_mediacodec
> > > >> and so on can use it. Unfortunately for those new avpriv_.
> > > >
> > > > What do you mean by "Unfortunately" ? Would you like to make the JNI API
> > > > public ?
> > >
> > > I think it’s our target to reduce the number of avpriv API, not increase
> > > it. Does duplicate the compile unit work in this case so we don’t need to
> > > export the symbols?
> > >
> >
> > Directly including ffjni.c from libavformat/file.c works. We still need to
> > pass the application context though (could be added to avcodec/jni.h)
>
> So what would be the preferred way forward ? including libavformat/file.c or
> migrating the code to avutil (avpriv_*) ?
Ping (sorry to ping this early, I'd like to not miss the 7.0 window,
especially if we choose the avpriv_ route).
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 51+ messages in thread
* Re: [FFmpeg-devel] Add protocol for Android content providers
2024-02-27 7:17 ` Matthieu Bouron
@ 2024-02-27 13:14 ` Zhao Zhili
2024-02-27 13:19 ` Matthieu Bouron
0 siblings, 1 reply; 51+ messages in thread
From: Zhao Zhili @ 2024-02-27 13:14 UTC (permalink / raw)
To: FFmpeg development discussions and patches
> On Feb 27, 2024, at 15:17, Matthieu Bouron <matthieu.bouron@gmail.com> wrote:
>
> On Sat, Feb 24, 2024 at 12:29:24PM +0100, Matthieu Bouron wrote:
>> On Thu, Feb 15, 2024 at 10:13:03AM +0100, Matthieu Bouron wrote:
>>> Le jeu. 15 févr. 2024, 9:46 AM, Zhao Zhili <quinkblack@foxmail.com> a
>>> écrit :
>>>
>>>>
>>>>> 在 2024年2月15日,下午3:57,Matthieu Bouron <matthieu.bouron@gmail.com> 写道:
>>>>>
>>>>> On Thu, Feb 15, 2024 at 12:13:59PM +0800, Zhao Zhili wrote:
>>>>>>
>>>>>>
>>>>>>>> On Feb 14, 2024, at 06:50, Matthieu Bouron <matthieu.bouron@gmail.com>
>>>> wrote:
>>>>>>>
>>>>>>> Hi,
>>>>>>>
>>>>>>> On Android, content providers are used for accessing files through
>>>> shared
>>>>>>> mechanisms. One typical case would be an app willing to open a video
>>>> from
>>>>>>> Google Photos, gallery apps, TikTok, Instagram or some other providers.
>>>>>>> A content URI looks something like "content://authority/path/id", see:
>>>>>>> https://developer.android.com/reference/android/content/ContentUris
>>>>>>>
>>>> https://developer.android.com/guide/topics/providers/content-provider-basics
>>>>>>>
>>>>>>> It can currently be somehow managed through clumsy means such as using
>>>> a "fd:"
>>>>>>> filename and crafting a special AVOption, which also has the drawback
>>>> of
>>>>>>> requiring the third party to carry around opened file descriptors
>>>> (with the
>>>>>>> multiple opened file limitations implied). Custom AVIOContexts are
>>>> also an
>>>>>>
>>>>>> File descriptor is a general abstraction layer, it target more
>>>> platforms than
>>>>>> Android specific content provider. Android provided getFd() API since
>>>> API
>>>>>> level 12, I guess that’s the default method to deal with content
>>>> provider in
>>>>>> native code. It’s a few lines of code to get native fd in Java, but
>>>> dozens of code
>>>>>> in C with JNI, which is what this patchset done.
>>>>>>
>>>>>> For multiple opened file limitations issue, they can close the file
>>>> descriptor after
>>>>>> open. It’s unlikely to reach the limit in normal case without leak.
>>>>>>
>>>>>> I’m OK to provide this android_content_protocol helper if user requests.
>>>>>
>>>>> I've been doing this kind of work for 3/4 users (including myself) at
>>>> this
>>>>> point and have to do it another time, this is what motivated me to
>>>> propose
>>>>> this patchset.
>>>>>
>>>>>>
>>>>>>> option. Both options will have to deal with the JNI though and end
>>>> users will
>>>>>>> have to re-implement the same exact thing.
>>>>>>
>>>>>> User still need to deal with JNI with the new android_content_protocol,
>>>> more or
>>>>>> less, it’s unavoidable.
>>>>>
>>>>> The advantage I see of using this protocol is that the user only need to
>>>>> call av_jni_set_jvm() + av_jni_set_android_app_ctx() at the start of the
>>>>> application and FFmpeg will handle the content-uri transparently. This is
>>>>> especially helpful if the Android application rely on multiple libraries
>>>>> that in turn rely on FFmpeg to read medias.
>>>>
>>>> The url still need to be passed from Java to C via JNI, it’s not much
>>>> different compared to pass fd.
>>>>
>>>
>>> It's not that much different I agree. But let's say you have a rendering
>>> engine (in C) where you need to pass hundreds of media (from the user) to
>>> render a scene, each media is used at different time during the rendering.
>>> And Ffmpeg is not a direct dependency and can be called from different
>>> libraries/places used by the rendering engine. Calling
>>> av_jni_set_android_app_ctx() and you're done, you can pass the content URI
>>> to the engine (passing fd at this stage is not an option imho). You still
>>> need to convert the uri from java string to c before calling the c code,
>>> but it's a direct translation which is typically part of a binding.
>>>
>>>
>>>
>>>>>
>>>>>>
>>>>>>>
>>>>>>> This patchset addresses this by adding a content provider protocol,
>>>> which has
>>>>>>> an API fairly similar to fopen. Android 11 appears to provide something
>>>>>>> transparent within fopen(), but FFmpeg doesn't use it in the file
>>>> protocol, and
>>>>>>> Android < 11 are still widely used.
>>>>>>>
>>>>>>> The first part move the JNI infrastructure from avcodec to avutil (it
>>>> remains
>>>>>>> internally shared, there is little user implication),
>>>>>>
>>>>>> OK. JNI infrastructure should belong to avutil at the first place, so
>>>> hwcontext_mediacodec
>>>>>> and so on can use it. Unfortunately for those new avpriv_.
>>>>>
>>>>> What do you mean by "Unfortunately" ? Would you like to make the JNI API
>>>>> public ?
>>>>
>>>> I think it’s our target to reduce the number of avpriv API, not increase
>>>> it. Does duplicate the compile unit work in this case so we don’t need to
>>>> export the symbols?
>>>>
>>>
>>> Directly including ffjni.c from libavformat/file.c works. We still need to
>>> pass the application context though (could be added to avcodec/jni.h)
>>
>> So what would be the preferred way forward ? including libavformat/file.c or
>> migrating the code to avutil (avpriv_*) ?
>
> Ping (sorry to ping this early, I'd like to not miss the 7.0 window,
> especially if we choose the avpriv_ route).
I prefer the solution to dup compile unit and use as less avpriv_ as possible.
>
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
> To unsubscribe, visit link above, or email
> ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 51+ messages in thread
* Re: [FFmpeg-devel] Add protocol for Android content providers
2024-02-27 13:14 ` Zhao Zhili
@ 2024-02-27 13:19 ` Matthieu Bouron
0 siblings, 0 replies; 51+ messages in thread
From: Matthieu Bouron @ 2024-02-27 13:19 UTC (permalink / raw)
To: FFmpeg development discussions and patches
On Tue, Feb 27, 2024 at 09:14:04PM +0800, Zhao Zhili wrote:
>
>
> > On Feb 27, 2024, at 15:17, Matthieu Bouron <matthieu.bouron@gmail.com> wrote:
> >
> > On Sat, Feb 24, 2024 at 12:29:24PM +0100, Matthieu Bouron wrote:
> >> On Thu, Feb 15, 2024 at 10:13:03AM +0100, Matthieu Bouron wrote:
> >>> Le jeu. 15 févr. 2024, 9:46 AM, Zhao Zhili <quinkblack@foxmail.com> a
> >>> écrit :
> >>>
> >>>>
> >>>>> 在 2024年2月15日,下午3:57,Matthieu Bouron <matthieu.bouron@gmail.com> 写道:
> >>>>>
> >>>>> On Thu, Feb 15, 2024 at 12:13:59PM +0800, Zhao Zhili wrote:
> >>>>>>
> >>>>>>
> >>>>>>>> On Feb 14, 2024, at 06:50, Matthieu Bouron <matthieu.bouron@gmail.com>
> >>>> wrote:
> >>>>>>>
> >>>>>>> Hi,
> >>>>>>>
> >>>>>>> On Android, content providers are used for accessing files through
> >>>> shared
> >>>>>>> mechanisms. One typical case would be an app willing to open a video
> >>>> from
> >>>>>>> Google Photos, gallery apps, TikTok, Instagram or some other providers.
> >>>>>>> A content URI looks something like "content://authority/path/id", see:
> >>>>>>> https://developer.android.com/reference/android/content/ContentUris
> >>>>>>>
> >>>> https://developer.android.com/guide/topics/providers/content-provider-basics
> >>>>>>>
> >>>>>>> It can currently be somehow managed through clumsy means such as using
> >>>> a "fd:"
> >>>>>>> filename and crafting a special AVOption, which also has the drawback
> >>>> of
> >>>>>>> requiring the third party to carry around opened file descriptors
> >>>> (with the
> >>>>>>> multiple opened file limitations implied). Custom AVIOContexts are
> >>>> also an
> >>>>>>
> >>>>>> File descriptor is a general abstraction layer, it target more
> >>>> platforms than
> >>>>>> Android specific content provider. Android provided getFd() API since
> >>>> API
> >>>>>> level 12, I guess that’s the default method to deal with content
> >>>> provider in
> >>>>>> native code. It’s a few lines of code to get native fd in Java, but
> >>>> dozens of code
> >>>>>> in C with JNI, which is what this patchset done.
> >>>>>>
> >>>>>> For multiple opened file limitations issue, they can close the file
> >>>> descriptor after
> >>>>>> open. It’s unlikely to reach the limit in normal case without leak.
> >>>>>>
> >>>>>> I’m OK to provide this android_content_protocol helper if user requests.
> >>>>>
> >>>>> I've been doing this kind of work for 3/4 users (including myself) at
> >>>> this
> >>>>> point and have to do it another time, this is what motivated me to
> >>>> propose
> >>>>> this patchset.
> >>>>>
> >>>>>>
> >>>>>>> option. Both options will have to deal with the JNI though and end
> >>>> users will
> >>>>>>> have to re-implement the same exact thing.
> >>>>>>
> >>>>>> User still need to deal with JNI with the new android_content_protocol,
> >>>> more or
> >>>>>> less, it’s unavoidable.
> >>>>>
> >>>>> The advantage I see of using this protocol is that the user only need to
> >>>>> call av_jni_set_jvm() + av_jni_set_android_app_ctx() at the start of the
> >>>>> application and FFmpeg will handle the content-uri transparently. This is
> >>>>> especially helpful if the Android application rely on multiple libraries
> >>>>> that in turn rely on FFmpeg to read medias.
> >>>>
> >>>> The url still need to be passed from Java to C via JNI, it’s not much
> >>>> different compared to pass fd.
> >>>>
> >>>
> >>> It's not that much different I agree. But let's say you have a rendering
> >>> engine (in C) where you need to pass hundreds of media (from the user) to
> >>> render a scene, each media is used at different time during the rendering.
> >>> And Ffmpeg is not a direct dependency and can be called from different
> >>> libraries/places used by the rendering engine. Calling
> >>> av_jni_set_android_app_ctx() and you're done, you can pass the content URI
> >>> to the engine (passing fd at this stage is not an option imho). You still
> >>> need to convert the uri from java string to c before calling the c code,
> >>> but it's a direct translation which is typically part of a binding.
> >>>
> >>>
> >>>
> >>>>>
> >>>>>>
> >>>>>>>
> >>>>>>> This patchset addresses this by adding a content provider protocol,
> >>>> which has
> >>>>>>> an API fairly similar to fopen. Android 11 appears to provide something
> >>>>>>> transparent within fopen(), but FFmpeg doesn't use it in the file
> >>>> protocol, and
> >>>>>>> Android < 11 are still widely used.
> >>>>>>>
> >>>>>>> The first part move the JNI infrastructure from avcodec to avutil (it
> >>>> remains
> >>>>>>> internally shared, there is little user implication),
> >>>>>>
> >>>>>> OK. JNI infrastructure should belong to avutil at the first place, so
> >>>> hwcontext_mediacodec
> >>>>>> and so on can use it. Unfortunately for those new avpriv_.
> >>>>>
> >>>>> What do you mean by "Unfortunately" ? Would you like to make the JNI API
> >>>>> public ?
> >>>>
> >>>> I think it’s our target to reduce the number of avpriv API, not increase
> >>>> it. Does duplicate the compile unit work in this case so we don’t need to
> >>>> export the symbols?
> >>>>
> >>>
> >>> Directly including ffjni.c from libavformat/file.c works. We still need to
> >>> pass the application context though (could be added to avcodec/jni.h)
> >>
> >> So what would be the preferred way forward ? including libavformat/file.c or
> >> migrating the code to avutil (avpriv_*) ?
> >
> > Ping (sorry to ping this early, I'd like to not miss the 7.0 window,
> > especially if we choose the avpriv_ route).
>
> I prefer the solution to dup compile unit and use as less avpriv_ as possible.
Thanks. I'll adjust the patchset accordingly.
[...]
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 51+ messages in thread
* Re: [FFmpeg-devel] [PATCH 2/7] avutil: add av_jni_{get, set}_android_app_ctx helper
2024-02-13 22:50 ` [FFmpeg-devel] [PATCH 2/7] avutil: add av_jni_{get, set}_android_app_ctx helper Matthieu Bouron
@ 2024-02-27 13:42 ` Andreas Rheinhardt
2024-02-27 14:46 ` Matthieu Bouron
0 siblings, 1 reply; 51+ messages in thread
From: Andreas Rheinhardt @ 2024-02-27 13:42 UTC (permalink / raw)
To: ffmpeg-devel
Matthieu Bouron:
> This will allow users to pass the Android ApplicationContext which is mandatory
> to retrieve the ContentResolver responsible to resolve/open Android content-uri.
> ---
> libavutil/jni.c | 28 ++++++++++++++++++++++++++++
> libavutil/jni.h | 17 +++++++++++++++++
> 2 files changed, 45 insertions(+)
>
> diff --git a/libavutil/jni.c b/libavutil/jni.c
> index 541747cb20..d6f96717b0 100644
> --- a/libavutil/jni.c
> +++ b/libavutil/jni.c
> @@ -34,6 +34,7 @@
> #include "libavutil/jni.h"
>
> static void *java_vm;
> +static void *android_app_ctx;
> static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
>
> int av_jni_set_jvm(void *vm, void *log_ctx)
> @@ -63,6 +64,24 @@ void *av_jni_get_jvm(void *log_ctx)
> return vm;
> }
>
> +void av_jni_set_android_app_ctx(void *app_ctx)
> +{
> + pthread_mutex_lock(&lock);
> + android_app_ctx = app_ctx;
> + pthread_mutex_unlock(&lock);
> +}
> +
> +void *av_jni_get_android_app_ctx(void)
> +{
> + void *ctx;
> +
> + pthread_mutex_lock(&lock);
> + ctx = android_app_ctx;
> + pthread_mutex_unlock(&lock);
> +
> + return ctx;
> +}
> +
> #else
>
> int av_jni_set_java_vm(void *vm, void *log_ctx)
> @@ -75,4 +94,13 @@ void *av_jni_get_java_vm(void *log_ctx)
> return NULL;
> }
>
> +void av_jni_set_android_app_ctx(void *app_ctx)
> +{
> +}
> +
> +void *av_jni_get_android_app_ctx(void)
> +{
> + return NULL;
> +}
> +
> #endif
> diff --git a/libavutil/jni.h b/libavutil/jni.h
> index 700960dbb8..630f4074a1 100644
> --- a/libavutil/jni.h
> +++ b/libavutil/jni.h
> @@ -43,4 +43,21 @@ int av_jni_set_jvm(void *vm, void *log_ctx);
> */
> void *av_jni_get_jvm(void *log_ctx);
>
> +/*
> + * Set the Android application context which will be used to retrieve the Android
> + * content resolver to resolve content uris.
> + *
> + * @param app_ctx global JNI reference to the Android application context
> + */
> +void av_jni_set_android_app_ctx(void *app_ctx);
> +
> +/*
> + * Get the Android application context that has been set with
> + * av_jni_set_android_app_ctx.
> + *
> + * @return a pointer the the Android application context
> + */
> +void *av_jni_get_android_app_ctx(void);
> +
> +
> #endif /* AVUTIL_JNI_H */
This adds global state in order to pass the application context to your
protocol (in lieu of an option to pass pointers to a protocol). Can
there be scenarios in which multiple application contexts are useful in
the same process?
- Andreas
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 51+ messages in thread
* Re: [FFmpeg-devel] [PATCH 2/7] avutil: add av_jni_{get, set}_android_app_ctx helper
2024-02-27 13:42 ` Andreas Rheinhardt
@ 2024-02-27 14:46 ` Matthieu Bouron
0 siblings, 0 replies; 51+ messages in thread
From: Matthieu Bouron @ 2024-02-27 14:46 UTC (permalink / raw)
To: FFmpeg development discussions and patches
On Tue, Feb 27, 2024 at 02:42:01PM +0100, Andreas Rheinhardt wrote:
> Matthieu Bouron:
> > This will allow users to pass the Android ApplicationContext which is mandatory
> > to retrieve the ContentResolver responsible to resolve/open Android content-uri.
> > ---
> > libavutil/jni.c | 28 ++++++++++++++++++++++++++++
> > libavutil/jni.h | 17 +++++++++++++++++
> > 2 files changed, 45 insertions(+)
> >
> > diff --git a/libavutil/jni.c b/libavutil/jni.c
> > index 541747cb20..d6f96717b0 100644
> > --- a/libavutil/jni.c
> > +++ b/libavutil/jni.c
> > @@ -34,6 +34,7 @@
> > #include "libavutil/jni.h"
> >
> > static void *java_vm;
> > +static void *android_app_ctx;
> > static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
> >
> > int av_jni_set_jvm(void *vm, void *log_ctx)
> > @@ -63,6 +64,24 @@ void *av_jni_get_jvm(void *log_ctx)
> > return vm;
> > }
> >
> > +void av_jni_set_android_app_ctx(void *app_ctx)
> > +{
> > + pthread_mutex_lock(&lock);
> > + android_app_ctx = app_ctx;
> > + pthread_mutex_unlock(&lock);
> > +}
> > +
> > +void *av_jni_get_android_app_ctx(void)
> > +{
> > + void *ctx;
> > +
> > + pthread_mutex_lock(&lock);
> > + ctx = android_app_ctx;
> > + pthread_mutex_unlock(&lock);
> > +
> > + return ctx;
> > +}
> > +
> > #else
> >
> > int av_jni_set_java_vm(void *vm, void *log_ctx)
> > @@ -75,4 +94,13 @@ void *av_jni_get_java_vm(void *log_ctx)
> > return NULL;
> > }
> >
> > +void av_jni_set_android_app_ctx(void *app_ctx)
> > +{
> > +}
> > +
> > +void *av_jni_get_android_app_ctx(void)
> > +{
> > + return NULL;
> > +}
> > +
> > #endif
> > diff --git a/libavutil/jni.h b/libavutil/jni.h
> > index 700960dbb8..630f4074a1 100644
> > --- a/libavutil/jni.h
> > +++ b/libavutil/jni.h
> > @@ -43,4 +43,21 @@ int av_jni_set_jvm(void *vm, void *log_ctx);
> > */
> > void *av_jni_get_jvm(void *log_ctx);
> >
> > +/*
> > + * Set the Android application context which will be used to retrieve the Android
> > + * content resolver to resolve content uris.
> > + *
> > + * @param app_ctx global JNI reference to the Android application context
> > + */
> > +void av_jni_set_android_app_ctx(void *app_ctx);
> > +
> > +/*
> > + * Get the Android application context that has been set with
> > + * av_jni_set_android_app_ctx.
> > + *
> > + * @return a pointer the the Android application context
> > + */
> > +void *av_jni_get_android_app_ctx(void);
> > +
> > +
> > #endif /* AVUTIL_JNI_H */
>
> This adds global state in order to pass the application context to your
> protocol (in lieu of an option to pass pointers to a protocol). Can
> there be scenarios in which multiple application contexts are useful in
> the same process?
This is intended. In general, there is only one application context that
lives for the entire application lifetime. I don't think there is any
useful scenario where multiple application contexts are useful (and I
haven't encountered any), even while unit testing (where you can easily
craft multiple application contexts).
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 51+ messages in thread
* [FFmpeg-devel] Add protocol for Android content providers (v2)
2024-02-13 22:50 [FFmpeg-devel] Add protocol for Android content providers Matthieu Bouron
` (7 preceding siblings ...)
2024-02-15 4:13 ` [FFmpeg-devel] Add protocol for Android content providers Zhao Zhili
@ 2024-02-27 14:50 ` Matthieu Bouron
2024-02-27 14:50 ` [FFmpeg-devel] [PATCH v2 1/6] avcodec: add av_jni_{get, set}_android_app_ctx helper Matthieu Bouron
` (7 more replies)
8 siblings, 8 replies; 51+ messages in thread
From: Matthieu Bouron @ 2024-02-27 14:50 UTC (permalink / raw)
To: ffmpeg-devel
Diff from initial patchset:
- directly include libavcodec/ffjni.c from libavformat/file.c instead of
migrating ffjni to libavutil (avpriv_*)
- check that the passed application context reference is a global one and error
out if it's not the case
--
Matthieu
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 51+ messages in thread
* [FFmpeg-devel] [PATCH v2 1/6] avcodec: add av_jni_{get, set}_android_app_ctx helper
2024-02-27 14:50 ` [FFmpeg-devel] Add protocol for Android content providers (v2) Matthieu Bouron
@ 2024-02-27 14:50 ` Matthieu Bouron
2024-03-04 11:30 ` Andreas Rheinhardt
2024-02-27 14:50 ` [FFmpeg-devel] [PATCH v2 2/6] avformat: add Android content resolver protocol support Matthieu Bouron
` (6 subsequent siblings)
7 siblings, 1 reply; 51+ messages in thread
From: Matthieu Bouron @ 2024-02-27 14:50 UTC (permalink / raw)
To: ffmpeg-devel; +Cc: Matthieu Bouron
This will allow users to pass the Android ApplicationContext which is mandatory
to retrieve the ContentResolver responsible to resolve/open Android content-uri.
---
libavcodec/jni.c | 40 ++++++++++++++++++++++++++++++++++++++++
libavcodec/jni.h | 17 +++++++++++++++++
2 files changed, 57 insertions(+)
diff --git a/libavcodec/jni.c b/libavcodec/jni.c
index ae6490de9d..7d04d0a268 100644
--- a/libavcodec/jni.c
+++ b/libavcodec/jni.c
@@ -64,6 +64,36 @@ void *av_jni_get_java_vm(void *log_ctx)
return vm;
}
+int av_jni_set_android_app_ctx(void *app_ctx, void *log_ctx)
+{
+ JNIEnv *env = avpriv_jni_get_env(c);
+ if (!env)
+ return AVERROR(EINVAL);
+
+ jobjectRefType type = (*env)->GetObjectRefType(env, app_ctx);
+ if (type != JNIGlobalRefType) {
+ av_log(log_ctx, AV_LOG_ERROR, "Application context must be passed as a global reference");
+ return AVERROR(EINVAL);
+ }
+
+ pthread_mutex_lock(&lock);
+ android_app_ctx = app_ctx;
+ pthread_mutex_unlock(&lock);
+
+ return 0;
+}
+
+void *av_jni_get_android_app_ctx(void)
+{
+ void *ctx;
+
+ pthread_mutex_lock(&lock);
+ ctx = android_app_ctx;
+ pthread_mutex_unlock(&lock);
+
+ return ctx;
+}
+
#else
int av_jni_set_java_vm(void *vm, void *log_ctx)
@@ -76,4 +106,14 @@ void *av_jni_get_java_vm(void *log_ctx)
return NULL;
}
+int av_jni_set_android_app_ctx(void *app_ctx, void *log_ctx)
+{
+ return AVERROR(ENOSYS);
+}
+
+void *av_jni_get_android_app_ctx(void)
+{
+ return NULL;
+}
+
#endif
diff --git a/libavcodec/jni.h b/libavcodec/jni.h
index dd99e92611..da8025f830 100644
--- a/libavcodec/jni.h
+++ b/libavcodec/jni.h
@@ -43,4 +43,21 @@ int av_jni_set_java_vm(void *vm, void *log_ctx);
*/
void *av_jni_get_java_vm(void *log_ctx);
+/*
+ * Set the Android application context which will be used to retrieve the Android
+ * content resolver to resolve content uris.
+ *
+ * @param app_ctx global JNI reference to the Android application context
+ * @return 0 on success, < 0 otherwise
+ */
+int av_jni_set_android_app_ctx(void *app_ctx, void *log_ctx);
+
+/*
+ * Get the Android application context that has been set with
+ * av_jni_set_android_app_ctx.
+ *
+ * @return a pointer the the Android application context
+ */
+void *av_jni_get_android_app_ctx(void);
+
#endif /* AVCODEC_JNI_H */
--
2.44.0
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 51+ messages in thread
* [FFmpeg-devel] [PATCH v2 2/6] avformat: add Android content resolver protocol support
2024-02-27 14:50 ` [FFmpeg-devel] Add protocol for Android content providers (v2) Matthieu Bouron
2024-02-27 14:50 ` [FFmpeg-devel] [PATCH v2 1/6] avcodec: add av_jni_{get, set}_android_app_ctx helper Matthieu Bouron
@ 2024-02-27 14:50 ` Matthieu Bouron
2024-03-04 19:37 ` Matthieu Bouron
2024-02-27 14:50 ` [FFmpeg-devel] [PATCH v2 3/6] avutil/jni: use size_t to store structure offsets Matthieu Bouron
` (5 subsequent siblings)
7 siblings, 1 reply; 51+ messages in thread
From: Matthieu Bouron @ 2024-02-27 14:50 UTC (permalink / raw)
To: ffmpeg-devel; +Cc: Matthieu Bouron
Handles Android content-uri starting with content://.
---
configure | 2 +
doc/APIchanges | 3 +
libavcodec/jni.c | 3 +-
libavformat/Makefile | 1 +
libavformat/file.c | 157 ++++++++++++++++++++++++++++++++++++++++
libavformat/protocols.c | 1 +
6 files changed, 166 insertions(+), 1 deletion(-)
diff --git a/configure b/configure
index bb5e630bad..790a1df7c8 100755
--- a/configure
+++ b/configure
@@ -3655,6 +3655,8 @@ xcbgrab_indev_suggest="libxcb_shm libxcb_shape libxcb_xfixes"
xv_outdev_deps="xlib_xv xlib_x11 xlib_xext"
# protocols
+android_content_protocol_deps="jni"
+android_content_protocol_select="file_protocol"
async_protocol_deps="threads"
bluray_protocol_deps="libbluray"
ffrtmpcrypt_protocol_conflict="librtmp_protocol"
diff --git a/doc/APIchanges b/doc/APIchanges
index 10f6667e9e..258e953ca6 100644
--- a/doc/APIchanges
+++ b/doc/APIchanges
@@ -2,6 +2,9 @@ The last version increases of all libraries were on 2023-02-09
API changes, most recent first:
+2024-02-xx - xxxxxxxxxx - lavc 60.41.100 - jni.h
+ Add av_jni_set_android_app_ctx() and av_jni_get_android_app_ctx().
+
2024-02-26 - xxxxxxxxxx - lavf 60.22.101 - avformat.h
AV_DISPOSITION_DEPENDENT may now also be used for video streams
intended to be merged with other video streams for presentation.
diff --git a/libavcodec/jni.c b/libavcodec/jni.c
index 7d04d0a268..5a75d97f19 100644
--- a/libavcodec/jni.c
+++ b/libavcodec/jni.c
@@ -35,6 +35,7 @@
#include "ffjni.h"
static void *java_vm;
+static void *android_app_ctx;
static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
int av_jni_set_java_vm(void *vm, void *log_ctx)
@@ -66,7 +67,7 @@ void *av_jni_get_java_vm(void *log_ctx)
int av_jni_set_android_app_ctx(void *app_ctx, void *log_ctx)
{
- JNIEnv *env = avpriv_jni_get_env(c);
+ JNIEnv *env = ff_jni_get_env(log_ctx);
if (!env)
return AVERROR(EINVAL);
diff --git a/libavformat/Makefile b/libavformat/Makefile
index 4a380668bd..08fe98a535 100644
--- a/libavformat/Makefile
+++ b/libavformat/Makefile
@@ -657,6 +657,7 @@ OBJS-$(CONFIG_LIBOPENMPT_DEMUXER) += libopenmpt.o
OBJS-$(CONFIG_VAPOURSYNTH_DEMUXER) += vapoursynth.o
# protocols I/O
+OBJS-$(CONFIG_ANDROID_CONTENT_PROTOCOL) += file.o
OBJS-$(CONFIG_ASYNC_PROTOCOL) += async.o
OBJS-$(CONFIG_APPLEHTTP_PROTOCOL) += hlsproto.o
OBJS-$(CONFIG_BLURAY_PROTOCOL) += bluray.o
diff --git a/libavformat/file.c b/libavformat/file.c
index 64df7ff6fb..1b2b69f090 100644
--- a/libavformat/file.c
+++ b/libavformat/file.c
@@ -40,6 +40,12 @@
#include <stdlib.h>
#include "os_support.h"
#include "url.h"
+#if CONFIG_ANDROID_CONTENT_PROTOCOL
+#include <jni.h>
+#include "libavcodec/jni.h"
+#include "libavcodec/ffjni.c"
+#endif
+
/* Some systems may not have S_ISFIFO */
#ifndef S_ISFIFO
@@ -101,6 +107,21 @@ typedef struct FileContext {
int64_t initial_pos;
} FileContext;
+
+#if CONFIG_ANDROID_CONTENT_PROTOCOL
+static const AVOption android_content_options[] = {
+ { "blocksize", "set I/O operation maximum block size", offsetof(FileContext, blocksize), AV_OPT_TYPE_INT, { .i64 = INT_MAX }, 1, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM },
+ { NULL }
+};
+
+static const AVClass android_content_class = {
+ .class_name = "android_content",
+ .item_name = av_default_item_name,
+ .option = android_content_options,
+ .version = LIBAVUTIL_VERSION_INT,
+};
+#endif
+
static const AVOption file_options[] = {
{ "truncate", "truncate existing files on write", offsetof(FileContext, trunc), AV_OPT_TYPE_BOOL, { .i64 = 1 }, 0, 1, AV_OPT_FLAG_ENCODING_PARAM },
{ "blocksize", "set I/O operation maximum block size", offsetof(FileContext, blocksize), AV_OPT_TYPE_INT, { .i64 = INT_MAX }, 1, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM },
@@ -524,3 +545,139 @@ const URLProtocol ff_fd_protocol = {
};
#endif /* CONFIG_FD_PROTOCOL */
+
+#if CONFIG_ANDROID_CONTENT_PROTOCOL
+
+struct JFields {
+ jclass uri_class;
+ jmethodID parse_id;
+
+ jclass context_class;
+ jmethodID get_content_resolver_id;
+
+ jclass content_resolver_class;
+ jmethodID open_file_descriptor_id;
+
+ jclass parcel_file_descriptor_class;
+ jmethodID detach_fd_id;
+};
+
+#define OFFSET(x) offsetof(struct JFields, x)
+static const struct FFJniField jfields_mapping[] = {
+ { "android/net/Uri", NULL, NULL, FF_JNI_CLASS, OFFSET(uri_class), 1 },
+ { "android/net/Uri", "parse", "(Ljava/lang/String;)Landroid/net/Uri;", FF_JNI_STATIC_METHOD, OFFSET(parse_id), 1 },
+
+ { "android/content/Context", NULL, NULL, FF_JNI_CLASS, OFFSET(context_class), 1 },
+ { "android/content/Context", "getContentResolver", "()Landroid/content/ContentResolver;", FF_JNI_METHOD, OFFSET(get_content_resolver_id), 1 },
+
+ { "android/content/ContentResolver", NULL, NULL, FF_JNI_CLASS, OFFSET(content_resolver_class), 1 },
+ { "android/content/ContentResolver", "openFileDescriptor", "(Landroid/net/Uri;Ljava/lang/String;)Landroid/os/ParcelFileDescriptor;", FF_JNI_METHOD, OFFSET(open_file_descriptor_id), 1 },
+
+ { "android/os/ParcelFileDescriptor", NULL, NULL, FF_JNI_CLASS, OFFSET(parcel_file_descriptor_class), 1 },
+ { "android/os/ParcelFileDescriptor", "detachFd", "()I", FF_JNI_METHOD, OFFSET(detach_fd_id), 1 },
+
+ { NULL }
+};
+#undef OFFSET
+
+static int android_content_open(URLContext *h, const char *filename, int flags)
+{
+ FileContext *c = h->priv_data;
+ int fd, ret;
+ const char *mode_str = "r";
+
+ JNIEnv *env;
+ struct JFields jfields = { 0 };
+ jobject application_context = NULL;
+ jobject url = NULL;
+ jobject mode = NULL;
+ jobject uri = NULL;
+ jobject content_resolver = NULL;
+ jobject parcel_file_descriptor = NULL;
+
+ env = ff_jni_get_env(c);
+ if (!env) {
+ return AVERROR(EINVAL);
+ }
+
+ ret = ff_jni_init_jfields(env, &jfields, jfields_mapping, 0, c);
+ if (ret < 0) {
+ av_log(c, AV_LOG_ERROR, "failed to initialize jni fields\n");
+ return ret;
+ }
+
+ application_context = av_jni_get_android_app_ctx();
+ if (!application_context) {
+ av_log(c, AV_LOG_ERROR, "application context is not set\n");
+ ret = AVERROR_EXTERNAL;
+ goto done;
+ }
+
+ url = ff_jni_utf_chars_to_jstring(env, filename, c);
+ if (!url) {
+ ret = AVERROR_EXTERNAL;
+ goto done;
+ }
+
+ if (flags & AVIO_FLAG_WRITE && flags & AVIO_FLAG_READ)
+ mode_str = "rw";
+ else if (flags & AVIO_FLAG_WRITE)
+ mode_str = "w";
+
+ mode = ff_jni_utf_chars_to_jstring(env, mode_str, c);
+ if (!mode) {
+ ret = AVERROR_EXTERNAL;
+ goto done;
+ }
+
+ uri = (*env)->CallStaticObjectMethod(env, jfields.uri_class, jfields.parse_id, url);
+ ret = ff_jni_exception_check(env, 1, c);
+ if (ret < 0)
+ goto done;
+
+ content_resolver = (*env)->CallObjectMethod(env, application_context, jfields.get_content_resolver_id);
+ ret = ff_jni_exception_check(env, 1, c);
+ if (ret < 0)
+ goto done;
+
+ parcel_file_descriptor = (*env)->CallObjectMethod(env, content_resolver, jfields.open_file_descriptor_id, uri, mode);
+ ret = ff_jni_exception_check(env, 1, c);
+ if (ret < 0)
+ goto done;
+
+ fd = (*env)->CallIntMethod(env, parcel_file_descriptor, jfields.detach_fd_id);
+ ret = ff_jni_exception_check(env, 1, c);
+ if (ret < 0)
+ goto done;
+
+#if HAVE_SETMODE
+ setmode(fd, O_BINARY);
+#endif
+ c->fd = fd;
+ h->is_streamed = 0;
+
+done:
+ (*env)->DeleteLocalRef(env, url);
+ (*env)->DeleteLocalRef(env, mode);
+ (*env)->DeleteLocalRef(env, uri);
+ (*env)->DeleteLocalRef(env, content_resolver);
+ (*env)->DeleteLocalRef(env, parcel_file_descriptor);
+ ff_jni_reset_jfields(env, &jfields, jfields_mapping, 0, c);
+
+ return ret;
+}
+
+URLProtocol ff_android_content_protocol = {
+ .name = "content",
+ .url_open = android_content_open,
+ .url_read = file_read,
+ .url_write = file_write,
+ .url_seek = file_seek,
+ .url_close = file_close,
+ .url_get_file_handle = file_get_handle,
+ .url_check = NULL,
+ .priv_data_size = sizeof(FileContext),
+ .priv_data_class = &android_content_class,
+};
+
+#endif /* CONFIG_ANDROID_CONTENT_PROTOCOL */
diff --git a/libavformat/protocols.c b/libavformat/protocols.c
index 360018b17c..93a6d67261 100644
--- a/libavformat/protocols.c
+++ b/libavformat/protocols.c
@@ -24,6 +24,7 @@
#include "url.h"
+extern const URLProtocol ff_android_content_protocol;
extern const URLProtocol ff_async_protocol;
extern const URLProtocol ff_bluray_protocol;
extern const URLProtocol ff_cache_protocol;
--
2.44.0
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 51+ messages in thread
* [FFmpeg-devel] [PATCH v2 3/6] avutil/jni: use size_t to store structure offsets
2024-02-27 14:50 ` [FFmpeg-devel] Add protocol for Android content providers (v2) Matthieu Bouron
2024-02-27 14:50 ` [FFmpeg-devel] [PATCH v2 1/6] avcodec: add av_jni_{get, set}_android_app_ctx helper Matthieu Bouron
2024-02-27 14:50 ` [FFmpeg-devel] [PATCH v2 2/6] avformat: add Android content resolver protocol support Matthieu Bouron
@ 2024-02-27 14:50 ` Matthieu Bouron
2024-03-04 20:10 ` Andreas Rheinhardt
2024-02-27 14:50 ` [FFmpeg-devel] [PATCH v2 4/6] avutil/jni: remove unnecessary NULL checks before calling DeleteLocalRef() Matthieu Bouron
` (4 subsequent siblings)
7 siblings, 1 reply; 51+ messages in thread
From: Matthieu Bouron @ 2024-02-27 14:50 UTC (permalink / raw)
To: ffmpeg-devel; +Cc: Matthieu Bouron
---
libavcodec/ffjni.h | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/libavcodec/ffjni.h b/libavcodec/ffjni.h
index 6027bac0ab..d5894609ed 100644
--- a/libavcodec/ffjni.h
+++ b/libavcodec/ffjni.h
@@ -24,6 +24,7 @@
#define AVCODEC_FFJNI_H
#include <jni.h>
+#include <stdlib.h>
/*
* Attach permanently a JNI environment to the current thread and retrieve it.
@@ -105,7 +106,7 @@ struct FFJniField {
const char *method;
const char *signature;
enum FFJniFieldType type;
- int offset;
+ size_t offset;
int mandatory;
};
--
2.44.0
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 51+ messages in thread
* [FFmpeg-devel] [PATCH v2 4/6] avutil/jni: remove unnecessary NULL checks before calling DeleteLocalRef()
2024-02-27 14:50 ` [FFmpeg-devel] Add protocol for Android content providers (v2) Matthieu Bouron
` (2 preceding siblings ...)
2024-02-27 14:50 ` [FFmpeg-devel] [PATCH v2 3/6] avutil/jni: use size_t to store structure offsets Matthieu Bouron
@ 2024-02-27 14:50 ` Matthieu Bouron
2024-02-27 14:50 ` [FFmpeg-devel] [PATCH v2 5/6] avcodec/mediacodec_wrapper: use an OFFSET() macro where relevant Matthieu Bouron
` (3 subsequent siblings)
7 siblings, 0 replies; 51+ messages in thread
From: Matthieu Bouron @ 2024-02-27 14:50 UTC (permalink / raw)
To: ffmpeg-devel; +Cc: Matthieu Bouron
Delete{Global,Local}Ref() already handle NULL.
---
libavcodec/ffjni.c | 14 +++-----------
1 file changed, 3 insertions(+), 11 deletions(-)
diff --git a/libavcodec/ffjni.c b/libavcodec/ffjni.c
index e3cf24d3e2..69d9a9faa3 100644
--- a/libavcodec/ffjni.c
+++ b/libavcodec/ffjni.c
@@ -236,17 +236,9 @@ done:
av_free(name);
av_free(message);
- if (class_class) {
- (*env)->DeleteLocalRef(env, class_class);
- }
-
- if (exception_class) {
- (*env)->DeleteLocalRef(env, exception_class);
- }
-
- if (string) {
- (*env)->DeleteLocalRef(env, string);
- }
+ (*env)->DeleteLocalRef(env, class_class);
+ (*env)->DeleteLocalRef(env, exception_class);
+ (*env)->DeleteLocalRef(env, string);
return ret;
}
--
2.44.0
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 51+ messages in thread
* [FFmpeg-devel] [PATCH v2 5/6] avcodec/mediacodec_wrapper: use an OFFSET() macro where relevant
2024-02-27 14:50 ` [FFmpeg-devel] Add protocol for Android content providers (v2) Matthieu Bouron
` (3 preceding siblings ...)
2024-02-27 14:50 ` [FFmpeg-devel] [PATCH v2 4/6] avutil/jni: remove unnecessary NULL checks before calling DeleteLocalRef() Matthieu Bouron
@ 2024-02-27 14:50 ` Matthieu Bouron
2024-02-27 14:50 ` [FFmpeg-devel] [PATCH v2 6/6] avcodec/mediacodec_wrapper: remove unnecessary NULL checks before calling Delete{Global, Local}Ref() Matthieu Bouron
` (2 subsequent siblings)
7 siblings, 0 replies; 51+ messages in thread
From: Matthieu Bouron @ 2024-02-27 14:50 UTC (permalink / raw)
To: ffmpeg-devel; +Cc: Matthieu Bouron
Reduces a bit the horizontal spacing.
---
libavcodec/mediacodec_wrapper.c | 138 +++++++++++++++++---------------
1 file changed, 72 insertions(+), 66 deletions(-)
diff --git a/libavcodec/mediacodec_wrapper.c b/libavcodec/mediacodec_wrapper.c
index 0880ddd3ef..78cd28f53d 100644
--- a/libavcodec/mediacodec_wrapper.c
+++ b/libavcodec/mediacodec_wrapper.c
@@ -60,31 +60,33 @@ struct JNIAMediaCodecListFields {
jfieldID level_id;
};
+#define OFFSET(x) offsetof(struct JNIAMediaCodecListFields, x)
static const struct FFJniField jni_amediacodeclist_mapping[] = {
- { "android/media/MediaCodecList", NULL, NULL, FF_JNI_CLASS, offsetof(struct JNIAMediaCodecListFields, mediacodec_list_class), 1 },
- { "android/media/MediaCodecList", "<init>", "(I)V", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecListFields, init_id), 0 },
- { "android/media/MediaCodecList", "findDecoderForFormat", "(Landroid/media/MediaFormat;)Ljava/lang/String;", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecListFields, find_decoder_for_format_id), 0 },
+ { "android/media/MediaCodecList", NULL, NULL, FF_JNI_CLASS, OFFSET(mediacodec_list_class), 1 },
+ { "android/media/MediaCodecList", "<init>", "(I)V", FF_JNI_METHOD, OFFSET(init_id), 0 },
+ { "android/media/MediaCodecList", "findDecoderForFormat", "(Landroid/media/MediaFormat;)Ljava/lang/String;", FF_JNI_METHOD, OFFSET(find_decoder_for_format_id), 0 },
- { "android/media/MediaCodecList", "getCodecCount", "()I", FF_JNI_STATIC_METHOD, offsetof(struct JNIAMediaCodecListFields, get_codec_count_id), 1 },
- { "android/media/MediaCodecList", "getCodecInfoAt", "(I)Landroid/media/MediaCodecInfo;", FF_JNI_STATIC_METHOD, offsetof(struct JNIAMediaCodecListFields, get_codec_info_at_id), 1 },
+ { "android/media/MediaCodecList", "getCodecCount", "()I", FF_JNI_STATIC_METHOD, OFFSET(get_codec_count_id), 1 },
+ { "android/media/MediaCodecList", "getCodecInfoAt", "(I)Landroid/media/MediaCodecInfo;", FF_JNI_STATIC_METHOD, OFFSET(get_codec_info_at_id), 1 },
- { "android/media/MediaCodecInfo", NULL, NULL, FF_JNI_CLASS, offsetof(struct JNIAMediaCodecListFields, mediacodec_info_class), 1 },
- { "android/media/MediaCodecInfo", "getName", "()Ljava/lang/String;", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecListFields, get_name_id), 1 },
- { "android/media/MediaCodecInfo", "getCapabilitiesForType", "(Ljava/lang/String;)Landroid/media/MediaCodecInfo$CodecCapabilities;", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecListFields, get_codec_capabilities_id), 1 },
- { "android/media/MediaCodecInfo", "getSupportedTypes", "()[Ljava/lang/String;", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecListFields, get_supported_types_id), 1 },
- { "android/media/MediaCodecInfo", "isEncoder", "()Z", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecListFields, is_encoder_id), 1 },
- { "android/media/MediaCodecInfo", "isSoftwareOnly", "()Z", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecListFields, is_software_only_id), 0 },
+ { "android/media/MediaCodecInfo", NULL, NULL, FF_JNI_CLASS, OFFSET(mediacodec_info_class), 1 },
+ { "android/media/MediaCodecInfo", "getName", "()Ljava/lang/String;", FF_JNI_METHOD, OFFSET(get_name_id), 1 },
+ { "android/media/MediaCodecInfo", "getCapabilitiesForType", "(Ljava/lang/String;)Landroid/media/MediaCodecInfo$CodecCapabilities;", FF_JNI_METHOD, OFFSET(get_codec_capabilities_id), 1 },
+ { "android/media/MediaCodecInfo", "getSupportedTypes", "()[Ljava/lang/String;", FF_JNI_METHOD, OFFSET(get_supported_types_id), 1 },
+ { "android/media/MediaCodecInfo", "isEncoder", "()Z", FF_JNI_METHOD, OFFSET(is_encoder_id), 1 },
+ { "android/media/MediaCodecInfo", "isSoftwareOnly", "()Z", FF_JNI_METHOD, OFFSET(is_software_only_id), 0 },
- { "android/media/MediaCodecInfo$CodecCapabilities", NULL, NULL, FF_JNI_CLASS, offsetof(struct JNIAMediaCodecListFields, codec_capabilities_class), 1 },
- { "android/media/MediaCodecInfo$CodecCapabilities", "colorFormats", "[I", FF_JNI_FIELD, offsetof(struct JNIAMediaCodecListFields, color_formats_id), 1 },
- { "android/media/MediaCodecInfo$CodecCapabilities", "profileLevels", "[Landroid/media/MediaCodecInfo$CodecProfileLevel;", FF_JNI_FIELD, offsetof(struct JNIAMediaCodecListFields, profile_levels_id), 1 },
+ { "android/media/MediaCodecInfo$CodecCapabilities", NULL, NULL, FF_JNI_CLASS, OFFSET(codec_capabilities_class), 1 },
+ { "android/media/MediaCodecInfo$CodecCapabilities", "colorFormats", "[I", FF_JNI_FIELD, OFFSET(color_formats_id), 1 },
+ { "android/media/MediaCodecInfo$CodecCapabilities", "profileLevels", "[Landroid/media/MediaCodecInfo$CodecProfileLevel;", FF_JNI_FIELD, OFFSET(profile_levels_id), 1 },
- { "android/media/MediaCodecInfo$CodecProfileLevel", NULL, NULL, FF_JNI_CLASS, offsetof(struct JNIAMediaCodecListFields, codec_profile_level_class), 1 },
- { "android/media/MediaCodecInfo$CodecProfileLevel", "profile", "I", FF_JNI_FIELD, offsetof(struct JNIAMediaCodecListFields, profile_id), 1 },
- { "android/media/MediaCodecInfo$CodecProfileLevel", "level", "I", FF_JNI_FIELD, offsetof(struct JNIAMediaCodecListFields, level_id), 1 },
+ { "android/media/MediaCodecInfo$CodecProfileLevel", NULL, NULL, FF_JNI_CLASS, OFFSET(codec_profile_level_class), 1 },
+ { "android/media/MediaCodecInfo$CodecProfileLevel", "profile", "I", FF_JNI_FIELD, OFFSET(profile_id), 1 },
+ { "android/media/MediaCodecInfo$CodecProfileLevel", "level", "I", FF_JNI_FIELD, OFFSET(level_id), 1 },
{ NULL }
};
+#undef OFFSET
struct JNIAMediaFormatFields {
@@ -110,29 +112,31 @@ struct JNIAMediaFormatFields {
};
+#define OFFSET(x) offsetof(struct JNIAMediaFormatFields, x)
static const struct FFJniField jni_amediaformat_mapping[] = {
- { "android/media/MediaFormat", NULL, NULL, FF_JNI_CLASS, offsetof(struct JNIAMediaFormatFields, mediaformat_class), 1 },
+ { "android/media/MediaFormat", NULL, NULL, FF_JNI_CLASS, OFFSET(mediaformat_class), 1 },
- { "android/media/MediaFormat", "<init>", "()V", FF_JNI_METHOD, offsetof(struct JNIAMediaFormatFields, init_id), 1 },
+ { "android/media/MediaFormat", "<init>", "()V", FF_JNI_METHOD, OFFSET(init_id), 1 },
- { "android/media/MediaFormat", "containsKey", "(Ljava/lang/String;)Z", FF_JNI_METHOD,offsetof(struct JNIAMediaFormatFields, contains_key_id), 1 },
+ { "android/media/MediaFormat", "containsKey", "(Ljava/lang/String;)Z", FF_JNI_METHOD, OFFSET(contains_key_id), 1 },
- { "android/media/MediaFormat", "getInteger", "(Ljava/lang/String;)I", FF_JNI_METHOD, offsetof(struct JNIAMediaFormatFields, get_integer_id), 1 },
- { "android/media/MediaFormat", "getLong", "(Ljava/lang/String;)J", FF_JNI_METHOD, offsetof(struct JNIAMediaFormatFields, get_long_id), 1 },
- { "android/media/MediaFormat", "getFloat", "(Ljava/lang/String;)F", FF_JNI_METHOD, offsetof(struct JNIAMediaFormatFields, get_float_id), 1 },
- { "android/media/MediaFormat", "getByteBuffer", "(Ljava/lang/String;)Ljava/nio/ByteBuffer;", FF_JNI_METHOD, offsetof(struct JNIAMediaFormatFields, get_bytebuffer_id), 1 },
- { "android/media/MediaFormat", "getString", "(Ljava/lang/String;)Ljava/lang/String;", FF_JNI_METHOD, offsetof(struct JNIAMediaFormatFields, get_string_id), 1 },
+ { "android/media/MediaFormat", "getInteger", "(Ljava/lang/String;)I", FF_JNI_METHOD, OFFSET(get_integer_id), 1 },
+ { "android/media/MediaFormat", "getLong", "(Ljava/lang/String;)J", FF_JNI_METHOD, OFFSET(get_long_id), 1 },
+ { "android/media/MediaFormat", "getFloat", "(Ljava/lang/String;)F", FF_JNI_METHOD, OFFSET(get_float_id), 1 },
+ { "android/media/MediaFormat", "getByteBuffer", "(Ljava/lang/String;)Ljava/nio/ByteBuffer;", FF_JNI_METHOD, OFFSET(get_bytebuffer_id), 1 },
+ { "android/media/MediaFormat", "getString", "(Ljava/lang/String;)Ljava/lang/String;", FF_JNI_METHOD, OFFSET(get_string_id), 1 },
- { "android/media/MediaFormat", "setInteger", "(Ljava/lang/String;I)V", FF_JNI_METHOD, offsetof(struct JNIAMediaFormatFields, set_integer_id), 1 },
- { "android/media/MediaFormat", "setLong", "(Ljava/lang/String;J)V", FF_JNI_METHOD, offsetof(struct JNIAMediaFormatFields, set_long_id), 1 },
- { "android/media/MediaFormat", "setFloat", "(Ljava/lang/String;F)V", FF_JNI_METHOD, offsetof(struct JNIAMediaFormatFields, set_float_id), 1 },
- { "android/media/MediaFormat", "setByteBuffer", "(Ljava/lang/String;Ljava/nio/ByteBuffer;)V", FF_JNI_METHOD, offsetof(struct JNIAMediaFormatFields, set_bytebuffer_id), 1 },
- { "android/media/MediaFormat", "setString", "(Ljava/lang/String;Ljava/lang/String;)V", FF_JNI_METHOD, offsetof(struct JNIAMediaFormatFields, set_string_id), 1 },
+ { "android/media/MediaFormat", "setInteger", "(Ljava/lang/String;I)V", FF_JNI_METHOD, OFFSET(set_integer_id), 1 },
+ { "android/media/MediaFormat", "setLong", "(Ljava/lang/String;J)V", FF_JNI_METHOD, OFFSET(set_long_id), 1 },
+ { "android/media/MediaFormat", "setFloat", "(Ljava/lang/String;F)V", FF_JNI_METHOD, OFFSET(set_float_id), 1 },
+ { "android/media/MediaFormat", "setByteBuffer", "(Ljava/lang/String;Ljava/nio/ByteBuffer;)V", FF_JNI_METHOD, OFFSET(set_bytebuffer_id), 1 },
+ { "android/media/MediaFormat", "setString", "(Ljava/lang/String;Ljava/lang/String;)V", FF_JNI_METHOD, OFFSET(set_string_id), 1 },
- { "android/media/MediaFormat", "toString", "()Ljava/lang/String;", FF_JNI_METHOD, offsetof(struct JNIAMediaFormatFields, to_string_id), 1 },
+ { "android/media/MediaFormat", "toString", "()Ljava/lang/String;", FF_JNI_METHOD, OFFSET(to_string_id), 1 },
{ NULL }
};
+#undef OFFSET
static const AVClass amediaformat_class = {
.class_name = "amediaformat",
@@ -202,57 +206,59 @@ struct JNIAMediaCodecFields {
};
+#define OFFSET(x) offsetof(struct JNIAMediaCodecFields, x)
static const struct FFJniField jni_amediacodec_mapping[] = {
- { "android/media/MediaCodec", NULL, NULL, FF_JNI_CLASS, offsetof(struct JNIAMediaCodecFields, mediacodec_class), 1 },
+ { "android/media/MediaCodec", NULL, NULL, FF_JNI_CLASS, OFFSET(mediacodec_class), 1 },
- { "android/media/MediaCodec", "INFO_TRY_AGAIN_LATER", "I", FF_JNI_STATIC_FIELD, offsetof(struct JNIAMediaCodecFields, info_try_again_later_id), 1 },
- { "android/media/MediaCodec", "INFO_OUTPUT_BUFFERS_CHANGED", "I", FF_JNI_STATIC_FIELD, offsetof(struct JNIAMediaCodecFields, info_output_buffers_changed_id), 1 },
- { "android/media/MediaCodec", "INFO_OUTPUT_FORMAT_CHANGED", "I", FF_JNI_STATIC_FIELD, offsetof(struct JNIAMediaCodecFields, info_output_format_changed_id), 1 },
+ { "android/media/MediaCodec", "INFO_TRY_AGAIN_LATER", "I", FF_JNI_STATIC_FIELD, OFFSET(info_try_again_later_id), 1 },
+ { "android/media/MediaCodec", "INFO_OUTPUT_BUFFERS_CHANGED", "I", FF_JNI_STATIC_FIELD, OFFSET(info_output_buffers_changed_id), 1 },
+ { "android/media/MediaCodec", "INFO_OUTPUT_FORMAT_CHANGED", "I", FF_JNI_STATIC_FIELD, OFFSET(info_output_format_changed_id), 1 },
- { "android/media/MediaCodec", "BUFFER_FLAG_CODEC_CONFIG", "I", FF_JNI_STATIC_FIELD, offsetof(struct JNIAMediaCodecFields, buffer_flag_codec_config_id), 1 },
- { "android/media/MediaCodec", "BUFFER_FLAG_END_OF_STREAM", "I", FF_JNI_STATIC_FIELD, offsetof(struct JNIAMediaCodecFields, buffer_flag_end_of_stream_id), 1 },
- { "android/media/MediaCodec", "BUFFER_FLAG_KEY_FRAME", "I", FF_JNI_STATIC_FIELD, offsetof(struct JNIAMediaCodecFields, buffer_flag_key_frame_id), 0 },
+ { "android/media/MediaCodec", "BUFFER_FLAG_CODEC_CONFIG", "I", FF_JNI_STATIC_FIELD, OFFSET(buffer_flag_codec_config_id), 1 },
+ { "android/media/MediaCodec", "BUFFER_FLAG_END_OF_STREAM", "I", FF_JNI_STATIC_FIELD, OFFSET(buffer_flag_end_of_stream_id), 1 },
+ { "android/media/MediaCodec", "BUFFER_FLAG_KEY_FRAME", "I", FF_JNI_STATIC_FIELD, OFFSET(buffer_flag_key_frame_id), 0 },
- { "android/media/MediaCodec", "CONFIGURE_FLAG_ENCODE", "I", FF_JNI_STATIC_FIELD, offsetof(struct JNIAMediaCodecFields, configure_flag_encode_id), 1 },
+ { "android/media/MediaCodec", "CONFIGURE_FLAG_ENCODE", "I", FF_JNI_STATIC_FIELD, OFFSET(configure_flag_encode_id), 1 },
- { "android/media/MediaCodec", "createByCodecName", "(Ljava/lang/String;)Landroid/media/MediaCodec;", FF_JNI_STATIC_METHOD, offsetof(struct JNIAMediaCodecFields, create_by_codec_name_id), 1 },
- { "android/media/MediaCodec", "createDecoderByType", "(Ljava/lang/String;)Landroid/media/MediaCodec;", FF_JNI_STATIC_METHOD, offsetof(struct JNIAMediaCodecFields, create_decoder_by_type_id), 1 },
- { "android/media/MediaCodec", "createEncoderByType", "(Ljava/lang/String;)Landroid/media/MediaCodec;", FF_JNI_STATIC_METHOD, offsetof(struct JNIAMediaCodecFields, create_encoder_by_type_id), 1 },
+ { "android/media/MediaCodec", "createByCodecName", "(Ljava/lang/String;)Landroid/media/MediaCodec;", FF_JNI_STATIC_METHOD, OFFSET(create_by_codec_name_id), 1 },
+ { "android/media/MediaCodec", "createDecoderByType", "(Ljava/lang/String;)Landroid/media/MediaCodec;", FF_JNI_STATIC_METHOD, OFFSET(create_decoder_by_type_id), 1 },
+ { "android/media/MediaCodec", "createEncoderByType", "(Ljava/lang/String;)Landroid/media/MediaCodec;", FF_JNI_STATIC_METHOD, OFFSET(create_encoder_by_type_id), 1 },
- { "android/media/MediaCodec", "getName", "()Ljava/lang/String;", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecFields, get_name_id), 1 },
+ { "android/media/MediaCodec", "getName", "()Ljava/lang/String;", FF_JNI_METHOD, OFFSET(get_name_id), 1 },
- { "android/media/MediaCodec", "configure", "(Landroid/media/MediaFormat;Landroid/view/Surface;Landroid/media/MediaCrypto;I)V", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecFields, configure_id), 1 },
- { "android/media/MediaCodec", "start", "()V", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecFields, start_id), 1 },
- { "android/media/MediaCodec", "flush", "()V", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecFields, flush_id), 1 },
- { "android/media/MediaCodec", "stop", "()V", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecFields, stop_id), 1 },
- { "android/media/MediaCodec", "release", "()V", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecFields, release_id), 1 },
+ { "android/media/MediaCodec", "configure", "(Landroid/media/MediaFormat;Landroid/view/Surface;Landroid/media/MediaCrypto;I)V", FF_JNI_METHOD, OFFSET(configure_id), 1 },
+ { "android/media/MediaCodec", "start", "()V", FF_JNI_METHOD, OFFSET(start_id), 1 },
+ { "android/media/MediaCodec", "flush", "()V", FF_JNI_METHOD, OFFSET(flush_id), 1 },
+ { "android/media/MediaCodec", "stop", "()V", FF_JNI_METHOD, OFFSET(stop_id), 1 },
+ { "android/media/MediaCodec", "release", "()V", FF_JNI_METHOD, OFFSET(release_id), 1 },
- { "android/media/MediaCodec", "getOutputFormat", "()Landroid/media/MediaFormat;", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecFields, get_output_format_id), 1 },
+ { "android/media/MediaCodec", "getOutputFormat", "()Landroid/media/MediaFormat;", FF_JNI_METHOD, OFFSET(get_output_format_id), 1 },
- { "android/media/MediaCodec", "dequeueInputBuffer", "(J)I", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecFields, dequeue_input_buffer_id), 1 },
- { "android/media/MediaCodec", "queueInputBuffer", "(IIIJI)V", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecFields, queue_input_buffer_id), 1 },
- { "android/media/MediaCodec", "getInputBuffer", "(I)Ljava/nio/ByteBuffer;", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecFields, get_input_buffer_id), 0 },
- { "android/media/MediaCodec", "getInputBuffers", "()[Ljava/nio/ByteBuffer;", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecFields, get_input_buffers_id), 1 },
+ { "android/media/MediaCodec", "dequeueInputBuffer", "(J)I", FF_JNI_METHOD, OFFSET(dequeue_input_buffer_id), 1 },
+ { "android/media/MediaCodec", "queueInputBuffer", "(IIIJI)V", FF_JNI_METHOD, OFFSET(queue_input_buffer_id), 1 },
+ { "android/media/MediaCodec", "getInputBuffer", "(I)Ljava/nio/ByteBuffer;", FF_JNI_METHOD, OFFSET(get_input_buffer_id), 0 },
+ { "android/media/MediaCodec", "getInputBuffers", "()[Ljava/nio/ByteBuffer;", FF_JNI_METHOD, OFFSET(get_input_buffers_id), 1 },
- { "android/media/MediaCodec", "dequeueOutputBuffer", "(Landroid/media/MediaCodec$BufferInfo;J)I", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecFields, dequeue_output_buffer_id), 1 },
- { "android/media/MediaCodec", "getOutputBuffer", "(I)Ljava/nio/ByteBuffer;", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecFields, get_output_buffer_id), 0 },
- { "android/media/MediaCodec", "getOutputBuffers", "()[Ljava/nio/ByteBuffer;", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecFields, get_output_buffers_id), 1 },
- { "android/media/MediaCodec", "releaseOutputBuffer", "(IZ)V", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecFields, release_output_buffer_id), 1 },
- { "android/media/MediaCodec", "releaseOutputBuffer", "(IJ)V", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecFields, release_output_buffer_at_time_id), 0 },
+ { "android/media/MediaCodec", "dequeueOutputBuffer", "(Landroid/media/MediaCodec$BufferInfo;J)I", FF_JNI_METHOD, OFFSET(dequeue_output_buffer_id), 1 },
+ { "android/media/MediaCodec", "getOutputBuffer", "(I)Ljava/nio/ByteBuffer;", FF_JNI_METHOD, OFFSET(get_output_buffer_id), 0 },
+ { "android/media/MediaCodec", "getOutputBuffers", "()[Ljava/nio/ByteBuffer;", FF_JNI_METHOD, OFFSET(get_output_buffers_id), 1 },
+ { "android/media/MediaCodec", "releaseOutputBuffer", "(IZ)V", FF_JNI_METHOD, OFFSET(release_output_buffer_id), 1 },
+ { "android/media/MediaCodec", "releaseOutputBuffer", "(IJ)V", FF_JNI_METHOD, OFFSET(release_output_buffer_at_time_id), 0 },
- { "android/media/MediaCodec", "setInputSurface", "(Landroid/view/Surface;)V", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecFields, set_input_surface_id), 0 },
- { "android/media/MediaCodec", "signalEndOfInputStream", "()V", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecFields, signal_end_of_input_stream_id), 0 },
+ { "android/media/MediaCodec", "setInputSurface", "(Landroid/view/Surface;)V", FF_JNI_METHOD, OFFSET(set_input_surface_id), 0 },
+ { "android/media/MediaCodec", "signalEndOfInputStream", "()V", FF_JNI_METHOD, OFFSET(signal_end_of_input_stream_id), 0 },
- { "android/media/MediaCodec$BufferInfo", NULL, NULL, FF_JNI_CLASS, offsetof(struct JNIAMediaCodecFields, mediainfo_class), 1 },
+ { "android/media/MediaCodec$BufferInfo", NULL, NULL, FF_JNI_CLASS, OFFSET(mediainfo_class), 1 },
- { "android/media/MediaCodec.BufferInfo", "<init>", "()V", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecFields, init_id), 1 },
- { "android/media/MediaCodec.BufferInfo", "flags", "I", FF_JNI_FIELD, offsetof(struct JNIAMediaCodecFields, flags_id), 1 },
- { "android/media/MediaCodec.BufferInfo", "offset", "I", FF_JNI_FIELD, offsetof(struct JNIAMediaCodecFields, offset_id), 1 },
- { "android/media/MediaCodec.BufferInfo", "presentationTimeUs", "J", FF_JNI_FIELD, offsetof(struct JNIAMediaCodecFields, presentation_time_us_id), 1 },
- { "android/media/MediaCodec.BufferInfo", "size", "I", FF_JNI_FIELD, offsetof(struct JNIAMediaCodecFields, size_id), 1 },
+ { "android/media/MediaCodec.BufferInfo", "<init>", "()V", FF_JNI_METHOD, OFFSET(init_id), 1 },
+ { "android/media/MediaCodec.BufferInfo", "flags", "I", FF_JNI_FIELD, OFFSET(flags_id), 1 },
+ { "android/media/MediaCodec.BufferInfo", "offset", "I", FF_JNI_FIELD, OFFSET(offset_id), 1 },
+ { "android/media/MediaCodec.BufferInfo", "presentationTimeUs", "J", FF_JNI_FIELD, OFFSET(presentation_time_us_id), 1 },
+ { "android/media/MediaCodec.BufferInfo", "size", "I", FF_JNI_FIELD, OFFSET(size_id), 1 },
{ NULL }
};
+#undef OFFSET
static const AVClass amediacodec_class = {
.class_name = "amediacodec",
--
2.44.0
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 51+ messages in thread
* [FFmpeg-devel] [PATCH v2 6/6] avcodec/mediacodec_wrapper: remove unnecessary NULL checks before calling Delete{Global, Local}Ref()
2024-02-27 14:50 ` [FFmpeg-devel] Add protocol for Android content providers (v2) Matthieu Bouron
` (4 preceding siblings ...)
2024-02-27 14:50 ` [FFmpeg-devel] [PATCH v2 5/6] avcodec/mediacodec_wrapper: use an OFFSET() macro where relevant Matthieu Bouron
@ 2024-02-27 14:50 ` Matthieu Bouron
2024-03-04 8:21 ` [FFmpeg-devel] Add protocol for Android content providers (v2) Matthieu Bouron
2024-03-17 22:28 ` [FFmpeg-devel] Add protocol for Android content providers (v4) Matthieu Bouron
7 siblings, 0 replies; 51+ messages in thread
From: Matthieu Bouron @ 2024-02-27 14:50 UTC (permalink / raw)
To: ffmpeg-devel; +Cc: Matthieu Bouron
Delete{Global,Local}Ref already handle NULL.
---
libavcodec/mediacodec_wrapper.c | 189 ++++++++------------------------
1 file changed, 47 insertions(+), 142 deletions(-)
diff --git a/libavcodec/mediacodec_wrapper.c b/libavcodec/mediacodec_wrapper.c
index 78cd28f53d..306359071e 100644
--- a/libavcodec/mediacodec_wrapper.c
+++ b/libavcodec/mediacodec_wrapper.c
@@ -549,10 +549,8 @@ char *ff_AMediaCodecList_getCodecNameByType(const char *mime, int profile, int e
goto done;
}
- if (codec_name) {
- (*env)->DeleteLocalRef(env, codec_name);
- codec_name = NULL;
- }
+ (*env)->DeleteLocalRef(env, codec_name);
+ codec_name = NULL;
/* Skip software decoders */
if (
@@ -616,10 +614,8 @@ char *ff_AMediaCodecList_getCodecNameByType(const char *mime, int profile, int e
found_codec = profile == supported_profile;
- if (profile_level) {
- (*env)->DeleteLocalRef(env, profile_level);
- profile_level = NULL;
- }
+ (*env)->DeleteLocalRef(env, profile_level);
+ profile_level = NULL;
if (found_codec) {
break;
@@ -627,20 +623,14 @@ char *ff_AMediaCodecList_getCodecNameByType(const char *mime, int profile, int e
}
done_with_type:
- if (profile_levels) {
- (*env)->DeleteLocalRef(env, profile_levels);
- profile_levels = NULL;
- }
+ (*env)->DeleteLocalRef(env, profile_levels);
+ profile_levels = NULL;
- if (capabilities) {
- (*env)->DeleteLocalRef(env, capabilities);
- capabilities = NULL;
- }
+ (*env)->DeleteLocalRef(env, capabilities);
+ capabilities = NULL;
- if (type) {
- (*env)->DeleteLocalRef(env, type);
- type = NULL;
- }
+ (*env)->DeleteLocalRef(env, type);
+ type = NULL;
av_freep(&supported_type);
@@ -650,15 +640,11 @@ done_with_type:
}
done_with_info:
- if (info) {
- (*env)->DeleteLocalRef(env, info);
- info = NULL;
- }
+ (*env)->DeleteLocalRef(env, info);
+ info = NULL;
- if (types) {
- (*env)->DeleteLocalRef(env, types);
- types = NULL;
- }
+ (*env)->DeleteLocalRef(env, types);
+ types = NULL;
if (found_codec) {
break;
@@ -668,33 +654,13 @@ done_with_info:
}
done:
- if (codec_name) {
- (*env)->DeleteLocalRef(env, codec_name);
- }
-
- if (info) {
- (*env)->DeleteLocalRef(env, info);
- }
-
- if (type) {
- (*env)->DeleteLocalRef(env, type);
- }
-
- if (types) {
- (*env)->DeleteLocalRef(env, types);
- }
-
- if (capabilities) {
- (*env)->DeleteLocalRef(env, capabilities);
- }
-
- if (profile_level) {
- (*env)->DeleteLocalRef(env, profile_level);
- }
-
- if (profile_levels) {
- (*env)->DeleteLocalRef(env, profile_levels);
- }
+ (*env)->DeleteLocalRef(env, codec_name);
+ (*env)->DeleteLocalRef(env, info);
+ (*env)->DeleteLocalRef(env, type);
+ (*env)->DeleteLocalRef(env, types);
+ (*env)->DeleteLocalRef(env, capabilities);
+ (*env)->DeleteLocalRef(env, profile_level);
+ (*env)->DeleteLocalRef(env, profile_levels);
av_freep(&supported_type);
@@ -741,9 +707,7 @@ static FFAMediaFormat *mediaformat_jni_new(void)
}
fail:
- if (object) {
- (*env)->DeleteLocalRef(env, object);
- }
+ (*env)->DeleteLocalRef(env, object);
if (!format->object) {
ff_jni_reset_jfields(env, &format->jfields, jni_amediaformat_mapping, 1, format);
@@ -828,9 +792,7 @@ static char* mediaformat_jni_toString(FFAMediaFormat* ctx)
ret = ff_jni_jstring_to_utf_chars(env, description, format);
fail:
- if (description) {
- (*env)->DeleteLocalRef(env, description);
- }
+ (*env)->DeleteLocalRef(env, description);
return ret;
}
@@ -867,9 +829,7 @@ static int mediaformat_jni_getInt32(FFAMediaFormat* ctx, const char *name, int32
ret = 1;
fail:
- if (key) {
- (*env)->DeleteLocalRef(env, key);
- }
+ (*env)->DeleteLocalRef(env, key);
return ret;
}
@@ -906,9 +866,7 @@ static int mediaformat_jni_getInt64(FFAMediaFormat* ctx, const char *name, int64
ret = 1;
fail:
- if (key) {
- (*env)->DeleteLocalRef(env, key);
- }
+ (*env)->DeleteLocalRef(env, key);
return ret;
}
@@ -945,9 +903,7 @@ static int mediaformat_jni_getFloat(FFAMediaFormat* ctx, const char *name, float
ret = 1;
fail:
- if (key) {
- (*env)->DeleteLocalRef(env, key);
- }
+ (*env)->DeleteLocalRef(env, key);
return ret;
}
@@ -999,13 +955,8 @@ static int mediaformat_jni_getBuffer(FFAMediaFormat* ctx, const char *name, void
ret = 1;
fail:
- if (key) {
- (*env)->DeleteLocalRef(env, key);
- }
-
- if (result) {
- (*env)->DeleteLocalRef(env, result);
- }
+ (*env)->DeleteLocalRef(env, key);
+ (*env)->DeleteLocalRef(env, result);
return ret;
}
@@ -1049,13 +1000,8 @@ static int mediaformat_jni_getString(FFAMediaFormat* ctx, const char *name, cons
ret = 1;
fail:
- if (key) {
- (*env)->DeleteLocalRef(env, key);
- }
-
- if (result) {
- (*env)->DeleteLocalRef(env, result);
- }
+ (*env)->DeleteLocalRef(env, key);
+ (*env)->DeleteLocalRef(env, result);
return ret;
}
@@ -1081,9 +1027,7 @@ static void mediaformat_jni_setInt32(FFAMediaFormat* ctx, const char* name, int3
}
fail:
- if (key) {
- (*env)->DeleteLocalRef(env, key);
- }
+ (*env)->DeleteLocalRef(env, key);
}
static void mediaformat_jni_setInt64(FFAMediaFormat* ctx, const char* name, int64_t value)
@@ -1107,9 +1051,7 @@ static void mediaformat_jni_setInt64(FFAMediaFormat* ctx, const char* name, int6
}
fail:
- if (key) {
- (*env)->DeleteLocalRef(env, key);
- }
+ (*env)->DeleteLocalRef(env, key);
}
static void mediaformat_jni_setFloat(FFAMediaFormat* ctx, const char* name, float value)
@@ -1133,9 +1075,7 @@ static void mediaformat_jni_setFloat(FFAMediaFormat* ctx, const char* name, floa
}
fail:
- if (key) {
- (*env)->DeleteLocalRef(env, key);
- }
+ (*env)->DeleteLocalRef(env, key);
}
static void mediaformat_jni_setString(FFAMediaFormat* ctx, const char* name, const char* value)
@@ -1165,13 +1105,8 @@ static void mediaformat_jni_setString(FFAMediaFormat* ctx, const char* name, con
}
fail:
- if (key) {
- (*env)->DeleteLocalRef(env, key);
- }
-
- if (string) {
- (*env)->DeleteLocalRef(env, string);
- }
+ (*env)->DeleteLocalRef(env, key);
+ (*env)->DeleteLocalRef(env, string);
}
static void mediaformat_jni_setBuffer(FFAMediaFormat* ctx, const char* name, void* data, size_t size)
@@ -1213,13 +1148,8 @@ static void mediaformat_jni_setBuffer(FFAMediaFormat* ctx, const char* name, voi
}
fail:
- if (key) {
- (*env)->DeleteLocalRef(env, key);
- }
-
- if (buffer) {
- (*env)->DeleteLocalRef(env, buffer);
- }
+ (*env)->DeleteLocalRef(env, key);
+ (*env)->DeleteLocalRef(env, buffer);
}
static int codec_init_static_fields(FFAMediaCodecJni *codec)
@@ -1352,26 +1282,13 @@ static inline FFAMediaCodec *codec_create(int method, const char *arg)
ret = 0;
fail:
- if (jarg) {
- (*env)->DeleteLocalRef(env, jarg);
- }
-
- if (object) {
- (*env)->DeleteLocalRef(env, object);
- }
-
- if (buffer_info) {
- (*env)->DeleteLocalRef(env, buffer_info);
- }
+ (*env)->DeleteLocalRef(env, jarg);
+ (*env)->DeleteLocalRef(env, object);
+ (*env)->DeleteLocalRef(env, buffer_info);
if (ret < 0) {
- if (codec->object) {
- (*env)->DeleteGlobalRef(env, codec->object);
- }
-
- if (codec->buffer_info) {
- (*env)->DeleteGlobalRef(env, codec->buffer_info);
- }
+ (*env)->DeleteGlobalRef(env, codec->object);
+ (*env)->DeleteGlobalRef(env, codec->buffer_info);
ff_jni_reset_jfields(env, &codec->jfields, jni_amediacodec_mapping, 1, codec);
av_freep(&codec);
@@ -1692,13 +1609,8 @@ static uint8_t* mediacodec_jni_getInputBuffer(FFAMediaCodec* ctx, size_t idx, si
ret = (*env)->GetDirectBufferAddress(env, buffer);
*out_size = (*env)->GetDirectBufferCapacity(env, buffer);
fail:
- if (buffer) {
- (*env)->DeleteLocalRef(env, buffer);
- }
-
- if (input_buffers) {
- (*env)->DeleteLocalRef(env, input_buffers);
- }
+ (*env)->DeleteLocalRef(env, buffer);
+ (*env)->DeleteLocalRef(env, input_buffers);
return ret;
}
@@ -1740,13 +1652,8 @@ static uint8_t* mediacodec_jni_getOutputBuffer(FFAMediaCodec* ctx, size_t idx, s
ret = (*env)->GetDirectBufferAddress(env, buffer);
*out_size = (*env)->GetDirectBufferCapacity(env, buffer);
fail:
- if (buffer) {
- (*env)->DeleteLocalRef(env, buffer);
- }
-
- if (output_buffers) {
- (*env)->DeleteLocalRef(env, output_buffers);
- }
+ (*env)->DeleteLocalRef(env, buffer);
+ (*env)->DeleteLocalRef(env, output_buffers);
return ret;
}
@@ -1768,9 +1675,7 @@ static FFAMediaFormat* mediacodec_jni_getOutputFormat(FFAMediaCodec* ctx)
ret = mediaformat_jni_newFromObject(mediaformat);
fail:
- if (mediaformat) {
- (*env)->DeleteLocalRef(env, mediaformat);
- }
+ (*env)->DeleteLocalRef(env, mediaformat);
return ret;
}
--
2.44.0
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 51+ messages in thread
* Re: [FFmpeg-devel] Add protocol for Android content providers (v2)
2024-02-27 14:50 ` [FFmpeg-devel] Add protocol for Android content providers (v2) Matthieu Bouron
` (5 preceding siblings ...)
2024-02-27 14:50 ` [FFmpeg-devel] [PATCH v2 6/6] avcodec/mediacodec_wrapper: remove unnecessary NULL checks before calling Delete{Global, Local}Ref() Matthieu Bouron
@ 2024-03-04 8:21 ` Matthieu Bouron
2024-03-14 8:04 ` Matthieu Bouron
2024-03-17 22:28 ` [FFmpeg-devel] Add protocol for Android content providers (v4) Matthieu Bouron
7 siblings, 1 reply; 51+ messages in thread
From: Matthieu Bouron @ 2024-03-04 8:21 UTC (permalink / raw)
To: ffmpeg-devel
On Tue, Feb 27, 2024 at 03:50:36PM +0100, Matthieu Bouron wrote:
> Diff from initial patchset:
> - directly include libavcodec/ffjni.c from libavformat/file.c instead of
> migrating ffjni to libavutil (avpriv_*)
> - check that the passed application context reference is a global one and error
> out if it's not the case
>
Ping.
Note: I reworded locally the commit msgs using avutil/jni to avcodec/jni.
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 51+ messages in thread
* Re: [FFmpeg-devel] [PATCH v2 1/6] avcodec: add av_jni_{get, set}_android_app_ctx helper
2024-02-27 14:50 ` [FFmpeg-devel] [PATCH v2 1/6] avcodec: add av_jni_{get, set}_android_app_ctx helper Matthieu Bouron
@ 2024-03-04 11:30 ` Andreas Rheinhardt
2024-03-04 15:11 ` Matthieu Bouron
0 siblings, 1 reply; 51+ messages in thread
From: Andreas Rheinhardt @ 2024-03-04 11:30 UTC (permalink / raw)
To: ffmpeg-devel
Matthieu Bouron:
> This will allow users to pass the Android ApplicationContext which is mandatory
> to retrieve the ContentResolver responsible to resolve/open Android content-uri.
> ---
> libavcodec/jni.c | 40 ++++++++++++++++++++++++++++++++++++++++
> libavcodec/jni.h | 17 +++++++++++++++++
> 2 files changed, 57 insertions(+)
>
> diff --git a/libavcodec/jni.c b/libavcodec/jni.c
> index ae6490de9d..7d04d0a268 100644
> --- a/libavcodec/jni.c
> +++ b/libavcodec/jni.c
> @@ -64,6 +64,36 @@ void *av_jni_get_java_vm(void *log_ctx)
> return vm;
> }
>
> +int av_jni_set_android_app_ctx(void *app_ctx, void *log_ctx)
> +{
> + JNIEnv *env = avpriv_jni_get_env(c);
Patch #1 won't compile on its own due to this; you fix this up in patch #2.
> + if (!env)
> + return AVERROR(EINVAL);
> +
> + jobjectRefType type = (*env)->GetObjectRefType(env, app_ctx);
> + if (type != JNIGlobalRefType) {
> + av_log(log_ctx, AV_LOG_ERROR, "Application context must be passed as a global reference");
> + return AVERROR(EINVAL);
> + }
> +
> + pthread_mutex_lock(&lock);
> + android_app_ctx = app_ctx;
> + pthread_mutex_unlock(&lock);
> +
> + return 0;
> +}
> +
> +void *av_jni_get_android_app_ctx(void)
> +{
> + void *ctx;
> +
> + pthread_mutex_lock(&lock);
> + ctx = android_app_ctx;
> + pthread_mutex_unlock(&lock);
> +
> + return ctx;
> +}
> +
> #else
>
> int av_jni_set_java_vm(void *vm, void *log_ctx)
> @@ -76,4 +106,14 @@ void *av_jni_get_java_vm(void *log_ctx)
> return NULL;
> }
>
> +int av_jni_set_android_app_ctx(void *app_ctx, void *log_ctx)
> +{
> + return AVERROR(ENOSYS);
> +}
> +
> +void *av_jni_get_android_app_ctx(void)
> +{
> + return NULL;
> +}
I am against adding stub functions on platforms where they are known to
be useless, i.e. everything except android.
> +
> #endif
> diff --git a/libavcodec/jni.h b/libavcodec/jni.h
> index dd99e92611..da8025f830 100644
> --- a/libavcodec/jni.h
> +++ b/libavcodec/jni.h
> @@ -43,4 +43,21 @@ int av_jni_set_java_vm(void *vm, void *log_ctx);
> */
> void *av_jni_get_java_vm(void *log_ctx);
>
> +/*
> + * Set the Android application context which will be used to retrieve the Android
> + * content resolver to resolve content uris.
> + *
> + * @param app_ctx global JNI reference to the Android application context
> + * @return 0 on success, < 0 otherwise
> + */
> +int av_jni_set_android_app_ctx(void *app_ctx, void *log_ctx);
> +
> +/*
> + * Get the Android application context that has been set with
> + * av_jni_set_android_app_ctx.
> + *
> + * @return a pointer the the Android application context
> + */
> +void *av_jni_get_android_app_ctx(void);
> +
> #endif /* AVCODEC_JNI_H */
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 51+ messages in thread
* Re: [FFmpeg-devel] [PATCH v2 1/6] avcodec: add av_jni_{get, set}_android_app_ctx helper
2024-03-04 11:30 ` Andreas Rheinhardt
@ 2024-03-04 15:11 ` Matthieu Bouron
2024-03-04 16:35 ` Matthieu Bouron
0 siblings, 1 reply; 51+ messages in thread
From: Matthieu Bouron @ 2024-03-04 15:11 UTC (permalink / raw)
To: FFmpeg development discussions and patches
On Mon, Mar 4, 2024 at 12:29 PM Andreas Rheinhardt
<andreas.rheinhardt@outlook.com> wrote:
>
> Matthieu Bouron:
> > This will allow users to pass the Android ApplicationContext which is mandatory
> > to retrieve the ContentResolver responsible to resolve/open Android content-uri.
> > ---
> > libavcodec/jni.c | 40 ++++++++++++++++++++++++++++++++++++++++
> > libavcodec/jni.h | 17 +++++++++++++++++
> > 2 files changed, 57 insertions(+)
> >
> > diff --git a/libavcodec/jni.c b/libavcodec/jni.c
> > index ae6490de9d..7d04d0a268 100644
> > --- a/libavcodec/jni.c
> > +++ b/libavcodec/jni.c
> > @@ -64,6 +64,36 @@ void *av_jni_get_java_vm(void *log_ctx)
> > return vm;
> > }
> >
> > +int av_jni_set_android_app_ctx(void *app_ctx, void *log_ctx)
> > +{
> > + JNIEnv *env = avpriv_jni_get_env(c);
>
> Patch #1 won't compile on its own due to this; you fix this up in patch #2.
>
> > + if (!env)
> > + return AVERROR(EINVAL);
> > +
> > + jobjectRefType type = (*env)->GetObjectRefType(env, app_ctx);
> > + if (type != JNIGlobalRefType) {
> > + av_log(log_ctx, AV_LOG_ERROR, "Application context must be passed as a global reference");
> > + return AVERROR(EINVAL);
> > + }
> > +
> > + pthread_mutex_lock(&lock);
> > + android_app_ctx = app_ctx;
> > + pthread_mutex_unlock(&lock);
> > +
> > + return 0;
> > +}
> > +
> > +void *av_jni_get_android_app_ctx(void)
> > +{
> > + void *ctx;
> > +
> > + pthread_mutex_lock(&lock);
> > + ctx = android_app_ctx;
> > + pthread_mutex_unlock(&lock);
> > +
> > + return ctx;
> > +}
> > +
> > #else
> >
> > int av_jni_set_java_vm(void *vm, void *log_ctx)
> > @@ -76,4 +106,14 @@ void *av_jni_get_java_vm(void *log_ctx)
> > return NULL;
> > }
> >
> > +int av_jni_set_android_app_ctx(void *app_ctx, void *log_ctx)
> > +{
> > + return AVERROR(ENOSYS);
> > +}
> > +
> > +void *av_jni_get_android_app_ctx(void)
> > +{
> > + return NULL;
> > +}
>
> I am against adding stub functions on platforms where they are known to
> be useless, i.e. everything except android.
Ok. Will update the patch introducing a new header "jni_android.h".
Unless we want to also scope avcodec/jni.h to Android only ?
>
> > +
> > #endif
> > diff --git a/libavcodec/jni.h b/libavcodec/jni.h
> > index dd99e92611..da8025f830 100644
> > --- a/libavcodec/jni.h
> > +++ b/libavcodec/jni.h
> > @@ -43,4 +43,21 @@ int av_jni_set_java_vm(void *vm, void *log_ctx);
> > */
> > void *av_jni_get_java_vm(void *log_ctx);
> >
> > +/*
> > + * Set the Android application context which will be used to retrieve the Android
> > + * content resolver to resolve content uris.
> > + *
> > + * @param app_ctx global JNI reference to the Android application context
> > + * @return 0 on success, < 0 otherwise
> > + */
> > +int av_jni_set_android_app_ctx(void *app_ctx, void *log_ctx);
> > +
> > +/*
> > + * Get the Android application context that has been set with
> > + * av_jni_set_android_app_ctx.
> > + *
> > + * @return a pointer the the Android application context
> > + */
> > +void *av_jni_get_android_app_ctx(void);
> > +
> > #endif /* AVCODEC_JNI_H */
>
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
> To unsubscribe, visit link above, or email
> ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 51+ messages in thread
* Re: [FFmpeg-devel] [PATCH v2 1/6] avcodec: add av_jni_{get, set}_android_app_ctx helper
2024-03-04 15:11 ` Matthieu Bouron
@ 2024-03-04 16:35 ` Matthieu Bouron
2024-03-04 19:36 ` Matthieu Bouron
0 siblings, 1 reply; 51+ messages in thread
From: Matthieu Bouron @ 2024-03-04 16:35 UTC (permalink / raw)
To: FFmpeg development discussions and patches
On Mon, Mar 4, 2024 at 4:11 PM Matthieu Bouron
<matthieu.bouron@gmail.com> wrote:
>
> On Mon, Mar 4, 2024 at 12:29 PM Andreas Rheinhardt
> <andreas.rheinhardt@outlook.com> wrote:
> >
> > Matthieu Bouron:
> > > This will allow users to pass the Android ApplicationContext which is mandatory
> > > to retrieve the ContentResolver responsible to resolve/open Android content-uri.
> > > ---
> > > libavcodec/jni.c | 40 ++++++++++++++++++++++++++++++++++++++++
> > > libavcodec/jni.h | 17 +++++++++++++++++
> > > 2 files changed, 57 insertions(+)
> > >
> > > diff --git a/libavcodec/jni.c b/libavcodec/jni.c
> > > index ae6490de9d..7d04d0a268 100644
> > > --- a/libavcodec/jni.c
> > > +++ b/libavcodec/jni.c
> > > @@ -64,6 +64,36 @@ void *av_jni_get_java_vm(void *log_ctx)
> > > return vm;
> > > }
> > >
> > > +int av_jni_set_android_app_ctx(void *app_ctx, void *log_ctx)
> > > +{
> > > + JNIEnv *env = avpriv_jni_get_env(c);
> >
> > Patch #1 won't compile on its own due to this; you fix this up in patch #2.
> >
> > > + if (!env)
> > > + return AVERROR(EINVAL);
> > > +
> > > + jobjectRefType type = (*env)->GetObjectRefType(env, app_ctx);
> > > + if (type != JNIGlobalRefType) {
> > > + av_log(log_ctx, AV_LOG_ERROR, "Application context must be passed as a global reference");
> > > + return AVERROR(EINVAL);
> > > + }
> > > +
> > > + pthread_mutex_lock(&lock);
> > > + android_app_ctx = app_ctx;
> > > + pthread_mutex_unlock(&lock);
> > > +
> > > + return 0;
> > > +}
> > > +
> > > +void *av_jni_get_android_app_ctx(void)
> > > +{
> > > + void *ctx;
> > > +
> > > + pthread_mutex_lock(&lock);
> > > + ctx = android_app_ctx;
> > > + pthread_mutex_unlock(&lock);
> > > +
> > > + return ctx;
> > > +}
> > > +
> > > #else
> > >
> > > int av_jni_set_java_vm(void *vm, void *log_ctx)
> > > @@ -76,4 +106,14 @@ void *av_jni_get_java_vm(void *log_ctx)
> > > return NULL;
> > > }
> > >
> > > +int av_jni_set_android_app_ctx(void *app_ctx, void *log_ctx)
> > > +{
> > > + return AVERROR(ENOSYS);
> > > +}
> > > +
> > > +void *av_jni_get_android_app_ctx(void)
> > > +{
> > > + return NULL;
> > > +}
> >
> > I am against adding stub functions on platforms where they are known to
> > be useless, i.e. everything except android.
>
> Ok. Will update the patch introducing a new header "jni_android.h".
> Unless we want to also scope avcodec/jni.h to Android only ?
Or maybe you mean adding a ifdef guard to it ?
>
> >
> > > +
> > > #endif
> > > diff --git a/libavcodec/jni.h b/libavcodec/jni.h
> > > index dd99e92611..da8025f830 100644
> > > --- a/libavcodec/jni.h
> > > +++ b/libavcodec/jni.h
> > > @@ -43,4 +43,21 @@ int av_jni_set_java_vm(void *vm, void *log_ctx);
> > > */
> > > void *av_jni_get_java_vm(void *log_ctx);
> > >
> > > +/*
> > > + * Set the Android application context which will be used to retrieve the Android
> > > + * content resolver to resolve content uris.
> > > + *
> > > + * @param app_ctx global JNI reference to the Android application context
> > > + * @return 0 on success, < 0 otherwise
> > > + */
> > > +int av_jni_set_android_app_ctx(void *app_ctx, void *log_ctx);
> > > +
> > > +/*
> > > + * Get the Android application context that has been set with
> > > + * av_jni_set_android_app_ctx.
> > > + *
> > > + * @return a pointer the the Android application context
> > > + */
> > > +void *av_jni_get_android_app_ctx(void);
> > > +
> > > #endif /* AVCODEC_JNI_H */
> >
> > _______________________________________________
> > ffmpeg-devel mailing list
> > ffmpeg-devel@ffmpeg.org
> > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
> >
> > To unsubscribe, visit link above, or email
> > ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 51+ messages in thread
* Re: [FFmpeg-devel] [PATCH v2 1/6] avcodec: add av_jni_{get, set}_android_app_ctx helper
2024-03-04 16:35 ` Matthieu Bouron
@ 2024-03-04 19:36 ` Matthieu Bouron
0 siblings, 0 replies; 51+ messages in thread
From: Matthieu Bouron @ 2024-03-04 19:36 UTC (permalink / raw)
To: FFmpeg development discussions and patches
[-- Attachment #1: Type: text/plain, Size: 670 bytes --]
On Mon, Mar 04, 2024 at 05:35:36PM +0100, Matthieu Bouron wrote:
> On Mon, Mar 4, 2024 at 4:11 PM Matthieu Bouron
> <matthieu.bouron@gmail.com> wrote:
> >
> > On Mon, Mar 4, 2024 at 12:29 PM Andreas Rheinhardt
> > <andreas.rheinhardt@outlook.com> wrote:
[...]
> > >
> > > I am against adding stub functions on platforms where they are known to
> > > be useless, i.e. everything except android.
> >
> > Ok. Will update the patch introducing a new header "jni_android.h".
> > Unless we want to also scope avcodec/jni.h to Android only ?
>
> Or maybe you mean adding a ifdef guard to it ?
>
New patch attached. The functions are now only built for Android.
[...]
[-- Attachment #2: v3-0001-avcodec-add-av_jni_-get-set-_android_app_ctx-help.patch --]
[-- Type: text/plain, Size: 2418 bytes --]
From 1b674e78c6a86090f5c9ed6fef5f47ae83ba98be Mon Sep 17 00:00:00 2001
From: Matthieu Bouron <matthieu.bouron@gmail.com>
Date: Mon, 12 Feb 2024 23:13:09 +0100
Subject: [PATCH v3 1/6] avcodec: add av_jni_{get,set}_android_app_ctx helper
This will allow users to pass the Android ApplicationContext which is mandatory
to retrieve the ContentResolver responsible to resolve/open Android content-uri.
---
libavcodec/jni.c | 42 ++++++++++++++++++++++++++++++++++++++++++
libavcodec/jni.h | 17 +++++++++++++++++
2 files changed, 59 insertions(+)
diff --git a/libavcodec/jni.c b/libavcodec/jni.c
index ae6490de9d..cfe95bd1ec 100644
--- a/libavcodec/jni.c
+++ b/libavcodec/jni.c
@@ -77,3 +77,45 @@ void *av_jni_get_java_vm(void *log_ctx)
}
#endif
+
+#if defined(__ANDROID__)
+
+int av_jni_set_android_app_ctx(void *app_ctx, void *log_ctx)
+{
+#if CONFIG_JNI
+ JNIEnv *env = ff_jni_get_env(log_ctx);
+ if (!env)
+ return AVERROR(EINVAL);
+
+ jobjectRefType type = (*env)->GetObjectRefType(env, app_ctx);
+ if (type != JNIGlobalRefType) {
+ av_log(log_ctx, AV_LOG_ERROR, "Application context must be passed as a global reference");
+ return AVERROR(EINVAL);
+ }
+
+ pthread_mutex_lock(&lock);
+ android_app_ctx = app_ctx;
+ pthread_mutex_unlock(&lock);
+
+ return 0;
+#else
+ return AVERROR(ENOSYS);
+#endif
+}
+
+void *av_jni_get_android_app_ctx(void)
+{
+#if CONFIG_JNI
+ void *ctx;
+
+ pthread_mutex_lock(&lock);
+ ctx = android_app_ctx;
+ pthread_mutex_unlock(&lock);
+
+ return ctx;
+#else
+ return NULL;
+#endif
+}
+
+#endif
diff --git a/libavcodec/jni.h b/libavcodec/jni.h
index dd99e92611..da8025f830 100644
--- a/libavcodec/jni.h
+++ b/libavcodec/jni.h
@@ -43,4 +43,21 @@ int av_jni_set_java_vm(void *vm, void *log_ctx);
*/
void *av_jni_get_java_vm(void *log_ctx);
+/*
+ * Set the Android application context which will be used to retrieve the Android
+ * content resolver to resolve content uris.
+ *
+ * @param app_ctx global JNI reference to the Android application context
+ * @return 0 on success, < 0 otherwise
+ */
+int av_jni_set_android_app_ctx(void *app_ctx, void *log_ctx);
+
+/*
+ * Get the Android application context that has been set with
+ * av_jni_set_android_app_ctx.
+ *
+ * @return a pointer the the Android application context
+ */
+void *av_jni_get_android_app_ctx(void);
+
#endif /* AVCODEC_JNI_H */
--
2.44.0
[-- Attachment #3: Type: text/plain, Size: 251 bytes --]
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 51+ messages in thread
* Re: [FFmpeg-devel] [PATCH v2 2/6] avformat: add Android content resolver protocol support
2024-02-27 14:50 ` [FFmpeg-devel] [PATCH v2 2/6] avformat: add Android content resolver protocol support Matthieu Bouron
@ 2024-03-04 19:37 ` Matthieu Bouron
2024-03-17 4:33 ` Zhao Zhili
0 siblings, 1 reply; 51+ messages in thread
From: Matthieu Bouron @ 2024-03-04 19:37 UTC (permalink / raw)
To: ffmpeg-devel
[-- Attachment #1: Type: text/plain, Size: 207 bytes --]
On Tue, Feb 27, 2024 at 03:50:38PM +0100, Matthieu Bouron wrote:
> Handles Android content-uri starting with content://.
> ---
[...]
New patch attached (I moved an unrelated chunk to the previous commit).
[-- Attachment #2: v3-0002-avformat-add-Android-content-resolver-protocol-su.patch --]
[-- Type: text/plain, Size: 8797 bytes --]
From 6ef059b721c1b1635565cc9e7d836be4733c928d Mon Sep 17 00:00:00 2001
From: Matthieu Bouron <matthieu.bouron@gmail.com>
Date: Mon, 12 Feb 2024 23:14:35 +0100
Subject: [PATCH v3 2/6] avformat: add Android content resolver protocol
support
Handles Android content-uri starting with content://.
---
configure | 2 +
doc/APIchanges | 3 +
libavcodec/jni.c | 1 +
libavformat/Makefile | 1 +
libavformat/file.c | 157 ++++++++++++++++++++++++++++++++++++++++
libavformat/protocols.c | 1 +
6 files changed, 165 insertions(+)
diff --git a/configure b/configure
index bb5e630bad..790a1df7c8 100755
--- a/configure
+++ b/configure
@@ -3655,6 +3655,8 @@ xcbgrab_indev_suggest="libxcb_shm libxcb_shape libxcb_xfixes"
xv_outdev_deps="xlib_xv xlib_x11 xlib_xext"
# protocols
+android_content_protocol_deps="jni"
+android_content_protocol_select="file_protocol"
async_protocol_deps="threads"
bluray_protocol_deps="libbluray"
ffrtmpcrypt_protocol_conflict="librtmp_protocol"
diff --git a/doc/APIchanges b/doc/APIchanges
index 10f6667e9e..258e953ca6 100644
--- a/doc/APIchanges
+++ b/doc/APIchanges
@@ -2,6 +2,9 @@ The last version increases of all libraries were on 2023-02-09
API changes, most recent first:
+2024-02-xx - xxxxxxxxxx - lavc 60.41.100 - jni.h
+ Add av_jni_set_android_app_ctx() and av_jni_get_android_app_ctx().
+
2024-02-26 - xxxxxxxxxx - lavf 60.22.101 - avformat.h
AV_DISPOSITION_DEPENDENT may now also be used for video streams
intended to be merged with other video streams for presentation.
diff --git a/libavcodec/jni.c b/libavcodec/jni.c
index cfe95bd1ec..1193c608c3 100644
--- a/libavcodec/jni.c
+++ b/libavcodec/jni.c
@@ -35,6 +35,7 @@
#include "ffjni.h"
static void *java_vm;
+static void *android_app_ctx;
static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
int av_jni_set_java_vm(void *vm, void *log_ctx)
diff --git a/libavformat/Makefile b/libavformat/Makefile
index 4a380668bd..08fe98a535 100644
--- a/libavformat/Makefile
+++ b/libavformat/Makefile
@@ -657,6 +657,7 @@ OBJS-$(CONFIG_LIBOPENMPT_DEMUXER) += libopenmpt.o
OBJS-$(CONFIG_VAPOURSYNTH_DEMUXER) += vapoursynth.o
# protocols I/O
+OBJS-$(CONFIG_ANDROID_CONTENT_PROTOCOL) += file.o
OBJS-$(CONFIG_ASYNC_PROTOCOL) += async.o
OBJS-$(CONFIG_APPLEHTTP_PROTOCOL) += hlsproto.o
OBJS-$(CONFIG_BLURAY_PROTOCOL) += bluray.o
diff --git a/libavformat/file.c b/libavformat/file.c
index 64df7ff6fb..1b2b69f090 100644
--- a/libavformat/file.c
+++ b/libavformat/file.c
@@ -40,6 +40,12 @@
#include <stdlib.h>
#include "os_support.h"
#include "url.h"
+#if CONFIG_ANDROID_CONTENT_PROTOCOL
+#include <jni.h>
+#include "libavcodec/jni.h"
+#include "libavcodec/ffjni.c"
+#endif
+
/* Some systems may not have S_ISFIFO */
#ifndef S_ISFIFO
@@ -101,6 +107,21 @@ typedef struct FileContext {
int64_t initial_pos;
} FileContext;
+
+#if CONFIG_ANDROID_CONTENT_PROTOCOL
+static const AVOption android_content_options[] = {
+ { "blocksize", "set I/O operation maximum block size", offsetof(FileContext, blocksize), AV_OPT_TYPE_INT, { .i64 = INT_MAX }, 1, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM },
+ { NULL }
+};
+
+static const AVClass android_content_class = {
+ .class_name = "android_content",
+ .item_name = av_default_item_name,
+ .option = android_content_options,
+ .version = LIBAVUTIL_VERSION_INT,
+};
+#endif
+
static const AVOption file_options[] = {
{ "truncate", "truncate existing files on write", offsetof(FileContext, trunc), AV_OPT_TYPE_BOOL, { .i64 = 1 }, 0, 1, AV_OPT_FLAG_ENCODING_PARAM },
{ "blocksize", "set I/O operation maximum block size", offsetof(FileContext, blocksize), AV_OPT_TYPE_INT, { .i64 = INT_MAX }, 1, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM },
@@ -524,3 +545,139 @@ const URLProtocol ff_fd_protocol = {
};
#endif /* CONFIG_FD_PROTOCOL */
+
+#if CONFIG_ANDROID_CONTENT_PROTOCOL
+
+struct JFields {
+ jclass uri_class;
+ jmethodID parse_id;
+
+ jclass context_class;
+ jmethodID get_content_resolver_id;
+
+ jclass content_resolver_class;
+ jmethodID open_file_descriptor_id;
+
+ jclass parcel_file_descriptor_class;
+ jmethodID detach_fd_id;
+};
+
+#define OFFSET(x) offsetof(struct JFields, x)
+static const struct FFJniField jfields_mapping[] = {
+ { "android/net/Uri", NULL, NULL, FF_JNI_CLASS, OFFSET(uri_class), 1 },
+ { "android/net/Uri", "parse", "(Ljava/lang/String;)Landroid/net/Uri;", FF_JNI_STATIC_METHOD, OFFSET(parse_id), 1 },
+
+ { "android/content/Context", NULL, NULL, FF_JNI_CLASS, OFFSET(context_class), 1 },
+ { "android/content/Context", "getContentResolver", "()Landroid/content/ContentResolver;", FF_JNI_METHOD, OFFSET(get_content_resolver_id), 1 },
+
+ { "android/content/ContentResolver", NULL, NULL, FF_JNI_CLASS, OFFSET(content_resolver_class), 1 },
+ { "android/content/ContentResolver", "openFileDescriptor", "(Landroid/net/Uri;Ljava/lang/String;)Landroid/os/ParcelFileDescriptor;", FF_JNI_METHOD, OFFSET(open_file_descriptor_id), 1 },
+
+ { "android/os/ParcelFileDescriptor", NULL, NULL, FF_JNI_CLASS, OFFSET(parcel_file_descriptor_class), 1 },
+ { "android/os/ParcelFileDescriptor", "detachFd", "()I", FF_JNI_METHOD, OFFSET(detach_fd_id), 1 },
+
+ { NULL }
+};
+#undef OFFSET
+
+static int android_content_open(URLContext *h, const char *filename, int flags)
+{
+ FileContext *c = h->priv_data;
+ int fd, ret;
+ const char *mode_str = "r";
+
+ JNIEnv *env;
+ struct JFields jfields = { 0 };
+ jobject application_context = NULL;
+ jobject url = NULL;
+ jobject mode = NULL;
+ jobject uri = NULL;
+ jobject content_resolver = NULL;
+ jobject parcel_file_descriptor = NULL;
+
+ env = ff_jni_get_env(c);
+ if (!env) {
+ return AVERROR(EINVAL);
+ }
+
+ ret = ff_jni_init_jfields(env, &jfields, jfields_mapping, 0, c);
+ if (ret < 0) {
+ av_log(c, AV_LOG_ERROR, "failed to initialize jni fields\n");
+ return ret;
+ }
+
+ application_context = av_jni_get_android_app_ctx();
+ if (!application_context) {
+ av_log(c, AV_LOG_ERROR, "application context is not set\n");
+ ret = AVERROR_EXTERNAL;
+ goto done;
+ }
+
+ url = ff_jni_utf_chars_to_jstring(env, filename, c);
+ if (!url) {
+ ret = AVERROR_EXTERNAL;
+ goto done;
+ }
+
+ if (flags & AVIO_FLAG_WRITE && flags & AVIO_FLAG_READ)
+ mode_str = "rw";
+ else if (flags & AVIO_FLAG_WRITE)
+ mode_str = "w";
+
+ mode = ff_jni_utf_chars_to_jstring(env, mode_str, c);
+ if (!mode) {
+ ret = AVERROR_EXTERNAL;
+ goto done;
+ }
+
+ uri = (*env)->CallStaticObjectMethod(env, jfields.uri_class, jfields.parse_id, url);
+ ret = ff_jni_exception_check(env, 1, c);
+ if (ret < 0)
+ goto done;
+
+ content_resolver = (*env)->CallObjectMethod(env, application_context, jfields.get_content_resolver_id);
+ ret = ff_jni_exception_check(env, 1, c);
+ if (ret < 0)
+ goto done;
+
+ parcel_file_descriptor = (*env)->CallObjectMethod(env, content_resolver, jfields.open_file_descriptor_id, uri, mode);
+ ret = ff_jni_exception_check(env, 1, c);
+ if (ret < 0)
+ goto done;
+
+ fd = (*env)->CallIntMethod(env, parcel_file_descriptor, jfields.detach_fd_id);
+ ret = ff_jni_exception_check(env, 1, c);
+ if (ret < 0)
+ goto done;
+
+#if HAVE_SETMODE
+ setmode(fd, O_BINARY);
+#endif
+ c->fd = fd;
+ h->is_streamed = 0;
+
+done:
+ (*env)->DeleteLocalRef(env, url);
+ (*env)->DeleteLocalRef(env, mode);
+ (*env)->DeleteLocalRef(env, uri);
+ (*env)->DeleteLocalRef(env, content_resolver);
+ (*env)->DeleteLocalRef(env, parcel_file_descriptor);
+ ff_jni_reset_jfields(env, &jfields, jfields_mapping, 0, c);
+
+ return ret;
+}
+
+URLProtocol ff_android_content_protocol = {
+ .name = "content",
+ .url_open = android_content_open,
+ .url_read = file_read,
+ .url_write = file_write,
+ .url_seek = file_seek,
+ .url_close = file_close,
+ .url_get_file_handle = file_get_handle,
+ .url_check = NULL,
+ .priv_data_size = sizeof(FileContext),
+ .priv_data_class = &android_content_class,
+};
+
+#endif /* CONFIG_ANDROID_CONTENT_PROTOCOL */
diff --git a/libavformat/protocols.c b/libavformat/protocols.c
index 360018b17c..93a6d67261 100644
--- a/libavformat/protocols.c
+++ b/libavformat/protocols.c
@@ -24,6 +24,7 @@
#include "url.h"
+extern const URLProtocol ff_android_content_protocol;
extern const URLProtocol ff_async_protocol;
extern const URLProtocol ff_bluray_protocol;
extern const URLProtocol ff_cache_protocol;
--
2.44.0
[-- Attachment #3: Type: text/plain, Size: 251 bytes --]
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 51+ messages in thread
* Re: [FFmpeg-devel] [PATCH v2 3/6] avutil/jni: use size_t to store structure offsets
2024-02-27 14:50 ` [FFmpeg-devel] [PATCH v2 3/6] avutil/jni: use size_t to store structure offsets Matthieu Bouron
@ 2024-03-04 20:10 ` Andreas Rheinhardt
2024-03-05 7:58 ` Matthieu Bouron
0 siblings, 1 reply; 51+ messages in thread
From: Andreas Rheinhardt @ 2024-03-04 20:10 UTC (permalink / raw)
To: ffmpeg-devel
Matthieu Bouron:
> ---
> libavcodec/ffjni.h | 3 ++-
> 1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/libavcodec/ffjni.h b/libavcodec/ffjni.h
> index 6027bac0ab..d5894609ed 100644
> --- a/libavcodec/ffjni.h
> +++ b/libavcodec/ffjni.h
> @@ -24,6 +24,7 @@
> #define AVCODEC_FFJNI_H
>
> #include <jni.h>
> +#include <stdlib.h>
>
stddef.h is the "cheaper" header for size_t.
> /*
> * Attach permanently a JNI environment to the current thread and retrieve it.
> @@ -105,7 +106,7 @@ struct FFJniField {
> const char *method;
> const char *signature;
> enum FFJniFieldType type;
> - int offset;
> + size_t offset;
> int mandatory;
>
> };
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 51+ messages in thread
* Re: [FFmpeg-devel] [PATCH v2 3/6] avutil/jni: use size_t to store structure offsets
2024-03-04 20:10 ` Andreas Rheinhardt
@ 2024-03-05 7:58 ` Matthieu Bouron
0 siblings, 0 replies; 51+ messages in thread
From: Matthieu Bouron @ 2024-03-05 7:58 UTC (permalink / raw)
To: FFmpeg development discussions and patches
[-- Attachment #1: Type: text/plain, Size: 521 bytes --]
On Mon, Mar 04, 2024 at 09:10:49PM +0100, Andreas Rheinhardt wrote:
> Matthieu Bouron:
> > ---
> > libavcodec/ffjni.h | 3 ++-
> > 1 file changed, 2 insertions(+), 1 deletion(-)
> >
> > diff --git a/libavcodec/ffjni.h b/libavcodec/ffjni.h
> > index 6027bac0ab..d5894609ed 100644
> > --- a/libavcodec/ffjni.h
> > +++ b/libavcodec/ffjni.h
> > @@ -24,6 +24,7 @@
> > #define AVCODEC_FFJNI_H
> >
> > #include <jni.h>
> > +#include <stdlib.h>
> >
>
> stddef.h is the "cheaper" header for size_t.
New patch attached.
[-- Attachment #2: v3-0003-avcodec-jni-use-size_t-to-store-structure-offsets.patch --]
[-- Type: text/plain, Size: 824 bytes --]
From 0a5f890dcbedf87da3df5b49ece545a847e423a4 Mon Sep 17 00:00:00 2001
From: Matthieu Bouron <matthieu.bouron@gmail.com>
Date: Tue, 13 Feb 2024 11:03:22 +0100
Subject: [PATCH v3 3/6] avcodec/jni: use size_t to store structure offsets
---
libavcodec/ffjni.h | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/libavcodec/ffjni.h b/libavcodec/ffjni.h
index 6027bac0ab..d1e86f8329 100644
--- a/libavcodec/ffjni.h
+++ b/libavcodec/ffjni.h
@@ -24,6 +24,7 @@
#define AVCODEC_FFJNI_H
#include <jni.h>
+#include <stddef.h>
/*
* Attach permanently a JNI environment to the current thread and retrieve it.
@@ -105,7 +106,7 @@ struct FFJniField {
const char *method;
const char *signature;
enum FFJniFieldType type;
- int offset;
+ size_t offset;
int mandatory;
};
--
2.44.0
[-- Attachment #3: Type: text/plain, Size: 251 bytes --]
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 51+ messages in thread
* Re: [FFmpeg-devel] Add protocol for Android content providers (v2)
2024-03-04 8:21 ` [FFmpeg-devel] Add protocol for Android content providers (v2) Matthieu Bouron
@ 2024-03-14 8:04 ` Matthieu Bouron
0 siblings, 0 replies; 51+ messages in thread
From: Matthieu Bouron @ 2024-03-14 8:04 UTC (permalink / raw)
To: ffmpeg-devel
On Mon, Mar 04, 2024 at 09:21:43AM +0100, Matthieu Bouron wrote:
> On Tue, Feb 27, 2024 at 03:50:36PM +0100, Matthieu Bouron wrote:
> > Diff from initial patchset:
> > - directly include libavcodec/ffjni.c from libavformat/file.c instead of
> > migrating ffjni to libavutil (avpriv_*)
> > - check that the passed application context reference is a global one and error
> > out if it's not the case
> >
>
> Ping.
>
> Note: I reworded locally the commit msgs using avutil/jni to avcodec/jni.
If there is no objection, I will push the patchset in a few days.
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 51+ messages in thread
* Re: [FFmpeg-devel] [PATCH v2 2/6] avformat: add Android content resolver protocol support
2024-03-04 19:37 ` Matthieu Bouron
@ 2024-03-17 4:33 ` Zhao Zhili
2024-03-17 22:34 ` Matthieu Bouron
0 siblings, 1 reply; 51+ messages in thread
From: Zhao Zhili @ 2024-03-17 4:33 UTC (permalink / raw)
To: FFmpeg development discussions and patches
Sorry for the long delay of review.
> On Mar 5, 2024, at 03:37, Matthieu Bouron <matthieu.bouron@gmail.com> wrote:
>
> On Tue, Feb 27, 2024 at 03:50:38PM +0100, Matthieu Bouron wrote:
>> Handles Android content-uri starting with content://.
>> ---
>
> [...]
>
> Handles Android content-uri starting with content://.
> ---
> configure | 2 +
> doc/APIchanges | 3 +
> libavcodec/jni.c | 1 +
> libavformat/Makefile | 1 +
> libavformat/file.c | 157 ++++++++++++++++++++++++++++++++++++++++
> libavformat/protocols.c | 1 +
> 6 files changed, 165 insertions(+)
>
> diff --git a/configure b/configure
> index bb5e630bad..790a1df7c8 100755
> --- a/configure
> +++ b/configure
> @@ -3655,6 +3655,8 @@ xcbgrab_indev_suggest="libxcb_shm libxcb_shape libxcb_xfixes"
> xv_outdev_deps="xlib_xv xlib_x11 xlib_xext"
>
> # protocols
> +android_content_protocol_deps="jni"
> +android_content_protocol_select="file_protocol"
> async_protocol_deps="threads"
> bluray_protocol_deps="libbluray"
> ffrtmpcrypt_protocol_conflict="librtmp_protocol"
> diff --git a/doc/APIchanges b/doc/APIchanges
> index 10f6667e9e..258e953ca6 100644
> --- a/doc/APIchanges
> +++ b/doc/APIchanges
> @@ -2,6 +2,9 @@ The last version increases of all libraries were on 2023-02-09
>
> API changes, most recent first:
>
> +2024-02-xx - xxxxxxxxxx - lavc 60.41.100 - jni.h
> + Add av_jni_set_android_app_ctx() and av_jni_get_android_app_ctx().
Should be added together with patch 1/6.
> +
> 2024-02-26 - xxxxxxxxxx - lavf 60.22.101 - avformat.h
> AV_DISPOSITION_DEPENDENT may now also be used for video streams
> intended to be merged with other video streams for presentation.
> diff --git a/libavcodec/jni.c b/libavcodec/jni.c
> index cfe95bd1ec..1193c608c3 100644
> --- a/libavcodec/jni.c
> +++ b/libavcodec/jni.c
> @@ -35,6 +35,7 @@
> #include "ffjni.h"
>
> static void *java_vm;
> +static void *android_app_ctx;
> static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
>
> int av_jni_set_java_vm(void *vm, void *log_ctx)
> diff --git a/libavformat/Makefile b/libavformat/Makefile
> index 4a380668bd..08fe98a535 100644
> --- a/libavformat/Makefile
> +++ b/libavformat/Makefile
> @@ -657,6 +657,7 @@ OBJS-$(CONFIG_LIBOPENMPT_DEMUXER) += libopenmpt.o
> OBJS-$(CONFIG_VAPOURSYNTH_DEMUXER) += vapoursynth.o
>
> # protocols I/O
> +OBJS-$(CONFIG_ANDROID_CONTENT_PROTOCOL) += file.o
> OBJS-$(CONFIG_ASYNC_PROTOCOL) += async.o
> OBJS-$(CONFIG_APPLEHTTP_PROTOCOL) += hlsproto.o
> OBJS-$(CONFIG_BLURAY_PROTOCOL) += bluray.o
> diff --git a/libavformat/file.c b/libavformat/file.c
> index 64df7ff6fb..1b2b69f090 100644
> --- a/libavformat/file.c
> +++ b/libavformat/file.c
> @@ -40,6 +40,12 @@
> #include <stdlib.h>
> #include "os_support.h"
> #include "url.h"
> +#if CONFIG_ANDROID_CONTENT_PROTOCOL
> +#include <jni.h>
> +#include "libavcodec/jni.h"
> +#include "libavcodec/ffjni.c"
> +#endif
> +
>
> /* Some systems may not have S_ISFIFO */
> #ifndef S_ISFIFO
> @@ -101,6 +107,21 @@ typedef struct FileContext {
> int64_t initial_pos;
> } FileContext;
>
> +
> +#if CONFIG_ANDROID_CONTENT_PROTOCOL
> +static const AVOption android_content_options[] = {
> + { "blocksize", "set I/O operation maximum block size", offsetof(FileContext, blocksize), AV_OPT_TYPE_INT, { .i64 = INT_MAX }, 1, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM },
> + { NULL }
> +};
> +
> +static const AVClass android_content_class = {
> + .class_name = "android_content",
> + .item_name = av_default_item_name,
> + .option = android_content_options,
> + .version = LIBAVUTIL_VERSION_INT,
> +};
> +#endif
> +
> static const AVOption file_options[] = {
> { "truncate", "truncate existing files on write", offsetof(FileContext, trunc), AV_OPT_TYPE_BOOL, { .i64 = 1 }, 0, 1, AV_OPT_FLAG_ENCODING_PARAM },
> { "blocksize", "set I/O operation maximum block size", offsetof(FileContext, blocksize), AV_OPT_TYPE_INT, { .i64 = INT_MAX }, 1, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM },
> @@ -524,3 +545,139 @@ const URLProtocol ff_fd_protocol = {
> };
>
> #endif /* CONFIG_FD_PROTOCOL */
> +
> +#if CONFIG_ANDROID_CONTENT_PROTOCOL
> +
> +struct JFields {
> + jclass uri_class;
> + jmethodID parse_id;
> +
> + jclass context_class;
> + jmethodID get_content_resolver_id;
> +
> + jclass content_resolver_class;
> + jmethodID open_file_descriptor_id;
> +
> + jclass parcel_file_descriptor_class;
> + jmethodID detach_fd_id;
> +};
typedef struct is the preferred coding style of FFmpeg, it’s mentioned in
developer.texi.
> +
> +#define OFFSET(x) offsetof(struct JFields, x)
> +static const struct FFJniField jfields_mapping[] = {
> + { "android/net/Uri", NULL, NULL, FF_JNI_CLASS, OFFSET(uri_class), 1 },
> + { "android/net/Uri", "parse", "(Ljava/lang/String;)Landroid/net/Uri;", FF_JNI_STATIC_METHOD, OFFSET(parse_id), 1 },
> +
> + { "android/content/Context", NULL, NULL, FF_JNI_CLASS, OFFSET(context_class), 1 },
> + { "android/content/Context", "getContentResolver", "()Landroid/content/ContentResolver;", FF_JNI_METHOD, OFFSET(get_content_resolver_id), 1 },
> +
> + { "android/content/ContentResolver", NULL, NULL, FF_JNI_CLASS, OFFSET(content_resolver_class), 1 },
> + { "android/content/ContentResolver", "openFileDescriptor", "(Landroid/net/Uri;Ljava/lang/String;)Landroid/os/ParcelFileDescriptor;", FF_JNI_METHOD, OFFSET(open_file_descriptor_id), 1 },
> +
> + { "android/os/ParcelFileDescriptor", NULL, NULL, FF_JNI_CLASS, OFFSET(parcel_file_descriptor_class), 1 },
> + { "android/os/ParcelFileDescriptor", "detachFd", "()I", FF_JNI_METHOD, OFFSET(detach_fd_id), 1 },
> +
> + { NULL }
> +};
> +#undef OFFSET
> +
> +static int android_content_open(URLContext *h, const char *filename, int flags)
> +{
> + FileContext *c = h->priv_data;
> + int fd, ret;
> + const char *mode_str = "r";
> +
> + JNIEnv *env;
> + struct JFields jfields = { 0 };
> + jobject application_context = NULL;
> + jobject url = NULL;
> + jobject mode = NULL;
> + jobject uri = NULL;
> + jobject content_resolver = NULL;
> + jobject parcel_file_descriptor = NULL;
> +
> + env = ff_jni_get_env(c);
> + if (!env) {
> + return AVERROR(EINVAL);
> + }
> +
> + ret = ff_jni_init_jfields(env, &jfields, jfields_mapping, 0, c);
> + if (ret < 0) {
> + av_log(c, AV_LOG_ERROR, "failed to initialize jni fields\n");
> + return ret;
> + }
> +
> + application_context = av_jni_get_android_app_ctx();
> + if (!application_context) {
> + av_log(c, AV_LOG_ERROR, "application context is not set\n");
> + ret = AVERROR_EXTERNAL;
> + goto done;
> + }
> +
> + url = ff_jni_utf_chars_to_jstring(env, filename, c);
> + if (!url) {
> + ret = AVERROR_EXTERNAL;
> + goto done;
> + }
> +
> + if (flags & AVIO_FLAG_WRITE && flags & AVIO_FLAG_READ)
> + mode_str = "rw";
> + else if (flags & AVIO_FLAG_WRITE)
> + mode_str = "w";
> +
> + mode = ff_jni_utf_chars_to_jstring(env, mode_str, c);
> + if (!mode) {
> + ret = AVERROR_EXTERNAL;
> + goto done;
> + }
> +
> + uri = (*env)->CallStaticObjectMethod(env, jfields.uri_class, jfields.parse_id, url);
> + ret = ff_jni_exception_check(env, 1, c);
> + if (ret < 0)
> + goto done;
> +
> + content_resolver = (*env)->CallObjectMethod(env, application_context, jfields.get_content_resolver_id);
> + ret = ff_jni_exception_check(env, 1, c);
> + if (ret < 0)
> + goto done;
> +
> + parcel_file_descriptor = (*env)->CallObjectMethod(env, content_resolver, jfields.open_file_descriptor_id, uri, mode);
> + ret = ff_jni_exception_check(env, 1, c);
> + if (ret < 0)
> + goto done;
> +
> + fd = (*env)->CallIntMethod(env, parcel_file_descriptor, jfields.detach_fd_id);
> + ret = ff_jni_exception_check(env, 1, c);
> + if (ret < 0)
> + goto done;
> +
> +#if HAVE_SETMODE
> + setmode(fd, O_BINARY);
> +#endif
Since it’s android specific protocol, the conditional compile is always false, isn’t it?
> + c->fd = fd;
> + h->is_streamed = 0;
Firstly, is_streamed is default to false, so the above line is unnecessary.
Secondly, I’m not sure whether it’s always seeable.
> +
> +done:
> + (*env)->DeleteLocalRef(env, url);
> + (*env)->DeleteLocalRef(env, mode);
> + (*env)->DeleteLocalRef(env, uri);
> + (*env)->DeleteLocalRef(env, content_resolver);
> + (*env)->DeleteLocalRef(env, parcel_file_descriptor);
> + ff_jni_reset_jfields(env, &jfields, jfields_mapping, 0, c);
> +
> + return ret;
> +}
> +
> +URLProtocol ff_android_content_protocol = {
> + .name = "content",
> + .url_open = android_content_open,
> + .url_read = file_read,
> + .url_write = file_write,
> + .url_seek = file_seek,
> + .url_close = file_close,
> + .url_get_file_handle = file_get_handle,
> + .url_check = NULL,
> + .priv_data_size = sizeof(FileContext),
> + .priv_data_class = &android_content_class,
> +};
> +
> +#endif /* CONFIG_ANDROID_CONTENT_PROTOCOL */
> diff --git a/libavformat/protocols.c b/libavformat/protocols.c
> index 360018b17c..93a6d67261 100644
> --- a/libavformat/protocols.c
> +++ b/libavformat/protocols.c
> @@ -24,6 +24,7 @@
>
> #include "url.h"
>
> +extern const URLProtocol ff_android_content_protocol;
> extern const URLProtocol ff_async_protocol;
> extern const URLProtocol ff_bluray_protocol;
> extern const URLProtocol ff_cache_protocol;
> --
> 2.44.0
>
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 51+ messages in thread
* [FFmpeg-devel] Add protocol for Android content providers (v4)
2024-02-27 14:50 ` [FFmpeg-devel] Add protocol for Android content providers (v2) Matthieu Bouron
` (6 preceding siblings ...)
2024-03-04 8:21 ` [FFmpeg-devel] Add protocol for Android content providers (v2) Matthieu Bouron
@ 2024-03-17 22:28 ` Matthieu Bouron
2024-03-17 22:28 ` [FFmpeg-devel] [PATCH v4 1/6] avcodec: add av_jni_{get, set}_android_app_ctx helper Matthieu Bouron
` (6 more replies)
7 siblings, 7 replies; 51+ messages in thread
From: Matthieu Bouron @ 2024-03-17 22:28 UTC (permalink / raw)
To: ffmpeg-devel
Diff with previous iteration:
- rebaed on latest master
- applied feedback from Zhao (removed HAVE_SETMODE block, use a typedef struct,
check that the fd is seekable, moved doc/APIChanges changes to the right
commit)
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 51+ messages in thread
* [FFmpeg-devel] [PATCH v4 1/6] avcodec: add av_jni_{get, set}_android_app_ctx helper
2024-03-17 22:28 ` [FFmpeg-devel] Add protocol for Android content providers (v4) Matthieu Bouron
@ 2024-03-17 22:28 ` Matthieu Bouron
2024-03-17 22:38 ` Andreas Rheinhardt
2024-03-17 22:28 ` [FFmpeg-devel] [PATCH v4 2/6] avformat: add Android content resolver protocol support Matthieu Bouron
` (5 subsequent siblings)
6 siblings, 1 reply; 51+ messages in thread
From: Matthieu Bouron @ 2024-03-17 22:28 UTC (permalink / raw)
To: ffmpeg-devel; +Cc: Matthieu Bouron
This will allow users to pass the Android ApplicationContext which is mandatory
to retrieve the ContentResolver responsible to resolve/open Android content-uri.
---
doc/APIchanges | 3 +++
libavcodec/jni.c | 42 ++++++++++++++++++++++++++++++++++++++++++
libavcodec/jni.h | 17 +++++++++++++++++
3 files changed, 62 insertions(+)
diff --git a/doc/APIchanges b/doc/APIchanges
index a44c8e4f10..ae1868047e 100644
--- a/doc/APIchanges
+++ b/doc/APIchanges
@@ -2,6 +2,9 @@ The last version increases of all libraries were on 2024-03-07
API changes, most recent first:
+2024-03-xx - xxxxxxxxxx - lavc 61.2.100 - jni.h
+ Add av_jni_set_android_app_ctx() and av_jni_get_android_app_ctx().
+
2024-03-xx - xxxxxxxxxx - lavu 59.2.100 - channel_layout.h
Add AV_CHANNEL_LAYOUT_RETYPE_FLAG_CANONICAL.
diff --git a/libavcodec/jni.c b/libavcodec/jni.c
index ae6490de9d..cfe95bd1ec 100644
--- a/libavcodec/jni.c
+++ b/libavcodec/jni.c
@@ -77,3 +77,45 @@ void *av_jni_get_java_vm(void *log_ctx)
}
#endif
+
+#if defined(__ANDROID__)
+
+int av_jni_set_android_app_ctx(void *app_ctx, void *log_ctx)
+{
+#if CONFIG_JNI
+ JNIEnv *env = ff_jni_get_env(log_ctx);
+ if (!env)
+ return AVERROR(EINVAL);
+
+ jobjectRefType type = (*env)->GetObjectRefType(env, app_ctx);
+ if (type != JNIGlobalRefType) {
+ av_log(log_ctx, AV_LOG_ERROR, "Application context must be passed as a global reference");
+ return AVERROR(EINVAL);
+ }
+
+ pthread_mutex_lock(&lock);
+ android_app_ctx = app_ctx;
+ pthread_mutex_unlock(&lock);
+
+ return 0;
+#else
+ return AVERROR(ENOSYS);
+#endif
+}
+
+void *av_jni_get_android_app_ctx(void)
+{
+#if CONFIG_JNI
+ void *ctx;
+
+ pthread_mutex_lock(&lock);
+ ctx = android_app_ctx;
+ pthread_mutex_unlock(&lock);
+
+ return ctx;
+#else
+ return NULL;
+#endif
+}
+
+#endif
diff --git a/libavcodec/jni.h b/libavcodec/jni.h
index dd99e92611..da8025f830 100644
--- a/libavcodec/jni.h
+++ b/libavcodec/jni.h
@@ -43,4 +43,21 @@ int av_jni_set_java_vm(void *vm, void *log_ctx);
*/
void *av_jni_get_java_vm(void *log_ctx);
+/*
+ * Set the Android application context which will be used to retrieve the Android
+ * content resolver to resolve content uris.
+ *
+ * @param app_ctx global JNI reference to the Android application context
+ * @return 0 on success, < 0 otherwise
+ */
+int av_jni_set_android_app_ctx(void *app_ctx, void *log_ctx);
+
+/*
+ * Get the Android application context that has been set with
+ * av_jni_set_android_app_ctx.
+ *
+ * @return a pointer the the Android application context
+ */
+void *av_jni_get_android_app_ctx(void);
+
#endif /* AVCODEC_JNI_H */
--
2.44.0
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 51+ messages in thread
* [FFmpeg-devel] [PATCH v4 2/6] avformat: add Android content resolver protocol support
2024-03-17 22:28 ` [FFmpeg-devel] Add protocol for Android content providers (v4) Matthieu Bouron
2024-03-17 22:28 ` [FFmpeg-devel] [PATCH v4 1/6] avcodec: add av_jni_{get, set}_android_app_ctx helper Matthieu Bouron
@ 2024-03-17 22:28 ` Matthieu Bouron
2024-03-17 22:28 ` [FFmpeg-devel] [PATCH v4 3/6] avcodec/jni: use size_t to store structure offsets Matthieu Bouron
` (4 subsequent siblings)
6 siblings, 0 replies; 51+ messages in thread
From: Matthieu Bouron @ 2024-03-17 22:28 UTC (permalink / raw)
To: ffmpeg-devel; +Cc: Matthieu Bouron
Handles Android content-uri starting with content://.
---
configure | 2 +
libavcodec/jni.c | 1 +
libavformat/Makefile | 1 +
libavformat/file.c | 160 ++++++++++++++++++++++++++++++++++++++++
libavformat/protocols.c | 1 +
5 files changed, 165 insertions(+)
diff --git a/configure b/configure
index 2b4c4ec9a2..9ef432fddf 100755
--- a/configure
+++ b/configure
@@ -3656,6 +3656,8 @@ xcbgrab_indev_suggest="libxcb_shm libxcb_shape libxcb_xfixes"
xv_outdev_deps="xlib_xv xlib_x11 xlib_xext"
# protocols
+android_content_protocol_deps="jni"
+android_content_protocol_select="file_protocol"
async_protocol_deps="threads"
bluray_protocol_deps="libbluray"
ffrtmpcrypt_protocol_conflict="librtmp_protocol"
diff --git a/libavcodec/jni.c b/libavcodec/jni.c
index cfe95bd1ec..1193c608c3 100644
--- a/libavcodec/jni.c
+++ b/libavcodec/jni.c
@@ -35,6 +35,7 @@
#include "ffjni.h"
static void *java_vm;
+static void *android_app_ctx;
static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
int av_jni_set_java_vm(void *vm, void *log_ctx)
diff --git a/libavformat/Makefile b/libavformat/Makefile
index 94a949f555..44aa485029 100644
--- a/libavformat/Makefile
+++ b/libavformat/Makefile
@@ -658,6 +658,7 @@ OBJS-$(CONFIG_LIBOPENMPT_DEMUXER) += libopenmpt.o
OBJS-$(CONFIG_VAPOURSYNTH_DEMUXER) += vapoursynth.o
# protocols I/O
+OBJS-$(CONFIG_ANDROID_CONTENT_PROTOCOL) += file.o
OBJS-$(CONFIG_ASYNC_PROTOCOL) += async.o
OBJS-$(CONFIG_APPLEHTTP_PROTOCOL) += hlsproto.o
OBJS-$(CONFIG_BLURAY_PROTOCOL) += bluray.o
diff --git a/libavformat/file.c b/libavformat/file.c
index 64df7ff6fb..dd5819c06f 100644
--- a/libavformat/file.c
+++ b/libavformat/file.c
@@ -40,6 +40,12 @@
#include <stdlib.h>
#include "os_support.h"
#include "url.h"
+#if CONFIG_ANDROID_CONTENT_PROTOCOL
+#include <jni.h>
+#include "libavcodec/jni.h"
+#include "libavcodec/ffjni.c"
+#endif
+
/* Some systems may not have S_ISFIFO */
#ifndef S_ISFIFO
@@ -101,6 +107,21 @@ typedef struct FileContext {
int64_t initial_pos;
} FileContext;
+
+#if CONFIG_ANDROID_CONTENT_PROTOCOL
+static const AVOption android_content_options[] = {
+ { "blocksize", "set I/O operation maximum block size", offsetof(FileContext, blocksize), AV_OPT_TYPE_INT, { .i64 = INT_MAX }, 1, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM },
+ { NULL }
+};
+
+static const AVClass android_content_class = {
+ .class_name = "android_content",
+ .item_name = av_default_item_name,
+ .option = android_content_options,
+ .version = LIBAVUTIL_VERSION_INT,
+};
+#endif
+
static const AVOption file_options[] = {
{ "truncate", "truncate existing files on write", offsetof(FileContext, trunc), AV_OPT_TYPE_BOOL, { .i64 = 1 }, 0, 1, AV_OPT_FLAG_ENCODING_PARAM },
{ "blocksize", "set I/O operation maximum block size", offsetof(FileContext, blocksize), AV_OPT_TYPE_INT, { .i64 = INT_MAX }, 1, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM },
@@ -524,3 +545,142 @@ const URLProtocol ff_fd_protocol = {
};
#endif /* CONFIG_FD_PROTOCOL */
+
+#if CONFIG_ANDROID_CONTENT_PROTOCOL
+
+typedef struct JFields {
+ jclass uri_class;
+ jmethodID parse_id;
+
+ jclass context_class;
+ jmethodID get_content_resolver_id;
+
+ jclass content_resolver_class;
+ jmethodID open_file_descriptor_id;
+
+ jclass parcel_file_descriptor_class;
+ jmethodID detach_fd_id;
+} JFields;
+
+#define OFFSET(x) offsetof(JFields, x)
+static const struct FFJniField jfields_mapping[] = {
+ { "android/net/Uri", NULL, NULL, FF_JNI_CLASS, OFFSET(uri_class), 1 },
+ { "android/net/Uri", "parse", "(Ljava/lang/String;)Landroid/net/Uri;", FF_JNI_STATIC_METHOD, OFFSET(parse_id), 1 },
+
+ { "android/content/Context", NULL, NULL, FF_JNI_CLASS, OFFSET(context_class), 1 },
+ { "android/content/Context", "getContentResolver", "()Landroid/content/ContentResolver;", FF_JNI_METHOD, OFFSET(get_content_resolver_id), 1 },
+
+ { "android/content/ContentResolver", NULL, NULL, FF_JNI_CLASS, OFFSET(content_resolver_class), 1 },
+ { "android/content/ContentResolver", "openFileDescriptor", "(Landroid/net/Uri;Ljava/lang/String;)Landroid/os/ParcelFileDescriptor;", FF_JNI_METHOD, OFFSET(open_file_descriptor_id), 1 },
+
+ { "android/os/ParcelFileDescriptor", NULL, NULL, FF_JNI_CLASS, OFFSET(parcel_file_descriptor_class), 1 },
+ { "android/os/ParcelFileDescriptor", "detachFd", "()I", FF_JNI_METHOD, OFFSET(detach_fd_id), 1 },
+
+ { NULL }
+};
+#undef OFFSET
+
+static int android_content_open(URLContext *h, const char *filename, int flags)
+{
+ FileContext *c = h->priv_data;
+ int fd, ret;
+ struct stat st;
+ const char *mode_str = "r";
+
+ JNIEnv *env;
+ JFields jfields = { 0 };
+ jobject application_context = NULL;
+ jobject url = NULL;
+ jobject mode = NULL;
+ jobject uri = NULL;
+ jobject content_resolver = NULL;
+ jobject parcel_file_descriptor = NULL;
+
+ env = ff_jni_get_env(c);
+ if (!env) {
+ return AVERROR(EINVAL);
+ }
+
+ ret = ff_jni_init_jfields(env, &jfields, jfields_mapping, 0, c);
+ if (ret < 0) {
+ av_log(c, AV_LOG_ERROR, "failed to initialize jni fields\n");
+ return ret;
+ }
+
+ application_context = av_jni_get_android_app_ctx();
+ if (!application_context) {
+ av_log(c, AV_LOG_ERROR, "application context is not set\n");
+ ret = AVERROR_EXTERNAL;
+ goto done;
+ }
+
+ url = ff_jni_utf_chars_to_jstring(env, filename, c);
+ if (!url) {
+ ret = AVERROR_EXTERNAL;
+ goto done;
+ }
+
+ if (flags & AVIO_FLAG_WRITE && flags & AVIO_FLAG_READ)
+ mode_str = "rw";
+ else if (flags & AVIO_FLAG_WRITE)
+ mode_str = "w";
+
+ mode = ff_jni_utf_chars_to_jstring(env, mode_str, c);
+ if (!mode) {
+ ret = AVERROR_EXTERNAL;
+ goto done;
+ }
+
+ uri = (*env)->CallStaticObjectMethod(env, jfields.uri_class, jfields.parse_id, url);
+ ret = ff_jni_exception_check(env, 1, c);
+ if (ret < 0)
+ goto done;
+
+ content_resolver = (*env)->CallObjectMethod(env, application_context, jfields.get_content_resolver_id);
+ ret = ff_jni_exception_check(env, 1, c);
+ if (ret < 0)
+ goto done;
+
+ parcel_file_descriptor = (*env)->CallObjectMethod(env, content_resolver, jfields.open_file_descriptor_id, uri, mode);
+ ret = ff_jni_exception_check(env, 1, c);
+ if (ret < 0)
+ goto done;
+
+ fd = (*env)->CallIntMethod(env, parcel_file_descriptor, jfields.detach_fd_id);
+ ret = ff_jni_exception_check(env, 1, c);
+ if (ret < 0)
+ goto done;
+
+ if (fstat(fd, &st) < 0) {
+ close(fd);
+ return AVERROR(errno);
+ }
+
+ c->fd = fd;
+ h->is_streamed = !(S_ISREG(st.st_mode) || S_ISBLK(st.st_mode));
+
+done:
+ (*env)->DeleteLocalRef(env, url);
+ (*env)->DeleteLocalRef(env, mode);
+ (*env)->DeleteLocalRef(env, uri);
+ (*env)->DeleteLocalRef(env, content_resolver);
+ (*env)->DeleteLocalRef(env, parcel_file_descriptor);
+ ff_jni_reset_jfields(env, &jfields, jfields_mapping, 0, c);
+
+ return ret;
+}
+
+URLProtocol ff_android_content_protocol = {
+ .name = "content",
+ .url_open = android_content_open,
+ .url_read = file_read,
+ .url_write = file_write,
+ .url_seek = file_seek,
+ .url_close = file_close,
+ .url_get_file_handle = file_get_handle,
+ .url_check = NULL,
+ .priv_data_size = sizeof(FileContext),
+ .priv_data_class = &android_content_class,
+};
+
+#endif /* CONFIG_ANDROID_CONTENT_PROTOCOL */
diff --git a/libavformat/protocols.c b/libavformat/protocols.c
index 360018b17c..93a6d67261 100644
--- a/libavformat/protocols.c
+++ b/libavformat/protocols.c
@@ -24,6 +24,7 @@
#include "url.h"
+extern const URLProtocol ff_android_content_protocol;
extern const URLProtocol ff_async_protocol;
extern const URLProtocol ff_bluray_protocol;
extern const URLProtocol ff_cache_protocol;
--
2.44.0
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 51+ messages in thread
* [FFmpeg-devel] [PATCH v4 3/6] avcodec/jni: use size_t to store structure offsets
2024-03-17 22:28 ` [FFmpeg-devel] Add protocol for Android content providers (v4) Matthieu Bouron
2024-03-17 22:28 ` [FFmpeg-devel] [PATCH v4 1/6] avcodec: add av_jni_{get, set}_android_app_ctx helper Matthieu Bouron
2024-03-17 22:28 ` [FFmpeg-devel] [PATCH v4 2/6] avformat: add Android content resolver protocol support Matthieu Bouron
@ 2024-03-17 22:28 ` Matthieu Bouron
2024-03-17 22:28 ` [FFmpeg-devel] [PATCH v4 4/6] avcodec/jni: remove unnecessary NULL checks before calling DeleteLocalRef() Matthieu Bouron
` (3 subsequent siblings)
6 siblings, 0 replies; 51+ messages in thread
From: Matthieu Bouron @ 2024-03-17 22:28 UTC (permalink / raw)
To: ffmpeg-devel; +Cc: Matthieu Bouron
---
libavcodec/ffjni.h | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/libavcodec/ffjni.h b/libavcodec/ffjni.h
index 6027bac0ab..d1e86f8329 100644
--- a/libavcodec/ffjni.h
+++ b/libavcodec/ffjni.h
@@ -24,6 +24,7 @@
#define AVCODEC_FFJNI_H
#include <jni.h>
+#include <stddef.h>
/*
* Attach permanently a JNI environment to the current thread and retrieve it.
@@ -105,7 +106,7 @@ struct FFJniField {
const char *method;
const char *signature;
enum FFJniFieldType type;
- int offset;
+ size_t offset;
int mandatory;
};
--
2.44.0
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 51+ messages in thread
* [FFmpeg-devel] [PATCH v4 4/6] avcodec/jni: remove unnecessary NULL checks before calling DeleteLocalRef()
2024-03-17 22:28 ` [FFmpeg-devel] Add protocol for Android content providers (v4) Matthieu Bouron
` (2 preceding siblings ...)
2024-03-17 22:28 ` [FFmpeg-devel] [PATCH v4 3/6] avcodec/jni: use size_t to store structure offsets Matthieu Bouron
@ 2024-03-17 22:28 ` Matthieu Bouron
2024-03-17 22:28 ` [FFmpeg-devel] [PATCH v4 5/6] avcodec/mediacodec_wrapper: use an OFFSET() macro where relevant Matthieu Bouron
` (2 subsequent siblings)
6 siblings, 0 replies; 51+ messages in thread
From: Matthieu Bouron @ 2024-03-17 22:28 UTC (permalink / raw)
To: ffmpeg-devel; +Cc: Matthieu Bouron
Delete{Global,Local}Ref() already handle NULL.
---
libavcodec/ffjni.c | 14 +++-----------
1 file changed, 3 insertions(+), 11 deletions(-)
diff --git a/libavcodec/ffjni.c b/libavcodec/ffjni.c
index e3cf24d3e2..69d9a9faa3 100644
--- a/libavcodec/ffjni.c
+++ b/libavcodec/ffjni.c
@@ -236,17 +236,9 @@ done:
av_free(name);
av_free(message);
- if (class_class) {
- (*env)->DeleteLocalRef(env, class_class);
- }
-
- if (exception_class) {
- (*env)->DeleteLocalRef(env, exception_class);
- }
-
- if (string) {
- (*env)->DeleteLocalRef(env, string);
- }
+ (*env)->DeleteLocalRef(env, class_class);
+ (*env)->DeleteLocalRef(env, exception_class);
+ (*env)->DeleteLocalRef(env, string);
return ret;
}
--
2.44.0
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 51+ messages in thread
* [FFmpeg-devel] [PATCH v4 5/6] avcodec/mediacodec_wrapper: use an OFFSET() macro where relevant
2024-03-17 22:28 ` [FFmpeg-devel] Add protocol for Android content providers (v4) Matthieu Bouron
` (3 preceding siblings ...)
2024-03-17 22:28 ` [FFmpeg-devel] [PATCH v4 4/6] avcodec/jni: remove unnecessary NULL checks before calling DeleteLocalRef() Matthieu Bouron
@ 2024-03-17 22:28 ` Matthieu Bouron
2024-03-17 22:28 ` [FFmpeg-devel] [PATCH v4 6/6] avcodec/mediacodec_wrapper: remove unnecessary NULL checks before calling Delete{Global, Local}Ref() Matthieu Bouron
2024-03-19 17:49 ` [FFmpeg-devel] Add protocol for Android content providers (v4) Matthieu Bouron
6 siblings, 0 replies; 51+ messages in thread
From: Matthieu Bouron @ 2024-03-17 22:28 UTC (permalink / raw)
To: ffmpeg-devel; +Cc: Matthieu Bouron
Reduces a bit the horizontal spacing.
---
libavcodec/mediacodec_wrapper.c | 138 +++++++++++++++++---------------
1 file changed, 72 insertions(+), 66 deletions(-)
diff --git a/libavcodec/mediacodec_wrapper.c b/libavcodec/mediacodec_wrapper.c
index 0880ddd3ef..78cd28f53d 100644
--- a/libavcodec/mediacodec_wrapper.c
+++ b/libavcodec/mediacodec_wrapper.c
@@ -60,31 +60,33 @@ struct JNIAMediaCodecListFields {
jfieldID level_id;
};
+#define OFFSET(x) offsetof(struct JNIAMediaCodecListFields, x)
static const struct FFJniField jni_amediacodeclist_mapping[] = {
- { "android/media/MediaCodecList", NULL, NULL, FF_JNI_CLASS, offsetof(struct JNIAMediaCodecListFields, mediacodec_list_class), 1 },
- { "android/media/MediaCodecList", "<init>", "(I)V", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecListFields, init_id), 0 },
- { "android/media/MediaCodecList", "findDecoderForFormat", "(Landroid/media/MediaFormat;)Ljava/lang/String;", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecListFields, find_decoder_for_format_id), 0 },
+ { "android/media/MediaCodecList", NULL, NULL, FF_JNI_CLASS, OFFSET(mediacodec_list_class), 1 },
+ { "android/media/MediaCodecList", "<init>", "(I)V", FF_JNI_METHOD, OFFSET(init_id), 0 },
+ { "android/media/MediaCodecList", "findDecoderForFormat", "(Landroid/media/MediaFormat;)Ljava/lang/String;", FF_JNI_METHOD, OFFSET(find_decoder_for_format_id), 0 },
- { "android/media/MediaCodecList", "getCodecCount", "()I", FF_JNI_STATIC_METHOD, offsetof(struct JNIAMediaCodecListFields, get_codec_count_id), 1 },
- { "android/media/MediaCodecList", "getCodecInfoAt", "(I)Landroid/media/MediaCodecInfo;", FF_JNI_STATIC_METHOD, offsetof(struct JNIAMediaCodecListFields, get_codec_info_at_id), 1 },
+ { "android/media/MediaCodecList", "getCodecCount", "()I", FF_JNI_STATIC_METHOD, OFFSET(get_codec_count_id), 1 },
+ { "android/media/MediaCodecList", "getCodecInfoAt", "(I)Landroid/media/MediaCodecInfo;", FF_JNI_STATIC_METHOD, OFFSET(get_codec_info_at_id), 1 },
- { "android/media/MediaCodecInfo", NULL, NULL, FF_JNI_CLASS, offsetof(struct JNIAMediaCodecListFields, mediacodec_info_class), 1 },
- { "android/media/MediaCodecInfo", "getName", "()Ljava/lang/String;", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecListFields, get_name_id), 1 },
- { "android/media/MediaCodecInfo", "getCapabilitiesForType", "(Ljava/lang/String;)Landroid/media/MediaCodecInfo$CodecCapabilities;", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecListFields, get_codec_capabilities_id), 1 },
- { "android/media/MediaCodecInfo", "getSupportedTypes", "()[Ljava/lang/String;", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecListFields, get_supported_types_id), 1 },
- { "android/media/MediaCodecInfo", "isEncoder", "()Z", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecListFields, is_encoder_id), 1 },
- { "android/media/MediaCodecInfo", "isSoftwareOnly", "()Z", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecListFields, is_software_only_id), 0 },
+ { "android/media/MediaCodecInfo", NULL, NULL, FF_JNI_CLASS, OFFSET(mediacodec_info_class), 1 },
+ { "android/media/MediaCodecInfo", "getName", "()Ljava/lang/String;", FF_JNI_METHOD, OFFSET(get_name_id), 1 },
+ { "android/media/MediaCodecInfo", "getCapabilitiesForType", "(Ljava/lang/String;)Landroid/media/MediaCodecInfo$CodecCapabilities;", FF_JNI_METHOD, OFFSET(get_codec_capabilities_id), 1 },
+ { "android/media/MediaCodecInfo", "getSupportedTypes", "()[Ljava/lang/String;", FF_JNI_METHOD, OFFSET(get_supported_types_id), 1 },
+ { "android/media/MediaCodecInfo", "isEncoder", "()Z", FF_JNI_METHOD, OFFSET(is_encoder_id), 1 },
+ { "android/media/MediaCodecInfo", "isSoftwareOnly", "()Z", FF_JNI_METHOD, OFFSET(is_software_only_id), 0 },
- { "android/media/MediaCodecInfo$CodecCapabilities", NULL, NULL, FF_JNI_CLASS, offsetof(struct JNIAMediaCodecListFields, codec_capabilities_class), 1 },
- { "android/media/MediaCodecInfo$CodecCapabilities", "colorFormats", "[I", FF_JNI_FIELD, offsetof(struct JNIAMediaCodecListFields, color_formats_id), 1 },
- { "android/media/MediaCodecInfo$CodecCapabilities", "profileLevels", "[Landroid/media/MediaCodecInfo$CodecProfileLevel;", FF_JNI_FIELD, offsetof(struct JNIAMediaCodecListFields, profile_levels_id), 1 },
+ { "android/media/MediaCodecInfo$CodecCapabilities", NULL, NULL, FF_JNI_CLASS, OFFSET(codec_capabilities_class), 1 },
+ { "android/media/MediaCodecInfo$CodecCapabilities", "colorFormats", "[I", FF_JNI_FIELD, OFFSET(color_formats_id), 1 },
+ { "android/media/MediaCodecInfo$CodecCapabilities", "profileLevels", "[Landroid/media/MediaCodecInfo$CodecProfileLevel;", FF_JNI_FIELD, OFFSET(profile_levels_id), 1 },
- { "android/media/MediaCodecInfo$CodecProfileLevel", NULL, NULL, FF_JNI_CLASS, offsetof(struct JNIAMediaCodecListFields, codec_profile_level_class), 1 },
- { "android/media/MediaCodecInfo$CodecProfileLevel", "profile", "I", FF_JNI_FIELD, offsetof(struct JNIAMediaCodecListFields, profile_id), 1 },
- { "android/media/MediaCodecInfo$CodecProfileLevel", "level", "I", FF_JNI_FIELD, offsetof(struct JNIAMediaCodecListFields, level_id), 1 },
+ { "android/media/MediaCodecInfo$CodecProfileLevel", NULL, NULL, FF_JNI_CLASS, OFFSET(codec_profile_level_class), 1 },
+ { "android/media/MediaCodecInfo$CodecProfileLevel", "profile", "I", FF_JNI_FIELD, OFFSET(profile_id), 1 },
+ { "android/media/MediaCodecInfo$CodecProfileLevel", "level", "I", FF_JNI_FIELD, OFFSET(level_id), 1 },
{ NULL }
};
+#undef OFFSET
struct JNIAMediaFormatFields {
@@ -110,29 +112,31 @@ struct JNIAMediaFormatFields {
};
+#define OFFSET(x) offsetof(struct JNIAMediaFormatFields, x)
static const struct FFJniField jni_amediaformat_mapping[] = {
- { "android/media/MediaFormat", NULL, NULL, FF_JNI_CLASS, offsetof(struct JNIAMediaFormatFields, mediaformat_class), 1 },
+ { "android/media/MediaFormat", NULL, NULL, FF_JNI_CLASS, OFFSET(mediaformat_class), 1 },
- { "android/media/MediaFormat", "<init>", "()V", FF_JNI_METHOD, offsetof(struct JNIAMediaFormatFields, init_id), 1 },
+ { "android/media/MediaFormat", "<init>", "()V", FF_JNI_METHOD, OFFSET(init_id), 1 },
- { "android/media/MediaFormat", "containsKey", "(Ljava/lang/String;)Z", FF_JNI_METHOD,offsetof(struct JNIAMediaFormatFields, contains_key_id), 1 },
+ { "android/media/MediaFormat", "containsKey", "(Ljava/lang/String;)Z", FF_JNI_METHOD, OFFSET(contains_key_id), 1 },
- { "android/media/MediaFormat", "getInteger", "(Ljava/lang/String;)I", FF_JNI_METHOD, offsetof(struct JNIAMediaFormatFields, get_integer_id), 1 },
- { "android/media/MediaFormat", "getLong", "(Ljava/lang/String;)J", FF_JNI_METHOD, offsetof(struct JNIAMediaFormatFields, get_long_id), 1 },
- { "android/media/MediaFormat", "getFloat", "(Ljava/lang/String;)F", FF_JNI_METHOD, offsetof(struct JNIAMediaFormatFields, get_float_id), 1 },
- { "android/media/MediaFormat", "getByteBuffer", "(Ljava/lang/String;)Ljava/nio/ByteBuffer;", FF_JNI_METHOD, offsetof(struct JNIAMediaFormatFields, get_bytebuffer_id), 1 },
- { "android/media/MediaFormat", "getString", "(Ljava/lang/String;)Ljava/lang/String;", FF_JNI_METHOD, offsetof(struct JNIAMediaFormatFields, get_string_id), 1 },
+ { "android/media/MediaFormat", "getInteger", "(Ljava/lang/String;)I", FF_JNI_METHOD, OFFSET(get_integer_id), 1 },
+ { "android/media/MediaFormat", "getLong", "(Ljava/lang/String;)J", FF_JNI_METHOD, OFFSET(get_long_id), 1 },
+ { "android/media/MediaFormat", "getFloat", "(Ljava/lang/String;)F", FF_JNI_METHOD, OFFSET(get_float_id), 1 },
+ { "android/media/MediaFormat", "getByteBuffer", "(Ljava/lang/String;)Ljava/nio/ByteBuffer;", FF_JNI_METHOD, OFFSET(get_bytebuffer_id), 1 },
+ { "android/media/MediaFormat", "getString", "(Ljava/lang/String;)Ljava/lang/String;", FF_JNI_METHOD, OFFSET(get_string_id), 1 },
- { "android/media/MediaFormat", "setInteger", "(Ljava/lang/String;I)V", FF_JNI_METHOD, offsetof(struct JNIAMediaFormatFields, set_integer_id), 1 },
- { "android/media/MediaFormat", "setLong", "(Ljava/lang/String;J)V", FF_JNI_METHOD, offsetof(struct JNIAMediaFormatFields, set_long_id), 1 },
- { "android/media/MediaFormat", "setFloat", "(Ljava/lang/String;F)V", FF_JNI_METHOD, offsetof(struct JNIAMediaFormatFields, set_float_id), 1 },
- { "android/media/MediaFormat", "setByteBuffer", "(Ljava/lang/String;Ljava/nio/ByteBuffer;)V", FF_JNI_METHOD, offsetof(struct JNIAMediaFormatFields, set_bytebuffer_id), 1 },
- { "android/media/MediaFormat", "setString", "(Ljava/lang/String;Ljava/lang/String;)V", FF_JNI_METHOD, offsetof(struct JNIAMediaFormatFields, set_string_id), 1 },
+ { "android/media/MediaFormat", "setInteger", "(Ljava/lang/String;I)V", FF_JNI_METHOD, OFFSET(set_integer_id), 1 },
+ { "android/media/MediaFormat", "setLong", "(Ljava/lang/String;J)V", FF_JNI_METHOD, OFFSET(set_long_id), 1 },
+ { "android/media/MediaFormat", "setFloat", "(Ljava/lang/String;F)V", FF_JNI_METHOD, OFFSET(set_float_id), 1 },
+ { "android/media/MediaFormat", "setByteBuffer", "(Ljava/lang/String;Ljava/nio/ByteBuffer;)V", FF_JNI_METHOD, OFFSET(set_bytebuffer_id), 1 },
+ { "android/media/MediaFormat", "setString", "(Ljava/lang/String;Ljava/lang/String;)V", FF_JNI_METHOD, OFFSET(set_string_id), 1 },
- { "android/media/MediaFormat", "toString", "()Ljava/lang/String;", FF_JNI_METHOD, offsetof(struct JNIAMediaFormatFields, to_string_id), 1 },
+ { "android/media/MediaFormat", "toString", "()Ljava/lang/String;", FF_JNI_METHOD, OFFSET(to_string_id), 1 },
{ NULL }
};
+#undef OFFSET
static const AVClass amediaformat_class = {
.class_name = "amediaformat",
@@ -202,57 +206,59 @@ struct JNIAMediaCodecFields {
};
+#define OFFSET(x) offsetof(struct JNIAMediaCodecFields, x)
static const struct FFJniField jni_amediacodec_mapping[] = {
- { "android/media/MediaCodec", NULL, NULL, FF_JNI_CLASS, offsetof(struct JNIAMediaCodecFields, mediacodec_class), 1 },
+ { "android/media/MediaCodec", NULL, NULL, FF_JNI_CLASS, OFFSET(mediacodec_class), 1 },
- { "android/media/MediaCodec", "INFO_TRY_AGAIN_LATER", "I", FF_JNI_STATIC_FIELD, offsetof(struct JNIAMediaCodecFields, info_try_again_later_id), 1 },
- { "android/media/MediaCodec", "INFO_OUTPUT_BUFFERS_CHANGED", "I", FF_JNI_STATIC_FIELD, offsetof(struct JNIAMediaCodecFields, info_output_buffers_changed_id), 1 },
- { "android/media/MediaCodec", "INFO_OUTPUT_FORMAT_CHANGED", "I", FF_JNI_STATIC_FIELD, offsetof(struct JNIAMediaCodecFields, info_output_format_changed_id), 1 },
+ { "android/media/MediaCodec", "INFO_TRY_AGAIN_LATER", "I", FF_JNI_STATIC_FIELD, OFFSET(info_try_again_later_id), 1 },
+ { "android/media/MediaCodec", "INFO_OUTPUT_BUFFERS_CHANGED", "I", FF_JNI_STATIC_FIELD, OFFSET(info_output_buffers_changed_id), 1 },
+ { "android/media/MediaCodec", "INFO_OUTPUT_FORMAT_CHANGED", "I", FF_JNI_STATIC_FIELD, OFFSET(info_output_format_changed_id), 1 },
- { "android/media/MediaCodec", "BUFFER_FLAG_CODEC_CONFIG", "I", FF_JNI_STATIC_FIELD, offsetof(struct JNIAMediaCodecFields, buffer_flag_codec_config_id), 1 },
- { "android/media/MediaCodec", "BUFFER_FLAG_END_OF_STREAM", "I", FF_JNI_STATIC_FIELD, offsetof(struct JNIAMediaCodecFields, buffer_flag_end_of_stream_id), 1 },
- { "android/media/MediaCodec", "BUFFER_FLAG_KEY_FRAME", "I", FF_JNI_STATIC_FIELD, offsetof(struct JNIAMediaCodecFields, buffer_flag_key_frame_id), 0 },
+ { "android/media/MediaCodec", "BUFFER_FLAG_CODEC_CONFIG", "I", FF_JNI_STATIC_FIELD, OFFSET(buffer_flag_codec_config_id), 1 },
+ { "android/media/MediaCodec", "BUFFER_FLAG_END_OF_STREAM", "I", FF_JNI_STATIC_FIELD, OFFSET(buffer_flag_end_of_stream_id), 1 },
+ { "android/media/MediaCodec", "BUFFER_FLAG_KEY_FRAME", "I", FF_JNI_STATIC_FIELD, OFFSET(buffer_flag_key_frame_id), 0 },
- { "android/media/MediaCodec", "CONFIGURE_FLAG_ENCODE", "I", FF_JNI_STATIC_FIELD, offsetof(struct JNIAMediaCodecFields, configure_flag_encode_id), 1 },
+ { "android/media/MediaCodec", "CONFIGURE_FLAG_ENCODE", "I", FF_JNI_STATIC_FIELD, OFFSET(configure_flag_encode_id), 1 },
- { "android/media/MediaCodec", "createByCodecName", "(Ljava/lang/String;)Landroid/media/MediaCodec;", FF_JNI_STATIC_METHOD, offsetof(struct JNIAMediaCodecFields, create_by_codec_name_id), 1 },
- { "android/media/MediaCodec", "createDecoderByType", "(Ljava/lang/String;)Landroid/media/MediaCodec;", FF_JNI_STATIC_METHOD, offsetof(struct JNIAMediaCodecFields, create_decoder_by_type_id), 1 },
- { "android/media/MediaCodec", "createEncoderByType", "(Ljava/lang/String;)Landroid/media/MediaCodec;", FF_JNI_STATIC_METHOD, offsetof(struct JNIAMediaCodecFields, create_encoder_by_type_id), 1 },
+ { "android/media/MediaCodec", "createByCodecName", "(Ljava/lang/String;)Landroid/media/MediaCodec;", FF_JNI_STATIC_METHOD, OFFSET(create_by_codec_name_id), 1 },
+ { "android/media/MediaCodec", "createDecoderByType", "(Ljava/lang/String;)Landroid/media/MediaCodec;", FF_JNI_STATIC_METHOD, OFFSET(create_decoder_by_type_id), 1 },
+ { "android/media/MediaCodec", "createEncoderByType", "(Ljava/lang/String;)Landroid/media/MediaCodec;", FF_JNI_STATIC_METHOD, OFFSET(create_encoder_by_type_id), 1 },
- { "android/media/MediaCodec", "getName", "()Ljava/lang/String;", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecFields, get_name_id), 1 },
+ { "android/media/MediaCodec", "getName", "()Ljava/lang/String;", FF_JNI_METHOD, OFFSET(get_name_id), 1 },
- { "android/media/MediaCodec", "configure", "(Landroid/media/MediaFormat;Landroid/view/Surface;Landroid/media/MediaCrypto;I)V", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecFields, configure_id), 1 },
- { "android/media/MediaCodec", "start", "()V", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecFields, start_id), 1 },
- { "android/media/MediaCodec", "flush", "()V", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecFields, flush_id), 1 },
- { "android/media/MediaCodec", "stop", "()V", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecFields, stop_id), 1 },
- { "android/media/MediaCodec", "release", "()V", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecFields, release_id), 1 },
+ { "android/media/MediaCodec", "configure", "(Landroid/media/MediaFormat;Landroid/view/Surface;Landroid/media/MediaCrypto;I)V", FF_JNI_METHOD, OFFSET(configure_id), 1 },
+ { "android/media/MediaCodec", "start", "()V", FF_JNI_METHOD, OFFSET(start_id), 1 },
+ { "android/media/MediaCodec", "flush", "()V", FF_JNI_METHOD, OFFSET(flush_id), 1 },
+ { "android/media/MediaCodec", "stop", "()V", FF_JNI_METHOD, OFFSET(stop_id), 1 },
+ { "android/media/MediaCodec", "release", "()V", FF_JNI_METHOD, OFFSET(release_id), 1 },
- { "android/media/MediaCodec", "getOutputFormat", "()Landroid/media/MediaFormat;", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecFields, get_output_format_id), 1 },
+ { "android/media/MediaCodec", "getOutputFormat", "()Landroid/media/MediaFormat;", FF_JNI_METHOD, OFFSET(get_output_format_id), 1 },
- { "android/media/MediaCodec", "dequeueInputBuffer", "(J)I", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecFields, dequeue_input_buffer_id), 1 },
- { "android/media/MediaCodec", "queueInputBuffer", "(IIIJI)V", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecFields, queue_input_buffer_id), 1 },
- { "android/media/MediaCodec", "getInputBuffer", "(I)Ljava/nio/ByteBuffer;", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecFields, get_input_buffer_id), 0 },
- { "android/media/MediaCodec", "getInputBuffers", "()[Ljava/nio/ByteBuffer;", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecFields, get_input_buffers_id), 1 },
+ { "android/media/MediaCodec", "dequeueInputBuffer", "(J)I", FF_JNI_METHOD, OFFSET(dequeue_input_buffer_id), 1 },
+ { "android/media/MediaCodec", "queueInputBuffer", "(IIIJI)V", FF_JNI_METHOD, OFFSET(queue_input_buffer_id), 1 },
+ { "android/media/MediaCodec", "getInputBuffer", "(I)Ljava/nio/ByteBuffer;", FF_JNI_METHOD, OFFSET(get_input_buffer_id), 0 },
+ { "android/media/MediaCodec", "getInputBuffers", "()[Ljava/nio/ByteBuffer;", FF_JNI_METHOD, OFFSET(get_input_buffers_id), 1 },
- { "android/media/MediaCodec", "dequeueOutputBuffer", "(Landroid/media/MediaCodec$BufferInfo;J)I", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecFields, dequeue_output_buffer_id), 1 },
- { "android/media/MediaCodec", "getOutputBuffer", "(I)Ljava/nio/ByteBuffer;", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecFields, get_output_buffer_id), 0 },
- { "android/media/MediaCodec", "getOutputBuffers", "()[Ljava/nio/ByteBuffer;", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecFields, get_output_buffers_id), 1 },
- { "android/media/MediaCodec", "releaseOutputBuffer", "(IZ)V", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecFields, release_output_buffer_id), 1 },
- { "android/media/MediaCodec", "releaseOutputBuffer", "(IJ)V", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecFields, release_output_buffer_at_time_id), 0 },
+ { "android/media/MediaCodec", "dequeueOutputBuffer", "(Landroid/media/MediaCodec$BufferInfo;J)I", FF_JNI_METHOD, OFFSET(dequeue_output_buffer_id), 1 },
+ { "android/media/MediaCodec", "getOutputBuffer", "(I)Ljava/nio/ByteBuffer;", FF_JNI_METHOD, OFFSET(get_output_buffer_id), 0 },
+ { "android/media/MediaCodec", "getOutputBuffers", "()[Ljava/nio/ByteBuffer;", FF_JNI_METHOD, OFFSET(get_output_buffers_id), 1 },
+ { "android/media/MediaCodec", "releaseOutputBuffer", "(IZ)V", FF_JNI_METHOD, OFFSET(release_output_buffer_id), 1 },
+ { "android/media/MediaCodec", "releaseOutputBuffer", "(IJ)V", FF_JNI_METHOD, OFFSET(release_output_buffer_at_time_id), 0 },
- { "android/media/MediaCodec", "setInputSurface", "(Landroid/view/Surface;)V", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecFields, set_input_surface_id), 0 },
- { "android/media/MediaCodec", "signalEndOfInputStream", "()V", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecFields, signal_end_of_input_stream_id), 0 },
+ { "android/media/MediaCodec", "setInputSurface", "(Landroid/view/Surface;)V", FF_JNI_METHOD, OFFSET(set_input_surface_id), 0 },
+ { "android/media/MediaCodec", "signalEndOfInputStream", "()V", FF_JNI_METHOD, OFFSET(signal_end_of_input_stream_id), 0 },
- { "android/media/MediaCodec$BufferInfo", NULL, NULL, FF_JNI_CLASS, offsetof(struct JNIAMediaCodecFields, mediainfo_class), 1 },
+ { "android/media/MediaCodec$BufferInfo", NULL, NULL, FF_JNI_CLASS, OFFSET(mediainfo_class), 1 },
- { "android/media/MediaCodec.BufferInfo", "<init>", "()V", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecFields, init_id), 1 },
- { "android/media/MediaCodec.BufferInfo", "flags", "I", FF_JNI_FIELD, offsetof(struct JNIAMediaCodecFields, flags_id), 1 },
- { "android/media/MediaCodec.BufferInfo", "offset", "I", FF_JNI_FIELD, offsetof(struct JNIAMediaCodecFields, offset_id), 1 },
- { "android/media/MediaCodec.BufferInfo", "presentationTimeUs", "J", FF_JNI_FIELD, offsetof(struct JNIAMediaCodecFields, presentation_time_us_id), 1 },
- { "android/media/MediaCodec.BufferInfo", "size", "I", FF_JNI_FIELD, offsetof(struct JNIAMediaCodecFields, size_id), 1 },
+ { "android/media/MediaCodec.BufferInfo", "<init>", "()V", FF_JNI_METHOD, OFFSET(init_id), 1 },
+ { "android/media/MediaCodec.BufferInfo", "flags", "I", FF_JNI_FIELD, OFFSET(flags_id), 1 },
+ { "android/media/MediaCodec.BufferInfo", "offset", "I", FF_JNI_FIELD, OFFSET(offset_id), 1 },
+ { "android/media/MediaCodec.BufferInfo", "presentationTimeUs", "J", FF_JNI_FIELD, OFFSET(presentation_time_us_id), 1 },
+ { "android/media/MediaCodec.BufferInfo", "size", "I", FF_JNI_FIELD, OFFSET(size_id), 1 },
{ NULL }
};
+#undef OFFSET
static const AVClass amediacodec_class = {
.class_name = "amediacodec",
--
2.44.0
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 51+ messages in thread
* [FFmpeg-devel] [PATCH v4 6/6] avcodec/mediacodec_wrapper: remove unnecessary NULL checks before calling Delete{Global, Local}Ref()
2024-03-17 22:28 ` [FFmpeg-devel] Add protocol for Android content providers (v4) Matthieu Bouron
` (4 preceding siblings ...)
2024-03-17 22:28 ` [FFmpeg-devel] [PATCH v4 5/6] avcodec/mediacodec_wrapper: use an OFFSET() macro where relevant Matthieu Bouron
@ 2024-03-17 22:28 ` Matthieu Bouron
2024-03-19 17:49 ` [FFmpeg-devel] Add protocol for Android content providers (v4) Matthieu Bouron
6 siblings, 0 replies; 51+ messages in thread
From: Matthieu Bouron @ 2024-03-17 22:28 UTC (permalink / raw)
To: ffmpeg-devel; +Cc: Matthieu Bouron
Delete{Global,Local}Ref already handle NULL.
---
libavcodec/mediacodec_wrapper.c | 189 ++++++++------------------------
1 file changed, 47 insertions(+), 142 deletions(-)
diff --git a/libavcodec/mediacodec_wrapper.c b/libavcodec/mediacodec_wrapper.c
index 78cd28f53d..306359071e 100644
--- a/libavcodec/mediacodec_wrapper.c
+++ b/libavcodec/mediacodec_wrapper.c
@@ -549,10 +549,8 @@ char *ff_AMediaCodecList_getCodecNameByType(const char *mime, int profile, int e
goto done;
}
- if (codec_name) {
- (*env)->DeleteLocalRef(env, codec_name);
- codec_name = NULL;
- }
+ (*env)->DeleteLocalRef(env, codec_name);
+ codec_name = NULL;
/* Skip software decoders */
if (
@@ -616,10 +614,8 @@ char *ff_AMediaCodecList_getCodecNameByType(const char *mime, int profile, int e
found_codec = profile == supported_profile;
- if (profile_level) {
- (*env)->DeleteLocalRef(env, profile_level);
- profile_level = NULL;
- }
+ (*env)->DeleteLocalRef(env, profile_level);
+ profile_level = NULL;
if (found_codec) {
break;
@@ -627,20 +623,14 @@ char *ff_AMediaCodecList_getCodecNameByType(const char *mime, int profile, int e
}
done_with_type:
- if (profile_levels) {
- (*env)->DeleteLocalRef(env, profile_levels);
- profile_levels = NULL;
- }
+ (*env)->DeleteLocalRef(env, profile_levels);
+ profile_levels = NULL;
- if (capabilities) {
- (*env)->DeleteLocalRef(env, capabilities);
- capabilities = NULL;
- }
+ (*env)->DeleteLocalRef(env, capabilities);
+ capabilities = NULL;
- if (type) {
- (*env)->DeleteLocalRef(env, type);
- type = NULL;
- }
+ (*env)->DeleteLocalRef(env, type);
+ type = NULL;
av_freep(&supported_type);
@@ -650,15 +640,11 @@ done_with_type:
}
done_with_info:
- if (info) {
- (*env)->DeleteLocalRef(env, info);
- info = NULL;
- }
+ (*env)->DeleteLocalRef(env, info);
+ info = NULL;
- if (types) {
- (*env)->DeleteLocalRef(env, types);
- types = NULL;
- }
+ (*env)->DeleteLocalRef(env, types);
+ types = NULL;
if (found_codec) {
break;
@@ -668,33 +654,13 @@ done_with_info:
}
done:
- if (codec_name) {
- (*env)->DeleteLocalRef(env, codec_name);
- }
-
- if (info) {
- (*env)->DeleteLocalRef(env, info);
- }
-
- if (type) {
- (*env)->DeleteLocalRef(env, type);
- }
-
- if (types) {
- (*env)->DeleteLocalRef(env, types);
- }
-
- if (capabilities) {
- (*env)->DeleteLocalRef(env, capabilities);
- }
-
- if (profile_level) {
- (*env)->DeleteLocalRef(env, profile_level);
- }
-
- if (profile_levels) {
- (*env)->DeleteLocalRef(env, profile_levels);
- }
+ (*env)->DeleteLocalRef(env, codec_name);
+ (*env)->DeleteLocalRef(env, info);
+ (*env)->DeleteLocalRef(env, type);
+ (*env)->DeleteLocalRef(env, types);
+ (*env)->DeleteLocalRef(env, capabilities);
+ (*env)->DeleteLocalRef(env, profile_level);
+ (*env)->DeleteLocalRef(env, profile_levels);
av_freep(&supported_type);
@@ -741,9 +707,7 @@ static FFAMediaFormat *mediaformat_jni_new(void)
}
fail:
- if (object) {
- (*env)->DeleteLocalRef(env, object);
- }
+ (*env)->DeleteLocalRef(env, object);
if (!format->object) {
ff_jni_reset_jfields(env, &format->jfields, jni_amediaformat_mapping, 1, format);
@@ -828,9 +792,7 @@ static char* mediaformat_jni_toString(FFAMediaFormat* ctx)
ret = ff_jni_jstring_to_utf_chars(env, description, format);
fail:
- if (description) {
- (*env)->DeleteLocalRef(env, description);
- }
+ (*env)->DeleteLocalRef(env, description);
return ret;
}
@@ -867,9 +829,7 @@ static int mediaformat_jni_getInt32(FFAMediaFormat* ctx, const char *name, int32
ret = 1;
fail:
- if (key) {
- (*env)->DeleteLocalRef(env, key);
- }
+ (*env)->DeleteLocalRef(env, key);
return ret;
}
@@ -906,9 +866,7 @@ static int mediaformat_jni_getInt64(FFAMediaFormat* ctx, const char *name, int64
ret = 1;
fail:
- if (key) {
- (*env)->DeleteLocalRef(env, key);
- }
+ (*env)->DeleteLocalRef(env, key);
return ret;
}
@@ -945,9 +903,7 @@ static int mediaformat_jni_getFloat(FFAMediaFormat* ctx, const char *name, float
ret = 1;
fail:
- if (key) {
- (*env)->DeleteLocalRef(env, key);
- }
+ (*env)->DeleteLocalRef(env, key);
return ret;
}
@@ -999,13 +955,8 @@ static int mediaformat_jni_getBuffer(FFAMediaFormat* ctx, const char *name, void
ret = 1;
fail:
- if (key) {
- (*env)->DeleteLocalRef(env, key);
- }
-
- if (result) {
- (*env)->DeleteLocalRef(env, result);
- }
+ (*env)->DeleteLocalRef(env, key);
+ (*env)->DeleteLocalRef(env, result);
return ret;
}
@@ -1049,13 +1000,8 @@ static int mediaformat_jni_getString(FFAMediaFormat* ctx, const char *name, cons
ret = 1;
fail:
- if (key) {
- (*env)->DeleteLocalRef(env, key);
- }
-
- if (result) {
- (*env)->DeleteLocalRef(env, result);
- }
+ (*env)->DeleteLocalRef(env, key);
+ (*env)->DeleteLocalRef(env, result);
return ret;
}
@@ -1081,9 +1027,7 @@ static void mediaformat_jni_setInt32(FFAMediaFormat* ctx, const char* name, int3
}
fail:
- if (key) {
- (*env)->DeleteLocalRef(env, key);
- }
+ (*env)->DeleteLocalRef(env, key);
}
static void mediaformat_jni_setInt64(FFAMediaFormat* ctx, const char* name, int64_t value)
@@ -1107,9 +1051,7 @@ static void mediaformat_jni_setInt64(FFAMediaFormat* ctx, const char* name, int6
}
fail:
- if (key) {
- (*env)->DeleteLocalRef(env, key);
- }
+ (*env)->DeleteLocalRef(env, key);
}
static void mediaformat_jni_setFloat(FFAMediaFormat* ctx, const char* name, float value)
@@ -1133,9 +1075,7 @@ static void mediaformat_jni_setFloat(FFAMediaFormat* ctx, const char* name, floa
}
fail:
- if (key) {
- (*env)->DeleteLocalRef(env, key);
- }
+ (*env)->DeleteLocalRef(env, key);
}
static void mediaformat_jni_setString(FFAMediaFormat* ctx, const char* name, const char* value)
@@ -1165,13 +1105,8 @@ static void mediaformat_jni_setString(FFAMediaFormat* ctx, const char* name, con
}
fail:
- if (key) {
- (*env)->DeleteLocalRef(env, key);
- }
-
- if (string) {
- (*env)->DeleteLocalRef(env, string);
- }
+ (*env)->DeleteLocalRef(env, key);
+ (*env)->DeleteLocalRef(env, string);
}
static void mediaformat_jni_setBuffer(FFAMediaFormat* ctx, const char* name, void* data, size_t size)
@@ -1213,13 +1148,8 @@ static void mediaformat_jni_setBuffer(FFAMediaFormat* ctx, const char* name, voi
}
fail:
- if (key) {
- (*env)->DeleteLocalRef(env, key);
- }
-
- if (buffer) {
- (*env)->DeleteLocalRef(env, buffer);
- }
+ (*env)->DeleteLocalRef(env, key);
+ (*env)->DeleteLocalRef(env, buffer);
}
static int codec_init_static_fields(FFAMediaCodecJni *codec)
@@ -1352,26 +1282,13 @@ static inline FFAMediaCodec *codec_create(int method, const char *arg)
ret = 0;
fail:
- if (jarg) {
- (*env)->DeleteLocalRef(env, jarg);
- }
-
- if (object) {
- (*env)->DeleteLocalRef(env, object);
- }
-
- if (buffer_info) {
- (*env)->DeleteLocalRef(env, buffer_info);
- }
+ (*env)->DeleteLocalRef(env, jarg);
+ (*env)->DeleteLocalRef(env, object);
+ (*env)->DeleteLocalRef(env, buffer_info);
if (ret < 0) {
- if (codec->object) {
- (*env)->DeleteGlobalRef(env, codec->object);
- }
-
- if (codec->buffer_info) {
- (*env)->DeleteGlobalRef(env, codec->buffer_info);
- }
+ (*env)->DeleteGlobalRef(env, codec->object);
+ (*env)->DeleteGlobalRef(env, codec->buffer_info);
ff_jni_reset_jfields(env, &codec->jfields, jni_amediacodec_mapping, 1, codec);
av_freep(&codec);
@@ -1692,13 +1609,8 @@ static uint8_t* mediacodec_jni_getInputBuffer(FFAMediaCodec* ctx, size_t idx, si
ret = (*env)->GetDirectBufferAddress(env, buffer);
*out_size = (*env)->GetDirectBufferCapacity(env, buffer);
fail:
- if (buffer) {
- (*env)->DeleteLocalRef(env, buffer);
- }
-
- if (input_buffers) {
- (*env)->DeleteLocalRef(env, input_buffers);
- }
+ (*env)->DeleteLocalRef(env, buffer);
+ (*env)->DeleteLocalRef(env, input_buffers);
return ret;
}
@@ -1740,13 +1652,8 @@ static uint8_t* mediacodec_jni_getOutputBuffer(FFAMediaCodec* ctx, size_t idx, s
ret = (*env)->GetDirectBufferAddress(env, buffer);
*out_size = (*env)->GetDirectBufferCapacity(env, buffer);
fail:
- if (buffer) {
- (*env)->DeleteLocalRef(env, buffer);
- }
-
- if (output_buffers) {
- (*env)->DeleteLocalRef(env, output_buffers);
- }
+ (*env)->DeleteLocalRef(env, buffer);
+ (*env)->DeleteLocalRef(env, output_buffers);
return ret;
}
@@ -1768,9 +1675,7 @@ static FFAMediaFormat* mediacodec_jni_getOutputFormat(FFAMediaCodec* ctx)
ret = mediaformat_jni_newFromObject(mediaformat);
fail:
- if (mediaformat) {
- (*env)->DeleteLocalRef(env, mediaformat);
- }
+ (*env)->DeleteLocalRef(env, mediaformat);
return ret;
}
--
2.44.0
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 51+ messages in thread
* Re: [FFmpeg-devel] [PATCH v2 2/6] avformat: add Android content resolver protocol support
2024-03-17 4:33 ` Zhao Zhili
@ 2024-03-17 22:34 ` Matthieu Bouron
0 siblings, 0 replies; 51+ messages in thread
From: Matthieu Bouron @ 2024-03-17 22:34 UTC (permalink / raw)
To: FFmpeg development discussions and patches
On Sun, Mar 17, 2024 at 12:33:04PM +0800, Zhao Zhili wrote:
> Sorry for the long delay of review.
>
> > On Mar 5, 2024, at 03:37, Matthieu Bouron <matthieu.bouron@gmail.com> wrote:
> >
> > On Tue, Feb 27, 2024 at 03:50:38PM +0100, Matthieu Bouron wrote:
> >> Handles Android content-uri starting with content://.
> >> ---
> >
> > [...]
> >
>
> > Handles Android content-uri starting with content://.
> > ---
> > configure | 2 +
> > doc/APIchanges | 3 +
> > libavcodec/jni.c | 1 +
> > libavformat/Makefile | 1 +
> > libavformat/file.c | 157 ++++++++++++++++++++++++++++++++++++++++
> > libavformat/protocols.c | 1 +
> > 6 files changed, 165 insertions(+)
> >
> > diff --git a/configure b/configure
> > index bb5e630bad..790a1df7c8 100755
> > --- a/configure
> > +++ b/configure
> > @@ -3655,6 +3655,8 @@ xcbgrab_indev_suggest="libxcb_shm libxcb_shape libxcb_xfixes"
> > xv_outdev_deps="xlib_xv xlib_x11 xlib_xext"
> >
> > # protocols
> > +android_content_protocol_deps="jni"
> > +android_content_protocol_select="file_protocol"
> > async_protocol_deps="threads"
> > bluray_protocol_deps="libbluray"
> > ffrtmpcrypt_protocol_conflict="librtmp_protocol"
> > diff --git a/doc/APIchanges b/doc/APIchanges
> > index 10f6667e9e..258e953ca6 100644
> > --- a/doc/APIchanges
> > +++ b/doc/APIchanges
> > @@ -2,6 +2,9 @@ The last version increases of all libraries were on 2023-02-09
> >
> > API changes, most recent first:
> >
> > +2024-02-xx - xxxxxxxxxx - lavc 60.41.100 - jni.h
> > + Add av_jni_set_android_app_ctx() and av_jni_get_android_app_ctx().
>
> Should be added together with patch 1/6.
Fixed.
>
> > +
> > 2024-02-26 - xxxxxxxxxx - lavf 60.22.101 - avformat.h
> > AV_DISPOSITION_DEPENDENT may now also be used for video streams
> > intended to be merged with other video streams for presentation.
> > diff --git a/libavcodec/jni.c b/libavcodec/jni.c
> > index cfe95bd1ec..1193c608c3 100644
> > --- a/libavcodec/jni.c
> > +++ b/libavcodec/jni.c
> > @@ -35,6 +35,7 @@
> > #include "ffjni.h"
> >
> > static void *java_vm;
> > +static void *android_app_ctx;
> > static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
> >
> > int av_jni_set_java_vm(void *vm, void *log_ctx)
> > diff --git a/libavformat/Makefile b/libavformat/Makefile
> > index 4a380668bd..08fe98a535 100644
> > --- a/libavformat/Makefile
> > +++ b/libavformat/Makefile
> > @@ -657,6 +657,7 @@ OBJS-$(CONFIG_LIBOPENMPT_DEMUXER) += libopenmpt.o
> > OBJS-$(CONFIG_VAPOURSYNTH_DEMUXER) += vapoursynth.o
> >
> > # protocols I/O
> > +OBJS-$(CONFIG_ANDROID_CONTENT_PROTOCOL) += file.o
> > OBJS-$(CONFIG_ASYNC_PROTOCOL) += async.o
> > OBJS-$(CONFIG_APPLEHTTP_PROTOCOL) += hlsproto.o
> > OBJS-$(CONFIG_BLURAY_PROTOCOL) += bluray.o
> > diff --git a/libavformat/file.c b/libavformat/file.c
> > index 64df7ff6fb..1b2b69f090 100644
> > --- a/libavformat/file.c
> > +++ b/libavformat/file.c
> > @@ -40,6 +40,12 @@
> > #include <stdlib.h>
> > #include "os_support.h"
> > #include "url.h"
> > +#if CONFIG_ANDROID_CONTENT_PROTOCOL
> > +#include <jni.h>
> > +#include "libavcodec/jni.h"
> > +#include "libavcodec/ffjni.c"
> > +#endif
> > +
> >
> > /* Some systems may not have S_ISFIFO */
> > #ifndef S_ISFIFO
> > @@ -101,6 +107,21 @@ typedef struct FileContext {
> > int64_t initial_pos;
> > } FileContext;
> >
> > +
> > +#if CONFIG_ANDROID_CONTENT_PROTOCOL
> > +static const AVOption android_content_options[] = {
> > + { "blocksize", "set I/O operation maximum block size", offsetof(FileContext, blocksize), AV_OPT_TYPE_INT, { .i64 = INT_MAX }, 1, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM },
> > + { NULL }
> > +};
> > +
> > +static const AVClass android_content_class = {
> > + .class_name = "android_content",
> > + .item_name = av_default_item_name,
> > + .option = android_content_options,
> > + .version = LIBAVUTIL_VERSION_INT,
> > +};
> > +#endif
> > +
> > static const AVOption file_options[] = {
> > { "truncate", "truncate existing files on write", offsetof(FileContext, trunc), AV_OPT_TYPE_BOOL, { .i64 = 1 }, 0, 1, AV_OPT_FLAG_ENCODING_PARAM },
> > { "blocksize", "set I/O operation maximum block size", offsetof(FileContext, blocksize), AV_OPT_TYPE_INT, { .i64 = INT_MAX }, 1, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM },
> > @@ -524,3 +545,139 @@ const URLProtocol ff_fd_protocol = {
> > };
> >
> > #endif /* CONFIG_FD_PROTOCOL */
> > +
> > +#if CONFIG_ANDROID_CONTENT_PROTOCOL
> > +
> > +struct JFields {
> > + jclass uri_class;
> > + jmethodID parse_id;
> > +
> > + jclass context_class;
> > + jmethodID get_content_resolver_id;
> > +
> > + jclass content_resolver_class;
> > + jmethodID open_file_descriptor_id;
> > +
> > + jclass parcel_file_descriptor_class;
> > + jmethodID detach_fd_id;
> > +};
>
> typedef struct is the preferred coding style of FFmpeg, it’s mentioned in
> developer.texi.
Fixed.
>
> > +
> > +#define OFFSET(x) offsetof(struct JFields, x)
> > +static const struct FFJniField jfields_mapping[] = {
> > + { "android/net/Uri", NULL, NULL, FF_JNI_CLASS, OFFSET(uri_class), 1 },
> > + { "android/net/Uri", "parse", "(Ljava/lang/String;)Landroid/net/Uri;", FF_JNI_STATIC_METHOD, OFFSET(parse_id), 1 },
> > +
> > + { "android/content/Context", NULL, NULL, FF_JNI_CLASS, OFFSET(context_class), 1 },
> > + { "android/content/Context", "getContentResolver", "()Landroid/content/ContentResolver;", FF_JNI_METHOD, OFFSET(get_content_resolver_id), 1 },
> > +
> > + { "android/content/ContentResolver", NULL, NULL, FF_JNI_CLASS, OFFSET(content_resolver_class), 1 },
> > + { "android/content/ContentResolver", "openFileDescriptor", "(Landroid/net/Uri;Ljava/lang/String;)Landroid/os/ParcelFileDescriptor;", FF_JNI_METHOD, OFFSET(open_file_descriptor_id), 1 },
> > +
> > + { "android/os/ParcelFileDescriptor", NULL, NULL, FF_JNI_CLASS, OFFSET(parcel_file_descriptor_class), 1 },
> > + { "android/os/ParcelFileDescriptor", "detachFd", "()I", FF_JNI_METHOD, OFFSET(detach_fd_id), 1 },
> > +
> > + { NULL }
> > +};
> > +#undef OFFSET
> > +
> > +static int android_content_open(URLContext *h, const char *filename, int flags)
> > +{
> > + FileContext *c = h->priv_data;
> > + int fd, ret;
> > + const char *mode_str = "r";
> > +
> > + JNIEnv *env;
> > + struct JFields jfields = { 0 };
> > + jobject application_context = NULL;
> > + jobject url = NULL;
> > + jobject mode = NULL;
> > + jobject uri = NULL;
> > + jobject content_resolver = NULL;
> > + jobject parcel_file_descriptor = NULL;
> > +
> > + env = ff_jni_get_env(c);
> > + if (!env) {
> > + return AVERROR(EINVAL);
> > + }
> > +
> > + ret = ff_jni_init_jfields(env, &jfields, jfields_mapping, 0, c);
> > + if (ret < 0) {
> > + av_log(c, AV_LOG_ERROR, "failed to initialize jni fields\n");
> > + return ret;
> > + }
> > +
> > + application_context = av_jni_get_android_app_ctx();
> > + if (!application_context) {
> > + av_log(c, AV_LOG_ERROR, "application context is not set\n");
> > + ret = AVERROR_EXTERNAL;
> > + goto done;
> > + }
> > +
> > + url = ff_jni_utf_chars_to_jstring(env, filename, c);
> > + if (!url) {
> > + ret = AVERROR_EXTERNAL;
> > + goto done;
> > + }
> > +
> > + if (flags & AVIO_FLAG_WRITE && flags & AVIO_FLAG_READ)
> > + mode_str = "rw";
> > + else if (flags & AVIO_FLAG_WRITE)
> > + mode_str = "w";
> > +
> > + mode = ff_jni_utf_chars_to_jstring(env, mode_str, c);
> > + if (!mode) {
> > + ret = AVERROR_EXTERNAL;
> > + goto done;
> > + }
> > +
> > + uri = (*env)->CallStaticObjectMethod(env, jfields.uri_class, jfields.parse_id, url);
> > + ret = ff_jni_exception_check(env, 1, c);
> > + if (ret < 0)
> > + goto done;
> > +
> > + content_resolver = (*env)->CallObjectMethod(env, application_context, jfields.get_content_resolver_id);
> > + ret = ff_jni_exception_check(env, 1, c);
> > + if (ret < 0)
> > + goto done;
> > +
> > + parcel_file_descriptor = (*env)->CallObjectMethod(env, content_resolver, jfields.open_file_descriptor_id, uri, mode);
> > + ret = ff_jni_exception_check(env, 1, c);
> > + if (ret < 0)
> > + goto done;
> > +
> > + fd = (*env)->CallIntMethod(env, parcel_file_descriptor, jfields.detach_fd_id);
> > + ret = ff_jni_exception_check(env, 1, c);
> > + if (ret < 0)
> > + goto done;
> > +
> > +#if HAVE_SETMODE
> > + setmode(fd, O_BINARY);
> > +#endif
>
> Since it’s android specific protocol, the conditional compile is always false, isn’t it?
You're right. Removed.
>
> > + c->fd = fd;
> > + h->is_streamed = 0;
>
> Firstly, is_streamed is default to false, so the above line is unnecessary.
> Secondly, I’m not sure whether it’s always seeable.
Added a check.
Thanks for the review, I've sent an updated patch series (v4).
Best regards,
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 51+ messages in thread
* Re: [FFmpeg-devel] [PATCH v4 1/6] avcodec: add av_jni_{get, set}_android_app_ctx helper
2024-03-17 22:28 ` [FFmpeg-devel] [PATCH v4 1/6] avcodec: add av_jni_{get, set}_android_app_ctx helper Matthieu Bouron
@ 2024-03-17 22:38 ` Andreas Rheinhardt
2024-03-17 22:43 ` Matthieu Bouron
0 siblings, 1 reply; 51+ messages in thread
From: Andreas Rheinhardt @ 2024-03-17 22:38 UTC (permalink / raw)
To: ffmpeg-devel
Matthieu Bouron:
> This will allow users to pass the Android ApplicationContext which is mandatory
> to retrieve the ContentResolver responsible to resolve/open Android content-uri.
> ---
> doc/APIchanges | 3 +++
> libavcodec/jni.c | 42 ++++++++++++++++++++++++++++++++++++++++++
> libavcodec/jni.h | 17 +++++++++++++++++
> 3 files changed, 62 insertions(+)
>
> diff --git a/doc/APIchanges b/doc/APIchanges
> index a44c8e4f10..ae1868047e 100644
> --- a/doc/APIchanges
> +++ b/doc/APIchanges
> @@ -2,6 +2,9 @@ The last version increases of all libraries were on 2024-03-07
>
> API changes, most recent first:
>
> +2024-03-xx - xxxxxxxxxx - lavc 61.2.100 - jni.h
> + Add av_jni_set_android_app_ctx() and av_jni_get_android_app_ctx().
> +
> 2024-03-xx - xxxxxxxxxx - lavu 59.2.100 - channel_layout.h
> Add AV_CHANNEL_LAYOUT_RETYPE_FLAG_CANONICAL.
>
> diff --git a/libavcodec/jni.c b/libavcodec/jni.c
> index ae6490de9d..cfe95bd1ec 100644
> --- a/libavcodec/jni.c
> +++ b/libavcodec/jni.c
> @@ -77,3 +77,45 @@ void *av_jni_get_java_vm(void *log_ctx)
> }
>
> #endif
> +
> +#if defined(__ANDROID__)
> +
> +int av_jni_set_android_app_ctx(void *app_ctx, void *log_ctx)
> +{
> +#if CONFIG_JNI
> + JNIEnv *env = ff_jni_get_env(log_ctx);
> + if (!env)
> + return AVERROR(EINVAL);
> +
> + jobjectRefType type = (*env)->GetObjectRefType(env, app_ctx);
> + if (type != JNIGlobalRefType) {
> + av_log(log_ctx, AV_LOG_ERROR, "Application context must be passed as a global reference");
> + return AVERROR(EINVAL);
> + }
> +
> + pthread_mutex_lock(&lock);
> + android_app_ctx = app_ctx;
> + pthread_mutex_unlock(&lock);
> +
> + return 0;
> +#else
> + return AVERROR(ENOSYS);
> +#endif
> +}
> +
> +void *av_jni_get_android_app_ctx(void)
> +{
> +#if CONFIG_JNI
> + void *ctx;
> +
> + pthread_mutex_lock(&lock);
> + ctx = android_app_ctx;
> + pthread_mutex_unlock(&lock);
> +
> + return ctx;
> +#else
> + return NULL;
> +#endif
> +}
> +
> +#endif
> diff --git a/libavcodec/jni.h b/libavcodec/jni.h
> index dd99e92611..da8025f830 100644
> --- a/libavcodec/jni.h
> +++ b/libavcodec/jni.h
> @@ -43,4 +43,21 @@ int av_jni_set_java_vm(void *vm, void *log_ctx);
> */
> void *av_jni_get_java_vm(void *log_ctx);
>
> +/*
> + * Set the Android application context which will be used to retrieve the Android
> + * content resolver to resolve content uris.
> + *
> + * @param app_ctx global JNI reference to the Android application context
> + * @return 0 on success, < 0 otherwise
> + */
> +int av_jni_set_android_app_ctx(void *app_ctx, void *log_ctx);
> +
> +/*
> + * Get the Android application context that has been set with
> + * av_jni_set_android_app_ctx.
> + *
> + * @return a pointer the the Android application context
> + */
> +void *av_jni_get_android_app_ctx(void);
This should mention that these functions are only available on android.
> +
> #endif /* AVCODEC_JNI_H */
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 51+ messages in thread
* Re: [FFmpeg-devel] [PATCH v4 1/6] avcodec: add av_jni_{get, set}_android_app_ctx helper
2024-03-17 22:38 ` Andreas Rheinhardt
@ 2024-03-17 22:43 ` Matthieu Bouron
0 siblings, 0 replies; 51+ messages in thread
From: Matthieu Bouron @ 2024-03-17 22:43 UTC (permalink / raw)
To: FFmpeg development discussions and patches
On Sun, Mar 17, 2024 at 11:38 PM Andreas Rheinhardt
<andreas.rheinhardt@outlook.com> wrote:
>
> Matthieu Bouron:
> > This will allow users to pass the Android ApplicationContext which is mandatory
> > to retrieve the ContentResolver responsible to resolve/open Android content-uri.
> > ---
> > doc/APIchanges | 3 +++
> > libavcodec/jni.c | 42 ++++++++++++++++++++++++++++++++++++++++++
> > libavcodec/jni.h | 17 +++++++++++++++++
> > 3 files changed, 62 insertions(+)
> >
> > diff --git a/doc/APIchanges b/doc/APIchanges
> > index a44c8e4f10..ae1868047e 100644
> > --- a/doc/APIchanges
> > +++ b/doc/APIchanges
> > @@ -2,6 +2,9 @@ The last version increases of all libraries were on 2024-03-07
> >
> > API changes, most recent first:
> >
> > +2024-03-xx - xxxxxxxxxx - lavc 61.2.100 - jni.h
> > + Add av_jni_set_android_app_ctx() and av_jni_get_android_app_ctx().
> > +
> > 2024-03-xx - xxxxxxxxxx - lavu 59.2.100 - channel_layout.h
> > Add AV_CHANNEL_LAYOUT_RETYPE_FLAG_CANONICAL.
> >
> > diff --git a/libavcodec/jni.c b/libavcodec/jni.c
> > index ae6490de9d..cfe95bd1ec 100644
> > --- a/libavcodec/jni.c
> > +++ b/libavcodec/jni.c
> > @@ -77,3 +77,45 @@ void *av_jni_get_java_vm(void *log_ctx)
> > }
> >
> > #endif
> > +
> > +#if defined(__ANDROID__)
> > +
> > +int av_jni_set_android_app_ctx(void *app_ctx, void *log_ctx)
> > +{
> > +#if CONFIG_JNI
> > + JNIEnv *env = ff_jni_get_env(log_ctx);
> > + if (!env)
> > + return AVERROR(EINVAL);
> > +
> > + jobjectRefType type = (*env)->GetObjectRefType(env, app_ctx);
> > + if (type != JNIGlobalRefType) {
> > + av_log(log_ctx, AV_LOG_ERROR, "Application context must be passed as a global reference");
> > + return AVERROR(EINVAL);
> > + }
> > +
> > + pthread_mutex_lock(&lock);
> > + android_app_ctx = app_ctx;
> > + pthread_mutex_unlock(&lock);
> > +
> > + return 0;
> > +#else
> > + return AVERROR(ENOSYS);
> > +#endif
> > +}
> > +
> > +void *av_jni_get_android_app_ctx(void)
> > +{
> > +#if CONFIG_JNI
> > + void *ctx;
> > +
> > + pthread_mutex_lock(&lock);
> > + ctx = android_app_ctx;
> > + pthread_mutex_unlock(&lock);
> > +
> > + return ctx;
> > +#else
> > + return NULL;
> > +#endif
> > +}
> > +
> > +#endif
> > diff --git a/libavcodec/jni.h b/libavcodec/jni.h
> > index dd99e92611..da8025f830 100644
> > --- a/libavcodec/jni.h
> > +++ b/libavcodec/jni.h
> > @@ -43,4 +43,21 @@ int av_jni_set_java_vm(void *vm, void *log_ctx);
> > */
> > void *av_jni_get_java_vm(void *log_ctx);
> >
> > +/*
> > + * Set the Android application context which will be used to retrieve the Android
> > + * content resolver to resolve content uris.
> > + *
> > + * @param app_ctx global JNI reference to the Android application context
> > + * @return 0 on success, < 0 otherwise
> > + */
> > +int av_jni_set_android_app_ctx(void *app_ctx, void *log_ctx);
> > +
> > +/*
> > + * Get the Android application context that has been set with
> > + * av_jni_set_android_app_ctx.
> > + *
> > + * @return a pointer the the Android application context
> > + */
> > +void *av_jni_get_android_app_ctx(void);
>
> This should mention that these functions are only available on android.
Added the following chunk locally to both functions:
*
+ * This function is only available on Android.
+ *
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 51+ messages in thread
* Re: [FFmpeg-devel] Add protocol for Android content providers (v4)
2024-03-17 22:28 ` [FFmpeg-devel] Add protocol for Android content providers (v4) Matthieu Bouron
` (5 preceding siblings ...)
2024-03-17 22:28 ` [FFmpeg-devel] [PATCH v4 6/6] avcodec/mediacodec_wrapper: remove unnecessary NULL checks before calling Delete{Global, Local}Ref() Matthieu Bouron
@ 2024-03-19 17:49 ` Matthieu Bouron
2024-03-23 10:40 ` Matthieu Bouron
6 siblings, 1 reply; 51+ messages in thread
From: Matthieu Bouron @ 2024-03-19 17:49 UTC (permalink / raw)
To: ffmpeg-devel
On Sun, Mar 17, 2024 at 11:28:31PM +0100, Matthieu Bouron wrote:
> Diff with previous iteration:
> - rebaed on latest master
> - applied feedback from Zhao (removed HAVE_SETMODE block, use a typedef struct,
> check that the fd is seekable, moved doc/APIChanges changes to the right
> commit)
>
I will push the patchset in a few days if there is no other comment (nor
any objection).
--
Matthieu B.
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 51+ messages in thread
* Re: [FFmpeg-devel] Add protocol for Android content providers (v4)
2024-03-19 17:49 ` [FFmpeg-devel] Add protocol for Android content providers (v4) Matthieu Bouron
@ 2024-03-23 10:40 ` Matthieu Bouron
0 siblings, 0 replies; 51+ messages in thread
From: Matthieu Bouron @ 2024-03-23 10:40 UTC (permalink / raw)
To: ffmpeg-devel
On Tue, Mar 19, 2024 at 06:49:43PM +0100, Matthieu Bouron wrote:
> On Sun, Mar 17, 2024 at 11:28:31PM +0100, Matthieu Bouron wrote:
> > Diff with previous iteration:
> > - rebaed on latest master
> > - applied feedback from Zhao (removed HAVE_SETMODE block, use a typedef struct,
> > check that the fd is seekable, moved doc/APIChanges changes to the right
> > commit)
> >
>
> I will push the patchset in a few days if there is no other comment (nor
> any objection).
Patchset applied (with a few rewords on the commit msgs).
--
Matthieu B.
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 51+ messages in thread
end of thread, other threads:[~2024-03-23 10:41 UTC | newest]
Thread overview: 51+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-02-13 22:50 [FFmpeg-devel] Add protocol for Android content providers Matthieu Bouron
2024-02-13 22:50 ` [FFmpeg-devel] [PATCH 1/7] avcodec: move ffjni to avutil/jniutils Matthieu Bouron
2024-02-14 18:18 ` Michael Niedermayer
2024-02-14 22:23 ` Matthieu Bouron
2024-02-14 23:31 ` Mark Thompson
2024-02-15 7:40 ` Matthieu Bouron
2024-02-13 22:50 ` [FFmpeg-devel] [PATCH 2/7] avutil: add av_jni_{get, set}_android_app_ctx helper Matthieu Bouron
2024-02-27 13:42 ` Andreas Rheinhardt
2024-02-27 14:46 ` Matthieu Bouron
2024-02-13 22:50 ` [FFmpeg-devel] [PATCH 3/7] avformat: add Android content resolver protocol support Matthieu Bouron
2024-02-13 22:50 ` [FFmpeg-devel] [PATCH 4/7] avutil/jni: use size_t to store structure offsets Matthieu Bouron
2024-02-13 22:50 ` [FFmpeg-devel] [PATCH 5/7] avutil/jni: remove unnecessary NULL checks before calling DeleteLocalRef() Matthieu Bouron
2024-02-13 22:50 ` [FFmpeg-devel] [PATCH 6/7] avcodec/mediacodec_wrapper: use an OFFSET() macro where relevant Matthieu Bouron
2024-02-13 22:50 ` [FFmpeg-devel] [PATCH 7/7] avcodec/mediacodec_wrapper: remove unnecessary NULL checks before calling Delete{Global, Local}Ref() Matthieu Bouron
2024-02-15 4:13 ` [FFmpeg-devel] Add protocol for Android content providers Zhao Zhili
2024-02-15 7:57 ` Matthieu Bouron
2024-02-15 8:46 ` Zhao Zhili
2024-02-15 9:13 ` Matthieu Bouron
2024-02-24 11:29 ` Matthieu Bouron
2024-02-27 7:17 ` Matthieu Bouron
2024-02-27 13:14 ` Zhao Zhili
2024-02-27 13:19 ` Matthieu Bouron
2024-02-27 14:50 ` [FFmpeg-devel] Add protocol for Android content providers (v2) Matthieu Bouron
2024-02-27 14:50 ` [FFmpeg-devel] [PATCH v2 1/6] avcodec: add av_jni_{get, set}_android_app_ctx helper Matthieu Bouron
2024-03-04 11:30 ` Andreas Rheinhardt
2024-03-04 15:11 ` Matthieu Bouron
2024-03-04 16:35 ` Matthieu Bouron
2024-03-04 19:36 ` Matthieu Bouron
2024-02-27 14:50 ` [FFmpeg-devel] [PATCH v2 2/6] avformat: add Android content resolver protocol support Matthieu Bouron
2024-03-04 19:37 ` Matthieu Bouron
2024-03-17 4:33 ` Zhao Zhili
2024-03-17 22:34 ` Matthieu Bouron
2024-02-27 14:50 ` [FFmpeg-devel] [PATCH v2 3/6] avutil/jni: use size_t to store structure offsets Matthieu Bouron
2024-03-04 20:10 ` Andreas Rheinhardt
2024-03-05 7:58 ` Matthieu Bouron
2024-02-27 14:50 ` [FFmpeg-devel] [PATCH v2 4/6] avutil/jni: remove unnecessary NULL checks before calling DeleteLocalRef() Matthieu Bouron
2024-02-27 14:50 ` [FFmpeg-devel] [PATCH v2 5/6] avcodec/mediacodec_wrapper: use an OFFSET() macro where relevant Matthieu Bouron
2024-02-27 14:50 ` [FFmpeg-devel] [PATCH v2 6/6] avcodec/mediacodec_wrapper: remove unnecessary NULL checks before calling Delete{Global, Local}Ref() Matthieu Bouron
2024-03-04 8:21 ` [FFmpeg-devel] Add protocol for Android content providers (v2) Matthieu Bouron
2024-03-14 8:04 ` Matthieu Bouron
2024-03-17 22:28 ` [FFmpeg-devel] Add protocol for Android content providers (v4) Matthieu Bouron
2024-03-17 22:28 ` [FFmpeg-devel] [PATCH v4 1/6] avcodec: add av_jni_{get, set}_android_app_ctx helper Matthieu Bouron
2024-03-17 22:38 ` Andreas Rheinhardt
2024-03-17 22:43 ` Matthieu Bouron
2024-03-17 22:28 ` [FFmpeg-devel] [PATCH v4 2/6] avformat: add Android content resolver protocol support Matthieu Bouron
2024-03-17 22:28 ` [FFmpeg-devel] [PATCH v4 3/6] avcodec/jni: use size_t to store structure offsets Matthieu Bouron
2024-03-17 22:28 ` [FFmpeg-devel] [PATCH v4 4/6] avcodec/jni: remove unnecessary NULL checks before calling DeleteLocalRef() Matthieu Bouron
2024-03-17 22:28 ` [FFmpeg-devel] [PATCH v4 5/6] avcodec/mediacodec_wrapper: use an OFFSET() macro where relevant Matthieu Bouron
2024-03-17 22:28 ` [FFmpeg-devel] [PATCH v4 6/6] avcodec/mediacodec_wrapper: remove unnecessary NULL checks before calling Delete{Global, Local}Ref() Matthieu Bouron
2024-03-19 17:49 ` [FFmpeg-devel] Add protocol for Android content providers (v4) Matthieu Bouron
2024-03-23 10:40 ` Matthieu Bouron
Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
This inbox may be cloned and mirrored by anyone:
git clone --mirror https://master.gitmailbox.com/ffmpegdev/0 ffmpegdev/git/0.git
# If you have public-inbox 1.1+ installed, you may
# initialize and index your mirror using the following commands:
public-inbox-init -V2 ffmpegdev ffmpegdev/ https://master.gitmailbox.com/ffmpegdev \
ffmpegdev@gitmailbox.com
public-inbox-index ffmpegdev
Example config snippet for mirrors.
AGPL code for this site: git clone https://public-inbox.org/public-inbox.git