FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavutil/container_fifo.c
Date: 2026-09-27 02:02:56
Exec Total Coverage
Lines: 82 96 85.4%
Functions: 15 15 100.0%
Branches: 21 32 65.6%

Line Branch Exec Source
1 /*
2 * This file is part of FFmpeg.
3 *
4 * FFmpeg is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * FFmpeg is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with FFmpeg; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18
19 #include "avassert.h"
20 #include "container_fifo.h"
21 #include "error.h"
22 #include "fifo.h"
23 #include "frame.h"
24 #include "mem.h"
25 #include "refstruct.h"
26
27 struct AVContainerFifo {
28 AVFifo *fifo;
29 AVRefStructPool *pool;
30
31 void *opaque;
32 void* (*container_alloc)(void *opaque);
33 void (*container_reset)(void *opaque, void *obj);
34 void (*container_free) (void *opaque, void *obj);
35 int (*fifo_transfer) (void *opaque, void *dst, void *src, unsigned flags);
36
37 };
38
39 54163 static int container_fifo_init_entry(AVRefStructOpaque opaque, void *obj)
40 {
41 54163 AVContainerFifo *cf = opaque.nc;
42 54163 void **pobj = obj;
43
44 54163 *pobj = cf->container_alloc(cf->opaque);
45
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 54163 times.
54163 if (!*pobj)
46 ✗ return AVERROR(ENOMEM);
47
48 54163 return 0;
49 }
50
51 2048385 static void container_fifo_reset_entry(AVRefStructOpaque opaque, void *obj)
52 {
53 2048385 AVContainerFifo *cf = opaque.nc;
54 2048385 cf->container_reset(cf->opaque, *(void**)obj);
55 2048385 }
56
57 54163 static void container_fifo_free_entry(AVRefStructOpaque opaque, void *obj)
58 {
59 54163 AVContainerFifo *cf = opaque.nc;
60 54163 cf->container_free(cf->opaque, *(void**)obj);
61 54163 }
62
63 AVContainerFifo*
64 36654 av_container_fifo_alloc(void *opaque,
65 void* (*container_alloc)(void *opaque),
66 void (*container_reset)(void *opaque, void *obj),
67 void (*container_free) (void *opaque, void *obj),
68 int (*fifo_transfer) (void *opaque, void *dst, void *src, unsigned flags),
69 unsigned flags)
70 {
71 AVContainerFifo *cf;
72
73 36654 cf = av_mallocz(sizeof(*cf));
74
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 36654 times.
36654 if (!cf)
75 ✗ return NULL;
76
77 36654 cf->opaque = opaque;
78 36654 cf->container_alloc = container_alloc;
79 36654 cf->container_reset = container_reset;
80 36654 cf->container_free = container_free;
81 36654 cf->fifo_transfer = fifo_transfer;
82
83 36654 cf->fifo = av_fifo_alloc2(1, sizeof(void*), AV_FIFO_FLAG_AUTO_GROW);
84
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 36654 times.
36654 if (!cf->fifo)
85 ✗ goto fail;
86
87 36654 cf->pool = av_refstruct_pool_alloc_ext(sizeof(void*), 0, cf,
88 container_fifo_init_entry,
89 container_fifo_reset_entry,
90 container_fifo_free_entry,
91 NULL);
92
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 36654 times.
36654 if (!cf->pool)
93 ✗ goto fail;
94
95 36654 return cf;
96 ✗ fail:
97 ✗ av_container_fifo_free(&cf);
98 ✗ return NULL;
99 }
100
101 36654 void av_container_fifo_free(AVContainerFifo **pcf)
102 {
103 AVContainerFifo *cf;
104
105
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 36654 times.
36654 if (!*pcf)
106 ✗ return;
107
108 36654 cf = *pcf;
109
110
1/2
✓ Branch 0 taken 36654 times.
✗ Branch 1 not taken.
36654 if (cf->fifo) {
111 void *obj;
112
2/2
✓ Branch 1 taken 13357 times.
✓ Branch 2 taken 36654 times.
50011 while (av_fifo_read(cf->fifo, &obj, 1) >= 0)
113 13357 av_refstruct_unref(&obj);
114 36654 av_fifo_freep2(&cf->fifo);
115 }
116
117 36654 av_refstruct_pool_uninit(&cf->pool);
118
119 36654 av_freep(pcf);
120 }
121
122 3187995 int av_container_fifo_read(AVContainerFifo *cf, void *obj, unsigned flags)
123 {
124 void **psrc;
125 int ret;
126
127 3187995 ret = av_fifo_read(cf->fifo, &psrc, 1);
128
2/2
✓ Branch 0 taken 1168716 times.
✓ Branch 1 taken 2019279 times.
3187995 if (ret < 0)
129 1168716 return ret;
130
131 2019279 ret = cf->fifo_transfer(cf->opaque, obj, *psrc, flags);
132 2019279 av_refstruct_unref(&psrc);
133
134 2019279 return ret;
135 }
136
137 281475 int av_container_fifo_peek(AVContainerFifo *cf, void **pdst, size_t offset)
138 {
139 void **pobj;
140 int ret;
141
142 281475 ret = av_fifo_peek(cf->fifo, &pobj, 1, offset);
143
2/2
✓ Branch 0 taken 17387 times.
✓ Branch 1 taken 264088 times.
281475 if (ret < 0)
144 17387 return ret;
145
146 264088 *pdst = *pobj;
147
148 264088 return 0;
149 }
150
151 15749 void av_container_fifo_drain(AVContainerFifo *cf, size_t nb_elems)
152 {
153
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 15749 times.
15749 av_assert0(nb_elems <= av_fifo_can_read(cf->fifo));
154
2/2
✓ Branch 0 taken 15749 times.
✓ Branch 1 taken 15749 times.
31498 while (nb_elems--) {
155 void **pobj;
156 15749 int ret = av_fifo_read(cf->fifo, &pobj, 1);
157
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15749 times.
15749 av_assert0(ret >= 0);
158 15749 av_refstruct_unref(&pobj);
159 }
160 15749 }
161
162 2048385 int av_container_fifo_write(AVContainerFifo *cf, void *obj, unsigned flags)
163 {
164 void **pdst;
165 int ret;
166
167 2048385 pdst = av_refstruct_pool_get(cf->pool);
168
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2048385 times.
2048385 if (!pdst)
169 ✗ return AVERROR(ENOMEM);
170
171 2048385 ret = cf->fifo_transfer(cf->opaque, *pdst, obj, flags);
172
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2048385 times.
2048385 if (ret < 0)
173 ✗ goto fail;
174
175 2048385 ret = av_fifo_write(cf->fifo, &pdst, 1);
176
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2048385 times.
2048385 if (ret < 0)
177 ✗ goto fail;
178
179 2048385 return 0;
180 ✗ fail:
181 ✗ av_refstruct_unref(&pdst);
182 ✗ return ret;
183 }
184
185 197631 size_t av_container_fifo_can_read(const AVContainerFifo *cf)
186 {
187 197631 return av_fifo_can_read(cf->fifo);
188 }
189
190 28217 static void *frame_alloc(void *opaque)
191 {
192 28217 return av_frame_alloc();
193 }
194
195 1016527 static void frame_reset(void *opaque, void *obj)
196 {
197 1016527 av_frame_unref(obj);
198 1016527 }
199
200 28217 static void frame_free(void *opaque, void *obj)
201 {
202 28217 AVFrame *frame = obj;
203 28217 av_frame_free(&frame);
204 28217 }
205
206 2010913 static int frame_transfer(void *opaque, void *dst, void *src, unsigned flags)
207 {
208
2/2
✓ Branch 0 taken 10308 times.
✓ Branch 1 taken 2000605 times.
2010913 if (flags & AV_CONTAINER_FIFO_FLAG_REF)
209 10308 return av_frame_ref(dst, src);
210
211 2000605 av_frame_move_ref(dst, src);
212 2000605 return 0;
213 }
214
215 20599 AVContainerFifo *av_container_fifo_alloc_avframe(unsigned flags)
216 {
217 20599 return av_container_fifo_alloc(NULL, frame_alloc, frame_reset, frame_free,
218 frame_transfer, 0);
219 }
220