FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavformat/aviobuf.c
Date: 2025-04-25 22:50:00
Exec Total Coverage
Lines: 736 846 87.0%
Functions: 86 88 97.7%
Branches: 426 604 70.5%

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 234699 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 234699 AVIOContext *const s = &ctx->pub;
60
61 234699 memset(ctx, 0, sizeof(*ctx));
62
63 234699 s->buffer = buffer;
64 234699 ctx->orig_buffer_size =
65 234699 s->buffer_size = buffer_size;
66 234699 s->buf_ptr = buffer;
67 234699 s->buf_ptr_max = buffer;
68 234699 s->opaque = opaque;
69 234699 s->direct = 0;
70
71
2/2
✓ Branch 0 taken 48912 times.
✓ Branch 1 taken 185787 times.
234699 url_resetbuf(s, write_flag ? AVIO_FLAG_WRITE : AVIO_FLAG_READ);
72
73 234699 s->write_packet = write_packet;
74 234699 s->read_packet = read_packet;
75 234699 s->seek = seek;
76 234699 s->pos = 0;
77 234699 s->eof_reached = 0;
78 234699 s->error = 0;
79 234699 s->seekable = seek ? AVIO_SEEKABLE_NORMAL : 0;
80 234699 s->min_packet_size = 0;
81 234699 s->max_packet_size = 0;
82 234699 s->update_checksum = NULL;
83 234699 ctx->short_seek_threshold = SHORT_SEEK_THRESHOLD;
84
85
4/4
✓ Branch 0 taken 121428 times.
✓ Branch 1 taken 113271 times.
✓ Branch 2 taken 81507 times.
✓ Branch 3 taken 39921 times.
234699 if (!read_packet && !write_flag) {
86 81507 s->pos = buffer_size;
87 81507 s->buf_end = s->buffer + buffer_size;
88 }
89 234699 s->read_pause = NULL;
90 234699 s->read_seek = NULL;
91
92 234699 s->write_data_type = NULL;
93 234699 s->ignore_boundary_point = 0;
94 234699 ctx->current_type = AVIO_DATA_MARKER_UNKNOWN;
95 234699 ctx->last_time = AV_NOPTS_VALUE;
96 234699 ctx->short_seek_get = NULL;
97 234699 }
98
99 81338 void ffio_init_read_context(FFIOContext *s, const uint8_t *buffer, int buffer_size)
100 {
101 81338 ffio_init_context(s, (unsigned char*)buffer, buffer_size, 0, NULL, NULL, NULL, NULL);
102 81338 }
103
104 218 void ffio_init_write_context(FFIOContext *s, uint8_t *buffer, int buffer_size)
105 {
106 218 ffio_init_context(s, buffer, buffer_size, 1, NULL, NULL, NULL, NULL);
107 218 }
108
109 113287 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 113287 FFIOContext *s = av_malloc(sizeof(*s));
119
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 113287 times.
113287 if (!s)
120 return NULL;
121 113287 ffio_init_context(s, buffer, buffer_size, write_flag, opaque,
122 read_packet, write_packet, seek);
123 113287 return &s->pub;
124 }
125
126 132084 void avio_context_free(AVIOContext **ps)
127 {
128 132084 av_freep(ps);
129 132084 }
130
131 425223 static void writeout(AVIOContext *s, const uint8_t *data, int len)
132 {
133 425223 FFIOContext *const ctx = ffiocontext(s);
134
1/2
✓ Branch 0 taken 425223 times.
✗ Branch 1 not taken.
425223 if (!s->error) {
135 425223 int ret = 0;
136
2/2
✓ Branch 0 taken 126 times.
✓ Branch 1 taken 425097 times.
425223 if (s->write_data_type)
137 126 ret = s->write_data_type(s->opaque, data,
138 len,
139 ctx->current_type,
140 ctx->last_time);
141
2/2
✓ Branch 0 taken 425090 times.
✓ Branch 1 taken 7 times.
425097 else if (s->write_packet)
142 425090 ret = s->write_packet(s->opaque, data, len);
143
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 425223 times.
425223 if (ret < 0) {
144 s->error = ret;
145 } else {
146 425223 ctx->bytes_written += len;
147 425223 s->bytes_written = ctx->bytes_written;
148
149
2/2
✓ Branch 0 taken 423388 times.
✓ Branch 1 taken 1835 times.
425223 if (s->pos + len > ctx->written_output_size) {
150 423388 ctx->written_output_size = s->pos + len;
151 }
152 }
153 }
154
2/2
✓ Branch 0 taken 425176 times.
✓ Branch 1 taken 47 times.
425223 if (ctx->current_type == AVIO_DATA_MARKER_SYNC_POINT ||
155
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 425171 times.
425176 ctx->current_type == AVIO_DATA_MARKER_BOUNDARY_POINT) {
156 52 ctx->current_type = AVIO_DATA_MARKER_UNKNOWN;
157 }
158 425223 ctx->last_time = AV_NOPTS_VALUE;
159 425223 ctx->writeout_count++;
160 425223 s->pos += len;
161 425223 }
162
163 558678 static void flush_buffer(AVIOContext *s)
164 {
165 558678 s->buf_ptr_max = FFMAX(s->buf_ptr, s->buf_ptr_max);
166
4/4
✓ Branch 0 taken 454422 times.
✓ Branch 1 taken 104256 times.
✓ Branch 2 taken 417976 times.
✓ Branch 3 taken 36446 times.
558678 if (s->write_flag && s->buf_ptr_max > s->buffer) {
167 417976 writeout(s, s->buffer, s->buf_ptr_max - s->buffer);
168
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 417976 times.
417976 if (s->update_checksum) {
169 s->checksum = s->update_checksum(s->checksum, s->checksum_ptr,
170 s->buf_ptr_max - s->checksum_ptr);
171 s->checksum_ptr = s->buffer;
172 }
173 }
174 558678 s->buf_ptr = s->buf_ptr_max = s->buffer;
175
2/2
✓ Branch 0 taken 104256 times.
✓ Branch 1 taken 454422 times.
558678 if (!s->write_flag)
176 104256 s->buf_end = s->buffer;
177 558678 }
178
179 3543620 void avio_w8(AVIOContext *s, int b)
180 {
181 av_assert2(b>=-128 && b<=255);
182 3543620 *s->buf_ptr++ = b;
183
2/2
✓ Branch 0 taken 65 times.
✓ Branch 1 taken 3543555 times.
3543620 if (s->buf_ptr >= s->buf_end)
184 65 flush_buffer(s);
185 3543620 }
186
187 33630 void ffio_fill(AVIOContext *s, int b, int64_t count)
188 {
189
2/2
✓ Branch 0 taken 21273 times.
✓ Branch 1 taken 33630 times.
54903 while (count > 0) {
190 21273 int len = FFMIN(s->buf_end - s->buf_ptr, count);
191 21273 memset(s->buf_ptr, b, len);
192 21273 s->buf_ptr += len;
193
194
2/2
✓ Branch 0 taken 194 times.
✓ Branch 1 taken 21079 times.
21273 if (s->buf_ptr >= s->buf_end)
195 194 flush_buffer(s);
196
197 21273 count -= len;
198 }
199 33630 }
200
201 717171 void avio_write(AVIOContext *s, const unsigned char *buf, int size)
202 {
203
2/2
✓ Branch 0 taken 7811 times.
✓ Branch 1 taken 709360 times.
717171 if (size <= 0)
204 7811 return;
205
3/4
✓ Branch 0 taken 7247 times.
✓ Branch 1 taken 702113 times.
✓ Branch 2 taken 7247 times.
✗ Branch 3 not taken.
709360 if (s->direct && !s->update_checksum) {
206 7247 avio_flush(s);
207 7247 writeout(s, buf, size);
208 7247 return;
209 }
210 do {
211 856001 int len = FFMIN(s->buf_end - s->buf_ptr, size);
212 856001 memcpy(s->buf_ptr, buf, len);
213 856001 s->buf_ptr += len;
214
215
2/2
✓ Branch 0 taken 154585 times.
✓ Branch 1 taken 701416 times.
856001 if (s->buf_ptr >= s->buf_end)
216 154585 flush_buffer(s);
217
218 856001 buf += len;
219 856001 size -= len;
220
2/2
✓ Branch 0 taken 153888 times.
✓ Branch 1 taken 702113 times.
856001 } while (size > 0);
221 }
222
223 400887 void avio_flush(AVIOContext *s)
224 {
225
2/2
✓ Branch 0 taken 296631 times.
✓ Branch 1 taken 104256 times.
400887 int seekback = s->write_flag ? FFMIN(0, s->buf_ptr - s->buf_ptr_max) : 0;
226 400887 flush_buffer(s);
227
2/2
✓ Branch 0 taken 127 times.
✓ Branch 1 taken 400760 times.
400887 if (seekback)
228 127 avio_seek(s, seekback, SEEK_CUR);
229 400887 }
230
231 3838324 int64_t avio_seek(AVIOContext *s, int64_t offset, int whence)
232 {
233 3838324 FFIOContext *const ctx = ffiocontext(s);
234 int64_t offset1;
235 int64_t pos;
236 3838324 int force = whence & AVSEEK_FORCE;
237 int buffer_size;
238 int short_seek;
239 3838324 whence &= ~AVSEEK_FORCE;
240
241
2/2
✓ Branch 0 taken 11729 times.
✓ Branch 1 taken 3826595 times.
3838324 if(!s)
242 11729 return AVERROR(EINVAL);
243
244
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3826595 times.
3826595 if ((whence & AVSEEK_SIZE))
245 return s->seek ? s->seek(s->opaque, offset, AVSEEK_SIZE) : AVERROR(ENOSYS);
246
247 3826595 buffer_size = s->buf_end - s->buffer;
248 // pos is the absolute position that the beginning of s->buffer corresponds to in the file
249
2/2
✓ Branch 0 taken 3569571 times.
✓ Branch 1 taken 257024 times.
3826595 pos = s->pos - (s->write_flag ? 0 : buffer_size);
250
251
3/4
✓ Branch 0 taken 216358 times.
✓ Branch 1 taken 3610237 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 216358 times.
3826595 if (whence != SEEK_CUR && whence != SEEK_SET)
252 return AVERROR(EINVAL);
253
254
2/2
✓ Branch 0 taken 3610237 times.
✓ Branch 1 taken 216358 times.
3826595 if (whence == SEEK_CUR) {
255 3610237 offset1 = pos + (s->buf_ptr - s->buffer);
256
2/2
✓ Branch 0 taken 3488050 times.
✓ Branch 1 taken 122187 times.
3610237 if (offset == 0)
257 3488050 return offset1;
258
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 122187 times.
122187 if (offset > INT64_MAX - offset1)
259 return AVERROR(EINVAL);
260 122187 offset += offset1;
261 }
262
2/2
✓ Branch 0 taken 54 times.
✓ Branch 1 taken 338491 times.
338545 if (offset < 0)
263 54 return AVERROR(EINVAL);
264
265 338491 short_seek = ctx->short_seek_threshold;
266
2/2
✓ Branch 0 taken 322905 times.
✓ Branch 1 taken 15586 times.
338491 if (ctx->short_seek_get) {
267 322905 int tmp = ctx->short_seek_get(s->opaque);
268 322905 short_seek = FFMAX(tmp, short_seek);
269 }
270
271 338491 offset1 = offset - pos; // "offset1" is the relative offset from the beginning of s->buffer
272 338491 s->buf_ptr_max = FFMAX(s->buf_ptr_max, s->buf_ptr);
273
5/6
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 338481 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 10 times.
✓ Branch 4 taken 330824 times.
✓ Branch 5 taken 7657 times.
338491 if ((!s->direct || !s->seek) &&
274
4/4
✓ Branch 0 taken 27625 times.
✓ Branch 1 taken 303199 times.
✓ Branch 2 taken 324476 times.
✓ Branch 3 taken 6348 times.
330824 offset1 >= 0 && offset1 <= (s->write_flag ? s->buf_ptr_max - s->buffer : buffer_size)) {
275 /* can do the seek inside the buffer */
276 324476 s->buf_ptr = s->buffer + offset1;
277
2/2
✓ Branch 0 taken 14008 times.
✓ Branch 1 taken 7 times.
14015 } else if ((!(s->seekable & AVIO_SEEKABLE_NORMAL) ||
278
2/2
✓ Branch 0 taken 10085 times.
✓ Branch 1 taken 3923 times.
14008 offset1 <= buffer_size + short_seek) &&
279
4/4
✓ Branch 0 taken 8076 times.
✓ Branch 1 taken 2016 times.
✓ Branch 2 taken 2171 times.
✓ Branch 3 taken 5905 times.
10092 !s->write_flag && offset1 >= 0 &&
280
4/6
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 2163 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 8 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 2163 times.
2171 (!s->direct || !s->seek) &&
281 (whence != SEEK_END || force)) {
282
4/4
✓ Branch 0 taken 2313 times.
✓ Branch 1 taken 2090 times.
✓ Branch 2 taken 2240 times.
✓ Branch 3 taken 73 times.
4403 while(s->pos < offset && !s->eof_reached)
283 2240 fill_buffer(s);
284
2/2
✓ Branch 0 taken 73 times.
✓ Branch 1 taken 2090 times.
2163 if (s->eof_reached)
285 73 return AVERROR_EOF;
286 2090 s->buf_ptr = s->buf_end - (s->pos - offset);
287
10/10
✓ Branch 0 taken 8905 times.
✓ Branch 1 taken 2947 times.
✓ Branch 2 taken 5905 times.
✓ Branch 3 taken 3000 times.
✓ Branch 4 taken 546 times.
✓ Branch 5 taken 5359 times.
✓ Branch 6 taken 544 times.
✓ Branch 7 taken 2 times.
✓ Branch 8 taken 534 times.
✓ Branch 9 taken 10 times.
11852 } else if(!s->write_flag && offset1 < 0 && -offset1 < buffer_size>>1 && s->seek && offset > 0) {
288 int64_t res;
289
290 534 pos -= FFMIN(buffer_size>>1, pos);
291
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 534 times.
534 if ((res = s->seek(s->opaque, pos, SEEK_SET)) < 0)
292 return res;
293 534 s->buf_end =
294 534 s->buf_ptr = s->buffer;
295 534 s->pos = pos;
296 534 s->eof_reached = 0;
297 534 fill_buffer(s);
298 534 return avio_seek(s, offset, SEEK_SET | force);
299 } else {
300 int64_t res;
301
2/2
✓ Branch 0 taken 2947 times.
✓ Branch 1 taken 8371 times.
11318 if (s->write_flag) {
302 2947 flush_buffer(s);
303 }
304
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 11316 times.
11318 if (!s->seek)
305 2 return AVERROR(EPIPE);
306
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 11316 times.
11316 if ((res = s->seek(s->opaque, offset, SEEK_SET)) < 0)
307 return res;
308 11316 ctx->seek_count++;
309
2/2
✓ Branch 0 taken 8369 times.
✓ Branch 1 taken 2947 times.
11316 if (!s->write_flag)
310 8369 s->buf_end = s->buffer;
311 11316 s->buf_ptr = s->buf_ptr_max = s->buffer;
312 11316 s->pos = offset;
313 }
314 337882 s->eof_reached = 0;
315 337882 return offset;
316 }
317
318 128900 int64_t avio_skip(AVIOContext *s, int64_t offset)
319 {
320 128900 return avio_seek(s, offset, SEEK_CUR);
321 }
322
323 623742 int64_t avio_size(AVIOContext *s)
324 {
325 623742 FFIOContext *const ctx = ffiocontext(s);
326 int64_t size;
327
328
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 623742 times.
623742 if (!s)
329 return AVERROR(EINVAL);
330
331
2/2
✓ Branch 0 taken 400117 times.
✓ Branch 1 taken 223625 times.
623742 if (ctx->written_output_size)
332 400117 return ctx->written_output_size;
333
334
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 223624 times.
223625 if (!s->seek)
335 1 return AVERROR(ENOSYS);
336 223624 size = s->seek(s->opaque, 0, AVSEEK_SIZE);
337
2/2
✓ Branch 0 taken 14728 times.
✓ Branch 1 taken 208896 times.
223624 if (size < 0) {
338
2/2
✓ Branch 1 taken 14723 times.
✓ Branch 2 taken 5 times.
14728 if ((size = s->seek(s->opaque, -1, SEEK_END)) < 0)
339 14723 return size;
340 5 size++;
341 5 s->seek(s->opaque, s->pos, SEEK_SET);
342 }
343 208901 return size;
344 }
345
346 6402781 int avio_feof(AVIOContext *s)
347 {
348
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6402781 times.
6402781 if(!s)
349 return 0;
350
2/2
✓ Branch 0 taken 7218 times.
✓ Branch 1 taken 6395563 times.
6402781 if(s->eof_reached){
351 7218 s->eof_reached=0;
352 7218 fill_buffer(s);
353 }
354 6402781 return s->eof_reached;
355 }
356
357 540972 void avio_wl32(AVIOContext *s, unsigned int val)
358 {
359 540972 avio_w8(s, (uint8_t) val );
360 540972 avio_w8(s, (uint8_t)(val >> 8 ));
361 540972 avio_w8(s, (uint8_t)(val >> 16));
362 540972 avio_w8(s, val >> 24 );
363 540972 }
364
365 145950 void avio_wb32(AVIOContext *s, unsigned int val)
366 {
367 145950 avio_w8(s, val >> 24 );
368 145950 avio_w8(s, (uint8_t)(val >> 16));
369 145950 avio_w8(s, (uint8_t)(val >> 8 ));
370 145950 avio_w8(s, (uint8_t) val );
371 145950 }
372
373 498 int avio_put_str(AVIOContext *s, const char *str)
374 {
375 498 int len = 1;
376
1/2
✓ Branch 0 taken 498 times.
✗ Branch 1 not taken.
498 if (str) {
377 498 len += strlen(str);
378 498 avio_write(s, (const unsigned char *) str, len);
379 } else
380 avio_w8(s, 0);
381 498 return len;
382 }
383
384 178 static inline int put_str16(AVIOContext *s, const char *str, const int be)
385 {
386 178 const uint8_t *q = str;
387 178 int ret = 0;
388 178 int err = 0;
389
390
2/2
✓ Branch 0 taken 1237 times.
✓ Branch 1 taken 178 times.
1415 while (*q) {
391 uint32_t ch;
392 uint16_t tmp;
393
394
5/8
✓ Branch 0 taken 1237 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1237 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 32 times.
✓ Branch 6 taken 32 times.
✓ Branch 7 taken 1237 times.
1269 GET_UTF8(ch, *q++, goto invalid;)
395
3/8
✓ Branch 0 taken 1237 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 918 times.
✓ Branch 3 taken 319 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
1237 PUT_UTF16(ch, tmp, be ? avio_wb16(s, tmp) : avio_wl16(s, tmp);
396 ret += 2;)
397 1237 continue;
398 invalid:
399 av_log(s, AV_LOG_ERROR, "Invalid UTF8 sequence in avio_put_str16%s\n", be ? "be" : "le");
400 err = AVERROR(EINVAL);
401 if (!*(q-1))
402 break;
403 }
404
2/2
✓ Branch 0 taken 144 times.
✓ Branch 1 taken 34 times.
178 if (be)
405 144 avio_wb16(s, 0);
406 else
407 34 avio_wl16(s, 0);
408
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 178 times.
178 if (err)
409 return err;
410 178 ret += 2;
411 178 return ret;
412 }
413
414 #define PUT_STR16(type, big_endian) \
415 int avio_put_str16 ## type(AVIOContext *s, const char *str) \
416 { \
417 return put_str16(s, str, big_endian); \
418 }
419
420 34 PUT_STR16(le, 0)
421 144 PUT_STR16(be, 1)
422
423 #undef PUT_STR16
424
425 1047 void avio_wl64(AVIOContext *s, uint64_t val)
426 {
427 1047 avio_wl32(s, (uint32_t)(val & 0xffffffff));
428 1047 avio_wl32(s, (uint32_t)(val >> 32));
429 1047 }
430
431 25890 void avio_wb64(AVIOContext *s, uint64_t val)
432 {
433 25890 avio_wb32(s, (uint32_t)(val >> 32));
434 25890 avio_wb32(s, (uint32_t)(val & 0xffffffff));
435 25890 }
436
437 28442 void avio_wl16(AVIOContext *s, unsigned int val)
438 {
439 28442 avio_w8(s, (uint8_t)val);
440 28442 avio_w8(s, (int)val >> 8);
441 28442 }
442
443 86458 void avio_wb16(AVIOContext *s, unsigned int val)
444 {
445 86458 avio_w8(s, (int)val >> 8);
446 86458 avio_w8(s, (uint8_t)val);
447 86458 }
448
449 22 void avio_wl24(AVIOContext *s, unsigned int val)
450 {
451 22 avio_wl16(s, val & 0xffff);
452 22 avio_w8(s, (int)val >> 16);
453 22 }
454
455 12250 void avio_wb24(AVIOContext *s, unsigned int val)
456 {
457 12250 avio_wb16(s, (int)val >> 8);
458 12250 avio_w8(s, (uint8_t)val);
459 12250 }
460
461 544451 void avio_write_marker(AVIOContext *s, int64_t time, enum AVIODataMarkerType type)
462 {
463 544451 FFIOContext *const ctx = ffiocontext(s);
464
2/2
✓ Branch 0 taken 523470 times.
✓ Branch 1 taken 20981 times.
544451 if (type == AVIO_DATA_MARKER_FLUSH_POINT) {
465
2/2
✓ Branch 0 taken 264039 times.
✓ Branch 1 taken 259431 times.
523470 if (s->buf_ptr - s->buffer >= s->min_packet_size)
466 264039 avio_flush(s);
467 523470 return;
468 }
469
2/2
✓ Branch 0 taken 20798 times.
✓ Branch 1 taken 183 times.
20981 if (!s->write_data_type)
470 20798 return;
471 // If ignoring boundary points, just treat it as unknown
472
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)
473 type = AVIO_DATA_MARKER_UNKNOWN;
474 // Avoid unnecessary flushes if we are already in non-header/trailer
475 // data and setting the type to unknown
476
2/2
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 155 times.
183 if (type == AVIO_DATA_MARKER_UNKNOWN &&
477
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 28 times.
28 (ctx->current_type != AVIO_DATA_MARKER_HEADER &&
478 ctx->current_type != AVIO_DATA_MARKER_TRAILER))
479 return;
480
481
2/2
✓ Branch 0 taken 103 times.
✓ Branch 1 taken 80 times.
183 switch (type) {
482 103 case AVIO_DATA_MARKER_HEADER:
483 case AVIO_DATA_MARKER_TRAILER:
484 // For header/trailer, ignore a new marker of the same type;
485 // consecutive header/trailer markers can be merged.
486
2/2
✓ Branch 0 taken 11 times.
✓ Branch 1 taken 92 times.
103 if (type == ctx->current_type)
487 11 return;
488 92 break;
489 }
490
491 // If we've reached here, we have a new, noteworthy marker.
492 // Flush the previous data and mark the start of the new data.
493 172 avio_flush(s);
494 172 ctx->current_type = type;
495 172 ctx->last_time = time;
496 }
497
498 220628 static int read_packet_wrapper(AVIOContext *s, uint8_t *buf, int size)
499 {
500 int ret;
501
502
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 220623 times.
220628 if (!s->read_packet)
503 5 return AVERROR(EINVAL);
504 220623 ret = s->read_packet(s->opaque, buf, size);
505 av_assert2(ret || s->max_packet_size);
506 220623 return ret;
507 }
508
509 /* Input stream */
510
511 95968 static void fill_buffer(AVIOContext *s)
512 {
513 95968 FFIOContext *const ctx = (FFIOContext *)s;
514 191936 int max_buffer_size = s->max_packet_size ?
515
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 95968 times.
95968 s->max_packet_size : IO_BUFFER_SIZE;
516
2/2
✓ Branch 0 taken 24105 times.
✓ Branch 1 taken 71863 times.
95968 uint8_t *dst = s->buf_end - s->buffer + max_buffer_size <= s->buffer_size ?
517 s->buf_end : s->buffer;
518 95968 int len = s->buffer_size - (dst - s->buffer);
519
520 /* can't fill the buffer without read_packet, just set EOF if appropriate */
521
4/4
✓ Branch 0 taken 11 times.
✓ Branch 1 taken 95957 times.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 5 times.
95968 if (!s->read_packet && s->buf_ptr >= s->buf_end)
522 6 s->eof_reached = 1;
523
524 /* no need to do anything if EOF already reached */
525
2/2
✓ Branch 0 taken 10137 times.
✓ Branch 1 taken 85831 times.
95968 if (s->eof_reached)
526 10137 return;
527
528
3/4
✓ Branch 0 taken 337 times.
✓ Branch 1 taken 85494 times.
✓ Branch 2 taken 337 times.
✗ Branch 3 not taken.
85831 if (s->update_checksum && dst == s->buffer) {
529
2/2
✓ Branch 0 taken 264 times.
✓ Branch 1 taken 73 times.
337 if (s->buf_end > s->checksum_ptr)
530 264 s->checksum = s->update_checksum(s->checksum, s->checksum_ptr,
531 264 s->buf_end - s->checksum_ptr);
532 337 s->checksum_ptr = s->buffer;
533 }
534
535 /* make buffer smaller in case it ended up large after probing */
536
3/4
✓ Branch 0 taken 85826 times.
✓ Branch 1 taken 5 times.
✓ Branch 2 taken 85826 times.
✗ Branch 3 not taken.
85831 if (s->read_packet && ctx->orig_buffer_size &&
537
3/4
✓ Branch 0 taken 346 times.
✓ Branch 1 taken 85480 times.
✓ Branch 2 taken 346 times.
✗ Branch 3 not taken.
85826 s->buffer_size > ctx->orig_buffer_size && len >= ctx->orig_buffer_size) {
538
3/4
✓ Branch 0 taken 22 times.
✓ Branch 1 taken 324 times.
✓ Branch 2 taken 22 times.
✗ Branch 3 not taken.
346 if (dst == s->buffer && s->buf_ptr != dst) {
539 22 int ret = set_buf_size(s, ctx->orig_buffer_size);
540
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 22 times.
22 if (ret < 0)
541 av_log(s, AV_LOG_WARNING, "Failed to decrease buffer size\n");
542
543 22 s->checksum_ptr = dst = s->buffer;
544 }
545 346 len = ctx->orig_buffer_size;
546 }
547
548 85831 len = read_packet_wrapper(s, dst, len);
549
2/2
✓ Branch 0 taken 11727 times.
✓ Branch 1 taken 74104 times.
85831 if (len == AVERROR_EOF) {
550 /* do not modify buffer if EOF reached so that a seek back can
551 be done without rereading data */
552 11727 s->eof_reached = 1;
553
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 74099 times.
74104 } else if (len < 0) {
554 5 s->eof_reached = 1;
555 5 s->error= len;
556 } else {
557 74099 s->pos += len;
558 74099 s->buf_ptr = dst;
559 74099 s->buf_end = dst + len;
560 74099 ffiocontext(s)->bytes_read += len;
561 74099 s->bytes_read = ffiocontext(s)->bytes_read;
562 }
563 }
564
565 32987 unsigned long ff_crc04C11DB7_update(unsigned long checksum, const uint8_t *buf,
566 unsigned int len)
567 {
568 32987 return av_crc(av_crc_get_table(AV_CRC_32_IEEE), checksum, buf, len);
569 }
570
571 14 unsigned long ff_crcEDB88320_update(unsigned long checksum, const uint8_t *buf,
572 unsigned int len)
573 {
574 14 return av_crc(av_crc_get_table(AV_CRC_32_IEEE_LE), checksum, buf, len);
575 }
576
577 72 unsigned long ff_crcA001_update(unsigned long checksum, const uint8_t *buf,
578 unsigned int len)
579 {
580 72 return av_crc(av_crc_get_table(AV_CRC_16_ANSI_LE), checksum, buf, len);
581 }
582
583 30211 unsigned long ffio_get_checksum(AVIOContext *s)
584 {
585 60422 s->checksum = s->update_checksum(s->checksum, s->checksum_ptr,
586 30211 s->buf_ptr - s->checksum_ptr);
587 30211 s->update_checksum = NULL;
588 30211 return s->checksum;
589 }
590
591 30298 void ffio_init_checksum(AVIOContext *s,
592 unsigned long (*update_checksum)(unsigned long c, const uint8_t *p, unsigned int len),
593 unsigned long checksum)
594 {
595 30298 s->update_checksum = update_checksum;
596
2/2
✓ Branch 0 taken 30269 times.
✓ Branch 1 taken 29 times.
30298 if (s->update_checksum) {
597 30269 s->checksum = checksum;
598 30269 s->checksum_ptr = s->buf_ptr;
599 }
600 30298 }
601
602 /* XXX: put an inline version */
603 11780669 int avio_r8(AVIOContext *s)
604 {
605
2/2
✓ Branch 0 taken 24168 times.
✓ Branch 1 taken 11756501 times.
11780669 if (s->buf_ptr >= s->buf_end)
606 24168 fill_buffer(s);
607
2/2
✓ Branch 0 taken 11769713 times.
✓ Branch 1 taken 10956 times.
11780669 if (s->buf_ptr < s->buf_end)
608 11769713 return *s->buf_ptr++;
609 10956 return 0;
610 }
611
612 733008 int avio_read(AVIOContext *s, unsigned char *buf, int size)
613 {
614 int len, size1;
615
616 733008 size1 = size;
617
2/2
✓ Branch 0 taken 801961 times.
✓ Branch 1 taken 730701 times.
1532662 while (size > 0) {
618 801961 len = FFMIN(s->buf_end - s->buf_ptr, size);
619
3/4
✓ Branch 0 taken 625199 times.
✓ Branch 1 taken 176762 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 625199 times.
801961 if (len == 0 || s->write_flag) {
620
7/8
✓ Branch 0 taken 176708 times.
✓ Branch 1 taken 54 times.
✓ Branch 2 taken 134752 times.
✓ Branch 3 taken 41956 times.
✓ Branch 4 taken 134797 times.
✓ Branch 5 taken 9 times.
✓ Branch 6 taken 134797 times.
✗ Branch 7 not taken.
176762 if((s->direct || size > s->buffer_size) && !s->update_checksum && s->read_packet) {
621 // bypass the buffer and read data directly into buf
622 134797 len = read_packet_wrapper(s, buf, size);
623
2/2
✓ Branch 0 taken 571 times.
✓ Branch 1 taken 134226 times.
134797 if (len == AVERROR_EOF) {
624 /* do not modify buffer if EOF reached so that a seek back can
625 be done without rereading data */
626 571 s->eof_reached = 1;
627 571 break;
628
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 134226 times.
134226 } else if (len < 0) {
629 s->eof_reached = 1;
630 s->error= len;
631 break;
632 } else {
633 134226 s->pos += len;
634 134226 ffiocontext(s)->bytes_read += len;
635 134226 s->bytes_read = ffiocontext(s)->bytes_read;
636 134226 size -= len;
637 134226 buf += len;
638 // reset the buffer
639 134226 s->buf_ptr = s->buffer;
640 134226 s->buf_end = s->buffer/* + len*/;
641 }
642 } else {
643 41965 fill_buffer(s);
644 41965 len = s->buf_end - s->buf_ptr;
645
2/2
✓ Branch 0 taken 1736 times.
✓ Branch 1 taken 40229 times.
41965 if (len == 0)
646 1736 break;
647 }
648 } else {
649 625199 memcpy(buf, s->buf_ptr, len);
650 625199 buf += len;
651 625199 s->buf_ptr += len;
652 625199 size -= len;
653 }
654 }
655
2/2
✓ Branch 0 taken 3303 times.
✓ Branch 1 taken 729705 times.
733008 if (size1 == size) {
656
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3303 times.
3303 if (s->error) return s->error;
657
2/2
✓ Branch 1 taken 1581 times.
✓ Branch 2 taken 1722 times.
3303 if (avio_feof(s)) return AVERROR_EOF;
658 }
659 731427 return size1 - size;
660 }
661
662 15971 int ffio_read_size(AVIOContext *s, unsigned char *buf, int size)
663 {
664 15971 int ret = avio_read(s, buf, size);
665
2/2
✓ Branch 0 taken 15955 times.
✓ Branch 1 taken 16 times.
15971 if (ret == size)
666 15955 return ret;
667
3/4
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 14 times.
16 if (ret < 0 && ret != AVERROR_EOF)
668 return ret;
669 16 return AVERROR_INVALIDDATA;
670 }
671
672 398615 int ffio_read_indirect(AVIOContext *s, unsigned char *buf, int size, const unsigned char **data)
673 {
674
3/4
✓ Branch 0 taken 395847 times.
✓ Branch 1 taken 2768 times.
✓ Branch 2 taken 395847 times.
✗ Branch 3 not taken.
398615 if (s->buf_end - s->buf_ptr >= size && !s->write_flag) {
675 395847 *data = s->buf_ptr;
676 395847 s->buf_ptr += size;
677 395847 return size;
678 } else {
679 2768 *data = buf;
680 2768 return avio_read(s, buf, size);
681 }
682 }
683
684 585754 int avio_read_partial(AVIOContext *s, unsigned char *buf, int size)
685 {
686 int len;
687
688
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 585754 times.
585754 if (size < 0)
689 return AVERROR(EINVAL);
690
691
2/4
✓ Branch 0 taken 585754 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 585754 times.
585754 if (s->read_packet && s->write_flag) {
692 len = read_packet_wrapper(s, buf, size);
693 if (len > 0)
694 s->pos += len;
695 return len;
696 }
697
698 585754 len = s->buf_end - s->buf_ptr;
699
2/2
✓ Branch 0 taken 19843 times.
✓ Branch 1 taken 565911 times.
585754 if (len == 0) {
700 19843 fill_buffer(s);
701 19843 len = s->buf_end - s->buf_ptr;
702 }
703
2/2
✓ Branch 0 taken 565353 times.
✓ Branch 1 taken 20401 times.
585754 if (len > size)
704 565353 len = size;
705 585754 memcpy(buf, s->buf_ptr, len);
706 585754 s->buf_ptr += len;
707
2/2
✓ Branch 0 taken 1912 times.
✓ Branch 1 taken 583842 times.
585754 if (!len) {
708
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1912 times.
1912 if (s->error) return s->error;
709
1/2
✓ Branch 1 taken 1912 times.
✗ Branch 2 not taken.
1912 if (avio_feof(s)) return AVERROR_EOF;
710 }
711 583842 return len;
712 }
713
714 852835 unsigned int avio_rl16(AVIOContext *s)
715 {
716 unsigned int val;
717 852835 val = avio_r8(s);
718 852835 val |= avio_r8(s) << 8;
719 852835 return val;
720 }
721
722 337 unsigned int avio_rl24(AVIOContext *s)
723 {
724 unsigned int val;
725 337 val = avio_rl16(s);
726 337 val |= avio_r8(s) << 16;
727 337 return val;
728 }
729
730 408390 unsigned int avio_rl32(AVIOContext *s)
731 {
732 unsigned int val;
733 408390 val = avio_rl16(s);
734 408390 val |= avio_rl16(s) << 16;
735 408390 return val;
736 }
737
738 5250 uint64_t avio_rl64(AVIOContext *s)
739 {
740 uint64_t val;
741 5250 val = (uint64_t)avio_rl32(s);
742 5250 val |= (uint64_t)avio_rl32(s) << 32;
743 5250 return val;
744 }
745
746 1145731 unsigned int avio_rb16(AVIOContext *s)
747 {
748 unsigned int val;
749 1145731 val = avio_r8(s) << 8;
750 1145731 val |= avio_r8(s);
751 1145731 return val;
752 }
753
754 27199 unsigned int avio_rb24(AVIOContext *s)
755 {
756 unsigned int val;
757 27199 val = avio_rb16(s) << 8;
758 27199 val |= avio_r8(s);
759 27199 return val;
760 }
761 510664 unsigned int avio_rb32(AVIOContext *s)
762 {
763 unsigned int val;
764 510664 val = avio_rb16(s) << 16;
765 510664 val |= avio_rb16(s);
766 510664 return val;
767 }
768
769 937 int ff_get_line(AVIOContext *s, char *buf, int maxlen)
770 {
771 937 int i = 0;
772 char c;
773
774 do {
775 24722 c = avio_r8(s);
776
3/4
✓ Branch 0 taken 24693 times.
✓ Branch 1 taken 29 times.
✓ Branch 2 taken 24693 times.
✗ Branch 3 not taken.
24722 if (c && i < maxlen-1)
777 24693 buf[i++] = c;
778
6/6
✓ Branch 0 taken 24124 times.
✓ Branch 1 taken 598 times.
✓ Branch 2 taken 23814 times.
✓ Branch 3 taken 310 times.
✓ Branch 4 taken 23785 times.
✓ Branch 5 taken 29 times.
24722 } while (c != '\n' && c != '\r' && c);
779
3/6
✓ Branch 0 taken 310 times.
✓ Branch 1 taken 627 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 310 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
937 if (c == '\r' && avio_r8(s) != '\n' && !avio_feof(s))
780 avio_skip(s, -1);
781
782 937 buf[i] = 0;
783 937 return i;
784 }
785
786 236 int ff_get_chomp_line(AVIOContext *s, char *buf, int maxlen)
787 {
788 236 int len = ff_get_line(s, buf, maxlen);
789
4/4
✓ Branch 0 taken 446 times.
✓ Branch 1 taken 13 times.
✓ Branch 2 taken 223 times.
✓ Branch 3 taken 223 times.
459 while (len > 0 && av_isspace(buf[len - 1]))
790 223 buf[--len] = '\0';
791 236 return len;
792 }
793
794 typedef enum FFBPrintReadStringMode {
795 FFBPrintReadString = 0,
796 FFBPrintReadLine = 1,
797 } FFBPrintReadStringMode;
798
799 316 static int64_t read_string_to_bprint(AVIOContext *s, AVBPrint *bp,
800 FFBPrintReadStringMode mode,
801 int64_t max_len)
802 {
803 int len, end;
804 316 int64_t read = 0;
805 char tmp[1024];
806 char c;
807
808
1/2
✓ Branch 0 taken 316 times.
✗ Branch 1 not taken.
316 if (!max_len)
809 return 0;
810
811 do {
812 316 len = 0;
813 do {
814 5031 c = avio_r8(s);
815
7/8
✓ Branch 0 taken 4567 times.
✓ Branch 1 taken 464 times.
✓ Branch 2 taken 4567 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 4294 times.
✓ Branch 5 taken 273 times.
✓ Branch 6 taken 43 times.
✓ Branch 7 taken 4715 times.
5031 end = ((mode == FFBPrintReadLine && (c == '\r' || c == '\n')) ||
816 c == '\0');
817
2/2
✓ Branch 0 taken 4715 times.
✓ Branch 1 taken 316 times.
5031 if (!end)
818 4715 tmp[len++] = c;
819
5/6
✓ Branch 0 taken 4715 times.
✓ Branch 1 taken 316 times.
✓ Branch 2 taken 4715 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 4289 times.
✓ Branch 5 taken 426 times.
5031 } while (!end && len < sizeof(tmp) &&
820
1/2
✓ Branch 0 taken 426 times.
✗ Branch 1 not taken.
426 ((max_len < 0) || (read + len < max_len)));
821 316 av_bprint_append_data(bp, tmp, len);
822 316 read += len;
823
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 316 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
316 } while (!end && ((max_len < 0) || (read < max_len)));
824
825
3/4
✓ Branch 0 taken 278 times.
✓ Branch 1 taken 38 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 278 times.
316 if (mode == FFBPrintReadLine &&
826 c == '\r' && avio_r8(s) != '\n' && !avio_feof(s))
827 avio_skip(s, -1);
828
829
3/4
✓ Branch 0 taken 43 times.
✓ Branch 1 taken 273 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 43 times.
316 if (!c && s->error)
830 return s->error;
831
832
6/6
✓ Branch 0 taken 43 times.
✓ Branch 1 taken 273 times.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 37 times.
✓ Branch 5 taken 5 times.
✓ Branch 6 taken 1 times.
316 if (!c && !read && avio_feof(s))
833 5 return AVERROR_EOF;
834
835 311 return read;
836 }
837
838 316 static int64_t read_string_to_bprint_overwrite(AVIOContext *s, AVBPrint *bp,
839 FFBPrintReadStringMode mode,
840 int64_t max_len)
841 {
842 int64_t ret;
843
844 316 av_bprint_clear(bp);
845 316 ret = read_string_to_bprint(s, bp, mode, max_len);
846
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 311 times.
316 if (ret < 0)
847 5 return ret;
848
849
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 311 times.
311 if (!av_bprint_is_complete(bp))
850 return AVERROR(ENOMEM);
851
852 311 return bp->len;
853 }
854
855 278 int64_t ff_read_line_to_bprint_overwrite(AVIOContext *s, AVBPrint *bp)
856 {
857 278 return read_string_to_bprint_overwrite(s, bp, FFBPrintReadLine, -1);
858 }
859
860 38 int64_t ff_read_string_to_bprint_overwrite(AVIOContext *s, AVBPrint *bp,
861 int64_t max_len)
862 {
863 38 return read_string_to_bprint_overwrite(s, bp, FFBPrintReadString, max_len);
864 }
865
866 597 int avio_get_str(AVIOContext *s, int maxlen, char *buf, int buflen)
867 {
868 int i;
869
870
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 597 times.
597 if (buflen <= 0)
871 return AVERROR(EINVAL);
872 // reserve 1 byte for terminating 0
873 597 buflen = FFMIN(buflen - 1, maxlen);
874
2/2
✓ Branch 0 taken 8849 times.
✓ Branch 1 taken 272 times.
9121 for (i = 0; i < buflen; i++)
875
2/2
✓ Branch 1 taken 325 times.
✓ Branch 2 taken 8524 times.
8849 if (!(buf[i] = avio_r8(s)))
876 325 return i + 1;
877 272 buf[i] = 0;
878
2/2
✓ Branch 0 taken 280 times.
✓ Branch 1 taken 262 times.
542 for (; i < maxlen; i++)
879
2/2
✓ Branch 1 taken 10 times.
✓ Branch 2 taken 270 times.
280 if (!avio_r8(s))
880 10 return i + 1;
881 262 return maxlen;
882 }
883
884 #define GET_STR16(type, read) \
885 int avio_get_str16 ##type(AVIOContext *pb, int maxlen, char *buf, int buflen)\
886 {\
887 char* q = buf;\
888 int ret = 0;\
889 if (buflen <= 0) \
890 return AVERROR(EINVAL); \
891 while (ret + 1 < maxlen) {\
892 uint8_t tmp;\
893 uint32_t ch;\
894 GET_UTF16(ch, (ret += 2) <= maxlen ? read(pb) : 0, break;)\
895 if (!ch)\
896 break;\
897 PUT_UTF8(ch, tmp, if (q - buf < buflen - 1) *q++ = tmp;)\
898 }\
899 *q = 0;\
900 return ret;\
901 }\
902
903
14/26
✗ Branch 0 not taken.
✓ Branch 1 taken 618 times.
✓ Branch 2 taken 8430 times.
✗ Branch 3 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 8430 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 7828 times.
✓ Branch 16 taken 7827 times.
✓ Branch 17 taken 1 times.
✓ Branch 18 taken 7827 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 8430 times.
✓ Branch 27 taken 16 times.
8447 GET_STR16(le, avio_rl16)
904
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)
905
906 #undef GET_STR16
907
908 144409 uint64_t avio_rb64(AVIOContext *s)
909 {
910 uint64_t val;
911 144409 val = (uint64_t)avio_rb32(s) << 32;
912 144409 val |= (uint64_t)avio_rb32(s);
913 144409 return val;
914 }
915
916 10698 uint64_t ffio_read_varlen(AVIOContext *bc){
917 10698 uint64_t val = 0;
918 int tmp;
919
920 do{
921 18264 tmp = avio_r8(bc);
922 18264 val= (val<<7) + (tmp&127);
923
2/2
✓ Branch 0 taken 7566 times.
✓ Branch 1 taken 10698 times.
18264 }while(tmp&128);
924 10698 return val;
925 }
926
927 1033 unsigned int ffio_read_leb(AVIOContext *s) {
928 1033 int more, i = 0;
929 1033 unsigned leb = 0;
930
931 do {
932 1429 int byte = avio_r8(s);
933 1429 unsigned bits = byte & 0x7f;
934 1429 more = byte & 0x80;
935
1/2
✓ Branch 0 taken 1429 times.
✗ Branch 1 not taken.
1429 if (i <= 4)
936 1429 leb |= bits << (i * 7);
937
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1429 times.
1429 if (++i == 8)
938 break;
939
2/2
✓ Branch 0 taken 396 times.
✓ Branch 1 taken 1033 times.
1429 } while (more);
940
941 1033 return leb;
942 }
943
944 1372 void ffio_write_leb(AVIOContext *s, unsigned val)
945 {
946 int len;
947 uint8_t byte;
948
949 1372 len = (av_log2(val) + 7) / 7;
950
951
2/2
✓ Branch 0 taken 2170 times.
✓ Branch 1 taken 1372 times.
3542 for (int i = 0; i < len; i++) {
952 2170 byte = val >> (7 * i) & 0x7f;
953
2/2
✓ Branch 0 taken 798 times.
✓ Branch 1 taken 1372 times.
2170 if (i < len - 1)
954 798 byte |= 0x80;
955
956 2170 avio_w8(s, byte);
957 }
958 1372 }
959
960 28 void ffio_write_lines(AVIOContext *s, const unsigned char *buf, int size,
961 const unsigned char *ending)
962 {
963
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 28 times.
28 int ending_len = ending ? strlen(ending) : 1;
964
1/2
✓ Branch 0 taken 28 times.
✗ Branch 1 not taken.
28 if (!ending)
965 28 ending = "\n";
966
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 28 times.
28 if (size < 0)
967 size = strlen(buf);
968
969
2/2
✓ Branch 0 taken 439 times.
✓ Branch 1 taken 28 times.
467 while (size > 0) {
970 439 size_t len = 0;
971 439 char last = 0;
972
1/2
✓ Branch 0 taken 19804 times.
✗ Branch 1 not taken.
19804 for (; len < size; len++) {
973 19804 last = buf[len];
974
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')
975 break;
976 }
977
978 439 avio_write(s, buf, len);
979 439 avio_write(s, ending, ending_len);
980
981 439 buf += len + 1;
982 439 size -= len + 1;
983
984
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') {
985 103 buf++;
986 103 size--;
987 }
988 }
989 28 }
990
991 12 int ffio_copy_url_options(AVIOContext* pb, AVDictionary** avio_opts)
992 {
993 12 const char *opts[] = {
994 "headers", "user_agent", "cookies", "http_proxy", "referer", "rw_timeout", "icy", NULL };
995 12 const char **opt = opts;
996 12 uint8_t *buf = NULL;
997 12 int ret = 0;
998
999
2/2
✓ Branch 0 taken 84 times.
✓ Branch 1 taken 12 times.
96 while (*opt) {
1000
2/2
✓ Branch 1 taken 12 times.
✓ Branch 2 taken 72 times.
84 if (av_opt_get(pb, *opt, AV_OPT_SEARCH_CHILDREN, &buf) >= 0) {
1001
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
12 if (buf[0] != '\0') {
1002 12 ret = av_dict_set(avio_opts, *opt, buf, AV_DICT_DONT_STRDUP_VAL);
1003
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
12 if (ret < 0)
1004 return ret;
1005 } else {
1006 av_freep(&buf);
1007 }
1008 }
1009 84 opt++;
1010 }
1011
1012 12 return ret;
1013 }
1014
1015 11 static void update_checksum(AVIOContext *s)
1016 {
1017
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 11 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
11 if (s->update_checksum && s->buf_ptr > s->checksum_ptr) {
1018 s->checksum = s->update_checksum(s->checksum, s->checksum_ptr,
1019 s->buf_ptr - s->checksum_ptr);
1020 }
1021 11 }
1022
1023 22176 int ffio_ensure_seekback(AVIOContext *s, int64_t buf_size)
1024 {
1025 uint8_t *buffer;
1026 44352 int max_buffer_size = s->max_packet_size ?
1027
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 22176 times.
22176 s->max_packet_size : IO_BUFFER_SIZE;
1028 22176 ptrdiff_t filled = s->buf_end - s->buf_ptr;
1029
1030
2/2
✓ Branch 0 taken 19175 times.
✓ Branch 1 taken 3001 times.
22176 if (buf_size <= s->buf_end - s->buf_ptr)
1031 19175 return 0;
1032
1033
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3001 times.
3001 if (buf_size > INT_MAX - max_buffer_size)
1034 return AVERROR(EINVAL);
1035
1036 3001 buf_size += max_buffer_size - 1;
1037
1038
5/6
✓ Branch 0 taken 3001 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 14 times.
✓ Branch 3 taken 2987 times.
✓ Branch 4 taken 3 times.
✓ Branch 5 taken 11 times.
3001 if (buf_size + s->buf_ptr - s->buffer <= s->buffer_size || s->seekable || !s->read_packet)
1039 2990 return 0;
1040
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11 times.
11 av_assert0(!s->write_flag);
1041
1042
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11 times.
11 if (buf_size <= s->buffer_size) {
1043 update_checksum(s);
1044 memmove(s->buffer, s->buf_ptr, filled);
1045 } else {
1046 11 buffer = av_malloc(buf_size);
1047
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11 times.
11 if (!buffer)
1048 return AVERROR(ENOMEM);
1049 11 update_checksum(s);
1050 11 memcpy(buffer, s->buf_ptr, filled);
1051 11 av_free(s->buffer);
1052 11 s->buffer = buffer;
1053 11 s->buffer_size = buf_size;
1054 }
1055 11 s->buf_ptr = s->buffer;
1056 11 s->buf_end = s->buffer + filled;
1057 11 s->checksum_ptr = s->buffer;
1058 11 return 0;
1059 }
1060
1061 6266 int ffio_limit(AVIOContext *s, int size)
1062 {
1063 6266 FFIOContext *const ctx = ffiocontext(s);
1064
2/2
✓ Branch 0 taken 6239 times.
✓ Branch 1 taken 27 times.
6266 if (ctx->maxsize >= 0) {
1065 6239 int64_t pos = avio_tell(s);
1066 6239 int64_t remaining = ctx->maxsize - pos;
1067
2/2
✓ Branch 0 taken 419 times.
✓ Branch 1 taken 5820 times.
6239 if (remaining < size) {
1068 419 int64_t newsize = avio_size(s);
1069
3/4
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 414 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 5 times.
419 if (!ctx->maxsize || ctx->maxsize < newsize)
1070 414 ctx->maxsize = newsize - !newsize;
1071
3/4
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 418 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
419 if (pos > ctx->maxsize && ctx->maxsize >= 0)
1072 ctx->maxsize = AVERROR(EIO);
1073
2/2
✓ Branch 0 taken 418 times.
✓ Branch 1 taken 1 times.
419 if (ctx->maxsize >= 0)
1074 418 remaining = ctx->maxsize - pos;
1075 }
1076
1077
5/6
✓ Branch 0 taken 6238 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 5 times.
✓ Branch 3 taken 6233 times.
✓ Branch 4 taken 5 times.
✗ Branch 5 not taken.
6239 if (ctx->maxsize >= 0 && remaining < size && size > 1) {
1078 5 av_log(NULL, remaining ? AV_LOG_ERROR : AV_LOG_DEBUG,
1079 "Truncating packet of size %d to %"PRId64"\n",
1080
1/2
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
5 size, remaining + !remaining);
1081 5 size = remaining + !remaining;
1082 }
1083 }
1084 6266 return size;
1085 }
1086
1087 22 static int set_buf_size(AVIOContext *s, int buf_size)
1088 {
1089 uint8_t *buffer;
1090 22 buffer = av_malloc(buf_size);
1091
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 22 times.
22 if (!buffer)
1092 return AVERROR(ENOMEM);
1093
1094 22 av_free(s->buffer);
1095 22 s->buffer = buffer;
1096 44 ffiocontext(s)->orig_buffer_size =
1097 22 s->buffer_size = buf_size;
1098 22 s->buf_ptr = s->buf_ptr_max = buffer;
1099
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 22 times.
22 url_resetbuf(s, s->write_flag ? AVIO_FLAG_WRITE : AVIO_FLAG_READ);
1100 22 return 0;
1101 }
1102
1103 int ffio_realloc_buf(AVIOContext *s, int buf_size)
1104 {
1105 uint8_t *buffer;
1106 int data_size;
1107
1108 if (!s->buffer_size)
1109 return set_buf_size(s, buf_size);
1110
1111 if (buf_size <= s->buffer_size)
1112 return 0;
1113
1114 buffer = av_malloc(buf_size);
1115 if (!buffer)
1116 return AVERROR(ENOMEM);
1117
1118 data_size = s->write_flag ? (s->buf_ptr - s->buffer) : (s->buf_end - s->buf_ptr);
1119 if (data_size > 0)
1120 memcpy(buffer, s->write_flag ? s->buffer : s->buf_ptr, data_size);
1121 av_free(s->buffer);
1122 s->buffer = buffer;
1123 ffiocontext(s)->orig_buffer_size = buf_size;
1124 s->buffer_size = buf_size;
1125 s->buf_ptr = s->write_flag ? (s->buffer + data_size) : s->buffer;
1126 if (s->write_flag)
1127 s->buf_ptr_max = s->buffer + data_size;
1128
1129 s->buf_end = s->write_flag ? (s->buffer + s->buffer_size) : (s->buf_ptr + data_size);
1130
1131 return 0;
1132 }
1133
1134 234721 static int url_resetbuf(AVIOContext *s, int flags)
1135 {
1136 av_assert1(flags == AVIO_FLAG_WRITE || flags == AVIO_FLAG_READ);
1137
1138
2/2
✓ Branch 0 taken 48912 times.
✓ Branch 1 taken 185809 times.
234721 if (flags & AVIO_FLAG_WRITE) {
1139 48912 s->buf_end = s->buffer + s->buffer_size;
1140 48912 s->write_flag = 1;
1141 } else {
1142 185809 s->buf_end = s->buffer;
1143 185809 s->write_flag = 0;
1144 }
1145 234721 return 0;
1146 }
1147
1148 3712 int ffio_rewind_with_probe_data(AVIOContext *s, unsigned char **bufp, int buf_size)
1149 {
1150 int64_t buffer_start;
1151 int buffer_size;
1152 int overlap, new_size, alloc_size;
1153 3712 uint8_t *buf = *bufp;
1154
1155
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3712 times.
3712 if (s->write_flag) {
1156 av_freep(bufp);
1157 return AVERROR(EINVAL);
1158 }
1159
1160 3712 buffer_size = s->buf_end - s->buffer;
1161
1162 /* the buffers must touch or overlap */
1163
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3712 times.
3712 if ((buffer_start = s->pos - buffer_size) > buf_size) {
1164 av_freep(bufp);
1165 return AVERROR(EINVAL);
1166 }
1167
1168 3712 overlap = buf_size - buffer_start;
1169 3712 new_size = buf_size + buffer_size - overlap;
1170
1171 3712 alloc_size = FFMAX(s->buffer_size, new_size);
1172
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 54 times.
3712 if (alloc_size > buf_size)
1173
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 3658 times.
3658 if (!(buf = (*bufp) = av_realloc_f(buf, 1, alloc_size)))
1174 return AVERROR(ENOMEM);
1175
1176
2/2
✓ Branch 0 taken 3494 times.
✓ Branch 1 taken 218 times.
3712 if (new_size > buf_size) {
1177 3494 memcpy(buf + buf_size, s->buffer + overlap, buffer_size - overlap);
1178 3494 buf_size = new_size;
1179 }
1180
1181 3712 av_free(s->buffer);
1182 3712 s->buf_ptr = s->buffer = buf;
1183 3712 s->buffer_size = alloc_size;
1184 3712 s->pos = buf_size;
1185 3712 s->buf_end = s->buf_ptr + buf_size;
1186 3712 s->eof_reached = 0;
1187
1188 3712 return 0;
1189 }
1190
1191 23064 int avio_vprintf(AVIOContext *s, const char *fmt, va_list ap)
1192 {
1193 AVBPrint bp;
1194
1195 23064 av_bprint_init(&bp, 0, INT_MAX);
1196 23064 av_vbprintf(&bp, fmt, ap);
1197
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 23064 times.
23064 if (!av_bprint_is_complete(&bp)) {
1198 av_bprint_finalize(&bp, NULL);
1199 s->error = AVERROR(ENOMEM);
1200 return AVERROR(ENOMEM);
1201 }
1202 23064 avio_write(s, bp.str, bp.len);
1203 23064 av_bprint_finalize(&bp, NULL);
1204 23064 return bp.len;
1205 }
1206
1207 23064 int avio_printf(AVIOContext *s, const char *fmt, ...)
1208 {
1209 va_list ap;
1210 int ret;
1211
1212 23064 va_start(ap, fmt);
1213 23064 ret = avio_vprintf(s, fmt, ap);
1214 23064 va_end(ap);
1215
1216 23064 return ret;
1217 }
1218
1219 485 void avio_print_string_array(AVIOContext *s, const char *const strings[])
1220 {
1221
2/2
✓ Branch 0 taken 1455 times.
✓ Branch 1 taken 485 times.
1940 for(; *strings; strings++)
1222 1455 avio_write(s, (const unsigned char *)*strings, strlen(*strings));
1223 485 }
1224
1225 int avio_pause(AVIOContext *s, int pause)
1226 {
1227 if (!s->read_pause)
1228 return AVERROR(ENOSYS);
1229 return s->read_pause(s->opaque, pause);
1230 }
1231
1232 315 int64_t avio_seek_time(AVIOContext *s, int stream_index,
1233 int64_t timestamp, int flags)
1234 {
1235 int64_t ret;
1236
1/2
✓ Branch 0 taken 315 times.
✗ Branch 1 not taken.
315 if (!s->read_seek)
1237 315 return AVERROR(ENOSYS);
1238 ret = s->read_seek(s->opaque, stream_index, timestamp, flags);
1239 if (ret >= 0) {
1240 int64_t pos;
1241 s->buf_ptr = s->buf_end; // Flush buffer
1242 pos = s->seek(s->opaque, 0, SEEK_CUR);
1243 if (pos >= 0)
1244 s->pos = pos;
1245 else if (pos != AVERROR(ENOSYS))
1246 ret = pos;
1247 }
1248 return ret;
1249 }
1250
1251 73 int avio_read_to_bprint(AVIOContext *h, AVBPrint *pb, size_t max_size)
1252 {
1253 int ret;
1254 char buf[1024];
1255
2/2
✓ Branch 0 taken 8129 times.
✓ Branch 1 taken 2 times.
8131 while (max_size) {
1256 8129 ret = avio_read(h, buf, FFMIN(max_size, sizeof(buf)));
1257
2/2
✓ Branch 0 taken 71 times.
✓ Branch 1 taken 8058 times.
8129 if (ret == AVERROR_EOF)
1258 71 return 0;
1259
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8058 times.
8058 if (ret <= 0)
1260 return ret;
1261 8058 av_bprint_append_data(pb, buf, ret);
1262
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 8058 times.
8058 if (!av_bprint_is_complete(pb))
1263 return AVERROR(ENOMEM);
1264 8058 max_size -= ret;
1265 }
1266 2 return 0;
1267 }
1268
1269 /* output in a dynamic buffer */
1270
1271 typedef struct DynBuffer {
1272 int pos, size, allocated_size;
1273 uint8_t *buffer;
1274 int io_buffer_size;
1275 uint8_t io_buffer[1];
1276 } DynBuffer;
1277
1278 33974 static int dyn_buf_write(void *opaque, const uint8_t *buf, int buf_size)
1279 {
1280 33974 DynBuffer *d = opaque;
1281 unsigned new_size;
1282
1283 /* reallocate buffer if needed */
1284 33974 new_size = (unsigned)d->pos + buf_size;
1285
2/4
✓ Branch 0 taken 33974 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 33974 times.
33974 if (new_size < d->pos || new_size > INT_MAX)
1286 return AVERROR(ERANGE);
1287
2/2
✓ Branch 0 taken 7700 times.
✓ Branch 1 taken 26274 times.
33974 if (new_size > d->allocated_size) {
1288 17062 unsigned new_allocated_size = d->allocated_size ? d->allocated_size
1289
2/2
✓ Branch 0 taken 1662 times.
✓ Branch 1 taken 6038 times.
7700 : new_size;
1290 int err;
1291
2/2
✓ Branch 0 taken 2864 times.
✓ Branch 1 taken 7700 times.
10564 while (new_size > new_allocated_size)
1292 2864 new_allocated_size += new_allocated_size / 2 + 1;
1293
1294
1/2
✓ Branch 0 taken 7700 times.
✗ Branch 1 not taken.
7700 new_allocated_size = FFMIN(new_allocated_size, INT_MAX);
1295
1296
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 7700 times.
7700 if ((err = av_reallocp(&d->buffer, new_allocated_size)) < 0) {
1297 d->allocated_size = 0;
1298 d->size = 0;
1299 return err;
1300 }
1301 7700 d->allocated_size = new_allocated_size;
1302 }
1303 33974 memcpy(d->buffer + d->pos, buf, buf_size);
1304 33974 d->pos = new_size;
1305
2/2
✓ Branch 0 taken 33958 times.
✓ Branch 1 taken 16 times.
33974 if (d->pos > d->size)
1306 33958 d->size = d->pos;
1307 33974 return buf_size;
1308 }
1309
1310 265 static int dyn_packet_buf_write(void *opaque, const uint8_t *buf, int buf_size)
1311 {
1312 unsigned char buf1[4];
1313 int ret;
1314
1315 /* packetized write: output the header */
1316 265 AV_WB32(buf1, buf_size);
1317 265 ret = dyn_buf_write(opaque, buf1, 4);
1318
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 265 times.
265 if (ret < 0)
1319 return ret;
1320
1321 /* then the data */
1322 265 return dyn_buf_write(opaque, buf, buf_size);
1323 }
1324
1325 279 static int64_t dyn_buf_seek(void *opaque, int64_t offset, int whence)
1326 {
1327 279 DynBuffer *d = opaque;
1328
1329
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 279 times.
279 if (whence == SEEK_CUR)
1330 offset += d->pos;
1331
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 279 times.
279 else if (whence == SEEK_END)
1332 offset += d->size;
1333
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 279 times.
279 if (offset < 0)
1334 return AVERROR(EINVAL);
1335
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 279 times.
279 if (offset > INT_MAX)
1336 return AVERROR(ERANGE);
1337 279 d->pos = offset;
1338 279 return 0;
1339 }
1340
1341 18795 static int url_open_dyn_buf_internal(AVIOContext **s, int max_packet_size)
1342 {
1343 struct { FFIOContext pb; DynBuffer d; } *ret;
1344 DynBuffer *d;
1345
2/2
✓ Branch 0 taken 38 times.
✓ Branch 1 taken 18757 times.
18795 unsigned io_buffer_size = max_packet_size ? max_packet_size : 1024;
1346
1347 if (sizeof(*ret) + io_buffer_size < io_buffer_size)
1348 return AVERROR(ERANGE);
1349 18795 ret = av_mallocz(sizeof(*ret) + io_buffer_size);
1350
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 18795 times.
18795 if (!ret)
1351 return AVERROR(ENOMEM);
1352 18795 d = &ret->d;
1353 18795 d->io_buffer_size = io_buffer_size;
1354
4/4
✓ Branch 0 taken 18757 times.
✓ Branch 1 taken 38 times.
✓ Branch 2 taken 38 times.
✓ Branch 3 taken 18757 times.
18795 ffio_init_context(&ret->pb, d->io_buffer, d->io_buffer_size, 1, d, NULL,
1355 max_packet_size ? dyn_packet_buf_write : dyn_buf_write,
1356 max_packet_size ? NULL : dyn_buf_seek);
1357 18795 *s = &ret->pb.pub;
1358 18795 (*s)->max_packet_size = max_packet_size;
1359 18795 return 0;
1360 }
1361
1362 18639 int avio_open_dyn_buf(AVIOContext **s)
1363 {
1364 18639 return url_open_dyn_buf_internal(s, 0);
1365 }
1366
1367 38 int ffio_open_dyn_packet_buf(AVIOContext **s, int max_packet_size)
1368 {
1369
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 38 times.
38 if (max_packet_size <= 0)
1370 return AVERROR(EINVAL);
1371 38 return url_open_dyn_buf_internal(s, max_packet_size);
1372 }
1373
1374 22617 int avio_get_dyn_buf(AVIOContext *s, uint8_t **pbuffer)
1375 {
1376 DynBuffer *d;
1377
1378
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 22617 times.
22617 if (!s) {
1379 *pbuffer = NULL;
1380 return 0;
1381 }
1382 22617 d = s->opaque;
1383
1384
3/4
✓ Branch 0 taken 22617 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 22003 times.
✓ Branch 3 taken 614 times.
22617 if (!s->error && !d->size) {
1385 22003 *pbuffer = d->io_buffer;
1386 22003 return FFMAX(s->buf_ptr, s->buf_ptr_max) - s->buffer;
1387 }
1388
1389 614 avio_flush(s);
1390
1391 614 *pbuffer = d->buffer;
1392
1393 614 return d->size;
1394 }
1395
1396 20880 void ffio_reset_dyn_buf(AVIOContext *s)
1397 {
1398 20880 DynBuffer *d = s->opaque;
1399 20880 int max_packet_size = s->max_packet_size;
1400
1401 20880 ffio_init_context(ffiocontext(s), d->io_buffer, d->io_buffer_size,
1402 1, d, NULL, s->write_packet, s->seek);
1403 20880 s->max_packet_size = max_packet_size;
1404 20880 d->pos = d->size = 0;
1405 20880 }
1406
1407 5967 int avio_close_dyn_buf(AVIOContext *s, uint8_t **pbuffer)
1408 {
1409 DynBuffer *d;
1410 int size;
1411 5967 int padding = 0;
1412
1413
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5967 times.
5967 if (!s) {
1414 *pbuffer = NULL;
1415 return 0;
1416 }
1417
1418 /* don't attempt to pad fixed-size packet buffers */
1419
2/2
✓ Branch 0 taken 5931 times.
✓ Branch 1 taken 36 times.
5967 if (!s->max_packet_size) {
1420 5931 ffio_fill(s, 0, AV_INPUT_BUFFER_PADDING_SIZE);
1421 5931 padding = AV_INPUT_BUFFER_PADDING_SIZE;
1422 }
1423
1424 5967 avio_flush(s);
1425
1426 5967 d = s->opaque;
1427 5967 *pbuffer = d->buffer;
1428 5967 size = d->size;
1429
1430 5967 avio_context_free(&s);
1431
1432 5967 return size - padding;
1433 }
1434
1435 13649 void ffio_free_dyn_buf(AVIOContext **s)
1436 {
1437 DynBuffer *d;
1438
1439
2/2
✓ Branch 0 taken 939 times.
✓ Branch 1 taken 12710 times.
13649 if (!*s)
1440 939 return;
1441
1442 12710 d = (*s)->opaque;
1443 12710 av_free(d->buffer);
1444 12710 avio_context_free(s);
1445 }
1446
1447 316 static int null_buf_write(void *opaque, const uint8_t *buf, int buf_size)
1448 {
1449 316 DynBuffer *d = opaque;
1450
1451 316 d->pos += buf_size;
1452
2/2
✓ Branch 0 taken 185 times.
✓ Branch 1 taken 131 times.
316 if (d->pos > d->size)
1453 185 d->size = d->pos;
1454 316 return buf_size;
1455 }
1456
1457 118 int ffio_open_null_buf(AVIOContext **s)
1458 {
1459 118 int ret = url_open_dyn_buf_internal(s, 0);
1460
1/2
✓ Branch 0 taken 118 times.
✗ Branch 1 not taken.
118 if (ret >= 0) {
1461 118 AVIOContext *pb = *s;
1462 118 pb->write_packet = null_buf_write;
1463 }
1464 118 return ret;
1465 }
1466
1467 118 int ffio_close_null_buf(AVIOContext *s)
1468 {
1469 118 DynBuffer *d = s->opaque;
1470 int size;
1471
1472 118 avio_flush(s);
1473
1474 118 size = d->size;
1475
1476 118 avio_context_free(&s);
1477
1478 118 return size;
1479 }
1480