jmethodID init_id;
+ jmethodID contains_key_id;
+
jmethodID get_integer_id;
jmethodID get_long_id;
jmethodID get_float_id;
{ "android/media/MediaFormat", "<init>", "()V", FF_JNI_METHOD, offsetof(struct JNIAMediaFormatFields, init_id), 1 },
+ { "android/media/MediaFormat", "containsKey", "(Ljava/lang/String;)Z", FF_JNI_METHOD,offsetof(struct JNIAMediaFormatFields, 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 },
static const AVClass amediaformat_class = {
.class_name = "amediaformat",
.item_name = av_default_item_name,
- .version = LIBAVCODEC_VERSION_INT,
+ .version = LIBAVUTIL_VERSION_INT,
};
struct FFAMediaFormat {
static const AVClass amediacodec_class = {
.class_name = "amediacodec",
.item_name = av_default_item_name,
- .version = LIBAVCODEC_VERSION_INT,
+ .version = LIBAVUTIL_VERSION_INT,
};
struct FFAMediaCodec {
struct JNIAMediaCodecFields jfields;
jobject object;
+ jobject buffer_info;
jobject input_buffers;
jobject output_buffers;
goto done;
}
- if (strstr(name, "OMX.google")) {
+ /* Skip software decoders */
+ if (
+ strstr(name, "OMX.google") ||
+ strstr(name, "OMX.ffmpeg") ||
+ (strstr(name, "OMX.SEC") && strstr(name, ".sw.")) ||
+ !strcmp(name, "OMX.qcom.video.decoder.hevcswvdec")) {
av_freep(&name);
goto done_with_type;
}
JNIEnv *env = NULL;
jstring key = NULL;
+ jboolean contains_key;
av_assert0(format != NULL);
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) {
+ 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) {
ret = 0;
JNIEnv *env = NULL;
jstring key = NULL;
+ jboolean contains_key;
av_assert0(format != NULL);
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) {
+ 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) {
ret = 0;
JNIEnv *env = NULL;
jstring key = NULL;
+ jboolean contains_key;
av_assert0(format != NULL);
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) {
+ 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) {
ret = 0;
JNIEnv *env = NULL;
jstring key = NULL;
+ jboolean contains_key;
jobject result = NULL;
av_assert0(format != NULL);
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) {
+ 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) {
ret = 0;
JNIEnv *env = NULL;
jstring key = NULL;
+ jboolean contains_key;
jstring result = NULL;
av_assert0(format != NULL);
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) {
+ 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) {
ret = 0;
FFAMediaCodec *codec = NULL;
jstring jarg = NULL;
jobject object = NULL;
+ jobject buffer_info = NULL;
jmethodID create_id = NULL;
codec = av_mallocz(sizeof(FFAMediaCodec));
codec->has_get_i_o_buffer = 1;
}
+ buffer_info = (*env)->NewObject(env, codec->jfields.mediainfo_class, codec->jfields.init_id);
+ if (ff_jni_exception_check(env, 1, codec) < 0) {
+ goto fail;
+ }
+
+ codec->buffer_info = (*env)->NewGlobalRef(env, buffer_info);
+ if (!codec->buffer_info) {
+ goto fail;
+ }
+
ret = 0;
fail:
if (jarg) {
(*env)->DeleteLocalRef(env, object);
}
+ if (buffer_info) {
+ (*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);
+ }
+
ff_jni_reset_jfields(env, &codec->jfields, jni_amediacodec_mapping, 1, codec);
av_freep(&codec);
}
(*env)->DeleteGlobalRef(env, codec->object);
codec->object = NULL;
+ (*env)->DeleteGlobalRef(env, codec->buffer_info);
+ codec->buffer_info = NULL;
+
ff_jni_reset_jfields(env, &codec->jfields, jni_amediacodec_mapping, 1, codec);
av_freep(&codec);
int ret = 0;
JNIEnv *env = NULL;
- jobject mediainfo = NULL;
-
JNI_GET_ENV_OR_RETURN(env, codec, AVERROR_EXTERNAL);
- mediainfo = (*env)->NewObject(env, codec->jfields.mediainfo_class, codec->jfields.init_id);
+ 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) {
- ret = AVERROR_EXTERNAL;
- goto fail;
+ return AVERROR_EXTERNAL;
}
- ret = (*env)->CallIntMethod(env, codec->object, codec->jfields.dequeue_output_buffer_id, mediainfo, timeoutUs);
+ info->flags = (*env)->GetIntField(env, codec->buffer_info, codec->jfields.flags_id);
if (ff_jni_exception_check(env, 1, codec) < 0) {
- ret = AVERROR_EXTERNAL;
- goto fail;
+ return AVERROR_EXTERNAL;
}
- info->flags = (*env)->GetIntField(env, mediainfo, codec->jfields.flags_id);
+ info->offset = (*env)->GetIntField(env, codec->buffer_info, codec->jfields.offset_id);
if (ff_jni_exception_check(env, 1, codec) < 0) {
- ret = AVERROR_EXTERNAL;
- goto fail;
- }
-
- info->offset = (*env)->GetIntField(env, mediainfo, codec->jfields.offset_id);
- if (ff_jni_exception_check(env, 1, codec) < 0) {
- ret = AVERROR_EXTERNAL;
- goto fail;
+ return AVERROR_EXTERNAL;
}
- info->presentationTimeUs = (*env)->GetLongField(env, mediainfo, codec->jfields.presentation_time_us_id);
+ info->presentationTimeUs = (*env)->GetLongField(env, codec->buffer_info, codec->jfields.presentation_time_us_id);
if (ff_jni_exception_check(env, 1, codec) < 0) {
- ret = AVERROR_EXTERNAL;
- goto fail;
+ return AVERROR_EXTERNAL;
}
- info->size = (*env)->GetIntField(env, mediainfo, codec->jfields.size_id);
+ info->size = (*env)->GetIntField(env, codec->buffer_info, codec->jfields.size_id);
if (ff_jni_exception_check(env, 1, codec) < 0) {
- ret = AVERROR_EXTERNAL;
- goto fail;
- }
-fail:
- if (mediainfo) {
- (*env)->DeleteLocalRef(env, mediainfo);
+ return AVERROR_EXTERNAL;
}
return ret;
fail:
return ret;
}
+
+int ff_Build_SDK_INT(AVCodecContext *avctx)
+{
+ int ret = -1;
+ JNIEnv *env = NULL;
+ jclass versionClass;
+ jfieldID sdkIntFieldID;
+ JNI_GET_ENV_OR_RETURN(env, avctx, -1);
+
+ versionClass = (*env)->FindClass(env, "android/os/Build$VERSION");
+ sdkIntFieldID = (*env)->GetStaticFieldID(env, versionClass, "SDK_INT", "I");
+ ret = (*env)->GetStaticIntField(env, versionClass, sdkIntFieldID);
+ (*env)->DeleteLocalRef(env, versionClass);
+ return ret;
+}