FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavformat/utils.c
Date: 2025-04-25 22:50:00
Exec Total Coverage
Lines: 201 335 60.0%
Functions: 21 27 77.8%
Branches: 113 263 43.0%

Line Branch Exec Source
1 /*
2 * various utility functions for use within FFmpeg
3 * Copyright (c) 2000, 2001, 2002 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 <stdint.h>
23 #include <time.h>
24
25 #include "config.h"
26
27 #include "libavutil/avstring.h"
28 #include "libavutil/bprint.h"
29 #include "libavutil/dict.h"
30 #include "libavutil/internal.h"
31 #include "libavutil/mem.h"
32 #include "libavutil/time.h"
33 #include "libavutil/time_internal.h"
34
35 #include "libavcodec/internal.h"
36
37 #include "avformat.h"
38 #include "avio_internal.h"
39 #include "internal.h"
40 #if CONFIG_NETWORK
41 #include "network.h"
42 #endif
43 #include "os_support.h"
44
45 /**
46 * @file
47 * various utility functions for use within FFmpeg
48 */
49
50 /* an arbitrarily chosen "sane" max packet size -- 50M */
51 #define SANE_CHUNK_SIZE (50000000)
52
53 /* Read the data in sane-sized chunks and append to pkt.
54 * Return the number of bytes read or an error. */
55 272542 static int append_packet_chunked(AVIOContext *s, AVPacket *pkt, int size)
56 {
57 272542 int orig_size = pkt->size;
58 int ret;
59
60 do {
61 272542 int prev_size = pkt->size;
62 int read_size;
63
64 /* When the caller requests a lot of data, limit it to the amount
65 * left in file or SANE_CHUNK_SIZE when it is not known. */
66 272542 read_size = size;
67
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 272542 times.
272542 if (read_size > SANE_CHUNK_SIZE/10) {
68 read_size = ffio_limit(s, read_size);
69 // If filesize/maxsize is unknown, limit to SANE_CHUNK_SIZE
70 if (ffiocontext(s)->maxsize < 0)
71 read_size = FFMIN(read_size, SANE_CHUNK_SIZE);
72 }
73
74 272542 ret = av_grow_packet(pkt, read_size);
75
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 272542 times.
272542 if (ret < 0)
76 break;
77
78 272542 ret = avio_read(s, pkt->data + prev_size, read_size);
79
2/2
✓ Branch 0 taken 920 times.
✓ Branch 1 taken 271622 times.
272542 if (ret != read_size) {
80 920 av_shrink_packet(pkt, prev_size + FFMAX(ret, 0));
81 920 break;
82 }
83
84 271622 size -= read_size;
85
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 271622 times.
271622 } while (size > 0);
86
2/2
✓ Branch 0 taken 875 times.
✓ Branch 1 taken 271667 times.
272542 if (size > 0)
87 875 pkt->flags |= AV_PKT_FLAG_CORRUPT;
88
89
2/2
✓ Branch 0 taken 2250 times.
✓ Branch 1 taken 270292 times.
272542 if (!pkt->size)
90 2250 av_packet_unref(pkt);
91
2/2
✓ Branch 0 taken 270287 times.
✓ Branch 1 taken 2255 times.
272542 return pkt->size > orig_size ? pkt->size - orig_size : ret;
92 }
93
94 263112 int av_get_packet(AVIOContext *s, AVPacket *pkt, int size)
95 {
96 #if FF_API_INIT_PACKET
97 FF_DISABLE_DEPRECATION_WARNINGS
98 263112 av_init_packet(pkt);
99 263112 pkt->data = NULL;
100 263112 pkt->size = 0;
101 FF_ENABLE_DEPRECATION_WARNINGS
102 #else
103 av_packet_unref(pkt);
104 #endif
105 263112 pkt->pos = avio_tell(s);
106
107 263112 return append_packet_chunked(s, pkt, size);
108 }
109
110 10020 int av_append_packet(AVIOContext *s, AVPacket *pkt, int size)
111 {
112
2/2
✓ Branch 0 taken 590 times.
✓ Branch 1 taken 9430 times.
10020 if (!pkt->size)
113 590 return av_get_packet(s, pkt, size);
114 9430 return append_packet_chunked(s, pkt, size);
115 }
116
117 996 int av_filename_number_test(const char *filename)
118 {
119 char buf[1024];
120
3/4
✓ Branch 0 taken 996 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 300 times.
✓ Branch 3 taken 696 times.
1992 return filename &&
121 996 (av_get_frame_filename(buf, sizeof(buf), filename, 1) >= 0);
122 }
123
124 /**********************************************************/
125
126 1320 unsigned int ff_codec_get_tag(const AVCodecTag *tags, enum AVCodecID id)
127 {
128
2/2
✓ Branch 0 taken 9771 times.
✓ Branch 1 taken 2 times.
9773 while (tags->id != AV_CODEC_ID_NONE) {
129
2/2
✓ Branch 0 taken 1318 times.
✓ Branch 1 taken 8453 times.
9771 if (tags->id == id)
130 1318 return tags->tag;
131 8453 tags++;
132 }
133 2 return 0;
134 }
135
136 2995 enum AVCodecID ff_codec_get_id(const AVCodecTag *tags, unsigned int tag)
137 {
138
2/2
✓ Branch 0 taken 258807 times.
✓ Branch 1 taken 873 times.
259680 for (int i = 0; tags[i].id != AV_CODEC_ID_NONE; i++)
139
2/2
✓ Branch 0 taken 2122 times.
✓ Branch 1 taken 256685 times.
258807 if (tag == tags[i].tag)
140 2122 return tags[i].id;
141
2/2
✓ Branch 0 taken 77732 times.
✓ Branch 1 taken 868 times.
78600 for (int i = 0; tags[i].id != AV_CODEC_ID_NONE; i++)
142
2/2
✓ Branch 2 taken 5 times.
✓ Branch 3 taken 77727 times.
77732 if (ff_toupper4(tag) == ff_toupper4(tags[i].tag))
143 5 return tags[i].id;
144 868 return AV_CODEC_ID_NONE;
145 }
146
147 551 enum AVCodecID ff_get_pcm_codec_id(int bps, int flt, int be, int sflags)
148 {
149
2/4
✓ Branch 0 taken 551 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 551 times.
551 if (bps <= 0 || bps > 64)
150 return AV_CODEC_ID_NONE;
151
152
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 547 times.
551 if (flt) {
153
2/3
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
4 switch (bps) {
154 2 case 32:
155
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 return be ? AV_CODEC_ID_PCM_F32BE : AV_CODEC_ID_PCM_F32LE;
156 2 case 64:
157
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 return be ? AV_CODEC_ID_PCM_F64BE : AV_CODEC_ID_PCM_F64LE;
158 default:
159 return AV_CODEC_ID_NONE;
160 }
161 } else {
162 547 bps += 7;
163 547 bps >>= 3;
164
2/2
✓ Branch 0 taken 529 times.
✓ Branch 1 taken 18 times.
547 if (sflags & (1 << (bps - 1))) {
165
3/6
✗ Branch 0 not taken.
✓ Branch 1 taken 514 times.
✓ Branch 2 taken 12 times.
✓ Branch 3 taken 3 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
529 switch (bps) {
166 case 1:
167 return AV_CODEC_ID_PCM_S8;
168 514 case 2:
169
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 512 times.
514 return be ? AV_CODEC_ID_PCM_S16BE : AV_CODEC_ID_PCM_S16LE;
170 12 case 3:
171
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 11 times.
12 return be ? AV_CODEC_ID_PCM_S24BE : AV_CODEC_ID_PCM_S24LE;
172 3 case 4:
173
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 return be ? AV_CODEC_ID_PCM_S32BE : AV_CODEC_ID_PCM_S32LE;
174 case 8:
175 return be ? AV_CODEC_ID_PCM_S64BE : AV_CODEC_ID_PCM_S64LE;
176 default:
177 return AV_CODEC_ID_NONE;
178 }
179 } else {
180
1/5
✓ Branch 0 taken 18 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
18 switch (bps) {
181 18 case 1:
182 18 return AV_CODEC_ID_PCM_U8;
183 case 2:
184 return be ? AV_CODEC_ID_PCM_U16BE : AV_CODEC_ID_PCM_U16LE;
185 case 3:
186 return be ? AV_CODEC_ID_PCM_U24BE : AV_CODEC_ID_PCM_U24LE;
187 case 4:
188 return be ? AV_CODEC_ID_PCM_U32BE : AV_CODEC_ID_PCM_U32LE;
189 default:
190 return AV_CODEC_ID_NONE;
191 }
192 }
193 }
194 }
195
196 6089 unsigned int av_codec_get_tag(const AVCodecTag *const *tags, enum AVCodecID id)
197 {
198 unsigned int tag;
199
2/2
✓ Branch 1 taken 13 times.
✓ Branch 2 taken 6076 times.
6089 if (!av_codec_get_tag2(tags, id, &tag))
200 13 return 0;
201 6076 return tag;
202 }
203
204 9391 int av_codec_get_tag2(const AVCodecTag * const *tags, enum AVCodecID id,
205 unsigned int *tag)
206 {
207
3/4
✓ Branch 0 taken 17682 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 17653 times.
✓ Branch 3 taken 29 times.
17682 for (int i = 0; tags && tags[i]; i++) {
208 17653 const AVCodecTag *codec_tags = tags[i];
209
2/2
✓ Branch 0 taken 763359 times.
✓ Branch 1 taken 8291 times.
771650 while (codec_tags->id != AV_CODEC_ID_NONE) {
210
2/2
✓ Branch 0 taken 9362 times.
✓ Branch 1 taken 753997 times.
763359 if (codec_tags->id == id) {
211 9362 *tag = codec_tags->tag;
212 9362 return 1;
213 }
214 753997 codec_tags++;
215 }
216 }
217 29 return 0;
218 }
219
220 187 enum AVCodecID av_codec_get_id(const AVCodecTag *const *tags, unsigned int tag)
221 {
222
3/4
✓ Branch 0 taken 342 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 282 times.
✓ Branch 3 taken 60 times.
342 for (int i = 0; tags && tags[i]; i++) {
223 282 enum AVCodecID id = ff_codec_get_id(tags[i], tag);
224
2/2
✓ Branch 0 taken 127 times.
✓ Branch 1 taken 155 times.
282 if (id != AV_CODEC_ID_NONE)
225 127 return id;
226 }
227 60 return AV_CODEC_ID_NONE;
228 }
229
230 918 int ff_alloc_extradata(AVCodecParameters *par, int size)
231 {
232 918 av_freep(&par->extradata);
233 918 par->extradata_size = 0;
234
235
2/4
✓ Branch 0 taken 918 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 918 times.
918 if (size < 0 || size >= INT32_MAX - AV_INPUT_BUFFER_PADDING_SIZE)
236 return AVERROR(EINVAL);
237
238 918 par->extradata = av_malloc(size + AV_INPUT_BUFFER_PADDING_SIZE);
239
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 918 times.
918 if (!par->extradata)
240 return AVERROR(ENOMEM);
241
242 918 memset(par->extradata + size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
243 918 par->extradata_size = size;
244
245 918 return 0;
246 }
247
248 /*******************************************************/
249
250 37 uint64_t ff_ntp_time(void)
251 {
252 37 return (av_gettime() / 1000) * 1000 + NTP_OFFSET_US;
253 }
254
255 uint64_t ff_get_formatted_ntp_time(uint64_t ntp_time_us)
256 {
257 uint64_t ntp_ts, frac_part, sec;
258 uint32_t usec;
259
260 //current ntp time in seconds and micro seconds
261 sec = ntp_time_us / 1000000;
262 usec = ntp_time_us % 1000000;
263
264 //encoding in ntp timestamp format
265 frac_part = usec * 0xFFFFFFFFULL;
266 frac_part /= 1000000;
267
268 if (sec > 0xFFFFFFFFULL)
269 av_log(NULL, AV_LOG_WARNING, "NTP time format roll over detected\n");
270
271 ntp_ts = sec << 32;
272 ntp_ts |= frac_part;
273
274 return ntp_ts;
275 }
276
277 uint64_t ff_parse_ntp_time(uint64_t ntp_ts)
278 {
279 uint64_t sec = ntp_ts >> 32;
280 uint64_t frac_part = ntp_ts & 0xFFFFFFFFULL;
281 uint64_t usec = (frac_part * 1000000) / 0xFFFFFFFFULL;
282
283 return (sec * 1000000) + usec;
284 }
285
286 152078 int ff_get_frame_filename(char *buf, int buf_size, const char *path, int64_t number, int flags)
287 {
288 const char *p;
289 char *q, buf1[20], c;
290 int nd, len, percentd_found;
291
292 152078 q = buf;
293 152078 p = path;
294 152078 percentd_found = 0;
295 for (;;) {
296 11591681 c = *p++;
297
2/2
✓ Branch 0 taken 152078 times.
✓ Branch 1 taken 11439603 times.
11591681 if (c == '\0')
298 152078 break;
299
2/2
✓ Branch 0 taken 151367 times.
✓ Branch 1 taken 11288236 times.
11439603 if (c == '%') {
300 do {
301 151367 nd = 0;
302
2/2
✓ Branch 0 taken 302622 times.
✓ Branch 1 taken 151367 times.
453989 while (av_isdigit(*p)) {
303
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 302622 times.
302622 if (nd >= INT_MAX / 10 - 255)
304 goto fail;
305 302622 nd = nd * 10 + *p++ - '0';
306 }
307 151367 c = *p++;
308
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 151367 times.
151367 } while (av_isdigit(c));
309
310
1/3
✗ Branch 0 not taken.
✓ Branch 1 taken 151367 times.
✗ Branch 2 not taken.
151367 switch (c) {
311 case '%':
312 goto addchar;
313 151367 case 'd':
314
3/4
✓ Branch 0 taken 150704 times.
✓ Branch 1 taken 663 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 150704 times.
151367 if (!(flags & AV_FRAME_FILENAME_FLAGS_MULTIPLE) && percentd_found)
315 goto fail;
316 151367 percentd_found = 1;
317
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 151367 times.
151367 if (number < 0)
318 nd += 1;
319 151367 snprintf(buf1, sizeof(buf1), "%0*" PRId64, nd, number);
320 151367 len = strlen(buf1);
321
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 151367 times.
151367 if ((q - buf + len) > buf_size - 1)
322 goto fail;
323 151367 memcpy(q, buf1, len);
324 151367 q += len;
325 151367 break;
326 default:
327 goto fail;
328 }
329 } else {
330 11288236 addchar:
331
1/2
✓ Branch 0 taken 11288236 times.
✗ Branch 1 not taken.
11288236 if ((q - buf) < buf_size - 1)
332 11288236 *q++ = c;
333 }
334 }
335
2/2
✓ Branch 0 taken 711 times.
✓ Branch 1 taken 151367 times.
152078 if (!percentd_found)
336 711 goto fail;
337 151367 *q = '\0';
338 151367 return 0;
339 711 fail:
340 711 *q = '\0';
341 711 return -1;
342 }
343
344 int av_get_frame_filename2(char *buf, int buf_size, const char *path, int number, int flags)
345 {
346 return ff_get_frame_filename(buf, buf_size, path, number, flags);
347 }
348
349 151408 int av_get_frame_filename(char *buf, int buf_size, const char *path, int number)
350 {
351 151408 return ff_get_frame_filename(buf, buf_size, path, number, 0);
352 }
353
354 9 void av_url_split(char *proto, int proto_size,
355 char *authorization, int authorization_size,
356 char *hostname, int hostname_size,
357 int *port_ptr, char *path, int path_size, const char *url)
358 {
359 const char *p, *ls, *at, *at2, *col, *brk;
360
361
1/2
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
9 if (port_ptr)
362 9 *port_ptr = -1;
363
1/2
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
9 if (proto_size > 0)
364 9 proto[0] = 0;
365
1/2
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
9 if (authorization_size > 0)
366 9 authorization[0] = 0;
367
1/2
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
9 if (hostname_size > 0)
368 9 hostname[0] = 0;
369
1/2
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
9 if (path_size > 0)
370 9 path[0] = 0;
371
372 /* parse protocol */
373
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 1 times.
9 if ((p = strchr(url, ':'))) {
374 8 av_strlcpy(proto, url, FFMIN(proto_size, p + 1 - url));
375 8 p++; /* skip ':' */
376
1/2
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
8 if (*p == '/')
377 8 p++;
378
1/2
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
8 if (*p == '/')
379 8 p++;
380 } else {
381 /* no protocol means plain filename */
382 1 av_strlcpy(path, url, path_size);
383 1 return;
384 }
385
386 /* separate path from hostname */
387 8 ls = p + strcspn(p, "/?#");
388 8 av_strlcpy(path, ls, path_size);
389
390 /* the rest is hostname, use that to parse auth/port */
391
1/2
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
8 if (ls != p) {
392 /* authorization (user[:pass]@hostname) */
393 8 at2 = p;
394
4/4
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 7 times.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 1 times.
10 while ((at = strchr(p, '@')) && at < ls) {
395 2 av_strlcpy(authorization, at2,
396 2 FFMIN(authorization_size, at + 1 - at2));
397 2 p = at + 1; /* skip '@' */
398 }
399
400
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
8 if (*p == '[' && (brk = strchr(p, ']')) && brk < ls) {
401 /* [host]:port */
402 av_strlcpy(hostname, p + 1,
403 FFMIN(hostname_size, brk - p));
404 if (brk[1] == ':' && port_ptr)
405 *port_ptr = atoi(brk + 2);
406
3/4
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 7 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
8 } else if ((col = strchr(p, ':')) && col < ls) {
407 1 av_strlcpy(hostname, p,
408 1 FFMIN(col + 1 - p, hostname_size));
409
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (port_ptr)
410 1 *port_ptr = atoi(col + 1);
411 } else
412 7 av_strlcpy(hostname, p,
413 7 FFMIN(ls + 1 - p, hostname_size));
414 }
415 }
416
417 int ff_mkdir_p(const char *path)
418 {
419 int ret = 0;
420 char *temp = av_strdup(path);
421 char *pos = temp;
422 char tmp_ch = '\0';
423
424 if (!path || !temp) {
425 return -1;
426 }
427
428 if (!av_strncasecmp(temp, "/", 1) || !av_strncasecmp(temp, "\\", 1)) {
429 pos++;
430 } else if (!av_strncasecmp(temp, "./", 2) || !av_strncasecmp(temp, ".\\", 2)) {
431 pos += 2;
432 }
433
434 for ( ; *pos != '\0'; ++pos) {
435 if (*pos == '/' || *pos == '\\') {
436 tmp_ch = *pos;
437 *pos = '\0';
438 ret = mkdir(temp, 0755);
439 *pos = tmp_ch;
440 }
441 }
442
443 if ((*(pos - 1) != '/') && (*(pos - 1) != '\\')) {
444 ret = mkdir(temp, 0755);
445 }
446
447 av_free(temp);
448 return ret;
449 }
450
451 3405 char *ff_data_to_hex(char *buff, const uint8_t *src, int s, int lowercase)
452 {
453 static const char hex_table_uc[16] = { '0', '1', '2', '3',
454 '4', '5', '6', '7',
455 '8', '9', 'A', 'B',
456 'C', 'D', 'E', 'F' };
457 static const char hex_table_lc[16] = { '0', '1', '2', '3',
458 '4', '5', '6', '7',
459 '8', '9', 'a', 'b',
460 'c', 'd', 'e', 'f' };
461
2/2
✓ Branch 0 taken 2708 times.
✓ Branch 1 taken 697 times.
3405 const char *hex_table = lowercase ? hex_table_lc : hex_table_uc;
462
463
2/2
✓ Branch 0 taken 54494 times.
✓ Branch 1 taken 3405 times.
57899 for (int i = 0; i < s; i++) {
464 54494 buff[i * 2] = hex_table[src[i] >> 4];
465 54494 buff[i * 2 + 1] = hex_table[src[i] & 0xF];
466 }
467 3405 buff[2 * s] = '\0';
468
469 3405 return buff;
470 }
471
472 int ff_hex_to_data(uint8_t *data, const char *p)
473 {
474 int c, len, v;
475
476 len = 0;
477 v = 1;
478 for (;;) {
479 p += strspn(p, SPACE_CHARS);
480 if (*p == '\0')
481 break;
482 c = av_toupper((unsigned char) *p++);
483 if (c >= '0' && c <= '9')
484 c = c - '0';
485 else if (c >= 'A' && c <= 'F')
486 c = c - 'A' + 10;
487 else
488 break;
489 v = (v << 4) | c;
490 if (v & 0x100) {
491 if (data)
492 data[len] = v;
493 len++;
494 v = 1;
495 }
496 }
497 return len;
498 }
499
500 void ff_parse_key_value(const char *str, ff_parse_key_val_cb callback_get_buf,
501 void *context)
502 {
503 const char *ptr = str;
504
505 /* Parse key=value pairs. */
506 for (;;) {
507 const char *key;
508 char *dest = NULL, *dest_end;
509 int key_len, dest_len = 0;
510
511 /* Skip whitespace and potential commas. */
512 while (*ptr && (av_isspace(*ptr) || *ptr == ','))
513 ptr++;
514 if (!*ptr)
515 break;
516
517 key = ptr;
518
519 if (!(ptr = strchr(key, '=')))
520 break;
521 ptr++;
522 key_len = ptr - key;
523
524 callback_get_buf(context, key, key_len, &dest, &dest_len);
525 dest_end = dest ? dest + dest_len - 1 : NULL;
526
527 if (*ptr == '\"') {
528 ptr++;
529 while (*ptr && *ptr != '\"') {
530 if (*ptr == '\\') {
531 if (!ptr[1])
532 break;
533 if (dest && dest < dest_end)
534 *dest++ = ptr[1];
535 ptr += 2;
536 } else {
537 if (dest && dest < dest_end)
538 *dest++ = *ptr;
539 ptr++;
540 }
541 }
542 if (*ptr == '\"')
543 ptr++;
544 } else {
545 for (; *ptr && !(av_isspace(*ptr) || *ptr == ','); ptr++)
546 if (dest && dest < dest_end)
547 *dest++ = *ptr;
548 }
549 if (dest)
550 *dest = 0;
551 }
552 }
553
554 8394 int avformat_network_init(void)
555 {
556 #if CONFIG_NETWORK
557 int ret;
558
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 8394 times.
8394 if ((ret = ff_network_init()) < 0)
559 return ret;
560
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 8394 times.
8394 if ((ret = ff_tls_init()) < 0)
561 return ret;
562 #endif
563 8394 return 0;
564 }
565
566 8394 int avformat_network_deinit(void)
567 {
568 #if CONFIG_NETWORK
569 8394 ff_network_close();
570 8394 ff_tls_deinit();
571 #endif
572 8394 return 0;
573 }
574
575 366 int ff_is_http_proto(const char *filename) {
576 366 const char *proto = avio_find_protocol_name(filename);
577
3/6
✓ Branch 0 taken 366 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 366 times.
✗ Branch 4 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 366 times.
366 return proto ? (!av_strcasecmp(proto, "http") || !av_strcasecmp(proto, "https")) : 0;
578 }
579
580 9 int ff_bprint_to_codecpar_extradata(AVCodecParameters *par, struct AVBPrint *buf)
581 {
582 int ret;
583 char *str;
584
585 9 ret = av_bprint_finalize(buf, &str);
586
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9 times.
9 if (ret < 0)
587 return ret;
588
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 9 times.
9 if (!av_bprint_is_complete(buf)) {
589 av_free(str);
590 return AVERROR(ENOMEM);
591 }
592
593 9 par->extradata = str;
594 /* Note: the string is NUL terminated (so extradata can be read as a
595 * string), but the ending character is not accounted in the size (in
596 * binary formats you are likely not supposed to mux that character). When
597 * extradata is copied, it is also padded with AV_INPUT_BUFFER_PADDING_SIZE
598 * zeros. */
599 9 par->extradata_size = buf->len;
600 9 return 0;
601 }
602
603 564 int ff_dict_set_timestamp(AVDictionary **dict, const char *key, int64_t timestamp)
604 {
605 564 time_t seconds = timestamp / 1000000;
606 struct tm *ptm, tmbuf;
607 564 ptm = gmtime_r(&seconds, &tmbuf);
608
1/2
✓ Branch 0 taken 564 times.
✗ Branch 1 not taken.
564 if (ptm) {
609 char buf[32];
610
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 564 times.
564 if (!strftime(buf, sizeof(buf), "%Y-%m-%dT%H:%M:%S", ptm))
611 return AVERROR_EXTERNAL;
612 564 av_strlcatf(buf, sizeof(buf), ".%06dZ", (int)(timestamp % 1000000));
613 564 return av_dict_set(dict, key, buf, 0);
614 } else {
615 return AVERROR_EXTERNAL;
616 }
617 }
618