This is an automated email from the git hooks/post-receive script.

Git pushed a commit to branch master
in repository ffmpeg.

commit e5d295b3cd467fc713300e208ba2dacc7ff603a0
Author:     罗乾林 <[email protected]>
AuthorDate: Thu May 7 08:16:49 2026 +0800
Commit:     Zhao Zhili <[email protected]>
CommitDate: Sun Aug 30 03:23:09 2026 +0000

    avcodec/mediacodec_wrapper: avoid leaking setBuffer backing storage
---
 libavcodec/mediacodec_wrapper.c | 126 +++++++++++++++++++++++++++++++++++-----
 1 file changed, 113 insertions(+), 13 deletions(-)

diff --git a/libavcodec/mediacodec_wrapper.c b/libavcodec/mediacodec_wrapper.c
index 283bbe72d6..895b9aaa20 100644
--- a/libavcodec/mediacodec_wrapper.c
+++ b/libavcodec/mediacodec_wrapper.c
@@ -110,6 +110,13 @@ struct JNIAMediaFormatFields {
 
     jmethodID to_string_id;
 
+    jclass bytebuffer_class;
+    jmethodID bytebuffer_wrap_id;
+    jmethodID bytebuffer_duplicate_id;
+    jmethodID bytebuffer_slice_id;
+    jmethodID bytebuffer_remaining_id;
+    jmethodID bytebuffer_get_id;
+
 };
 
 #define OFFSET(x) offsetof(struct JNIAMediaFormatFields, x)
@@ -134,6 +141,13 @@ static const struct FFJniField jni_amediaformat_mapping[] 
= {
 
         { "android/media/MediaFormat", "toString", "()Ljava/lang/String;", 
FF_JNI_METHOD, OFFSET(to_string_id), 1 },
 
+    { "java/nio/ByteBuffer", NULL, NULL, FF_JNI_CLASS, 
OFFSET(bytebuffer_class), 1 },
+        { "java/nio/ByteBuffer", "wrap", "([B)Ljava/nio/ByteBuffer;", 
FF_JNI_STATIC_METHOD, OFFSET(bytebuffer_wrap_id), 1 },
+        { "java/nio/ByteBuffer", "duplicate", "()Ljava/nio/ByteBuffer;", 
FF_JNI_METHOD, OFFSET(bytebuffer_duplicate_id), 1 },
+        { "java/nio/ByteBuffer", "slice", "()Ljava/nio/ByteBuffer;", 
FF_JNI_METHOD, OFFSET(bytebuffer_slice_id), 1 },
+        { "java/nio/ByteBuffer", "remaining", "()I", FF_JNI_METHOD, 
OFFSET(bytebuffer_remaining_id), 1 },
+        { "java/nio/ByteBuffer", "get", "([B)Ljava/nio/ByteBuffer;", 
FF_JNI_METHOD, OFFSET(bytebuffer_get_id), 1 },
+
     { NULL }
 };
 #undef OFFSET
