FFmpeg: libavutil/fifo.c Source File
Go to the documentation of this file. 1 /*
2 * a very simple circular buffer FIFO implementation
3 * Copyright (c) 2000, 2001, 2002 Fabrice Bellard
4 * Copyright (c) 2006 Roman Shaposhnik
5 *
6 * This file is part of FFmpeg.
7 *
8 * FFmpeg is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
12 *
13 * FFmpeg is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with FFmpeg; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 */
22
23 #include <stdint.h>
24 #include <string.h>
25
31
32 // by default the FIFO can be auto-grown to 1MB
33 #define AUTO_GROW_DEFAULT_BYTES (1024 * 1024)
34
37
40 // distinguishes the ambiguous situation offset_r == offset_w
42
45 };
46
49 {
52
53 if (!elem_size)
55
56 if (nb_elems) {
60 }
65 }
67 f->nb_elems = nb_elems;
68 f->elem_size = elem_size;
70
73
75 }
76
78 {
79 f->auto_grow_limit = max_elems;
80 }
81
83 {
85 }
86
88 {
89 if (
f->offset_w <=
f->offset_r && !
f->is_empty)
90 return f->nb_elems -
f->offset_r +
f->offset_w;
91 return f->offset_w -
f->offset_r;
92 }
93
95 {
97 }
98
100 {
102
103 if (inc > SIZE_MAX -
f->nb_elems)
105
110
111 // move the data from the beginning of the ring buffer
112 // to the newly allocated space
113 if (
f->offset_w <=
f->offset_r && !
f->is_empty) {
115 memcpy(
tmp +
f->nb_elems *
f->elem_size,
tmp,
copy *
f->elem_size);
116 if (copy < f->offset_w) {
118 (
f->offset_w -
copy) *
f->elem_size);
120 } else
121 f->offset_w =
copy == inc ? 0 :
f->nb_elems +
copy;
122 }
123
125
126 return 0;
127 }
128
130 {
132 const size_t need_grow = to_write > can_write ? to_write - can_write : 0;
133 size_t can_grow;
134
135 if (!need_grow)
136 return 0;
137
138 can_grow =
f->auto_grow_limit >
f->nb_elems ?
139 f->auto_grow_limit -
f->nb_elems : 0;
141 // allocate a bit more than necessary, if we can
142 const size_t inc = (need_grow < can_grow / 2 ) ? need_grow * 2 : can_grow;
144 }
145
147 }
148
151 {
152 size_t to_write = *nb_elems;
153 size_t offset_w;
155
159
160 offset_w =
f->offset_w;
161
162 while (to_write > 0) {
163 size_t len =
FFMIN(
f->nb_elems - offset_w, to_write);
164 uint8_t *wptr =
f->buffer + offset_w *
f->elem_size;
165
169 break;
170 } else {
171 memcpy(wptr, buf,
len *
f->elem_size);
172 buf +=
len *
f->elem_size;
173 }
175 if (offset_w >=
f->nb_elems)
176 offset_w = 0;
178 }
179 f->offset_w = offset_w;
180
181 if (*nb_elems != to_write)
183 *nb_elems -= to_write;
184
186 }
187
189 {
191 }
192
194 void *opaque, size_t *nb_elems)
195 {
197 }
198
201 {
202 size_t to_read = *nb_elems;
203 size_t offset_r =
f->offset_r;
206
208 *nb_elems = 0;
210 }
211
212 if (offset_r >=
f->nb_elems -
offset)
213 offset_r -=
f->nb_elems -
offset;
214 else
216
217 while (to_read > 0) {
218 size_t len =
FFMIN(
f->nb_elems - offset_r, to_read);
219 uint8_t *rptr =
f->buffer + offset_r *
f->elem_size;
220
224 break;
225 } else {
226 memcpy(buf, rptr,
len *
f->elem_size);
227 buf +=
len *
f->elem_size;
228 }
230 if (offset_r >=
f->nb_elems)
231 offset_r = 0;
233 }
234
235 *nb_elems -= to_read;
236
238 }
239
241 {
245 }
246
248 void *opaque, size_t *nb_elems)
249 {
253 }
254
256 {
258 }
259
261 size_t *nb_elems,
size_t offset)
262 {
264 }
265
267 {
269
271 if (cur_size ==
size)
273
274 if (
f->offset_r >=
f->nb_elems -
size)
275 f->offset_r -=
f->nb_elems -
size;
276 else
278 }
279
281 {
282 f->offset_r =
f->offset_w = 0;
284 }
285
287 {
291 }
292 }
293
294
295 #if FF_API_FIFO_OLD_API
297 #define OLD_FIFO_SIZE_MAX (size_t)FFMIN3(INT_MAX, UINT32_MAX, SIZE_MAX)
298
300 {
303
306
314 }
316 f->end =
f->buffer + nmemb *
size;
319 }
320
322 {
324 }
325
327 {
331 }
332 }
333
335 {
339 }
340 }
341
343 {
344 f->wptr =
f->rptr =
f->buffer;
345 f->wndx =
f->rndx = 0;
346 }
347
349 {
350 return (uint32_t)(
f->wndx -
f->rndx);
351 }
352
354 {
356 }
357
359 {
360 unsigned int old_size =
f->end -
f->buffer;
361
364
365 if (old_size < new_size) {
366 size_t offset_r =
f->rptr -
f->buffer;
367 size_t offset_w =
f->wptr -
f->buffer;
369
373
374 // move the data from the beginning of the ring buffer
375 // to the newly allocated space
376 // the second condition distinguishes full vs empty fifo
378 const size_t copy =
FFMIN(new_size - old_size, offset_w);
380 if (
copy < offset_w) {
383 } else
384 offset_w = old_size +
copy;
385 }
386
388 f->end =
f->buffer + new_size;
389 f->rptr =
f->buffer + offset_r;
390 f->wptr =
f->buffer + offset_w;
391 }
392 return 0;
393 }
394
396 {
397 unsigned int old_size =
f->end -
f->buffer;
400
402
405 return 0;
406 }
407
408 /* src must NOT be const as it can be a context for func that may need
409 * updating (like a pointer or byte counter) */
411 int (*
func)(
void *,
void *,
int))
412 {
414 uint32_t wndx=
f->wndx;
415 uint8_t *wptr=
f->wptr;
416
419
420 do {
425 break;
426 } else {
429 }
439 }
440
442 {
443 uint8_t *rptr =
f->rptr;
444
447
449 rptr +=
offset - (
f->end -
f->buffer);
450 else
452
453 while (buf_size > 0) {
455
457 rptr -=
f->end -
f->buffer;
458
462 else {
463 memcpy(dest, rptr,
len);
464 dest = (uint8_t *)dest +
len;
465 }
466
469 }
470
471 return 0;
472 }
473
475 void (*
func)(
void *,
void *,
int))
476 {
478 }
479
481 void (*
func)(
void *,
void *,
int))
482 {
485
486 do {
490 else {
491 memcpy(dest,
f->rptr,
len);
492 dest = (uint8_t *)dest +
len;
493 }
496 } while (buf_size > 0);
497 return 0;
498 }
499
500 /** Discard data from the FIFO. */
502 {
505 if (
f->rptr >=
f->end)
506 f->rptr -=
f->end -
f->buffer;
508 }
510 #endif
AVFifoBuffer * av_fifo_alloc_array(size_t nmemb, size_t size)
Initialize an AVFifoBuffer.
int(* func)(AVBPrint *dst, const char *in, const char *arg)
void av_fifo_drain2(AVFifo *f, size_t size)
Discard the specified amount of data from an AVFifo.
#define FF_ENABLE_DEPRECATION_WARNINGS
size_t av_fifo_can_write(const AVFifo *f)
Filter the word "frame" indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
void av_fifo_freep(AVFifoBuffer **f)
Free an AVFifoBuffer and reset pointer to NULL.
void av_fifo_free(AVFifoBuffer *f)
Free an AVFifoBuffer.
#define OLD_FIFO_SIZE_MAX
void av_fifo_auto_grow_limit(AVFifo *f, size_t max_elems)
Set the maximum size (in elements) to which the FIFO can be resized automatically.
void av_fifo_drain(AVFifoBuffer *f, int size)
Discard data from the FIFO.
int av_fifo_write(AVFifo *f, const void *buf, size_t nb_elems)
Write data into a FIFO.
int av_fifo_grow2(AVFifo *f, size_t inc)
Enlarge an AVFifo.
int av_fifo_peek_to_cb(AVFifo *f, AVFifoCB write_cb, void *opaque, size_t *nb_elems, size_t offset)
Feed data from a FIFO into a user-provided callback.
int AVFifoCB(void *opaque, void *buf, size_t *nb_elems)
Callback for writing or reading from a FIFO, passed to (and invoked from) the av_fifo_*_cb() function...
int av_fifo_realloc2(AVFifoBuffer *f, unsigned int new_size)
Resize an AVFifoBuffer.
int av_fifo_read(AVFifo *f, void *buf, size_t nb_elems)
Read data from a FIFO.
int av_fifo_generic_write(AVFifoBuffer *f, void *src, int size, int(*func)(void *, void *, int))
Feed data from a user-supplied callback to an AVFifoBuffer.
void * av_realloc_array(void *ptr, size_t nmemb, size_t size)
#define av_assert0(cond)
assert() equivalent, that is always enabled.
int av_fifo_generic_peek(AVFifoBuffer *f, void *dest, int buf_size, void(*func)(void *, void *, int))
Feed data from an AVFifoBuffer to a user-supplied callback.
int av_fifo_grow(AVFifoBuffer *f, unsigned int size)
Enlarge an AVFifoBuffer.
int av_fifo_write_from_cb(AVFifo *f, AVFifoCB read_cb, void *opaque, size_t *nb_elems)
Write data from a user-provided callback into a FIFO.
size_t av_fifo_can_read(const AVFifo *f)
size_t av_fifo_elem_size(const AVFifo *f)
void av_fifo_reset2(AVFifo *f)
int av_fifo_read_to_cb(AVFifo *f, AVFifoCB write_cb, void *opaque, size_t *nb_elems)
Feed data from a FIFO into a user-provided callback.
static void copy(const float *p1, float *p2, const int length)
static int read_cb(void *opaque, void *buf, size_t *nb_elems)
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf offset
#define AUTO_GROW_DEFAULT_BYTES
int av_fifo_peek(AVFifo *f, void *buf, size_t nb_elems, size_t offset)
Read data from a FIFO without modifying FIFO state.
#define av_assert2(cond)
assert() equivalent, that does lie in speed critical code.
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
static int fifo_write_common(AVFifo *f, const uint8_t *buf, size_t *nb_elems, AVFifoCB read_cb, void *opaque)
AVFifo * av_fifo_alloc2(size_t nb_elems, size_t elem_size, unsigned int flags)
Allocate and initialize an AVFifo with a given element size.
int av_fifo_size(const AVFifoBuffer *f)
Return the amount of data in bytes in the AVFifoBuffer, that is the amount of data you can read from ...
static int fifo_check_space(AVFifo *f, size_t to_write)
AVFifoBuffer * av_fifo_alloc(unsigned int size)
Initialize an AVFifoBuffer.
the frame and frame reference mechanism is intended to as much as expensive copies of that data while still allowing the filters to produce correct results The data is stored in buffers represented by AVFrame structures Several references can point to the same frame buffer
void av_fifo_reset(AVFifoBuffer *f)
Reset the AVFifoBuffer to the state right after av_fifo_alloc, in particular it is emptied.
#define FF_DISABLE_DEPRECATION_WARNINGS
static int fifo_peek_common(const AVFifo *f, uint8_t *buf, size_t *nb_elems, size_t offset, AVFifoCB write_cb, void *opaque)
int av_fifo_space(const AVFifoBuffer *f)
Return the amount of space in bytes in the AVFifoBuffer, that is the amount of data you can write int...
int av_fifo_generic_read(AVFifoBuffer *f, void *dest, int buf_size, void(*func)(void *, void *, int))
Feed data from an AVFifoBuffer to a user-supplied callback.
static int write_cb(void *opaque, void *buf, size_t *nb_elems)
#define flags(name, subs,...)
void av_fifo_freep2(AVFifo **f)
Free an AVFifo and reset pointer to NULL.
int av_fifo_generic_peek_at(AVFifoBuffer *f, void *dest, int offset, int buf_size, void(*func)(void *, void *, int))
Feed data at specific position from an AVFifoBuffer to a user-supplied callback.
#define AV_FIFO_FLAG_AUTO_GROW
Automatically resize the FIFO on writes, so that the data fits.
void * av_realloc(void *ptr, size_t size)
Allocate, reallocate, or free a block of memory.
Generated on Tue Feb 28 2023 21:33:51 for FFmpeg by
doxygen
1.8.17