FFmpeg
fifo.c
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 "avassert.h"
24 #include "common.h"
25 #include "fifo.h"
26 
27 static AVFifoBuffer *fifo_alloc_common(void *buffer, size_t size)
28 {
29  AVFifoBuffer *f;
30  if (!buffer)
31  return NULL;
32  f = av_mallocz(sizeof(AVFifoBuffer));
33  if (!f) {
34  av_free(buffer);
35  return NULL;
36  }
37  f->buffer = buffer;
38  f->end = f->buffer + size;
40  return f;
41 }
42 
44 {
45  void *buffer = av_malloc(size);
46  return fifo_alloc_common(buffer, size);
47 }
48 
49 AVFifoBuffer *av_fifo_alloc_array(size_t nmemb, size_t size)
50 {
51  void *buffer = av_malloc_array(nmemb, size);
52  return fifo_alloc_common(buffer, nmemb * size);
53 }
54 
56 {
57  if (f) {
58  av_freep(&f->buffer);
59  av_free(f);
60  }
61 }
62 
64 {
65  if (f) {
66  av_fifo_free(*f);
67  *f = NULL;
68  }
69 }
70 
72 {
73  f->wptr = f->rptr = f->buffer;
74  f->wndx = f->rndx = 0;
75 }
76 
78 {
79  return (uint32_t)(f->wndx - f->rndx);
80 }
81 
83 {
84  return f->end - f->buffer - av_fifo_size(f);
85 }
86 
87 int av_fifo_realloc2(AVFifoBuffer *f, unsigned int new_size)
88 {
89  unsigned int old_size = f->end - f->buffer;
90 
91  if (old_size < new_size) {
92  int len = av_fifo_size(f);
93  AVFifoBuffer *f2 = av_fifo_alloc(new_size);
94 
95  if (!f2)
96  return AVERROR(ENOMEM);
98  f2->wptr += len;
99  f2->wndx += len;
100  av_free(f->buffer);
101  *f = *f2;
102  av_free(f2);
103  }
104  return 0;
105 }
106 
107 int av_fifo_grow(AVFifoBuffer *f, unsigned int size)
108 {
109  unsigned int old_size = f->end - f->buffer;
110  if(size + (unsigned)av_fifo_size(f) < size)
111  return AVERROR(EINVAL);
112 
113  size += av_fifo_size(f);
114 
115  if (old_size < size)
116  return av_fifo_realloc2(f, FFMAX(size, 2*old_size));
117  return 0;
118 }
119 
120 /* src must NOT be const as it can be a context for func that may need
121  * updating (like a pointer or byte counter) */
123  int (*func)(void *, void *, int))
124 {
125  int total = size;
126  uint32_t wndx= f->wndx;
127  uint8_t *wptr= f->wptr;
128 
129  do {
130  int len = FFMIN(f->end - wptr, size);
131  if (func) {
132  len = func(src, wptr, len);
133  if (len <= 0)
134  break;
135  } else {
136  memcpy(wptr, src, len);
137  src = (uint8_t *)src + len;
138  }
139 // Write memory barrier needed for SMP here in theory
140  wptr += len;
141  if (wptr >= f->end)
142  wptr = f->buffer;
143  wndx += len;
144  size -= len;
145  } while (size > 0);
146  f->wndx= wndx;
147  f->wptr= wptr;
148  return total - size;
149 }
150 
151 int av_fifo_generic_peek_at(AVFifoBuffer *f, void *dest, int offset, int buf_size, void (*func)(void*, void*, int))
152 {
153  uint8_t *rptr = f->rptr;
154 
155  av_assert2(offset >= 0);
156 
157  /*
158  * *ndx are indexes modulo 2^32, they are intended to overflow,
159  * to handle *ndx greater than 4gb.
160  */
161  av_assert2(buf_size + (unsigned)offset <= f->wndx - f->rndx);
162 
163  if (offset >= f->end - rptr)
164  rptr += offset - (f->end - f->buffer);
165  else
166  rptr += offset;
167 
168  while (buf_size > 0) {
169  int len;
170 
171  if (rptr >= f->end)
172  rptr -= f->end - f->buffer;
173 
174  len = FFMIN(f->end - rptr, buf_size);
175  if (func)
176  func(dest, rptr, len);
177  else {
178  memcpy(dest, rptr, len);
179  dest = (uint8_t *)dest + len;
180  }
181 
182  buf_size -= len;
183  rptr += len;
184  }
185 
186  return 0;
187 }
188 
189 int av_fifo_generic_peek(AVFifoBuffer *f, void *dest, int buf_size,
190  void (*func)(void *, void *, int))
191 {
192 // Read memory barrier needed for SMP here in theory
193  uint8_t *rptr = f->rptr;
194 
195  do {
196  int len = FFMIN(f->end - rptr, buf_size);
197  if (func)
198  func(dest, rptr, len);
199  else {
200  memcpy(dest, rptr, len);
201  dest = (uint8_t *)dest + len;
202  }
203 // memory barrier needed for SMP here in theory
204  rptr += len;
205  if (rptr >= f->end)
206  rptr -= f->end - f->buffer;
207  buf_size -= len;
208  } while (buf_size > 0);
209 
210  return 0;
211 }
212 
213 int av_fifo_generic_read(AVFifoBuffer *f, void *dest, int buf_size,
214  void (*func)(void *, void *, int))
215 {
216 // Read memory barrier needed for SMP here in theory
217  do {
218  int len = FFMIN(f->end - f->rptr, buf_size);
219  if (func)
220  func(dest, f->rptr, len);
221  else {
222  memcpy(dest, f->rptr, len);
223  dest = (uint8_t *)dest + len;
224  }
225 // memory barrier needed for SMP here in theory
226  av_fifo_drain(f, len);
227  buf_size -= len;
228  } while (buf_size > 0);
229  return 0;
230 }
231 
232 /** Discard data from the FIFO. */
234 {
236  f->rptr += size;
237  if (f->rptr >= f->end)
238  f->rptr -= f->end - f->buffer;
239  f->rndx += size;
240 }
func
int(* func)(AVBPrint *dst, const char *in, const char *arg)
Definition: jacosubdec.c:68
AVERROR
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
av_fifo_generic_write
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.
Definition: fifo.c:122
av_fifo_free
void av_fifo_free(AVFifoBuffer *f)
Free an AVFifoBuffer.
Definition: fifo.c:55
av_fifo_grow
int av_fifo_grow(AVFifoBuffer *f, unsigned int size)
Enlarge an AVFifoBuffer.
Definition: fifo.c:107
fifo_alloc_common
static AVFifoBuffer * fifo_alloc_common(void *buffer, size_t size)
Definition: fifo.c:27
AVFifoBuffer::wptr
uint8_t * wptr
Definition: fifo.h:33
av_fifo_generic_peek
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.
Definition: fifo.c:189
av_fifo_generic_read
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.
Definition: fifo.c:213
av_fifo_reset
void av_fifo_reset(AVFifoBuffer *f)
Reset the AVFifoBuffer to the state right after av_fifo_alloc, in particular it is emptied.
Definition: fifo.c:71
av_fifo_drain
void av_fifo_drain(AVFifoBuffer *f, int size)
Discard data from the FIFO.
Definition: fifo.c:233
av_malloc
#define av_malloc(s)
Definition: tableprint_vlc.h:31
AVFifoBuffer
Definition: fifo.h:31
fifo.h
avassert.h
av_fifo_space
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...
Definition: fifo.c:82
av_fifo_realloc2
int av_fifo_realloc2(AVFifoBuffer *f, unsigned int new_size)
Resize an AVFifoBuffer.
Definition: fifo.c:87
f
#define f(width, name)
Definition: cbs_vp9.c:255
NULL
#define NULL
Definition: coverity.c:32
src
#define src
Definition: vp8dsp.c:255
FFMAX
#define FFMAX(a, b)
Definition: common.h:103
size
int size
Definition: twinvq_data.h:10344
FFMIN
#define FFMIN(a, b)
Definition: common.h:105
offset
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
Definition: writing_filters.txt:86
av_assert2
#define av_assert2(cond)
assert() equivalent, that does lie in speed critical code.
Definition: avassert.h:64
av_malloc_array
#define av_malloc_array(a, b)
Definition: tableprint_vlc.h:32
common.h
av_fifo_alloc_array
AVFifoBuffer * av_fifo_alloc_array(size_t nmemb, size_t size)
Initialize an AVFifoBuffer.
Definition: fifo.c:49
av_mallocz
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
Definition: mem.c:243
len
int len
Definition: vorbis_enc_data.h:452
AVFifoBuffer::buffer
uint8_t * buffer
Definition: fifo.h:32
AVFifoBuffer::wndx
uint32_t wndx
Definition: fifo.h:34
buffer
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
Definition: filter_design.txt:49
av_fifo_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 ...
Definition: fifo.c:77
av_fifo_generic_peek_at
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.
Definition: fifo.c:151
av_fifo_freep
void av_fifo_freep(AVFifoBuffer **f)
Free an AVFifoBuffer and reset pointer to NULL.
Definition: fifo.c:63
av_free
#define av_free(p)
Definition: tableprint_vlc.h:34
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:35
av_fifo_alloc
AVFifoBuffer * av_fifo_alloc(unsigned int size)
Initialize an AVFifoBuffer.
Definition: fifo.c:43