FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavformat/aviobuf.c
Date: 2026-04-24 19:58:39
Exec Total Coverage
Lines: 740 850 87.1%
Functions: 86 88 97.7%
Branches: 430 606 71.0%

Line Branch Exec Source
1 /*
2 * buffered I/O
3 * Copyright (c) 2000,2001 Fabrice Bellard
4 *
5 * This file is part of FFmpeg.
6 *
7 * FFmpeg is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * FFmpeg is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with FFmpeg; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
22 #include "libavutil/bprint.h"
23 #include "libavutil/crc.h"
24 #include "libavutil/dict.h"
25 #include "libavutil/intreadwrite.h"
26 #include "libavutil/log.h"
27 #include "libavutil/mem.h"
28 #include "libavutil/opt.h"
29 #include "libavutil/avassert.h"
30 #include "libavcodec/defs.h"
31 #include "avio.h"
32 #include "avio_internal.h"
33 #include "internal.h"
34 #include <stdarg.h>
35
36 #define IO_BUFFER_SIZE 32768
37
38 /**
39 * Do seeks within this distance ahead of the current buffer by skipping
40 * data instead of calling the protocol seek function, for seekable
41 * protocols.
42 */
43 #define SHORT_SEEK_THRESHOLD 32768
44
45 static void fill_buffer(AVIOContext *s);
46 static int url_resetbuf(AVIOContext *s, int flags);
47 /** @warning must be called before any I/O */
48 static int set_buf_size(AVIOContext *s, int buf_size);
49
50 242525 void ffio_init_context(FFIOContext *ctx,
51 unsigned char *buffer,
52 int buffer_size,
53 int write_flag,
54 void *opaque,
55 int (*read_packet)(void *opaque, uint8_t *buf, int buf_size),
56 int (*write_packet)(void *opaque, const uint8_t *buf, int buf_size),
57 int64_t (*seek)(void *opaque, int64_t offset, int whence))
58 {
59 242525 AVIOContext *const s = &ctx->pub;
60
61 242525 memset(ctx, 0, sizeof(*ctx));
62
63 242525 s->buffer = buffer;
64 242525 ctx->orig_buffer_size =
65 242525 s->buffer_size = buffer_size;
66 242525 s->buf_ptr = buffer;
67 242525 s->buf_ptr_max = buffer;
68 242525 s->opaque = opaque;
69 242525 s->direct = 0;
70
71
2/2
✓ Branch 0 taken 51851 times.
✓ Branch 1 taken 190674 times.
242525 url_resetbuf(s, write_flag ? AVIO_FLAG_WRITE : AVIO_FLAG_READ);
72
73 242525 s->write_packet = write_packet;
74 242525 s->read_packet = read_packet;
75 242525 s->seek = seek;
76 242525 s->pos = 0;
77 242525 s->eof_reached = 0;
78 242525 s->error = 0;
79 242525 s->seekable = seek ? AVIO_SEEKABLE_NORMAL : 0;
80 242525 s->min_packet_size = 0;
81 242525 s->max_packet_size = 0;
82 242525 s->update_checksum = NULL;
83 242525 ctx->short_seek_threshold = SHORT_SEEK_THRESHOLD;
84
85
4/4
✓ Branch 0 taken 126028 times.
✓ Branch 1 taken 116497 times.
✓ Branch 2 taken 83516 times.
✓ Branch 3 taken 42512 times.
242525 if (!read_packet && !write_flag) {
86 83516 s->pos = buffer_size;
87 83516 s->buf_end = s->buffer + buffer_size;
88 }
89 242525 s->read_pause = NULL;
90 242525 s->read_seek = NULL;
91
92 242525 s->write_data_type = NULL;
93 242525 s->ignore_boundary_point = 0;
94 242525 ctx->current_type = AVIO_DATA_MARKER_UNKNOWN;
95 242525 ctx->last_time = AV_NOPTS_VALUE;
96 242525 ctx->short_seek_get = NULL;
97 242525 }
98
99 83314 void ffio_init_read_context(FFIOContext *s, const uint8_t *buffer, int buffer_size)
100 {
101 83314 ffio_init_context(s, (unsigned char*)buffer, buffer_size, 0, NULL, NULL, NULL, NULL);
102 83314 }
103
104 224 void ffio_init_write_context(FFIOContext *s, uint8_t *buffer, int buffer_size)
105 {
106 224 ffio_init_context(s, buffer, buffer_size, 1, NULL, NULL, NULL, NULL);
107 224 }
108
109 116511 AVIOContext *avio_alloc_context(
110 unsigned char *buffer,
111 int buffer_size,
112 int write_flag,
113 void *opaque,
114 int (*read_packet)(void *opaque, uint8_t *buf, int buf_size),
115 int (*write_packet)(void *opaque, const uint8_t *buf, int buf_size),
116 int64_t (*seek)(void *opaque, int64_t offset, int whence))
117 {
118 116511 FFIOContext *s = av_malloc(sizeof(*s));
119
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 116511 times.
116511 if (!s)
120 return NULL;
121 116511 ffio_init_context(s, buffer, buffer_size, write_flag, opaque,
122 read_packet, write_packet, seek);
123 116511 return &s->pub;
124 }
125
126 137023 void avio_context_free(AVIOContext **ps)
127 {
128 137023 AVIOContext *s = *ps;
129
2/2
✓ Branch 0 taken 137021 times.
✓ Branch 1 taken 2 times.
137023 if (s) {
130 137021 av_freep(&s->protocol_whitelist);
131 137021 av_freep(&s->protocol_blacklist);
132 }
133 137023 av_freep(ps);
134 137023 }
135
136 437659 static void writeout(AVIOContext *s, const uint8_t *data, int len)
137 {
138 437659 FFIOContext *const ctx = ffiocontext(s);
139
1/2
✓ Branch 0 taken 437659 times.
✗ Branch 1 not taken.
437659 if (!s->error) {
140 437659 int ret = 0;
141
2/2
✓ Branch 0 taken 126 times.
✓ Branch 1 taken 437533 times.
437659 if (s->write_data_type)
142 126 ret = s->write_data_type(s->opaque, data,
143 len,
144 ctx->current_type,
145 ctx->last_time);
146
2/2
✓ Branch 0 taken 437520 times.
✓ Branch 1 taken 13 times.
437533 else if (s->write_packet)
147 437520 ret = s->write_packet(s->opaque, data, len);
148
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 437659 times.
437659 if (ret < 0) {
149 s->error = ret;
150 } else {
151 437659 ctx->bytes_written += len;
152 437659 s->bytes_written = ctx->bytes_written;
153
154
2/2
✓ Branch 0 taken 435803 times.
✓ Branch 1 taken 1856 times.
437659 if (s->pos + len > ctx->written_output_size) {
155 435803 ctx->written_output_size = s->pos + len;
156 }
157 }
158 }
159
2/2
✓ Branch 0 taken 437612 times.
✓ Branch 1 taken 47 times.
437659 if (ctx->current_type == AVIO_DATA_MARKER_SYNC_POINT ||
160
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 437607 times.
437612 ctx->current_type == AVIO_DATA_MARKER_BOUNDARY_POINT) {
161 52 ctx->current_type = AVIO_DATA_MARKER_UNKNOWN;
162 }
163 437659 ctx->last_time = AV_NOPTS_VALUE;
164 437659 ctx->writeout_count++;
165 437659 s->pos += len;
166 437659 }
167
168 575109 static void flush_buffer(AVIOContext *s)
169 {
170 575109 s->buf_ptr_max = FFMAX(s->buf_ptr, s->buf_ptr_max);
171
4/4
✓ Branch 0 taken 467977 times.
✓ Branch 1 taken 107132 times.
✓ Branch 2 taken 430409 times.
✓ Branch 3 taken 37568 times.
575109 if (s->write_flag && s->buf_ptr_max > s->buffer) {
172 430409 writeout(s, s->buffer, s->buf_ptr_max - s->buffer);
173
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 430409 times.
430409 if (s->update_checksum) {
174 s->checksum = s->update_checksum(s->checksum, s->checksum_ptr,
175 s->buf_ptr_max - s->checksum_ptr);
176 s->checksum_ptr = s->buffer;
177 }
178 }
179 575109 s->buf_ptr = s->buf_ptr_max = s->buffer;
180
2/2
✓ Branch 0 taken 107132 times.
✓ Branch 1 taken 467977 times.
575109 if (!s->write_flag)
181 107132 s->buf_end = s->buffer;
182 575109 }
183
184 3619324 void avio_w8(AVIOContext *s, int b)
185 {
186 av_assert2(b>=-128 && b<=255);
187 3619324 *s->buf_ptr++ = b;
188
2/2
✓ Branch 0 taken 67 times.
✓ Branch 1 taken 3619257 times.
3619324 if (s->buf_ptr >= s->buf_end)
189 67 flush_buffer(s);
190 3619324 }
191
192 33834 void ffio_fill(AVIOContext *s, int b, int64_t count)
193 {
194
2/2
✓ Branch 0 taken 21463 times.
✓ Branch 1 taken 33834 times.
55297 while (count > 0) {
195 21463 int len = FFMIN(s->buf_end - s->buf_ptr, count);
196 21463 memset(s->buf_ptr, b, len);
197 21463 s->buf_ptr += len;
198
199
2/2
✓ Branch 0 taken 195 times.
✓ Branch 1 taken 21268 times.
21463 if (s->buf_ptr >= s->buf_end)
200 195 flush_buffer(s);
201
202 21463 count -= len;
203 }
204 33834 }
205
206 905980 void avio_write(AVIOContext *s, const unsigned char *buf, int size)
207 {
208
2/2
✓ Branch 0 taken 9053 times.
✓ Branch 1 taken 896927 times.
905980 if (size <= 0)
209 9053 return;
210
3/4
✓ Branch 0 taken 7250 times.
✓ Branch 1 taken 889677 times.
✓ Branch 2 taken 7250 times.
✗ Branch 3 not taken.
896927 if (s->direct && !s->update_checksum) {
211 7250 avio_flush(s);
212 7250 writeout(s, buf, size);
213 7250 return;
214 }
215 do {
216 1051333 int len = FFMIN(s->buf_end - s->buf_ptr, size);
217 1051333 memcpy(s->buf_ptr, buf, len);
218 1051333 s->buf_ptr += len;
219
220
2/2
✓ Branch 0 taken 162547 times.
✓ Branch 1 taken 888786 times.
1051333 if (s->buf_ptr >= s->buf_end)
221 162547 flush_buffer(s);
222
223 1051333 buf += len;
224 1051333 size -= len;
225
2/2
✓ Branch 0 taken 161656 times.
✓ Branch 1 taken 889677 times.
1051333 } while (size > 0);
226 }
227
228 409314 void avio_flush(AVIOContext *s)
229 {
230
2/2
✓ Branch 0 taken 302182 times.
✓ Branch 1 taken 107132 times.
409314 int seekback = s->write_flag ? FFMIN(0, s->buf_ptr - s->buf_ptr_max) : 0;
231 409314 flush_buffer(s);
232
2/2
✓ Branch 0 taken 127 times.
✓ Branch 1 taken 409187 times.
409314 if (seekback)
233 127 avio_seek(s, seekback, SEEK_CUR);
234 409314 }
235
236 3999830 int64_t avio_seek(AVIOContext *s, int64_t offset, int whence)
237 {
238 3999830 FFIOContext *const ctx = ffiocontext(s);
239 int64_t offset1;
240 int64_t pos;
241 int buffer_size;
242 int short_seek;
243 3999830 whence &= ~AVSEEK_FORCE; // force flag does nothing
244
245
2/2
✓ Branch 0 taken 12725 times.
✓ Branch 1 taken 3987105 times.
3999830 if(!s)
246 12725 return AVERROR(EINVAL);
247
248
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3987105 times.
3987105 if ((whence & AVSEEK_SIZE))
249 return s->seek ? s->seek(s->opaque, offset, AVSEEK_SIZE) : AVERROR(ENOSYS);
250
251 3987105 buffer_size = s->buf_end - s->buffer;
252 // pos is the absolute position that the beginning of s->buffer corresponds to in the file
253
2/2
✓ Branch 0 taken 3679556 times.
✓ Branch 1 taken 307549 times.
3987105 pos = s->pos - (s->write_flag ? 0 : buffer_size);
254
255
3/4
✓ Branch 0 taken 215119 times.
✓ Branch 1 taken 3771986 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 215119 times.
3987105 if (whence != SEEK_CUR && whence != SEEK_SET)
256 return AVERROR(EINVAL);
257
258
2/2
✓ Branch 0 taken 3771986 times.
✓ Branch 1 taken 215119 times.
3987105 if (whence == SEEK_CUR) {
259 3771986 offset1 = pos + (s->buf_ptr - s->buffer);
260
2/2
✓ Branch 0 taken 3616541 times.
✓ Branch 1 taken 155445 times.
3771986 if (offset == 0)
261 3616541 return offset1;
262
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 155445 times.
155445 if (offset > INT64_MAX - offset1)
263 return AVERROR(EINVAL);
264 155445 offset += offset1;
265 }
266
2/2
✓ Branch 0 taken 54 times.
✓ Branch 1 taken 370510 times.
370564 if (offset < 0)
267 54 return AVERROR(EINVAL);
268
269 370510 short_seek = ctx->short_seek_threshold;
270
2/2
✓ Branch 0 taken 353957 times.
✓ Branch 1 taken 16553 times.
370510 if (ctx->short_seek_get) {
271 353957 int tmp = ctx->short_seek_get(s->opaque);
272 353957 short_seek = FFMAX(tmp, short_seek);
273 }
274
275 370510 offset1 = offset - pos; // "offset1" is the relative offset from the beginning of s->buffer
276 370510 s->buf_ptr_max = FFMAX(s->buf_ptr_max, s->buf_ptr);
277
5/6
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 370501 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 9 times.
✓ Branch 4 taken 362695 times.
✓ Branch 5 taken 7806 times.
370510 if ((!s->direct || !s->seek) &&
278
4/4
✓ Branch 0 taken 29841 times.
✓ Branch 1 taken 332854 times.
✓ Branch 2 taken 356144 times.
✓ Branch 3 taken 6551 times.
362695 offset1 >= 0 && offset1 <= (s->write_flag ? s->buf_ptr_max - s->buffer : buffer_size)) {
279 /* can do the seek inside the buffer */
280 356144 s->buf_ptr = s->buffer + offset1;
281
2/2
✓ Branch 0 taken 14359 times.
✓ Branch 1 taken 7 times.
14366 } else if ((!(s->seekable & AVIO_SEEKABLE_NORMAL) ||
282
2/2
✓ Branch 0 taken 10383 times.
✓ Branch 1 taken 3976 times.
14359 offset1 <= buffer_size + short_seek) &&
283
4/4
✓ Branch 0 taken 8349 times.
✓ Branch 1 taken 2041 times.
✓ Branch 2 taken 2315 times.
✓ Branch 3 taken 6034 times.
10390 !s->write_flag && offset1 >= 0 &&
284
3/4
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 2308 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 7 times.
2315 (!s->direct || !s->seek)) {
285
4/4
✓ Branch 0 taken 2476 times.
✓ Branch 1 taken 2218 times.
✓ Branch 2 taken 2386 times.
✓ Branch 3 taken 90 times.
4694 while(s->pos < offset && !s->eof_reached)
286 2386 fill_buffer(s);
287
2/2
✓ Branch 0 taken 90 times.
✓ Branch 1 taken 2218 times.
2308 if (s->eof_reached)
288 90 return AVERROR_EOF;
289 2218 s->buf_ptr = s->buf_end - (s->pos - offset);
290
10/10
✓ Branch 0 taken 9072 times.
✓ Branch 1 taken 2986 times.
✓ Branch 2 taken 6034 times.
✓ Branch 3 taken 3038 times.
✓ Branch 4 taken 548 times.
✓ Branch 5 taken 5486 times.
✓ Branch 6 taken 546 times.
✓ Branch 7 taken 2 times.
✓ Branch 8 taken 536 times.
✓ Branch 9 taken 10 times.
12058 } else if(!s->write_flag && offset1 < 0 && -offset1 < buffer_size>>1 && s->seek && offset > 0) {
291 int64_t res;
292
293 536 pos -= FFMIN(buffer_size>>1, pos);
294
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 536 times.
536 if ((res = s->seek(s->opaque, pos, SEEK_SET)) < 0)
295 return res;
296 536 s->buf_end =
297 536 s->buf_ptr = s->buffer;
298 536 s->pos = pos;
299 536 s->eof_reached = 0;
300 536 fill_buffer(s);
301 536 return avio_seek(s, offset, SEEK_SET);
302 } else {
303 int64_t res;
304
2/2
✓ Branch 0 taken 2986 times.
✓ Branch 1 taken 8536 times.
11522 if (s->write_flag) {
305 2986 flush_buffer(s);
306 }
307
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 11520 times.
11522 if (!s->seek)
308 2 return AVERROR(EPIPE);
309
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 11520 times.
11520 if ((res = s->seek(s->opaque, offset, SEEK_SET)) < 0)
310 return res;
311 11520 ctx->seek_count++;
312
2/2
✓ Branch 0 taken 8534 times.
✓ Branch 1 taken 2986 times.
11520 if (!s->write_flag)
313 8534 s->buf_end = s->buffer;
314 11520 s->checksum_ptr = s->buf_ptr = s->buf_ptr_max = s->buffer;
315 11520 s->pos = offset;
316 }
317 369882 s->eof_reached = 0;
318 369882 return offset;
319 }
320
321 161393 int64_t avio_skip(AVIOContext *s, int64_t offset)
322 {
323 161393 return avio_seek(s, offset, SEEK_CUR);
324 }
325
326 711575 int64_t avio_size(AVIOContext *s)
327 {
328 711575 FFIOContext *const ctx = ffiocontext(s);
329 int64_t size;
330
331
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 711575 times.
711575 if (!s)
332 return AVERROR(EINVAL);
333
334
2/2
✓ Branch 0 taken 440108 times.
✓ Branch 1 taken 271467 times.
711575 if (ctx->written_output_size)
335 440108 return ctx->written_output_size;
336
337
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 271465 times.
271467 if (!s->seek)
338 2 return AVERROR(ENOSYS);
339 271465 size = s->seek(s->opaque, 0, AVSEEK_SIZE);
340
2/2
✓ Branch 0 taken 14840 times.
✓ Branch 1 taken 256625 times.
271465 if (size < 0) {
341
2/2
✓ Branch 1 taken 14835 times.
✓ Branch 2 taken 5 times.
14840 if ((size = s->seek(s->opaque, -1, SEEK_END)) < 0)
342 14835 return size;
343 5 size++;
344 5 s->seek(s->opaque, s->pos, SEEK_SET);
345 }
346 256630 return size;
347 }
348
349 6412244 int avio_feof(AVIOContext *s)
350 {
351
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6412244 times.
6412244 if(!s)
352 return 0;
353
2/2
✓ Branch 0 taken 7569 times.
✓ Branch 1 taken 6404675 times.
6412244 if(s->eof_reached){
354 7569 s->eof_reached=0;
355 7569 fill_buffer(s);
356 }
357 6412244 return s->eof_reached;
358 }
359
360 543244 void avio_wl32(AVIOContext *s, unsigned int val)
361 {
362 543244 avio_w8(s, (uint8_t) val );
363 543244 avio_w8(s, (uint8_t)(val >> 8 ));
364 543244 avio_w8(s, (uint8_t)(val >> 16));
365 543244 avio_w8(s, val >> 24 );
366 543244 }
367
368 158481 void avio_wb32(AVIOContext *s, unsigned int val)
369 {
370 158481 avio_w8(s, val >> 24 );
371 158481 avio_w8(s, (uint8_t)(val >> 16));
372 158481 avio_w8(s, (uint8_t)(val >> 8 ));
373 158481 avio_w8(s, (uint8_t) val );
374 158481 }
375
376 511 int avio_put_str(AVIOContext *s, const char *str)
377 {
378 511 int len = 1;
379
1/2
✓ Branch 0 taken 511 times.
✗ Branch 1 not taken.
511 if (str) {
380 511 len += strlen(str);
381 511 avio_write(s, (const unsigned char *) str, len);
382 } else
383 avio_w8(s, 0);
384 511 return len;
385 }
386
387 178 static inline int put_str16(AVIOContext *s, const char *str, const int be)
388 {
389 178 const uint8_t *q = str;
390 178 int ret = 0;
391 178 int err = 0;
392
393
2/2
✓ Branch 0 taken 1241 times.
✓ Branch 1 taken 178 times.
1419 while (*q) {
394 uint32_t ch;
395 uint16_t tmp16;
396
397
5/8
✓ Branch 0 taken 1241 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1241 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 32 times.
✓ Branch 6 taken 32 times.
✓ Branch 7 taken 1241 times.
1273 GET_UTF8(ch, *q++, goto invalid;)
398
3/8
✓ Branch 0 taken 1241 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 918 times.
✓ Branch 3 taken 323 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
1241 PUT_UTF16(ch, tmp16, be ? avio_wb16(s, tmp16) : avio_wl16(s, tmp16);
399 ret += 2;)
400 1241 continue;
401 invalid:
402 av_log(s, AV_LOG_ERROR, "Invalid UTF8 sequence in avio_put_str16%s\n", be ? "be" : "le");
403 err = AVERROR(EINVAL);
404 if (!*(q-1))
405 break;
406 }
407
2/2
✓ Branch 0 taken 144 times.
✓ Branch 1 taken 34 times.
178 if (be)
408 144 avio_wb16(s, 0);
409 else
410 34 avio_wl16(s, 0);
411
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 178 times.
178 if (err)
412 return err;
413 178 ret += 2;
414 178 return ret;
415 }
416
417 #define PUT_STR16(type, big_endian) \
418 int avio_put_str16 ## type(AVIOContext *s, const char *str) \
419 { \
420 return put_str16(s, str, big_endian); \
421 }
422
423 34 PUT_STR16(le, 0)
424 144 PUT_STR16(be, 1)
425
426 #undef PUT_STR16
427
428 1047 void avio_wl64(AVIOContext *s, uint64_t val)
429 {
430 1047 avio_wl32(s, (uint32_t)(val & 0xffffffff));
431 1047 avio_wl32(s, (uint32_t)(val >> 32));
432 1047 }
433
434 26910 void avio_wb64(AVIOContext *s, uint64_t val)
435 {
436 26910 avio_wb32(s, (uint32_t)(val >> 32));
437 26910 avio_wb32(s, (uint32_t)(val & 0xffffffff));
438 26910 }
439
440 28484 void avio_wl16(AVIOContext *s, unsigned int val)
441 {
442 28484 avio_w8(s, (uint8_t)val);
443 28484 avio_w8(s, (int)val >> 8);
444 28484 }
445
446 87441 void avio_wb16(AVIOContext *s, unsigned int val)
447 {
448 87441 avio_w8(s, (int)val >> 8);
449 87441 avio_w8(s, (uint8_t)val);
450 87441 }
451
452 22 void avio_wl24(AVIOContext *s, unsigned int val)
453 {
454 22 avio_wl16(s, val & 0xffff);
455 22 avio_w8(s, (int)val >> 16);
456 22 }
457
458 12726 void avio_wb24(AVIOContext *s, unsigned int val)
459 {
460 12726 avio_wb16(s, (int)val >> 8);
461 12726 avio_w8(s, (uint8_t)val);
462 12726 }
463
464 629986 void avio_write_marker(AVIOContext *s, int64_t time, enum AVIODataMarkerType type)
465 {
466 629986 FFIOContext *const ctx = ffiocontext(s);
467
2/2
✓ Branch 0 taken 608228 times.
✓ Branch 1 taken 21758 times.
629986 if (type == AVIO_DATA_MARKER_FLUSH_POINT) {
468
2/2
✓ Branch 0 taken 268461 times.
✓ Branch 1 taken 339767 times.
608228 if (s->buf_ptr - s->buffer >= s->min_packet_size)
469 268461 avio_flush(s);
470 608228 return;
471 }
472
2/2
✓ Branch 0 taken 21575 times.
✓ Branch 1 taken 183 times.
21758 if (!s->write_data_type)
473 21575 return;
474 // If ignoring boundary points, just treat it as unknown
475
3/4
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 178 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 5 times.
183 if (type == AVIO_DATA_MARKER_BOUNDARY_POINT && s->ignore_boundary_point)
476 type = AVIO_DATA_MARKER_UNKNOWN;
477 // Avoid unnecessary flushes if we are already in non-header/trailer
478 // data and setting the type to unknown
479
2/2
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 155 times.
183 if (type == AVIO_DATA_MARKER_UNKNOWN &&
480
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 28 times.
28 (ctx->current_type != AVIO_DATA_MARKER_HEADER &&
481 ctx->current_type != AVIO_DATA_MARKER_TRAILER))
482 return;
483
484
2/2
✓ Branch 0 taken 103 times.
✓ Branch 1 taken 80 times.
183 switch (type) {
485 103 case AVIO_DATA_MARKER_HEADER:
486 case AVIO_DATA_MARKER_TRAILER:
487 // For header/trailer, ignore a new marker of the same type;
488 // consecutive header/trailer markers can be merged.
489
2/2
✓ Branch 0 taken 11 times.
✓ Branch 1 taken 92 times.
103 if (type == ctx->current_type)
490 11 return;
491 92 break;
492 }
493
494 // If we've reached here, we have a new, noteworthy marker.
495 // Flush the previous data and mark the start of the new data.
496 172 avio_flush(s);
497 172 ctx->current_type = type;
498 172 ctx->last_time = time;
499 }
500
501 224488 static int read_packet_wrapper(AVIOContext *s, uint8_t *buf, int size)
502 {
503 int ret;
504
505
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 224483 times.
224488 if (!s->read_packet)
506 5 return AVERROR(EINVAL);
507 224483 ret = s->read_packet(s->opaque, buf, size);
508 av_assert2(ret || s->max_packet_size);
509 224483 return ret;
510 }
511
512 /* Input stream */
513
514 98204 static void fill_buffer(AVIOContext *s)
515 {
516 98204 FFIOContext *const ctx = (FFIOContext *)s;
517 196408 int max_buffer_size = s->max_packet_size ?
518
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 98204 times.
98204 s->max_packet_size : IO_BUFFER_SIZE;
519
2/2
✓ Branch 0 taken 24503 times.
✓ Branch 1 taken 73701 times.
98204 uint8_t *dst = s->buf_end - s->buffer + max_buffer_size <= s->buffer_size ?
520 s->buf_end : s->buffer;
521 98204 int len = s->buffer_size - (dst - s->buffer);
522
523 /* can't fill the buffer without read_packet, just set EOF if appropriate */
524
4/4
✓ Branch 0 taken 11 times.
✓ Branch 1 taken 98193 times.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 5 times.
98204 if (!s->read_packet && s->buf_ptr >= s->buf_end)
525 6 s->eof_reached = 1;
526
527 /* no need to do anything if EOF already reached */
528
2/2
✓ Branch 0 taken 11237 times.
✓ Branch 1 taken 86967 times.
98204 if (s->eof_reached)
529 11237 return;
530
531
3/4
✓ Branch 0 taken 335 times.
✓ Branch 1 taken 86632 times.
✓ Branch 2 taken 335 times.
✗ Branch 3 not taken.
86967 if (s->update_checksum && dst == s->buffer) {
532
2/2
✓ Branch 0 taken 264 times.
✓ Branch 1 taken 71 times.
335 if (s->buf_end > s->checksum_ptr)
533 264 s->checksum = s->update_checksum(s->checksum, s->checksum_ptr,
534 264 s->buf_end - s->checksum_ptr);
535 335 s->checksum_ptr = s->buffer;
536 }
537
538 /* make buffer smaller in case it ended up large after probing */
539
3/4
✓ Branch 0 taken 86962 times.
✓ Branch 1 taken 5 times.
✓ Branch 2 taken 86962 times.
✗ Branch 3 not taken.
86967 if (s->read_packet && ctx->orig_buffer_size &&
540
3/4
✓ Branch 0 taken 355 times.
✓ Branch 1 taken 86607 times.
✓ Branch 2 taken 355 times.
✗ Branch 3 not taken.
86962 s->buffer_size > ctx->orig_buffer_size && len >= ctx->orig_buffer_size) {
541
4/4
✓ Branch 0 taken 23 times.
✓ Branch 1 taken 332 times.
✓ Branch 2 taken 22 times.
✓ Branch 3 taken 1 times.
355 if (dst == s->buffer && s->buf_ptr != dst) {
542 22 int ret = set_buf_size(s, ctx->orig_buffer_size);
543
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 22 times.
22 if (ret < 0)
544 av_log(s, AV_LOG_WARNING, "Failed to decrease buffer size\n");
545
546 22 s->checksum_ptr = dst = s->buffer;
547 }
548 355 len = ctx->orig_buffer_size;
549 }
550
551 86967 len = read_packet_wrapper(s, dst, len);
552
2/2
✓ Branch 0 taken 12282 times.
✓ Branch 1 taken 74685 times.
86967 if (len == AVERROR_EOF) {
553 /* do not modify buffer if EOF reached so that a seek back can
554 be done without rereading data */
555 12282 s->eof_reached = 1;
556
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 74680 times.
74685 } else if (len < 0) {
557 5 s->eof_reached = 1;
558 5 s->error= len;
559 } else {
560 74680 s->pos += len;
561 74680 s->buf_ptr = dst;
562 74680 s->buf_end = dst + len;
563 74680 ffiocontext(s)->bytes_read += len;
564 74680 s->bytes_read = ffiocontext(s)->bytes_read;
565 }
566 }
567
568 34061 unsigned long ff_crc04C11DB7_update(unsigned long checksum, const uint8_t *buf,
569 unsigned int len)
570 {
571 34061 return av_crc(av_crc_get_table(AV_CRC_32_IEEE), checksum, buf, len);
572 }
573
574 9 unsigned long ff_crcEDB88320_update(unsigned long checksum, const uint8_t *buf,
575 unsigned int len)
576 {
577 9 return av_crc(av_crc_get_table(AV_CRC_32_IEEE_LE), checksum, buf, len);
578 }
579
580 74 unsigned long ff_crcA001_update(unsigned long checksum, const uint8_t *buf,
581 unsigned int len)
582 {
583 74 return av_crc(av_crc_get_table(AV_CRC_16_ANSI_LE), checksum, buf, len);
584 }
585
586 31165 unsigned long ffio_get_checksum(AVIOContext *s)
587 {
588 62330 s->checksum = s->update_checksum(s->checksum, s->checksum_ptr,
589 31165 s->buf_ptr - s->checksum_ptr);
590 31165 s->update_checksum = NULL;
591 31165 return s->checksum;
592 }
593
594 31253 void ffio_init_checksum(AVIOContext *s,
595 unsigned long (*update_checksum)(unsigned long c, const uint8_t *p, unsigned int len),
596 unsigned long checksum)
597 {
598 31253 s->update_checksum = update_checksum;
599
2/2
✓ Branch 0 taken 31224 times.
✓ Branch 1 taken 29 times.
31253 if (s->update_checksum) {
600 31224 s->checksum = checksum;
601 31224 s->checksum_ptr = s->buf_ptr;
602 }
603 31253 }
604
605 /* XXX: put an inline version */
606 11924320 int avio_r8(AVIOContext *s)
607 {
608
2/2
✓ Branch 0 taken 25566 times.
✓ Branch 1 taken 11898754 times.
11924320 if (s->buf_ptr >= s->buf_end)
609 25566 fill_buffer(s);
610
2/2
✓ Branch 0 taken 11912300 times.
✓ Branch 1 taken 12020 times.
11924320 if (s->buf_ptr < s->buf_end)
611 11912300 return *s->buf_ptr++;
612 12020 return 0;
613 }
614
615 738573 int avio_read(AVIOContext *s, unsigned char *buf, int size)
616 {
617 int len, size1;
618
619 738573 size1 = size;
620
2/2
✓ Branch 0 taken 807423 times.
✓ Branch 1 taken 736071 times.
1543494 while (size > 0) {
621 807423 len = FFMIN(s->buf_end - s->buf_ptr, size);
622
3/4
✓ Branch 0 taken 627867 times.
✓ Branch 1 taken 179556 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 627867 times.
807423 if (len == 0 || s->write_flag) {
623
7/8
✓ Branch 0 taken 179503 times.
✓ Branch 1 taken 53 times.
✓ Branch 2 taken 137477 times.
✓ Branch 3 taken 42026 times.
✓ Branch 4 taken 137521 times.
✓ Branch 5 taken 9 times.
✓ Branch 6 taken 137521 times.
✗ Branch 7 not taken.
179556 if((s->direct || size > s->buffer_size) && !s->update_checksum && s->read_packet) {
624 // bypass the buffer and read data directly into buf
625 137521 len = read_packet_wrapper(s, buf, size);
626
2/2
✓ Branch 0 taken 578 times.
✓ Branch 1 taken 136943 times.
137521 if (len == AVERROR_EOF) {
627 /* do not modify buffer if EOF reached so that a seek back can
628 be done without rereading data */
629 578 s->eof_reached = 1;
630 578 break;
631
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 136943 times.
136943 } else if (len < 0) {
632 s->eof_reached = 1;
633 s->error= len;
634 break;
635 } else {
636 136943 s->pos += len;
637 136943 ffiocontext(s)->bytes_read += len;
638 136943 s->bytes_read = ffiocontext(s)->bytes_read;
639 136943 size -= len;
640 136943 buf += len;
641 // reset the buffer
642 136943 s->buf_ptr = s->buffer;
643 136943 s->buf_end = s->buffer/* + len*/;
644 }
645 } else {
646 42035 fill_buffer(s);
647 42035 len = s->buf_end - s->buf_ptr;
648
2/2
✓ Branch 0 taken 1924 times.
✓ Branch 1 taken 40111 times.
42035 if (len == 0)
649 1924 break;
650 }
651 } else {
652 627867 memcpy(buf, s->buf_ptr, len);
653 627867 buf += len;
654 627867 s->buf_ptr += len;
655 627867 size -= len;
656 }
657 }
658
2/2
✓ Branch 0 taken 3479 times.
✓ Branch 1 taken 735094 times.
738573 if (size1 == size) {
659
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3479 times.
3479 if (s->error) return s->error;
660
2/2
✓ Branch 1 taken 1752 times.
✓ Branch 2 taken 1727 times.
3479 if (avio_feof(s)) return AVERROR_EOF;
661 }
662 736821 return size1 - size;
663 }
664
665 182842 int ffio_read_size(AVIOContext *s, unsigned char *buf, int size)
666 {
667 182842 int ret = avio_read(s, buf, size);
668
2/2
✓ Branch 0 taken 182765 times.
✓ Branch 1 taken 77 times.
182842 if (ret == size)
669 182765 return ret;
670
3/4
✓ Branch 0 taken 53 times.
✓ Branch 1 taken 24 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 53 times.
77 if (ret < 0 && ret != AVERROR_EOF)
671 return ret;
672 77 return AVERROR_INVALIDDATA;
673 }
674
675 456313 int ffio_read_indirect(AVIOContext *s, unsigned char *buf, int size, const unsigned char **data)
676 {
677
3/4
✓ Branch 0 taken 453130 times.
✓ Branch 1 taken 3183 times.
✓ Branch 2 taken 453130 times.
✗ Branch 3 not taken.
456313 if (s->buf_end - s->buf_ptr >= size && !s->write_flag) {
678 453130 *data = s->buf_ptr;
679 453130 s->buf_ptr += size;
680 453130 return size;
681 } else {
682 3183 *data = buf;
683 3183 return avio_read(s, buf, size);
684 }
685 }
686
687 592738 int avio_read_partial(AVIOContext *s, unsigned char *buf, int size)
688 {
689 int len;
690
691
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 592738 times.
592738 if (size < 0)
692 return AVERROR(EINVAL);
693
694
2/4
✓ Branch 0 taken 592738 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 592738 times.
592738 if (s->read_packet && s->write_flag) {
695 len = read_packet_wrapper(s, buf, size);
696 if (len > 0)
697 s->pos += len;
698 return len;
699 }
700
701 592738 len = s->buf_end - s->buf_ptr;
702
2/2
✓ Branch 0 taken 20112 times.
✓ Branch 1 taken 572626 times.
592738 if (len == 0) {
703 20112 fill_buffer(s);
704 20112 len = s->buf_end - s->buf_ptr;
705 }
706
2/2
✓ Branch 0 taken 572080 times.
✓ Branch 1 taken 20658 times.
592738 if (len > size)
707 572080 len = size;
708 592738 memcpy(buf, s->buf_ptr, len);
709 592738 s->buf_ptr += len;
710
2/2
✓ Branch 0 taken 1946 times.
✓ Branch 1 taken 590792 times.
592738 if (!len) {
711
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1946 times.
1946 if (s->error) return s->error;
712
1/2
✓ Branch 1 taken 1946 times.
✗ Branch 2 not taken.
1946 if (avio_feof(s)) return AVERROR_EOF;
713 }
714 590792 return len;
715 }
716
717 863883 unsigned int avio_rl16(AVIOContext *s)
718 {
719 unsigned int val;
720 863883 val = avio_r8(s);
721 863883 val |= avio_r8(s) << 8;
722 863883 return val;
723 }
724
725 336 unsigned int avio_rl24(AVIOContext *s)
726 {
727 unsigned int val;
728 336 val = avio_rl16(s);
729 336 val |= avio_r8(s) << 16;
730 336 return val;
731 }
732
733 413840 unsigned int avio_rl32(AVIOContext *s)
734 {
735 unsigned int val;
736 413840 val = avio_rl16(s);
737 413840 val |= avio_rl16(s) << 16;
738 413840 return val;
739 }
740
741 5371 uint64_t avio_rl64(AVIOContext *s)
742 {
743 uint64_t val;
744 5371 val = (uint64_t)avio_rl32(s);
745 5371 val |= (uint64_t)avio_rl32(s) << 32;
746 5371 return val;
747 }
748
749 1176168 unsigned int avio_rb16(AVIOContext *s)
750 {
751 unsigned int val;
752 1176168 val = avio_r8(s) << 8;
753 1176168 val |= avio_r8(s);
754 1176168 return val;
755 }
756
757 28006 unsigned int avio_rb24(AVIOContext *s)
758 {
759 unsigned int val;
760 28006 val = avio_rb16(s) << 8;
761 28006 val |= avio_r8(s);
762 28006 return val;
763 }
764 524958 unsigned int avio_rb32(AVIOContext *s)
765 {
766 unsigned int val;
767 524958 val = avio_rb16(s) << 16;
768 524958 val |= avio_rb16(s);
769 524958 return val;
770 }
771
772 966 int ff_get_line(AVIOContext *s, char *buf, int maxlen)
773 {
774 966 int i = 0;
775 char c;
776
777 do {
778 25266 c = avio_r8(s);
779
3/4
✓ Branch 0 taken 25235 times.
✓ Branch 1 taken 31 times.
✓ Branch 2 taken 25235 times.
✗ Branch 3 not taken.
25266 if (c && i < maxlen-1)
780 25235 buf[i++] = c;
781
6/6
✓ Branch 0 taken 24641 times.
✓ Branch 1 taken 625 times.
✓ Branch 2 taken 24331 times.
✓ Branch 3 taken 310 times.
✓ Branch 4 taken 24300 times.
✓ Branch 5 taken 31 times.
25266 } while (c != '\n' && c != '\r' && c);
782
3/6
✓ Branch 0 taken 310 times.
✓ Branch 1 taken 656 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 310 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
966 if (c == '\r' && avio_r8(s) != '\n' && !avio_feof(s))
783 avio_skip(s, -1);
784
785 966 buf[i] = 0;
786 966 return i;
787 }
788
789 265 int ff_get_chomp_line(AVIOContext *s, char *buf, int maxlen)
790 {
791 265 int len = ff_get_line(s, buf, maxlen);
792
4/4
✓ Branch 0 taken 500 times.
✓ Branch 1 taken 15 times.
✓ Branch 2 taken 250 times.
✓ Branch 3 taken 250 times.
515 while (len > 0 && av_isspace(buf[len - 1]))
793 250 buf[--len] = '\0';
794 265 return len;
795 }
796
797 typedef enum FFBPrintReadStringMode {
798 FFBPrintReadString = 0,
799 FFBPrintReadLine = 1,
800 } FFBPrintReadStringMode;
801
802 338 static int64_t read_string_to_bprint(AVIOContext *s, AVBPrint *bp,
803 FFBPrintReadStringMode mode,
804 int64_t max_len)
805 {
806 int len, end;
807 338 int64_t read = 0;
808 char tmp[1024];
809 char c;
810
811
1/2
✓ Branch 0 taken 338 times.
✗ Branch 1 not taken.
338 if (!max_len)
812 return 0;
813
814 do {
815 338 len = 0;
816 do {
817 5328 c = avio_r8(s);
818
7/8
✓ Branch 0 taken 4562 times.
✓ Branch 1 taken 766 times.
✓ Branch 2 taken 4562 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 4294 times.
✓ Branch 5 taken 268 times.
✓ Branch 6 taken 70 times.
✓ Branch 7 taken 4990 times.
5328 end = ((mode == FFBPrintReadLine && (c == '\r' || c == '\n')) ||
819 c == '\0');
820
2/2
✓ Branch 0 taken 4990 times.
✓ Branch 1 taken 338 times.
5328 if (!end)
821 4990 tmp[len++] = c;
822
5/6
✓ Branch 0 taken 4990 times.
✓ Branch 1 taken 338 times.
✓ Branch 2 taken 4990 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 4289 times.
✓ Branch 5 taken 701 times.
5328 } while (!end && len < sizeof(tmp) &&
823
1/2
✓ Branch 0 taken 701 times.
✗ Branch 1 not taken.
701 ((max_len < 0) || (read + len < max_len)));
824 338 av_bprint_append_data(bp, tmp, len);
825 338 read += len;
826
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 338 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
338 } while (!end && ((max_len < 0) || (read < max_len)));
827
828
3/4
✓ Branch 0 taken 273 times.
✓ Branch 1 taken 65 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 273 times.
338 if (mode == FFBPrintReadLine &&
829 c == '\r' && avio_r8(s) != '\n' && !avio_feof(s))
830 avio_skip(s, -1);
831
832
3/4
✓ Branch 0 taken 70 times.
✓ Branch 1 taken 268 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 70 times.
338 if (!c && s->error)
833 return s->error;
834
835
6/6
✓ Branch 0 taken 70 times.
✓ Branch 1 taken 268 times.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 64 times.
✓ Branch 5 taken 5 times.
✓ Branch 6 taken 1 times.
338 if (!c && !read && avio_feof(s))
836 5 return AVERROR_EOF;
837
838 333 return read;
839 }
840
841 338 static int64_t read_string_to_bprint_overwrite(AVIOContext *s, AVBPrint *bp,
842 FFBPrintReadStringMode mode,
843 int64_t max_len)
844 {
845 int64_t ret;
846
847 338 av_bprint_clear(bp);
848 338 ret = read_string_to_bprint(s, bp, mode, max_len);
849
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 333 times.
338 if (ret < 0)
850 5 return ret;
851
852
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 333 times.
333 if (!av_bprint_is_complete(bp))
853 return AVERROR(ENOMEM);
854
855 333 return bp->len;
856 }
857
858 273 int64_t ff_read_line_to_bprint_overwrite(AVIOContext *s, AVBPrint *bp)
859 {
860 273 return read_string_to_bprint_overwrite(s, bp, FFBPrintReadLine, -1);
861 }
862
863 65 int64_t ff_read_string_to_bprint_overwrite(AVIOContext *s, AVBPrint *bp,
864 int64_t max_len)
865 {
866 65 return read_string_to_bprint_overwrite(s, bp, FFBPrintReadString, max_len);
867 }
868
869 625 int avio_get_str(AVIOContext *s, int maxlen, char *buf, int buflen)
870 {
871 int i;
872
873
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 625 times.
625 if (buflen <= 0)
874 return AVERROR(EINVAL);
875 // reserve 1 byte for terminating 0
876 625 buflen = FFMIN(buflen - 1, maxlen);
877
2/2
✓ Branch 0 taken 9266 times.
✓ Branch 1 taken 272 times.
9538 for (i = 0; i < buflen; i++)
878
2/2
✓ Branch 1 taken 353 times.
✓ Branch 2 taken 8913 times.
9266 if (!(buf[i] = avio_r8(s)))
879 353 return i + 1;
880 272 buf[i] = 0;
881
2/2
✓ Branch 0 taken 280 times.
✓ Branch 1 taken 262 times.
542 for (; i < maxlen; i++)
882
2/2
✓ Branch 1 taken 10 times.
✓ Branch 2 taken 270 times.
280 if (!avio_r8(s))
883 10 return i + 1;
884 262 return maxlen;
885 }
886
887 #define GET_STR16(type, read) \
888 int avio_get_str16 ##type(AVIOContext *pb, int maxlen, char *buf, int buflen)\
889 {\
890 char* q = buf;\
891 int ret = 0;\
892 if (buflen <= 0) \
893 return AVERROR(EINVAL); \
894 while (ret + 1 < maxlen) {\
895 uint8_t tmp;\
896 uint32_t ch;\
897 GET_UTF16(ch, (ret += 2) <= maxlen ? read(pb) : 0, break;)\
898 if (!ch)\
899 break;\
900 PUT_UTF8(ch, tmp, if (q - buf < buflen - 1) *q++ = tmp;)\
901 }\
902 *q = 0;\
903 return ret;\
904 }\
905
906
14/26
✗ Branch 0 not taken.
✓ Branch 1 taken 618 times.
✓ Branch 2 taken 8432 times.
✗ Branch 3 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 8432 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✓ Branch 14 taken 602 times.
✓ Branch 15 taken 7830 times.
✓ Branch 16 taken 7829 times.
✓ Branch 17 taken 1 times.
✓ Branch 18 taken 7829 times.
✗ Branch 19 not taken.
✓ Branch 20 taken 1 times.
✗ Branch 21 not taken.
✓ Branch 22 taken 1 times.
✗ Branch 23 not taken.
✓ Branch 24 taken 1 times.
✓ Branch 25 taken 1 times.
✓ Branch 26 taken 8432 times.
✓ Branch 27 taken 16 times.
8449 GET_STR16(le, avio_rl16)
907
9/26
✗ Branch 0 not taken.
✓ Branch 1 taken 596 times.
✓ Branch 2 taken 5514 times.
✗ Branch 3 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 5514 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✓ Branch 14 taken 539 times.
✓ Branch 15 taken 4975 times.
✓ Branch 16 taken 4975 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 4975 times.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
✓ Branch 26 taken 5514 times.
✓ Branch 27 taken 57 times.
5571 GET_STR16(be, avio_rb16)
908
909 #undef GET_STR16
910
911 145747 uint64_t avio_rb64(AVIOContext *s)
912 {
913 uint64_t val;
914 145747 val = (uint64_t)avio_rb32(s) << 32;
915 145747 val |= (uint64_t)avio_rb32(s);
916 145747 return val;
917 }
918
919 10686 uint64_t ffio_read_varlen(AVIOContext *bc){
920 10686 uint64_t val = 0;
921 int tmp;
922
923 do{
924 18251 tmp = avio_r8(bc);
925 18251 val= (val<<7) + (tmp&127);
926
2/2
✓ Branch 0 taken 7565 times.
✓ Branch 1 taken 10686 times.
18251 }while(tmp&128);
927 10686 return val;
928 }
929
930 1265 unsigned int ffio_read_leb(AVIOContext *s) {
931 1265 int more, i = 0;
932 1265 unsigned leb = 0;
933
934 do {
935 1750 int byte = avio_r8(s);
936 1750 unsigned bits = byte & 0x7f;
937 1750 more = byte & 0x80;
938
1/2
✓ Branch 0 taken 1750 times.
✗ Branch 1 not taken.
1750 if (i <= 4)
939 1750 leb |= bits << (i * 7);
940
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1750 times.
1750 if (++i == 8)
941 break;
942
2/2
✓ Branch 0 taken 485 times.
✓ Branch 1 taken 1265 times.
1750 } while (more);
943
944 1265 return leb;
945 }
946
947 2496 void ffio_write_leb(AVIOContext *s, unsigned val)
948 {
949 int len;
950 uint8_t byte;
951
952 2496 len = (av_log2(val) + 7) / 7;
953
954
2/2
✓ Branch 0 taken 3410 times.
✓ Branch 1 taken 2496 times.
5906 for (int i = 0; i < len; i++) {
955 3410 byte = val >> (7 * i) & 0x7f;
956
2/2
✓ Branch 0 taken 914 times.
✓ Branch 1 taken 2496 times.
3410 if (i < len - 1)
957 914 byte |= 0x80;
958
959 3410 avio_w8(s, byte);
960 }
961 2496 }
962
963 28 void ffio_write_lines(AVIOContext *s, const unsigned char *buf, int size,
964 const unsigned char *ending)
965 {
966
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 28 times.
28 int ending_len = ending ? strlen(ending) : 1;
967
1/2
✓ Branch 0 taken 28 times.
✗ Branch 1 not taken.
28 if (!ending)
968 28 ending = "\n";
969
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 28 times.
28 if (size < 0)
970 size = strlen(buf);
971
972
2/2
✓ Branch 0 taken 439 times.
✓ Branch 1 taken 28 times.
467 while (size > 0) {
973 439 size_t len = 0;
974 439 char last = 0;
975
1/2
✓ Branch 0 taken 19804 times.
✗ Branch 1 not taken.
19804 for (; len < size; len++) {
976 19804 last = buf[len];
977
4/4
✓ Branch 0 taken 19701 times.
✓ Branch 1 taken 103 times.
✓ Branch 2 taken 19365 times.
✓ Branch 3 taken 336 times.
19804 if (last == '\r' || last == '\n')
978 break;
979 }
980
981 439 avio_write(s, buf, len);
982 439 avio_write(s, ending, ending_len);
983
984 439 buf += len + 1;
985 439 size -= len + 1;
986
987
5/6
✓ Branch 0 taken 415 times.
✓ Branch 1 taken 24 times.
✓ Branch 2 taken 103 times.
✓ Branch 3 taken 312 times.
✓ Branch 4 taken 103 times.
✗ Branch 5 not taken.
439 if (size > 0 && last == '\r' && buf[0] == '\n') {
988 103 buf++;
989 103 size--;
990 }
991 }
992 28 }
993
994 14 int ffio_copy_url_options(AVIOContext* pb, AVDictionary** avio_opts)
995 {
996 14 const char *opts[] = {
997 "headers", "user_agent", "cookies", "http_proxy", "referer", "rw_timeout", "icy", NULL };
998 14 const char **opt = opts;
999 14 uint8_t *buf = NULL;
1000 14 int ret = 0;
1001
1002
2/2
✓ Branch 0 taken 98 times.
✓ Branch 1 taken 14 times.
112 while (*opt) {
1003
2/2
✓ Branch 1 taken 14 times.
✓ Branch 2 taken 84 times.
98 if (av_opt_get(pb, *opt, AV_OPT_SEARCH_CHILDREN, &buf) >= 0) {
1004
1/2
✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
14 if (buf[0] != '\0') {
1005 14 ret = av_dict_set(avio_opts, *opt, buf, AV_DICT_DONT_STRDUP_VAL);
1006
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14 times.
14 if (ret < 0)
1007 return ret;
1008 } else {
1009 av_freep(&buf);
1010 }
1011 }
1012 98 opt++;
1013 }
1014
1015 14 return ret;
1016 }
1017
1018 12 static void update_checksum(AVIOContext *s)
1019 {
1020
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
12 if (s->update_checksum && s->buf_ptr > s->checksum_ptr) {
1021 s->checksum = s->update_checksum(s->checksum, s->checksum_ptr,
1022 s->buf_ptr - s->checksum_ptr);
1023 }
1024 12 }
1025
1026 19182 int ffio_ensure_seekback(AVIOContext *s, int64_t buf_size)
1027 {
1028 uint8_t *buffer;
1029 38364 int max_buffer_size = s->max_packet_size ?
1030
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 19182 times.
19182 s->max_packet_size : IO_BUFFER_SIZE;
1031 19182 ptrdiff_t filled = s->buf_end - s->buf_ptr;
1032
1033
2/2
✓ Branch 0 taken 16836 times.
✓ Branch 1 taken 2346 times.
19182 if (buf_size <= s->buf_end - s->buf_ptr)
1034 16836 return 0;
1035
1036
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2346 times.
2346 if (buf_size > INT_MAX - max_buffer_size)
1037 return AVERROR(EINVAL);
1038
1039 2346 buf_size += max_buffer_size - 1;
1040
1041
5/6
✓ Branch 0 taken 2346 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15 times.
✓ Branch 3 taken 2331 times.
✓ Branch 4 taken 3 times.
✓ Branch 5 taken 12 times.
2346 if (buf_size + s->buf_ptr - s->buffer <= s->buffer_size || s->seekable || !s->read_packet)
1042 2334 return 0;
1043
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
12 av_assert0(!s->write_flag);
1044
1045
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
12 if (buf_size <= s->buffer_size) {
1046 update_checksum(s);
1047 memmove(s->buffer, s->buf_ptr, filled);
1048 } else {
1049 12 buffer = av_malloc(buf_size);
1050
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
12 if (!buffer)
1051 return AVERROR(ENOMEM);
1052 12 update_checksum(s);
1053 12 memcpy(buffer, s->buf_ptr, filled);
1054 12 av_free(s->buffer);
1055 12 s->buffer = buffer;
1056 12 s->buffer_size = buf_size;
1057 }
1058 12 s->buf_ptr = s->buffer;
1059 12 s->buf_end = s->buffer + filled;
1060 12 s->checksum_ptr = s->buffer;
1061 12 return 0;
1062 }
1063
1064 6293 int ffio_limit(AVIOContext *s, int size)
1065 {
1066 6293 FFIOContext *const ctx = ffiocontext(s);
1067
2/2
✓ Branch 0 taken 6266 times.
✓ Branch 1 taken 27 times.
6293 if (ctx->maxsize >= 0) {
1068 6266 int64_t pos = avio_tell(s);
1069 6266 int64_t remaining = ctx->maxsize - pos;
1070
2/2
✓ Branch 0 taken 421 times.
✓ Branch 1 taken 5845 times.
6266 if (remaining < size) {
1071 421 int64_t newsize = avio_size(s);
1072
3/4
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 416 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 5 times.
421 if (!ctx->maxsize || ctx->maxsize < newsize)
1073 416 ctx->maxsize = newsize - !newsize;
1074
3/4
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 420 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
421 if (pos > ctx->maxsize && ctx->maxsize >= 0)
1075 ctx->maxsize = AVERROR(EIO);
1076
2/2
✓ Branch 0 taken 420 times.
✓ Branch 1 taken 1 times.
421 if (ctx->maxsize >= 0)
1077 420 remaining = ctx->maxsize - pos;
1078 }
1079
1080
5/6
✓ Branch 0 taken 6265 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 5 times.
✓ Branch 3 taken 6260 times.
✓ Branch 4 taken 5 times.
✗ Branch 5 not taken.
6266 if (ctx->maxsize >= 0 && remaining < size && size > 1) {
1081 5 av_log(NULL, remaining ? AV_LOG_ERROR : AV_LOG_DEBUG,
1082 "Truncating packet of size %d to %"PRId64"\n",
1083
1/2
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
5 size, remaining + !remaining);
1084 5 size = remaining + !remaining;
1085 }
1086 }
1087 6293 return size;
1088 }
1089
1090 22 static int set_buf_size(AVIOContext *s, int buf_size)
1091 {
1092 uint8_t *buffer;
1093 22 buffer = av_malloc(buf_size);
1094
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 22 times.
22 if (!buffer)
1095 return AVERROR(ENOMEM);
1096
1097 22 av_free(s->buffer);
1098 22 s->buffer = buffer;
1099 44 ffiocontext(s)->orig_buffer_size =
1100 22 s->buffer_size = buf_size;
1101 22 s->buf_ptr = s->buf_ptr_max = buffer;
1102
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 22 times.
22 url_resetbuf(s, s->write_flag ? AVIO_FLAG_WRITE : AVIO_FLAG_READ);
1103 22 return 0;
1104 }
1105
1106 int ffio_realloc_buf(AVIOContext *s, int buf_size)
1107 {
1108 uint8_t *buffer;
1109 int data_size;
1110
1111 if (!s->buffer_size)
1112 return set_buf_size(s, buf_size);
1113
1114 if (buf_size <= s->buffer_size)
1115 return 0;
1116
1117 buffer = av_malloc(buf_size);
1118 if (!buffer)
1119 return AVERROR(ENOMEM);
1120
1121 data_size = s->write_flag ? (s->buf_ptr - s->buffer) : (s->buf_end - s->buf_ptr);
1122 if (data_size > 0)
1123 memcpy(buffer, s->write_flag ? s->buffer : s->buf_ptr, data_size);
1124 av_free(s->buffer);
1125 s->buffer = buffer;
1126 ffiocontext(s)->orig_buffer_size = buf_size;
1127 s->buffer_size = buf_size;
1128 s->buf_ptr = s->write_flag ? (s->buffer + data_size) : s->buffer;
1129 if (s->write_flag)
1130 s->buf_ptr_max = s->buffer + data_size;
1131
1132 s->buf_end = s->write_flag ? (s->buffer + s->buffer_size) : (s->buf_ptr + data_size);
1133
1134 return 0;
1135 }
1136
1137 242547 static int url_resetbuf(AVIOContext *s, int flags)
1138 {
1139 av_assert1(flags == AVIO_FLAG_WRITE || flags == AVIO_FLAG_READ);
1140
1141
2/2
✓ Branch 0 taken 51851 times.
✓ Branch 1 taken 190696 times.
242547 if (flags & AVIO_FLAG_WRITE) {
1142 51851 s->buf_end = s->buffer + s->buffer_size;
1143 51851 s->write_flag = 1;
1144 } else {
1145 190696 s->buf_end = s->buffer;
1146 190696 s->write_flag = 0;
1147 }
1148 242547 return 0;
1149 }
1150
1151 3839 int ffio_rewind_with_probe_data(AVIOContext *s, unsigned char **bufp, int buf_size)
1152 {
1153 int64_t buffer_start;
1154 int buffer_size;
1155 int overlap, new_size, alloc_size;
1156 3839 uint8_t *buf = *bufp;
1157
1158
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3839 times.
3839 if (s->write_flag) {
1159 av_freep(bufp);
1160 return AVERROR(EINVAL);
1161 }
1162
1163 3839 buffer_size = s->buf_end - s->buffer;
1164
1165 /* the buffers must touch or overlap */
1166
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3839 times.
3839 if ((buffer_start = s->pos - buffer_size) > buf_size) {
1167 av_freep(bufp);
1168 return AVERROR(EINVAL);
1169 }
1170
1171 3839 overlap = buf_size - buffer_start;
1172 3839 new_size = buf_size + buffer_size - overlap;
1173
1174 3839 alloc_size = FFMAX(s->buffer_size, new_size);
1175
2/2
✓ Branch 0 taken 3785 times.
✓ Branch 1 taken 54 times.
3839 if (alloc_size > buf_size)
1176
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 3785 times.
3785 if (!(buf = (*bufp) = av_realloc_f(buf, 1, alloc_size)))
1177 return AVERROR(ENOMEM);
1178
1179
2/2
✓ Branch 0 taken 3615 times.
✓ Branch 1 taken 224 times.
3839 if (new_size > buf_size) {
1180 3615 memcpy(buf + buf_size, s->buffer + overlap, buffer_size - overlap);
1181 3615 buf_size = new_size;
1182 }
1183
1184 3839 av_free(s->buffer);
1185 3839 s->buf_ptr = s->buffer = buf;
1186 3839 s->buffer_size = alloc_size;
1187 3839 s->pos = buf_size;
1188 3839 s->buf_end = s->buf_ptr + buf_size;
1189 3839 s->eof_reached = 0;
1190
1191 3839 return 0;
1192 }
1193
1194 25398 int avio_vprintf(AVIOContext *s, const char *fmt, va_list ap)
1195 {
1196 AVBPrint bp;
1197
1198 25398 av_bprint_init(&bp, 0, INT_MAX);
1199 25398 av_vbprintf(&bp, fmt, ap);
1200
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 25398 times.
25398 if (!av_bprint_is_complete(&bp)) {
1201 av_bprint_finalize(&bp, NULL);
1202 s->error = AVERROR(ENOMEM);
1203 return AVERROR(ENOMEM);
1204 }
1205 25398 avio_write(s, bp.str, bp.len);
1206 25398 av_bprint_finalize(&bp, NULL);
1207 25398 return bp.len;
1208 }
1209
1210 25398 int avio_printf(AVIOContext *s, const char *fmt, ...)
1211 {
1212 va_list ap;
1213 int ret;
1214
1215 25398 va_start(ap, fmt);
1216 25398 ret = avio_vprintf(s, fmt, ap);
1217 25398 va_end(ap);
1218
1219 25398 return ret;
1220 }
1221
1222 485 void avio_print_string_array(AVIOContext *s, const char *const strings[])
1223 {
1224
2/2
✓ Branch 0 taken 1455 times.
✓ Branch 1 taken 485 times.
1940 for(; *strings; strings++)
1225 1455 avio_write(s, (const unsigned char *)*strings, strlen(*strings));
1226 485 }
1227
1228 int avio_pause(AVIOContext *s, int pause)
1229 {
1230 if (!s->read_pause)
1231 return AVERROR(ENOSYS);
1232 return s->read_pause(s->opaque, pause);
1233 }
1234
1235 315 int64_t avio_seek_time(AVIOContext *s, int stream_index,
1236 int64_t timestamp, int flags)
1237 {
1238 int64_t ret;
1239
1/2
✓ Branch 0 taken 315 times.
✗ Branch 1 not taken.
315 if (!s->read_seek)
1240 315 return AVERROR(ENOSYS);
1241 ret = s->read_seek(s->opaque, stream_index, timestamp, flags);
1242 if (ret >= 0) {
1243 int64_t pos;
1244 s->buf_ptr = s->buf_end; // Flush buffer
1245 pos = s->seek(s->opaque, 0, SEEK_CUR);
1246 if (pos >= 0)
1247 s->pos = pos;
1248 else if (pos != AVERROR(ENOSYS))
1249 ret = pos;
1250 }
1251 return ret;
1252 }
1253
1254 77 int avio_read_to_bprint(AVIOContext *h, AVBPrint *pb, size_t max_size)
1255 {
1256 int ret;
1257 char buf[1024];
1258
2/2
✓ Branch 0 taken 8137 times.
✓ Branch 1 taken 2 times.
8139 while (max_size) {
1259 8137 ret = avio_read(h, buf, FFMIN(max_size, sizeof(buf)));
1260
2/2
✓ Branch 0 taken 75 times.
✓ Branch 1 taken 8062 times.
8137 if (ret == AVERROR_EOF)
1261 75 return 0;
1262
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8062 times.
8062 if (ret <= 0)
1263 return ret;
1264 8062 av_bprint_append_data(pb, buf, ret);
1265
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 8062 times.
8062 if (!av_bprint_is_complete(pb))
1266 return AVERROR(ENOMEM);
1267 8062 max_size -= ret;
1268 }
1269 2 return 0;
1270 }
1271
1272 /* output in a dynamic buffer */
1273
1274 typedef struct DynBuffer {
1275 int pos, size, allocated_size;
1276 uint8_t *buffer;
1277 int io_buffer_size;
1278 uint8_t io_buffer[1];
1279 } DynBuffer;
1280
1281 36726 static int dyn_buf_write(void *opaque, const uint8_t *buf, int buf_size)
1282 {
1283 36726 DynBuffer *d = opaque;
1284 unsigned new_size;
1285
1286 /* reallocate buffer if needed */
1287 36726 new_size = (unsigned)d->pos + buf_size;
1288
2/4
✓ Branch 0 taken 36726 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 36726 times.
36726 if (new_size < d->pos || new_size > INT_MAX)
1289 return AVERROR(ERANGE);
1290
2/2
✓ Branch 0 taken 8022 times.
✓ Branch 1 taken 28704 times.
36726 if (new_size > d->allocated_size) {
1291 17865 unsigned new_allocated_size = d->allocated_size ? d->allocated_size
1292
2/2
✓ Branch 0 taken 1821 times.
✓ Branch 1 taken 6201 times.
8022 : new_size;
1293 int err;
1294
2/2
✓ Branch 0 taken 3081 times.
✓ Branch 1 taken 8022 times.
11103 while (new_size > new_allocated_size)
1295 3081 new_allocated_size += new_allocated_size / 2 + 1;
1296
1297
1/2
✓ Branch 0 taken 8022 times.
✗ Branch 1 not taken.
8022 new_allocated_size = FFMIN(new_allocated_size, INT_MAX);
1298
1299
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 8022 times.
8022 if ((err = av_reallocp(&d->buffer, new_allocated_size)) < 0) {
1300 d->allocated_size = 0;
1301 d->size = 0;
1302 return err;
1303 }
1304 8022 d->allocated_size = new_allocated_size;
1305 }
1306 36726 memcpy(d->buffer + d->pos, buf, buf_size);
1307 36726 d->pos = new_size;
1308
2/2
✓ Branch 0 taken 36710 times.
✓ Branch 1 taken 16 times.
36726 if (d->pos > d->size)
1309 36710 d->size = d->pos;
1310 36726 return buf_size;
1311 }
1312
1313 265 static int dyn_packet_buf_write(void *opaque, const uint8_t *buf, int buf_size)
1314 {
1315 unsigned char buf1[4];
1316 int ret;
1317
1318 /* packetized write: output the header */
1319 265 AV_WB32(buf1, buf_size);
1320 265 ret = dyn_buf_write(opaque, buf1, 4);
1321
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 265 times.
265 if (ret < 0)
1322 return ret;
1323
1324 /* then the data */
1325 265 return dyn_buf_write(opaque, buf, buf_size);
1326 }
1327
1328 280 static int64_t dyn_buf_seek(void *opaque, int64_t offset, int whence)
1329 {
1330 280 DynBuffer *d = opaque;
1331
1332
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 280 times.
280 if (whence == SEEK_CUR)
1333 offset += d->pos;
1334
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 280 times.
280 else if (whence == SEEK_END)
1335 offset += d->size;
1336
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 280 times.
280 if (offset < 0)
1337 return AVERROR(EINVAL);
1338
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 280 times.
280 if (offset > INT_MAX)
1339 return AVERROR(ERANGE);
1340 280 d->pos = offset;
1341 280 return 0;
1342 }
1343
1344 20510 static int url_open_dyn_buf_internal(AVIOContext **s, int max_packet_size)
1345 {
1346 struct { FFIOContext pb; DynBuffer d; } *ret;
1347 DynBuffer *d;
1348
2/2
✓ Branch 0 taken 38 times.
✓ Branch 1 taken 20472 times.
20510 unsigned io_buffer_size = max_packet_size ? max_packet_size : 1024;
1349
1350 if (sizeof(*ret) + io_buffer_size < io_buffer_size)
1351 return AVERROR(ERANGE);
1352 20510 ret = av_mallocz(sizeof(*ret) + io_buffer_size);
1353
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 20510 times.
20510 if (!ret)
1354 return AVERROR(ENOMEM);
1355 20510 d = &ret->d;
1356 20510 d->io_buffer_size = io_buffer_size;
1357
4/4
✓ Branch 0 taken 20472 times.
✓ Branch 1 taken 38 times.
✓ Branch 2 taken 38 times.
✓ Branch 3 taken 20472 times.
20510 ffio_init_context(&ret->pb, d->io_buffer, d->io_buffer_size, 1, d, NULL,
1358 max_packet_size ? dyn_packet_buf_write : dyn_buf_write,
1359 max_packet_size ? NULL : dyn_buf_seek);
1360 20510 *s = &ret->pb.pub;
1361 20510 (*s)->max_packet_size = max_packet_size;
1362 20510 return 0;
1363 }
1364
1365 20271 int avio_open_dyn_buf(AVIOContext **s)
1366 {
1367 20271 return url_open_dyn_buf_internal(s, 0);
1368 }
1369
1370 38 int ffio_open_dyn_packet_buf(AVIOContext **s, int max_packet_size)
1371 {
1372
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 38 times.
38 if (max_packet_size <= 0)
1373 return AVERROR(EINVAL);
1374 38 return url_open_dyn_buf_internal(s, max_packet_size);
1375 }
1376
1377 24575 int avio_get_dyn_buf(AVIOContext *s, uint8_t **pbuffer)
1378 {
1379 DynBuffer *d;
1380
1381
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 24575 times.
24575 if (!s) {
1382 *pbuffer = NULL;
1383 return 0;
1384 }
1385 24575 d = s->opaque;
1386
1387
3/4
✓ Branch 0 taken 24575 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 23803 times.
✓ Branch 3 taken 772 times.
24575 if (!s->error && !d->size) {
1388 23803 *pbuffer = d->io_buffer;
1389 23803 return FFMAX(s->buf_ptr, s->buf_ptr_max) - s->buffer;
1390 }
1391
1392 772 avio_flush(s);
1393
1394 772 *pbuffer = d->buffer;
1395
1396 772 return d->size;
1397 }
1398
1399 21750 void ffio_reset_dyn_buf(AVIOContext *s)
1400 {
1401 21750 DynBuffer *d = s->opaque;
1402 21750 int max_packet_size = s->max_packet_size;
1403
1404 21750 ffio_init_context(ffiocontext(s), d->io_buffer, d->io_buffer_size,
1405 1, d, NULL, s->write_packet, s->seek);
1406 21750 s->max_packet_size = max_packet_size;
1407 21750 d->pos = d->size = 0;
1408 21750 }
1409
1410 6111 int avio_close_dyn_buf(AVIOContext *s, uint8_t **pbuffer)
1411 {
1412 DynBuffer *d;
1413 int size;
1414 6111 int padding = 0;
1415
1416
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6111 times.
6111 if (!s) {
1417 *pbuffer = NULL;
1418 return 0;
1419 }
1420
1421 /* don't attempt to pad fixed-size packet buffers */
1422
2/2
✓ Branch 0 taken 6075 times.
✓ Branch 1 taken 36 times.
6111 if (!s->max_packet_size) {
1423 6075 ffio_fill(s, 0, AV_INPUT_BUFFER_PADDING_SIZE);
1424 6075 padding = AV_INPUT_BUFFER_PADDING_SIZE;
1425 }
1426
1427 6111 avio_flush(s);
1428
1429 6111 d = s->opaque;
1430 6111 *pbuffer = d->buffer;
1431 6111 size = d->size;
1432
1433 6111 avio_context_free(&s);
1434
1435 6111 return size - padding;
1436 }
1437
1438 15130 void ffio_free_dyn_buf(AVIOContext **s)
1439 {
1440 DynBuffer *d;
1441
1442
2/2
✓ Branch 0 taken 932 times.
✓ Branch 1 taken 14198 times.
15130 if (!*s)
1443 932 return;
1444
1445 14198 d = (*s)->opaque;
1446 14198 av_free(d->buffer);
1447 14198 avio_context_free(s);
1448 }
1449
1450 400 static int null_buf_write(void *opaque, const uint8_t *buf, int buf_size)
1451 {
1452 400 DynBuffer *d = opaque;
1453
1454
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 400 times.
400 if ((unsigned)d->pos + (unsigned)buf_size > INT_MAX)
1455 return AVERROR(ERANGE);
1456 400 d->pos += buf_size;
1457
2/2
✓ Branch 0 taken 268 times.
✓ Branch 1 taken 132 times.
400 if (d->pos > d->size)
1458 268 d->size = d->pos;
1459 400 return buf_size;
1460 }
1461
1462 201 int ffio_open_null_buf(AVIOContext **s)
1463 {
1464 201 int ret = url_open_dyn_buf_internal(s, 0);
1465
1/2
✓ Branch 0 taken 201 times.
✗ Branch 1 not taken.
201 if (ret >= 0) {
1466 201 AVIOContext *pb = *s;
1467 201 pb->write_packet = null_buf_write;
1468 }
1469 201 return ret;
1470 }
1471
1472 201 int ffio_close_null_buf(AVIOContext *s)
1473 {
1474 201 DynBuffer *d = s->opaque;
1475 int size;
1476
1477 201 avio_flush(s);
1478
1479
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 201 times.
201 size = s->error ? s->error : d->size;
1480
1481 201 avio_context_free(&s);
1482
1483 201 return size;
1484 }
1485