2 * various utility functions for use within FFmpeg
3 * Copyright (c) 2000, 2001, 2002 Fabrice Bellard
5 * This file is part of FFmpeg.
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.
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.
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
26 #include "libavutil/avstring.h"
27 #include "libavutil/bprint.h"
28 #include "libavutil/internal.h"
29 #include "libavutil/thread.h"
30 #include "libavutil/time.h"
32 #include "libavcodec/internal.h"
35 #include "avio_internal.h"
41 static AVMutex avformat_mutex
= AV_MUTEX_INITIALIZER
;
45 * various utility functions for use within FFmpeg
48 int ff_lock_avformat(void)
50 return ff_mutex_lock(&avformat_mutex
) ? -1 : 0;
53 int ff_unlock_avformat(void)
55 return ff_mutex_unlock(&avformat_mutex
) ? -1 : 0;
58 /* an arbitrarily chosen "sane" max packet size -- 50M */
59 #define SANE_CHUNK_SIZE (50000000)
61 /* Read the data in sane-sized chunks and append to pkt.
62 * Return the number of bytes read or an error. */
63 static int append_packet_chunked(AVIOContext
*s
, AVPacket
*pkt
, int size
)
65 int orig_size
= pkt
->size
;
69 int prev_size
= pkt
->size
;
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. */
75 if (read_size
> SANE_CHUNK_SIZE
/10) {
76 read_size
= ffio_limit(s
, read_size
);
77 // If filesize/maxsize is unknown, limit to SANE_CHUNK_SIZE
78 if (ffiocontext(s
)->maxsize
< 0)
79 read_size
= FFMIN(read_size
, SANE_CHUNK_SIZE
);
82 ret
= av_grow_packet(pkt
, read_size
);
86 ret
= avio_read(s
, pkt
->data
+ prev_size
, read_size
);
87 if (ret
!= read_size
) {
88 av_shrink_packet(pkt
, prev_size
+ FFMAX(ret
, 0));
95 pkt
->flags
|= AV_PKT_FLAG_CORRUPT
;
99 return pkt
->size
> orig_size
? pkt
->size
- orig_size
: ret
;
102 int av_get_packet(AVIOContext
*s
, AVPacket
*pkt
, int size
)
104 #if FF_API_INIT_PACKET
105 FF_DISABLE_DEPRECATION_WARNINGS
109 FF_ENABLE_DEPRECATION_WARNINGS
111 av_packet_unref(pkt
);
113 pkt
->pos
= avio_tell(s
);
115 return append_packet_chunked(s
, pkt
, size
);
118 int av_append_packet(AVIOContext
*s
, AVPacket
*pkt
, int size
)
121 return av_get_packet(s
, pkt
, size
);
122 return append_packet_chunked(s
, pkt
, size
);
125 int av_filename_number_test(const char *filename
)
129 (av_get_frame_filename(buf
, sizeof(buf
), filename
, 1) >= 0);
132 /**********************************************************/
134 unsigned int ff_codec_get_tag(const AVCodecTag
*tags
, enum AVCodecID id
)
136 while (tags
->id
!= AV_CODEC_ID_NONE
) {
144 enum AVCodecID
ff_codec_get_id(const AVCodecTag
*tags
, unsigned int tag
)
146 for (int i
= 0; tags
[i
].id
!= AV_CODEC_ID_NONE
; i
++)
147 if (tag
== tags
[i
].tag
)
149 for (int i
= 0; tags
[i
].id
!= AV_CODEC_ID_NONE
; i
++)
150 if (ff_toupper4(tag
) == ff_toupper4(tags
[i
].tag
))
152 return AV_CODEC_ID_NONE
;
155 enum AVCodecID
ff_get_pcm_codec_id(int bps
, int flt
, int be
, int sflags
)
157 if (bps
<= 0 || bps
> 64)
158 return AV_CODEC_ID_NONE
;
163 return be
? AV_CODEC_ID_PCM_F32BE
: AV_CODEC_ID_PCM_F32LE
;
165 return be
? AV_CODEC_ID_PCM_F64BE
: AV_CODEC_ID_PCM_F64LE
;
167 return AV_CODEC_ID_NONE
;
172 if (sflags
& (1 << (bps
- 1))) {
175 return AV_CODEC_ID_PCM_S8
;
177 return be
? AV_CODEC_ID_PCM_S16BE
: AV_CODEC_ID_PCM_S16LE
;
179 return be
? AV_CODEC_ID_PCM_S24BE
: AV_CODEC_ID_PCM_S24LE
;
181 return be
? AV_CODEC_ID_PCM_S32BE
: AV_CODEC_ID_PCM_S32LE
;
183 return be
? AV_CODEC_ID_PCM_S64BE
: AV_CODEC_ID_PCM_S64LE
;
185 return AV_CODEC_ID_NONE
;
190 return AV_CODEC_ID_PCM_U8
;
192 return be
? AV_CODEC_ID_PCM_U16BE
: AV_CODEC_ID_PCM_U16LE
;
194 return be
? AV_CODEC_ID_PCM_U24BE
: AV_CODEC_ID_PCM_U24LE
;
196 return be
? AV_CODEC_ID_PCM_U32BE
: AV_CODEC_ID_PCM_U32LE
;
198 return AV_CODEC_ID_NONE
;
204 unsigned int av_codec_get_tag(const AVCodecTag
*const *tags
, enum AVCodecID id
)
207 if (!av_codec_get_tag2(tags
, id
, &tag
))
212 int av_codec_get_tag2(const AVCodecTag
* const *tags
, enum AVCodecID id
,
215 for (int i
= 0; tags
&& tags
[i
]; i
++) {
216 const AVCodecTag
*codec_tags
= tags
[i
];
217 while (codec_tags
->id
!= AV_CODEC_ID_NONE
) {
218 if (codec_tags
->id
== id
) {
219 *tag
= codec_tags
->tag
;
228 enum AVCodecID
av_codec_get_id(const AVCodecTag
*const *tags
, unsigned int tag
)
230 for (int i
= 0; tags
&& tags
[i
]; i
++) {
231 enum AVCodecID id
= ff_codec_get_id(tags
[i
], tag
);
232 if (id
!= AV_CODEC_ID_NONE
)
235 return AV_CODEC_ID_NONE
;
238 int ff_alloc_extradata(AVCodecParameters
*par
, int size
)
240 av_freep(&par
->extradata
);
241 par
->extradata_size
= 0;
243 if (size
< 0 || size
>= INT32_MAX
- AV_INPUT_BUFFER_PADDING_SIZE
)
244 return AVERROR(EINVAL
);
246 par
->extradata
= av_malloc(size
+ AV_INPUT_BUFFER_PADDING_SIZE
);
248 return AVERROR(ENOMEM
);
250 memset(par
->extradata
+ size
, 0, AV_INPUT_BUFFER_PADDING_SIZE
);
251 par
->extradata_size
= size
;
256 /*******************************************************/
258 uint64_t ff_ntp_time(void)
260 return (av_gettime() / 1000) * 1000 + NTP_OFFSET_US
;
263 uint64_t ff_get_formatted_ntp_time(uint64_t ntp_time_us
)
265 uint64_t ntp_ts
, frac_part
, sec
;
268 //current ntp time in seconds and micro seconds
269 sec
= ntp_time_us
/ 1000000;
270 usec
= ntp_time_us
% 1000000;
272 //encoding in ntp timestamp format
273 frac_part
= usec
* 0xFFFFFFFFULL
;
274 frac_part
/= 1000000;
276 if (sec
> 0xFFFFFFFFULL
)
277 av_log(NULL
, AV_LOG_WARNING
, "NTP time format roll over detected\n");
285 uint64_t ff_parse_ntp_time(uint64_t ntp_ts
)
287 uint64_t sec
= ntp_ts
>> 32;
288 uint64_t frac_part
= ntp_ts
& 0xFFFFFFFFULL
;
289 uint64_t usec
= (frac_part
* 1000000) / 0xFFFFFFFFULL
;
291 return (sec
* 1000000) + usec
;
294 int av_get_frame_filename2(char *buf
, int buf_size
, const char *path
, int number
, int flags
)
297 char *q
, buf1
[20], c
;
298 int nd
, len
, percentd_found
;
310 while (av_isdigit(*p
)) {
311 if (nd
>= INT_MAX
/ 10 - 255)
313 nd
= nd
* 10 + *p
++ - '0';
316 } while (av_isdigit(c
));
322 if (!(flags
& AV_FRAME_FILENAME_FLAGS_MULTIPLE
) && percentd_found
)
327 snprintf(buf1
, sizeof(buf1
), "%0*d", nd
, number
);
329 if ((q
- buf
+ len
) > buf_size
- 1)
331 memcpy(q
, buf1
, len
);
339 if ((q
- buf
) < buf_size
- 1)
352 int av_get_frame_filename(char *buf
, int buf_size
, const char *path
, int number
)
354 return av_get_frame_filename2(buf
, buf_size
, path
, number
, 0);
357 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
)
362 const char *p
, *ls
, *at
, *at2
, *col
, *brk
;
368 if (authorization_size
> 0)
369 authorization
[0] = 0;
370 if (hostname_size
> 0)
376 if ((p
= strchr(url
, ':'))) {
377 av_strlcpy(proto
, url
, FFMIN(proto_size
, p
+ 1 - url
));
384 /* no protocol means plain filename */
385 av_strlcpy(path
, url
, path_size
);
389 /* separate path from hostname */
390 ls
= p
+ strcspn(p
, "/?#");
391 av_strlcpy(path
, ls
, path_size
);
393 /* the rest is hostname, use that to parse auth/port */
395 /* authorization (user[:pass]@hostname) */
397 while ((at
= strchr(p
, '@')) && at
< ls
) {
398 av_strlcpy(authorization
, at2
,
399 FFMIN(authorization_size
, at
+ 1 - at2
));
400 p
= at
+ 1; /* skip '@' */
403 if (*p
== '[' && (brk
= strchr(p
, ']')) && brk
< ls
) {
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 } else if ((col
= strchr(p
, ':')) && col
< ls
) {
410 av_strlcpy(hostname
, p
,
411 FFMIN(col
+ 1 - p
, hostname_size
));
413 *port_ptr
= atoi(col
+ 1);
415 av_strlcpy(hostname
, p
,
416 FFMIN(ls
+ 1 - p
, hostname_size
));
420 int ff_mkdir_p(const char *path
)
423 char *temp
= av_strdup(path
);
427 if (!path
|| !temp
) {
431 if (!av_strncasecmp(temp
, "/", 1) || !av_strncasecmp(temp
, "\\", 1)) {
433 } else if (!av_strncasecmp(temp
, "./", 2) || !av_strncasecmp(temp
, ".\\", 2)) {
437 for ( ; *pos
!= '\0'; ++pos
) {
438 if (*pos
== '/' || *pos
== '\\') {
441 ret
= mkdir(temp
, 0755);
446 if ((*(pos
- 1) != '/') && (*(pos
- 1) != '\\')) {
447 ret
= mkdir(temp
, 0755);
454 char *ff_data_to_hex(char *buff
, const uint8_t *src
, int s
, int lowercase
)
456 static const char hex_table_uc
[16] = { '0', '1', '2', '3',
459 'C', 'D', 'E', 'F' };
460 static const char hex_table_lc
[16] = { '0', '1', '2', '3',
463 'c', 'd', 'e', 'f' };
464 const char *hex_table
= lowercase
? hex_table_lc
: hex_table_uc
;
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];
475 int ff_hex_to_data(uint8_t *data
, const char *p
)
482 p
+= strspn(p
, SPACE_CHARS
);
485 c
= av_toupper((unsigned char) *p
++);
486 if (c
>= '0' && c
<= '9')
488 else if (c
>= 'A' && c
<= 'F')
503 void ff_parse_key_value(const char *str
, ff_parse_key_val_cb callback_get_buf
,
506 const char *ptr
= str
;
508 /* Parse key=value pairs. */
511 char *dest
= NULL
, *dest_end
;
512 int key_len
, dest_len
= 0;
514 /* Skip whitespace and potential commas. */
515 while (*ptr
&& (av_isspace(*ptr
) || *ptr
== ','))
522 if (!(ptr
= strchr(key
, '=')))
527 callback_get_buf(context
, key
, key_len
, &dest
, &dest_len
);
528 dest_end
= dest
? dest
+ dest_len
- 1 : NULL
;
532 while (*ptr
&& *ptr
!= '\"') {
536 if (dest
&& dest
< dest_end
)
540 if (dest
&& dest
< dest_end
)
548 for (; *ptr
&& !(av_isspace(*ptr
) || *ptr
== ','); ptr
++)
549 if (dest
&& dest
< dest_end
)
557 int avformat_network_init(void)
561 if ((ret
= ff_network_init()) < 0)
563 if ((ret
= ff_tls_init()) < 0)
569 int avformat_network_deinit(void)
578 int ff_is_http_proto(const char *filename
) {
579 const char *proto
= avio_find_protocol_name(filename
);
580 return proto
? (!av_strcasecmp(proto
, "http") || !av_strcasecmp(proto
, "https")) : 0;
583 int ff_bprint_to_codecpar_extradata(AVCodecParameters
*par
, struct AVBPrint
*buf
)
588 ret
= av_bprint_finalize(buf
, &str
);
591 if (!av_bprint_is_complete(buf
)) {
593 return AVERROR(ENOMEM
);
596 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
602 par
->extradata_size
= buf
->len
;