From: Matthieu Bouron <matthieu.bou...@stupeflix.com> Codec width/height restrictions seem hardcoded at the OMX level and seem arbitrary. Bypassing those restrictions allows a device to decode streams at higher resolutions.
For example it allows a Nexus 5 to decode h264 streams with a resolution higher than 1920x1080. --- libavcodec/mediacodec_wrapper.c | 31 ++++++++++++++++++++++++++----- libavcodec/mediacodec_wrapper.h | 2 +- libavcodec/mediacodecdec.c | 2 +- 3 files changed, 28 insertions(+), 7 deletions(-) diff --git a/libavcodec/mediacodec_wrapper.c b/libavcodec/mediacodec_wrapper.c index c847a11..2e3fcef 100644 --- a/libavcodec/mediacodec_wrapper.c +++ b/libavcodec/mediacodec_wrapper.c @@ -33,7 +33,8 @@ struct JNIAMediaCodecListFields { jclass mediaformat_class; - jmethodID create_video_format_id; + jmethodID mediaformat_init_id; + jmethodID set_string_id; jclass mediacodec_list_class; jmethodID init_id; @@ -51,7 +52,8 @@ struct JNIAMediaCodecListFields { static const struct FFJniField jfields_mapping[] = { { "android/media/MediaFormat", NULL, NULL, FF_JNI_CLASS, offsetof(struct JNIAMediaCodecListFields, mediaformat_class), 1 }, - { "android/media/MediaFormat", "createVideoFormat", "(Ljava/lang/String;II)Landroid/media/MediaFormat;", FF_JNI_STATIC_METHOD, offsetof(struct JNIAMediaCodecListFields, create_video_format_id), 1 }, + { "android/media/MediaFormat", "<init>", "()V", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecListFields, mediaformat_init_id), 1}, + { "android/media/MediaFormat", "setString", "(Ljava/lang/String;Ljava/lang/String;)V", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecListFields, set_string_id), 1}, { "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 }, @@ -87,7 +89,7 @@ static const struct FFJniField jfields_mapping[] = { ff_jni_detach_env(log_ctx); \ } while (0) -char *ff_AMediaCodecList_getCodecNameByType(const char *mime, int width, int height, void *log_ctx) +char *ff_AMediaCodecList_getCodecNameByType(const char *mime, void *log_ctx) { int ret; char *name = NULL; @@ -99,6 +101,7 @@ char *ff_AMediaCodecList_getCodecNameByType(const char *mime, int width, int hei jobject format = NULL; jobject codec = NULL; + jstring key = NULL; jstring tmp = NULL; jobject info = NULL; @@ -112,15 +115,29 @@ char *ff_AMediaCodecList_getCodecNameByType(const char *mime, int width, int hei } if (jfields.init_id && jfields.find_decoder_for_format_id) { + key = ff_jni_utf_chars_to_jstring(env, "mime", log_ctx); + if (!key) { + goto done; + } + tmp = ff_jni_utf_chars_to_jstring(env, mime, log_ctx); if (!tmp) { goto done; } - format = (*env)->CallStaticObjectMethod(env, jfields.mediaformat_class, jfields.create_video_format_id, tmp, width, height); + format = (*env)->NewObject(env, jfields.mediaformat_class, jfields.mediaformat_init_id); + if (ff_jni_exception_check(env, 1, log_ctx) < 0) { + goto done; + } + + (*env)->CallVoidMethod(env, format, jfields.set_string_id, key, tmp); if (ff_jni_exception_check(env, 1, log_ctx) < 0) { goto done; } + + (*env)->DeleteLocalRef(env, key); + key = NULL; + (*env)->DeleteLocalRef(env, tmp); tmp = NULL; @@ -135,7 +152,7 @@ char *ff_AMediaCodecList_getCodecNameByType(const char *mime, int width, int hei } if (!tmp) { av_log(NULL, AV_LOG_ERROR, "Could not find decoder in media codec list " - "for format { mime=%s width=%d height=%d }\n", mime, width, height); + "for format { mime=%s }\n", mime); goto done; } @@ -232,6 +249,10 @@ done: (*env)->DeleteLocalRef(env, codec); } + if (key) { + (*env)->DeleteLocalRef(env, key); + } + if (tmp) { (*env)->DeleteLocalRef(env, tmp); } diff --git a/libavcodec/mediacodec_wrapper.h b/libavcodec/mediacodec_wrapper.h index a804b61..36cd258 100644 --- a/libavcodec/mediacodec_wrapper.h +++ b/libavcodec/mediacodec_wrapper.h @@ -52,7 +52,7 @@ * */ -char *ff_AMediaCodecList_getCodecNameByType(const char *mime, int width, int height, void *log_ctx); +char *ff_AMediaCodecList_getCodecNameByType(const char *mime, void *log_ctx); struct FFAMediaFormat; typedef struct FFAMediaFormat FFAMediaFormat; diff --git a/libavcodec/mediacodecdec.c b/libavcodec/mediacodecdec.c index c21ceba..712f984 100644 --- a/libavcodec/mediacodecdec.c +++ b/libavcodec/mediacodecdec.c @@ -311,7 +311,7 @@ int ff_mediacodec_dec_init(AVCodecContext *avctx, MediaCodecDecContext *s, s->first_buffer_at = av_gettime(); - s->codec_name = ff_AMediaCodecList_getCodecNameByType(mime, avctx->width, avctx->height, avctx); + s->codec_name = ff_AMediaCodecList_getCodecNameByType(mime, avctx); if (!s->codec_name) { ret = AVERROR_EXTERNAL; goto fail; -- 2.8.3 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel