History

lavu/fifo: add a flag for automatically growing the FIFO as needed

This will not increase the FIFO beyond 1MB, unless the caller explicitly specifies otherwise.

Anton Khirnov committed 4 years ago

Commit 14429f81 parent 7329b223 files · +52 −4Browse files

Unified · Split

3 files
  1. doc/APIchanges +1 −1
  2. libavutil/fifo.c +37 −2
  3. libavutil/fifo.h +14 −1
doc/APIchanges+1−1
@@ -21,7 +21,7 @@ API changes, most recent first: · 20 unmodified lines
2121 av_fifo_can_write(), av_fifo_grow2(), av_fifo_drain2(), av_fifo_write(),
2222 av_fifo_write_from_cb(), av_fifo_read(), av_fifo_read_to_cb(),
2323 av_fifo_peek(), av_fifo_peek_to_cb(), av_fifo_drain2(), av_fifo_reset2(),
24− av_fifo_freep2().
24+ av_fifo_freep2(), av_fifo_auto_grow_limit().
2525
2626 2022-01-26 - af94ab7c7c0 - lavu 57.19.100 - tx.h
2727 Add AV_TX_FLOAT_RDFT, AV_TX_DOUBLE_RDFT and AV_TX_INT32_RDFT.
libavutil/fifo.c+37−2
@@ -26,6 +26,9 @@ · 25 unmodified lines
2626 #include "common.h"
2727 #include "fifo.h"
2828
29+// by default the FIFO can be auto-grown to 1MB
30+#define AUTO_GROW_DEFAULT_BYTES (1024 * 1024)
31+
2932 struct AVFifo {
3033 uint8_t *buffer;
3134
@@ -33,6 +36,9 @@ struct AVFifo { · 1 unmodified line
3336 size_t offset_r, offset_w;
3437 // distinguishes the ambiguous situation offset_r == offset_w
3538 int is_empty;
39+
40+ unsigned int flags;
41+ size_t auto_grow_limit;
3642 };
3743
3844 AVFifo *av_fifo_alloc2(size_t nb_elems, size_t elem_size,
@@ -59,9 +65,17 @@ AVFifo *av_fifo_alloc2(size_t nb_elems, size_t elem_size, · 20 unmodified lines
5965 f->elem_size = elem_size;
6066 f->is_empty = 1;
6167
68+ f->flags = flags;
69+ f->auto_grow_limit = FFMAX(AUTO_GROW_DEFAULT_BYTES / elem_size, 1);
70+
6271 return f;
6372 }
6473
74+void av_fifo_auto_grow_limit(AVFifo *f, size_t max_elems)
75+{
76+ f->auto_grow_limit = max_elems;
77+}
78+
6579 size_t av_fifo_elem_size(const AVFifo *f)
6680 {
6781 return f->elem_size;
@@ -109,6 +123,26 @@ int av_fifo_grow2(AVFifo *f, size_t inc) · 41 unmodified lines
109123 return 0;
110124 }
111125
126+static int fifo_check_space(AVFifo *f, size_t to_write)
127+{
128+ const size_t can_write = av_fifo_can_write(f);
129+ const size_t need_grow = to_write > can_write ? to_write - can_write : 0;
130+ size_t can_grow;
131+
132+ if (!need_grow)
133+ return 0;
134+
135+ can_grow = f->auto_grow_limit > f->nb_elems ?
136+ f->auto_grow_limit - f->nb_elems : 0;
137+ if ((f->flags & AV_FIFO_FLAG_AUTO_GROW) && need_grow <= can_grow) {
138+ // allocate a bit more than necessary, if we can
139+ const size_t inc = (need_grow < can_grow / 2 ) ? need_grow * 2 : can_grow;
140+ return av_fifo_grow2(f, inc);
141+ }
142+
143+ return AVERROR(ENOSPC);
144+}
145+
112146 static int fifo_write_common(AVFifo *f, const uint8_t *buf, size_t *nb_elems,
113147 AVFifoCB read_cb, void *opaque)
114148 {
@@ -116,8 +150,9 @@ static int fifo_write_common(AVFifo *f, const uint8_t *buf, size_t *nb_elems, · 1 unmodified line
116150 size_t offset_w = f->offset_w;
117151 int ret = 0;
118152
119− if (to_write > av_fifo_can_write(f))
120− return AVERROR(ENOSPC);
153+ ret = fifo_check_space(f, to_write);
154+ if (ret < 0)
155+ return ret;
121156
122157 while (to_write > 0) {
123158 size_t len = FFMIN(f->nb_elems - offset_w, to_write);
libavutil/fifo.h+14−1
@@ -48,13 +48,20 @@ typedef struct AVFifo AVFifo; · 47 unmodified lines
4848 */
4949 typedef int AVFifoCB(void *opaque, void *buf, size_t *nb_elems);
5050
51+/**
52+ * Automatically resize the FIFO on writes, so that the data fits. This
53+ * automatic resizing happens up to a limit that can be modified with
54+ * av_fifo_auto_grow_limit().
55+ */
56+#define AV_FIFO_FLAG_AUTO_GROW (1 << 0)
57+
5158 /**
5259 * Allocate and initialize an AVFifo with a given element size.
5360 *
5461 * @param elems initial number of elements that can be stored in the FIFO
5562 * @param elem_size Size in bytes of a single element. Further operations on
5663 * the returned FIFO will implicitly use this element size.
57− * @param flags currently unused, must be 0
64+ * @param flags a combination of AV_FIFO_FLAG_*
5865 *
5966 * @return newly-allocated AVFifo on success, a negative error code on failure
6067 */
@@ -67,6 +74,12 @@ AVFifo *av_fifo_alloc2(size_t elems, size_t elem_size, · 6 unmodified lines
6774 */
6875 size_t av_fifo_elem_size(const AVFifo *f);
6976
77+/**
78+ * Set the maximum size (in elements) to which the FIFO can be resized
79+ * automatically. Has no effect unless AV_FIFO_FLAG_AUTO_GROW is used.
80+ */
81+void av_fifo_auto_grow_limit(AVFifo *f, size_t max_elems);
82+
7083 /**
7184 * @return number of elements available for reading from the given FIFO.
7285 */

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t