| 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/avassert.h" | ||
| 28 | #include "libavutil/avstring.h" | ||
| 29 | #include "libavutil/bprint.h" | ||
| 30 | #include "libavutil/dict.h" | ||
| 31 | #include "libavutil/internal.h" | ||
| 32 | #include "libavutil/mem.h" | ||
| 33 | #include "libavutil/opt.h" | ||
| 34 | #include "libavutil/parseutils.h" | ||
| 35 | #include "libavutil/time.h" | ||
| 36 | #include "libavutil/time_internal.h" | ||
| 37 | |||
| 38 | #include "libavcodec/internal.h" | ||
| 39 | |||
| 40 | #include "avformat.h" | ||
| 41 | #include "avio_internal.h" | ||
| 42 | #include "internal.h" | ||
| 43 | #if CONFIG_NETWORK | ||
| 44 | #include "network.h" | ||
| 45 | #endif | ||
| 46 | #include "os_support.h" | ||
| 47 | #include "urldecode.h" | ||
| 48 | |||
| 49 | /** | ||
| 50 | * @file | ||
| 51 | * various utility functions for use within FFmpeg | ||
| 52 | */ | ||
| 53 | |||
| 54 | /* an arbitrarily chosen "sane" max packet size -- 50M */ | ||
| 55 | #define SANE_CHUNK_SIZE (50000000) | ||
| 56 | |||
| 57 | /* Read the data in sane-sized chunks and append to pkt. | ||
| 58 | * Return the number of bytes read or an error. */ | ||
| 59 | 285804 | static int append_packet_chunked(AVIOContext *s, AVPacket *pkt, int size) | |
| 60 | { | ||
| 61 | 285804 | int orig_size = pkt->size; | |
| 62 | int ret; | ||
| 63 | |||
| 64 | do { | ||
| 65 | 285804 | int prev_size = pkt->size; | |
| 66 | int read_size; | ||
| 67 | |||
| 68 | /* When the caller requests a lot of data, limit it to the amount | ||
| 69 | * left in file or SANE_CHUNK_SIZE when it is not known. */ | ||
| 70 | 285804 | read_size = size; | |
| 71 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 285804 times.
|
285804 | if (read_size > SANE_CHUNK_SIZE/10) { |
| 72 | ✗ | read_size = ffio_limit(s, read_size); | |
| 73 | // If filesize/maxsize is unknown, limit to SANE_CHUNK_SIZE | ||
| 74 | ✗ | if (ffiocontext(s)->maxsize < 0) | |
| 75 | ✗ | read_size = FFMIN(read_size, SANE_CHUNK_SIZE); | |
| 76 | } | ||
| 77 | |||
| 78 | 285804 | ret = av_grow_packet(pkt, read_size); | |
| 79 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 285804 times.
|
285804 | if (ret < 0) |
| 80 | ✗ | break; | |
| 81 | |||
| 82 | 285804 | ret = avio_read(s, pkt->data + prev_size, read_size); | |
| 83 |
2/2✓ Branch 0 taken 978 times.
✓ Branch 1 taken 284826 times.
|
285804 | if (ret != read_size) { |
| 84 | 978 | av_shrink_packet(pkt, prev_size + FFMAX(ret, 0)); | |
| 85 | 978 | break; | |
| 86 | } | ||
| 87 | |||
| 88 | 284826 | size -= read_size; | |
| 89 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 284826 times.
|
284826 | } while (size > 0); |
| 90 |
2/2✓ Branch 0 taken 933 times.
✓ Branch 1 taken 284871 times.
|
285804 | if (size > 0) |
| 91 | 933 | pkt->flags |= AV_PKT_FLAG_CORRUPT; | |
| 92 | |||
| 93 |
2/2✓ Branch 0 taken 2298 times.
✓ Branch 1 taken 283506 times.
|
285804 | if (!pkt->size) |
| 94 | 2298 | av_packet_unref(pkt); | |
| 95 |
2/2✓ Branch 0 taken 283501 times.
✓ Branch 1 taken 2303 times.
|
285804 | return pkt->size > orig_size ? pkt->size - orig_size : ret; |
| 96 | } | ||
| 97 | |||
| 98 | 278786 | int av_get_packet(AVIOContext *s, AVPacket *pkt, int size) | |
| 99 | { | ||
| 100 | #if FF_API_INIT_PACKET | ||
| 101 | FF_DISABLE_DEPRECATION_WARNINGS | ||
| 102 | 278786 | av_init_packet(pkt); | |
| 103 | 278786 | pkt->data = NULL; | |
| 104 | 278786 | pkt->size = 0; | |
| 105 | FF_ENABLE_DEPRECATION_WARNINGS | ||
| 106 | #else | ||
| 107 | av_packet_unref(pkt); | ||
| 108 | #endif | ||
| 109 | 278786 | pkt->pos = avio_tell(s); | |
| 110 | |||
| 111 | 278786 | return append_packet_chunked(s, pkt, size); | |
| 112 | } | ||
| 113 | |||
| 114 | 7608 | int av_append_packet(AVIOContext *s, AVPacket *pkt, int size) | |
| 115 | { | ||
| 116 |
2/2✓ Branch 0 taken 590 times.
✓ Branch 1 taken 7018 times.
|
7608 | if (!pkt->size) |
| 117 | 590 | return av_get_packet(s, pkt, size); | |
| 118 | 7018 | return append_packet_chunked(s, pkt, size); | |
| 119 | } | ||
| 120 | |||
| 121 | 1047 | int av_filename_number_test(const char *filename) | |
| 122 | { | ||
| 123 | AVBPrint bp; | ||
| 124 | |||
| 125 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1047 times.
|
1047 | if (!filename) |
| 126 | ✗ | return 0; | |
| 127 | 1047 | av_bprint_init(&bp, 0, AV_BPRINT_SIZE_COUNT_ONLY); | |
| 128 | 1047 | return (ff_bprint_get_frame_filename(&bp, filename, 1, AV_FRAME_FILENAME_FLAGS_IGNORE_TRUNCATION) >= 0); | |
| 129 | } | ||
| 130 | |||
| 131 | /**********************************************************/ | ||
| 132 | |||
| 133 | 1363 | unsigned int ff_codec_get_tag(const AVCodecTag *tags, enum AVCodecID id) | |
| 134 | { | ||
| 135 |
2/2✓ Branch 0 taken 10479 times.
✓ Branch 1 taken 2 times.
|
10481 | while (tags->id != AV_CODEC_ID_NONE) { |
| 136 |
2/2✓ Branch 0 taken 1361 times.
✓ Branch 1 taken 9118 times.
|
10479 | if (tags->id == id) |
| 137 | 1361 | return tags->tag; | |
| 138 | 9118 | tags++; | |
| 139 | } | ||
| 140 | 2 | return 0; | |
| 141 | } | ||
| 142 | |||
| 143 | 3441 | enum AVCodecID ff_codec_get_id(const AVCodecTag *tags, unsigned int tag) | |
| 144 | { | ||
| 145 |
2/2✓ Branch 0 taken 287787 times.
✓ Branch 1 taken 1067 times.
|
288854 | for (int i = 0; tags[i].id != AV_CODEC_ID_NONE; i++) |
| 146 |
2/2✓ Branch 0 taken 2374 times.
✓ Branch 1 taken 285413 times.
|
287787 | if (tag == tags[i].tag) |
| 147 | 2374 | return tags[i].id; | |
| 148 |
2/2✓ Branch 0 taken 96205 times.
✓ Branch 1 taken 1062 times.
|
97267 | for (int i = 0; tags[i].id != AV_CODEC_ID_NONE; i++) |
| 149 |
2/2✓ Branch 2 taken 5 times.
✓ Branch 3 taken 96200 times.
|
96205 | if (ff_toupper4(tag) == ff_toupper4(tags[i].tag)) |
| 150 | 5 | return tags[i].id; | |
| 151 | 1062 | return AV_CODEC_ID_NONE; | |
| 152 | } | ||
| 153 | |||
| 154 | 604 | enum AVCodecID ff_get_pcm_codec_id(int bps, int flt, int be, int sflags) | |
| 155 | { | ||
| 156 |
2/4✓ Branch 0 taken 604 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 604 times.
|
604 | if (bps <= 0 || bps > 64) |
| 157 | ✗ | return AV_CODEC_ID_NONE; | |
| 158 | |||
| 159 |
2/2✓ Branch 0 taken 4 times.
✓ Branch 1 taken 600 times.
|
604 | if (flt) { |
| 160 |
2/3✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
|
4 | switch (bps) { |
| 161 | 2 | case 32: | |
| 162 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
|
2 | return be ? AV_CODEC_ID_PCM_F32BE : AV_CODEC_ID_PCM_F32LE; |
| 163 | 2 | case 64: | |
| 164 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
|
2 | return be ? AV_CODEC_ID_PCM_F64BE : AV_CODEC_ID_PCM_F64LE; |
| 165 | ✗ | default: | |
| 166 | ✗ | return AV_CODEC_ID_NONE; | |
| 167 | } | ||
| 168 | } else { | ||
| 169 | 600 | bps += 7; | |
| 170 | 600 | bps >>= 3; | |
| 171 |
2/2✓ Branch 0 taken 580 times.
✓ Branch 1 taken 20 times.
|
600 | if (sflags & (1 << (bps - 1))) { |
| 172 |
3/6✗ Branch 0 not taken.
✓ Branch 1 taken 562 times.
✓ Branch 2 taken 15 times.
✓ Branch 3 taken 3 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
|
580 | switch (bps) { |
| 173 | ✗ | case 1: | |
| 174 | ✗ | return AV_CODEC_ID_PCM_S8; | |
| 175 | 562 | case 2: | |
| 176 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 560 times.
|
562 | return be ? AV_CODEC_ID_PCM_S16BE : AV_CODEC_ID_PCM_S16LE; |
| 177 | 15 | case 3: | |
| 178 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 14 times.
|
15 | return be ? AV_CODEC_ID_PCM_S24BE : AV_CODEC_ID_PCM_S24LE; |
| 179 | 3 | case 4: | |
| 180 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
|
3 | return be ? AV_CODEC_ID_PCM_S32BE : AV_CODEC_ID_PCM_S32LE; |
| 181 | ✗ | case 8: | |
| 182 | ✗ | return be ? AV_CODEC_ID_PCM_S64BE : AV_CODEC_ID_PCM_S64LE; | |
| 183 | ✗ | default: | |
| 184 | ✗ | return AV_CODEC_ID_NONE; | |
| 185 | } | ||
| 186 | } else { | ||
| 187 |
1/5✓ Branch 0 taken 20 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
20 | switch (bps) { |
| 188 | 20 | case 1: | |
| 189 | 20 | return AV_CODEC_ID_PCM_U8; | |
| 190 | ✗ | case 2: | |
| 191 | ✗ | return be ? AV_CODEC_ID_PCM_U16BE : AV_CODEC_ID_PCM_U16LE; | |
| 192 | ✗ | case 3: | |
| 193 | ✗ | return be ? AV_CODEC_ID_PCM_U24BE : AV_CODEC_ID_PCM_U24LE; | |
| 194 | ✗ | case 4: | |
| 195 | ✗ | return be ? AV_CODEC_ID_PCM_U32BE : AV_CODEC_ID_PCM_U32LE; | |
| 196 | ✗ | default: | |
| 197 | ✗ | return AV_CODEC_ID_NONE; | |
| 198 | } | ||
| 199 | } | ||
| 200 | } | ||
| 201 | } | ||
| 202 | |||
| 203 | 6254 | unsigned int av_codec_get_tag(const AVCodecTag *const *tags, enum AVCodecID id) | |
| 204 | { | ||
| 205 | unsigned int tag; | ||
| 206 |
2/2✓ Branch 1 taken 14 times.
✓ Branch 2 taken 6240 times.
|
6254 | if (!av_codec_get_tag2(tags, id, &tag)) |
| 207 | 14 | return 0; | |
| 208 | 6240 | return tag; | |
| 209 | } | ||
| 210 | |||
| 211 | 9693 | int av_codec_get_tag2(const AVCodecTag * const *tags, enum AVCodecID id, | |
| 212 | unsigned int *tag) | ||
| 213 | { | ||
| 214 |
3/4✓ Branch 0 taken 18394 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 18360 times.
✓ Branch 3 taken 34 times.
|
18394 | for (int i = 0; tags && tags[i]; i++) { |
| 215 | 18360 | const AVCodecTag *codec_tags = tags[i]; | |
| 216 |
2/2✓ Branch 0 taken 801606 times.
✓ Branch 1 taken 8701 times.
|
810307 | while (codec_tags->id != AV_CODEC_ID_NONE) { |
| 217 |
2/2✓ Branch 0 taken 9659 times.
✓ Branch 1 taken 791947 times.
|
801606 | if (codec_tags->id == id) { |
| 218 | 9659 | *tag = codec_tags->tag; | |
| 219 | 9659 | return 1; | |
| 220 | } | ||
| 221 | 791947 | codec_tags++; | |
| 222 | } | ||
| 223 | } | ||
| 224 | 34 | return 0; | |
| 225 | } | ||
| 226 | |||
| 227 | 253 | enum AVCodecID av_codec_get_id(const AVCodecTag *const *tags, unsigned int tag) | |
| 228 | { | ||
| 229 |
3/4✓ Branch 0 taken 487 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 412 times.
✓ Branch 3 taken 75 times.
|
487 | for (int i = 0; tags && tags[i]; i++) { |
| 230 | 412 | enum AVCodecID id = ff_codec_get_id(tags[i], tag); | |
| 231 |
2/2✓ Branch 0 taken 178 times.
✓ Branch 1 taken 234 times.
|
412 | if (id != AV_CODEC_ID_NONE) |
| 232 | 178 | return id; | |
| 233 | } | ||
| 234 | 75 | return AV_CODEC_ID_NONE; | |
| 235 | } | ||
| 236 | |||
| 237 | 1086 | int ff_alloc_extradata(AVCodecParameters *par, int size) | |
| 238 | { | ||
| 239 | 1086 | av_freep(&par->extradata); | |
| 240 | 1086 | par->extradata_size = 0; | |
| 241 | |||
| 242 |
2/4✓ Branch 0 taken 1086 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1086 times.
|
1086 | if (size < 0 || size >= INT32_MAX - AV_INPUT_BUFFER_PADDING_SIZE) |
| 243 | ✗ | return AVERROR(EINVAL); | |
| 244 | |||
| 245 | 1086 | par->extradata = av_malloc(size + AV_INPUT_BUFFER_PADDING_SIZE); | |
| 246 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1086 times.
|
1086 | if (!par->extradata) |
| 247 | ✗ | return AVERROR(ENOMEM); | |
| 248 | |||
| 249 | 1086 | memset(par->extradata + size, 0, AV_INPUT_BUFFER_PADDING_SIZE); | |
| 250 | 1086 | par->extradata_size = size; | |
| 251 | |||
| 252 | 1086 | return 0; | |
| 253 | } | ||
| 254 | |||
| 255 | /*******************************************************/ | ||
| 256 | |||
| 257 | 37 | uint64_t ff_ntp_time(void) | |
| 258 | { | ||
| 259 | 37 | return (av_gettime() / 1000) * 1000 + NTP_OFFSET_US; | |
| 260 | } | ||
| 261 | |||
| 262 | ✗ | uint64_t ff_get_formatted_ntp_time(uint64_t ntp_time_us) | |
| 263 | { | ||
| 264 | uint64_t ntp_ts, frac_part, sec; | ||
| 265 | uint32_t usec; | ||
| 266 | |||
| 267 | //current ntp time in seconds and microseconds | ||
| 268 | ✗ | sec = ntp_time_us / 1000000; | |
| 269 | ✗ | usec = ntp_time_us % 1000000; | |
| 270 | |||
| 271 | //encoding in ntp timestamp format | ||
| 272 | ✗ | frac_part = usec * 0xFFFFFFFFULL; | |
| 273 | ✗ | frac_part /= 1000000; | |
| 274 | |||
| 275 | ✗ | if (sec > 0xFFFFFFFFULL) | |
| 276 | ✗ | av_log(NULL, AV_LOG_WARNING, "NTP time format roll over detected\n"); | |
| 277 | |||
| 278 | ✗ | ntp_ts = sec << 32; | |
| 279 | ✗ | ntp_ts |= frac_part; | |
| 280 | |||
| 281 | ✗ | return ntp_ts; | |
| 282 | } | ||
| 283 | |||
| 284 | ✗ | uint64_t ff_parse_ntp_time(uint64_t ntp_ts) | |
| 285 | { | ||
| 286 | ✗ | uint64_t sec = ntp_ts >> 32; | |
| 287 | ✗ | uint64_t frac_part = ntp_ts & 0xFFFFFFFFULL; | |
| 288 | ✗ | uint64_t usec = (frac_part * 1000000) / 0xFFFFFFFFULL; | |
| 289 | |||
| 290 | ✗ | return (sec * 1000000) + usec; | |
| 291 | } | ||
| 292 | |||
| 293 | 171873 | int ff_bprint_get_frame_filename(struct AVBPrint *buf, const char *path, int64_t number, int flags) | |
| 294 | { | ||
| 295 | const char *p; | ||
| 296 | char c; | ||
| 297 | int nd, percentd_found; | ||
| 298 | |||
| 299 | 171873 | p = path; | |
| 300 | 171873 | percentd_found = 0; | |
| 301 | for (;;) { | ||
| 302 | 13095311 | c = *p++; | |
| 303 |
2/2✓ Branch 0 taken 171873 times.
✓ Branch 1 taken 12923438 times.
|
13095311 | if (c == '\0') |
| 304 | 171873 | break; | |
| 305 |
2/2✓ Branch 0 taken 171120 times.
✓ Branch 1 taken 12752318 times.
|
12923438 | if (c == '%') { |
| 306 | do { | ||
| 307 | 171120 | nd = 0; | |
| 308 |
2/2✓ Branch 0 taken 342128 times.
✓ Branch 1 taken 171120 times.
|
513248 | while (av_isdigit(*p)) { |
| 309 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 342128 times.
|
342128 | if (nd >= INT_MAX / 10 - 255) |
| 310 | ✗ | goto fail; | |
| 311 | 342128 | nd = nd * 10 + *p++ - '0'; | |
| 312 | } | ||
| 313 | 171120 | c = *p++; | |
| 314 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 171120 times.
|
171120 | } while (av_isdigit(c)); |
| 315 | |||
| 316 |
1/3✗ Branch 0 not taken.
✓ Branch 1 taken 171120 times.
✗ Branch 2 not taken.
|
171120 | switch (c) { |
| 317 | ✗ | case '%': | |
| 318 | ✗ | goto addchar; | |
| 319 | 171120 | case 'd': | |
| 320 |
3/4✓ Branch 0 taken 170454 times.
✓ Branch 1 taken 666 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 170454 times.
|
171120 | if (!(flags & AV_FRAME_FILENAME_FLAGS_MULTIPLE) && percentd_found) |
| 321 | ✗ | goto fail; | |
| 322 | 171120 | percentd_found = 1; | |
| 323 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 171120 times.
|
171120 | if (number < 0) |
| 324 | ✗ | nd += 1; | |
| 325 | 171120 | av_bprintf(buf, "%0*" PRId64, nd, number); | |
| 326 | 171120 | break; | |
| 327 | ✗ | default: | |
| 328 | ✗ | goto fail; | |
| 329 | } | ||
| 330 | } else { | ||
| 331 | 12752318 | addchar: | |
| 332 | 12752318 | av_bprint_chars(buf, c, 1); | |
| 333 | } | ||
| 334 | } | ||
| 335 |
2/2✓ Branch 0 taken 753 times.
✓ Branch 1 taken 171120 times.
|
171873 | if (!percentd_found) |
| 336 | 753 | goto fail; | |
| 337 |
3/4✓ Branch 0 taken 170812 times.
✓ Branch 1 taken 308 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 170812 times.
|
171120 | if (!(flags & AV_FRAME_FILENAME_FLAGS_IGNORE_TRUNCATION) && !av_bprint_is_complete(buf)) |
| 338 | ✗ | return AVERROR(ENOMEM); | |
| 339 | 171120 | return 0; | |
| 340 | 753 | fail: | |
| 341 | 753 | return AVERROR(EINVAL); | |
| 342 | } | ||
| 343 | |||
| 344 | ✗ | static int get_frame_filename(char *buf, int buf_size, const char *path, int64_t number, int flags) | |
| 345 | { | ||
| 346 | AVBPrint bp; | ||
| 347 | ✗ | av_bprint_init_for_buffer(&bp, buf, buf_size); | |
| 348 | ✗ | return ff_bprint_get_frame_filename(&bp, path, number, flags) < 0 ? -1 : 0; | |
| 349 | } | ||
| 350 | |||
| 351 | ✗ | int av_get_frame_filename2(char *buf, int buf_size, const char *path, int number, int flags) | |
| 352 | { | ||
| 353 | ✗ | return get_frame_filename(buf, buf_size, path, number, flags); | |
| 354 | } | ||
| 355 | |||
| 356 | ✗ | int av_get_frame_filename(char *buf, int buf_size, const char *path, int number) | |
| 357 | { | ||
| 358 | ✗ | return get_frame_filename(buf, buf_size, path, number, 0); | |
| 359 | } | ||
| 360 | |||
| 361 | 9 | void av_url_split(char *proto, int proto_size, | |
| 362 | char *authorization, int authorization_size, | ||
| 363 | char *hostname, int hostname_size, | ||
| 364 | int *port_ptr, char *path, int path_size, const char *url) | ||
| 365 | { | ||
| 366 | const char *p, *ls, *at, *at2, *col, *brk; | ||
| 367 | |||
| 368 |
1/2✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
|
9 | if (port_ptr) |
| 369 | 9 | *port_ptr = -1; | |
| 370 |
1/2✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
|
9 | if (proto_size > 0) |
| 371 | 9 | proto[0] = 0; | |
| 372 |
1/2✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
|
9 | if (authorization_size > 0) |
| 373 | 9 | authorization[0] = 0; | |
| 374 |
1/2✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
|
9 | if (hostname_size > 0) |
| 375 | 9 | hostname[0] = 0; | |
| 376 |
1/2✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
|
9 | if (path_size > 0) |
| 377 | 9 | path[0] = 0; | |
| 378 | |||
| 379 | /* parse protocol */ | ||
| 380 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 1 times.
|
9 | if ((p = strchr(url, ':'))) { |
| 381 | 8 | av_strlcpy(proto, url, FFMIN(proto_size, p + 1 - url)); | |
| 382 | 8 | p++; /* skip ':' */ | |
| 383 |
1/2✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
|
8 | if (*p == '/') |
| 384 | 8 | p++; | |
| 385 |
1/2✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
|
8 | if (*p == '/') |
| 386 | 8 | p++; | |
| 387 | } else { | ||
| 388 | /* no protocol means plain filename */ | ||
| 389 | 1 | av_strlcpy(path, url, path_size); | |
| 390 | 1 | return; | |
| 391 | } | ||
| 392 | |||
| 393 | /* separate path from hostname */ | ||
| 394 | 8 | ls = p + strcspn(p, "/?#"); | |
| 395 | 8 | av_strlcpy(path, ls, path_size); | |
| 396 | |||
| 397 | /* the rest is hostname, use that to parse auth/port */ | ||
| 398 |
1/2✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
|
8 | if (ls != p) { |
| 399 | /* authorization (user[:pass]@hostname) */ | ||
| 400 | 8 | at2 = p; | |
| 401 |
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) { |
| 402 | 2 | av_strlcpy(authorization, at2, | |
| 403 | 2 | FFMIN(authorization_size, at + 1 - at2)); | |
| 404 | 2 | p = at + 1; /* skip '@' */ | |
| 405 | } | ||
| 406 | |||
| 407 |
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) { |
| 408 | /* [host]:port */ | ||
| 409 | ✗ | av_strlcpy(hostname, p + 1, | |
| 410 | ✗ | FFMIN(hostname_size, brk - p)); | |
| 411 | ✗ | if (brk[1] == ':' && port_ptr) | |
| 412 | ✗ | *port_ptr = atoi(brk + 2); | |
| 413 |
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) { |
| 414 | 1 | av_strlcpy(hostname, p, | |
| 415 | 1 | FFMIN(col + 1 - p, hostname_size)); | |
| 416 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 | if (port_ptr) |
| 417 | 1 | *port_ptr = atoi(col + 1); | |
| 418 | } else | ||
| 419 | 7 | av_strlcpy(hostname, p, | |
| 420 | 7 | FFMIN(ls + 1 - p, hostname_size)); | |
| 421 | } | ||
| 422 | } | ||
| 423 | |||
| 424 | 1 | int ff_mkdir_p(const char *path) | |
| 425 | { | ||
| 426 | 1 | int ret = 0; | |
| 427 | 1 | char *temp = av_strdup(path); | |
| 428 | 1 | char *pos = temp; | |
| 429 | 1 | char tmp_ch = '\0'; | |
| 430 | |||
| 431 |
2/4✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
|
1 | if (!path || !temp) { |
| 432 | ✗ | return -1; | |
| 433 | } | ||
| 434 | |||
| 435 |
2/4✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
|
1 | if (!av_strncasecmp(temp, "/", 1) || !av_strncasecmp(temp, "\\", 1)) { |
| 436 | ✗ | pos++; | |
| 437 |
2/4✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
|
1 | } else if (!av_strncasecmp(temp, "./", 2) || !av_strncasecmp(temp, ".\\", 2)) { |
| 438 | ✗ | pos += 2; | |
| 439 | } | ||
| 440 | |||
| 441 |
2/2✓ Branch 0 taken 28 times.
✓ Branch 1 taken 1 times.
|
29 | for ( ; *pos != '\0'; ++pos) { |
| 442 |
3/4✓ Branch 0 taken 27 times.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 27 times.
|
28 | if (*pos == '/' || *pos == '\\') { |
| 443 | 1 | tmp_ch = *pos; | |
| 444 | 1 | *pos = '\0'; | |
| 445 | 1 | ret = mkdir(temp, 0755); | |
| 446 |
2/4✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
|
1 | if (ret < 0 && errno != EEXIST) { |
| 447 | ✗ | int err = errno; | |
| 448 | ✗ | av_free(temp); | |
| 449 | ✗ | errno = err; | |
| 450 | ✗ | return ret; | |
| 451 | } | ||
| 452 | 1 | *pos = tmp_ch; | |
| 453 | } | ||
| 454 | } | ||
| 455 | |||
| 456 |
2/4✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
1 | if ((*(pos - 1) != '/') && (*(pos - 1) != '\\')) { |
| 457 | 1 | ret = mkdir(temp, 0755); | |
| 458 | } | ||
| 459 | |||
| 460 | 1 | av_free(temp); | |
| 461 | 1 | return ret; | |
| 462 | } | ||
| 463 | |||
| 464 | 3501 | char *ff_data_to_hex(char *buff, const uint8_t *src, int s, int lowercase) | |
| 465 | { | ||
| 466 | static const char hex_table_uc[16] = { '0', '1', '2', '3', | ||
| 467 | '4', '5', '6', '7', | ||
| 468 | '8', '9', 'A', 'B', | ||
| 469 | 'C', 'D', 'E', 'F' }; | ||
| 470 | static const char hex_table_lc[16] = { '0', '1', '2', '3', | ||
| 471 | '4', '5', '6', '7', | ||
| 472 | '8', '9', 'a', 'b', | ||
| 473 | 'c', 'd', 'e', 'f' }; | ||
| 474 |
2/2✓ Branch 0 taken 2804 times.
✓ Branch 1 taken 697 times.
|
3501 | const char *hex_table = lowercase ? hex_table_lc : hex_table_uc; |
| 475 | |||
| 476 |
2/2✓ Branch 0 taken 56030 times.
✓ Branch 1 taken 3501 times.
|
59531 | for (int i = 0; i < s; i++) { |
| 477 | 56030 | buff[i * 2] = hex_table[src[i] >> 4]; | |
| 478 | 56030 | buff[i * 2 + 1] = hex_table[src[i] & 0xF]; | |
| 479 | } | ||
| 480 | 3501 | buff[2 * s] = '\0'; | |
| 481 | |||
| 482 | 3501 | return buff; | |
| 483 | } | ||
| 484 | |||
| 485 | 3 | int ff_hex_to_data(uint8_t *data, const char *p) | |
| 486 | { | ||
| 487 | int c, len, v; | ||
| 488 | |||
| 489 | 3 | len = 0; | |
| 490 | 3 | v = 1; | |
| 491 | for (;;) { | ||
| 492 | 96 | p += strspn(p, SPACE_CHARS); | |
| 493 |
2/2✓ Branch 0 taken 3 times.
✓ Branch 1 taken 96 times.
|
99 | if (*p == '\0') |
| 494 | 3 | break; | |
| 495 | 96 | c = av_toupper((unsigned char) *p++); | |
| 496 |
2/4✓ Branch 0 taken 96 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 96 times.
✗ Branch 3 not taken.
|
96 | if (c >= '0' && c <= '9') |
| 497 | 96 | c = c - '0'; | |
| 498 | ✗ | else if (c >= 'A' && c <= 'F') | |
| 499 | ✗ | c = c - 'A' + 10; | |
| 500 | else | ||
| 501 | break; | ||
| 502 | 96 | v = (v << 4) | c; | |
| 503 |
2/2✓ Branch 0 taken 48 times.
✓ Branch 1 taken 48 times.
|
96 | if (v & 0x100) { |
| 504 |
1/2✓ Branch 0 taken 48 times.
✗ Branch 1 not taken.
|
48 | if (data) |
| 505 | 48 | data[len] = v; | |
| 506 | 48 | len++; | |
| 507 | 48 | v = 1; | |
| 508 | } | ||
| 509 | } | ||
| 510 | 3 | return len; | |
| 511 | } | ||
| 512 | |||
| 513 | 3 | void ff_parse_key_value(const char *str, ff_parse_key_val_cb callback_get_buf, | |
| 514 | void *context) | ||
| 515 | { | ||
| 516 | 3 | const char *ptr = str; | |
| 517 | |||
| 518 | /* Parse key=value pairs. */ | ||
| 519 | 11 | for (;;) { | |
| 520 | const char *key; | ||
| 521 | 14 | char *dest = NULL, *dest_end; | |
| 522 | 14 | int key_len, dest_len = 0; | |
| 523 | |||
| 524 | /* Skip whitespace and potential commas. */ | ||
| 525 |
5/6✓ Branch 0 taken 19 times.
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 19 times.
✓ Branch 4 taken 8 times.
✓ Branch 5 taken 11 times.
|
22 | while (*ptr && (av_isspace(*ptr) || *ptr == ',')) |
| 526 | 8 | ptr++; | |
| 527 |
2/2✓ Branch 0 taken 3 times.
✓ Branch 1 taken 11 times.
|
14 | if (!*ptr) |
| 528 | 3 | break; | |
| 529 | |||
| 530 | 11 | key = ptr; | |
| 531 | |||
| 532 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 11 times.
|
11 | if (!(ptr = strchr(key, '='))) |
| 533 | ✗ | break; | |
| 534 | 11 | ptr++; | |
| 535 | 11 | key_len = ptr - key; | |
| 536 | |||
| 537 | 11 | callback_get_buf(context, key, key_len, &dest, &dest_len); | |
| 538 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 3 times.
|
11 | dest_end = dest ? dest + dest_len - 1 : NULL; |
| 539 | |||
| 540 |
2/2✓ Branch 0 taken 6 times.
✓ Branch 1 taken 5 times.
|
11 | if (*ptr == '\"') { |
| 541 | 6 | ptr++; | |
| 542 |
3/4✓ Branch 0 taken 52 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 46 times.
✓ Branch 3 taken 6 times.
|
52 | while (*ptr && *ptr != '\"') { |
| 543 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 46 times.
|
46 | if (*ptr == '\\') { |
| 544 | ✗ | if (!ptr[1]) | |
| 545 | ✗ | break; | |
| 546 | ✗ | if (dest && dest < dest_end) | |
| 547 | ✗ | *dest++ = ptr[1]; | |
| 548 | ✗ | ptr += 2; | |
| 549 | } else { | ||
| 550 |
3/4✓ Branch 0 taken 45 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 45 times.
✗ Branch 3 not taken.
|
46 | if (dest && dest < dest_end) |
| 551 | 45 | *dest++ = *ptr; | |
| 552 | 46 | ptr++; | |
| 553 | } | ||
| 554 | } | ||
| 555 |
1/2✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
|
6 | if (*ptr == '\"') |
| 556 | 6 | ptr++; | |
| 557 | } else { | ||
| 558 |
4/6✓ Branch 0 taken 31 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 31 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 26 times.
✓ Branch 5 taken 5 times.
|
31 | for (; *ptr && !(av_isspace(*ptr) || *ptr == ','); ptr++) |
| 559 |
3/4✓ Branch 0 taken 14 times.
✓ Branch 1 taken 12 times.
✓ Branch 2 taken 14 times.
✗ Branch 3 not taken.
|
26 | if (dest && dest < dest_end) |
| 560 | 14 | *dest++ = *ptr; | |
| 561 | } | ||
| 562 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 3 times.
|
11 | if (dest) |
| 563 | 8 | *dest = 0; | |
| 564 | } | ||
| 565 | 3 | } | |
| 566 | |||
| 567 | 8941 | int avformat_network_init(void) | |
| 568 | { | ||
| 569 | #if CONFIG_NETWORK | ||
| 570 | int ret; | ||
| 571 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 8941 times.
|
8941 | if ((ret = ff_network_init()) < 0) |
| 572 | ✗ | return ret; | |
| 573 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 8941 times.
|
8941 | if ((ret = ff_tls_init()) < 0) |
| 574 | ✗ | return ret; | |
| 575 | #endif | ||
| 576 | 8941 | return 0; | |
| 577 | } | ||
| 578 | |||
| 579 | 8941 | int avformat_network_deinit(void) | |
| 580 | { | ||
| 581 | #if CONFIG_NETWORK | ||
| 582 | 8941 | ff_network_close(); | |
| 583 | 8941 | ff_tls_deinit(); | |
| 584 | #endif | ||
| 585 | 8941 | return 0; | |
| 586 | } | ||
| 587 | |||
| 588 | 609 | int ff_is_http_proto(const char *filename) { | |
| 589 | 609 | const char *proto = avio_find_protocol_name(filename); | |
| 590 |
3/6✓ Branch 0 taken 609 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 609 times.
✗ Branch 4 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 609 times.
|
609 | return proto ? (!av_strcasecmp(proto, "http") || !av_strcasecmp(proto, "https")) : 0; |
| 591 | } | ||
| 592 | |||
| 593 | 9 | int ff_bprint_to_codecpar_extradata(AVCodecParameters *par, struct AVBPrint *buf) | |
| 594 | { | ||
| 595 | int ret; | ||
| 596 | char *str; | ||
| 597 | |||
| 598 | 9 | ret = av_bprint_finalize(buf, &str); | |
| 599 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 9 times.
|
9 | if (ret < 0) |
| 600 | ✗ | return ret; | |
| 601 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 9 times.
|
9 | if (!av_bprint_is_complete(buf)) { |
| 602 | ✗ | av_free(str); | |
| 603 | ✗ | return AVERROR(ENOMEM); | |
| 604 | } | ||
| 605 | |||
| 606 | 9 | par->extradata = str; | |
| 607 | /* Note: the string is NUL terminated (so extradata can be read as a | ||
| 608 | * string), but the ending character is not accounted in the size (in | ||
| 609 | * binary formats you are likely not supposed to mux that character). When | ||
| 610 | * extradata is copied, it is also padded with AV_INPUT_BUFFER_PADDING_SIZE | ||
| 611 | * zeros. */ | ||
| 612 | 9 | par->extradata_size = buf->len; | |
| 613 | 9 | return 0; | |
| 614 | } | ||
| 615 | |||
| 616 | 676 | int ff_dict_set_timestamp(AVDictionary **dict, const char *key, int64_t timestamp) | |
| 617 | { | ||
| 618 | 676 | int microsecs = timestamp % 1000000; | |
| 619 | 676 | time_t seconds = timestamp / 1000000 - (microsecs < 0); | |
| 620 | struct tm *ptm, tmbuf; | ||
| 621 | 676 | ptm = gmtime_r(&seconds, &tmbuf); | |
| 622 |
1/2✓ Branch 0 taken 676 times.
✗ Branch 1 not taken.
|
676 | if (ptm) { |
| 623 | char buf[32]; | ||
| 624 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 676 times.
|
676 | if (!strftime(buf, sizeof(buf), "%Y-%m-%dT%H:%M:%S", ptm)) |
| 625 | ✗ | return AVERROR_EXTERNAL; | |
| 626 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 676 times.
|
676 | av_strlcatf(buf, sizeof(buf), ".%06dZ", microsecs + (microsecs < 0) * 1000000); |
| 627 | 676 | return av_dict_set(dict, key, buf, 0); | |
| 628 | } else { | ||
| 629 | ✗ | return AVERROR_EXTERNAL; | |
| 630 | } | ||
| 631 | } | ||
| 632 | |||
| 633 | ✗ | static const AVOption* find_opt(void *obj, const char *name, size_t len) | |
| 634 | { | ||
| 635 | char decoded_name[128]; | ||
| 636 | |||
| 637 | ✗ | if (ff_urldecode_len(decoded_name, sizeof(decoded_name), name, len, 1) < 0) | |
| 638 | ✗ | return NULL; | |
| 639 | |||
| 640 | ✗ | return av_opt_find(obj, decoded_name, NULL, 0, 0); | |
| 641 | } | ||
| 642 | |||
| 643 | ✗ | int ff_parse_opts_from_query_string(void *obj, const char *str, int allow_unknown) | |
| 644 | { | ||
| 645 | const AVOption *opt; | ||
| 646 | char optval[512]; | ||
| 647 | int ret; | ||
| 648 | |||
| 649 | ✗ | if (*str == '?') | |
| 650 | ✗ | str++; | |
| 651 | ✗ | while (*str) { | |
| 652 | ✗ | size_t len = strcspn(str, "=&"); | |
| 653 | ✗ | opt = find_opt(obj, str, len); | |
| 654 | ✗ | if (!opt) { | |
| 655 | ✗ | if (!allow_unknown) { | |
| 656 | ✗ | av_log(obj, AV_LOG_ERROR, "Query string option '%.*s' does not exist\n", (int)len, str); | |
| 657 | ✗ | return AVERROR_OPTION_NOT_FOUND; | |
| 658 | } | ||
| 659 | ✗ | av_log(obj, AV_LOG_VERBOSE, "Ignoring unknown query string option '%.*s'\n", (int)len, str); | |
| 660 | } | ||
| 661 | ✗ | str += len; | |
| 662 | ✗ | if (!opt) { | |
| 663 | ✗ | len = strcspn(str, "&"); | |
| 664 | ✗ | str += len; | |
| 665 | ✗ | } else if (*str == '&' || *str == '\0') { | |
| 666 | /* Check for bool options without value, e.g. "?verify". | ||
| 667 | * Unfortunately "listen" is a tri-state INT for some protocols so | ||
| 668 | * we also have to allow that for backward compatibility. */ | ||
| 669 | ✗ | if (opt->type != AV_OPT_TYPE_BOOL && strcmp(opt->name, "listen")) { | |
| 670 | ✗ | av_log(obj, AV_LOG_ERROR, "Non-bool query string option '%s' has no value\n", opt->name); | |
| 671 | ✗ | return AVERROR(EINVAL); | |
| 672 | } | ||
| 673 | ✗ | ret = av_opt_set_int(obj, opt->name, 1, 0); | |
| 674 | ✗ | if (ret < 0) | |
| 675 | ✗ | return ret; | |
| 676 | } else { | ||
| 677 | av_assert2(*str == '='); | ||
| 678 | ✗ | str++; | |
| 679 | ✗ | len = strcspn(str, "&"); | |
| 680 | ✗ | if (ff_urldecode_len(optval, sizeof(optval), str, len, 1) < 0) { | |
| 681 | ✗ | av_log(obj, AV_LOG_ERROR, "Query string option '%s' value is too long\n", opt->name); | |
| 682 | ✗ | return AVERROR(EINVAL); | |
| 683 | } | ||
| 684 | ✗ | ret = av_opt_set(obj, opt->name, optval, 0); | |
| 685 | ✗ | if (ret < 0) | |
| 686 | ✗ | return ret; | |
| 687 | ✗ | str += len; | |
| 688 | } | ||
| 689 | ✗ | if (*str) | |
| 690 | ✗ | str++; | |
| 691 | } | ||
| 692 | ✗ | return 0; | |
| 693 | } | ||
| 694 | |||
| 695 | 106 | void *ff_bprint_finalize_as_fam(struct AVBPrint *bp, const void *struct_ptr, size_t fam_offset) | |
| 696 | { | ||
| 697 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 106 times.
|
106 | if (!av_bprint_is_complete(bp)) { |
| 698 | ✗ | av_bprint_finalize(bp, NULL); | |
| 699 | ✗ | return NULL; | |
| 700 | } | ||
| 701 | |||
| 702 | 106 | uint8_t *p = av_malloc(fam_offset + bp->len); | |
| 703 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 106 times.
|
106 | if (!p) { |
| 704 | ✗ | av_bprint_finalize(bp, NULL); | |
| 705 | ✗ | return NULL; | |
| 706 | } | ||
| 707 | 106 | memcpy(p, struct_ptr, fam_offset); | |
| 708 | 106 | memcpy(p + fam_offset, bp->str, bp->len); | |
| 709 | 106 | av_bprint_finalize(bp, NULL); | |
| 710 | |||
| 711 | 106 | return p; | |
| 712 | } | ||
| 713 |