From d527cefc757d1feef91d098bdd6490b720414c8d Mon Sep 17 00:00:00 2001 From: Matthieu Bouron Date: Mon, 4 Mar 2024 09:50:07 +0100 Subject: [PATCH] build: add content uri support to FFmpeg See https://ffmpeg.org//pipermail/ffmpeg-devel/2024-February/322247.html. --- configure.py | 9 + ...jni_-get-set-_android_app_ctx-helper.patch | 97 +++++ ...roid-content-resolver-protocol-suppo.patch | 269 +++++++++++++ ...se-size_t-to-store-structure-offsets.patch | 33 ++ ...ve-unnecessary-NULL-checks-before-ca.patch | 39 ++ ...ec_wrapper-use-an-OFFSET-macro-where.patch | 210 ++++++++++ ...ec_wrapper-remove-unnecessary-NULL-c.patch | 359 ++++++++++++++++++ 7 files changed, 1016 insertions(+) create mode 100644 patches/ffmpeg/0001-avcodec-add-av_jni_-get-set-_android_app_ctx-helper.patch create mode 100644 patches/ffmpeg/0002-avformat-add-Android-content-resolver-protocol-suppo.patch create mode 100644 patches/ffmpeg/0003-avcodec-jni-use-size_t-to-store-structure-offsets.patch create mode 100644 patches/ffmpeg/0004-avcodec-jni-remove-unnecessary-NULL-checks-before-ca.patch create mode 100644 patches/ffmpeg/0005-avcodec-mediacodec_wrapper-use-an-OFFSET-macro-where.patch create mode 100644 patches/ffmpeg/0006-avcodec-mediacodec_wrapper-remove-unnecessary-NULL-c.patch diff --git a/configure.py b/configure.py index f6dc42352..e0f9ccab1 100755 --- a/configure.py +++ b/configure.py @@ -121,6 +121,14 @@ def _gen_android_cross_file(cfg): url="https://ffmpeg.org/releases/ffmpeg-@VERSION@.tar.xz", dst_file="ffmpeg-@VERSION@.tar.xz", sha256="8684f4b00f94b85461884c3719382f1261f0d9eb3d59640a1f4ac0873616f968", + patches=[ + "0001-avcodec-add-av_jni_-get-set-_android_app_ctx-helper.patch", + "0002-avformat-add-Android-content-resolver-protocol-suppo.patch", + "0003-avcodec-jni-use-size_t-to-store-structure-offsets.patch", + "0004-avcodec-jni-remove-unnecessary-NULL-checks-before-ca.patch", + "0005-avcodec-mediacodec_wrapper-use-an-OFFSET-macro-where.patch", + "0006-avcodec-mediacodec_wrapper-remove-unnecessary-NULL-c.patch", + ], ), ffmpeg_Windows=dict( version="6.1.1", @@ -523,6 +531,7 @@ def _ffmpeg_setup(cfg): "http", "https", "pipe", + "android_content", ] filters = [ "aformat", diff --git a/patches/ffmpeg/0001-avcodec-add-av_jni_-get-set-_android_app_ctx-helper.patch b/patches/ffmpeg/0001-avcodec-add-av_jni_-get-set-_android_app_ctx-helper.patch new file mode 100644 index 000000000..0e51fbf89 --- /dev/null +++ b/patches/ffmpeg/0001-avcodec-add-av_jni_-get-set-_android_app_ctx-helper.patch @@ -0,0 +1,97 @@ +From 15533f90bc98b4cebd84b4ead2d0dd322b4f8ea7 Mon Sep 17 00:00:00 2001 +From: Matthieu Bouron +Date: Mon, 12 Feb 2024 23:13:09 +0100 +Subject: [PATCH 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 | 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 + diff --git a/patches/ffmpeg/0002-avformat-add-Android-content-resolver-protocol-suppo.patch b/patches/ffmpeg/0002-avformat-add-Android-content-resolver-protocol-suppo.patch new file mode 100644 index 000000000..b83e78401 --- /dev/null +++ b/patches/ffmpeg/0002-avformat-add-Android-content-resolver-protocol-suppo.patch @@ -0,0 +1,269 @@ +From 4cdded89ff4f00726d086021fe0de81ebc3eca73 Mon Sep 17 00:00:00 2001 +From: Matthieu Bouron +Date: Mon, 12 Feb 2024 23:14:35 +0100 +Subject: [PATCH 2/6] avformat: add Android content resolver protocol support + +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 + #include "os_support.h" + #include "url.h" ++#if CONFIG_ANDROID_CONTENT_PROTOCOL ++#include ++#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 + diff --git a/patches/ffmpeg/0003-avcodec-jni-use-size_t-to-store-structure-offsets.patch b/patches/ffmpeg/0003-avcodec-jni-use-size_t-to-store-structure-offsets.patch new file mode 100644 index 000000000..29acb727b --- /dev/null +++ b/patches/ffmpeg/0003-avcodec-jni-use-size_t-to-store-structure-offsets.patch @@ -0,0 +1,33 @@ +From 88634bc78f09bb3a91f67b343d9842857001611a Mon Sep 17 00:00:00 2001 +From: Matthieu Bouron +Date: Tue, 13 Feb 2024 11:03:22 +0100 +Subject: [PATCH 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..d5894609ed 100644 +--- a/libavcodec/ffjni.h ++++ b/libavcodec/ffjni.h +@@ -24,6 +24,7 @@ + #define AVCODEC_FFJNI_H + + #include ++#include + + /* + * 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 + diff --git a/patches/ffmpeg/0004-avcodec-jni-remove-unnecessary-NULL-checks-before-ca.patch b/patches/ffmpeg/0004-avcodec-jni-remove-unnecessary-NULL-checks-before-ca.patch new file mode 100644 index 000000000..d076b39d6 --- /dev/null +++ b/patches/ffmpeg/0004-avcodec-jni-remove-unnecessary-NULL-checks-before-ca.patch @@ -0,0 +1,39 @@ +From 5d922cd049658f72fe4420530ea3b394720fabbe Mon Sep 17 00:00:00 2001 +From: Matthieu Bouron +Date: Tue, 13 Feb 2024 11:05:45 +0100 +Subject: [PATCH 4/6] avcodec/jni: remove unnecessary NULL checks before + calling DeleteLocalRef() + +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 + diff --git a/patches/ffmpeg/0005-avcodec-mediacodec_wrapper-use-an-OFFSET-macro-where.patch b/patches/ffmpeg/0005-avcodec-mediacodec_wrapper-use-an-OFFSET-macro-where.patch new file mode 100644 index 000000000..59542eac9 --- /dev/null +++ b/patches/ffmpeg/0005-avcodec-mediacodec_wrapper-use-an-OFFSET-macro-where.patch @@ -0,0 +1,210 @@ +From 848e324397be0591788e356e648a35c30e9fa402 Mon Sep 17 00:00:00 2001 +From: Matthieu Bouron +Date: Tue, 13 Feb 2024 12:00:57 +0100 +Subject: [PATCH 5/6] avcodec/mediacodec_wrapper: use an OFFSET() macro where + relevant + +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", "", "(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", "", "(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", "", "()V", FF_JNI_METHOD, offsetof(struct JNIAMediaFormatFields, init_id), 1 }, ++ { "android/media/MediaFormat", "", "()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", "", "()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", "", "()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 + diff --git a/patches/ffmpeg/0006-avcodec-mediacodec_wrapper-remove-unnecessary-NULL-c.patch b/patches/ffmpeg/0006-avcodec-mediacodec_wrapper-remove-unnecessary-NULL-c.patch new file mode 100644 index 000000000..068db29a7 --- /dev/null +++ b/patches/ffmpeg/0006-avcodec-mediacodec_wrapper-remove-unnecessary-NULL-c.patch @@ -0,0 +1,359 @@ +From 8a9693c7af6e69a6a30d65ebd23232590ce820f6 Mon Sep 17 00:00:00 2001 +From: Matthieu Bouron +Date: Tue, 13 Feb 2024 12:15:03 +0100 +Subject: [PATCH 6/6] avcodec/mediacodec_wrapper: remove unnecessary NULL + checks before calling Delete{Global,Local}Ref() + +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 +