* [FFmpeg-devel] [PATCH 1/4] lavc/mediacodecenc: Add pix2color_fmt() and color2pix_fmt() @ 2023-02-24 8:59 Tomas Härdin 2023-02-24 9:00 ` [FFmpeg-devel] [PATCH 2/4] lavc/mediacodec_wrapper: Refactor ff_AMediaCodecList_getCodecNameByType() Tomas Härdin ` (3 more replies) 0 siblings, 4 replies; 8+ messages in thread From: Tomas Härdin @ 2023-02-24 8:59 UTC (permalink / raw) To: FFmpeg development discussions and patches [-- Attachment #1: Type: text/plain, Size: 1 bytes --] [-- Attachment #2: 0001-lavc-mediacodecenc-Add-pix2color_fmt-and-color2pix_f.patch --] [-- Type: text/x-patch, Size: 2211 bytes --] From 7374dab21cb37dc14d2481c72d333b435e23a76d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomas=20H=C3=A4rdin?= <git@haerdin.se> Date: Tue, 10 Jan 2023 20:37:18 +0100 Subject: [PATCH 1/4] lavc/mediacodecenc: Add pix2color_fmt() and color2pix_fmt() This patch has been released by Epic Games' legal department. --- libavcodec/mediacodecenc.c | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/libavcodec/mediacodecenc.c b/libavcodec/mediacodecenc.c index a92a8dc5a9..03c80cbf99 100644 --- a/libavcodec/mediacodecenc.c +++ b/libavcodec/mediacodecenc.c @@ -2,6 +2,7 @@ * Android MediaCodec encoders * * Copyright (c) 2022 Zhao Zhili <zhilizhao@tencent.com> + * Modifications by Epic Games, Inc., 2023. * * This file is part of FFmpeg. * @@ -110,6 +111,26 @@ static void mediacodec_output_format(AVCodecContext *avctx) ff_AMediaFormat_delete(out_format); } +static int pix2color_fmt(AVCodecContext *avctx, enum AVPixelFormat pix_fmt) +{ + for (int i = 0; i < FF_ARRAY_ELEMS(color_formats); i++) { + if (pix_fmt == color_formats[i].pix_fmt) { + return color_formats[i].color_format; + } + } + av_assert0(0); +} + +static enum AVPixelFormat color2pix_fmt(AVCodecContext *avctx, int color_format) +{ + for (int i = 0; i < FF_ARRAY_ELEMS(color_formats); i++) { + if (color_format == color_formats[i].color_format) { + return color_formats[i].pix_fmt; + } + } + av_assert0(0); +} + static int mediacodec_init_bsf(AVCodecContext *avctx) { MediaCodecEncContext *s = avctx->priv_data; @@ -235,13 +256,7 @@ static av_cold int mediacodec_init(AVCodecContext *avctx) } } - for (int i = 0; i < FF_ARRAY_ELEMS(color_formats); i++) { - if (avctx->pix_fmt == color_formats[i].pix_fmt) { - ff_AMediaFormat_setInt32(format, "color-format", - color_formats[i].color_format); - break; - } - } + ff_AMediaFormat_setInt32(format, "color-format", pix2color_fmt(avctx, avctx->pix_fmt)); if (avctx->bit_rate) ff_AMediaFormat_setInt32(format, "bitrate", avctx->bit_rate); -- 2.30.2 [-- 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] 8+ messages in thread
* [FFmpeg-devel] [PATCH 2/4] lavc/mediacodec_wrapper: Refactor ff_AMediaCodecList_getCodecNameByType() 2023-02-24 8:59 [FFmpeg-devel] [PATCH 1/4] lavc/mediacodecenc: Add pix2color_fmt() and color2pix_fmt() Tomas Härdin @ 2023-02-24 9:00 ` Tomas Härdin 2023-02-28 12:13 ` "zhilizhao(赵志立)" 2023-02-24 9:00 ` [FFmpeg-devel] [PATCH 3/4] lavc/mediacodec_wrapper: Add function for probing supported color formats Tomas Härdin ` (2 subsequent siblings) 3 siblings, 1 reply; 8+ messages in thread From: Tomas Härdin @ 2023-02-24 9:00 UTC (permalink / raw) To: FFmpeg development discussions and patches [-- Attachment #1: Type: text/plain, Size: 1 bytes --] [-- Attachment #2: 0002-lavc-mediacodec_wrapper-Refactor-ff_AMediaCodecList_.patch --] [-- Type: text/x-patch, Size: 10215 bytes --] From 9d4defbc92e4976f7d652149a215e2c165239e42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomas=20H=C3=A4rdin?= <git@haerdin.se> Date: Wed, 11 Jan 2023 21:49:30 +0100 Subject: [PATCH 2/4] lavc/mediacodec_wrapper: Refactor ff_AMediaCodecList_getCodecNameByType() A lot shorter, nested variables and keeps going in case of exceptions. Makes use of C99 declarations. This patch has been released by Epic Games' legal department. --- libavcodec/mediacodec_wrapper.c | 162 +++++++++----------------------- 1 file changed, 45 insertions(+), 117 deletions(-) diff --git a/libavcodec/mediacodec_wrapper.c b/libavcodec/mediacodec_wrapper.c index 34ec2134aa..82eead2833 100644 --- a/libavcodec/mediacodec_wrapper.c +++ b/libavcodec/mediacodec_wrapper.c @@ -2,6 +2,7 @@ * Android MediaCodec Wrapper * * Copyright (c) 2015-2016 Matthieu Bouron <matthieu.bouron stupeflix.com> + * Modifications by Epic Games, Inc., 2023. * * This file is part of FFmpeg. * @@ -365,26 +366,13 @@ int ff_AMediaCodecProfile_getProfileFromAVCodecContext(AVCodecContext *avctx) char *ff_AMediaCodecList_getCodecNameByType(const char *mime, int profile, int encoder, void *log_ctx) { int ret; - int i; - int codec_count; int found_codec = 0; char *name = NULL; - char *supported_type = NULL; JNIEnv *env = NULL; struct JNIAMediaCodecListFields jfields = { 0 }; struct JNIAMediaFormatFields mediaformat_jfields = { 0 }; - jobject codec_name = NULL; - - jobject info = NULL; - jobject type = NULL; - jobjectArray types = NULL; - - jobject capabilities = NULL; - jobject profile_level = NULL; - jobjectArray profile_levels = NULL; - JNI_GET_ENV_OR_RETURN(env, log_ctx, NULL); if ((ret = ff_jni_init_jfields(env, &jfields, jni_amediacodeclist_mapping, 0, log_ctx)) < 0) { @@ -395,29 +383,26 @@ char *ff_AMediaCodecList_getCodecNameByType(const char *mime, int profile, int e goto done; } - codec_count = (*env)->CallStaticIntMethod(env, jfields.mediacodec_list_class, jfields.get_codec_count_id); + int codec_count = (*env)->CallStaticIntMethod(env, jfields.mediacodec_list_class, jfields.get_codec_count_id); if (ff_jni_exception_check(env, 1, log_ctx) < 0) { goto done; } - for(i = 0; i < codec_count; i++) { - int j; - int type_count; - int is_encoder; - - info = (*env)->CallStaticObjectMethod(env, jfields.mediacodec_list_class, jfields.get_codec_info_at_id, i); + for (int i = 0; i < codec_count && !found_codec; i++) { + jobject 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) { - goto done; + continue; } - types = (*env)->CallObjectMethod(env, info, jfields.get_supported_types_id); + jobject codec_name = NULL; + jobjectArray types = (*env)->CallObjectMethod(env, info, jfields.get_supported_types_id); if (ff_jni_exception_check(env, 1, log_ctx) < 0) { - goto done; + goto done_with_info; } - is_encoder = (*env)->CallBooleanMethod(env, info, jfields.is_encoder_id); + int is_encoder = (*env)->CallBooleanMethod(env, info, jfields.is_encoder_id); if (ff_jni_exception_check(env, 1, log_ctx) < 0) { - goto done; + goto done_with_info; } if (is_encoder != encoder) { @@ -427,7 +412,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) { - goto done; + goto done_with_info; } if (is_software_only) { @@ -437,17 +422,12 @@ 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) { - goto done; + goto done_with_info; } name = ff_jni_jstring_to_utf_chars(env, codec_name, log_ctx); if (!name) { - goto done; - } - - if (codec_name) { - (*env)->DeleteLocalRef(env, codec_name); - codec_name = NULL; + goto done_with_info; } /* Skip software decoders */ @@ -459,141 +439,89 @@ char *ff_AMediaCodecList_getCodecNameByType(const char *mime, int profile, int e goto done_with_info; } - type_count = (*env)->GetArrayLength(env, types); - for (j = 0; j < type_count; j++) { - int k; - int profile_count; - - type = (*env)->GetObjectArrayElement(env, types, j); + int type_count = (*env)->GetArrayLength(env, types); + for (int j = 0; j < type_count && !found_codec; j++) { + jobject type = (*env)->GetObjectArrayElement(env, types, j); if (ff_jni_exception_check(env, 1, log_ctx) < 0) { - goto done; + continue; } - supported_type = ff_jni_jstring_to_utf_chars(env, type, log_ctx); + jobject capabilities = NULL; + jobjectArray profile_levels = NULL; + char *supported_type = ff_jni_jstring_to_utf_chars(env, type, log_ctx); if (!supported_type) { - goto done; + goto done_with_type; } - if (av_strcasecmp(supported_type, mime)) { + int strcasecmp_ret = av_strcasecmp(supported_type, mime); + av_freep(&supported_type); + if (strcasecmp_ret) { goto done_with_type; } capabilities = (*env)->CallObjectMethod(env, info, jfields.get_codec_capabilities_id, type); if (ff_jni_exception_check(env, 1, log_ctx) < 0) { - goto done; + goto done_with_type; } profile_levels = (*env)->GetObjectField(env, capabilities, jfields.profile_levels_id); if (ff_jni_exception_check(env, 1, log_ctx) < 0) { - goto done; + goto done_with_type; } - profile_count = (*env)->GetArrayLength(env, profile_levels); - if (!profile_count) { + // match profile if desired by user (profile >= 0) and codec has non-empty profileLevels + int profile_count = (*env)->GetArrayLength(env, profile_levels); + if (!profile_count || profile < 0) { found_codec = 1; - } - for (k = 0; k < profile_count; k++) { - int supported_profile = 0; - - if (profile < 0) { - found_codec = 1; - break; - } - - profile_level = (*env)->GetObjectArrayElement(env, profile_levels, k); - if (ff_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) { - goto done; - } - - found_codec = profile == supported_profile; + } else { + for (int k = 0; k < profile_count && !found_codec; k++) { + jobject profile_level = (*env)->GetObjectArrayElement(env, profile_levels, k); + if (ff_jni_exception_check(env, 1, log_ctx) < 0) { + continue; + } + + int supported_profile = (*env)->GetIntField(env, profile_level, jfields.profile_id); + if (ff_jni_exception_check(env, 1, log_ctx) >= 0) { + found_codec = profile == supported_profile; + } - if (profile_level) { (*env)->DeleteLocalRef(env, profile_level); - profile_level = NULL; - } - - if (found_codec) { - break; } } done_with_type: if (profile_levels) { (*env)->DeleteLocalRef(env, profile_levels); - profile_levels = NULL; } if (capabilities) { (*env)->DeleteLocalRef(env, capabilities); - capabilities = NULL; } if (type) { (*env)->DeleteLocalRef(env, type); - type = NULL; - } - - av_freep(&supported_type); - - if (found_codec) { - break; } } done_with_info: if (info) { (*env)->DeleteLocalRef(env, info); - info = NULL; } if (types) { (*env)->DeleteLocalRef(env, types); - types = NULL; } - if (found_codec) { - break; + if (codec_name) { + (*env)->DeleteLocalRef(env, codec_name); } - av_freep(&name); + if (!found_codec) { + av_freep(&name); + } } 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); - } - - 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); -- 2.30.2 [-- 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] 8+ messages in thread
* Re: [FFmpeg-devel] [PATCH 2/4] lavc/mediacodec_wrapper: Refactor ff_AMediaCodecList_getCodecNameByType() 2023-02-24 9:00 ` [FFmpeg-devel] [PATCH 2/4] lavc/mediacodec_wrapper: Refactor ff_AMediaCodecList_getCodecNameByType() Tomas Härdin @ 2023-02-28 12:13 ` "zhilizhao(赵志立)" 0 siblings, 0 replies; 8+ messages in thread From: "zhilizhao(赵志立)" @ 2023-02-28 12:13 UTC (permalink / raw) To: FFmpeg development discussions and patches > > A lot shorter, nested variables and keeps going in case of exceptions. > Makes use of C99 declarations. > > This patch has been released by Epic Games' legal department. This patch triggered multiple warning: warning: mixing declarations and code is incompatible with standards before C99 [-Wdeclaration-after-statement] C99 allows declaration-after-statement, but it’s not allowed by our coding style. -Wdeclaration-after-statement is enabled explicitly in configure. > --- > libavcodec/mediacodec_wrapper.c | 162 +++++++++----------------------- > 1 file changed, 45 insertions(+), 117 deletions(-) > > diff --git a/libavcodec/mediacodec_wrapper.c b/libavcodec/mediacodec_wrapper.c > index 34ec2134aa..82eead2833 100644 > --- a/libavcodec/mediacodec_wrapper.c > +++ b/libavcodec/mediacodec_wrapper.c > @@ -2,6 +2,7 @@ > * Android MediaCodec Wrapper > * > * Copyright (c) 2015-2016 Matthieu Bouron <matthieu.bouron stupeflix.com> > + * Modifications by Epic Games, Inc., 2023. > * > * This file is part of FFmpeg. > * > @@ -365,26 +366,13 @@ int ff_AMediaCodecProfile_getProfileFromAVCodecContext(AVCodecContext *avctx) > char *ff_AMediaCodecList_getCodecNameByType(const char *mime, int profile, int encoder, void *log_ctx) > { > int ret; > - int i; > - int codec_count; > int found_codec = 0; > char *name = NULL; > - char *supported_type = NULL; > > JNIEnv *env = NULL; > struct JNIAMediaCodecListFields jfields = { 0 }; > struct JNIAMediaFormatFields mediaformat_jfields = { 0 }; > > - jobject codec_name = NULL; > - > - jobject info = NULL; > - jobject type = NULL; > - jobjectArray types = NULL; > - > - jobject capabilities = NULL; > - jobject profile_level = NULL; > - jobjectArray profile_levels = NULL; > - > JNI_GET_ENV_OR_RETURN(env, log_ctx, NULL); > > if ((ret = ff_jni_init_jfields(env, &jfields, jni_amediacodeclist_mapping, 0, log_ctx)) < 0) { > @@ -395,29 +383,26 @@ char *ff_AMediaCodecList_getCodecNameByType(const char *mime, int profile, int e > goto done; > } > > - codec_count = (*env)->CallStaticIntMethod(env, jfields.mediacodec_list_class, jfields.get_codec_count_id); > + int codec_count = (*env)->CallStaticIntMethod(env, jfields.mediacodec_list_class, jfields.get_codec_count_id); > if (ff_jni_exception_check(env, 1, log_ctx) < 0) { > goto done; > } > > - for(i = 0; i < codec_count; i++) { > - int j; > - int type_count; > - int is_encoder; > - > - info = (*env)->CallStaticObjectMethod(env, jfields.mediacodec_list_class, jfields.get_codec_info_at_id, i); > + for (int i = 0; i < codec_count && !found_codec; i++) { > + jobject 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) { > - goto done; > + continue; > } > > - types = (*env)->CallObjectMethod(env, info, jfields.get_supported_types_id); > + jobject codec_name = NULL; > + jobjectArray types = (*env)->CallObjectMethod(env, info, jfields.get_supported_types_id); > if (ff_jni_exception_check(env, 1, log_ctx) < 0) { > - goto done; > + goto done_with_info; > } > > - is_encoder = (*env)->CallBooleanMethod(env, info, jfields.is_encoder_id); > + int is_encoder = (*env)->CallBooleanMethod(env, info, jfields.is_encoder_id); > if (ff_jni_exception_check(env, 1, log_ctx) < 0) { > - goto done; > + goto done_with_info; > } > > if (is_encoder != encoder) { > @@ -427,7 +412,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) { > - goto done; > + goto done_with_info; > } > > if (is_software_only) { > @@ -437,17 +422,12 @@ 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) { > - goto done; > + goto done_with_info; > } > > name = ff_jni_jstring_to_utf_chars(env, codec_name, log_ctx); > if (!name) { > - goto done; > - } > - > - if (codec_name) { > - (*env)->DeleteLocalRef(env, codec_name); > - codec_name = NULL; > + goto done_with_info; > } > > /* Skip software decoders */ > @@ -459,141 +439,89 @@ char *ff_AMediaCodecList_getCodecNameByType(const char *mime, int profile, int e > goto done_with_info; > } > > - type_count = (*env)->GetArrayLength(env, types); > - for (j = 0; j < type_count; j++) { > - int k; > - int profile_count; > - > - type = (*env)->GetObjectArrayElement(env, types, j); > + int type_count = (*env)->GetArrayLength(env, types); > + for (int j = 0; j < type_count && !found_codec; j++) { > + jobject type = (*env)->GetObjectArrayElement(env, types, j); > if (ff_jni_exception_check(env, 1, log_ctx) < 0) { > - goto done; > + continue; > } > > - supported_type = ff_jni_jstring_to_utf_chars(env, type, log_ctx); > + jobject capabilities = NULL; > + jobjectArray profile_levels = NULL; > + char *supported_type = ff_jni_jstring_to_utf_chars(env, type, log_ctx); > if (!supported_type) { > - goto done; > + goto done_with_type; > } > > - if (av_strcasecmp(supported_type, mime)) { > + int strcasecmp_ret = av_strcasecmp(supported_type, mime); > + av_freep(&supported_type); > + if (strcasecmp_ret) { > goto done_with_type; > } > > capabilities = (*env)->CallObjectMethod(env, info, jfields.get_codec_capabilities_id, type); > if (ff_jni_exception_check(env, 1, log_ctx) < 0) { > - goto done; > + goto done_with_type; > } > > profile_levels = (*env)->GetObjectField(env, capabilities, jfields.profile_levels_id); > if (ff_jni_exception_check(env, 1, log_ctx) < 0) { > - goto done; > + goto done_with_type; > } > > - profile_count = (*env)->GetArrayLength(env, profile_levels); > - if (!profile_count) { > + // match profile if desired by user (profile >= 0) and codec has non-empty profileLevels > + int profile_count = (*env)->GetArrayLength(env, profile_levels); > + if (!profile_count || profile < 0) { > found_codec = 1; > - } > - for (k = 0; k < profile_count; k++) { > - int supported_profile = 0; > - > - if (profile < 0) { > - found_codec = 1; > - break; > - } > - > - profile_level = (*env)->GetObjectArrayElement(env, profile_levels, k); > - if (ff_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) { > - goto done; > - } > - > - found_codec = profile == supported_profile; > + } else { > + for (int k = 0; k < profile_count && !found_codec; k++) { > + jobject profile_level = (*env)->GetObjectArrayElement(env, profile_levels, k); > + if (ff_jni_exception_check(env, 1, log_ctx) < 0) { > + continue; > + } > + > + int supported_profile = (*env)->GetIntField(env, profile_level, jfields.profile_id); > + if (ff_jni_exception_check(env, 1, log_ctx) >= 0) { > + found_codec = profile == supported_profile; > + } > > - if (profile_level) { > (*env)->DeleteLocalRef(env, profile_level); > - profile_level = NULL; > - } > - > - if (found_codec) { > - break; > } > } > > done_with_type: > if (profile_levels) { > (*env)->DeleteLocalRef(env, profile_levels); > - profile_levels = NULL; > } > > if (capabilities) { > (*env)->DeleteLocalRef(env, capabilities); > - capabilities = NULL; > } > > if (type) { > (*env)->DeleteLocalRef(env, type); > - type = NULL; > - } > - > - av_freep(&supported_type); > - > - if (found_codec) { > - break; > } > } > > done_with_info: > if (info) { > (*env)->DeleteLocalRef(env, info); > - info = NULL; > } > > if (types) { > (*env)->DeleteLocalRef(env, types); > - types = NULL; > } > > - if (found_codec) { > - break; > + if (codec_name) { > + (*env)->DeleteLocalRef(env, codec_name); > } > > - av_freep(&name); > + if (!found_codec) { > + av_freep(&name); > + } > } > > 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); > - } > - > - 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); > > -- > 2.30.2 > _______________________________________________ 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] 8+ messages in thread
* [FFmpeg-devel] [PATCH 3/4] lavc/mediacodec_wrapper: Add function for probing supported color formats 2023-02-24 8:59 [FFmpeg-devel] [PATCH 1/4] lavc/mediacodecenc: Add pix2color_fmt() and color2pix_fmt() Tomas Härdin 2023-02-24 9:00 ` [FFmpeg-devel] [PATCH 2/4] lavc/mediacodec_wrapper: Refactor ff_AMediaCodecList_getCodecNameByType() Tomas Härdin @ 2023-02-24 9:00 ` Tomas Härdin 2023-02-28 12:18 ` "zhilizhao(赵志立)" 2023-02-24 9:03 ` [FFmpeg-devel] [PATCH 4/4] lavc/mediacodecenc: List supported pixel formats on configuration error Tomas Härdin 2023-02-28 12:02 ` [FFmpeg-devel] [PATCH 1/4] lavc/mediacodecenc: Add pix2color_fmt() and color2pix_fmt() "zhilizhao(赵志立)" 3 siblings, 1 reply; 8+ messages in thread From: Tomas Härdin @ 2023-02-24 9:00 UTC (permalink / raw) To: FFmpeg development discussions and patches [-- Attachment #1: Type: text/plain, Size: 1 bytes --] [-- Attachment #2: 0003-lavc-mediacodec_wrapper-Add-function-for-probing-sup.patch --] [-- Type: text/x-patch, Size: 6206 bytes --] From 557f23650726af7f4881d29411de02f9f8bc78f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomas=20H=C3=A4rdin?= <git@haerdin.se> Date: Wed, 11 Jan 2023 22:25:39 +0100 Subject: [PATCH 3/4] lavc/mediacodec_wrapper: Add function for probing supported color formats This patch has been released by Epic Games' legal department. --- libavcodec/mediacodec_wrapper.c | 112 ++++++++++++++++++++++++++++++++ libavcodec/mediacodec_wrapper.h | 15 +++++ 2 files changed, 127 insertions(+) diff --git a/libavcodec/mediacodec_wrapper.c b/libavcodec/mediacodec_wrapper.c index 82eead2833..9d2560205f 100644 --- a/libavcodec/mediacodec_wrapper.c +++ b/libavcodec/mediacodec_wrapper.c @@ -532,6 +532,118 @@ done: return name; } +int ff_AMediaCodec_color_formats_intersect(const char *codec_name, const char *mime, + const int *in_formats, int nin_formats, + int *out_formats, void *log_ctx) +{ + int ret, found_codec = 0; + jstring jmime = NULL; + JNIEnv *env = NULL; + struct JNIAMediaCodecListFields jfields = { 0 }; + struct JNIAMediaFormatFields mediaformat_jfields = { 0 }; + + JNI_GET_ENV_OR_RETURN(env, log_ctx, -1); + + if ((ret = ff_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) { + goto done; + } + + // convert const char* to java.lang.String + jmime = ff_jni_utf_chars_to_jstring(env, mime, log_ctx); + if (!jmime) { + goto done; + } + + int codec_count = (*env)->CallStaticIntMethod(env, jfields.mediacodec_list_class, jfields.get_codec_count_id); + if (ff_jni_exception_check(env, 1, log_ctx) < 0) { + goto done; + } + + for (int i = 0; i < codec_count && !found_codec; i++) { + jobject 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) { + continue; + } + + char *name = NULL; + jboolean is_copy; + jintArray color_formats = NULL; + jobject capabilities = NULL; + jobject jcodec_name = (*env)->CallObjectMethod(env, info, jfields.get_name_id); + if (ff_jni_exception_check(env, 1, log_ctx) < 0) { + goto done_with_info; + } + + if (!(name = ff_jni_jstring_to_utf_chars(env, jcodec_name, log_ctx))) { + goto done_with_info; + } + + if (strcmp(name, codec_name)) { + goto done_with_info; + } + + capabilities = (*env)->CallObjectMethod(env, info, jfields.get_codec_capabilities_id, jmime); + if (ff_jni_exception_check(env, 1, log_ctx) < 0) { + goto done_with_info; + } + + color_formats = (*env)->GetObjectField(env, capabilities, jfields.color_formats_id); + if (ff_jni_exception_check(env, 1, log_ctx) < 0) { + goto done_with_info; + } + + int color_count = (*env)->GetArrayLength(env, color_formats); + int *elems = (*env)->GetIntArrayElements(env, color_formats, &is_copy); + ret = 0; + found_codec = 1; + + // out_formats = intersect(in_formats, elems) + for (int j = 0; j < nin_formats; j++) { + for (int k = 0; k < color_count; k++) { + if (elems[k] == in_formats[j]) { + out_formats[ret++] = in_formats[j]; + break; + } + } + } + + (*env)->ReleaseIntArrayElements(env, color_formats, elems, JNI_ABORT); + +done_with_info: + if (color_formats) { + (*env)->DeleteLocalRef(env, color_formats); + } + + if (capabilities) { + (*env)->DeleteLocalRef(env, capabilities); + } + + if (jcodec_name) { + (*env)->DeleteLocalRef(env, jcodec_name); + } + + if (info) { + (*env)->DeleteLocalRef(env, info); + } + + av_freep(&name); + } + +done: + if (jmime) { + (*env)->DeleteLocalRef(env, jmime); + } + + 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); + + return found_codec ? ret : -1; +} + static FFAMediaFormat *mediaformat_jni_new(void) { JNIEnv *env = NULL; diff --git a/libavcodec/mediacodec_wrapper.h b/libavcodec/mediacodec_wrapper.h index 1b81e6db84..7ab32c4dc7 100644 --- a/libavcodec/mediacodec_wrapper.h +++ b/libavcodec/mediacodec_wrapper.h @@ -2,6 +2,7 @@ * Android MediaCodec Wrapper * * Copyright (c) 2015-2016 Matthieu Bouron <matthieu.bouron stupeflix.com> + * Modifications by Epic Games, Inc., 2023. * * This file is part of FFmpeg. * @@ -230,6 +231,20 @@ FFAMediaCodec* ff_AMediaCodec_createCodecByName(const char *name, int ndk); FFAMediaCodec* ff_AMediaCodec_createDecoderByType(const char *mime_type, int ndk); FFAMediaCodec* ff_AMediaCodec_createEncoderByType(const char *mime_type, int ndk); +/** + * Intersects the given list of color formats with the formats actually supported by the named codec. + * @param[in] codec_name Name of the codec + * @param[in] mime MIME format. Typically "video/avc" or "video/hevc" + * @param[in] in_formats Array of input color formats + * @param[in] nin_formats Number of elements in in_formats + * @param[out] out_formats Computed intersection of in_formats and supported formats + * @param[in] log_ctx Logging context + * @return Size of out_formats or negative in case of error + */ +int ff_AMediaCodec_color_formats_intersect(const char *codec_name, const char *mime, + const int *in_formats, int nin_formats, + int *out_formats, void *log_ctx); + static inline int ff_AMediaCodec_configure(FFAMediaCodec *codec, const FFAMediaFormat *format, FFANativeWindow *surface, -- 2.30.2 [-- 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] 8+ messages in thread
* Re: [FFmpeg-devel] [PATCH 3/4] lavc/mediacodec_wrapper: Add function for probing supported color formats 2023-02-24 9:00 ` [FFmpeg-devel] [PATCH 3/4] lavc/mediacodec_wrapper: Add function for probing supported color formats Tomas Härdin @ 2023-02-28 12:18 ` "zhilizhao(赵志立)" 0 siblings, 0 replies; 8+ messages in thread From: "zhilizhao(赵志立)" @ 2023-02-28 12:18 UTC (permalink / raw) To: FFmpeg development discussions and patches > This patch has been released by Epic Games' legal department. This patch has the same -Wdeclaration-after-statement issue as patch 2/4. PS: I’m not sure whether the legal statement is appropriate as commit message. It should be self-evident for patches sending to the mailing list :) > --- > libavcodec/mediacodec_wrapper.c | 112 ++++++++++++++++++++++++++++++++ > libavcodec/mediacodec_wrapper.h | 15 +++++ > 2 files changed, 127 insertions(+) > > diff --git a/libavcodec/mediacodec_wrapper.c b/libavcodec/mediacodec_wrapper.c > index 82eead2833..9d2560205f 100644 > --- a/libavcodec/mediacodec_wrapper.c > +++ b/libavcodec/mediacodec_wrapper.c > @@ -532,6 +532,118 @@ done: > return name; > } > _______________________________________________ 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] 8+ messages in thread
* [FFmpeg-devel] [PATCH 4/4] lavc/mediacodecenc: List supported pixel formats on configuration error 2023-02-24 8:59 [FFmpeg-devel] [PATCH 1/4] lavc/mediacodecenc: Add pix2color_fmt() and color2pix_fmt() Tomas Härdin 2023-02-24 9:00 ` [FFmpeg-devel] [PATCH 2/4] lavc/mediacodec_wrapper: Refactor ff_AMediaCodecList_getCodecNameByType() Tomas Härdin 2023-02-24 9:00 ` [FFmpeg-devel] [PATCH 3/4] lavc/mediacodec_wrapper: Add function for probing supported color formats Tomas Härdin @ 2023-02-24 9:03 ` Tomas Härdin 2023-02-28 12:25 ` "zhilizhao(赵志立)" 2023-02-28 12:02 ` [FFmpeg-devel] [PATCH 1/4] lavc/mediacodecenc: Add pix2color_fmt() and color2pix_fmt() "zhilizhao(赵志立)" 3 siblings, 1 reply; 8+ messages in thread From: Tomas Härdin @ 2023-02-24 9:03 UTC (permalink / raw) To: FFmpeg development discussions and patches [-- Attachment #1: Type: text/plain, Size: 242 bytes --] This makes the situation a bit better for users, even if we can't reliably probe pixel formats in init_static_data. I decided to keep this patchset separate from that probing, since printing pixel formats this way should be reliable. /Tomas [-- Attachment #2: 0004-lavc-mediacodecenc-List-supported-pixel-formats-on-c.patch --] [-- Type: text/x-patch, Size: 2939 bytes --] From eed0ed202bf8c496ab945b32e2e7fc7cad062c30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomas=20H=C3=A4rdin?= <git@haerdin.se> Date: Tue, 10 Jan 2023 20:38:56 +0100 Subject: [PATCH 4/4] lavc/mediacodecenc: List supported pixel formats on configuration error This patch has been released by Epic Games' legal department. --- libavcodec/mediacodecenc.c | 46 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/libavcodec/mediacodecenc.c b/libavcodec/mediacodecenc.c index 03c80cbf99..1b8a2837c4 100644 --- a/libavcodec/mediacodecenc.c +++ b/libavcodec/mediacodecenc.c @@ -97,6 +97,12 @@ static const enum AVPixelFormat avc_pix_fmts[] = { AV_PIX_FMT_NONE }; +static const int in_formats[] = { + COLOR_FormatYUV420Planar, + COLOR_FormatYUV420SemiPlanar, + COLOR_FormatSurface, +}; + static void mediacodec_output_format(AVCodecContext *avctx) { MediaCodecEncContext *s = avctx->priv_data; @@ -131,6 +137,45 @@ static enum AVPixelFormat color2pix_fmt(AVCodecContext *avctx, int color_format) av_assert0(0); } +// list pixel formats if the user tried to use one that isn't supported on this device +static void list_pix_fmts(AVCodecContext *avctx, const char *mime) +{ + MediaCodecEncContext *s = avctx->priv_data; + int out_formats[FF_ARRAY_ELEMS(in_formats)], n; + char *name = ff_AMediaCodec_getName(s->codec); + + if (!name) { + // API level likely below 28 + return; + } + + if ((n = ff_AMediaCodec_color_formats_intersect(name, mime, in_formats, + FF_ARRAY_ELEMS(in_formats), + out_formats, avctx)) < 0) { + goto done; + } + + for (int i = 0; i < n; i++) { + if (color2pix_fmt(avctx, out_formats[i]) == avctx->pix_fmt) { + // user specified a pixel format that is actually supported, + // no need to print anything + goto done; + } + } + + AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt); + av_log(avctx, AV_LOG_ERROR, "pixel format %s not supported by MediaCodec %s\n", desc->name, name); + av_log(avctx, AV_LOG_INFO, "supported formats are:"); + for (int i = 0; i < n; i++) { + desc = av_pix_fmt_desc_get(color2pix_fmt(avctx, out_formats[i])); + av_log(avctx, AV_LOG_INFO, " %s", desc->name); + } + av_log(avctx, AV_LOG_INFO, "\n"); + +done: + av_free(name); +} + static int mediacodec_init_bsf(AVCodecContext *avctx) { MediaCodecEncContext *s = avctx->priv_data; @@ -308,6 +353,7 @@ static av_cold int mediacodec_init(AVCodecContext *avctx) ret = ff_AMediaCodec_configure(s->codec, format, s->window, NULL, ret); if (ret) { av_log(avctx, AV_LOG_ERROR, "MediaCodec configure failed, %s\n", av_err2str(ret)); + list_pix_fmts(avctx, codec_mime); goto bailout; } -- 2.30.2 [-- 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] 8+ messages in thread
* Re: [FFmpeg-devel] [PATCH 4/4] lavc/mediacodecenc: List supported pixel formats on configuration error 2023-02-24 9:03 ` [FFmpeg-devel] [PATCH 4/4] lavc/mediacodecenc: List supported pixel formats on configuration error Tomas Härdin @ 2023-02-28 12:25 ` "zhilizhao(赵志立)" 0 siblings, 0 replies; 8+ messages in thread From: "zhilizhao(赵志立)" @ 2023-02-28 12:25 UTC (permalink / raw) To: FFmpeg development discussions and patches > This patch has been released by Epic Games' legal department. > --- > libavcodec/mediacodecenc.c | 46 ++++++++++++++++++++++++++++++++++++++ > 1 file changed, 46 insertions(+) > > diff --git a/libavcodec/mediacodecenc.c b/libavcodec/mediacodecenc.c > index 03c80cbf99..1b8a2837c4 100644 > --- a/libavcodec/mediacodecenc.c > +++ b/libavcodec/mediacodecenc.c > @@ -97,6 +97,12 @@ static const enum AVPixelFormat avc_pix_fmts[] = { > AV_PIX_FMT_NONE > }; > > +static const int in_formats[] = { > + COLOR_FormatYUV420Planar, > + COLOR_FormatYUV420SemiPlanar, > + COLOR_FormatSurface, > +}; > + > static void mediacodec_output_format(AVCodecContext *avctx) > { > MediaCodecEncContext *s = avctx->priv_data; > @@ -131,6 +137,45 @@ static enum AVPixelFormat color2pix_fmt(AVCodecContext *avctx, int color_format) > av_assert0(0); > } > > +// list pixel formats if the user tried to use one that isn't supported on this device > +static void list_pix_fmts(AVCodecContext *avctx, const char *mime) > +{ > + MediaCodecEncContext *s = avctx->priv_data; > + int out_formats[FF_ARRAY_ELEMS(in_formats)], n; > + char *name = ff_AMediaCodec_getName(s->codec); > + > + if (!name) { > + // API level likely below 28 > + return; > + } > + > + if ((n = ff_AMediaCodec_color_formats_intersect(name, mime, in_formats, > + FF_ARRAY_ELEMS(in_formats), > + out_formats, avctx)) < 0) { > + goto done; > + } > + > + for (int i = 0; i < n; i++) { > + if (color2pix_fmt(avctx, out_formats[i]) == avctx->pix_fmt) { > + // user specified a pixel format that is actually supported, > + // no need to print anything > + goto done; > + } > + } > + > + AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt); Missing ‘const’ and triggered -Wdeclaration-after-statement. > + av_log(avctx, AV_LOG_ERROR, "pixel format %s not supported by MediaCodec %s\n", desc->name, name); > + av_log(avctx, AV_LOG_INFO, "supported formats are:"); > + for (int i = 0; i < n; i++) { > + desc = av_pix_fmt_desc_get(color2pix_fmt(avctx, out_formats[i])); > + av_log(avctx, AV_LOG_INFO, " %s", desc->name); > + } > + av_log(avctx, AV_LOG_INFO, "\n"); It’s not thread safe, it can be interrupted by other threads' log message. > + > +done: > + av_free(name); > +} > + > static int mediacodec_init_bsf(AVCodecContext *avctx) > { > MediaCodecEncContext *s = avctx->priv_data; > @@ -308,6 +353,7 @@ static av_cold int mediacodec_init(AVCodecContext *avctx) > ret = ff_AMediaCodec_configure(s->codec, format, s->window, NULL, ret); > if (ret) { > av_log(avctx, AV_LOG_ERROR, "MediaCodec configure failed, %s\n", av_err2str(ret)); > + list_pix_fmts(avctx, codec_mime); > goto bailout; > } > > -- > 2.30.2 > _______________________________________________ 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] 8+ messages in thread
* Re: [FFmpeg-devel] [PATCH 1/4] lavc/mediacodecenc: Add pix2color_fmt() and color2pix_fmt() 2023-02-24 8:59 [FFmpeg-devel] [PATCH 1/4] lavc/mediacodecenc: Add pix2color_fmt() and color2pix_fmt() Tomas Härdin ` (2 preceding siblings ...) 2023-02-24 9:03 ` [FFmpeg-devel] [PATCH 4/4] lavc/mediacodecenc: List supported pixel formats on configuration error Tomas Härdin @ 2023-02-28 12:02 ` "zhilizhao(赵志立)" 3 siblings, 0 replies; 8+ messages in thread From: "zhilizhao(赵志立)" @ 2023-02-28 12:02 UTC (permalink / raw) To: FFmpeg development discussions and patches > +static int pix2color_fmt(AVCodecContext *avctx, enum AVPixelFormat pix_fmt) > +{ > + for (int i = 0; i < FF_ARRAY_ELEMS(color_formats); i++) { > + if (pix_fmt == color_formats[i].pix_fmt) { > + return color_formats[i].color_format; > + } > + } > + av_assert0(0); > +} After extracting to a general function, there is no hint that pix_fmt comes from avctx->pix_fmt. So I prefer return error code here. > + > +static enum AVPixelFormat color2pix_fmt(AVCodecContext *avctx, int color_format) > +{ > + for (int i = 0; i < FF_ARRAY_ELEMS(color_formats); i++) { > + if (color_format == color_formats[i].color_format) { > + return color_formats[i].pix_fmt; > + } > + } > + av_assert0(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] 8+ messages in thread
end of thread, other threads:[~2023-02-28 12:25 UTC | newest] Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2023-02-24 8:59 [FFmpeg-devel] [PATCH 1/4] lavc/mediacodecenc: Add pix2color_fmt() and color2pix_fmt() Tomas Härdin 2023-02-24 9:00 ` [FFmpeg-devel] [PATCH 2/4] lavc/mediacodec_wrapper: Refactor ff_AMediaCodecList_getCodecNameByType() Tomas Härdin 2023-02-28 12:13 ` "zhilizhao(赵志立)" 2023-02-24 9:00 ` [FFmpeg-devel] [PATCH 3/4] lavc/mediacodec_wrapper: Add function for probing supported color formats Tomas Härdin 2023-02-28 12:18 ` "zhilizhao(赵志立)" 2023-02-24 9:03 ` [FFmpeg-devel] [PATCH 4/4] lavc/mediacodecenc: List supported pixel formats on configuration error Tomas Härdin 2023-02-28 12:25 ` "zhilizhao(赵志立)" 2023-02-28 12:02 ` [FFmpeg-devel] [PATCH 1/4] lavc/mediacodecenc: Add pix2color_fmt() and color2pix_fmt() "zhilizhao(赵志立)"
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