FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavformat/utils.c
Date: 2025-09-17 22:08:16
Exec Total Coverage
Lines: 219 333 65.8%
Functions: 21 28 75.0%
Branches: 129 263 49.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 273237 static int append_packet_chunked(AVIOContext *s, AVPacket *pkt, int size)
56 {
57 273237 int orig_size = pkt->size;
58 int ret;
59
60 do {
61 273237 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 273237 read_size = size;
67
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 273237 times.
273237 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 273237 ret = av_grow_packet(pkt, read_size);
75
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 273237 times.
273237 if (ret < 0)
76 break;
77
78 273237 ret = avio_read(s, pkt->data + prev_size, read_size);
79
2/2
✓ Branch 0 taken 928 times.
✓ Branch 1 taken 272309 times.
273237 if (ret != read_size) {
80 928 av_shrink_packet(pkt, prev_size + FFMAX(ret, 0));
81 928 break;
82 }
83
84 272309 size -= read_size;
85
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 272309 times.
272309 } while (size > 0);
86
2/2
✓ Branch 0 taken 883 times.
✓ Branch 1 taken 272354 times.
273237 if (size > 0)
87 883 pkt->flags |= AV_PKT_FLAG_CORRUPT;
88
89
2/2
✓ Branch 0 taken 2255 times.
✓ Branch 1 taken 270982 times.
273237 if (!pkt->size)
90 2255 av_packet_unref(pkt);
91
2/2
✓ Branch 0 taken 270977 times.
✓ Branch 1 taken 2260 times.
273237 return pkt->size > orig_size ? pkt->size - orig_size : ret;
92 }
93
94 263807 int av_get_packet(AVIOContext *s, AVPacket *pkt, int size)
95 {
96 #if FF_API_INIT_PACKET
97 FF_DISABLE_DEPRECATION_WARNINGS
98 263807 av_init_packet(pkt);
99 263807 pkt->data = NULL;
100 263807 pkt->size = 0;
101 FF_ENABLE_DEPRECATION_WARNINGS
102 #else
103 av_packet_unref(pkt);
104 #endif
105 263807 pkt->pos = avio_tell(s);
106
107 263807 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 1001 int av_filename_number_test(const char *filename)
118 {
119 AVBPrint bp;
120
121
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1001 times.
1001 if (!filename)
122 return 0;
123 1001 av_bprint_init(&bp, 0, AV_BPRINT_SIZE_COUNT_ONLY);
124 1001 return (ff_bprint_get_frame_filename(&bp, filename, 1, AV_FRAME_FILENAME_FLAGS_IGNORE_TRUNCATION) >= 0);
125 }
126
127 /**********************************************************/
128
129 1326 unsigned int ff_codec_get_tag(const AVCodecTag *tags, enum AVCodecID id)
130 {
131
2/2
✓ Branch 0 taken 9923 times.
✓ Branch 1 taken 2 times.
9925 while (tags->id != AV_CODEC_ID_NONE) {
132
2/2
✓ Branch 0 taken 1324 times.
✓ Branch 1 taken 8599 times.
9923 if (tags->id == id)
133 1324 return tags->tag;
134 8599 tags++;
135 }
136 2 return 0;
137 }
138
139 3089 enum AVCodecID ff_codec_get_id(const AVCodecTag *tags, unsigned int tag)
140 {
141
2/2
✓ Branch 0 taken 269601 times.
✓ Branch 1 taken 922 times.
270523 for (int i = 0; tags[i].id != AV_CODEC_ID_NONE; i++)
142
2/2
✓ Branch 0 taken 2167 times.
✓ Branch 1 taken 267434 times.
269601 if (tag == tags[i].tag)
143 2167 return tags[i].id;
144
2/2
✓ Branch 0 taken 83448 times.
✓ Branch 1 taken 917 times.
84365 for (int i = 0; tags[i].id != AV_CODEC_ID_NONE; i++)
145
2/2
✓ Branch 2 taken 5 times.
✓ Branch 3 taken 83443 times.
83448 if (ff_toupper4(tag) == ff_toupper4(tags[i].tag))
146 5 return tags[i].id;
147 917 return AV_CODEC_ID_NONE;
148 }
149
150 556 enum AVCodecID ff_get_pcm_codec_id(int bps, int flt, int be, int sflags)
151 {
152
2/4
✓ Branch 0 taken 556 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 556 times.
556 if (bps <= 0 || bps > 64)
153 return AV_CODEC_ID_NONE;
154
155
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 552 times.
556 if (flt) {
156
2/3
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
4 switch (bps) {
157 2 case 32:
158
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 return be ? AV_CODEC_ID_PCM_F32BE : AV_CODEC_ID_PCM_F32LE;
159 2 case 64:
160
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 return be ? AV_CODEC_ID_PCM_F64BE : AV_CODEC_ID_PCM_F64LE;
161 default:
162 return AV_CODEC_ID_NONE;
163 }
164 } else {
165 552 bps += 7;
166 552 bps >>= 3;
167
2/2
✓ Branch 0 taken 534 times.
✓ Branch 1 taken 18 times.
552 if (sflags & (1 << (bps - 1))) {
168
3/6
✗ Branch 0 not taken.
✓ Branch 1 taken 519 times.
✓ Branch 2 taken 12 times.
✓ Branch 3 taken 3 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
534 switch (bps) {
169 case 1:
170 return AV_CODEC_ID_PCM_S8;
171 519 case 2:
172
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 517 times.
519 return be ? AV_CODEC_ID_PCM_S16BE : AV_CODEC_ID_PCM_S16LE;
173 12 case 3:
174
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;
175 3 case 4:
176
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 return be ? AV_CODEC_ID_PCM_S32BE : AV_CODEC_ID_PCM_S32LE;
177 case 8:
178 return be ? AV_CODEC_ID_PCM_S64BE : AV_CODEC_ID_PCM_S64LE;
179 default:
180 return AV_CODEC_ID_NONE;
181 }
182 } else {
183
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) {
184 18 case 1:
185 18 return AV_CODEC_ID_PCM_U8;
186 case 2:
187 return be ? AV_CODEC_ID_PCM_U16BE : AV_CODEC_ID_PCM_U16LE;
188 case 3:
189 return be ? AV_CODEC_ID_PCM_U24BE : AV_CODEC_ID_PCM_U24LE;
190 case 4:
191 return be ? AV_CODEC_ID_PCM_U32BE : AV_CODEC_ID_PCM_U32LE;
192 default:
193 return AV_CODEC_ID_NONE;
194 }
195 }
196 }
197 }
198
199 6181 unsigned int av_codec_get_tag(const AVCodecTag *const *tags, enum AVCodecID id)
200 {
201 unsigned int tag;
202
2/2
✓ Branch 1 taken 13 times.
✓ Branch 2 taken 6168 times.
6181 if (!av_codec_get_tag2(tags, id, &tag))
203 13 return 0;
204 6168 return tag;
205 }
206
207 9582 int av_codec_get_tag2(const AVCodecTag * const *tags, enum AVCodecID id,
208 unsigned int *tag)
209 {
210
3/4
✓ Branch 0 taken 18160 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 18129 times.
✓ Branch 3 taken 31 times.
18160 for (int i = 0; tags && tags[i]; i++) {
211 18129 const AVCodecTag *codec_tags = tags[i];
212
2/2
✓ Branch 0 taken 785933 times.
✓ Branch 1 taken 8578 times.
794511 while (codec_tags->id != AV_CODEC_ID_NONE) {
213
2/2
✓ Branch 0 taken 9551 times.
✓ Branch 1 taken 776382 times.
785933 if (codec_tags->id == id) {
214 9551 *tag = codec_tags->tag;
215 9551 return 1;
216 }
217 776382 codec_tags++;
218 }
219 }
220 31 return 0;
221 }
222
223 193 enum AVCodecID av_codec_get_id(const AVCodecTag *const *tags, unsigned int tag)
224 {
225
3/4
✓ Branch 0 taken 357 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 294 times.
✓ Branch 3 taken 63 times.
357 for (int i = 0; tags && tags[i]; i++) {
226 294 enum AVCodecID id = ff_codec_get_id(tags[i], tag);
227
2/2
✓ Branch 0 taken 130 times.
✓ Branch 1 taken 164 times.
294 if (id != AV_CODEC_ID_NONE)
228 130 return id;
229 }
230 63 return AV_CODEC_ID_NONE;
231 }
232
233 949 int ff_alloc_extradata(AVCodecParameters *par, int size)
234 {
235 949 av_freep(&par->extradata);
236 949 par->extradata_size = 0;
237
238
2/4
✓ Branch 0 taken 949 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 949 times.
949 if (size < 0 || size >= INT32_MAX - AV_INPUT_BUFFER_PADDING_SIZE)
239 return AVERROR(EINVAL);
240
241 949 par->extradata = av_malloc(size + AV_INPUT_BUFFER_PADDING_SIZE);
242
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 949 times.
949 if (!par->extradata)
243 return AVERROR(ENOMEM);
244
245 949 memset(par->extradata + size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
246 949 par->extradata_size = size;
247
248 949 return 0;
249 }
250
251 /*******************************************************/
252
253 37 uint64_t ff_ntp_time(void)
254 {
255 37 return (av_gettime() / 1000) * 1000 + NTP_OFFSET_US;
256 }
257
258 uint64_t ff_get_formatted_ntp_time(uint64_t ntp_time_us)
259 {
260 uint64_t ntp_ts, frac_part, sec;
261 uint32_t usec;
262
263 //current ntp time in seconds and micro seconds
264 sec = ntp_time_us / 1000000;
265 usec = ntp_time_us % 1000000;
266
267 //encoding in ntp timestamp format
268 frac_part = usec * 0xFFFFFFFFULL;
269 frac_part /= 1000000;
270
271 if (sec > 0xFFFFFFFFULL)
272 av_log(NULL, AV_LOG_WARNING, "NTP time format roll over detected\n");
273
274 ntp_ts = sec << 32;
275 ntp_ts |= frac_part;
276
277 return ntp_ts;
278 }
279
280 uint64_t ff_parse_ntp_time(uint64_t ntp_ts)
281 {
282 uint64_t sec = ntp_ts >> 32;
283 uint64_t frac_part = ntp_ts & 0xFFFFFFFFULL;
284 uint64_t usec = (frac_part * 1000000) / 0xFFFFFFFFULL;
285
286 return (sec * 1000000) + usec;
287 }
288
289 156768 int ff_bprint_get_frame_filename(struct AVBPrint *buf, const char *path, int64_t number, int flags)
290 {
291 const char *p;
292 char c;
293 int nd, percentd_found;
294
295 156768 p = path;
296 156768 percentd_found = 0;
297 for (;;) {
298 11948431 c = *p++;
299
2/2
✓ Branch 0 taken 156768 times.
✓ Branch 1 taken 11791663 times.
11948431 if (c == '\0')
300 156768 break;
301
2/2
✓ Branch 0 taken 156053 times.
✓ Branch 1 taken 11635610 times.
11791663 if (c == '%') {
302 do {
303 156053 nd = 0;
304
2/2
✓ Branch 0 taken 311994 times.
✓ Branch 1 taken 156053 times.
468047 while (av_isdigit(*p)) {
305
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 311994 times.
311994 if (nd >= INT_MAX / 10 - 255)
306 goto fail;
307 311994 nd = nd * 10 + *p++ - '0';
308 }
309 156053 c = *p++;
310
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 156053 times.
156053 } while (av_isdigit(c));
311
312
1/3
✗ Branch 0 not taken.
✓ Branch 1 taken 156053 times.
✗ Branch 2 not taken.
156053 switch (c) {
313 case '%':
314 goto addchar;
315 156053 case 'd':
316
3/4
✓ Branch 0 taken 155390 times.
✓ Branch 1 taken 663 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 155390 times.
156053 if (!(flags & AV_FRAME_FILENAME_FLAGS_MULTIPLE) && percentd_found)
317 goto fail;
318 156053 percentd_found = 1;
319
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 156053 times.
156053 if (number < 0)
320 nd += 1;
321 156053 av_bprintf(buf, "%0*" PRId64, nd, number);
322 156053 break;
323 default:
324 goto fail;
325 }
326 } else {
327 11635610 addchar:
328 11635610 av_bprint_chars(buf, c, 1);
329 }
330 }
331
2/2
✓ Branch 0 taken 715 times.
✓ Branch 1 taken 156053 times.
156768 if (!percentd_found)
332 715 goto fail;
333
3/4
✓ Branch 0 taken 155753 times.
✓ Branch 1 taken 300 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 155753 times.
156053 if (!(flags & AV_FRAME_FILENAME_FLAGS_IGNORE_TRUNCATION) && !av_bprint_is_complete(buf))
334 return AVERROR(ENOMEM);
335 156053 return 0;
336 715 fail:
337 715 return AVERROR(EINVAL);
338 }
339
340 static int get_frame_filename(char *buf, int buf_size, const char *path, int64_t number, int flags)
341 {
342 AVBPrint bp;
343 av_bprint_init_for_buffer(&bp, buf, buf_size);
344 return ff_bprint_get_frame_filename(&bp, path, number, flags) < 0 ? -1 : 0;
345 }
346
347 int av_get_frame_filename2(char *buf, int buf_size, const char *path, int number, int flags)
348 {
349 return get_frame_filename(buf, buf_size, path, number, flags);
350 }
351
352 int av_get_frame_filename(char *buf, int buf_size, const char *path, int number)
353 {
354 return get_frame_filename(buf, buf_size, path, number, 0);
355 }
356
357 9 void av_url_split(char *proto, int proto_size,
358 char *authorization, int authorization_size,
359 char *hostname, int hostname_size,
360 int *port_ptr, char *path, int path_size, const char *url)
361 {
362 const char *p, *ls, *at, *at2, *col, *brk;
363
364
1/2
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
9 if (port_ptr)
365 9 *port_ptr = -1;
366
1/2
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
9 if (proto_size > 0)
367 9 proto[0] = 0;
368
1/2
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
9 if (authorization_size > 0)
369 9 authorization[0] = 0;
370
1/2
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
9 if (hostname_size > 0)
371 9 hostname[0] = 0;
372
1/2
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
9 if (path_size > 0)
373 9 path[0] = 0;
374
375 /* parse protocol */
376
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 1 times.
9 if ((p = strchr(url, ':'))) {
377 8 av_strlcpy(proto, url, FFMIN(proto_size, p + 1 - url));
378 8 p++; /* skip ':' */
379
1/2
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
8 if (*p == '/')
380 8 p++;
381
1/2
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
8 if (*p == '/')
382 8 p++;
383 } else {
384 /* no protocol means plain filename */
385 1 av_strlcpy(path, url, path_size);
386 1 return;
387 }
388
389 /* separate path from hostname */
390 8 ls = p + strcspn(p, "/?#");
391 8 av_strlcpy(path, ls, path_size);
392
393 /* the rest is hostname, use that to parse auth/port */
394
1/2
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
8 if (ls != p) {
395 /* authorization (user[:pass]@hostname) */
396 8 at2 = p;
397
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) {
398 2 av_strlcpy(authorization, at2,
399 2 FFMIN(authorization_size, at + 1 - at2));
400 2 p = at + 1; /* skip '@' */
401 }
402
403
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) {
404 /* [host]:port */
405 av_strlcpy(hostname, p + 1,
406 FFMIN(hostname_size, brk - p));
407 if (brk[1] == ':' && port_ptr)
408 *port_ptr = atoi(brk + 2);
409
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) {
410 1 av_strlcpy(hostname, p,
411 1 FFMIN(col + 1 - p, hostname_size));
412
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (port_ptr)
413 1 *port_ptr = atoi(col + 1);
414 } else
415 7 av_strlcpy(hostname, p,
416 7 FFMIN(ls + 1 - p, hostname_size));
417 }
418 }
419
420 int ff_mkdir_p(const char *path)
421 {
422 int ret = 0;
423 char *temp = av_strdup(path);
424 char *pos = temp;
425 char tmp_ch = '\0';
426
427 if (!path || !temp) {
428 return -1;
429 }
430
431 if (!av_strncasecmp(temp, "/", 1) || !av_strncasecmp(temp, "\\", 1)) {
432 pos++;
433 } else if (!av_strncasecmp(temp, "./", 2) || !av_strncasecmp(temp, ".\\", 2)) {
434 pos += 2;
435 }
436
437 for ( ; *pos != '\0'; ++pos) {
438 if (*pos == '/' || *pos == '\\') {
439 tmp_ch = *pos;
440 *pos = '\0';
441 ret = mkdir(temp, 0755);
442 *pos = tmp_ch;
443 }
444 }
445
446 if ((*(pos - 1) != '/') && (*(pos - 1) != '\\')) {
447 ret = mkdir(temp, 0755);
448 }
449
450 av_free(temp);
451 return ret;
452 }
453
454 3498 char *ff_data_to_hex(char *buff, const uint8_t *src, int s, int lowercase)
455 {
456 static const char hex_table_uc[16] = { '0', '1', '2', '3',
457 '4', '5', '6', '7',
458 '8', '9', 'A', 'B',
459 'C', 'D', 'E', 'F' };
460 static const char hex_table_lc[16] = { '0', '1', '2', '3',
461 '4', '5', '6', '7',
462 '8', '9', 'a', 'b',
463 'c', 'd', 'e', 'f' };
464
2/2
✓ Branch 0 taken 2801 times.
✓ Branch 1 taken 697 times.
3498 const char *hex_table = lowercase ? hex_table_lc : hex_table_uc;
465
466
2/2
✓ Branch 0 taken 55982 times.
✓ Branch 1 taken 3498 times.
59480 for (int i = 0; i < s; i++) {
467 55982 buff[i * 2] = hex_table[src[i] >> 4];
468 55982 buff[i * 2 + 1] = hex_table[src[i] & 0xF];
469 }
470 3498 buff[2 * s] = '\0';
471
472 3498 return buff;
473 }
474
475 int ff_hex_to_data(uint8_t *data, const char *p)
476 {
477 int c, len, v;
478
479 len = 0;
480 v = 1;
481 for (;;) {
482 p += strspn(p, SPACE_CHARS);
483 if (*p == '\0')
484 break;
485 c = av_toupper((unsigned char) *p++);
486 if (c >= '0' && c <= '9')
487 c = c - '0';
488 else if (c >= 'A' && c <= 'F')
489 c = c - 'A' + 10;
490 else
491 break;
492 v = (v << 4) | c;
493 if (v & 0x100) {
494 if (data)
495 data[len] = v;
496 len++;
497 v = 1;
498 }
499 }
500 return len;
501 }
502
503 1 void ff_parse_key_value(const char *str, ff_parse_key_val_cb callback_get_buf,
504 void *context)
505 {
506 1 const char *ptr = str;
507
508 /* Parse key=value pairs. */
509 1 for (;;) {
510 const char *key;
511 2 char *dest = NULL, *dest_end;
512 2 int key_len, dest_len = 0;
513
514 /* Skip whitespace and potential commas. */
515
4/6
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
2 while (*ptr && (av_isspace(*ptr) || *ptr == ','))
516 ptr++;
517
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 if (!*ptr)
518 1 break;
519
520 1 key = ptr;
521
522
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (!(ptr = strchr(key, '=')))
523 break;
524 1 ptr++;
525 1 key_len = ptr - key;
526
527 1 callback_get_buf(context, key, key_len, &dest, &dest_len);
528
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 dest_end = dest ? dest + dest_len - 1 : NULL;
529
530
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (*ptr == '\"') {
531 1 ptr++;
532
3/4
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
✓ Branch 3 taken 1 times.
9 while (*ptr && *ptr != '\"') {
533
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 if (*ptr == '\\') {
534 if (!ptr[1])
535 break;
536 if (dest && dest < dest_end)
537 *dest++ = ptr[1];
538 ptr += 2;
539 } else {
540
2/4
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
✗ Branch 3 not taken.
8 if (dest && dest < dest_end)
541 8 *dest++ = *ptr;
542 8 ptr++;
543 }
544 }
545
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (*ptr == '\"')
546 1 ptr++;
547 } else {
548 for (; *ptr && !(av_isspace(*ptr) || *ptr == ','); ptr++)
549 if (dest && dest < dest_end)
550 *dest++ = *ptr;
551 }
552
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (dest)
553 1 *dest = 0;
554 }
555 1 }
556
557 8569 int avformat_network_init(void)
558 {
559 #if CONFIG_NETWORK
560 int ret;
561
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 8569 times.
8569 if ((ret = ff_network_init()) < 0)
562 return ret;
563
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 8569 times.
8569 if ((ret = ff_tls_init()) < 0)
564 return ret;
565 #endif
566 8569 return 0;
567 }
568
569 8569 int avformat_network_deinit(void)
570 {
571 #if CONFIG_NETWORK
572 8569 ff_network_close();
573 8569 ff_tls_deinit();
574 #endif
575 8569 return 0;
576 }
577
578 376 int ff_is_http_proto(const char *filename) {
579 376 const char *proto = avio_find_protocol_name(filename);
580
3/6
✓ Branch 0 taken 376 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 376 times.
✗ Branch 4 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 376 times.
376 return proto ? (!av_strcasecmp(proto, "http") || !av_strcasecmp(proto, "https")) : 0;
581 }
582
583 9 int ff_bprint_to_codecpar_extradata(AVCodecParameters *par, struct AVBPrint *buf)
584 {
585 int ret;
586 char *str;
587
588 9 ret = av_bprint_finalize(buf, &str);
589
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9 times.
9 if (ret < 0)
590 return ret;
591
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 9 times.
9 if (!av_bprint_is_complete(buf)) {
592 av_free(str);
593 return AVERROR(ENOMEM);
594 }
595
596 9 par->extradata = str;
597 /* Note: the string is NUL terminated (so extradata can be read as a
598 * string), but the ending character is not accounted in the size (in
599 * binary formats you are likely not supposed to mux that character). When
600 * extradata is copied, it is also padded with AV_INPUT_BUFFER_PADDING_SIZE
601 * zeros. */
602 9 par->extradata_size = buf->len;
603 9 return 0;
604 }
605
606 572 int ff_dict_set_timestamp(AVDictionary **dict, const char *key, int64_t timestamp)
607 {
608 572 time_t seconds = timestamp / 1000000;
609 struct tm *ptm, tmbuf;
610 572 ptm = gmtime_r(&seconds, &tmbuf);
611
1/2
✓ Branch 0 taken 572 times.
✗ Branch 1 not taken.
572 if (ptm) {
612 char buf[32];
613
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 572 times.
572 if (!strftime(buf, sizeof(buf), "%Y-%m-%dT%H:%M:%S", ptm))
614 return AVERROR_EXTERNAL;
615 572 av_strlcatf(buf, sizeof(buf), ".%06dZ", (int)(timestamp % 1000000));
616 572 return av_dict_set(dict, key, buf, 0);
617 } else {
618 return AVERROR_EXTERNAL;
619 }
620 }
621