@@ -921,6 +935,8 @@ static int mediaformat_jni_getBuffer(FFAMediaFormat* ctx, 
const char *name, void
     av_assert0(format != NULL);
 
     JNI_GET_ENV_OR_RETURN(env, format, 0);
+    *data = NULL;
+    *size = 0;
 
     key = ff_jni_utf_chars_to_jstring(env, name, format);
     if (!key) {
@@ -940,18 +956,97 @@ static int mediaformat_jni_getBuffer(FFAMediaFormat* ctx, 
const char *name, void
         goto fail;
     }
 
-    *data = (*env)->GetDirectBufferAddress(env, result);
-    *size = (*env)->GetDirectBufferCapacity(env, result);
+    if (result) {
+        jobject duplicate = NULL;
+        jobject slice = NULL;
+        jbyteArray byte_array = NULL;
+        jint remaining = 0;
+        void *src = NULL;
 
-    if (*data && *size) {
-        void *src = *data;
-        *data = av_malloc(*size);
-        if (!*data) {
+        duplicate = (*env)->CallObjectMethod(env, result, 
format->jfields.bytebuffer_duplicate_id);
+        if ((ret = ff_jni_exception_check(env, 1, format)) < 0 || !duplicate) {
             ret = 0;
             goto fail;
         }
 
-        memcpy(*data, src, *size);
+        slice = (*env)->CallObjectMethod(env, duplicate, 
format->jfields.bytebuffer_slice_id);
+        if ((ret = ff_jni_exception_check(env, 1, format)) < 0 || !slice) {
+            ret = 0;
+            (*env)->DeleteLocalRef(env, duplicate);
+            goto fail;
+        }
+
+        remaining = (*env)->CallIntMethod(env, slice, 
format->jfields.bytebuffer_remaining_id);
+        if ((ret = ff_jni_exception_check(env, 1, format)) < 0 || remaining < 
0) {
+            ret = 0;
+            (*env)->DeleteLocalRef(env, slice);
+            (*env)->DeleteLocalRef(env, duplicate);
+            goto fail;
+        }
+        if (!remaining) {
+            ret = 1;
+            (*env)->DeleteLocalRef(env, slice);
+            (*env)->DeleteLocalRef(env, duplicate);
+            goto fail;
+        }
+
+        src = (*env)->GetDirectBufferAddress(env, slice);
+        if (src) {
+            *size = (size_t)remaining;
+            *data = av_malloc(*size);
+            if (!*data) {
+                ret = 0;
+                (*env)->DeleteLocalRef(env, slice);
+                (*env)->DeleteLocalRef(env, duplicate);
+                goto fail;
+            }
+            memcpy(*data, src, *size);
+        } else {
+            byte_array = (*env)->NewByteArray(env, remaining);
+            if (!byte_array) {
+                ret = 0;
+                (*env)->DeleteLocalRef(env, slice);
+                (*env)->DeleteLocalRef(env, duplicate);
+                goto fail;
+            }
+
+            (*env)->CallObjectMethod(env, slice, 
format->jfields.bytebuffer_get_id, byte_array);
+            if ((ret = ff_jni_exception_check(env, 1, format)) < 0) {
+                ret = 0;
+                (*env)->DeleteLocalRef(env, byte_array);
+                (*env)->DeleteLocalRef(env, slice);
+                (*env)->DeleteLocalRef(env, duplicate);
+                goto fail;
+            }
+
+            *size = (size_t)remaining;
+            *data = av_malloc(*size);
+            if (!*data) {
+                ret = 0;
+                (*env)->DeleteLocalRef(env, byte_array);
+                (*env)->DeleteLocalRef(env, slice);
+                (*env)->DeleteLocalRef(env, duplicate);
+                goto fail;
+            }
+
+            (*env)->GetByteArrayRegion(env, byte_array, 0, remaining, (jbyte 
*)*data);
+            if ((ret = ff_jni_exception_check(env, 1, format)) < 0) {
+                ret = 0;
+                av_freep(data);
+                (*env)->DeleteLocalRef(env, byte_array);
+                (*env)->DeleteLocalRef(env, slice);
+                (*env)->DeleteLocalRef(env, duplicate);
+                goto fail;
+            }
+
+            (*env)->DeleteLocalRef(env, byte_array);
+        }
+
+        (*env)->DeleteLocalRef(env, slice);
+        (*env)->DeleteLocalRef(env, duplicate);
+    } else {
+        ret = 0;
+        goto fail;
     }
 
     ret = 1;
@@ -1115,7 +1210,7 @@ static void mediaformat_jni_setBuffer(FFAMediaFormat* 
ctx, const char* name, voi
     JNIEnv *env = NULL;
     jstring key = NULL;
     jobject buffer = NULL;
-    void *buffer_data = NULL;
+    jbyteArray byte_array = NULL;
     FFAMediaFormatJni *format = (FFAMediaFormatJni *)ctx;
 
     av_assert0(format != NULL);
@@ -1131,15 +1226,19 @@ static void mediaformat_jni_setBuffer(FFAMediaFormat* 
ctx, const char* name, voi
         goto fail;
     }
 
-    buffer_data = av_malloc(size);
-    if (!buffer_data) {
+    byte_array = (*env)->NewByteArray(env, (jsize)size);
+    if (!byte_array) {
         goto fail;
     }
 
-    memcpy(buffer_data, data, size);
+    (*env)->SetByteArrayRegion(env, byte_array, 0, (jsize)size, (const jbyte 
*)data);
+    if (ff_jni_exception_check(env, 1, format) < 0) {
+        goto fail;
+    }
 
-    buffer = (*env)->NewDirectByteBuffer(env, buffer_data, size);
-    if (!buffer) {
+    buffer = (*env)->CallStaticObjectMethod(env, 
format->jfields.bytebuffer_class,
+                                            
format->jfields.bytebuffer_wrap_id, byte_array);
+    if ((ff_jni_exception_check(env, 1, format) < 0) || !buffer) {
         goto fail;
     }
 
@@ -1150,6 +1249,7 @@ static void mediaformat_jni_setBuffer(FFAMediaFormat* 
ctx, const char* name, voi
 
 fail:
     (*env)->DeleteLocalRef(env, key);
+    (*env)->DeleteLocalRef(env, byte_array);
     (*env)->DeleteLocalRef(env, buffer);
 }
 

-- 
To stop receiving notification emails like this one, please contact
[email protected].
_______________________________________________
ffmpeg-cvslog mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to