FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavcodec/bytestream.h
Date: 2024-11-20 23:03:26
Exec Total Coverage
Lines: 100 118 84.7%
Functions: 79 84 94.0%
Branches: 38 62 61.3%

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(GetByteContext *g) \
81 { \
82 return read(g->buffer); \
83 } \
84 static av_always_inline type bytestream2_peek_ ## name(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 34565 times.
✓ Branch 1 taken 508426 times.
✓ Branch 2 taken 34562 times.
✗ Branch 3 not taken.
3084755 DEF(uint64_t, le64, 8, AV_RL64, AV_WL64)
92
3/4
✓ Branch 0 taken 124356 times.
✓ Branch 1 taken 8027338 times.
✓ Branch 2 taken 124356 times.
✗ Branch 3 not taken.
139518386 DEF(unsigned int, le32, 4, AV_RL32, AV_WL32)
93
3/4
✓ Branch 0 taken 169 times.
✓ Branch 1 taken 404 times.
✓ Branch 2 taken 169 times.
✗ Branch 3 not taken.
141394948 DEF(unsigned int, le24, 3, AV_RL24, AV_WL24)
94
3/4
✓ Branch 0 taken 7942 times.
✓ Branch 1 taken 9507529 times.
✓ Branch 2 taken 7939 times.
✗ Branch 3 not taken.
466785216 DEF(unsigned int, le16, 2, AV_RL16, AV_WL16)
95
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7612 times.
2500328 DEF(uint64_t, be64, 8, AV_RB64, AV_WB64)
96
3/4
✓ Branch 0 taken 214111 times.
✓ Branch 1 taken 433031 times.
✓ Branch 2 taken 214096 times.
✗ Branch 3 not taken.
24541800 DEF(unsigned int, be32, 4, AV_RB32, AV_WB32)
97
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 68370 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
25944267 DEF(unsigned int, be24, 3, AV_RB24, AV_WB24)
98
3/4
✓ Branch 0 taken 7381400 times.
✓ Branch 1 taken 2437089 times.
✓ Branch 2 taken 7381396 times.
✗ Branch 3 not taken.
292585145 DEF(unsigned int, be16, 2, AV_RB16, AV_WB16)
99
3/4
✓ Branch 0 taken 22218640 times.
✓ Branch 1 taken 80896088 times.
✓ Branch 2 taken 22218639 times.
✗ Branch 3 not taken.
737197741 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 233379 static av_always_inline void bytestream2_init(GetByteContext *g,
138 const uint8_t *buf,
139 int buf_size)
140 {
141
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 233379 times.
233379 av_assert0(buf_size >= 0);
142 233379 g->buffer = buf;
143 233379 g->buffer_start = buf;
144 233379 g->buffer_end = buf + buf_size;
145 233379 }
146
147 17306 static av_always_inline void bytestream2_init_writer(PutByteContext *p,
148 uint8_t *buf,
149 int buf_size)
150 {
151
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 17306 times.
17306 av_assert0(buf_size >= 0);
152 17306 p->buffer = buf;
153 17306 p->buffer_start = buf;
154 17306 p->buffer_end = buf + buf_size;
155 17306 p->eof = 0;
156 17306 }
157
158 33793886 static av_always_inline int bytestream2_get_bytes_left(GetByteContext *g)
159 {
160 33793886 return g->buffer_end - g->buffer;
161 }
162
163 94993 static av_always_inline int bytestream2_get_bytes_left_p(PutByteContext *p)
164 {
165 94993 return p->buffer_end - p->buffer;
166 }
167
168 1129034 static av_always_inline void bytestream2_skip(GetByteContext *g,
169 unsigned int size)
170 {
171
2/2
✓ Branch 0 taken 1049416 times.
✓ Branch 1 taken 79618 times.
1129034 g->buffer += FFMIN(g->buffer_end - g->buffer, size);
172 1129034 }
173
174 82937 static av_always_inline void bytestream2_skipu(GetByteContext *g,
175 unsigned int size)
176 {
177 82937 g->buffer += size;
178 82937 }
179
180 40 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 40 times.
40 if (p->eof)
185 return;
186 40 size2 = FFMIN(p->buffer_end - p->buffer, size);
187
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 40 times.
40 if (size2 != size)
188 p->eof = 1;
189 40 p->buffer += size2;
190 }
191
192 4421501 static av_always_inline int bytestream2_tell(GetByteContext *g)
193 {
194 4421501 return (int)(g->buffer - g->buffer_start);
195 }
196
197 149642 static av_always_inline int bytestream2_tell_p(PutByteContext *p)
198 {
199 149642 return (int)(p->buffer - p->buffer_start);
200 }
201
202 1176 static av_always_inline int bytestream2_size(GetByteContext *g)
203 {
204 1176 return (int)(g->buffer_end - g->buffer_start);
205 }
206
207 static av_always_inline int bytestream2_size_p(PutByteContext *p)
208 {
209 return (int)(p->buffer_end - p->buffer_start);
210 }
211
212 778942 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 1007 times.
✓ Branch 2 taken 776739 times.
✗ Branch 3 not taken.
778942 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 1007 case SEEK_END:
223 1007 offset = av_clip(offset, -(g->buffer_end - g->buffer_start), 0);
224 1007 g->buffer = g->buffer_end + offset;
225 1007 break;
226 776739 case SEEK_SET:
227 776739 offset = av_clip(offset, 0, g->buffer_end - g->buffer_start);
228 776739 g->buffer = g->buffer_start + offset;
229 776739 break;
230 default:
231 return AVERROR(EINVAL);
232 }
233 778942 return bytestream2_tell(g);
234 }
235
236 10926 static av_always_inline int bytestream2_seek_p(PutByteContext *p,
237 int offset,
238 int whence)
239 {
240 10926 p->eof = 0;
241
2/4
✓ Branch 0 taken 7050 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3876 times.
✗ Branch 3 not taken.
10926 switch (whence) {
242 7050 case SEEK_CUR:
243
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7050 times.
7050 if (p->buffer_end - p->buffer < offset)
244 p->eof = 1;
245 7050 offset = av_clip(offset, -(p->buffer - p->buffer_start),
246 7050 p->buffer_end - p->buffer);
247 7050 p->buffer += offset;
248 7050 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 3876 case SEEK_SET:
256
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3876 times.
3876 if (p->buffer_end - p->buffer_start < offset)
257 p->eof = 1;
258 3876 offset = av_clip(offset, 0, p->buffer_end - p->buffer_start);
259 3876 p->buffer = p->buffer_start + offset;
260 3876 break;
261 default:
262 return AVERROR(EINVAL);
263 }
264 10926 return bytestream2_tell_p(p);
265 }
266
267 817494 static av_always_inline unsigned int bytestream2_get_buffer(GetByteContext *g,
268 uint8_t *dst,
269 unsigned int size)
270 {
271 817494 unsigned int size2 = FFMIN(g->buffer_end - g->buffer, size);
272 817494 memcpy(dst, g->buffer, size2);
273 817494 g->buffer += size2;
274 817494 return size2;
275 }
276
277 3495141 static av_always_inline unsigned int bytestream2_get_bufferu(GetByteContext *g,
278 uint8_t *dst,
279 unsigned int size)
280 {
281 3495141 memcpy(dst, g->buffer, size);
282 3495141 g->buffer += size;
283 3495141 return size;
284 }
285
286 57184 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 57184 times.
57184 if (p->eof)
292 return 0;
293 57184 size2 = FFMIN(p->buffer_end - p->buffer, size);
294
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 57184 times.
57184 if (size2 != size)
295 p->eof = 1;
296 57184 memcpy(p->buffer, src, size2);
297 57184 p->buffer += size2;
298 57184 return size2;
299 }
300
301 static av_always_inline unsigned int bytestream2_put_bufferu(PutByteContext *p,
302 const uint8_t *src,
303 unsigned int size)
304 {
305 memcpy(p->buffer, src, size);
306 p->buffer += size;
307 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 3885 static av_always_inline unsigned int bytestream2_get_eof(PutByteContext *p)
333 {
334 3885 return p->eof;
335 }
336
337 static av_always_inline unsigned int bytestream2_copy_bufferu(PutByteContext *p,
338 GetByteContext *g,
339 unsigned int size)
340 {
341 memcpy(p->buffer, g->buffer, size);
342 p->buffer += size;
343 g->buffer += size;
344 return size;
345 }
346
347 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 if (p->eof)
354 return 0;
355 size = FFMIN(g->buffer_end - g->buffer, size);
356 size2 = FFMIN(p->buffer_end - p->buffer, size);
357 if (size2 != size)
358 p->eof = 1;
359
360 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 3519049 static av_always_inline void bytestream_put_buffer(uint8_t **b,
373 const uint8_t *src,
374 unsigned int size)
375 {
376 3519049 memcpy(*b, src, size);
377 3519049 (*b) += size;
378 3519049 }
379
380 #endif /* AVCODEC_BYTESTREAM_H */
381