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
21 av_fifo_can_write(), av_fifo_grow2(), av_fifo_drain2(), av_fifo_write(),21 av_fifo_can_write(), av_fifo_grow2(), av_fifo_drain2(), av_fifo_write(),
22 av_fifo_write_from_cb(), av_fifo_read(), av_fifo_read_to_cb(),22 av_fifo_write_from_cb(), av_fifo_read(), av_fifo_read_to_cb(),
23 av_fifo_peek(), av_fifo_peek_to_cb(), av_fifo_drain2(), av_fifo_reset2(),23 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().
25 25
262022-01-26 - af94ab7c7c0 - lavu 57.19.100 - tx.h262022-01-26 - af94ab7c7c0 - lavu 57.19.100 - tx.h
27 Add AV_TX_FLOAT_RDFT, AV_TX_DOUBLE_RDFT and AV_TX_INT32_RDFT.27 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
26#include "common.h"26#include "common.h"
27#include "fifo.h"27#include "fifo.h"
28 28
29// by default the FIFO can be auto-grown to 1MB
30#define AUTO_GROW_DEFAULT_BYTES (1024 * 1024)
31
29struct AVFifo {32struct AVFifo {
30 uint8_t *buffer;33 uint8_t *buffer;
31 34
@@ -33,6 +36,9 @@ struct AVFifo { · 1 unmodified line
33 size_t offset_r, offset_w;36 size_t offset_r, offset_w;
34 // distinguishes the ambiguous situation offset_r == offset_w37 // distinguishes the ambiguous situation offset_r == offset_w
35 int is_empty;38 int is_empty;
39
40 unsigned int flags;
41 size_t auto_grow_limit;
36};42};
37 43
38AVFifo *av_fifo_alloc2(size_t nb_elems, size_t elem_size,44AVFifo *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
59 f->elem_size = elem_size;65 f->elem_size = elem_size;
60 f->is_empty = 1;66 f->is_empty = 1;
61 67
68 f->flags = flags;
69 f->auto_grow_limit = FFMAX(AUTO_GROW_DEFAULT_BYTES / elem_size, 1);
70
62 return f;71 return f;
63}72}
64 73
74void av_fifo_auto_grow_limit(AVFifo *f, size_t max_elems)
75{
76 f->auto_grow_limit = max_elems;
77}
78
65size_t av_fifo_elem_size(const AVFifo *f)79size_t av_fifo_elem_size(const AVFifo *f)
66{80{
67 return f->elem_size;81 return f->elem_size;
@@ -109,6 +123,26 @@ int av_fifo_grow2(AVFifo *f, size_t inc) · 41 unmodified lines
109 return 0;123 return 0;
110}124}
111 125
126static 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
112static int fifo_write_common(AVFifo *f, const uint8_t *buf, size_t *nb_elems,146static int fifo_write_common(AVFifo *f, const uint8_t *buf, size_t *nb_elems,
113 AVFifoCB read_cb, void *opaque)147 AVFifoCB read_cb, void *opaque)
114{148{
@@ -116,8 +150,9 @@ static int fifo_write_common(AVFifo *f, const uint8_t *buf, size_t *nb_elems, · 1 unmodified line
116 size_t offset_w = f->offset_w;150 size_t offset_w = f->offset_w;
117 int ret = 0;151 int ret = 0;
118 152
119 if (to_write > av_fifo_can_write(f))153 ret = fifo_check_space(f, to_write);
120 return AVERROR(ENOSPC);154 if (ret < 0)
155 return ret;
121 156
122 while (to_write > 0) {157 while (to_write > 0) {
123 size_t len = FFMIN(f->nb_elems - offset_w, to_write);158 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
48 */48 */
49typedef int AVFifoCB(void *opaque, void *buf, size_t *nb_elems);49typedef int AVFifoCB(void *opaque, void *buf, size_t *nb_elems);
50 50
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
51/**58/**
52 * Allocate and initialize an AVFifo with a given element size.59 * Allocate and initialize an AVFifo with a given element size.
53 *60 *
54 * @param elems initial number of elements that can be stored in the FIFO61 * @param elems initial number of elements that can be stored in the FIFO
55 * @param elem_size Size in bytes of a single element. Further operations on62 * @param elem_size Size in bytes of a single element. Further operations on
56 * the returned FIFO will implicitly use this element size.63 * the returned FIFO will implicitly use this element size.
57 * @param flags currently unused, must be 064 * @param flags a combination of AV_FIFO_FLAG_*
58 *65 *
59 * @return newly-allocated AVFifo on success, a negative error code on failure66 * @return newly-allocated AVFifo on success, a negative error code on failure
60 */67 */
@@ -67,6 +74,12 @@ AVFifo *av_fifo_alloc2(size_t elems, size_t elem_size, · 6 unmodified lines
67 */74 */
68size_t av_fifo_elem_size(const AVFifo *f);75size_t av_fifo_elem_size(const AVFifo *f);
69 76
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 */
81void av_fifo_auto_grow_limit(AVFifo *f, size_t max_elems);
82
70/**83/**
71 * @return number of elements available for reading from the given FIFO.84 * @return number of elements available for reading from the given FIFO.
72 */85 */

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