FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavcodec/bytestream.h
Date: 2026-10-29 17:07:12
Exec Total Coverage
Lines: 115 135 85.2%
Functions: 83 88 94.3%
Branches: 44 72 61.1%

Line Branch Exec Source
1 /*
2 * Bytestream functions
3 * copyright (c) 2006 Baptiste Coudurier <baptiste.coudurier@free.fr>
4 * Copyright (c) 2012 Aneesh Dogra (lionaneesh) <lionaneesh@gmail.com>
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 #ifndef AVCODEC_BYTESTREAM_H
24 #define AVCODEC_BYTESTREAM_H
25
26 #include <stdint.h>
27 #include <string.h>
28
29 #include "libavutil/avassert.h"
30 #include "libavutil/common.h"
31 #include "libavutil/intreadwrite.h"
32
33 typedef struct GetByteContext {
34 const uint8_t *buffer, *buffer_end, *buffer_start;
35 } GetByteContext;
36
37 typedef struct PutByteContext {
38 uint8_t *buffer, *buffer_end, *buffer_start;
39 int eof;
40 } PutByteContext;
41
42 #define DEF(type, name, bytes, read, write) \
43 static av_always_inline type bytestream_get_ ## name(const uint8_t **b) \
44 { \
45 (*b) += bytes; \
46 return read(*b - bytes); \
47 } \
48 static av_always_inline void bytestream_put_ ## name(uint8_t **b, \
49 const type value) \
50 { \
51 write(*b, value); \
52 (*b) += bytes; \
53 } \
54 static av_always_inline void bytestream2_put_ ## name ## u(PutByteContext *p, \
55 const type value) \
56 { \
57 bytestream_put_ ## name(&p->buffer, value); \
58 } \
59 static av_always_inline void bytestream2_put_ ## name(PutByteContext *p, \
60 const type value) \
61 { \
62 if (!p->eof && (p->buffer_end - p->buffer >= bytes)) { \
63 write(p->buffer, value); \
64 p->buffer += bytes; \
65 } else \
66 p->eof = 1; \
67 } \
68 static av_always_inline type bytestream2_get_ ## name ## u(GetByteContext *g) \
69 { \
70 return bytestream_get_ ## name(&g->buffer); \
71 } \
72 static av_always_inline type bytestream2_get_ ## name(GetByteContext *g) \
73 { \
74 if (g->buffer_end - g->buffer < bytes) { \
75 g->buffer = g->buffer_end; \
76 return 0; \
77 } \
78 return bytestream2_get_ ## name ## u(g); \
79 } \
80 static av_always_inline type bytestream2_peek_ ## name ## u(const GetByteContext *g) \
81 { \
82 return read(g->buffer); \
83 } \
84 static av_always_inline type bytestream2_peek_ ## name(const GetByteContext *g)\
85 { \
86 if (g->buffer_end - g->buffer < bytes) \
87 return 0; \
88 return bytestream2_peek_ ## name ## u(g); \
89 }
90
91
3/4
✓ Branch 0 taken 34566 times.
✓ Branch 1 taken 508429 times.
✓ Branch 2 taken 34562 times.
✗ Branch 3 not taken.
3084806 DEF(uint64_t, le64, 8, AV_RL64, AV_WL64)
92
3/4
✓ Branch 0 taken 129288 times.
✓ Branch 1 taken 8058586 times.
✓ Branch 2 taken 129288 times.
✗ Branch 3 not taken.
139734358 DEF(unsigned int, le32, 4, AV_RL32, AV_WL32)
93
3/4
✓ Branch 0 taken 232 times.
✓ Branch 1 taken 1084 times.
✓ Branch 2 taken 232 times.
✗ Branch 3 not taken.
153523339 DEF(unsigned int, le24, 3, AV_RL24, AV_WL24)
94
3/4
✓ Branch 0 taken 61236 times.
✓ Branch 1 taken 9500185 times.
✓ Branch 2 taken 61232 times.
✗ Branch 3 not taken.
607534529 DEF(unsigned int, le16, 2, AV_RL16, AV_WL16)
95
3/4
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 8767 times.
✓ Branch 2 taken 8 times.
✗ Branch 3 not taken.
2507332 DEF(uint64_t, be64, 8, AV_RB64, AV_WB64)
96
3/4
✓ Branch 0 taken 214253 times.
✓ Branch 1 taken 457492 times.
✓ Branch 2 taken 214238 times.
✗ Branch 3 not taken.
24662299 DEF(unsigned int, be32, 4, AV_RB32, AV_WB32)
97
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 69433 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
27492356 DEF(unsigned int, be24, 3, AV_RB24, AV_WB24)
98
3/4
✓ Branch 0 taken 7381442 times.
✓ Branch 1 taken 2446415 times.
✓ Branch 2 taken 7381438 times.
✗ Branch 3 not taken.
366542961 DEF(unsigned int, be16, 2, AV_RB16, AV_WB16)
99
3/4
✓ Branch 0 taken 22224148 times.
✓ Branch 1 taken 84426428 times.
✓ Branch 2 taken 22224147 times.
✗ Branch 3 not taken.
764797267 DEF(unsigned int, byte, 1, AV_RB8 , AV_WB8)
100
101 #if AV_HAVE_BIGENDIAN
102 # define bytestream2_get_ne16 bytestream2_get_be16
103 # define bytestream2_get_ne24 bytestream2_get_be24
104 # define bytestream2_get_ne32 bytestream2_get_be32
105 # define bytestream2_get_ne64 bytestream2_get_be64
106 # define bytestream2_get_ne16u bytestream2_get_be16u
107 # define bytestream2_get_ne24u bytestream2_get_be24u
108 # define bytestream2_get_ne32u bytestream2_get_be32u
109 # define bytestream2_get_ne64u bytestream2_get_be64u
110 # define bytestream2_put_ne16 bytestream2_put_be16
111 # define bytestream2_put_ne24 bytestream2_put_be24
112 # define bytestream2_put_ne32 bytestream2_put_be32
113 # define bytestream2_put_ne64 bytestream2_put_be64
114 # define bytestream2_peek_ne16 bytestream2_peek_be16
115 # define bytestream2_peek_ne24 bytestream2_peek_be24
116 # define bytestream2_peek_ne32 bytestream2_peek_be32
117 # define bytestream2_peek_ne64 bytestream2_peek_be64
118 #else
119 # define bytestream2_get_ne16 bytestream2_get_le16
120 # define bytestream2_get_ne24 bytestream2_get_le24
121 # define bytestream2_get_ne32 bytestream2_get_le32
122 # define bytestream2_get_ne64 bytestream2_get_le64
123 # define bytestream2_get_ne16u bytestream2_get_le16u
124 # define bytestream2_get_ne24u bytestream2_get_le24u
125 # define bytestream2_get_ne32u bytestream2_get_le32u
126 # define bytestream2_get_ne64u bytestream2_get_le64u
127 # define bytestream2_put_ne16 bytestream2_put_le16
128 # define bytestream2_put_ne24 bytestream2_put_le24
129 # define bytestream2_put_ne32 bytestream2_put_le32
130 # define bytestream2_put_ne64 bytestream2_put_le64
131 # define bytestream2_peek_ne16 bytestream2_peek_le16
132 # define bytestream2_peek_ne24 bytestream2_peek_le24
133 # define bytestream2_peek_ne32 bytestream2_peek_le32
134 # define bytestream2_peek_ne64 bytestream2_peek_le64
135 #endif
136
137 305823 static av_always_inline void bytestream2_init(GetByteContext *g,
138 const uint8_t *buf,
139 int buf_size)
140 {
141
2/4
✓ Branch 0 taken 305823 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 305823 times.
305823 av_assert0(buf && buf_size >= 0);
142 305823 g->buffer = buf;
143 305823 g->buffer_start = buf;
144 305823 g->buffer_end = buf + buf_size;
145 305823 }
146
147 27022 static av_always_inline void bytestream2_init_writer(PutByteContext *p,
148 uint8_t *buf,
149 int buf_size)
150 {
151
2/4
✓ Branch 0 taken 27022 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 27022 times.
27022 av_assert0(buf && buf_size >= 0);
152 27022 p->buffer = buf;
153 27022 p->buffer_start = buf;
154 27022 p->buffer_end = buf + buf_size;
155 27022 p->eof = 0;
156 27022 }
157
158 37855989 static av_always_inline int bytestream2_get_bytes_left(const GetByteContext *g)
159 {
160 37855989 return g->buffer_end - g->buffer;
161 }
162
163 95089 static av_always_inline int bytestream2_get_bytes_left_p(const PutByteContext *p)
164 {
165 95089 return p->buffer_end - p->buffer;
166 }
167
168 1209659 static av_always_inline void bytestream2_skip(GetByteContext *g,
169 unsigned int size)
170 {
171
2/2
✓ Branch 0 taken 1123942 times.
✓ Branch 1 taken 85717 times.
1209659 g->buffer += FFMIN(g->buffer_end - g->buffer, size);
172 1209659 }
173
174 110993 static av_always_inline void bytestream2_skipu(GetByteContext *g,
175 unsigned int size)
176 {
177 110993 g->buffer += size;
178 110993 }
179
180 103 static av_always_inline void bytestream2_skip_p(PutByteContext *p,
181 unsigned int size)
182 {
183 unsigned int size2;
184
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 103 times.
103 if (p->eof)
185 ✗ return;
186 103 size2 = FFMIN(p->buffer_end - p->buffer, size);
187
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 103 times.
103 if (size2 != size)
188 ✗ p->eof = 1;
189 103 p->buffer += size2;
190 }
191
192 4509987 static av_always_inline int bytestream2_tell(const GetByteContext *g)
193 {
194 4509987 return (int)(g->buffer - g->buffer_start);
195 }
196
197 163024 static av_always_inline int bytestream2_tell_p(const PutByteContext *p)
198 {
199 163024 return (int)(p->buffer - p->buffer_start);
200 }
201
202 1179 static av_always_inline int bytestream2_size(const GetByteContext *g)
203 {
204 1179 return (int)(g->buffer_end - g->buffer_start);
205 }
206
207 ✗ static av_always_inline int bytestream2_size_p(const PutByteContext *p)
208 {
209 ✗ return (int)(p->buffer_end - p->buffer_start);
210 }
211
212 783125 static av_always_inline int bytestream2_seek(GetByteContext *g,
213 int offset,
214 int whence)
215 {
216
3/4
✓ Branch 0 taken 1196 times.
✓ Branch 1 taken 1000 times.
✓ Branch 2 taken 780929 times.
✗ Branch 3 not taken.
783125 switch (whence) {
217 1196 case SEEK_CUR:
218 1196 offset = av_clip(offset, -(g->buffer - g->buffer_start),
219 1196 g->buffer_end - g->buffer);
220 1196 g->buffer += offset;
221 1196 break;
222 1000 case SEEK_END:
223 1000 offset = av_clip(offset, -(g->buffer_end - g->buffer_start), 0);
224 1000 g->buffer = g->buffer_end + offset;
225 1000 break;
226 780929 case SEEK_SET:
227 780929 offset = av_clip(offset, 0, g->buffer_end - g->buffer_start);
228 780929 g->buffer = g->buffer_start + offset;
229 780929 break;
230 ✗ default:
231 ✗ return AVERROR(EINVAL);
232 }
233 783125 return bytestream2_tell(g);
234 }
235
236 13502 static av_always_inline int bytestream2_seek_p(PutByteContext *p,
237 int offset,
238 int whence)
239 {
240 13502 p->eof = 0;
241
2/4
✓ Branch 0 taken 8131 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5371 times.
✗ Branch 3 not taken.
13502 switch (whence) {
242 8131 case SEEK_CUR:
243
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8131 times.
8131 if (p->buffer_end - p->buffer < offset)
244 ✗ p->eof = 1;
245 8131 offset = av_clip(offset, -(p->buffer - p->buffer_start),
246 8131 p->buffer_end - p->buffer);
247 8131 p->buffer += offset;
248 8131 break;
249 ✗ case SEEK_END:
250 ✗ if (offset > 0)
251 ✗ p->eof = 1;
252 ✗ offset = av_clip(offset, -(p->buffer_end - p->buffer_start), 0);
253 ✗ p->buffer = p->buffer_end + offset;
254 ✗ break;
255 5371 case SEEK_SET:
256
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5371 times.
5371 if (p->buffer_end - p->buffer_start < offset)
257 ✗ p->eof = 1;
258 5371 offset = av_clip(offset, 0, p->buffer_end - p->buffer_start);
259 5371 p->buffer = p->buffer_start + offset;
260 5371 break;
261 ✗ default:
262 ✗ return AVERROR(EINVAL);
263 }
264 13502 return bytestream2_tell_p(p);
265 }
266
267 819797 static av_always_inline unsigned int bytestream2_get_buffer(GetByteContext *g,
268 uint8_t *dst,
269 unsigned int size)
270 {
271 819797 unsigned int size2 = FFMIN(g->buffer_end - g->buffer, size);
272 819797 memcpy(dst, g->buffer, size2);
273 819797 g->buffer += size2;
274 819797 return size2;
275 }
276
277 3502749 static av_always_inline unsigned int bytestream2_get_bufferu(GetByteContext *g,
278 uint8_t *dst,
279 unsigned int size)
280 {
281 3502749 memcpy(dst, g->buffer, size);
282 3502749 g->buffer += size;
283 3502749 return size;
284 }
285
286 58470 static av_always_inline unsigned int bytestream2_put_buffer(PutByteContext *p,
287 const uint8_t *src,
288 unsigned int size)
289 {
290 unsigned int size2;
291
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 58470 times.
58470 if (p->eof)
292 ✗ return 0;
293 58470 size2 = FFMIN(p->buffer_end - p->buffer, size);
294
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 58470 times.
58470 if (size2 != size)
295 ✗ p->eof = 1;
296 58470 memcpy(p->buffer, src, size2);
297 58470 p->buffer += size2;
298 58470 return size2;
299 }
300
301 248065 static av_always_inline unsigned int bytestream2_put_bufferu(PutByteContext *p,
302 const uint8_t *src,
303 unsigned int size)
304 {
305 248065 memcpy(p->buffer, src, size);
306 248065 p->buffer += size;
307 248065 return size;
308 }
309
310 static av_always_inline void bytestream2_set_buffer(PutByteContext *p,
311 const uint8_t c,
312 unsigned int size)
313 {
314 unsigned int size2;
315 if (p->eof)
316 return;
317 size2 = FFMIN(p->buffer_end - p->buffer, size);
318 if (size2 != size)
319 p->eof = 1;
320 memset(p->buffer, c, size2);
321 p->buffer += size2;
322 }
323
324 static av_always_inline void bytestream2_set_bufferu(PutByteContext *p,
325 const uint8_t c,
326 unsigned int size)
327 {
328 memset(p->buffer, c, size);
329 p->buffer += size;
330 }
331
332 4450 static av_always_inline unsigned int bytestream2_get_eof(PutByteContext *p)
333 {
334 4450 return p->eof;
335 }
336
337 8 static av_always_inline unsigned int bytestream2_copy_bufferu(PutByteContext *p,
338 GetByteContext *g,
339 unsigned int size)
340 {
341 8 memcpy(p->buffer, g->buffer, size);
342 8 p->buffer += size;
343 8 g->buffer += size;
344 8 return size;
345 }
346
347 8 static av_always_inline unsigned int bytestream2_copy_buffer(PutByteContext *p,
348 GetByteContext *g,
349 unsigned int size)
350 {
351 unsigned int size2;
352
353
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 if (p->eof)
354 ✗ return 0;
355 8 size = FFMIN(g->buffer_end - g->buffer, size);
356 8 size2 = FFMIN(p->buffer_end - p->buffer, size);
357
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 if (size2 != size)
358 ✗ p->eof = 1;
359
360 8 return bytestream2_copy_bufferu(p, g, size2);
361 }
362
363 550 static av_always_inline unsigned int bytestream_get_buffer(const uint8_t **b,
364 uint8_t *dst,
365 unsigned int size)
366 {
367 550 memcpy(dst, *b, size);
368 550 (*b) += size;
369 550 return size;
370 }
371
372 3519122 static av_always_inline void bytestream_put_buffer(uint8_t **b,
373 const uint8_t *src,
374 unsigned int size)
375 {
376 3519122 memcpy(*b, src, size);
377 3519122 (*b) += size;
378 3519122 }
379
380 #endif /* AVCODEC_BYTESTREAM_H */
381