]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/mediacodec_wrapper.c
avdevice/decklink_dec: fix build with older SDK
[ffmpeg] / libavcodec / mediacodec_wrapper.c
index dbc37bf4639bfad65ddb86ced790f2edb5f9f547..79abc8b6aa915f224ba7f6ff7fecb3816e4f1965 100644 (file)
@@ -111,6 +111,8 @@ struct JNIAMediaFormatFields {
 
     jmethodID init_id;
 
+    jmethodID contains_key_id;
+
     jmethodID get_integer_id;
     jmethodID get_long_id;
     jmethodID get_float_id;
@@ -132,6 +134,8 @@ static const struct FFJniField jni_amediaformat_mapping[] = {
 
         { "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 },
@@ -152,7 +156,7 @@ static const struct FFJniField jni_amediaformat_mapping[] = {
 static const AVClass amediaformat_class = {
     .class_name = "amediaformat",
     .item_name  = av_default_item_name,
-    .version    = LIBAVCODEC_VERSION_INT,
+    .version    = LIBAVUTIL_VERSION_INT,
 };
 
 struct FFAMediaFormat {
@@ -264,7 +268,7 @@ static const struct FFJniField jni_amediacodec_mapping[] = {
 static const AVClass amediacodec_class = {
     .class_name = "amediacodec",
     .item_name  = av_default_item_name,
-    .version    = LIBAVCODEC_VERSION_INT,
+    .version    = LIBAVUTIL_VERSION_INT,
 };
 
 struct FFAMediaCodec {
@@ -388,8 +392,6 @@ char *ff_AMediaCodecList_getCodecNameByType(const char *mime, int profile, int e
     struct JNIAMediaCodecListFields jfields = { 0 };
     struct JNIAMediaFormatFields mediaformat_jfields = { 0 };
 
-    jobject format = NULL;
-    jobject codec = NULL;
     jobject codec_name = NULL;
 
     jobject info = NULL;
@@ -465,7 +467,17 @@ char *ff_AMediaCodecList_getCodecNameByType(const char *mime, int profile, int e
                     goto done;
                 }
 
-                if (strstr(name, "OMX.google")) {
+                if (codec_name) {
+                    (*env)->DeleteLocalRef(env, codec_name);
+                    codec_name = NULL;
+                }
+
+                /* 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;
                 }
@@ -557,14 +569,6 @@ done_with_info:
     }
 
 done:
-    if (format) {
-        (*env)->DeleteLocalRef(env, format);
-    }
-
-    if (codec) {
-        (*env)->DeleteLocalRef(env, codec);
-    }
-
     if (codec_name) {
         (*env)->DeleteLocalRef(env, codec_name);
     }
@@ -738,6 +742,7 @@ int ff_AMediaFormat_getInt32(FFAMediaFormat* format, const char *name, int32_t *
 
     JNIEnv *env = NULL;
     jstring key = NULL;
+    jboolean contains_key;
 
     av_assert0(format != NULL);
 
@@ -749,6 +754,12 @@ int ff_AMediaFormat_getInt32(FFAMediaFormat* format, const char *name, int32_t *
         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;
@@ -770,6 +781,7 @@ int ff_AMediaFormat_getInt64(FFAMediaFormat* format, const char *name, int64_t *
 
     JNIEnv *env = NULL;
     jstring key = NULL;
+    jboolean contains_key;
 
     av_assert0(format != NULL);
 
@@ -781,6 +793,12 @@ int ff_AMediaFormat_getInt64(FFAMediaFormat* format, const char *name, int64_t *
         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;
@@ -802,6 +820,7 @@ int ff_AMediaFormat_getFloat(FFAMediaFormat* format, const char *name, float *ou
 
     JNIEnv *env = NULL;
     jstring key = NULL;
+    jboolean contains_key;
 
     av_assert0(format != NULL);
 
@@ -813,6 +832,12 @@ int ff_AMediaFormat_getFloat(FFAMediaFormat* format, const char *name, float *ou
         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;
@@ -834,6 +859,7 @@ int ff_AMediaFormat_getBuffer(FFAMediaFormat* format, const char *name, void** d
 
     JNIEnv *env = NULL;
     jstring key = NULL;
+    jboolean contains_key;
     jobject result = NULL;
 
     av_assert0(format != NULL);
@@ -846,6 +872,12 @@ int ff_AMediaFormat_getBuffer(FFAMediaFormat* format, const char *name, void** d
         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;
@@ -885,6 +917,7 @@ int ff_AMediaFormat_getString(FFAMediaFormat* format, const char *name, const ch
 
     JNIEnv *env = NULL;
     jstring key = NULL;
+    jboolean contains_key;
     jstring result = NULL;
 
     av_assert0(format != NULL);
@@ -897,6 +930,12 @@ int ff_AMediaFormat_getString(FFAMediaFormat* format, const char *name, const ch
         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;
@@ -1264,6 +1303,12 @@ int ff_AMediaCodec_delete(FFAMediaCodec* codec)
         ret = AVERROR_EXTERNAL;
     }
 
+    (*env)->DeleteGlobalRef(env, codec->input_buffers);
+    codec->input_buffers = NULL;
+
+    (*env)->DeleteGlobalRef(env, codec->output_buffers);
+    codec->output_buffers = NULL;
+
     (*env)->DeleteGlobalRef(env, codec->object);
     codec->object = NULL;
 
@@ -1293,6 +1338,10 @@ char *ff_AMediaCodec_getName(FFAMediaCodec *codec)
     ret = ff_jni_jstring_to_utf_chars(env, name, codec);
 
 fail:
+    if (name) {
+        (*env)->DeleteLocalRef(env, name);
+    }
+
     return ret;
 }
 
@@ -1388,7 +1437,7 @@ int ff_AMediaCodec_releaseOutputBufferAtTime(FFAMediaCodec *codec, size_t idx, i
 
     JNI_GET_ENV_OR_RETURN(env, codec, AVERROR_EXTERNAL);
 
-    (*env)->CallVoidMethod(env, codec->object, codec->jfields.release_output_buffer_at_time_id, (jint)idx, timestampNs);
+    (*env)->CallVoidMethod(env, codec->object, codec->jfields.release_output_buffer_at_time_id, (jint)idx, (jlong)timestampNs);
     if (ff_jni_exception_check(env, 1, codec) < 0) {
         ret = AVERROR_EXTERNAL;
         goto fail;
@@ -1643,3 +1692,18 @@ int ff_AMediaCodec_cleanOutputBuffers(FFAMediaCodec *codec)
 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;
+}