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 AVFifoBuffer *av_fifo_alloc_array(size_t nmemb, size_t size)
28 {
29  AVFifoBuffer *f;
30  void *buffer = av_realloc_array(NULL, nmemb, size);
31  if (!buffer)
32  return NULL;
33  f = av_mallocz(sizeof(AVFifoBuffer));
34  if (!f) {
35  av_free(buffer);
36  return NULL;
37  }
38  f->buffer = buffer;
39  f->end = f->buffer + nmemb * size;
41  return f;
42 }
43 
45 {
46  return av_fifo_alloc_array(size, 1);
47 }
48 
50 {
51  if (f) {
52  av_freep(&f->buffer);
53  av_free(f);
54  }
55 }
56 
58 {
59  if (f) {
60  av_fifo_free(*f);
61  *f = NULL;
62  }
63 }
64 
66 {
67  f->wptr = f->rptr = f->buffer;
68  f->wndx = f->rndx = 0;
69 }
70 
72 {
73  return (uint32_t)(f->wndx - f->rndx);
74 }
75 
77 {
78  return f->end - f->buffer - av_fifo_size(f);
79 }
80 
81 int av_fifo_realloc2(AVFifoBuffer *f, unsigned int new_size)
82 {
83  unsigned int old_size = f->end - f->buffer;
84 
85  if (old_size < new_size) {
86  size_t offset_r = f->rptr - f->buffer;
87  size_t offset_w = f->wptr - f->buffer;
88  uint8_t *tmp;
89 
90  tmp = av_realloc(f->buffer, new_size);
91  if (!tmp)
92  return AVERROR(ENOMEM);
93 
94  // move the data from the beginning of the ring buffer
95  // to the newly allocated space
96  // the second condition distinguishes full vs empty fifo
97  if (offset_w <= offset_r && av_fifo_size(f)) {
98  const size_t copy = FFMIN(new_size - old_size, offset_w);
99  memcpy(tmp + old_size, tmp, copy);
100  if (copy < offset_w) {
101  memmove(tmp, tmp + copy , offset_w - copy);
102  offset_w -= copy;
103  } else
104  offset_w = old_size + copy;
105  }
106 
107  f->buffer = tmp;
108  f->end = f->buffer + new_size;
109  f->rptr = f->buffer + offset_r;
110  f->wptr = f->buffer + offset_w;
111  }
112  return 0;
113 }
114 
115 int av_fifo_grow(AVFifoBuffer *f, unsigned int size)
116 {
117  unsigned int old_size = f->end - f->buffer;
118  if(size + (unsigned)av_fifo_size(f) < size)
119  return AVERROR(EINVAL);
120 
121  size += av_fifo_size(f);
122 
123  if (old_size < size)
124  return av_fifo_realloc2(f, FFMAX(size, 2*old_size));
125  return 0;
126 }
127 
128 /* src must NOT be const as it can be a context for func that may need
129  * updating (like a pointer or byte counter) */
131  int (*func)(void *, void *, int))
132 {
133  int total = size;
134  uint32_t wndx= f->wndx;
135  uint8_t *wptr= f->wptr;
136 
137  if (size > av_fifo_space(f))
138  return AVERROR(ENOSPC);
139 
140  do {
141  int len = FFMIN(f->end - wptr, size);
142  if (func) {
143  len = func(src, wptr, len);
144  if (len <= 0)
145  break;
146  } else {
147  memcpy(wptr, src, len);
148  src = (uint8_t *)src + len;
149  }
150  wptr += len;
151  if (wptr >= f->end)
152  wptr = f->buffer;
153  wndx += len;
154  size -= len;
155  } while (size > 0);
156  f->wndx= wndx;
157  f->wptr= wptr;
158  return total - size;
159 }
160 
161 int av_fifo_generic_peek_at(AVFifoBuffer *f, void *dest, int offset, int buf_size, void (*func)(void*, void*, int))
162 {
163  uint8_t *rptr = f->rptr;
164 
165  if (offset < 0 || buf_size > av_fifo_size(f) - offset)
166  return AVERROR(EINVAL);
167 
168  if (offset >= f->end - rptr)
169  rptr += offset - (f->end - f->buffer);
170  else
171  rptr += offset;
172 
173  while (buf_size > 0) {
174  int len;
175 
176  if (rptr >= f->end)
177  rptr -= f->end - f->buffer;
178 
179  len = FFMIN(f->end - rptr, buf_size);
180  if (func)
181  func(dest, rptr, len);
182  else {
183  memcpy(dest, rptr, len);
184  dest = (uint8_t *)dest + len;
185  }
186 
187  buf_size -= len;
188  rptr += len;
189  }
190 
191  return 0;
192 }
193 
194 int av_fifo_generic_peek(AVFifoBuffer *f, void *dest, int buf_size,
195  void (*func)(void *, void *, int))
196 {
197  uint8_t *rptr = f->rptr;
198 
199  if (buf_size > av_fifo_size(f))
200  return AVERROR(EINVAL);
201 
202  do {
203  int len = FFMIN(f->end - rptr, buf_size);
204  if (func)
205  func(dest, rptr, len);
206  else {
207  memcpy(dest, rptr, len);
208  dest = (uint8_t *)dest + len;
209  }
210  rptr += len;
211  if (rptr >= f->end)
212  rptr -= f->end - f->buffer;
213  buf_size -= len;
214  } while (buf_size > 0);
215 
216  return 0;
217 }
218 
219 int av_fifo_generic_read(AVFifoBuffer *f, void *dest, int buf_size,
220  void (*func)(void *, void *, int))
221 {
222  if (buf_size > av_fifo_size(f))
223  return AVERROR(EINVAL);
224 
225  do {
226  int len = FFMIN(f->end - f->rptr, buf_size);
227  if (func)
228  func(dest, f->rptr, len);
229  else {
230  memcpy(dest, f->rptr, len);
231  dest = (uint8_t *)dest + len;
232  }
233  av_fifo_drain(f, len);
234  buf_size -= len;
235  } while (buf_size > 0);
236  return 0;
237 }
238 
239 /** Discard data from the FIFO. */
241 {
243  f->rptr += size;
244  if (f->rptr >= f->end)
245  f->rptr -= f->end - f->buffer;
246  f->rndx += size;
247 }
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:130
av_fifo_free
void av_fifo_free(AVFifoBuffer *f)
Free an AVFifoBuffer.
Definition: fifo.c:49
av_fifo_grow
int av_fifo_grow(AVFifoBuffer *f, unsigned int size)
Enlarge an AVFifoBuffer.
Definition: fifo.c:115
tmp
static uint8_t tmp[11]
Definition: aes_ctr.c:26
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:194
FFMAX
#define FFMAX(a, b)
Definition: macros.h:47
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:219
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:65
av_fifo_drain
void av_fifo_drain(AVFifoBuffer *f, int size)
Discard data from the FIFO.
Definition: fifo.c:240
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:76
av_realloc_array
void * av_realloc_array(void *ptr, size_t nmemb, size_t size)
Definition: mem.c:224
av_fifo_realloc2
int av_fifo_realloc2(AVFifoBuffer *f, unsigned int new_size)
Resize an AVFifoBuffer.
Definition: fifo.c:81
f
#define f(width, name)
Definition: cbs_vp9.c:255
NULL
#define NULL
Definition: coverity.c:32
av_realloc
void * av_realloc(void *ptr, size_t size)
Allocate, reallocate, or free a block of memory.
Definition: mem.c:152
copy
static void copy(const float *p1, float *p2, const int length)
Definition: vf_vaguedenoiser.c:187
size
int size
Definition: twinvq_data.h:10344
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
common.h
av_fifo_alloc_array
AVFifoBuffer * av_fifo_alloc_array(size_t nmemb, size_t size)
Initialize an AVFifoBuffer.
Definition: fifo.c:27
FFMIN
#define FFMIN(a, b)
Definition: macros.h: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:263
len
int len
Definition: vorbis_enc_data.h:426
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:71
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:161
av_fifo_freep
void av_fifo_freep(AVFifoBuffer **f)
Free an AVFifoBuffer and reset pointer to NULL.
Definition: fifo.c:57
av_free
#define av_free(p)
Definition: tableprint_vlc.h:34
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:35
src
INIT_CLIP pixel * src
Definition: h264pred_template.c:418
av_fifo_alloc
AVFifoBuffer * av_fifo_alloc(unsigned int size)
Initialize an AVFifoBuffer.
Definition: fifo.c:44