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
24 #include "config.h"
25
31
33
37 #if CONFIG_NETWORK
39 #endif
40
42
43 /**
44 * @file
45 * various utility functions for use within FFmpeg
46 */
47
49 {
51 }
52
54 {
56 }
57
58 /* an arbitrarily chosen "sane" max packet size -- 50M */
59 #define SANE_CHUNK_SIZE (50000000)
60
61 /* Read the data in sane-sized chunks and append to pkt.
62 * Return the number of bytes read or an error. */
64 {
67
68 do {
70 int read_size;
71
72 /* When the caller requests a lot of data, limit it to the amount
73 * left in file or SANE_CHUNK_SIZE when it is not known. */
77 // If filesize/maxsize is unknown, limit to SANE_CHUNK_SIZE
80 }
81
84 break;
85
87 if (
ret != read_size) {
89 break;
90 }
91
96
100 }
101
103 {
104 #if FF_API_INIT_PACKET
110 #else
112 #endif
114
116 }
117
119 {
123 }
124
126 {
127 char buf[1024];
128 return filename &&
130 }
131
132 /**********************************************************/
133
135 {
139 tags++;
140 }
141 return 0;
142 }
143
145 {
153 }
154
156 {
157 if (bps <= 0 || bps > 64)
159
160 if (flt) {
162 case 32:
164 case 64:
166 default:
168 }
169 } else {
172 if (sflags & (1 << (
bps - 1))) {
174 case 1:
176 case 2:
178 case 3:
180 case 4:
182 case 8:
184 default:
186 }
187 } else {
189 case 1:
191 case 2:
193 case 3:
195 case 4:
197 default:
199 }
200 }
201 }
202 }
203
205 {
208 return 0;
210 }
211
214 {
215 for (
int i = 0; tags && tags[
i];
i++) {
218 if (codec_tags->
id ==
id) {
220 return 1;
221 }
222 codec_tags++;
223 }
224 }
225 return 0;
226 }
227
229 {
230 for (
int i = 0; tags && tags[
i];
i++) {
234 }
236 }
237
239 {
242
245
249
252
253 return 0;
254 }
255
256 /*******************************************************/
257
259 {
261 }
262
264 {
265 uint64_t ntp_ts, frac_part, sec;
266 uint32_t usec;
267
268 //current ntp time in seconds and micro seconds
269 sec = ntp_time_us / 1000000;
270 usec = ntp_time_us % 1000000;
271
272 //encoding in ntp timestamp format
273 frac_part = usec * 0xFFFFFFFFULL;
274 frac_part /= 1000000;
275
276 if (sec > 0xFFFFFFFFULL)
278
279 ntp_ts = sec << 32;
280 ntp_ts |= frac_part;
281
282 return ntp_ts;
283 }
284
286 {
287 uint64_t sec = ntp_ts >> 32;
288 uint64_t frac_part = ntp_ts & 0xFFFFFFFFULL;
289 uint64_t usec = (frac_part * 1000000) / 0xFFFFFFFFULL;
290
291 return (sec * 1000000) + usec;
292 }
293
295 {
296 const char *p;
297 char *q, buf1[20],
c;
298 int nd,
len, percentd_found;
299
300 q = buf;
301 p = path;
302 percentd_found = 0;
303 for (;;) {
306 break;
308 do {
309 nd = 0;
311 if (nd >= INT_MAX / 10 - 255)
313 nd = nd * 10 + *p++ - '0';
314 }
317
319 case '%':
320 goto addchar;
321 case 'd':
324 percentd_found = 1;
325 if (number < 0)
326 nd += 1;
327 snprintf(buf1,
sizeof(buf1),
"%0*d", nd, number);
329 if ((q - buf +
len) > buf_size - 1)
331 memcpy(q, buf1,
len);
333 break;
334 default:
336 }
337 } else {
338 addchar:
339 if ((q - buf) < buf_size - 1)
341 }
342 }
343 if (!percentd_found)
345 *q = '0円';
346 return 0;
348 *q = '0円';
349 return -1;
350 }
351
353 {
355 }
356
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 if (port_ptr)
365 *port_ptr = -1;
366 if (proto_size > 0)
367 proto[0] = 0;
368 if (authorization_size > 0)
369 authorization[0] = 0;
370 if (hostname_size > 0)
371 hostname[0] = 0;
372 if (path_size > 0)
373 path[0] = 0;
374
375 /* parse protocol */
376 if ((p = strchr(url, ':'))) {
378 p++; /* skip ':' */
379 if (*p == '/')
380 p++;
381 if (*p == '/')
382 p++;
383 } else {
384 /* no protocol means plain filename */
386 return;
387 }
388
389 /* separate path from hostname */
390 ls = p + strcspn(p, "/?#");
392
393 /* the rest is hostname, use that to parse auth/port */
394 if (ls != p) {
395 /* authorization (user[:pass]@hostname) */
396 at2 = p;
397 while ((at = strchr(p, '@')) && at < ls) {
399 FFMIN(authorization_size, at + 1 - at2));
400 p = at + 1; /* skip '@' */
401 }
402
403 if (*p == '[' && (brk = strchr(p, ']')) && brk < ls) {
404 /* [host]:port */
406 FFMIN(hostname_size, brk - p));
407 if (brk[1] == ':' && port_ptr)
408 *port_ptr = atoi(brk + 2);
409 } else if ((col = strchr(p, ':')) && col < ls) {
411 FFMIN(col + 1 - p, hostname_size));
412 if (port_ptr)
413 *port_ptr = atoi(col + 1);
414 } else
416 FFMIN(ls + 1 - p, hostname_size));
417 }
418 }
419
421 {
425 char tmp_ch = '0円';
426
427 if (!path || !
temp) {
428 return -1;
429 }
430
435 }
436
437 for ( ; *
pos !=
'0円'; ++
pos) {
438 if (*
pos ==
'/' || *
pos ==
'\\') {
443 }
444 }
445
446 if ((*(
pos - 1) !=
'/') && (*(
pos - 1) !=
'\\')) {
448 }
449
452 }
453
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 const char *hex_table =
lowercase ? hex_table_lc : hex_table_uc;
465
466 for (
int i = 0;
i <
s;
i++) {
467 buff[
i * 2] = hex_table[
src[
i] >> 4];
468 buff[
i * 2 + 1] = hex_table[
src[
i] & 0xF];
469 }
471
472 return buff;
473 }
474
476 {
478
480 v = 1;
481 for (;;) {
483 if (*p == '0円')
484 break;
486 if (
c >=
'0' &&
c <=
'9')
488 else if (
c >=
'A' &&
c <=
'F')
490 else
491 break;
493 if (v & 0x100) {
497 v = 1;
498 }
499 }
501 }
502
505 {
506 const char *ptr =
str;
507
508 /* Parse key=value pairs. */
509 for (;;) {
511 char *dest =
NULL, *dest_end;
512 int key_len, dest_len = 0;
513
514 /* Skip whitespace and potential commas. */
515 while (*ptr && (
av_isspace(*ptr) || *ptr ==
','))
516 ptr++;
517 if (!*ptr)
518 break;
519
521
522 if (!(ptr = strchr(
key,
'=')))
523 break;
524 ptr++;
526
527 callback_get_buf(
context,
key, key_len, &dest, &dest_len);
528 dest_end = dest ? dest + dest_len - 1 :
NULL;
529
530 if (*ptr == '\"') {
531 ptr++;
532 while (*ptr && *ptr != '\"') {
533 if (*ptr == '\\') {
534 if (!ptr[1])
535 break;
536 if (dest && dest < dest_end)
537 *dest++ = ptr[1];
538 ptr += 2;
539 } else {
540 if (dest && dest < dest_end)
541 *dest++ = *ptr;
542 ptr++;
543 }
544 }
545 if (*ptr == '\"')
546 ptr++;
547 } else {
548 for (; *ptr && !(
av_isspace(*ptr) || *ptr ==
','); ptr++)
549 if (dest && dest < dest_end)
550 *dest++ = *ptr;
551 }
552 if (dest)
553 *dest = 0;
554 }
555 }
556
558 {
559 #if CONFIG_NETWORK
565 #endif
566 return 0;
567 }
568
570 {
571 #if CONFIG_NETWORK
574 #endif
575 return 0;
576 }
577
581 }
582
584 {
587
594 }
595
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. */
603 return 0;
604 }