This is an automated email from the git hooks/post-receive script. Git pushed a commit to branch master in repository ffmpeg.
commit 2d9c8a93820680b550bf73509438cd998d631380 Author: marcos ashton <[email protected]> AuthorDate: Thu Apr 9 15:24:48 2026 +0100 Commit: michaelni <[email protected]> CommitDate: Tue Apr 28 16:17:47 2026 +0000 tests/fate/libavutil: add FATE test for buffer Test av_buffer_alloc, av_buffer_allocz, av_buffer_create with custom free callback, AV_BUFFER_FLAG_READONLY, av_buffer_ref, av_buffer_is_writable, av_buffer_get_ref_count, av_buffer_make_writable, av_buffer_realloc (including from NULL), av_buffer_replace (including with NULL), av_buffer_pool init/get/uninit cycle, av_buffer_pool_init2 with custom alloc and pool_free callbacks, av_buffer_pool_buffer_get_opaque, and OOM paths via av_max_alloc. Coverage for libavutil/buffer.c: 0.00% -> 90.19% Remaining uncovered lines are mutex init failures and secondary allocation failure paths. --- .forgejo/CODEOWNERS | 2 + libavutil/Makefile | 1 + libavutil/tests/buffer.c | 251 +++++++++++++++++++++++++++++++++++++++++++++++ tests/fate/libavutil.mak | 4 + tests/ref/fate/buffer | 57 +++++++++++ 5 files changed, 315 insertions(+) diff --git a/.forgejo/CODEOWNERS b/.forgejo/CODEOWNERS index b9b7b107a9..96bee17dff 100644 --- a/.forgejo/CODEOWNERS +++ b/.forgejo/CODEOWNERS @@ -232,7 +232,9 @@ doc/.* @GyanD # tests # ===== tests/checkasm/riscv/.* @Courmisch +libavutil/tests/buffer.* @MarcosAsh tests/ref/.*drawvg.* @ayosec +tests/ref/fate/buffer @MarcosAsh tests/ref/fate/sub-mcc.* @programmerjake # Forgejo diff --git a/libavutil/Makefile b/libavutil/Makefile index 38e08a3d5d..903e5cdcad 100644 --- a/libavutil/Makefile +++ b/libavutil/Makefile @@ -263,6 +263,7 @@ TESTPROGS = adler32 \ base64 \ blowfish \ bprint \ + buffer \ cast5 \ camellia \ channel_layout \ diff --git a/libavutil/tests/buffer.c b/libavutil/tests/buffer.c new file mode 100644 index 0000000000..b6e67befb4 --- /dev/null +++ b/libavutil/tests/buffer.c @@ -0,0 +1,251 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include <limits.h> +#include <stdio.h> +#include <string.h> + +#include "libavutil/buffer.h" +#include "libavutil/mem.h" + +static int custom_free_called; +static int pool_free_called; +static int pool_alloc2_called; + +static void custom_free(void *opaque, uint8_t *data) +{ + custom_free_called = 1; + av_free(data); +} + +static AVBufferRef *pool_alloc2(void *opaque, size_t size) +{ + pool_alloc2_called = 1; + return av_buffer_alloc(size); +} + +static void pool_free_cb(void *opaque) +{ + pool_free_called = 1; +} + +int main(void) +{ + AVBufferRef *buf, *buf2; + AVBufferPool *pool; + + /* av_buffer_alloc */ + printf("Testing av_buffer_alloc()\n"); + buf = av_buffer_alloc(64); + if (buf) { + printf("alloc: size=%zu data=%s\n", buf->size, buf->data ? "set" : "null"); + printf("writable: %d\n", av_buffer_is_writable(buf)); + printf("refcount: %d\n", av_buffer_get_ref_count(buf)); + av_buffer_unref(&buf); + printf("after unref: %s\n", buf == NULL ? "null" : "leaked"); + } + + /* av_buffer_allocz */ + printf("\nTesting av_buffer_allocz()\n"); + buf = av_buffer_allocz(16); + if (buf) { + int zeroed = 1; + for (int i = 0; i < 16; i++) + if (buf->data[i] != 0) zeroed = 0; + printf("allocz: zeroed=%s\n", zeroed ? "yes" : "no"); + av_buffer_unref(&buf); + } + + /* av_buffer_create with custom free */ + printf("\nTesting av_buffer_create()\n"); + { + uint8_t *data = av_malloc(32); + if (data) { + custom_free_called = 0; + buf = av_buffer_create(data, 32, custom_free, NULL, 0); + if (buf) { + printf("create: size=%zu\n", buf->size); + printf("opaque: %s\n", + av_buffer_get_opaque(buf) == NULL ? "null" : "set"); + av_buffer_unref(&buf); + printf("custom_free called: %s\n", + custom_free_called ? "yes" : "no"); + } else { + av_free(data); + } + } + } + + /* av_buffer_create with READONLY flag */ + printf("\nTesting AV_BUFFER_FLAG_READONLY\n"); + { + uint8_t *data = av_malloc(16); + if (data) { + buf = av_buffer_create(data, 16, custom_free, NULL, + AV_BUFFER_FLAG_READONLY); + if (buf) { + printf("readonly writable: %d\n", av_buffer_is_writable(buf)); + av_buffer_unref(&buf); + } else { + av_free(data); + } + } + } + + /* av_buffer_ref and refcounting */ + printf("\nTesting av_buffer_ref()\n"); + buf = av_buffer_alloc(32); + if (buf) { + buf->data[0] = 0xAB; + buf2 = av_buffer_ref(buf); + if (buf2) { + printf("ref: refcount=%d\n", av_buffer_get_ref_count(buf)); + printf("shared data: %s\n", + buf2->data[0] == 0xAB ? "yes" : "no"); + printf("writable after ref: %d\n", av_buffer_is_writable(buf)); + av_buffer_unref(&buf2); + printf("refcount after unref: %d\n", av_buffer_get_ref_count(buf)); + printf("writable after unref: %d\n", av_buffer_is_writable(buf)); + } + av_buffer_unref(&buf); + } + + /* av_buffer_make_writable */ + printf("\nTesting av_buffer_make_writable()\n"); + buf = av_buffer_alloc(16); + if (buf) { + buf->data[0] = 0xCD; + buf2 = av_buffer_ref(buf); + if (buf2) { + int ret = av_buffer_make_writable(&buf2); + printf("make_writable ret: %d\n", ret >= 0); + printf("data preserved: %s\n", + buf2->data[0] == 0xCD ? "yes" : "no"); + printf("now writable: %d\n", av_buffer_is_writable(buf2)); + printf("original still valid: %s\n", + buf->data[0] == 0xCD ? "yes" : "no"); + av_buffer_unref(&buf2); + } + av_buffer_unref(&buf); + } + + /* av_buffer_realloc */ + printf("\nTesting av_buffer_realloc()\n"); + buf = av_buffer_alloc(16); + if (buf) { + memset(buf->data, 0xEF, 16); + av_buffer_realloc(&buf, 32); + if (buf) { + printf("realloc: size=%zu\n", buf->size); + printf("data preserved: %s\n", + buf->data[0] == 0xEF ? "yes" : "no"); + } + av_buffer_unref(&buf); + } + /* realloc from NULL */ + buf = NULL; + av_buffer_realloc(&buf, 8); + printf("realloc from null: %s\n", buf ? "OK" : "FAIL"); + av_buffer_unref(&buf); + + /* av_buffer_replace */ + printf("\nTesting av_buffer_replace()\n"); + buf = av_buffer_alloc(8); + buf2 = av_buffer_alloc(8); + if (buf && buf2) { + buf->data[0] = 0x11; + buf2->data[0] = 0x22; + av_buffer_replace(&buf, buf2); + printf("replace: data=0x%02x\n", buf->data[0]); + printf("refcount: %d\n", av_buffer_get_ref_count(buf2)); + } + av_buffer_unref(&buf); + av_buffer_unref(&buf2); + + /* replace with NULL */ + buf = av_buffer_alloc(8); + if (buf) { + av_buffer_replace(&buf, NULL); + printf("replace with null: %s\n", buf == NULL ? "OK" : "FAIL"); + } + + /* av_buffer_pool */ + printf("\nTesting av_buffer_pool()\n"); + pool = av_buffer_pool_init(64, NULL); + if (pool) { + buf = av_buffer_pool_get(pool); + if (buf) { + printf("pool get: size=%zu\n", buf->size); + av_buffer_unref(&buf); + } + /* get again -- should reuse the released buffer */ + buf = av_buffer_pool_get(pool); + if (buf) { + printf("pool reuse: size=%zu\n", buf->size); + av_buffer_unref(&buf); + } + av_buffer_pool_uninit(&pool); + printf("pool uninit: %s\n", pool == NULL ? "OK" : "FAIL"); + } + + /* av_buffer_pool_init2 with custom alloc and pool_free callbacks */ + printf("\nTesting av_buffer_pool_init2()\n"); + pool_alloc2_called = 0; + pool_free_called = 0; + pool = av_buffer_pool_init2(64, NULL, pool_alloc2, pool_free_cb); + if (pool) { + buf = av_buffer_pool_get(pool); + if (buf) { + printf("pool2 get: size=%zu\n", buf->size); + printf("alloc2 called: %s\n", pool_alloc2_called ? "yes" : "no"); + printf("pool_buffer_get_opaque: %s\n", + av_buffer_pool_buffer_get_opaque(buf) == NULL ? "null" : "set"); + av_buffer_unref(&buf); + } + av_buffer_pool_uninit(&pool); + printf("pool_free called: %s\n", pool_free_called ? "yes" : "no"); + } + + /* OOM paths via av_max_alloc */ + printf("\nTesting OOM paths\n"); + av_max_alloc(1); + buf = av_buffer_alloc(64); + printf("alloc OOM: %s\n", buf ? "FAIL" : "OK"); + av_buffer_unref(&buf); + buf = av_buffer_allocz(64); + printf("allocz OOM: %s\n", buf ? "FAIL" : "OK"); + av_buffer_unref(&buf); + pool = av_buffer_pool_init(64, NULL); + printf("pool init OOM: %s\n", pool ? "FAIL" : "OK"); + av_buffer_pool_uninit(&pool); + av_max_alloc(INT_MAX); + + buf = av_buffer_alloc(16); + if (buf) { + av_max_alloc(1); + buf2 = av_buffer_ref(buf); + printf("ref OOM: %s\n", buf2 ? "FAIL" : "OK"); + av_buffer_unref(&buf2); + printf("realloc OOM: %s\n", + av_buffer_realloc(&buf, 1024) < 0 ? "OK" : "FAIL"); + av_max_alloc(INT_MAX); + av_buffer_unref(&buf); + } + + return 0; +} diff --git a/tests/fate/libavutil.mak b/tests/fate/libavutil.mak index 12143bc248..af78a803e5 100644 --- a/tests/fate/libavutil.mak +++ b/tests/fate/libavutil.mak @@ -47,6 +47,10 @@ FATE_LIBAVUTIL += fate-bprint fate-bprint: libavutil/tests/bprint$(EXESUF) fate-bprint: CMD = run libavutil/tests/bprint$(EXESUF) +FATE_LIBAVUTIL += fate-buffer +fate-buffer: libavutil/tests/buffer$(EXESUF) +fate-buffer: CMD = run libavutil/tests/buffer$(EXESUF) + FATE_LIBAVUTIL += fate-cpu fate-cpu: libavutil/tests/cpu$(EXESUF) fate-cpu: CMD = runecho libavutil/tests/cpu$(EXESUF) $(CPUFLAGS:%=-c%) $(THREADS:%=-t%) diff --git a/tests/ref/fate/buffer b/tests/ref/fate/buffer new file mode 100644 index 0000000000..5c2946babf --- /dev/null +++ b/tests/ref/fate/buffer @@ -0,0 +1,57 @@ +Testing av_buffer_alloc() +alloc: size=64 data=set +writable: 1 +refcount: 1 +after unref: null + +Testing av_buffer_allocz() +allocz: zeroed=yes + +Testing av_buffer_create() +create: size=32 +opaque: null +custom_free called: yes + +Testing AV_BUFFER_FLAG_READONLY +readonly writable: 0 + +Testing av_buffer_ref() +ref: refcount=2 +shared data: yes +writable after ref: 0 +refcount after unref: 1 +writable after unref: 1 + +Testing av_buffer_make_writable() +make_writable ret: 1 +data preserved: yes +now writable: 1 +original still valid: yes + +Testing av_buffer_realloc() +realloc: size=32 +data preserved: yes +realloc from null: OK + +Testing av_buffer_replace() +replace: data=0x22 +refcount: 2 +replace with null: OK + +Testing av_buffer_pool() +pool get: size=64 +pool reuse: size=64 +pool uninit: OK + +Testing av_buffer_pool_init2() +pool2 get: size=64 +alloc2 called: yes +pool_buffer_get_opaque: null +pool_free called: yes + +Testing OOM paths +alloc OOM: OK +allocz OOM: OK +pool init OOM: OK +ref OOM: OK +realloc OOM: OK _______________________________________________ ffmpeg-cvslog mailing list -- [email protected] To unsubscribe send an email to [email protected]
