FFmpeg
Loading...
Searching...
No Matches
buffer.c
Go to the documentation of this file.
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
29
30static void custom_free(void *opaque, uint8_t *data)
31{
34}
35
36static AVBufferRef *pool_alloc2(void *opaque, size_t size)
37{
39 return av_buffer_alloc(size);
40}
41
42static void pool_free_cb(void *opaque)
43{
45}
46
47int main(void)
48{
49 AVBufferRef *buf, *buf2;
50 AVBufferPool *pool;
51
52 /* av_buffer_alloc */
53 printf("Testing av_buffer_alloc()\n");
54 buf = av_buffer_alloc(64);
55 if (buf) {
56 printf("alloc: size=%zu data=%s\n", buf->size, buf->data ? "set" : "null");
57 printf("writable: %d\n", av_buffer_is_writable(buf));
58 printf("refcount: %d\n", av_buffer_get_ref_count(buf));
59 av_buffer_unref(&buf);
60 printf("after unref: %s\n", buf == NULL ? "null" : "leaked");
61 }
62
63 /* av_buffer_allocz */
64 printf("\nTesting av_buffer_allocz()\n");
65 buf = av_buffer_allocz(16);
66 if (buf) {
67 int zeroed = 1;
68 for (int i = 0; i < 16; i++)
69 if (buf->data[i] != 0) zeroed = 0;
70 printf("allocz: zeroed=%s\n", zeroed ? "yes" : "no");
71 av_buffer_unref(&buf);
72 }
73
74 /* av_buffer_create with custom free */
75 printf("\nTesting av_buffer_create()\n");
76 {
77 uint8_t *data = av_malloc(32);
78 if (data) {
80 buf = av_buffer_create(data, 32, custom_free, NULL, 0);
81 if (buf) {
82 printf("create: size=%zu\n", buf->size);
83 printf("opaque: %s\n",
84 av_buffer_get_opaque(buf) == NULL ? "null" : "set");
85 av_buffer_unref(&buf);
86 printf("custom_free called: %s\n",
87 custom_free_called ? "yes" : "no");
88 } else {
90 }
91 }
92 }
93
94 /* av_buffer_create with READONLY flag */
95 printf("\nTesting AV_BUFFER_FLAG_READONLY\n");
96 {
97 uint8_t *data = av_malloc(16);
98 if (data) {
101 if (buf) {
102 printf("readonly writable: %d\n", av_buffer_is_writable(buf));
103 av_buffer_unref(&buf);
104 } else {
105 av_free(data);
106 }
107 }
108 }
109
110 /* av_buffer_ref and refcounting */
111 printf("\nTesting av_buffer_ref()\n");
112 buf = av_buffer_alloc(32);
113 if (buf) {
114 buf->data[0] = 0xAB;
115 buf2 = av_buffer_ref(buf);
116 if (buf2) {
117 printf("ref: refcount=%d\n", av_buffer_get_ref_count(buf));
118 printf("shared data: %s\n",
119 buf2->data[0] == 0xAB ? "yes" : "no");
120 printf("writable after ref: %d\n", av_buffer_is_writable(buf));
121 av_buffer_unref(&buf2);
122 printf("refcount after unref: %d\n", av_buffer_get_ref_count(buf));
123 printf("writable after unref: %d\n", av_buffer_is_writable(buf));
124 }
125 av_buffer_unref(&buf);
126 }
127
128 /* av_buffer_make_writable */
129 printf("\nTesting av_buffer_make_writable()\n");
130 buf = av_buffer_alloc(16);
131 if (buf) {
132 buf->data[0] = 0xCD;
133 buf2 = av_buffer_ref(buf);
134 if (buf2) {
135 int ret = av_buffer_make_writable(&buf2);
136 printf("make_writable ret: %d\n", ret >= 0);
137 printf("data preserved: %s\n",
138 buf2->data[0] == 0xCD ? "yes" : "no");
139 printf("now writable: %d\n", av_buffer_is_writable(buf2));
140 printf("original still valid: %s\n",
141 buf->data[0] == 0xCD ? "yes" : "no");
142 av_buffer_unref(&buf2);
143 }
144 av_buffer_unref(&buf);
145 }
146
147 /* av_buffer_realloc */
148 printf("\nTesting av_buffer_realloc()\n");
149 buf = av_buffer_alloc(16);
150 if (buf) {
151 memset(buf->data, 0xEF, 16);
152 av_buffer_realloc(&buf, 32);
153 if (buf) {
154 printf("realloc: size=%zu\n", buf->size);
155 printf("data preserved: %s\n",
156 buf->data[0] == 0xEF ? "yes" : "no");
157 }
158 av_buffer_unref(&buf);
159 }
160 /* realloc from NULL */
161 buf = NULL;
162 av_buffer_realloc(&buf, 8);
163 printf("realloc from null: %s\n", buf ? "OK" : "FAIL");
164 av_buffer_unref(&buf);
165
166 /* av_buffer_replace */
167 printf("\nTesting av_buffer_replace()\n");
168 buf = av_buffer_alloc(8);
169 buf2 = av_buffer_alloc(8);
170 if (buf && buf2) {
171 buf->data[0] = 0x11;
172 buf2->data[0] = 0x22;
173 av_buffer_replace(&buf, buf2);
174 printf("replace: data=0x%02x\n", buf->data[0]);
175 printf("refcount: %d\n", av_buffer_get_ref_count(buf2));
176 }
177 av_buffer_unref(&buf);
178 av_buffer_unref(&buf2);
179
180 /* replace with NULL */
181 buf = av_buffer_alloc(8);
182 if (buf) {
183 av_buffer_replace(&buf, NULL);
184 printf("replace with null: %s\n", buf == NULL ? "OK" : "FAIL");
185 }
186
187 /* av_buffer_pool */
188 printf("\nTesting av_buffer_pool()\n");
189 pool = av_buffer_pool_init(64, NULL);
190 if (pool) {
191 buf = av_buffer_pool_get(pool);
192 if (buf) {
193 printf("pool get: size=%zu\n", buf->size);
194 av_buffer_unref(&buf);
195 }
196 /* get again -- should reuse the released buffer */
197 buf = av_buffer_pool_get(pool);
198 if (buf) {
199 printf("pool reuse: size=%zu\n", buf->size);
200 av_buffer_unref(&buf);
201 }
203 printf("pool uninit: %s\n", pool == NULL ? "OK" : "FAIL");
204 }
205
206 /* av_buffer_pool_init2 with custom alloc and pool_free callbacks */
207 printf("\nTesting av_buffer_pool_init2()\n");
211 if (pool) {
212 buf = av_buffer_pool_get(pool);
213 if (buf) {
214 printf("pool2 get: size=%zu\n", buf->size);
215 printf("alloc2 called: %s\n", pool_alloc2_called ? "yes" : "no");
216 printf("pool_buffer_get_opaque: %s\n",
217 av_buffer_pool_buffer_get_opaque(buf) == NULL ? "null" : "set");
218 av_buffer_unref(&buf);
219 }
221 printf("pool_free called: %s\n", pool_free_called ? "yes" : "no");
222 }
223
224 /* OOM paths via av_max_alloc */
225 printf("\nTesting OOM paths\n");
226 av_max_alloc(1);
227 buf = av_buffer_alloc(64);
228 printf("alloc OOM: %s\n", buf ? "FAIL" : "OK");
229 av_buffer_unref(&buf);
230 buf = av_buffer_allocz(64);
231 printf("allocz OOM: %s\n", buf ? "FAIL" : "OK");
232 av_buffer_unref(&buf);
233 pool = av_buffer_pool_init(64, NULL);
234 printf("pool init OOM: %s\n", pool ? "FAIL" : "OK");
236 av_max_alloc(INT_MAX);
237
238 buf = av_buffer_alloc(16);
239 if (buf) {
240 av_max_alloc(1);
241 buf2 = av_buffer_ref(buf);
242 printf("ref OOM: %s\n", buf2 ? "FAIL" : "OK");
243 av_buffer_unref(&buf2);
244 printf("realloc OOM: %s\n",
245 av_buffer_realloc(&buf, 1024) < 0 ? "OK" : "FAIL");
246 av_max_alloc(INT_MAX);
247 av_buffer_unref(&buf);
248 }
249
250 return 0;
251}
refcounted data buffer API
#define i(width, name, range_min, range_max)
Definition cbs_h264.c:63
#define NULL
Definition coverity.c:32
__device__ int printf(const char *,...)
int av_buffer_is_writable(const AVBufferRef *buf)
Definition buffer.c:147
void av_buffer_unref(AVBufferRef **buf)
Free a given reference and automatically free the buffer if there are no more references to it.
Definition buffer.c:139
int av_buffer_realloc(AVBufferRef **pbuf, size_t size)
Reallocate a given buffer.
Definition buffer.c:183
AVBufferRef * av_buffer_allocz(size_t size)
Same as av_buffer_alloc(), except the returned buffer will be initialized to zero.
Definition buffer.c:93
int av_buffer_get_ref_count(const AVBufferRef *buf)
Definition buffer.c:160
int av_buffer_replace(AVBufferRef **pdst, const AVBufferRef *src)
Ensure dst refers to the same data as src.
Definition buffer.c:233
AVBufferRef * av_buffer_ref(const AVBufferRef *buf)
Create a new reference to an AVBuffer.
Definition buffer.c:103
int av_buffer_make_writable(AVBufferRef **pbuf)
Create a writable reference from a given buffer reference, avoiding data copy if possible.
Definition buffer.c:165
void * av_buffer_get_opaque(const AVBufferRef *buf)
Definition buffer.c:155
#define AV_BUFFER_FLAG_READONLY
Always treat the buffer as read-only, even when it has only one reference.
Definition buffer.h:114
AVBufferRef * av_buffer_alloc(size_t size)
Allocate an AVBuffer of the given size using av_malloc().
Definition buffer.c:77
AVBufferRef * av_buffer_create(uint8_t *data, size_t size, void(*free)(void *opaque, uint8_t *data), void *opaque, int flags)
Create an AVBuffer from an existing array.
Definition buffer.c:55
void * av_buffer_pool_buffer_get_opaque(const AVBufferRef *ref)
Query the original opaque parameter of an allocated buffer in the pool.
Definition buffer.c:417
void av_buffer_pool_uninit(AVBufferPool **ppool)
Mark the pool as being available for freeing.
Definition buffer.c:328
AVBufferPool * av_buffer_pool_init(size_t size, AVBufferRef *(*alloc)(size_t size))
Allocate and initialize a buffer pool.
Definition buffer.c:283
AVBufferRef * av_buffer_pool_get(AVBufferPool *pool)
Allocate a new AVBuffer, reusing an old buffer from the pool when available.
Definition buffer.c:390
AVBufferPool * av_buffer_pool_init2(size_t size, void *opaque, AVBufferRef *(*alloc)(void *opaque, size_t size), void(*pool_free)(void *opaque))
Allocate and initialize a buffer pool with a more complex allocator.
Definition buffer.c:259
void av_max_alloc(size_t max)
Set the maximum size that may be allocated in one block.
Definition mem.c:76
Memory handling functions.
const char data[16]
Definition mxf.c:149
#define av_malloc(s)
Definition ops_static.c:52
The buffer pool.
A reference to a data buffer.
Definition buffer.h:82
uint8_t * data
The data buffer.
Definition buffer.h:90
size_t size
Size of data in bytes.
Definition buffer.h:94
#define av_free(p)
static int pool_alloc2_called
Definition buffer.c:28
static AVBufferRef * pool_alloc2(void *opaque, size_t size)
Definition buffer.c:36
static void pool_free_cb(void *opaque)
Definition buffer.c:42
int main(void)
Definition buffer.c:47
static int pool_free_called
Definition buffer.c:27
static void custom_free(void *opaque, uint8_t *data)
Definition buffer.c:30
static int custom_free_called
Definition buffer.c:26
int size