FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavutil/tests/buffer.c
Date: 2026-08-15 14:54:27
Exec Total Coverage
Lines: 154 156 98.7%
Functions: 4 4 100.0%
Branches: 44 86 51.2%

Line Branch Exec Source
1 /*
2 * This file is part of FFmpeg.
3 *
4 * FFmpeg is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * FFmpeg is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with FFmpeg; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18
19 #include <limits.h>
20 #include <stdio.h>
21 #include <string.h>
22
23 #include "libavutil/buffer.h"
24 #include "libavutil/mem.h"
25
26 static int custom_free_called;
27 static int pool_free_called;
28 static int pool_alloc2_called;
29
30 2 static void custom_free(void *opaque, uint8_t *data)
31 {
32 2 custom_free_called = 1;
33 2 av_free(data);
34 2 }
35
36 1 static AVBufferRef *pool_alloc2(void *opaque, size_t size)
37 {
38 1 pool_alloc2_called = 1;
39 1 return av_buffer_alloc(size);
40 }
41
42 1 static void pool_free_cb(void *opaque)
43 {
44 1 pool_free_called = 1;
45 1 }
46
47 1 int main(void)
48 {
49 AVBufferRef *buf, *buf2;
50 AVBufferPool *pool;
51
52 /* av_buffer_alloc */
53 1 printf("Testing av_buffer_alloc()\n");
54 1 buf = av_buffer_alloc(64);
55
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (buf) {
56
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 printf("alloc: size=%zu data=%s\n", buf->size, buf->data ? "set" : "null");
57 1 printf("writable: %d\n", av_buffer_is_writable(buf));
58 1 printf("refcount: %d\n", av_buffer_get_ref_count(buf));
59 1 av_buffer_unref(&buf);
60
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 printf("after unref: %s\n", buf == NULL ? "null" : "leaked");
61 }
62
63 /* av_buffer_allocz */
64 1 printf("\nTesting av_buffer_allocz()\n");
65 1 buf = av_buffer_allocz(16);
66
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (buf) {
67 1 int zeroed = 1;
68
2/2
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 1 times.
17 for (int i = 0; i < 16; i++)
69
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
16 if (buf->data[i] != 0) zeroed = 0;
70
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 printf("allocz: zeroed=%s\n", zeroed ? "yes" : "no");
71 1 av_buffer_unref(&buf);
72 }
73
74 /* av_buffer_create with custom free */
75 1 printf("\nTesting av_buffer_create()\n");
76 {
77 1 uint8_t *data = av_malloc(32);
78
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (data) {
79 1 custom_free_called = 0;
80 1 buf = av_buffer_create(data, 32, custom_free, NULL, 0);
81
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (buf) {
82 1 printf("create: size=%zu\n", buf->size);
83
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 printf("opaque: %s\n",
84 1 av_buffer_get_opaque(buf) == NULL ? "null" : "set");
85 1 av_buffer_unref(&buf);
86 1 printf("custom_free called: %s\n",
87
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 custom_free_called ? "yes" : "no");
88 } else {
89 av_free(data);
90 }
91 }
92 }
93
94 /* av_buffer_create with READONLY flag */
95 1 printf("\nTesting AV_BUFFER_FLAG_READONLY\n");
96 {
97 1 uint8_t *data = av_malloc(16);
98
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (data) {
99 1 buf = av_buffer_create(data, 16, custom_free, NULL,
100 AV_BUFFER_FLAG_READONLY);
101
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (buf) {
102 1 printf("readonly writable: %d\n", av_buffer_is_writable(buf));
103 1 av_buffer_unref(&buf);
104 } else {
105 av_free(data);
106 }
107 }
108 }
109
110 /* av_buffer_ref and refcounting */
111 1 printf("\nTesting av_buffer_ref()\n");
112 1 buf = av_buffer_alloc(32);
113
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (buf) {
114 1 buf->data[0] = 0xAB;
115 1 buf2 = av_buffer_ref(buf);
116
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (buf2) {
117 1 printf("ref: refcount=%d\n", av_buffer_get_ref_count(buf));
118 1 printf("shared data: %s\n",
119
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 buf2->data[0] == 0xAB ? "yes" : "no");
120 1 printf("writable after ref: %d\n", av_buffer_is_writable(buf));
121 1 av_buffer_unref(&buf2);
122 1 printf("refcount after unref: %d\n", av_buffer_get_ref_count(buf));
123 1 printf("writable after unref: %d\n", av_buffer_is_writable(buf));
124 }
125 1 av_buffer_unref(&buf);
126 }
127
128 /* av_buffer_make_writable */
129 1 printf("\nTesting av_buffer_make_writable()\n");
130 1 buf = av_buffer_alloc(16);
131
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (buf) {
132 1 buf->data[0] = 0xCD;
133 1 buf2 = av_buffer_ref(buf);
134
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (buf2) {
135 1 int ret = av_buffer_make_writable(&buf2);
136 1 printf("make_writable ret: %d\n", ret >= 0);
137 1 printf("data preserved: %s\n",
138
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 buf2->data[0] == 0xCD ? "yes" : "no");
139 1 printf("now writable: %d\n", av_buffer_is_writable(buf2));
140 1 printf("original still valid: %s\n",
141
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 buf->data[0] == 0xCD ? "yes" : "no");
142 1 av_buffer_unref(&buf2);
143 }
144 1 av_buffer_unref(&buf);
145 }
146
147 /* av_buffer_realloc */
148 1 printf("\nTesting av_buffer_realloc()\n");
149 1 buf = av_buffer_alloc(16);
150
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (buf) {
151 1 memset(buf->data, 0xEF, 16);
152 1 av_buffer_realloc(&buf, 32);
153
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (buf) {
154 1 printf("realloc: size=%zu\n", buf->size);
155 1 printf("data preserved: %s\n",
156
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 buf->data[0] == 0xEF ? "yes" : "no");
157 }
158 1 av_buffer_unref(&buf);
159 }
160 /* realloc from NULL */
161 1 buf = NULL;
162 1 av_buffer_realloc(&buf, 8);
163
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 printf("realloc from null: %s\n", buf ? "OK" : "FAIL");
164 1 av_buffer_unref(&buf);
165
166 /* av_buffer_replace */
167 1 printf("\nTesting av_buffer_replace()\n");
168 1 buf = av_buffer_alloc(8);
169 1 buf2 = av_buffer_alloc(8);
170
2/4
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 if (buf && buf2) {
171 1 buf->data[0] = 0x11;
172 1 buf2->data[0] = 0x22;
173 1 av_buffer_replace(&buf, buf2);
174 1 printf("replace: data=0x%02x\n", buf->data[0]);
175 1 printf("refcount: %d\n", av_buffer_get_ref_count(buf2));
176 }
177 1 av_buffer_unref(&buf);
178 1 av_buffer_unref(&buf2);
179
180 /* replace with NULL */
181 1 buf = av_buffer_alloc(8);
182
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (buf) {
183 1 av_buffer_replace(&buf, NULL);
184
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 printf("replace with null: %s\n", buf == NULL ? "OK" : "FAIL");
185 }
186
187 /* av_buffer_pool */
188 1 printf("\nTesting av_buffer_pool()\n");
189 1 pool = av_buffer_pool_init(64, NULL);
190
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (pool) {
191 1 buf = av_buffer_pool_get(pool);
192
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (buf) {
193 1 printf("pool get: size=%zu\n", buf->size);
194 1 av_buffer_unref(&buf);
195 }
196 /* get again -- should reuse the released buffer */
197 1 buf = av_buffer_pool_get(pool);
198
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (buf) {
199 1 printf("pool reuse: size=%zu\n", buf->size);
200 1 av_buffer_unref(&buf);
201 }
202 1 av_buffer_pool_uninit(&pool);
203
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 printf("pool uninit: %s\n", pool == NULL ? "OK" : "FAIL");
204 }
205
206 /* av_buffer_pool_init2 with custom alloc and pool_free callbacks */
207 1 printf("\nTesting av_buffer_pool_init2()\n");
208 1 pool_alloc2_called = 0;
209 1 pool_free_called = 0;
210 1 pool = av_buffer_pool_init2(64, NULL, pool_alloc2, pool_free_cb);
211
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (pool) {
212 1 buf = av_buffer_pool_get(pool);
213
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (buf) {
214 1 printf("pool2 get: size=%zu\n", buf->size);
215
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 printf("alloc2 called: %s\n", pool_alloc2_called ? "yes" : "no");
216
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 printf("pool_buffer_get_opaque: %s\n",
217 1 av_buffer_pool_buffer_get_opaque(buf) == NULL ? "null" : "set");
218 1 av_buffer_unref(&buf);
219 }
220 1 av_buffer_pool_uninit(&pool);
221
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 printf("pool_free called: %s\n", pool_free_called ? "yes" : "no");
222 }
223
224 /* OOM paths via av_max_alloc */
225 1 printf("\nTesting OOM paths\n");
226 1 av_max_alloc(1);
227 1 buf = av_buffer_alloc(64);
228
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 printf("alloc OOM: %s\n", buf ? "FAIL" : "OK");
229 1 av_buffer_unref(&buf);
230 1 buf = av_buffer_allocz(64);
231
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 printf("allocz OOM: %s\n", buf ? "FAIL" : "OK");
232 1 av_buffer_unref(&buf);
233 1 pool = av_buffer_pool_init(64, NULL);
234
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 printf("pool init OOM: %s\n", pool ? "FAIL" : "OK");
235 1 av_buffer_pool_uninit(&pool);
236 1 av_max_alloc(INT_MAX);
237
238 1 buf = av_buffer_alloc(16);
239
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (buf) {
240 1 av_max_alloc(1);
241 1 buf2 = av_buffer_ref(buf);
242
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 printf("ref OOM: %s\n", buf2 ? "FAIL" : "OK");
243 1 av_buffer_unref(&buf2);
244
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 printf("realloc OOM: %s\n",
245 1 av_buffer_realloc(&buf, 1024) < 0 ? "OK" : "FAIL");
246 1 av_max_alloc(INT_MAX);
247 1 av_buffer_unref(&buf);
248 }
249
250 1 return 0;
251 }
252