This will not increase the FIFO beyond 1MB, unless the caller explicitly specifies otherwise.
Unified · Split
| @@ -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 | ||
| 26 | 2022-01-26 - af94ab7c7c0 - lavu 57.19.100 - tx.h | 26 | 2022-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. |
| @@ -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 | |||
| 29 | struct AVFifo { | 32 | struct 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_w | 37 | // 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 | ||
| 38 | AVFifo *av_fifo_alloc2(size_t nb_elems, size_t elem_size, | 44 | 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 | |||
| 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 | ||
| 74 | void av_fifo_auto_grow_limit(AVFifo *f, size_t max_elems) | ||
| 75 | { | ||
| 76 | f->auto_grow_limit = max_elems; | ||
| 77 | } | ||
| 78 | |||
| 65 | size_t av_fifo_elem_size(const AVFifo *f) | 79 | size_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 | ||
| 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 | |||
| 112 | static int fifo_write_common(AVFifo *f, const uint8_t *buf, size_t *nb_elems, | 146 | static 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); |
| @@ -48,13 +48,20 @@ typedef struct AVFifo AVFifo; · 47 unmodified lines | |||
| 48 | */ | 48 | */ |
| 49 | typedef int AVFifoCB(void *opaque, void *buf, size_t *nb_elems); | 49 | typedef 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 FIFO | 61 | * @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 on | 62 | * @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 0 | 64 | * @param flags a combination of AV_FIFO_FLAG_* |
| 58 | * | 65 | * |
| 59 | * @return newly-allocated AVFifo on success, a negative error code on failure | 66 | * @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 | */ |
| 68 | size_t av_fifo_elem_size(const AVFifo *f); | 75 | size_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 | */ | ||
| 81 | void 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 | */ |