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 |