FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavformat/aviobuf.c
Date: 2026-11-01 05:14:56
Exec Total Coverage
Lines: 722 832 86.8%
Functions: 86 88 97.7%
Branches: 456 626 72.8%

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 256314 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 256314 AVIOContext *const s = &ctx->pub;
60
61 256314 memset(ctx, 0, sizeof(*ctx));
62
63 256314 s->buffer = buffer;
64 256314 ctx->orig_buffer_size =
65 256314 s->buffer_size = buffer_size;
66 256314 s->buf_ptr = buffer;
67 256314 s->buf_ptr_max = buffer;
68 256314 s->opaque = opaque;
69 256314 s->direct = 0;
70
71
2/2
✓ Branch 0 taken 58062 times.
✓ Branch 1 taken 198252 times.
256314 url_resetbuf(s, write_flag ? AVIO_FLAG_WRITE : AVIO_FLAG_READ);
72
73 256314 s->write_packet = write_packet;
74 256314 s->read_packet = read_packet;
75 256314 s->seek = seek;
76 256314 s->pos = 0;
77 256314 s->eof_reached = 0;
78 256314 s->error = 0;
79 256314 s->seekable = seek ? AVIO_SEEKABLE_NORMAL : 0;
80 256314 s->min_packet_size = 0;
81 256314 s->max_packet_size = 0;
82 256314 s->update_checksum = NULL;
83 256314 ctx->short_seek_threshold = SHORT_SEEK_THRESHOLD;
84
85
4/4
✓ Branch 0 taken 138975 times.
✓ Branch 1 taken 117339 times.
✓ Branch 2 taken 90716 times.
✓ Branch 3 taken 48259 times.
256314 if (!read_packet && !write_flag) {
86 90716 s->pos = buffer_size;
87 90716 s->buf_end = s->buffer + buffer_size;
88 }
89 256314 s->read_pause = NULL;
90 256314 s->read_seek = NULL;
91
92 256314 s->write_data_type = NULL;
93 256314 s->ignore_boundary_point = 0;
94 256314 ctx->current_type = AVIO_DATA_MARKER_UNKNOWN;
95 256314 ctx->last_time = AV_NOPTS_VALUE;
96 256314 ctx->short_seek_get = NULL;
97 256314 }
98
99 90491 void ffio_init_read_context(FFIOContext *s, const uint8_t *buffer, int buffer_size)
100 {
101 90491 ffio_init_context(s, (unsigned char*)buffer, buffer_size, 0, NULL, NULL, NULL, NULL);
102 90491 }
103
104 237 void ffio_init_write_context(FFIOContext *s, uint8_t *buffer, int buffer_size)
105 {
106 237 ffio_init_context(s, buffer, buffer_size, 1, NULL, NULL, NULL, NULL);
107 237 }
108
109 117339 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 117339 FFIOContext *s = av_malloc(sizeof(*s));
119
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 117339 times.
117339 if (!s)
120 ✗ return NULL;
121 117339 ffio_init_context(s, buffer, buffer_size, write_flag, opaque,
122 read_packet, write_packet, seek);
123 117339 return &s->pub;
124 }
125
126 143102 void avio_context_free(AVIOContext **ps)
127 {
128 143102 AVIOContext *s = *ps;
129
2/2
✓ Branch 0 taken 143100 times.
✓ Branch 1 taken 2 times.
143102 if (s) {
130 143100 av_freep(&s->protocol_whitelist);
131 143100 av_freep(&s->protocol_blacklist);
132 }
133 143102 av_freep(ps);
134 143102 }
135
136 453566 static void writeout(AVIOContext *s, const uint8_t *data, int len)
137 {
138 453566 FFIOContext *const ctx = ffiocontext(s);
139
1/2
✓ Branch 0 taken 453566 times.
✗ Branch 1 not taken.
453566 if (!s->error) {
140 453566 int ret = 0;
141
2/2
✓ Branch 0 taken 129 times.
✓ Branch 1 taken 453437 times.
453566 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 453418 times.
✓ Branch 1 taken 19 times.
453437 else if (s->write_packet)
147 453418 ret = s->write_packet(s->opaque, data, len);
148
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 453558 times.
453566 if (ret < 0) {
149 8 s->error = ret;
150 } else {
151 453558 ctx->bytes_written += len;
152 453558 s->bytes_written = ctx->bytes_written;
153
154
2/2
✓ Branch 0 taken 451413 times.
✓ Branch 1 taken 2145 times.
453558 if (s->pos + len > ctx->written_output_size) {
155 451413 ctx->written_output_size = s->pos + len;
156 }
157 }
158 }
159
2/2
✓ Branch 0 taken 453519 times.
✓ Branch 1 taken 47 times.
453566 if (ctx->current_type == AVIO_DATA_MARKER_SYNC_POINT ||
160
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 453514 times.
453519 ctx->current_type == AVIO_DATA_MARKER_BOUNDARY_POINT) {
161 52 ctx->current_type = AVIO_DATA_MARKER_UNKNOWN;
162 }
163 453566 ctx->last_time = AV_NOPTS_VALUE;
164 453566 ctx->writeout_count++;
165 453566 s->pos += len;
166 453566 }
167
168 597829 static void flush_buffer(AVIOContext *s)
169 {
170 597829 s->buf_ptr_max = FFMAX(s->buf_ptr, s->buf_ptr_max);
171
4/4
✓ Branch 0 taken 490334 times.
✓ Branch 1 taken 107495 times.
✓ Branch 2 taken 446213 times.
✓ Branch 3 taken 44121 times.
597829 if (s->write_flag && s->buf_ptr_max > s->buffer) {
172 446213 writeout(s, s->buffer, s->buf_ptr_max - s->buffer);
173
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 446213 times.
446213 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 597829 s->buf_ptr = s->buf_ptr_max = s->buffer;
180
2/2
✓ Branch 0 taken 107495 times.
✓ Branch 1 taken 490334 times.
597829 if (!s->write_flag)
181 107495 s->buf_end = s->buffer;
182 597829 }
183
184 3913418 void avio_w8(AVIOContext *s, int b)
185 {
186 av_assert2(b>=-128 && b<=255);
187 3913418 *s->buf_ptr++ = b;
188
2/2
✓ Branch 0 taken 195 times.
✓ Branch 1 taken 3913223 times.
3913418 if (s->buf_ptr >= s->buf_end)
189 195 flush_buffer(s);
190 3913418 }
191
192 34947 void ffio_fill(AVIOContext *s, int b, int64_t count)
193 {
194
2/2
✓ Branch 0 taken 22516 times.
✓ Branch 1 taken 34947 times.
57463 while (count > 0) {
195 22516 int len = FFMIN(s->buf_end - s->buf_ptr, count);
196 22516 memset(s->buf_ptr, b, len);
197 22516 s->buf_ptr += len;
198
199
2/2
✓ Branch 0 taken 236 times.
✓ Branch 1 taken 22280 times.
22516 if (s->buf_ptr >= s->buf_end)
200 236 flush_buffer(s);
201
202 22516 count -= len;
203 }
204 34947 }
205
206 947409 void avio_write(AVIOContext *s, const unsigned char *buf, int size)
207 {
208
2/2
✓ Branch 0 taken 13006 times.
✓ Branch 1 taken 934403 times.
947409 if (size <= 0)
209 13006 return;
210
3/4
✓ Branch 0 taken 7353 times.
✓ Branch 1 taken 927050 times.
✓ Branch 2 taken 7353 times.
✗ Branch 3 not taken.
934403 if (s->direct && !s->update_checksum) {
211 7353 avio_flush(s);
212 7353 writeout(s, buf, size);
213 7353 return;
214 }
215 do {
216 1090345 int len = FFMIN(s->buf_end - s->buf_ptr, size);
217 1090345 memcpy(s->buf_ptr, buf, len);
218 1090345 s->buf_ptr += len;
219
220
2/2
✓ Branch 0 taken 164187 times.
✓ Branch 1 taken 926158 times.
1090345 if (s->buf_ptr >= s->buf_end)
221 164187 flush_buffer(s);
222
223 1090345 buf += len;
224 1090345 size -= len;
225
2/2
✓ Branch 0 taken 163295 times.
✓ Branch 1 taken 927050 times.
1090345 } while (size > 0);
226 }
227
228 429648 void avio_flush(AVIOContext *s)
229 {
230
2/2
✓ Branch 0 taken 322153 times.
✓ Branch 1 taken 107495 times.
429648 int seekback = s->write_flag ? FFMIN(0, s->buf_ptr - s->buf_ptr_max) : 0;
231 429648 flush_buffer(s);
232
2/2
✓ Branch 0 taken 132 times.
✓ Branch 1 taken 429516 times.
429648 if (seekback)
233 132 avio_seek(s, seekback, SEEK_CUR);
234 429648 }
235
236 4220434 int64_t avio_seek(AVIOContext *s, int64_t offset, int whence)
237 {
238 4220434 FFIOContext *const ctx = ffiocontext(s);
239 int64_t offset1;
240 int64_t pos;
241 int buffer_size;
242 int short_seek;
243 4220434 whence &= ~AVSEEK_FORCE; // force flag does nothing
244
245
2/2
✓ Branch 0 taken 6604 times.
✓ Branch 1 taken 4213830 times.
4220434 if(!s)
246 6604 return AVERROR(EINVAL);
247
248
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4213830 times.
4213830 if ((whence & AVSEEK_SIZE))
249 ✗ return s->seek ? s->seek(s->opaque, offset, AVSEEK_SIZE) : AVERROR(ENOSYS);
250
251 4213830 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 3866707 times.
✓ Branch 1 taken 347123 times.
4213830 pos = s->pos - (s->write_flag ? 0 : buffer_size);
254
255
3/4
✓ Branch 0 taken 250224 times.
✓ Branch 1 taken 3963606 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 250224 times.
4213830 if (whence != SEEK_CUR && whence != SEEK_SET)
256 ✗ return AVERROR(EINVAL);
257
258
2/2
✓ Branch 0 taken 3963606 times.
✓ Branch 1 taken 250224 times.
4213830 if (whence == SEEK_CUR) {
259 3963606 offset1 = pos + (s->buf_ptr - s->buffer);
260
2/2
✓ Branch 0 taken 3797683 times.
✓ Branch 1 taken 165923 times.
3963606 if (offset == 0)
261 3797683 return offset1;
262
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 165923 times.
165923 if (offset > INT64_MAX - offset1)
263 ✗ return AVERROR(EINVAL);
264 165923 offset += offset1;
265 }
266
2/2
✓ Branch 0 taken 54 times.
✓ Branch 1 taken 416093 times.
416147 if (offset < 0)
267 54 return AVERROR(EINVAL);
268
269 416093 short_seek = ctx->short_seek_threshold;
270
2/2
✓ Branch 0 taken 383760 times.
✓ Branch 1 taken 32333 times.
416093 if (ctx->short_seek_get) {
271 383760 int tmp = ctx->short_seek_get(s->opaque);
272 383760 short_seek = FFMAX(tmp, short_seek);
273 }
274
275 416093 offset1 = offset - pos; // "offset1" is the relative offset from the beginning of s->buffer
276 416093 s->buf_ptr_max = FFMAX(s->buf_ptr_max, s->buf_ptr);
277
5/6
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 416084 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 9 times.
✓ Branch 4 taken 407740 times.
✓ Branch 5 taken 8344 times.
416093 if ((!s->direct || !s->seek) &&
278
4/4
✓ Branch 0 taken 43691 times.
✓ Branch 1 taken 364049 times.
✓ Branch 2 taken 400840 times.
✓ Branch 3 taken 6900 times.
407740 offset1 >= 0 && offset1 <= (s->write_flag ? s->buf_ptr_max - s->buffer : buffer_size)) {
279 /* can do the seek inside the buffer */
280 400840 s->buf_ptr = s->buffer + offset1;
281
2/2
✓ Branch 0 taken 15246 times.
✓ Branch 1 taken 7 times.
15253 } else if ((!(s->seekable & AVIO_SEEKABLE_NORMAL) ||
282
2/2
✓ Branch 0 taken 11149 times.
✓ Branch 1 taken 4097 times.
15246 offset1 <= buffer_size + short_seek) &&
283
4/4
✓ Branch 0 taken 8593 times.
✓ Branch 1 taken 2563 times.
✓ Branch 2 taken 2314 times.
✓ Branch 3 taken 6279 times.
11156 !s->write_flag && offset1 >= 0 &&
284
3/4
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 2307 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 7 times.
2314 (!s->direct || !s->seek)) {
285
4/4
✓ Branch 0 taken 2483 times.
✓ Branch 1 taken 2204 times.
✓ Branch 2 taken 2380 times.
✓ Branch 3 taken 103 times.
4687 while(s->pos < offset && !s->eof_reached)
286 2380 fill_buffer(s);
287
2/2
✓ Branch 0 taken 103 times.
✓ Branch 1 taken 2204 times.
2307 if (s->eof_reached)
288 103 return AVERROR_EOF;
289 2204 s->buf_ptr = s->buf_end - (s->pos - offset);
290
10/10
✓ Branch 0 taken 9383 times.
✓ Branch 1 taken 3563 times.
✓ Branch 2 taken 6279 times.
✓ Branch 3 taken 3104 times.
✓ Branch 4 taken 496 times.
✓ Branch 5 taken 5783 times.
✓ Branch 6 taken 494 times.
✓ Branch 7 taken 2 times.
✓ Branch 8 taken 484 times.
✓ Branch 9 taken 10 times.
12946 } else if(!s->write_flag && offset1 < 0 && -offset1 < buffer_size>>1 && s->seek && offset > 0) {
291 int64_t res;
292
293 484 pos -= FFMIN(buffer_size>>1, pos);
294
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 484 times.
484 if ((res = s->seek(s->opaque, pos, SEEK_SET)) < 0)
295 ✗ return res;
296 484 s->buf_end =
297 484 s->buf_ptr = s->buffer;
298 484 s->pos = pos;
299 484 s->eof_reached = 0;
300 484 fill_buffer(s);
301 484 return avio_seek(s, offset, SEEK_SET);
302 } else {
303 int64_t res;
304
2/2
✓ Branch 0 taken 3563 times.
✓ Branch 1 taken 8899 times.
12462 if (s->write_flag) {
305 3563 flush_buffer(s);
306 }
307
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 12460 times.
12462 if (!s->seek)
308 2 return AVERROR(EPIPE);
309
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 12460 times.
12460 if ((res = s->seek(s->opaque, offset, SEEK_SET)) < 0)
310 ✗ return res;
311 12460 ctx->seek_count++;
312
2/2
✓ Branch 0 taken 8897 times.
✓ Branch 1 taken 3563 times.
12460 if (!s->write_flag)
313 8897 s->buf_end = s->buffer;
314 12460 s->checksum_ptr = s->buf_ptr = s->buf_ptr_max = s->buffer;
315 12460 s->pos = offset;
316 }
317 415504 s->eof_reached = 0;
318 415504 return offset;
319 }
320
321 163599 int64_t avio_skip(AVIOContext *s, int64_t offset)
322 {
323 163599 return avio_seek(s, offset, SEEK_CUR);
324 }
325
326 739484 int64_t avio_size(AVIOContext *s)
327 {
328 739484 FFIOContext *const ctx = ffiocontext(s);
329 int64_t size;
330
331
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 739484 times.
739484 if (!s)
332 ✗ return AVERROR(EINVAL);
333
334
2/2
✓ Branch 0 taken 462564 times.
✓ Branch 1 taken 276920 times.
739484 if (ctx->written_output_size)
335 462564 return ctx->written_output_size;
336
337
2/2
✓ Branch 0 taken 415 times.
✓ Branch 1 taken 276505 times.
276920 if (!s->seek)
338 415 return AVERROR(ENOSYS);
339 276505 size = s->seek(s->opaque, 0, AVSEEK_SIZE);
340
2/2
✓ Branch 0 taken 14634 times.
✓ Branch 1 taken 261871 times.
276505 if (size < 0) {
341
2/2
✓ Branch 1 taken 14629 times.
✓ Branch 2 taken 5 times.
14634 if ((size = s->seek(s->opaque, -1, SEEK_END)) < 0)
342 14629 return size;
343 5 size++;
344 5 s->seek(s->opaque, s->pos, SEEK_SET);
345 }
346 261876 return size;
347 }
348
349 6732994 int avio_feof(AVIOContext *s)
350 {
351
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6732994 times.
6732994 if(!s)
352 ✗ return 0;
353
2/2
✓ Branch 0 taken 8272 times.
✓ Branch 1 taken 6724722 times.
6732994 if(s->eof_reached){
354 8272 s->eof_reached=0;
355 8272 fill_buffer(s);
356 }
357 6732994 return s->eof_reached;
358 }
359
360 554590 void avio_wl32(AVIOContext *s, unsigned int val)
361 {
362 554590 avio_w8(s, (uint8_t) val );
363 554590 avio_w8(s, (uint8_t)(val >> 8 ));
364 554590 avio_w8(s, (uint8_t)(val >> 16));
365 554590 avio_w8(s, val >> 24 );
366 554590 }
367
368 203447 void avio_wb32(AVIOContext *s, unsigned int val)
369 {
370 203447 avio_w8(s, val >> 24 );
371 203447 avio_w8(s, (uint8_t)(val >> 16));
372 203447 avio_w8(s, (uint8_t)(val >> 8 ));
373 203447 avio_w8(s, (uint8_t) val );
374 203447 }
375
376 661 int avio_put_str(AVIOContext *s, const char *str)
377 {
378 661 int len = 1;
379
1/2
✓ Branch 0 taken 661 times.
✗ Branch 1 not taken.
661 if (str) {
380 661 len += strlen(str);
381 661 avio_write(s, (const unsigned char *) str, len);
382 } else
383 ✗ avio_w8(s, 0);
384 661 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 1977 times.
✓ Branch 1 taken 250 times.
2227 while (*q) {
394 uint32_t ch;
395 uint16_t tmp16;
396
397
5/8
✓ Branch 0 taken 1977 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1977 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 32 times.
✓ Branch 6 taken 32 times.
✓ Branch 7 taken 1977 times.
2009 GET_UTF8(ch, *q++, goto invalid;)
398
3/8
✓ Branch 0 taken 1977 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 918 times.
✓ Branch 3 taken 1059 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
1977 PUT_UTF16(ch, tmp16, be ? avio_wb16(s, tmp16) : avio_wl16(s, tmp16);
399 ret += 2;)
400 1977 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 29009 void avio_wb64(AVIOContext *s, uint64_t val)
435 {
436 29009 avio_wb32(s, (uint32_t)(val >> 32));
437 29009 avio_wb32(s, (uint32_t)(val & 0xffffffff));
438 29009 }
439
440 29640 void avio_wl16(AVIOContext *s, unsigned int val)
441 {
442 29640 avio_w8(s, (uint8_t)val);
443 29640 avio_w8(s, (int)val >> 8);
444 29640 }
445
446 98429 void avio_wb16(AVIOContext *s, unsigned int val)
447 {
448 98429 avio_w8(s, (int)val >> 8);
449 98429 avio_w8(s, (uint8_t)val);
450 98429 }
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 16695 void avio_wb24(AVIOContext *s, unsigned int val)
459 {
460 16695 avio_wb16(s, (int)val >> 8);
461 16695 avio_w8(s, (uint8_t)val);
462 16695 }
463
464 659448 void avio_write_marker(AVIOContext *s, int64_t time, enum AVIODataMarkerType type)
465 {
466 659448 FFIOContext *const ctx = ffiocontext(s);
467
2/2
✓ Branch 0 taken 636295 times.
✓ Branch 1 taken 23153 times.
659448 if (type == AVIO_DATA_MARKER_FLUSH_POINT) {
468
2/2
✓ Branch 0 taken 286569 times.
✓ Branch 1 taken 349726 times.
636295 if (s->buf_ptr - s->buffer >= s->min_packet_size)
469 286569 avio_flush(s);
470 636295 return;
471 }
472
2/2
✓ Branch 0 taken 22965 times.
✓ Branch 1 taken 188 times.
23153 if (!s->write_data_type)
473 22965 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 279814 static int read_packet_wrapper(AVIOContext *s, uint8_t *buf, int size)
502 {
503 int ret;
504
505
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 279809 times.
279814 if (!s->read_packet)
506 5 return AVERROR(EINVAL);
507 279809 ret = s->read_packet(s->opaque, buf, size);
508 av_assert2(ret || s->max_packet_size);
509 279809 return ret;
510 }
511
512 /* Input stream */
513
514 154113 static void fill_buffer(AVIOContext *s)
515 {
516 154113 FFIOContext *const ctx = (FFIOContext *)s;
517 308226 int max_buffer_size = s->max_packet_size ?
518
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 154113 times.
154113 s->max_packet_size : IO_BUFFER_SIZE;
519
2/2
✓ Branch 0 taken 76332 times.
✓ Branch 1 taken 77781 times.
154113 uint8_t *dst = s->buf_end - s->buffer + max_buffer_size <= s->buffer_size ?
520 s->buf_end : s->buffer;
521 154113 int len = s->buffer_size - (dst - s->buffer);
522
523
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 154113 times.
154113 if (s->error == AVERROR(EAGAIN)) {
524 ✗ s->error = 0;
525 ✗ s->eof_reached = 0;
526 }
527
528 /* can't fill the buffer without read_packet, just set EOF if appropriate */
529
4/4
✓ Branch 0 taken 152 times.
✓ Branch 1 taken 153961 times.
✓ Branch 2 taken 147 times.
✓ Branch 3 taken 5 times.
154113 if (!s->read_packet && s->buf_ptr >= s->buf_end)
530 147 s->eof_reached = 1;
531
532 /* no need to do anything if EOF already reached */
533
2/2
✓ Branch 0 taken 12090 times.
✓ Branch 1 taken 142023 times.
154113 if (s->eof_reached)
534 12090 return;
535
536
4/4
✓ Branch 0 taken 49564 times.
✓ Branch 1 taken 92459 times.
✓ Branch 2 taken 460 times.
✓ Branch 3 taken 49104 times.
142023 if (s->update_checksum && dst == s->buffer) {
537
2/2
✓ Branch 0 taken 379 times.
✓ Branch 1 taken 81 times.
460 if (s->buf_end > s->checksum_ptr)
538 379 s->checksum = s->update_checksum(s->checksum, s->checksum_ptr,
539 379 s->buf_end - s->checksum_ptr);
540 460 s->checksum_ptr = s->buffer;
541 }
542
543 /* make buffer smaller in case it ended up large after probing */
544
3/4
✓ Branch 0 taken 142018 times.
✓ Branch 1 taken 5 times.
✓ Branch 2 taken 142018 times.
✗ Branch 3 not taken.
142023 if (s->read_packet && ctx->orig_buffer_size &&
545
4/4
✓ Branch 0 taken 49665 times.
✓ Branch 1 taken 92353 times.
✓ Branch 2 taken 49664 times.
✓ Branch 3 taken 1 times.
142018 s->buffer_size > ctx->orig_buffer_size && len >= ctx->orig_buffer_size) {
546
4/4
✓ Branch 0 taken 81 times.
✓ Branch 1 taken 49583 times.
✓ Branch 2 taken 23 times.
✓ Branch 3 taken 58 times.
49664 if (dst == s->buffer && s->buf_ptr != dst) {
547 23 int ret = set_buf_size(s, ctx->orig_buffer_size);
548
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 23 times.
23 if (ret < 0)
549 ✗ av_log(s, AV_LOG_WARNING, "Failed to decrease buffer size\n");
550
551 23 s->checksum_ptr = dst = s->buffer;
552 }
553 49664 len = ctx->orig_buffer_size;
554 }
555
556 142023 len = read_packet_wrapper(s, dst, len);
557
2/2
✓ Branch 0 taken 13472 times.
✓ Branch 1 taken 128551 times.
142023 if (len == AVERROR_EOF) {
558 /* do not modify buffer if EOF reached so that a seek back can
559 be done without rereading data */
560 13472 s->eof_reached = 1;
561
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 128546 times.
128551 } else if (len < 0) {
562 5 s->eof_reached = 1;
563 5 s->error= len;
564 } else {
565 128546 s->pos += len;
566 128546 s->buf_ptr = dst;
567 128546 s->buf_end = dst + len;
568 128546 ffiocontext(s)->bytes_read += len;
569 128546 s->bytes_read = ffiocontext(s)->bytes_read;
570 }
571 }
572
573 36775 unsigned long ff_crc04C11DB7_update(unsigned long checksum, const uint8_t *buf,
574 unsigned int len)
575 {
576 36775 return av_crc(av_crc_get_table(AV_CRC_32_IEEE), checksum, buf, len);
577 }
578
579 9 unsigned long ff_crcEDB88320_update(unsigned long checksum, const uint8_t *buf,
580 unsigned int len)
581 {
582 9 return av_crc(av_crc_get_table(AV_CRC_32_IEEE_LE), checksum, buf, len);
583 }
584
585 198 unsigned long ff_crcA001_update(unsigned long checksum, const uint8_t *buf,
586 unsigned int len)
587 {
588 198 return av_crc(av_crc_get_table(AV_CRC_16_ANSI_LE), checksum, buf, len);
589 }
590
591 33128 unsigned long ffio_get_checksum(AVIOContext *s)
592 {
593 66256 s->checksum = s->update_checksum(s->checksum, s->checksum_ptr,
594 33128 s->buf_ptr - s->checksum_ptr);
595 33128 s->update_checksum = NULL;
596 33128 return s->checksum;
597 }
598
599 33285 void ffio_init_checksum(AVIOContext *s,
600 unsigned long (*update_checksum)(unsigned long c, const uint8_t *p, unsigned int len),
601 unsigned long checksum)
602 {
603 33285 s->update_checksum = update_checksum;
604
2/2
✓ Branch 0 taken 33225 times.
✓ Branch 1 taken 60 times.
33285 if (s->update_checksum) {
605 33225 s->checksum = checksum;
606 33225 s->checksum_ptr = s->buf_ptr;
607 }
608 33285 }
609
610 /* XXX: put an inline version */
611 8295765 int avio_r8(AVIOContext *s)
612 {
613
2/2
✓ Branch 0 taken 26765 times.
✓ Branch 1 taken 8269000 times.
8295765 if (s->buf_ptr >= s->buf_end)
614 26765 fill_buffer(s);
615
2/2
✓ Branch 0 taken 8282913 times.
✓ Branch 1 taken 12852 times.
8295765 if (s->buf_ptr < s->buf_end)
616 8282913 return *s->buf_ptr++;
617 12852 return 0;
618 }
619
620 786915 int avio_read(AVIOContext *s, unsigned char *buf, int size)
621 {
622 int len, size1;
623
624 786915 size1 = size;
625
2/2
✓ Branch 0 taken 960338 times.
✓ Branch 1 taken 784007 times.
1744345 while (size > 0) {
626 960338 len = FFMIN(s->buf_end - s->buf_ptr, size);
627
3/4
✓ Branch 0 taken 727117 times.
✓ Branch 1 taken 233221 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 727117 times.
960338 if (len == 0 || s->write_flag) {
628
8/8
✓ Branch 0 taken 233168 times.
✓ Branch 1 taken 53 times.
✓ Branch 2 taken 137749 times.
✓ Branch 3 taken 95419 times.
✓ Branch 4 taken 137793 times.
✓ Branch 5 taken 9 times.
✓ Branch 6 taken 137791 times.
✓ Branch 7 taken 2 times.
233221 if((s->direct || size > s->buffer_size) && !s->update_checksum && s->read_packet) {
629 // bypass the buffer and read data directly into buf
630
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 137791 times.
137791 if (s->error == AVERROR(EAGAIN)) {
631 ✗ s->error = 0;
632 ✗ s->eof_reached = 0;
633 }
634 137791 len = read_packet_wrapper(s, buf, size);
635
2/2
✓ Branch 0 taken 590 times.
✓ Branch 1 taken 137201 times.
137791 if (len == AVERROR_EOF) {
636 /* do not modify buffer if EOF reached so that a seek back can
637 be done without rereading data */
638 590 s->eof_reached = 1;
639 590 break;
640
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 137201 times.
137201 } else if (len < 0) {
641 ✗ s->eof_reached = 1;
642 ✗ s->error= len;
643 ✗ break;
644 } else {
645 137201 s->pos += len;
646 137201 ffiocontext(s)->bytes_read += len;
647 137201 s->bytes_read = ffiocontext(s)->bytes_read;
648 137201 size -= len;
649 137201 buf += len;
650 // reset the buffer
651 137201 s->buf_ptr = s->buffer;
652 137201 s->buf_end = s->buffer/* + len*/;
653 }
654 } else {
655 95430 fill_buffer(s);
656 95430 len = s->buf_end - s->buf_ptr;
657
2/2
✓ Branch 0 taken 2318 times.
✓ Branch 1 taken 93112 times.
95430 if (len == 0)
658 2318 break;
659 }
660 } else {
661 727117 memcpy(buf, s->buf_ptr, len);
662 727117 buf += len;
663 727117 s->buf_ptr += len;
664 727117 size -= len;
665 }
666 }
667
2/2
✓ Branch 0 taken 3798 times.
✓ Branch 1 taken 783117 times.
786915 if (size1 == size) {
668
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3798 times.
3798 if (s->error) return s->error;
669
2/2
✓ Branch 1 taken 2037 times.
✓ Branch 2 taken 1761 times.
3798 if (avio_feof(s)) return AVERROR_EOF;
670 }
671 784878 return size1 - size;
672 }
673
674 179646 int ffio_read_size(AVIOContext *s, unsigned char *buf, int size)
675 {
676 179646 int ret = avio_read(s, buf, size);
677
2/2
✓ Branch 0 taken 179568 times.
✓ Branch 1 taken 78 times.
179646 if (ret == size)
678 179568 return ret;
679
3/4
✓ Branch 0 taken 54 times.
✓ Branch 1 taken 24 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 54 times.
78 if (ret < 0 && ret != AVERROR_EOF)
680 ✗ return ret;
681 78 return AVERROR_INVALIDDATA;
682 }
683
684 490034 int ffio_read_indirect(AVIOContext *s, unsigned char *buf, int size, const unsigned char **data)
685 {
686
3/4
✓ Branch 0 taken 486503 times.
✓ Branch 1 taken 3531 times.
✓ Branch 2 taken 486503 times.
✗ Branch 3 not taken.
490034 if (s->buf_end - s->buf_ptr >= size && !s->write_flag) {
687 486503 *data = s->buf_ptr;
688 486503 s->buf_ptr += size;
689 486503 return size;
690 } else {
691 3531 *data = buf;
692 3531 return avio_read(s, buf, size);
693 }
694 }
695
696 609225 int avio_read_partial(AVIOContext *s, unsigned char *buf, int size)
697 {
698 int len;
699
700
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 609225 times.
609225 if (size < 0)
701 ✗ return AVERROR(EINVAL);
702
703
2/4
✓ Branch 0 taken 609225 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 609225 times.
609225 if (s->read_packet && s->write_flag) {
704 ✗ len = read_packet_wrapper(s, buf, size);
705 ✗ if (len > 0)
706 ✗ s->pos += len;
707 ✗ return len;
708 }
709
710 609225 len = s->buf_end - s->buf_ptr;
711
2/2
✓ Branch 0 taken 20782 times.
✓ Branch 1 taken 588443 times.
609225 if (len == 0) {
712 20782 fill_buffer(s);
713 20782 len = s->buf_end - s->buf_ptr;
714 }
715
2/2
✓ Branch 0 taken 587910 times.
✓ Branch 1 taken 21315 times.
609225 if (len > size)
716 587910 len = size;
717 609225 memcpy(buf, s->buf_ptr, len);
718 609225 s->buf_ptr += len;
719
2/2
✓ Branch 0 taken 2052 times.
✓ Branch 1 taken 607173 times.
609225 if (!len) {
720
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2052 times.
2052 if (s->error) return s->error;
721
1/2
✓ Branch 1 taken 2052 times.
✗ Branch 2 not taken.
2052 if (avio_feof(s)) return AVERROR_EOF;
722 }
723 607173 return len;
724 }
725
726 #define AVIO_READER(name, type, bytes, load, read1, shift1, read2, shift2) \
727 type name(AVIOContext *s) \
728 { \
729 type val; \
730 if (s->buf_end - s->buf_ptr >= bytes) { \
731 val = load(s->buf_ptr); \
732 s->buf_ptr += bytes; \
733 } else { \
734 val = (type)read1(s) << shift1; \
735 val |= (type)read2(s) << shift2; \
736 } \
737 return val; \
738 }
739
740
2/2
✓ Branch 0 taken 39297 times.
✓ Branch 1 taken 4577 times.
43874 AVIO_READER(avio_rl16, unsigned int, 2, AV_RL16, avio_r8, 0, avio_r8, 8)
741
2/2
✓ Branch 0 taken 327 times.
✓ Branch 1 taken 13 times.
340 AVIO_READER(avio_rl24, unsigned int, 3, AV_RL24, avio_rl16, 0, avio_r8, 16)
742
2/2
✓ Branch 0 taken 415892 times.
✓ Branch 1 taken 2650 times.
418542 AVIO_READER(avio_rl32, unsigned int, 4, AV_RL32, avio_rl16, 0, avio_rl16, 16)
743
2/2
✓ Branch 0 taken 5856 times.
✓ Branch 1 taken 83 times.
5939 AVIO_READER(avio_rl64, uint64_t, 8, AV_RL64, avio_rl32, 0, avio_rl32, 32)
744
2/2
✓ Branch 0 taken 112183 times.
✓ Branch 1 taken 4587 times.
116770 AVIO_READER(avio_rb16, unsigned int, 2, AV_RB16, avio_r8, 8, avio_r8, 0)
745
2/2
✓ Branch 0 taken 37034 times.
✓ Branch 1 taken 163 times.
37197 AVIO_READER(avio_rb24, unsigned int, 3, AV_RB24, avio_rb16, 8, avio_r8, 0)
746
2/2
✓ Branch 0 taken 274331 times.
✓ Branch 1 taken 3858 times.
278189 AVIO_READER(avio_rb32, unsigned int, 4, AV_RB32, avio_rb16, 16, avio_rb16, 0)
747
2/2
✓ Branch 0 taken 147144 times.
✓ Branch 1 taken 275 times.
147419 AVIO_READER(avio_rb64, uint64_t, 8, AV_RB64, avio_rb32, 32, avio_rb32, 0)
748 1295 int ff_get_line(AVIOContext *s, char *buf, int maxlen)
749 {
750 1295 int i = 0;
751 char c;
752
753 do {
754 31097 c = avio_r8(s);
755
3/4
✓ Branch 0 taken 31035 times.
✓ Branch 1 taken 62 times.
✓ Branch 2 taken 31035 times.
✗ Branch 3 not taken.
31097 if (c && i < maxlen-1)
756 31035 buf[i++] = c;
757
6/6
✓ Branch 0 taken 30174 times.
✓ Branch 1 taken 923 times.
✓ Branch 2 taken 29864 times.
✓ Branch 3 taken 310 times.
✓ Branch 4 taken 29802 times.
✓ Branch 5 taken 62 times.
31097 } while (c != '\n' && c != '\r' && c);
758
3/6
✓ Branch 0 taken 310 times.
✓ Branch 1 taken 985 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 310 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
1295 if (c == '\r' && avio_r8(s) != '\n' && !avio_feof(s))
759 ✗ avio_skip(s, -1);
760
761 1295 buf[i] = 0;
762 1295 return i;
763 }
764
765 594 int ff_get_chomp_line(AVIOContext *s, char *buf, int maxlen)
766 {
767 594 int len = ff_get_line(s, buf, maxlen);
768
4/4
✓ Branch 0 taken 1095 times.
✓ Branch 1 taken 47 times.
✓ Branch 2 taken 548 times.
✓ Branch 3 taken 547 times.
1142 while (len > 0 && av_isspace(buf[len - 1]))
769 548 buf[--len] = '\0';
770 594 return len;
771 }
772
773 typedef enum FFBPrintReadStringMode {
774 FFBPrintReadString = 0,
775 FFBPrintReadLine = 1,
776 } FFBPrintReadStringMode;
777
778 464 static int64_t read_string_to_bprint(AVIOContext *s, AVBPrint *bp,
779 FFBPrintReadStringMode mode,
780 int64_t max_len)
781 {
782 int len, end;
783 464 int64_t read = 0;
784 char tmp[1024];
785 char c;
786
787
1/2
✓ Branch 0 taken 464 times.
✗ Branch 1 not taken.
464 if (!max_len)
788 ✗ return 0;
789
790 do {
791 464 len = 0;
792 do {
793 7246 c = avio_r8(s);
794
7/8
✓ Branch 0 taken 4865 times.
✓ Branch 1 taken 2381 times.
✓ Branch 2 taken 4865 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 4581 times.
✓ Branch 5 taken 284 times.
✓ Branch 6 taken 180 times.
✓ Branch 7 taken 6782 times.
7246 end = ((mode == FFBPrintReadLine && (c == '\r' || c == '\n')) ||
795 c == '\0');
796
2/2
✓ Branch 0 taken 6782 times.
✓ Branch 1 taken 464 times.
7246 if (!end)
797 6782 tmp[len++] = c;
798
5/6
✓ Branch 0 taken 6782 times.
✓ Branch 1 taken 464 times.
✓ Branch 2 taken 6782 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 4574 times.
✓ Branch 5 taken 2208 times.
7246 } while (!end && len < sizeof(tmp) &&
799
1/2
✓ Branch 0 taken 2208 times.
✗ Branch 1 not taken.
2208 ((max_len < 0) || (read + len < max_len)));
800 464 av_bprint_append_data(bp, tmp, len);
801 464 read += len;
802
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 464 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
464 } while (!end && ((max_len < 0) || (read < max_len)));
803
804
3/4
✓ Branch 0 taken 291 times.
✓ Branch 1 taken 173 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 291 times.
464 if (mode == FFBPrintReadLine &&
805 ✗ c == '\r' && avio_r8(s) != '\n' && !avio_feof(s))
806 ✗ avio_skip(s, -1);
807
808
3/4
✓ Branch 0 taken 180 times.
✓ Branch 1 taken 284 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 180 times.
464 if (!c && s->error)
809 ✗ return s->error;
810
811
6/6
✓ Branch 0 taken 180 times.
✓ Branch 1 taken 284 times.
✓ Branch 2 taken 30 times.
✓ Branch 3 taken 150 times.
✓ Branch 5 taken 7 times.
✓ Branch 6 taken 23 times.
464 if (!c && !read && avio_feof(s))
812 7 return AVERROR_EOF;
813
814 457 return read;
815 }
816
817 464 static int64_t read_string_to_bprint_overwrite(AVIOContext *s, AVBPrint *bp,
818 FFBPrintReadStringMode mode,
819 int64_t max_len)
820 {
821 int64_t ret;
822
823 464 av_bprint_clear(bp);
824 464 ret = read_string_to_bprint(s, bp, mode, max_len);
825
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 457 times.
464 if (ret < 0)
826 7 return ret;
827
828
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 457 times.
457 if (!av_bprint_is_complete(bp))
829 ✗ return AVERROR(ENOMEM);
830
831 457 return bp->len;
832 }
833
834 291 int64_t ff_read_line_to_bprint_overwrite(AVIOContext *s, AVBPrint *bp)
835 {
836 291 return read_string_to_bprint_overwrite(s, bp, FFBPrintReadLine, -1);
837 }
838
839 173 int64_t ff_read_string_to_bprint_overwrite(AVIOContext *s, AVBPrint *bp,
840 int64_t max_len)
841 {
842 173 return read_string_to_bprint_overwrite(s, bp, FFBPrintReadString, max_len);
843 }
844
845 681 int avio_get_str(AVIOContext *s, int maxlen, char *buf, int buflen)
846 {
847 int i;
848
849
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 681 times.
681 if (buflen <= 0)
850 ✗ return AVERROR(EINVAL);
851 // reserve 1 byte for terminating 0
852 681 buflen = FFMIN(buflen - 1, maxlen);
853
2/2
✓ Branch 0 taken 10069 times.
✓ Branch 1 taken 282 times.
10351 for (i = 0; i < buflen; i++)
854
2/2
✓ Branch 1 taken 399 times.
✓ Branch 2 taken 9670 times.
10069 if (!(buf[i] = avio_r8(s)))
855 399 return i + 1;
856 282 buf[i] = 0;
857
2/2
✓ Branch 0 taken 290 times.
✓ Branch 1 taken 262 times.
552 for (; i < maxlen; i++)
858
2/2
✓ Branch 1 taken 20 times.
✓ Branch 2 taken 270 times.
290 if (!avio_r8(s))
859 20 return i + 1;
860 262 return maxlen;
861 }
862
863 #define GET_STR16(type, read) \
864 int avio_get_str16 ##type(AVIOContext *pb, int maxlen, char *buf, int buflen)\
865 {\
866 char* q = buf;\
867 int ret = 0;\
868 if (buflen <= 0) \
869 return AVERROR(EINVAL); \
870 while (ret + 1 < maxlen) {\
871 uint8_t tmp;\
872 uint32_t ch;\
873 GET_UTF16(ch, (ret += 2) <= maxlen ? read(pb) : 0, break;)\
874 if (!ch)\
875 break;\
876 PUT_UTF8(ch, tmp, if (q - buf < buflen - 1) *q++ = tmp;)\
877 }\
878 *q = 0;\
879 return ret;\
880 }\
881
882
14/26
✗ Branch 0 not taken.
✓ Branch 1 taken 773 times.
✓ Branch 2 taken 10196 times.
✗ Branch 3 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 10196 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 753 times.
✓ Branch 15 taken 9443 times.
✓ Branch 16 taken 9440 times.
✓ Branch 17 taken 3 times.
✓ Branch 18 taken 9440 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 10196 times.
✓ Branch 27 taken 20 times.
10219 GET_STR16(le, avio_rl16)
883
9/26
✗ Branch 0 not taken.
✓ Branch 1 taken 625 times.
✓ Branch 2 taken 5808 times.
✗ Branch 3 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 5808 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 5253 times.
✓ Branch 16 taken 5253 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 5253 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 5808 times.
✓ Branch 27 taken 70 times.
5878 GET_STR16(be, avio_rb16)
884
885 #undef GET_STR16
886
887 15934 uint64_t ffio_read_varlen(AVIOContext *bc){
888 15934 uint64_t val = 0;
889 int tmp;
890
891 do{
892 24651 tmp = avio_r8(bc);
893 24651 val= (val<<7) + (tmp&127);
894
2/2
✓ Branch 0 taken 8717 times.
✓ Branch 1 taken 15934 times.
24651 }while(tmp&128);
895 15934 return val;
896 }
897
898 1485 unsigned int ffio_read_leb(AVIOContext *s) {
899 1485 int more, i = 0;
900 1485 unsigned leb = 0;
901
902 do {
903 2035 int byte = avio_r8(s);
904 2035 unsigned bits = byte & 0x7f;
905 2035 more = byte & 0x80;
906
1/2
✓ Branch 0 taken 2035 times.
✗ Branch 1 not taken.
2035 if (i <= 4)
907 2035 leb |= bits << (i * 7);
908
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2035 times.
2035 if (++i == 8)
909 ✗ break;
910
2/2
✓ Branch 0 taken 550 times.
✓ Branch 1 taken 1485 times.
2035 } while (more);
911
912 1485 return leb;
913 }
914
915 6572 void ffio_write_leb(AVIOContext *s, unsigned val)
916 {
917 int len;
918 uint8_t byte;
919
920 6572 len = (av_log2(val) + 7) / 7;
921
922
2/2
✓ Branch 0 taken 11426 times.
✓ Branch 1 taken 6572 times.
17998 for (int i = 0; i < len; i++) {
923 11426 byte = val >> (7 * i) & 0x7f;
924
2/2
✓ Branch 0 taken 4854 times.
✓ Branch 1 taken 6572 times.
11426 if (i < len - 1)
925 4854 byte |= 0x80;
926
927 11426 avio_w8(s, byte);
928 }
929 6572 }
930
931 28 void ffio_write_lines(AVIOContext *s, const unsigned char *buf, int size,
932 const unsigned char *ending)
933 {
934
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 28 times.
28 int ending_len = ending ? strlen(ending) : 1;
935
1/2
✓ Branch 0 taken 28 times.
✗ Branch 1 not taken.
28 if (!ending)
936 28 ending = "\n";
937
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 28 times.
28 if (size < 0)
938 ✗ size = strlen(buf);
939
940
2/2
✓ Branch 0 taken 439 times.
✓ Branch 1 taken 28 times.
467 while (size > 0) {
941 439 size_t len = 0;
942 439 char last = 0;
943
1/2
✓ Branch 0 taken 19804 times.
✗ Branch 1 not taken.
19804 for (; len < size; len++) {
944 19804 last = buf[len];
945
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')
946 break;
947 }
948
949 439 avio_write(s, buf, len);
950 439 avio_write(s, ending, ending_len);
951
952 439 buf += len + 1;
953 439 size -= len + 1;
954
955
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') {
956 103 buf++;
957 103 size--;
958 }
959 }
960 28 }
961
962 24 int ffio_copy_url_options(AVIOContext* pb, AVDictionary** avio_opts)
963 {
964 24 const char *opts[] = {
965 "headers", "user_agent", "cookies", "http_proxy", "referer", "rw_timeout", "icy", "prefer_libcurl", NULL };
966 24 const char **opt = opts;
967 24 uint8_t *buf = NULL;
968 24 int ret = 0;
969
970
2/2
✓ Branch 0 taken 192 times.
✓ Branch 1 taken 24 times.
216 while (*opt) {
971
2/2
✓ Branch 1 taken 48 times.
✓ Branch 2 taken 144 times.
192 if (av_opt_get(pb, *opt, AV_OPT_SEARCH_CHILDREN, &buf) >= 0) {
972
1/2
✓ Branch 0 taken 48 times.
✗ Branch 1 not taken.
48 if (buf[0] != '\0') {
973 48 ret = av_dict_set(avio_opts, *opt, buf, AV_DICT_DONT_STRDUP_VAL);
974
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 48 times.
48 if (ret < 0)
975 ✗ return ret;
976 } else {
977 ✗ av_freep(&buf);
978 }
979 }
980 192 opt++;
981 }
982
983 24 return ret;
984 }
985
986 65 static void update_checksum(AVIOContext *s)
987 {
988
3/4
✓ Branch 0 taken 42 times.
✓ Branch 1 taken 23 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 42 times.
65 if (s->update_checksum && s->buf_ptr > s->checksum_ptr) {
989 ✗ s->checksum = s->update_checksum(s->checksum, s->checksum_ptr,
990 ✗ s->buf_ptr - s->checksum_ptr);
991 }
992 65 }
993
994 24758 int ffio_ensure_seekback(AVIOContext *s, int64_t buf_size)
995 {
996 uint8_t *buffer;
997 49516 int max_buffer_size = s->max_packet_size ?
998
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 24758 times.
24758 s->max_packet_size : IO_BUFFER_SIZE;
999 24758 ptrdiff_t filled = s->buf_end - s->buf_ptr;
1000
1001
2/2
✓ Branch 0 taken 21669 times.
✓ Branch 1 taken 3089 times.
24758 if (buf_size <= s->buf_end - s->buf_ptr)
1002 21669 return 0;
1003
1004
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3089 times.
3089 if (buf_size > INT_MAX - max_buffer_size)
1005 ✗ return AVERROR(EINVAL);
1006
1007 3089 buf_size += max_buffer_size - 1;
1008
1009
5/6
✓ Branch 0 taken 3089 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 87 times.
✓ Branch 3 taken 3002 times.
✓ Branch 4 taken 22 times.
✓ Branch 5 taken 65 times.
3089 if (buf_size + s->buf_ptr - s->buffer <= s->buffer_size || s->seekable || !s->read_packet)
1010 3024 return 0;
1011
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 65 times.
65 av_assert0(!s->write_flag);
1012
1013
2/2
✓ Branch 0 taken 40 times.
✓ Branch 1 taken 25 times.
65 if (buf_size <= s->buffer_size) {
1014 40 update_checksum(s);
1015 40 memmove(s->buffer, s->buf_ptr, filled);
1016 } else {
1017 25 buffer = av_malloc(buf_size);
1018
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 25 times.
25 if (!buffer)
1019 ✗ return AVERROR(ENOMEM);
1020 25 update_checksum(s);
1021 25 memcpy(buffer, s->buf_ptr, filled);
1022 25 av_free(s->buffer);
1023 25 s->buffer = buffer;
1024 25 s->buffer_size = buf_size;
1025 }
1026 65 s->buf_ptr = s->buffer;
1027 65 s->buf_end = s->buffer + filled;
1028 65 s->checksum_ptr = s->buffer;
1029 65 return 0;
1030 }
1031
1032 6995 int ffio_limit(AVIOContext *s, int size)
1033 {
1034 6995 FFIOContext *const ctx = ffiocontext(s);
1035
2/2
✓ Branch 0 taken 6968 times.
✓ Branch 1 taken 27 times.
6995 if (ctx->maxsize >= 0) {
1036 6968 int64_t pos = avio_tell(s);
1037 6968 int64_t remaining = ctx->maxsize - pos;
1038
2/2
✓ Branch 0 taken 472 times.
✓ Branch 1 taken 6496 times.
6968 if (remaining < size) {
1039 472 int64_t newsize = avio_size(s);
1040
3/4
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 467 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 5 times.
472 if (!ctx->maxsize || ctx->maxsize < newsize)
1041 467 ctx->maxsize = newsize - !newsize;
1042
4/4
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 470 times.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 1 times.
472 if (pos > ctx->maxsize && ctx->maxsize >= 0)
1043 1 ctx->maxsize = AVERROR(EIO);
1044
2/2
✓ Branch 0 taken 470 times.
✓ Branch 1 taken 2 times.
472 if (ctx->maxsize >= 0)
1045 470 remaining = ctx->maxsize - pos;
1046 }
1047
1048
5/6
✓ Branch 0 taken 6966 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 5 times.
✓ Branch 3 taken 6961 times.
✓ Branch 4 taken 5 times.
✗ Branch 5 not taken.
6968 if (ctx->maxsize >= 0 && remaining < size && size > 1) {
1049 5 av_log(NULL, remaining ? AV_LOG_ERROR : AV_LOG_DEBUG,
1050 "Truncating packet of size %d to %"PRId64"\n",
1051
1/2
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
5 size, remaining + !remaining);
1052 5 size = remaining + !remaining;
1053 }
1054 }
1055 6995 return size;
1056 }
1057
1058 23 static int set_buf_size(AVIOContext *s, int buf_size)
1059 {
1060 uint8_t *buffer;
1061 23 buffer = av_malloc(buf_size);
1062
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 23 times.
23 if (!buffer)
1063 ✗ return AVERROR(ENOMEM);
1064
1065 23 av_free(s->buffer);
1066 23 s->buffer = buffer;
1067 46 ffiocontext(s)->orig_buffer_size =
1068 23 s->buffer_size = buf_size;
1069 23 s->buf_ptr = s->buf_ptr_max = buffer;
1070
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 23 times.
23 url_resetbuf(s, s->write_flag ? AVIO_FLAG_WRITE : AVIO_FLAG_READ);
1071 23 return 0;
1072 }
1073
1074 ✗ int ffio_realloc_buf(AVIOContext *s, int buf_size)
1075 {
1076 uint8_t *buffer;
1077 int data_size;
1078
1079 ✗ if (!s->buffer_size)
1080 ✗ return set_buf_size(s, buf_size);
1081
1082 ✗ if (buf_size <= s->buffer_size)
1083 ✗ return 0;
1084
1085 ✗ buffer = av_malloc(buf_size);
1086 ✗ if (!buffer)
1087 ✗ return AVERROR(ENOMEM);
1088
1089 ✗ data_size = s->write_flag ? (s->buf_ptr - s->buffer) : (s->buf_end - s->buf_ptr);
1090 ✗ if (data_size > 0)
1091 ✗ memcpy(buffer, s->write_flag ? s->buffer : s->buf_ptr, data_size);
1092 ✗ av_free(s->buffer);
1093 ✗ s->buffer = buffer;
1094 ✗ ffiocontext(s)->orig_buffer_size = buf_size;
1095 ✗ s->buffer_size = buf_size;
1096 ✗ s->buf_ptr = s->write_flag ? (s->buffer + data_size) : s->buffer;
1097 ✗ if (s->write_flag)
1098 ✗ s->buf_ptr_max = s->buffer + data_size;
1099
1100 ✗ s->buf_end = s->write_flag ? (s->buffer + s->buffer_size) : (s->buf_ptr + data_size);
1101
1102 ✗ return 0;
1103 }
1104
1105 256337 static int url_resetbuf(AVIOContext *s, int flags)
1106 {
1107 av_assert1(flags == AVIO_FLAG_WRITE || flags == AVIO_FLAG_READ);
1108
1109
2/2
✓ Branch 0 taken 58062 times.
✓ Branch 1 taken 198275 times.
256337 if (flags & AVIO_FLAG_WRITE) {
1110 58062 s->buf_end = s->buffer + s->buffer_size;
1111 58062 s->write_flag = 1;
1112 } else {
1113 198275 s->buf_end = s->buffer;
1114 198275 s->write_flag = 0;
1115 }
1116 256337 return 0;
1117 }
1118
1119 4346 int ffio_rewind_with_probe_data(AVIOContext *s, unsigned char **bufp, int buf_size)
1120 {
1121 int64_t buffer_start;
1122 int buffer_size;
1123 int overlap, new_size, alloc_size;
1124 4346 uint8_t *buf = *bufp;
1125
1126
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4346 times.
4346 if (s->write_flag) {
1127 ✗ av_freep(bufp);
1128 ✗ return AVERROR(EINVAL);
1129 }
1130
1131 4346 buffer_size = s->buf_end - s->buffer;
1132
1133 /* the buffers must touch or overlap */
1134
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4346 times.
4346 if ((buffer_start = s->pos - buffer_size) > buf_size) {
1135 ✗ av_freep(bufp);
1136 ✗ return AVERROR(EINVAL);
1137 }
1138
1139 4346 overlap = buf_size - buffer_start;
1140 4346 new_size = buf_size + buffer_size - overlap;
1141
1142 4346 alloc_size = FFMAX(s->buffer_size, new_size);
1143
2/2
✓ Branch 0 taken 4289 times.
✓ Branch 1 taken 57 times.
4346 if (alloc_size > buf_size)
1144
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 4289 times.
4289 if (!(buf = (*bufp) = av_realloc_f(buf, 1, alloc_size)))
1145 ✗ return AVERROR(ENOMEM);
1146
1147
2/2
✓ Branch 0 taken 4061 times.
✓ Branch 1 taken 285 times.
4346 if (new_size > buf_size) {
1148 4061 memcpy(buf + buf_size, s->buffer + overlap, buffer_size - overlap);
1149 4061 buf_size = new_size;
1150 }
1151
1152 4346 av_free(s->buffer);
1153 4346 s->buf_ptr = s->buffer = buf;
1154 4346 s->buffer_size = alloc_size;
1155 4346 s->pos = buf_size;
1156 4346 s->buf_end = s->buf_ptr + buf_size;
1157 4346 s->eof_reached = 0;
1158
1159 4346 return 0;
1160 }
1161
1162 27520 int avio_vprintf(AVIOContext *s, const char *fmt, va_list ap)
1163 {
1164 AVBPrint bp;
1165
1166 27520 av_bprint_init(&bp, 0, INT_MAX);
1167 27520 av_vbprintf(&bp, fmt, ap);
1168
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 27520 times.
27520 if (!av_bprint_is_complete(&bp)) {
1169 ✗ av_bprint_finalize(&bp, NULL);
1170 ✗ s->error = AVERROR(ENOMEM);
1171 ✗ return AVERROR(ENOMEM);
1172 }
1173 27520 avio_write(s, bp.str, bp.len);
1174 27520 av_bprint_finalize(&bp, NULL);
1175 27520 return bp.len;
1176 }
1177
1178 27253 int avio_printf(AVIOContext *s, const char *fmt, ...)
1179 {
1180 va_list ap;
1181 int ret;
1182
1183 27253 va_start(ap, fmt);
1184 27253 ret = avio_vprintf(s, fmt, ap);
1185 27253 va_end(ap);
1186
1187 27253 return ret;
1188 }
1189
1190 485 void avio_print_string_array(AVIOContext *s, const char *const strings[])
1191 {
1192
2/2
✓ Branch 0 taken 1455 times.
✓ Branch 1 taken 485 times.
1940 for(; *strings; strings++)
1193 1455 avio_write(s, (const unsigned char *)*strings, strlen(*strings));
1194 485 }
1195
1196 ✗ int avio_pause(AVIOContext *s, int pause)
1197 {
1198 ✗ if (!s->read_pause)
1199 ✗ return AVERROR(ENOSYS);
1200 ✗ return s->read_pause(s->opaque, pause);
1201 }
1202
1203 321 int64_t avio_seek_time(AVIOContext *s, int stream_index,
1204 int64_t timestamp, int flags)
1205 {
1206 int64_t ret;
1207
1/2
✓ Branch 0 taken 321 times.
✗ Branch 1 not taken.
321 if (!s->read_seek)
1208 321 return AVERROR(ENOSYS);
1209 ✗ ret = s->read_seek(s->opaque, stream_index, timestamp, flags);
1210 ✗ if (ret >= 0) {
1211 int64_t pos;
1212 ✗ s->buf_ptr = s->buf_end; // Flush buffer
1213 ✗ pos = s->seek(s->opaque, 0, SEEK_CUR);
1214 ✗ if (pos >= 0)
1215 ✗ s->pos = pos;
1216 ✗ else if (pos != AVERROR(ENOSYS))
1217 ✗ ret = pos;
1218 }
1219 ✗ return ret;
1220 }
1221
1222 90 int avio_read_to_bprint(AVIOContext *h, AVBPrint *pb, size_t max_size)
1223 {
1224 int ret;
1225 char buf[1024];
1226
2/2
✓ Branch 0 taken 8230 times.
✓ Branch 1 taken 3 times.
8233 while (max_size) {
1227 8230 ret = avio_read(h, buf, FFMIN(max_size, sizeof(buf)));
1228
2/2
✓ Branch 0 taken 87 times.
✓ Branch 1 taken 8143 times.
8230 if (ret == AVERROR_EOF)
1229 87 return 0;
1230
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8143 times.
8143 if (ret <= 0)
1231 ✗ return ret;
1232 8143 av_bprint_append_data(pb, buf, ret);
1233
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 8143 times.
8143 if (!av_bprint_is_complete(pb))
1234 ✗ return AVERROR(ENOMEM);
1235 8143 max_size -= ret;
1236 }
1237 3 return 0;
1238 }
1239
1240 /* output in a dynamic buffer */
1241
1242 typedef struct DynBuffer {
1243 int pos, size, allocated_size;
1244 uint8_t *buffer;
1245 int io_buffer_size;
1246 uint8_t io_buffer[1];
1247 } DynBuffer;
1248
1249 39386 static int dyn_buf_write(void *opaque, const uint8_t *buf, int buf_size)
1250 {
1251 39386 DynBuffer *d = opaque;
1252 unsigned new_size;
1253
1254 /* reallocate buffer if needed */
1255 39386 new_size = (unsigned)d->pos + buf_size;
1256
2/4
✓ Branch 0 taken 39386 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 39386 times.
39386 if (new_size < d->pos || new_size > INT_MAX)
1257 ✗ return AVERROR(ERANGE);
1258
2/2
✓ Branch 0 taken 9054 times.
✓ Branch 1 taken 30332 times.
39386 if (new_size > d->allocated_size) {
1259 20243 unsigned new_allocated_size = d->allocated_size ? d->allocated_size
1260
2/2
✓ Branch 0 taken 2135 times.
✓ Branch 1 taken 6919 times.
9054 : new_size;
1261 int err;
1262
2/2
✓ Branch 0 taken 3672 times.
✓ Branch 1 taken 9054 times.
12726 while (new_size > new_allocated_size)
1263 3672 new_allocated_size += new_allocated_size / 2 + 1;
1264
1265
1/2
✓ Branch 0 taken 9054 times.
✗ Branch 1 not taken.
9054 new_allocated_size = FFMIN(new_allocated_size, INT_MAX);
1266
1267
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 9054 times.
9054 if ((err = av_reallocp(&d->buffer, new_allocated_size)) < 0) {
1268 ✗ d->allocated_size = 0;
1269 ✗ d->size = 0;
1270 ✗ return err;
1271 }
1272 9054 d->allocated_size = new_allocated_size;
1273 }
1274 39386 memcpy(d->buffer + d->pos, buf, buf_size);
1275 39386 d->pos = new_size;
1276
2/2
✓ Branch 0 taken 39263 times.
✓ Branch 1 taken 123 times.
39386 if (d->pos > d->size)
1277 39263 d->size = d->pos;
1278 39386 return buf_size;
1279 }
1280
1281 265 static int dyn_packet_buf_write(void *opaque, const uint8_t *buf, int buf_size)
1282 {
1283 unsigned char buf1[4];
1284 int ret;
1285
1286 /* packetized write: output the header */
1287 265 AV_WB32(buf1, buf_size);
1288 265 ret = dyn_buf_write(opaque, buf1, 4);
1289
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 265 times.
265 if (ret < 0)
1290 ✗ return ret;
1291
1292 /* then the data */
1293 265 return dyn_buf_write(opaque, buf, buf_size);
1294 }
1295
1296 684 static int64_t dyn_buf_seek(void *opaque, int64_t offset, int whence)
1297 {
1298 684 DynBuffer *d = opaque;
1299
1300
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 684 times.
684 if (whence == SEEK_CUR)
1301 ✗ offset += d->pos;
1302
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 684 times.
684 else if (whence == SEEK_END)
1303 ✗ offset += d->size;
1304
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 684 times.
684 if (offset < 0)
1305 ✗ return AVERROR(EINVAL);
1306
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 684 times.
684 if (offset > INT_MAX)
1307 ✗ return AVERROR(ERANGE);
1308 684 d->pos = offset;
1309 684 return 0;
1310 }
1311
1312 25761 static int url_open_dyn_buf_internal(AVIOContext **s, int max_packet_size)
1313 {
1314 struct { FFIOContext pb; DynBuffer d; } *ret;
1315 DynBuffer *d;
1316
2/2
✓ Branch 0 taken 38 times.
✓ Branch 1 taken 25723 times.
25761 unsigned io_buffer_size = max_packet_size ? max_packet_size : 1024;
1317
1318 if (sizeof(*ret) + io_buffer_size < io_buffer_size)
1319 return AVERROR(ERANGE);
1320 25761 ret = av_mallocz(sizeof(*ret) + io_buffer_size);
1321
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 25761 times.
25761 if (!ret)
1322 ✗ return AVERROR(ENOMEM);
1323 25761 d = &ret->d;
1324 25761 d->io_buffer_size = io_buffer_size;
1325
4/4
✓ Branch 0 taken 25723 times.
✓ Branch 1 taken 38 times.
✓ Branch 2 taken 38 times.
✓ Branch 3 taken 25723 times.
25761 ffio_init_context(&ret->pb, d->io_buffer, d->io_buffer_size, 1, d, NULL,
1326 max_packet_size ? dyn_packet_buf_write : dyn_buf_write,
1327 max_packet_size ? NULL : dyn_buf_seek);
1328 25761 *s = &ret->pb.pub;
1329 25761 (*s)->max_packet_size = max_packet_size;
1330 25761 return 0;
1331 }
1332
1333 25482 int avio_open_dyn_buf(AVIOContext **s)
1334 {
1335 25482 return url_open_dyn_buf_internal(s, 0);
1336 }
1337
1338 38 int ffio_open_dyn_packet_buf(AVIOContext **s, int max_packet_size)
1339 {
1340
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 38 times.
38 if (max_packet_size <= 0)
1341 ✗ return AVERROR(EINVAL);
1342 38 return url_open_dyn_buf_internal(s, max_packet_size);
1343 }
1344
1345 29404 int avio_get_dyn_buf(AVIOContext *s, uint8_t **pbuffer)
1346 {
1347 DynBuffer *d;
1348
1349
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 29404 times.
29404 if (!s) {
1350 ✗ *pbuffer = NULL;
1351 ✗ return 0;
1352 }
1353 29404 d = s->opaque;
1354
1355
3/4
✓ Branch 0 taken 29404 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 28603 times.
✓ Branch 3 taken 801 times.
29404 if (!s->error && !d->size) {
1356 28603 *pbuffer = d->io_buffer;
1357 28603 return FFMAX(s->buf_ptr, s->buf_ptr_max) - s->buffer;
1358 }
1359
1360 801 avio_flush(s);
1361
1362 801 *pbuffer = d->buffer;
1363
1364 801 return d->size;
1365 }
1366
1367 22232 void ffio_reset_dyn_buf(AVIOContext *s)
1368 {
1369 22232 DynBuffer *d = s->opaque;
1370 22232 int max_packet_size = s->max_packet_size;
1371
1372 22232 ffio_init_context(ffiocontext(s), d->io_buffer, d->io_buffer_size,
1373 1, d, NULL, s->write_packet, s->seek);
1374 22232 s->max_packet_size = max_packet_size;
1375 22232 d->pos = d->size = 0;
1376 22232 }
1377
1378 6804 int avio_close_dyn_buf(AVIOContext *s, uint8_t **pbuffer)
1379 {
1380 DynBuffer *d;
1381 int size;
1382 6804 int padding = 0;
1383
1384
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6804 times.
6804 if (!s) {
1385 ✗ *pbuffer = NULL;
1386 ✗ return 0;
1387 }
1388
1389 /* don't attempt to pad fixed-size packet buffers */
1390
2/2
✓ Branch 0 taken 6768 times.
✓ Branch 1 taken 36 times.
6804 if (!s->max_packet_size) {
1391 6768 ffio_fill(s, 0, AV_INPUT_BUFFER_PADDING_SIZE);
1392 6768 padding = AV_INPUT_BUFFER_PADDING_SIZE;
1393 }
1394
1395 6804 avio_flush(s);
1396
1397 6804 d = s->opaque;
1398 6804 *pbuffer = d->buffer;
1399 6804 size = d->size;
1400
1401 6804 avio_context_free(&s);
1402
1403 6804 return size - padding;
1404 }
1405
1406 19968 void ffio_free_dyn_buf(AVIOContext **s)
1407 {
1408 DynBuffer *d;
1409
1410
2/2
✓ Branch 0 taken 1252 times.
✓ Branch 1 taken 18716 times.
19968 if (!*s)
1411 1252 return;
1412
1413 18716 d = (*s)->opaque;
1414 18716 av_free(d->buffer);
1415 18716 avio_context_free(s);
1416 }
1417
1418 732 static int null_buf_write(void *opaque, const uint8_t *buf, int buf_size)
1419 {
1420 732 DynBuffer *d = opaque;
1421
1422
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 732 times.
732 if ((unsigned)d->pos + (unsigned)buf_size > INT_MAX)
1423 ✗ return AVERROR(ERANGE);
1424 732 d->pos += buf_size;
1425
2/2
✓ Branch 0 taken 504 times.
✓ Branch 1 taken 228 times.
732 if (d->pos > d->size)
1426 504 d->size = d->pos;
1427 732 return buf_size;
1428 }
1429
1430 241 int ffio_open_null_buf(AVIOContext **s)
1431 {
1432 241 int ret = url_open_dyn_buf_internal(s, 0);
1433
1/2
✓ Branch 0 taken 241 times.
✗ Branch 1 not taken.
241 if (ret >= 0) {
1434 241 AVIOContext *pb = *s;
1435 241 pb->write_packet = null_buf_write;
1436 }
1437 241 return ret;
1438 }
1439
1440 241 int ffio_close_null_buf(AVIOContext *s)
1441 {
1442 241 DynBuffer *d = s->opaque;
1443 int size;
1444
1445 241 avio_flush(s);
1446
1447
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 241 times.
241 size = s->error ? s->error : d->size;
1448
1449 241 avio_context_free(&s);
1450
1451 241 return size;
1452 }
1453