FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavformat/aviobuf.c
Date: 2026-10-09 03:22:29
Exec Total Coverage
Lines: 717 826 86.8%
Functions: 86 88 97.7%
Branches: 448 622 72.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 253464 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 253464 AVIOContext *const s = &ctx->pub;
60
61 253464 memset(ctx, 0, sizeof(*ctx));
62
63 253464 s->buffer = buffer;
64 253464 ctx->orig_buffer_size =
65 253464 s->buffer_size = buffer_size;
66 253464 s->buf_ptr = buffer;
67 253464 s->buf_ptr_max = buffer;
68 253464 s->opaque = opaque;
69 253464 s->direct = 0;
70
71
2/2
✓ Branch 0 taken 57727 times.
✓ Branch 1 taken 195737 times.
253464 url_resetbuf(s, write_flag ? AVIO_FLAG_WRITE : AVIO_FLAG_READ);
72
73 253464 s->write_packet = write_packet;
74 253464 s->read_packet = read_packet;
75 253464 s->seek = seek;
76 253464 s->pos = 0;
77 253464 s->eof_reached = 0;
78 253464 s->error = 0;
79 253464 s->seekable = seek ? AVIO_SEEKABLE_NORMAL : 0;
80 253464 s->min_packet_size = 0;
81 253464 s->max_packet_size = 0;
82 253464 s->update_checksum = NULL;
83 253464 ctx->short_seek_threshold = SHORT_SEEK_THRESHOLD;
84
85
4/4
✓ Branch 0 taken 136459 times.
✓ Branch 1 taken 117005 times.
✓ Branch 2 taken 88428 times.
✓ Branch 3 taken 48031 times.
253464 if (!read_packet && !write_flag) {
86 88428 s->pos = buffer_size;
87 88428 s->buf_end = s->buffer + buffer_size;
88 }
89 253464 s->read_pause = NULL;
90 253464 s->read_seek = NULL;
91
92 253464 s->write_data_type = NULL;
93 253464 s->ignore_boundary_point = 0;
94 253464 ctx->current_type = AVIO_DATA_MARKER_UNKNOWN;
95 253464 ctx->last_time = AV_NOPTS_VALUE;
96 253464 ctx->short_seek_get = NULL;
97 253464 }
98
99 88212 void ffio_init_read_context(FFIOContext *s, const uint8_t *buffer, int buffer_size)
100 {
101 88212 ffio_init_context(s, (unsigned char*)buffer, buffer_size, 0, NULL, NULL, NULL, NULL);
102 88212 }
103
104 235 void ffio_init_write_context(FFIOContext *s, uint8_t *buffer, int buffer_size)
105 {
106 235 ffio_init_context(s, buffer, buffer_size, 1, NULL, NULL, NULL, NULL);
107 235 }
108
109 117012 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 117012 FFIOContext *s = av_malloc(sizeof(*s));
119
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 117012 times.
117012 if (!s)
120 ✗ return NULL;
121 117012 ffio_init_context(s, buffer, buffer_size, write_flag, opaque,
122 read_packet, write_packet, seek);
123 117012 return &s->pub;
124 }
125
126 142566 void avio_context_free(AVIOContext **ps)
127 {
128 142566 AVIOContext *s = *ps;
129
2/2
✓ Branch 0 taken 142564 times.
✓ Branch 1 taken 2 times.
142566 if (s) {
130 142564 av_freep(&s->protocol_whitelist);
131 142564 av_freep(&s->protocol_blacklist);
132 }
133 142566 av_freep(ps);
134 142566 }
135
136 451782 static void writeout(AVIOContext *s, const uint8_t *data, int len)
137 {
138 451782 FFIOContext *const ctx = ffiocontext(s);
139
1/2
✓ Branch 0 taken 451782 times.
✗ Branch 1 not taken.
451782 if (!s->error) {
140 451782 int ret = 0;
141
2/2
✓ Branch 0 taken 129 times.
✓ Branch 1 taken 451653 times.
451782 if (s->write_data_type)
142 129 ret = s->write_data_type(s->opaque, data,
143 len,
144 ctx->current_type,
145 ctx->last_time);
146
2/2
✓ Branch 0 taken 451636 times.
✓ Branch 1 taken 17 times.
451653 else if (s->write_packet)
147 451636 ret = s->write_packet(s->opaque, data, len);
148
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 451782 times.
451782 if (ret < 0) {
149 ✗ s->error = ret;
150 } else {
151 451782 ctx->bytes_written += len;
152 451782 s->bytes_written = ctx->bytes_written;
153
154
2/2
✓ Branch 0 taken 449668 times.
✓ Branch 1 taken 2114 times.
451782 if (s->pos + len > ctx->written_output_size) {
155 449668 ctx->written_output_size = s->pos + len;
156 }
157 }
158 }
159
2/2
✓ Branch 0 taken 451735 times.
✓ Branch 1 taken 47 times.
451782 if (ctx->current_type == AVIO_DATA_MARKER_SYNC_POINT ||
160
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 451730 times.
451735 ctx->current_type == AVIO_DATA_MARKER_BOUNDARY_POINT) {
161 52 ctx->current_type = AVIO_DATA_MARKER_UNKNOWN;
162 }
163 451782 ctx->last_time = AV_NOPTS_VALUE;
164 451782 ctx->writeout_count++;
165 451782 s->pos += len;
166 451782 }
167
168 595506 static void flush_buffer(AVIOContext *s)
169 {
170 595506 s->buf_ptr_max = FFMAX(s->buf_ptr, s->buf_ptr_max);
171
4/4
✓ Branch 0 taken 488231 times.
✓ Branch 1 taken 107275 times.
✓ Branch 2 taken 444438 times.
✓ Branch 3 taken 43793 times.
595506 if (s->write_flag && s->buf_ptr_max > s->buffer) {
172 444438 writeout(s, s->buffer, s->buf_ptr_max - s->buffer);
173
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 444438 times.
444438 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 595506 s->buf_ptr = s->buf_ptr_max = s->buffer;
180
2/2
✓ Branch 0 taken 107275 times.
✓ Branch 1 taken 488231 times.
595506 if (!s->write_flag)
181 107275 s->buf_end = s->buffer;
182 595506 }
183
184 3890061 void avio_w8(AVIOContext *s, int b)
185 {
186 av_assert2(b>=-128 && b<=255);
187 3890061 *s->buf_ptr++ = b;
188
2/2
✓ Branch 0 taken 193 times.
✓ Branch 1 taken 3889868 times.
3890061 if (s->buf_ptr >= s->buf_end)
189 193 flush_buffer(s);
190 3890061 }
191
192 34780 void ffio_fill(AVIOContext *s, int b, int64_t count)
193 {
194
2/2
✓ Branch 0 taken 22367 times.
✓ Branch 1 taken 34780 times.
57147 while (count > 0) {
195 22367 int len = FFMIN(s->buf_end - s->buf_ptr, count);
196 22367 memset(s->buf_ptr, b, len);
197 22367 s->buf_ptr += len;
198
199
2/2
✓ Branch 0 taken 236 times.
✓ Branch 1 taken 22131 times.
22367 if (s->buf_ptr >= s->buf_end)
200 236 flush_buffer(s);
201
202 22367 count -= len;
203 }
204 34780 }
205
206 941112 void avio_write(AVIOContext *s, const unsigned char *buf, int size)
207 {
208
2/2
✓ Branch 0 taken 12838 times.
✓ Branch 1 taken 928274 times.
941112 if (size <= 0)
209 12838 return;
210
3/4
✓ Branch 0 taken 7344 times.
✓ Branch 1 taken 920930 times.
✓ Branch 2 taken 7344 times.
✗ Branch 3 not taken.
928274 if (s->direct && !s->update_checksum) {
211 7344 avio_flush(s);
212 7344 writeout(s, buf, size);
213 7344 return;
214 }
215 do {
216 1083970 int len = FFMIN(s->buf_end - s->buf_ptr, size);
217 1083970 memcpy(s->buf_ptr, buf, len);
218 1083970 s->buf_ptr += len;
219
220
2/2
✓ Branch 0 taken 163928 times.
✓ Branch 1 taken 920042 times.
1083970 if (s->buf_ptr >= s->buf_end)
221 163928 flush_buffer(s);
222
223 1083970 buf += len;
224 1083970 size -= len;
225
2/2
✓ Branch 0 taken 163040 times.
✓ Branch 1 taken 920930 times.
1083970 } while (size > 0);
226 }
227
228 427643 void avio_flush(AVIOContext *s)
229 {
230
2/2
✓ Branch 0 taken 320368 times.
✓ Branch 1 taken 107275 times.
427643 int seekback = s->write_flag ? FFMIN(0, s->buf_ptr - s->buf_ptr_max) : 0;
231 427643 flush_buffer(s);
232
2/2
✓ Branch 0 taken 131 times.
✓ Branch 1 taken 427512 times.
427643 if (seekback)
233 131 avio_seek(s, seekback, SEEK_CUR);
234 427643 }
235
236 4156242 int64_t avio_seek(AVIOContext *s, int64_t offset, int whence)
237 {
238 4156242 FFIOContext *const ctx = ffiocontext(s);
239 int64_t offset1;
240 int64_t pos;
241 int buffer_size;
242 int short_seek;
243 4156242 whence &= ~AVSEEK_FORCE; // force flag does nothing
244
245
2/2
✓ Branch 0 taken 6586 times.
✓ Branch 1 taken 4149656 times.
4156242 if(!s)
246 6586 return AVERROR(EINVAL);
247
248
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4149656 times.
4149656 if ((whence & AVSEEK_SIZE))
249 ✗ return s->seek ? s->seek(s->opaque, offset, AVSEEK_SIZE) : AVERROR(ENOSYS);
250
251 4149656 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 3805932 times.
✓ Branch 1 taken 343724 times.
4149656 pos = s->pos - (s->write_flag ? 0 : buffer_size);
254
255
3/4
✓ Branch 0 taken 247359 times.
✓ Branch 1 taken 3902297 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 247359 times.
4149656 if (whence != SEEK_CUR && whence != SEEK_SET)
256 ✗ return AVERROR(EINVAL);
257
258
2/2
✓ Branch 0 taken 3902297 times.
✓ Branch 1 taken 247359 times.
4149656 if (whence == SEEK_CUR) {
259 3902297 offset1 = pos + (s->buf_ptr - s->buffer);
260
2/2
✓ Branch 0 taken 3738929 times.
✓ Branch 1 taken 163368 times.
3902297 if (offset == 0)
261 3738929 return offset1;
262
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 163368 times.
163368 if (offset > INT64_MAX - offset1)
263 ✗ return AVERROR(EINVAL);
264 163368 offset += offset1;
265 }
266
2/2
✓ Branch 0 taken 54 times.
✓ Branch 1 taken 410673 times.
410727 if (offset < 0)
267 54 return AVERROR(EINVAL);
268
269 410673 short_seek = ctx->short_seek_threshold;
270
2/2
✓ Branch 0 taken 378842 times.
✓ Branch 1 taken 31831 times.
410673 if (ctx->short_seek_get) {
271 378842 int tmp = ctx->short_seek_get(s->opaque);
272 378842 short_seek = FFMAX(tmp, short_seek);
273 }
274
275 410673 offset1 = offset - pos; // "offset1" is the relative offset from the beginning of s->buffer
276 410673 s->buf_ptr_max = FFMAX(s->buf_ptr_max, s->buf_ptr);
277
5/6
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 410664 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 9 times.
✓ Branch 4 taken 402455 times.
✓ Branch 5 taken 8209 times.
410673 if ((!s->direct || !s->seek) &&
278
4/4
✓ Branch 0 taken 42930 times.
✓ Branch 1 taken 359525 times.
✓ Branch 2 taken 395637 times.
✓ Branch 3 taken 6818 times.
402455 offset1 >= 0 && offset1 <= (s->write_flag ? s->buf_ptr_max - s->buffer : buffer_size)) {
279 /* can do the seek inside the buffer */
280 395637 s->buf_ptr = s->buffer + offset1;
281
2/2
✓ Branch 0 taken 15030 times.
✓ Branch 1 taken 6 times.
15036 } else if ((!(s->seekable & AVIO_SEEKABLE_NORMAL) ||
282
2/2
✓ Branch 0 taken 10977 times.
✓ Branch 1 taken 4053 times.
15030 offset1 <= buffer_size + short_seek) &&
283
4/4
✓ Branch 0 taken 8468 times.
✓ Branch 1 taken 2515 times.
✓ Branch 2 taken 2292 times.
✓ Branch 3 taken 6176 times.
10983 !s->write_flag && offset1 >= 0 &&
284
3/4
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 2285 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 7 times.
2292 (!s->direct || !s->seek)) {
285
4/4
✓ Branch 0 taken 2460 times.
✓ Branch 1 taken 2183 times.
✓ Branch 2 taken 2358 times.
✓ Branch 3 taken 102 times.
4643 while(s->pos < offset && !s->eof_reached)
286 2358 fill_buffer(s);
287
2/2
✓ Branch 0 taken 102 times.
✓ Branch 1 taken 2183 times.
2285 if (s->eof_reached)
288 102 return AVERROR_EOF;
289 2183 s->buf_ptr = s->buf_end - (s->pos - offset);
290
10/10
✓ Branch 0 taken 9245 times.
✓ Branch 1 taken 3506 times.
✓ Branch 2 taken 6176 times.
✓ Branch 3 taken 3069 times.
✓ Branch 4 taken 489 times.
✓ Branch 5 taken 5687 times.
✓ Branch 6 taken 487 times.
✓ Branch 7 taken 2 times.
✓ Branch 8 taken 477 times.
✓ Branch 9 taken 10 times.
12751 } else if(!s->write_flag && offset1 < 0 && -offset1 < buffer_size>>1 && s->seek && offset > 0) {
291 int64_t res;
292
293 477 pos -= FFMIN(buffer_size>>1, pos);
294
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 477 times.
477 if ((res = s->seek(s->opaque, pos, SEEK_SET)) < 0)
295 ✗ return res;
296 477 s->buf_end =
297 477 s->buf_ptr = s->buffer;
298 477 s->pos = pos;
299 477 s->eof_reached = 0;
300 477 fill_buffer(s);
301 477 return avio_seek(s, offset, SEEK_SET);
302 } else {
303 int64_t res;
304
2/2
✓ Branch 0 taken 3506 times.
✓ Branch 1 taken 8768 times.
12274 if (s->write_flag) {
305 3506 flush_buffer(s);
306 }
307
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 12272 times.
12274 if (!s->seek)
308 2 return AVERROR(EPIPE);
309
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 12272 times.
12272 if ((res = s->seek(s->opaque, offset, SEEK_SET)) < 0)
310 ✗ return res;
311 12272 ctx->seek_count++;
312
2/2
✓ Branch 0 taken 8766 times.
✓ Branch 1 taken 3506 times.
12272 if (!s->write_flag)
313 8766 s->buf_end = s->buffer;
314 12272 s->checksum_ptr = s->buf_ptr = s->buf_ptr_max = s->buffer;
315 12272 s->pos = offset;
316 }
317 410092 s->eof_reached = 0;
318 410092 return offset;
319 }
320
321 160808 int64_t avio_skip(AVIOContext *s, int64_t offset)
322 {
323 160808 return avio_seek(s, offset, SEEK_CUR);
324 }
325
326 735744 int64_t avio_size(AVIOContext *s)
327 {
328 735744 FFIOContext *const ctx = ffiocontext(s);
329 int64_t size;
330
331
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 735744 times.
735744 if (!s)
332 ✗ return AVERROR(EINVAL);
333
334
2/2
✓ Branch 0 taken 460301 times.
✓ Branch 1 taken 275443 times.
735744 if (ctx->written_output_size)
335 460301 return ctx->written_output_size;
336
337
2/2
✓ Branch 0 taken 406 times.
✓ Branch 1 taken 275037 times.
275443 if (!s->seek)
338 406 return AVERROR(ENOSYS);
339 275037 size = s->seek(s->opaque, 0, AVSEEK_SIZE);
340
2/2
✓ Branch 0 taken 14563 times.
✓ Branch 1 taken 260474 times.
275037 if (size < 0) {
341
2/2
✓ Branch 1 taken 14558 times.
✓ Branch 2 taken 5 times.
14563 if ((size = s->seek(s->opaque, -1, SEEK_END)) < 0)
342 14558 return size;
343 5 size++;
344 5 s->seek(s->opaque, s->pos, SEEK_SET);
345 }
346 260479 return size;
347 }
348
349 6479346 int avio_feof(AVIOContext *s)
350 {
351
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6479346 times.
6479346 if(!s)
352 ✗ return 0;
353
2/2
✓ Branch 0 taken 8033 times.
✓ Branch 1 taken 6471313 times.
6479346 if(s->eof_reached){
354 8033 s->eof_reached=0;
355 8033 fill_buffer(s);
356 }
357 6479346 return s->eof_reached;
358 }
359
360 552774 void avio_wl32(AVIOContext *s, unsigned int val)
361 {
362 552774 avio_w8(s, (uint8_t) val );
363 552774 avio_w8(s, (uint8_t)(val >> 8 ));
364 552774 avio_w8(s, (uint8_t)(val >> 16));
365 552774 avio_w8(s, val >> 24 );
366 552774 }
367
368 200759 void avio_wb32(AVIOContext *s, unsigned int val)
369 {
370 200759 avio_w8(s, val >> 24 );
371 200759 avio_w8(s, (uint8_t)(val >> 16));
372 200759 avio_w8(s, (uint8_t)(val >> 8 ));
373 200759 avio_w8(s, (uint8_t) val );
374 200759 }
375
376 640 int avio_put_str(AVIOContext *s, const char *str)
377 {
378 640 int len = 1;
379
1/2
✓ Branch 0 taken 640 times.
✗ Branch 1 not taken.
640 if (str) {
380 640 len += strlen(str);
381 640 avio_write(s, (const unsigned char *) str, len);
382 } else
383 ✗ avio_w8(s, 0);
384 640 return len;
385 }
386
387 250 static inline int put_str16(AVIOContext *s, const char *str, const int be)
388 {
389 250 const uint8_t *q = str;
390 250 int ret = 0;
391 250 int err = 0;
392
393
2/2
✓ Branch 0 taken 1973 times.
✓ Branch 1 taken 250 times.
2223 while (*q) {
394 uint32_t ch;
395 uint16_t tmp16;
396
397
5/8
✓ Branch 0 taken 1973 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1973 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 32 times.
✓ Branch 6 taken 32 times.
✓ Branch 7 taken 1973 times.
2005 GET_UTF8(ch, *q++, goto invalid;)
398
3/8
✓ Branch 0 taken 1973 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 918 times.
✓ Branch 3 taken 1055 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
1973 PUT_UTF16(ch, tmp16, be ? avio_wb16(s, tmp16) : avio_wl16(s, tmp16);
399 ret += 2;)
400 1973 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 106 times.
250 if (be)
408 144 avio_wb16(s, 0);
409 else
410 106 avio_wl16(s, 0);
411
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 250 times.
250 if (err)
412 ✗ return err;
413 250 ret += 2;
414 250 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 106 PUT_STR16(le, 0)
424 144 PUT_STR16(be, 1)
425
426 #undef PUT_STR16
427
428 1093 void avio_wl64(AVIOContext *s, uint64_t val)
429 {
430 1093 avio_wl32(s, (uint32_t)(val & 0xffffffff));
431 1093 avio_wl32(s, (uint32_t)(val >> 32));
432 1093 }
433
434 28975 void avio_wb64(AVIOContext *s, uint64_t val)
435 {
436 28975 avio_wb32(s, (uint32_t)(val >> 32));
437 28975 avio_wb32(s, (uint32_t)(val & 0xffffffff));
438 28975 }
439
440 29608 void avio_wl16(AVIOContext *s, unsigned int val)
441 {
442 29608 avio_w8(s, (uint8_t)val);
443 29608 avio_w8(s, (int)val >> 8);
444 29608 }
445
446 97866 void avio_wb16(AVIOContext *s, unsigned int val)
447 {
448 97866 avio_w8(s, (int)val >> 8);
449 97866 avio_w8(s, (uint8_t)val);
450 97866 }
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 16613 void avio_wb24(AVIOContext *s, unsigned int val)
459 {
460 16613 avio_wb16(s, (int)val >> 8);
461 16613 avio_w8(s, (uint8_t)val);
462 16613 }
463
464 656118 void avio_write_marker(AVIOContext *s, int64_t time, enum AVIODataMarkerType type)
465 {
466 656118 FFIOContext *const ctx = ffiocontext(s);
467
2/2
✓ Branch 0 taken 633205 times.
✓ Branch 1 taken 22913 times.
656118 if (type == AVIO_DATA_MARKER_FLUSH_POINT) {
468
2/2
✓ Branch 0 taken 285161 times.
✓ Branch 1 taken 348044 times.
633205 if (s->buf_ptr - s->buffer >= s->min_packet_size)
469 285161 avio_flush(s);
470 633205 return;
471 }
472
2/2
✓ Branch 0 taken 22725 times.
✓ Branch 1 taken 188 times.
22913 if (!s->write_data_type)
473 22725 return;
474 // If ignoring boundary points, just treat it as unknown
475
3/4
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 183 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 5 times.
188 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 29 times.
✓ Branch 1 taken 159 times.
188 if (type == AVIO_DATA_MARKER_UNKNOWN &&
480
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 29 times.
29 (ctx->current_type != AVIO_DATA_MARKER_HEADER &&
481 ✗ ctx->current_type != AVIO_DATA_MARKER_TRAILER))
482 ✗ return;
483
484
2/2
✓ Branch 0 taken 107 times.
✓ Branch 1 taken 81 times.
188 switch (type) {
485 107 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 96 times.
107 if (type == ctx->current_type)
490 11 return;
491 96 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 177 avio_flush(s);
497 177 ctx->current_type = type;
498 177 ctx->last_time = time;
499 }
500
501 227600 static int read_packet_wrapper(AVIOContext *s, uint8_t *buf, int size)
502 {
503 int ret;
504
505
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 227596 times.
227600 if (!s->read_packet)
506 4 return AVERROR(EINVAL);
507 227596 ret = s->read_packet(s->opaque, buf, size);
508 av_assert2(ret || s->max_packet_size);
509 227596 return ret;
510 }
511
512 /* Input stream */
513
514 102069 static void fill_buffer(AVIOContext *s)
515 {
516 102069 FFIOContext *const ctx = (FFIOContext *)s;
517 204138 int max_buffer_size = s->max_packet_size ?
518
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 102069 times.
102069 s->max_packet_size : IO_BUFFER_SIZE;
519
2/2
✓ Branch 0 taken 25307 times.
✓ Branch 1 taken 76762 times.
102069 uint8_t *dst = s->buf_end - s->buffer + max_buffer_size <= s->buffer_size ?
520 s->buf_end : s->buffer;
521 102069 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 78 times.
✓ Branch 1 taken 101991 times.
✓ Branch 2 taken 74 times.
✓ Branch 3 taken 4 times.
102069 if (!s->read_packet && s->buf_ptr >= s->buf_end)
525 74 s->eof_reached = 1;
526
527 /* no need to do anything if EOF already reached */
528
2/2
✓ Branch 0 taken 11763 times.
✓ Branch 1 taken 90306 times.
102069 if (s->eof_reached)
529 11763 return;
530
531
3/4
✓ Branch 0 taken 446 times.
✓ Branch 1 taken 89860 times.
✓ Branch 2 taken 446 times.
✗ Branch 3 not taken.
90306 if (s->update_checksum && dst == s->buffer) {
532
2/2
✓ Branch 0 taken 372 times.
✓ Branch 1 taken 74 times.
446 if (s->buf_end > s->checksum_ptr)
533 372 s->checksum = s->update_checksum(s->checksum, s->checksum_ptr,
534 372 s->buf_end - s->checksum_ptr);
535 446 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 90302 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 90302 times.
✗ Branch 3 not taken.
90306 if (s->read_packet && ctx->orig_buffer_size &&
540
3/4
✓ Branch 0 taken 442 times.
✓ Branch 1 taken 89860 times.
✓ Branch 2 taken 442 times.
✗ Branch 3 not taken.
90302 s->buffer_size > ctx->orig_buffer_size && len >= ctx->orig_buffer_size) {
541
4/4
✓ Branch 0 taken 76 times.
✓ Branch 1 taken 366 times.
✓ Branch 2 taken 23 times.
✓ Branch 3 taken 53 times.
442 if (dst == s->buffer && s->buf_ptr != dst) {
542 23 int ret = set_buf_size(s, ctx->orig_buffer_size);
543
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 23 times.
23 if (ret < 0)
544 ✗ av_log(s, AV_LOG_WARNING, "Failed to decrease buffer size\n");
545
546 23 s->checksum_ptr = dst = s->buffer;
547 }
548 442 len = ctx->orig_buffer_size;
549 }
550
551 90306 len = read_packet_wrapper(s, dst, len);
552
2/2
✓ Branch 0 taken 13048 times.
✓ Branch 1 taken 77258 times.
90306 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 13048 s->eof_reached = 1;
556
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 77254 times.
77258 } else if (len < 0) {
557 4 s->eof_reached = 1;
558 4 s->error= len;
559 } else {
560 77254 s->pos += len;
561 77254 s->buf_ptr = dst;
562 77254 s->buf_end = dst + len;
563 77254 ffiocontext(s)->bytes_read += len;
564 77254 s->bytes_read = ffiocontext(s)->bytes_read;
565 }
566 }
567
568 36122 unsigned long ff_crc04C11DB7_update(unsigned long checksum, const uint8_t *buf,
569 unsigned int len)
570 {
571 36122 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 194 unsigned long ff_crcA001_update(unsigned long checksum, const uint8_t *buf,
581 unsigned int len)
582 {
583 194 return av_crc(av_crc_get_table(AV_CRC_16_ANSI_LE), checksum, buf, len);
584 }
585
586 32694 unsigned long ffio_get_checksum(AVIOContext *s)
587 {
588 65388 s->checksum = s->update_checksum(s->checksum, s->checksum_ptr,
589 32694 s->buf_ptr - s->checksum_ptr);
590 32694 s->update_checksum = NULL;
591 32694 return s->checksum;
592 }
593
594 32845 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 32845 s->update_checksum = update_checksum;
599
2/2
✓ Branch 0 taken 32785 times.
✓ Branch 1 taken 60 times.
32845 if (s->update_checksum) {
600 32785 s->checksum = checksum;
601 32785 s->checksum_ptr = s->buf_ptr;
602 }
603 32845 }
604
605 /* XXX: put an inline version */
606 7994987 int avio_r8(AVIOContext *s)
607 {
608
2/2
✓ Branch 0 taken 26231 times.
✓ Branch 1 taken 7968756 times.
7994987 if (s->buf_ptr >= s->buf_end)
609 26231 fill_buffer(s);
610
2/2
✓ Branch 0 taken 7982410 times.
✓ Branch 1 taken 12577 times.
7994987 if (s->buf_ptr < s->buf_end)
611 7982410 return *s->buf_ptr++;
612 12577 return 0;
613 }
614
615 774291 int avio_read(AVIOContext *s, unsigned char *buf, int size)
616 {
617 int len, size1;
618
619 774291 size1 = size;
620
2/2
✓ Branch 0 taken 846046 times.
✓ Branch 1 taken 771588 times.
1617634 while (size > 0) {
621 846046 len = FFMIN(s->buf_end - s->buf_ptr, size);
622
3/4
✓ Branch 0 taken 664496 times.
✓ Branch 1 taken 181550 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 664496 times.
846046 if (len == 0 || s->write_flag) {
623
8/8
✓ Branch 0 taken 181497 times.
✓ Branch 1 taken 53 times.
✓ Branch 2 taken 137251 times.
✓ Branch 3 taken 44246 times.
✓ Branch 4 taken 137295 times.
✓ Branch 5 taken 9 times.
✓ Branch 6 taken 137294 times.
✓ Branch 7 taken 1 times.
181550 if((s->direct || size > s->buffer_size) && !s->update_checksum && s->read_packet) {
624 // bypass the buffer and read data directly into buf
625 137294 len = read_packet_wrapper(s, buf, size);
626
2/2
✓ Branch 0 taken 586 times.
✓ Branch 1 taken 136708 times.
137294 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 586 s->eof_reached = 1;
630 586 break;
631
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 136708 times.
136708 } else if (len < 0) {
632 ✗ s->eof_reached = 1;
633 ✗ s->error= len;
634 ✗ break;
635 } else {
636 136708 s->pos += len;
637 136708 ffiocontext(s)->bytes_read += len;
638 136708 s->bytes_read = ffiocontext(s)->bytes_read;
639 136708 size -= len;
640 136708 buf += len;
641 // reset the buffer
642 136708 s->buf_ptr = s->buffer;
643 136708 s->buf_end = s->buffer/* + len*/;
644 }
645 } else {
646 44256 fill_buffer(s);
647 44256 len = s->buf_end - s->buf_ptr;
648
2/2
✓ Branch 0 taken 2117 times.
✓ Branch 1 taken 42139 times.
44256 if (len == 0)
649 2117 break;
650 }
651 } else {
652 664496 memcpy(buf, s->buf_ptr, len);
653 664496 buf += len;
654 664496 s->buf_ptr += len;
655 664496 size -= len;
656 }
657 }
658
2/2
✓ Branch 0 taken 3639 times.
✓ Branch 1 taken 770652 times.
774291 if (size1 == size) {
659
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3639 times.
3639 if (s->error) return s->error;
660
2/2
✓ Branch 1 taken 1908 times.
✓ Branch 2 taken 1731 times.
3639 if (avio_feof(s)) return AVERROR_EOF;
661 }
662 772383 return size1 - size;
663 }
664
665 177551 int ffio_read_size(AVIOContext *s, unsigned char *buf, int size)
666 {
667 177551 int ret = avio_read(s, buf, size);
668
2/2
✓ Branch 0 taken 177472 times.
✓ Branch 1 taken 79 times.
177551 if (ret == size)
669 177472 return ret;
670
3/4
✓ Branch 0 taken 55 times.
✓ Branch 1 taken 24 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 55 times.
79 if (ret < 0 && ret != AVERROR_EOF)
671 ✗ return ret;
672 79 return AVERROR_INVALIDDATA;
673 }
674
675 465747 int ffio_read_indirect(AVIOContext *s, unsigned char *buf, int size, const unsigned char **data)
676 {
677
3/4
✓ Branch 0 taken 462453 times.
✓ Branch 1 taken 3294 times.
✓ Branch 2 taken 462453 times.
✗ Branch 3 not taken.
465747 if (s->buf_end - s->buf_ptr >= size && !s->write_flag) {
678 462453 *data = s->buf_ptr;
679 462453 s->buf_ptr += size;
680 462453 return size;
681 } else {
682 3294 *data = buf;
683 3294 return avio_read(s, buf, size);
684 }
685 }
686
687 608333 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 608333 times.
608333 if (size < 0)
692 ✗ return AVERROR(EINVAL);
693
694
2/4
✓ Branch 0 taken 608333 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 608333 times.
608333 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 608333 len = s->buf_end - s->buf_ptr;
702
2/2
✓ Branch 0 taken 20714 times.
✓ Branch 1 taken 587619 times.
608333 if (len == 0) {
703 20714 fill_buffer(s);
704 20714 len = s->buf_end - s->buf_ptr;
705 }
706
2/2
✓ Branch 0 taken 587109 times.
✓ Branch 1 taken 21224 times.
608333 if (len > size)
707 587109 len = size;
708 608333 memcpy(buf, s->buf_ptr, len);
709 608333 s->buf_ptr += len;
710
2/2
✓ Branch 0 taken 2016 times.
✓ Branch 1 taken 606317 times.
608333 if (!len) {
711
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2016 times.
2016 if (s->error) return s->error;
712
1/2
✓ Branch 1 taken 2016 times.
✗ Branch 2 not taken.
2016 if (avio_feof(s)) return AVERROR_EOF;
713 }
714 606317 return len;
715 }
716
717 #define AVIO_READER(name, type, bytes, load, read1, shift1, read2, shift2) \
718 type name(AVIOContext *s) \
719 { \
720 type val; \
721 if (s->buf_end - s->buf_ptr >= bytes) { \
722 val = load(s->buf_ptr); \
723 s->buf_ptr += bytes; \
724 } else { \
725 val = (type)read1(s) << shift1; \
726 val |= (type)read2(s) << shift2; \
727 } \
728 return val; \
729 }
730
731
2/2
✓ Branch 0 taken 39209 times.
✓ Branch 1 taken 4474 times.
43683 AVIO_READER(avio_rl16, unsigned int, 2, AV_RL16, avio_r8, 0, avio_r8, 8)
732
2/2
✓ Branch 0 taken 324 times.
✓ Branch 1 taken 13 times.
337 AVIO_READER(avio_rl24, unsigned int, 3, AV_RL24, avio_rl16, 0, avio_r8, 16)
733
2/2
✓ Branch 0 taken 410368 times.
✓ Branch 1 taken 2592 times.
412960 AVIO_READER(avio_rl32, unsigned int, 4, AV_RL32, avio_rl16, 0, avio_rl16, 16)
734
2/2
✓ Branch 0 taken 5633 times.
✓ Branch 1 taken 74 times.
5707 AVIO_READER(avio_rl64, uint64_t, 8, AV_RL64, avio_rl32, 0, avio_rl32, 32)
735
2/2
✓ Branch 0 taken 109641 times.
✓ Branch 1 taken 4479 times.
114120 AVIO_READER(avio_rb16, unsigned int, 2, AV_RB16, avio_r8, 8, avio_r8, 0)
736
2/2
✓ Branch 0 taken 30825 times.
✓ Branch 1 taken 159 times.
30984 AVIO_READER(avio_rb24, unsigned int, 3, AV_RB24, avio_rb16, 8, avio_r8, 0)
737
2/2
✓ Branch 0 taken 258848 times.
✓ Branch 1 taken 3795 times.
262643 AVIO_READER(avio_rb32, unsigned int, 4, AV_RB32, avio_rb16, 16, avio_rb16, 0)
738
2/2
✓ Branch 0 taken 146944 times.
✓ Branch 1 taken 265 times.
147209 AVIO_READER(avio_rb64, uint64_t, 8, AV_RB64, avio_rb32, 32, avio_rb32, 0)
739 1050 int ff_get_line(AVIOContext *s, char *buf, int maxlen)
740 {
741 1050 int i = 0;
742 char c;
743
744 do {
745 26889 c = avio_r8(s);
746
3/4
✓ Branch 0 taken 26849 times.
✓ Branch 1 taken 40 times.
✓ Branch 2 taken 26849 times.
✗ Branch 3 not taken.
26889 if (c && i < maxlen-1)
747 26849 buf[i++] = c;
748
6/6
✓ Branch 0 taken 26189 times.
✓ Branch 1 taken 700 times.
✓ Branch 2 taken 25879 times.
✓ Branch 3 taken 310 times.
✓ Branch 4 taken 25839 times.
✓ Branch 5 taken 40 times.
26889 } while (c != '\n' && c != '\r' && c);
749
3/6
✓ Branch 0 taken 310 times.
✓ Branch 1 taken 740 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 310 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
1050 if (c == '\r' && avio_r8(s) != '\n' && !avio_feof(s))
750 ✗ avio_skip(s, -1);
751
752 1050 buf[i] = 0;
753 1050 return i;
754 }
755
756 349 int ff_get_chomp_line(AVIOContext *s, char *buf, int maxlen)
757 {
758 349 int len = ff_get_line(s, buf, maxlen);
759
4/4
✓ Branch 0 taken 649 times.
✓ Branch 1 taken 25 times.
✓ Branch 2 taken 325 times.
✓ Branch 3 taken 324 times.
674 while (len > 0 && av_isspace(buf[len - 1]))
760 325 buf[--len] = '\0';
761 349 return len;
762 }
763
764 typedef enum FFBPrintReadStringMode {
765 FFBPrintReadString = 0,
766 FFBPrintReadLine = 1,
767 } FFBPrintReadStringMode;
768
769 348 static int64_t read_string_to_bprint(AVIOContext *s, AVBPrint *bp,
770 FFBPrintReadStringMode mode,
771 int64_t max_len)
772 {
773 int len, end;
774 348 int64_t read = 0;
775 char tmp[1024];
776 char c;
777
778
1/2
✓ Branch 0 taken 348 times.
✗ Branch 1 not taken.
348 if (!max_len)
779 ✗ return 0;
780
781 do {
782 348 len = 0;
783 do {
784 5467 c = avio_r8(s);
785
7/8
✓ Branch 0 taken 4701 times.
✓ Branch 1 taken 766 times.
✓ Branch 2 taken 4701 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 4424 times.
✓ Branch 5 taken 277 times.
✓ Branch 6 taken 71 times.
✓ Branch 7 taken 5119 times.
5467 end = ((mode == FFBPrintReadLine && (c == '\r' || c == '\n')) ||
786 c == '\0');
787
2/2
✓ Branch 0 taken 5119 times.
✓ Branch 1 taken 348 times.
5467 if (!end)
788 5119 tmp[len++] = c;
789
5/6
✓ Branch 0 taken 5119 times.
✓ Branch 1 taken 348 times.
✓ Branch 2 taken 5119 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 4418 times.
✓ Branch 5 taken 701 times.
5467 } while (!end && len < sizeof(tmp) &&
790
1/2
✓ Branch 0 taken 701 times.
✗ Branch 1 not taken.
701 ((max_len < 0) || (read + len < max_len)));
791 348 av_bprint_append_data(bp, tmp, len);
792 348 read += len;
793
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 348 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
348 } while (!end && ((max_len < 0) || (read < max_len)));
794
795
3/4
✓ Branch 0 taken 283 times.
✓ Branch 1 taken 65 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 283 times.
348 if (mode == FFBPrintReadLine &&
796 ✗ c == '\r' && avio_r8(s) != '\n' && !avio_feof(s))
797 ✗ avio_skip(s, -1);
798
799
3/4
✓ Branch 0 taken 71 times.
✓ Branch 1 taken 277 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 71 times.
348 if (!c && s->error)
800 ✗ return s->error;
801
802
6/6
✓ Branch 0 taken 71 times.
✓ Branch 1 taken 277 times.
✓ Branch 2 taken 7 times.
✓ Branch 3 taken 64 times.
✓ Branch 5 taken 6 times.
✓ Branch 6 taken 1 times.
348 if (!c && !read && avio_feof(s))
803 6 return AVERROR_EOF;
804
805 342 return read;
806 }
807
808 348 static int64_t read_string_to_bprint_overwrite(AVIOContext *s, AVBPrint *bp,
809 FFBPrintReadStringMode mode,
810 int64_t max_len)
811 {
812 int64_t ret;
813
814 348 av_bprint_clear(bp);
815 348 ret = read_string_to_bprint(s, bp, mode, max_len);
816
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 342 times.
348 if (ret < 0)
817 6 return ret;
818
819
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 342 times.
342 if (!av_bprint_is_complete(bp))
820 ✗ return AVERROR(ENOMEM);
821
822 342 return bp->len;
823 }
824
825 283 int64_t ff_read_line_to_bprint_overwrite(AVIOContext *s, AVBPrint *bp)
826 {
827 283 return read_string_to_bprint_overwrite(s, bp, FFBPrintReadLine, -1);
828 }
829
830 65 int64_t ff_read_string_to_bprint_overwrite(AVIOContext *s, AVBPrint *bp,
831 int64_t max_len)
832 {
833 65 return read_string_to_bprint_overwrite(s, bp, FFBPrintReadString, max_len);
834 }
835
836 642 int avio_get_str(AVIOContext *s, int maxlen, char *buf, int buflen)
837 {
838 int i;
839
840
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 642 times.
642 if (buflen <= 0)
841 ✗ return AVERROR(EINVAL);
842 // reserve 1 byte for terminating 0
843 642 buflen = FFMIN(buflen - 1, maxlen);
844
2/2
✓ Branch 0 taken 9503 times.
✓ Branch 1 taken 272 times.
9775 for (i = 0; i < buflen; i++)
845
2/2
✓ Branch 1 taken 370 times.
✓ Branch 2 taken 9133 times.
9503 if (!(buf[i] = avio_r8(s)))
846 370 return i + 1;
847 272 buf[i] = 0;
848
2/2
✓ Branch 0 taken 280 times.
✓ Branch 1 taken 262 times.
542 for (; i < maxlen; i++)
849
2/2
✓ Branch 1 taken 10 times.
✓ Branch 2 taken 270 times.
280 if (!avio_r8(s))
850 10 return i + 1;
851 262 return maxlen;
852 }
853
854 #define GET_STR16(type, read) \
855 int avio_get_str16 ##type(AVIOContext *pb, int maxlen, char *buf, int buflen)\
856 {\
857 char* q = buf;\
858 int ret = 0;\
859 if (buflen <= 0) \
860 return AVERROR(EINVAL); \
861 while (ret + 1 < maxlen) {\
862 uint8_t tmp;\
863 uint32_t ch;\
864 GET_UTF16(ch, (ret += 2) <= maxlen ? read(pb) : 0, break;)\
865 if (!ch)\
866 break;\
867 PUT_UTF8(ch, tmp, if (q - buf < buflen - 1) *q++ = tmp;)\
868 }\
869 *q = 0;\
870 return ret;\
871 }\
872
873
14/26
✗ Branch 0 not taken.
✓ Branch 1 taken 778 times.
✓ Branch 2 taken 10277 times.
✗ Branch 3 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 10277 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 756 times.
✓ Branch 15 taken 9521 times.
✓ Branch 16 taken 9518 times.
✓ Branch 17 taken 3 times.
✓ Branch 18 taken 9518 times.
✗ Branch 19 not taken.
✓ Branch 20 taken 3 times.
✗ Branch 21 not taken.
✓ Branch 22 taken 3 times.
✗ Branch 23 not taken.
✓ Branch 24 taken 3 times.
✓ Branch 25 taken 3 times.
✓ Branch 26 taken 10277 times.
✓ Branch 27 taken 22 times.
10302 GET_STR16(le, avio_rl16)
874
9/26
✗ Branch 0 not taken.
✓ Branch 1 taken 615 times.
✓ Branch 2 taken 5642 times.
✗ Branch 3 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 5642 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 555 times.
✓ Branch 15 taken 5087 times.
✓ Branch 16 taken 5087 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 5087 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 5642 times.
✓ Branch 27 taken 60 times.
5702 GET_STR16(be, avio_rb16)
875
876 #undef GET_STR16
877
878 15934 uint64_t ffio_read_varlen(AVIOContext *bc){
879 15934 uint64_t val = 0;
880 int tmp;
881
882 do{
883 24651 tmp = avio_r8(bc);
884 24651 val= (val<<7) + (tmp&127);
885
2/2
✓ Branch 0 taken 8717 times.
✓ Branch 1 taken 15934 times.
24651 }while(tmp&128);
886 15934 return val;
887 }
888
889 1429 unsigned int ffio_read_leb(AVIOContext *s) {
890 1429 int more, i = 0;
891 1429 unsigned leb = 0;
892
893 do {
894 1963 int byte = avio_r8(s);
895 1963 unsigned bits = byte & 0x7f;
896 1963 more = byte & 0x80;
897
1/2
✓ Branch 0 taken 1963 times.
✗ Branch 1 not taken.
1963 if (i <= 4)
898 1963 leb |= bits << (i * 7);
899
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1963 times.
1963 if (++i == 8)
900 ✗ break;
901
2/2
✓ Branch 0 taken 534 times.
✓ Branch 1 taken 1429 times.
1963 } while (more);
902
903 1429 return leb;
904 }
905
906 6513 void ffio_write_leb(AVIOContext *s, unsigned val)
907 {
908 int len;
909 uint8_t byte;
910
911 6513 len = (av_log2(val) + 7) / 7;
912
913
2/2
✓ Branch 0 taken 11335 times.
✓ Branch 1 taken 6513 times.
17848 for (int i = 0; i < len; i++) {
914 11335 byte = val >> (7 * i) & 0x7f;
915
2/2
✓ Branch 0 taken 4822 times.
✓ Branch 1 taken 6513 times.
11335 if (i < len - 1)
916 4822 byte |= 0x80;
917
918 11335 avio_w8(s, byte);
919 }
920 6513 }
921
922 28 void ffio_write_lines(AVIOContext *s, const unsigned char *buf, int size,
923 const unsigned char *ending)
924 {
925
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 28 times.
28 int ending_len = ending ? strlen(ending) : 1;
926
1/2
✓ Branch 0 taken 28 times.
✗ Branch 1 not taken.
28 if (!ending)
927 28 ending = "\n";
928
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 28 times.
28 if (size < 0)
929 ✗ size = strlen(buf);
930
931
2/2
✓ Branch 0 taken 439 times.
✓ Branch 1 taken 28 times.
467 while (size > 0) {
932 439 size_t len = 0;
933 439 char last = 0;
934
1/2
✓ Branch 0 taken 19804 times.
✗ Branch 1 not taken.
19804 for (; len < size; len++) {
935 19804 last = buf[len];
936
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')
937 break;
938 }
939
940 439 avio_write(s, buf, len);
941 439 avio_write(s, ending, ending_len);
942
943 439 buf += len + 1;
944 439 size -= len + 1;
945
946
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') {
947 103 buf++;
948 103 size--;
949 }
950 }
951 28 }
952
953 19 int ffio_copy_url_options(AVIOContext* pb, AVDictionary** avio_opts)
954 {
955 19 const char *opts[] = {
956 "headers", "user_agent", "cookies", "http_proxy", "referer", "rw_timeout", "icy", "prefer_libcurl", NULL };
957 19 const char **opt = opts;
958 19 uint8_t *buf = NULL;
959 19 int ret = 0;
960
961
2/2
✓ Branch 0 taken 152 times.
✓ Branch 1 taken 19 times.
171 while (*opt) {
962
2/2
✓ Branch 1 taken 38 times.
✓ Branch 2 taken 114 times.
152 if (av_opt_get(pb, *opt, AV_OPT_SEARCH_CHILDREN, &buf) >= 0) {
963
1/2
✓ Branch 0 taken 38 times.
✗ Branch 1 not taken.
38 if (buf[0] != '\0') {
964 38 ret = av_dict_set(avio_opts, *opt, buf, AV_DICT_DONT_STRDUP_VAL);
965
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 38 times.
38 if (ret < 0)
966 ✗ return ret;
967 } else {
968 ✗ av_freep(&buf);
969 }
970 }
971 152 opt++;
972 }
973
974 19 return ret;
975 }
976
977 16 static void update_checksum(AVIOContext *s)
978 {
979
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
16 if (s->update_checksum && s->buf_ptr > s->checksum_ptr) {
980 ✗ s->checksum = s->update_checksum(s->checksum, s->checksum_ptr,
981 ✗ s->buf_ptr - s->checksum_ptr);
982 }
983 16 }
984
985 24345 int ffio_ensure_seekback(AVIOContext *s, int64_t buf_size)
986 {
987 uint8_t *buffer;
988 48690 int max_buffer_size = s->max_packet_size ?
989
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 24345 times.
24345 s->max_packet_size : IO_BUFFER_SIZE;
990 24345 ptrdiff_t filled = s->buf_end - s->buf_ptr;
991
992
2/2
✓ Branch 0 taken 21533 times.
✓ Branch 1 taken 2812 times.
24345 if (buf_size <= s->buf_end - s->buf_ptr)
993 21533 return 0;
994
995
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2812 times.
2812 if (buf_size > INT_MAX - max_buffer_size)
996 ✗ return AVERROR(EINVAL);
997
998 2812 buf_size += max_buffer_size - 1;
999
1000
5/6
✓ Branch 0 taken 2812 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 27 times.
✓ Branch 3 taken 2785 times.
✓ Branch 4 taken 11 times.
✓ Branch 5 taken 16 times.
2812 if (buf_size + s->buf_ptr - s->buffer <= s->buffer_size || s->seekable || !s->read_packet)
1001 2796 return 0;
1002
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
16 av_assert0(!s->write_flag);
1003
1004
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
16 if (buf_size <= s->buffer_size) {
1005 ✗ update_checksum(s);
1006 ✗ memmove(s->buffer, s->buf_ptr, filled);
1007 } else {
1008 16 buffer = av_malloc(buf_size);
1009
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
16 if (!buffer)
1010 ✗ return AVERROR(ENOMEM);
1011 16 update_checksum(s);
1012 16 memcpy(buffer, s->buf_ptr, filled);
1013 16 av_free(s->buffer);
1014 16 s->buffer = buffer;
1015 16 s->buffer_size = buf_size;
1016 }
1017 16 s->buf_ptr = s->buffer;
1018 16 s->buf_end = s->buffer + filled;
1019 16 s->checksum_ptr = s->buffer;
1020 16 return 0;
1021 }
1022
1023 6869 int ffio_limit(AVIOContext *s, int size)
1024 {
1025 6869 FFIOContext *const ctx = ffiocontext(s);
1026
2/2
✓ Branch 0 taken 6842 times.
✓ Branch 1 taken 27 times.
6869 if (ctx->maxsize >= 0) {
1027 6842 int64_t pos = avio_tell(s);
1028 6842 int64_t remaining = ctx->maxsize - pos;
1029
2/2
✓ Branch 0 taken 460 times.
✓ Branch 1 taken 6382 times.
6842 if (remaining < size) {
1030 460 int64_t newsize = avio_size(s);
1031
3/4
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 455 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 5 times.
460 if (!ctx->maxsize || ctx->maxsize < newsize)
1032 455 ctx->maxsize = newsize - !newsize;
1033
4/4
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 458 times.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 1 times.
460 if (pos > ctx->maxsize && ctx->maxsize >= 0)
1034 1 ctx->maxsize = AVERROR(EIO);
1035
2/2
✓ Branch 0 taken 458 times.
✓ Branch 1 taken 2 times.
460 if (ctx->maxsize >= 0)
1036 458 remaining = ctx->maxsize - pos;
1037 }
1038
1039
5/6
✓ Branch 0 taken 6840 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 5 times.
✓ Branch 3 taken 6835 times.
✓ Branch 4 taken 5 times.
✗ Branch 5 not taken.
6842 if (ctx->maxsize >= 0 && remaining < size && size > 1) {
1040 5 av_log(NULL, remaining ? AV_LOG_ERROR : AV_LOG_DEBUG,
1041 "Truncating packet of size %d to %"PRId64"\n",
1042
1/2
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
5 size, remaining + !remaining);
1043 5 size = remaining + !remaining;
1044 }
1045 }
1046 6869 return size;
1047 }
1048
1049 23 static int set_buf_size(AVIOContext *s, int buf_size)
1050 {
1051 uint8_t *buffer;
1052 23 buffer = av_malloc(buf_size);
1053
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 23 times.
23 if (!buffer)
1054 ✗ return AVERROR(ENOMEM);
1055
1056 23 av_free(s->buffer);
1057 23 s->buffer = buffer;
1058 46 ffiocontext(s)->orig_buffer_size =
1059 23 s->buffer_size = buf_size;
1060 23 s->buf_ptr = s->buf_ptr_max = buffer;
1061
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 23 times.
23 url_resetbuf(s, s->write_flag ? AVIO_FLAG_WRITE : AVIO_FLAG_READ);
1062 23 return 0;
1063 }
1064
1065 ✗ int ffio_realloc_buf(AVIOContext *s, int buf_size)
1066 {
1067 uint8_t *buffer;
1068 int data_size;
1069
1070 ✗ if (!s->buffer_size)
1071 ✗ return set_buf_size(s, buf_size);
1072
1073 ✗ if (buf_size <= s->buffer_size)
1074 ✗ return 0;
1075
1076 ✗ buffer = av_malloc(buf_size);
1077 ✗ if (!buffer)
1078 ✗ return AVERROR(ENOMEM);
1079
1080 ✗ data_size = s->write_flag ? (s->buf_ptr - s->buffer) : (s->buf_end - s->buf_ptr);
1081 ✗ if (data_size > 0)
1082 ✗ memcpy(buffer, s->write_flag ? s->buffer : s->buf_ptr, data_size);
1083 ✗ av_free(s->buffer);
1084 ✗ s->buffer = buffer;
1085 ✗ ffiocontext(s)->orig_buffer_size = buf_size;
1086 ✗ s->buffer_size = buf_size;
1087 ✗ s->buf_ptr = s->write_flag ? (s->buffer + data_size) : s->buffer;
1088 ✗ if (s->write_flag)
1089 ✗ s->buf_ptr_max = s->buffer + data_size;
1090
1091 ✗ s->buf_end = s->write_flag ? (s->buffer + s->buffer_size) : (s->buf_ptr + data_size);
1092
1093 ✗ return 0;
1094 }
1095
1096 253487 static int url_resetbuf(AVIOContext *s, int flags)
1097 {
1098 av_assert1(flags == AVIO_FLAG_WRITE || flags == AVIO_FLAG_READ);
1099
1100
2/2
✓ Branch 0 taken 57727 times.
✓ Branch 1 taken 195760 times.
253487 if (flags & AVIO_FLAG_WRITE) {
1101 57727 s->buf_end = s->buffer + s->buffer_size;
1102 57727 s->write_flag = 1;
1103 } else {
1104 195760 s->buf_end = s->buffer;
1105 195760 s->write_flag = 0;
1106 }
1107 253487 return 0;
1108 }
1109
1110 4183 int ffio_rewind_with_probe_data(AVIOContext *s, unsigned char **bufp, int buf_size)
1111 {
1112 int64_t buffer_start;
1113 int buffer_size;
1114 int overlap, new_size, alloc_size;
1115 4183 uint8_t *buf = *bufp;
1116
1117
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4183 times.
4183 if (s->write_flag) {
1118 ✗ av_freep(bufp);
1119 ✗ return AVERROR(EINVAL);
1120 }
1121
1122 4183 buffer_size = s->buf_end - s->buffer;
1123
1124 /* the buffers must touch or overlap */
1125
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4183 times.
4183 if ((buffer_start = s->pos - buffer_size) > buf_size) {
1126 ✗ av_freep(bufp);
1127 ✗ return AVERROR(EINVAL);
1128 }
1129
1130 4183 overlap = buf_size - buffer_start;
1131 4183 new_size = buf_size + buffer_size - overlap;
1132
1133 4183 alloc_size = FFMAX(s->buffer_size, new_size);
1134
2/2
✓ Branch 0 taken 4127 times.
✓ Branch 1 taken 56 times.
4183 if (alloc_size > buf_size)
1135
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 4127 times.
4127 if (!(buf = (*bufp) = av_realloc_f(buf, 1, alloc_size)))
1136 ✗ return AVERROR(ENOMEM);
1137
1138
2/2
✓ Branch 0 taken 3930 times.
✓ Branch 1 taken 253 times.
4183 if (new_size > buf_size) {
1139 3930 memcpy(buf + buf_size, s->buffer + overlap, buffer_size - overlap);
1140 3930 buf_size = new_size;
1141 }
1142
1143 4183 av_free(s->buffer);
1144 4183 s->buf_ptr = s->buffer = buf;
1145 4183 s->buffer_size = alloc_size;
1146 4183 s->pos = buf_size;
1147 4183 s->buf_end = s->buf_ptr + buf_size;
1148 4183 s->eof_reached = 0;
1149
1150 4183 return 0;
1151 }
1152
1153 26979 int avio_vprintf(AVIOContext *s, const char *fmt, va_list ap)
1154 {
1155 AVBPrint bp;
1156
1157 26979 av_bprint_init(&bp, 0, INT_MAX);
1158 26979 av_vbprintf(&bp, fmt, ap);
1159
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 26979 times.
26979 if (!av_bprint_is_complete(&bp)) {
1160 ✗ av_bprint_finalize(&bp, NULL);
1161 ✗ s->error = AVERROR(ENOMEM);
1162 ✗ return AVERROR(ENOMEM);
1163 }
1164 26979 avio_write(s, bp.str, bp.len);
1165 26979 av_bprint_finalize(&bp, NULL);
1166 26979 return bp.len;
1167 }
1168
1169 26712 int avio_printf(AVIOContext *s, const char *fmt, ...)
1170 {
1171 va_list ap;
1172 int ret;
1173
1174 26712 va_start(ap, fmt);
1175 26712 ret = avio_vprintf(s, fmt, ap);
1176 26712 va_end(ap);
1177
1178 26712 return ret;
1179 }
1180
1181 485 void avio_print_string_array(AVIOContext *s, const char *const strings[])
1182 {
1183
2/2
✓ Branch 0 taken 1455 times.
✓ Branch 1 taken 485 times.
1940 for(; *strings; strings++)
1184 1455 avio_write(s, (const unsigned char *)*strings, strlen(*strings));
1185 485 }
1186
1187 ✗ int avio_pause(AVIOContext *s, int pause)
1188 {
1189 ✗ if (!s->read_pause)
1190 ✗ return AVERROR(ENOSYS);
1191 ✗ return s->read_pause(s->opaque, pause);
1192 }
1193
1194 315 int64_t avio_seek_time(AVIOContext *s, int stream_index,
1195 int64_t timestamp, int flags)
1196 {
1197 int64_t ret;
1198
1/2
✓ Branch 0 taken 315 times.
✗ Branch 1 not taken.
315 if (!s->read_seek)
1199 315 return AVERROR(ENOSYS);
1200 ✗ ret = s->read_seek(s->opaque, stream_index, timestamp, flags);
1201 ✗ if (ret >= 0) {
1202 int64_t pos;
1203 ✗ s->buf_ptr = s->buf_end; // Flush buffer
1204 ✗ pos = s->seek(s->opaque, 0, SEEK_CUR);
1205 ✗ if (pos >= 0)
1206 ✗ s->pos = pos;
1207 ✗ else if (pos != AVERROR(ENOSYS))
1208 ✗ ret = pos;
1209 }
1210 ✗ return ret;
1211 }
1212
1213 78 int avio_read_to_bprint(AVIOContext *h, AVBPrint *pb, size_t max_size)
1214 {
1215 int ret;
1216 char buf[1024];
1217
2/2
✓ Branch 0 taken 8139 times.
✓ Branch 1 taken 2 times.
8141 while (max_size) {
1218 8139 ret = avio_read(h, buf, FFMIN(max_size, sizeof(buf)));
1219
2/2
✓ Branch 0 taken 76 times.
✓ Branch 1 taken 8063 times.
8139 if (ret == AVERROR_EOF)
1220 76 return 0;
1221
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8063 times.
8063 if (ret <= 0)
1222 ✗ return ret;
1223 8063 av_bprint_append_data(pb, buf, ret);
1224
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 8063 times.
8063 if (!av_bprint_is_complete(pb))
1225 ✗ return AVERROR(ENOMEM);
1226 8063 max_size -= ret;
1227 }
1228 2 return 0;
1229 }
1230
1231 /* output in a dynamic buffer */
1232
1233 typedef struct DynBuffer {
1234 int pos, size, allocated_size;
1235 uint8_t *buffer;
1236 int io_buffer_size;
1237 uint8_t io_buffer[1];
1238 } DynBuffer;
1239
1240 39100 static int dyn_buf_write(void *opaque, const uint8_t *buf, int buf_size)
1241 {
1242 39100 DynBuffer *d = opaque;
1243 unsigned new_size;
1244
1245 /* reallocate buffer if needed */
1246 39100 new_size = (unsigned)d->pos + buf_size;
1247
2/4
✓ Branch 0 taken 39100 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 39100 times.
39100 if (new_size < d->pos || new_size > INT_MAX)
1248 ✗ return AVERROR(ERANGE);
1249
2/2
✓ Branch 0 taken 8852 times.
✓ Branch 1 taken 30248 times.
39100 if (new_size > d->allocated_size) {
1250 19749 unsigned new_allocated_size = d->allocated_size ? d->allocated_size
1251
2/2
✓ Branch 0 taken 2045 times.
✓ Branch 1 taken 6807 times.
8852 : new_size;
1252 int err;
1253
2/2
✓ Branch 0 taken 3522 times.
✓ Branch 1 taken 8852 times.
12374 while (new_size > new_allocated_size)
1254 3522 new_allocated_size += new_allocated_size / 2 + 1;
1255
1256
1/2
✓ Branch 0 taken 8852 times.
✗ Branch 1 not taken.
8852 new_allocated_size = FFMIN(new_allocated_size, INT_MAX);
1257
1258
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 8852 times.
8852 if ((err = av_reallocp(&d->buffer, new_allocated_size)) < 0) {
1259 ✗ d->allocated_size = 0;
1260 ✗ d->size = 0;
1261 ✗ return err;
1262 }
1263 8852 d->allocated_size = new_allocated_size;
1264 }
1265 39100 memcpy(d->buffer + d->pos, buf, buf_size);
1266 39100 d->pos = new_size;
1267
2/2
✓ Branch 0 taken 38988 times.
✓ Branch 1 taken 112 times.
39100 if (d->pos > d->size)
1268 38988 d->size = d->pos;
1269 39100 return buf_size;
1270 }
1271
1272 265 static int dyn_packet_buf_write(void *opaque, const uint8_t *buf, int buf_size)
1273 {
1274 unsigned char buf1[4];
1275 int ret;
1276
1277 /* packetized write: output the header */
1278 265 AV_WB32(buf1, buf_size);
1279 265 ret = dyn_buf_write(opaque, buf1, 4);
1280
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 265 times.
265 if (ret < 0)
1281 ✗ return ret;
1282
1283 /* then the data */
1284 265 return dyn_buf_write(opaque, buf, buf_size);
1285 }
1286
1287 662 static int64_t dyn_buf_seek(void *opaque, int64_t offset, int whence)
1288 {
1289 662 DynBuffer *d = opaque;
1290
1291
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 662 times.
662 if (whence == SEEK_CUR)
1292 ✗ offset += d->pos;
1293
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 662 times.
662 else if (whence == SEEK_END)
1294 ✗ offset += d->size;
1295
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 662 times.
662 if (offset < 0)
1296 ✗ return AVERROR(EINVAL);
1297
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 662 times.
662 if (offset > INT_MAX)
1298 ✗ return AVERROR(ERANGE);
1299 662 d->pos = offset;
1300 662 return 0;
1301 }
1302
1303 25552 static int url_open_dyn_buf_internal(AVIOContext **s, int max_packet_size)
1304 {
1305 struct { FFIOContext pb; DynBuffer d; } *ret;
1306 DynBuffer *d;
1307
2/2
✓ Branch 0 taken 38 times.
✓ Branch 1 taken 25514 times.
25552 unsigned io_buffer_size = max_packet_size ? max_packet_size : 1024;
1308
1309 if (sizeof(*ret) + io_buffer_size < io_buffer_size)
1310 return AVERROR(ERANGE);
1311 25552 ret = av_mallocz(sizeof(*ret) + io_buffer_size);
1312
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 25552 times.
25552 if (!ret)
1313 ✗ return AVERROR(ENOMEM);
1314 25552 d = &ret->d;
1315 25552 d->io_buffer_size = io_buffer_size;
1316
4/4
✓ Branch 0 taken 25514 times.
✓ Branch 1 taken 38 times.
✓ Branch 2 taken 38 times.
✓ Branch 3 taken 25514 times.
25552 ffio_init_context(&ret->pb, d->io_buffer, d->io_buffer_size, 1, d, NULL,
1317 max_packet_size ? dyn_packet_buf_write : dyn_buf_write,
1318 max_packet_size ? NULL : dyn_buf_seek);
1319 25552 *s = &ret->pb.pub;
1320 25552 (*s)->max_packet_size = max_packet_size;
1321 25552 return 0;
1322 }
1323
1324 25291 int avio_open_dyn_buf(AVIOContext **s)
1325 {
1326 25291 return url_open_dyn_buf_internal(s, 0);
1327 }
1328
1329 38 int ffio_open_dyn_packet_buf(AVIOContext **s, int max_packet_size)
1330 {
1331
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 38 times.
38 if (max_packet_size <= 0)
1332 ✗ return AVERROR(EINVAL);
1333 38 return url_open_dyn_buf_internal(s, max_packet_size);
1334 }
1335
1336 29305 int avio_get_dyn_buf(AVIOContext *s, uint8_t **pbuffer)
1337 {
1338 DynBuffer *d;
1339
1340
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 29305 times.
29305 if (!s) {
1341 ✗ *pbuffer = NULL;
1342 ✗ return 0;
1343 }
1344 29305 d = s->opaque;
1345
1346
3/4
✓ Branch 0 taken 29305 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 28514 times.
✓ Branch 3 taken 791 times.
29305 if (!s->error && !d->size) {
1347 28514 *pbuffer = d->io_buffer;
1348 28514 return FFMAX(s->buf_ptr, s->buf_ptr_max) - s->buffer;
1349 }
1350
1351 791 avio_flush(s);
1352
1353 791 *pbuffer = d->buffer;
1354
1355 791 return d->size;
1356 }
1357
1358 22215 void ffio_reset_dyn_buf(AVIOContext *s)
1359 {
1360 22215 DynBuffer *d = s->opaque;
1361 22215 int max_packet_size = s->max_packet_size;
1362
1363 22215 ffio_init_context(ffiocontext(s), d->io_buffer, d->io_buffer_size,
1364 1, d, NULL, s->write_packet, s->seek);
1365 22215 s->max_packet_size = max_packet_size;
1366 22215 d->pos = d->size = 0;
1367 22215 }
1368
1369 6700 int avio_close_dyn_buf(AVIOContext *s, uint8_t **pbuffer)
1370 {
1371 DynBuffer *d;
1372 int size;
1373 6700 int padding = 0;
1374
1375
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6700 times.
6700 if (!s) {
1376 ✗ *pbuffer = NULL;
1377 ✗ return 0;
1378 }
1379
1380 /* don't attempt to pad fixed-size packet buffers */
1381
2/2
✓ Branch 0 taken 6664 times.
✓ Branch 1 taken 36 times.
6700 if (!s->max_packet_size) {
1382 6664 ffio_fill(s, 0, AV_INPUT_BUFFER_PADDING_SIZE);
1383 6664 padding = AV_INPUT_BUFFER_PADDING_SIZE;
1384 }
1385
1386 6700 avio_flush(s);
1387
1388 6700 d = s->opaque;
1389 6700 *pbuffer = d->buffer;
1390 6700 size = d->size;
1391
1392 6700 avio_context_free(&s);
1393
1394 6700 return size - padding;
1395 }
1396
1397 19843 void ffio_free_dyn_buf(AVIOContext **s)
1398 {
1399 DynBuffer *d;
1400
1401
2/2
✓ Branch 0 taken 1214 times.
✓ Branch 1 taken 18629 times.
19843 if (!*s)
1402 1214 return;
1403
1404 18629 d = (*s)->opaque;
1405 18629 av_free(d->buffer);
1406 18629 avio_context_free(s);
1407 }
1408
1409 646 static int null_buf_write(void *opaque, const uint8_t *buf, int buf_size)
1410 {
1411 646 DynBuffer *d = opaque;
1412
1413
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 646 times.
646 if ((unsigned)d->pos + (unsigned)buf_size > INT_MAX)
1414 ✗ return AVERROR(ERANGE);
1415 646 d->pos += buf_size;
1416
2/2
✓ Branch 0 taken 418 times.
✓ Branch 1 taken 228 times.
646 if (d->pos > d->size)
1417 418 d->size = d->pos;
1418 646 return buf_size;
1419 }
1420
1421 223 int ffio_open_null_buf(AVIOContext **s)
1422 {
1423 223 int ret = url_open_dyn_buf_internal(s, 0);
1424
1/2
✓ Branch 0 taken 223 times.
✗ Branch 1 not taken.
223 if (ret >= 0) {
1425 223 AVIOContext *pb = *s;
1426 223 pb->write_packet = null_buf_write;
1427 }
1428 223 return ret;
1429 }
1430
1431 223 int ffio_close_null_buf(AVIOContext *s)
1432 {
1433 223 DynBuffer *d = s->opaque;
1434 int size;
1435
1436 223 avio_flush(s);
1437
1438
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 223 times.
223 size = s->error ? s->error : d->size;
1439
1440 223 avio_context_free(&s);
1441
1442 223 return size;
1443 }
1444