* commit 'df9f22d42b0905385629a9d368bb5a1eef2b45ef': avf: move url utility functions in a separate file Conflicts: libavformat/internal.h Merged-by: Michael Niedermayer <michaelni@gmx.at>tags/n2.0
| @@ -21,6 +21,7 @@ OBJS = allformats.o \ | |||
| riff.o \ | |||
| sdp.o \ | |||
| seek.o \ | |||
| url.o \ | |||
| utils.o \ | |||
| OBJS-$(CONFIG_NETWORK) += network.o | |||
| @@ -23,6 +23,7 @@ | |||
| #include "libavutil/parseutils.h" | |||
| #include "avformat.h" | |||
| #include "internal.h" | |||
| #include "url.h" | |||
| typedef struct { | |||
| char *url; | |||
| @@ -89,31 +89,6 @@ void ff_read_frame_flush(AVFormatContext *s); | |||
| /** Get the current time since NTP epoch in microseconds. */ | |||
| uint64_t ff_ntp_time(void); | |||
| /** | |||
| * Assemble a URL string from components. This is the reverse operation | |||
| * of av_url_split. | |||
| * | |||
| * Note, this requires networking to be initialized, so the caller must | |||
| * ensure ff_network_init has been called. | |||
| * | |||
| * @see av_url_split | |||
| * | |||
| * @param str the buffer to fill with the url | |||
| * @param size the size of the str buffer | |||
| * @param proto the protocol identifier, if null, the separator | |||
| * after the identifier is left out, too | |||
| * @param authorization an optional authorization string, may be null. | |||
| * An empty string is treated the same as a null string. | |||
| * @param hostname the host name string | |||
| * @param port the port number, left out from the string if negative | |||
| * @param fmt a generic format string for everything to add after the | |||
| * host/port, may be null | |||
| * @return the number of characters written to the destination buffer | |||
| */ | |||
| int ff_url_join(char *str, int size, const char *proto, | |||
| const char *authorization, const char *hostname, | |||
| int port, const char *fmt, ...) av_printf_format(7, 8); | |||
| /** | |||
| * Append the media-specific SDP fragment for the media stream c | |||
| * to the buffer buff. | |||
| @@ -240,17 +215,6 @@ AVChapter *avpriv_new_chapter(AVFormatContext *s, int id, AVRational time_base, | |||
| */ | |||
| void ff_reduce_index(AVFormatContext *s, int stream_index); | |||
| /** | |||
| * Convert a relative url into an absolute url, given a base url. | |||
| * | |||
| * @param buf the buffer where output absolute url is written | |||
| * @param size the size of buf | |||
| * @param base the base url, may be equal to buf. | |||
| * @param rel the new url, which is interpreted relative to base | |||
| */ | |||
| void ff_make_absolute_url(char *buf, int size, const char *base, | |||
| const char *rel); | |||
| enum AVCodecID ff_guess_image2_codec(const char *filename); | |||
| /** | |||
| @@ -18,7 +18,7 @@ | |||
| * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |||
| */ | |||
| #include "internal.h" | |||
| #include "url.h" | |||
| static void test(const char *base, const char *rel) | |||
| { | |||
| @@ -0,0 +1,147 @@ | |||
| /* | |||
| * URL utility functions | |||
| * Copyright (c) 2000, 2001, 2002 Fabrice Bellard | |||
| * | |||
| * This file is part of FFmpeg. | |||
| * | |||
| * FFmpeg is free software; you can redistribute it and/or | |||
| * modify it under the terms of the GNU Lesser General Public | |||
| * License as published by the Free Software Foundation; either | |||
| * version 2.1 of the License, or (at your option) any later version. | |||
| * | |||
| * FFmpeg is distributed in the hope that it will be useful, | |||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
| * Lesser General Public License for more details. | |||
| * | |||
| * You should have received a copy of the GNU Lesser General Public | |||
| * License along with FFmpeg; if not, write to the Free Software | |||
| * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |||
| */ | |||
| #include "avformat.h" | |||
| #include "config.h" | |||
| #include "url.h" | |||
| #if CONFIG_NETWORK | |||
| #include "network.h" | |||
| #endif | |||
| #include "libavutil/avstring.h" | |||
| /** | |||
| * @file | |||
| * URL utility functions. | |||
| */ | |||
| int ff_url_join(char *str, int size, const char *proto, | |||
| const char *authorization, const char *hostname, | |||
| int port, const char *fmt, ...) | |||
| { | |||
| #if CONFIG_NETWORK | |||
| struct addrinfo hints = { 0 }, *ai; | |||
| #endif | |||
| str[0] = '\0'; | |||
| if (proto) | |||
| av_strlcatf(str, size, "%s://", proto); | |||
| if (authorization && authorization[0]) | |||
| av_strlcatf(str, size, "%s@", authorization); | |||
| #if CONFIG_NETWORK && defined(AF_INET6) | |||
| /* Determine if hostname is a numerical IPv6 address, | |||
| * properly escape it within [] in that case. */ | |||
| hints.ai_flags = AI_NUMERICHOST; | |||
| if (!getaddrinfo(hostname, NULL, &hints, &ai)) { | |||
| if (ai->ai_family == AF_INET6) { | |||
| av_strlcat(str, "[", size); | |||
| av_strlcat(str, hostname, size); | |||
| av_strlcat(str, "]", size); | |||
| } else { | |||
| av_strlcat(str, hostname, size); | |||
| } | |||
| freeaddrinfo(ai); | |||
| } else | |||
| #endif | |||
| /* Not an IPv6 address, just output the plain string. */ | |||
| av_strlcat(str, hostname, size); | |||
| if (port >= 0) | |||
| av_strlcatf(str, size, ":%d", port); | |||
| if (fmt) { | |||
| va_list vl; | |||
| int len = strlen(str); | |||
| va_start(vl, fmt); | |||
| vsnprintf(str + len, size > len ? size - len : 0, fmt, vl); | |||
| va_end(vl); | |||
| } | |||
| return strlen(str); | |||
| } | |||
| void ff_make_absolute_url(char *buf, int size, const char *base, | |||
| const char *rel) | |||
| { | |||
| char *sep, *path_query; | |||
| /* Absolute path, relative to the current server */ | |||
| if (base && strstr(base, "://") && rel[0] == '/') { | |||
| if (base != buf) | |||
| av_strlcpy(buf, base, size); | |||
| sep = strstr(buf, "://"); | |||
| if (sep) { | |||
| /* Take scheme from base url */ | |||
| if (rel[1] == '/') { | |||
| sep[1] = '\0'; | |||
| } else { | |||
| /* Take scheme and host from base url */ | |||
| sep += 3; | |||
| sep = strchr(sep, '/'); | |||
| if (sep) | |||
| *sep = '\0'; | |||
| } | |||
| } | |||
| av_strlcat(buf, rel, size); | |||
| return; | |||
| } | |||
| /* If rel actually is an absolute url, just copy it */ | |||
| if (!base || strstr(rel, "://") || rel[0] == '/') { | |||
| av_strlcpy(buf, rel, size); | |||
| return; | |||
| } | |||
| if (base != buf) | |||
| av_strlcpy(buf, base, size); | |||
| /* Strip off any query string from base */ | |||
| path_query = strchr(buf, '?'); | |||
| if (path_query != NULL) | |||
| *path_query = '\0'; | |||
| /* Is relative path just a new query part? */ | |||
| if (rel[0] == '?') { | |||
| av_strlcat(buf, rel, size); | |||
| return; | |||
| } | |||
| /* Remove the file name from the base url */ | |||
| sep = strrchr(buf, '/'); | |||
| if (sep) | |||
| sep[1] = '\0'; | |||
| else | |||
| buf[0] = '\0'; | |||
| while (av_strstart(rel, "../", NULL) && sep) { | |||
| /* Remove the path delimiter at the end */ | |||
| sep[0] = '\0'; | |||
| sep = strrchr(buf, '/'); | |||
| /* If the next directory name to pop off is "..", break here */ | |||
| if (!strcmp(sep ? &sep[1] : buf, "..")) { | |||
| /* Readd the slash we just removed */ | |||
| av_strlcat(buf, "/", size); | |||
| break; | |||
| } | |||
| /* Cut off the directory name */ | |||
| if (sep) | |||
| sep[1] = '\0'; | |||
| else | |||
| buf[0] = '\0'; | |||
| rel += 3; | |||
| } | |||
| av_strlcat(buf, rel, size); | |||
| } | |||
| @@ -248,4 +248,41 @@ URLProtocol *ffurl_protocol_next(URLProtocol *prev); | |||
| int ff_udp_set_remote_url(URLContext *h, const char *uri); | |||
| int ff_udp_get_local_port(URLContext *h); | |||
| /** | |||
| * Assemble a URL string from components. This is the reverse operation | |||
| * of av_url_split. | |||
| * | |||
| * Note, this requires networking to be initialized, so the caller must | |||
| * ensure ff_network_init has been called. | |||
| * | |||
| * @see av_url_split | |||
| * | |||
| * @param str the buffer to fill with the url | |||
| * @param size the size of the str buffer | |||
| * @param proto the protocol identifier, if null, the separator | |||
| * after the identifier is left out, too | |||
| * @param authorization an optional authorization string, may be null. | |||
| * An empty string is treated the same as a null string. | |||
| * @param hostname the host name string | |||
| * @param port the port number, left out from the string if negative | |||
| * @param fmt a generic format string for everything to add after the | |||
| * host/port, may be null | |||
| * @return the number of characters written to the destination buffer | |||
| */ | |||
| int ff_url_join(char *str, int size, const char *proto, | |||
| const char *authorization, const char *hostname, | |||
| int port, const char *fmt, ...) av_printf_format(7, 8); | |||
| /** | |||
| * Convert a relative url into an absolute url, given a base url. | |||
| * | |||
| * @param buf the buffer where output absolute url is written | |||
| * @param size the size of buf | |||
| * @param base the base url, may be equal to buf. | |||
| * @param rel the new url, which is interpreted relative to base | |||
| */ | |||
| void ff_make_absolute_url(char *buf, int size, const char *base, | |||
| const char *rel); | |||
| #endif /* AVFORMAT_URL_H */ | |||
| @@ -3840,50 +3840,6 @@ void avpriv_set_pts_info(AVStream *s, int pts_wrap_bits, | |||
| s->pts_wrap_bits = pts_wrap_bits; | |||
| } | |||
| int ff_url_join(char *str, int size, const char *proto, | |||
| const char *authorization, const char *hostname, | |||
| int port, const char *fmt, ...) | |||
| { | |||
| #if CONFIG_NETWORK | |||
| struct addrinfo hints = { 0 }, *ai; | |||
| #endif | |||
| str[0] = '\0'; | |||
| if (proto) | |||
| av_strlcatf(str, size, "%s://", proto); | |||
| if (authorization && authorization[0]) | |||
| av_strlcatf(str, size, "%s@", authorization); | |||
| #if CONFIG_NETWORK && defined(AF_INET6) | |||
| /* Determine if hostname is a numerical IPv6 address, | |||
| * properly escape it within [] in that case. */ | |||
| hints.ai_flags = AI_NUMERICHOST; | |||
| if (!getaddrinfo(hostname, NULL, &hints, &ai)) { | |||
| if (ai->ai_family == AF_INET6) { | |||
| av_strlcat(str, "[", size); | |||
| av_strlcat(str, hostname, size); | |||
| av_strlcat(str, "]", size); | |||
| } else { | |||
| av_strlcat(str, hostname, size); | |||
| } | |||
| freeaddrinfo(ai); | |||
| } else | |||
| #endif | |||
| /* Not an IPv6 address, just output the plain string. */ | |||
| av_strlcat(str, hostname, size); | |||
| if (port >= 0) | |||
| av_strlcatf(str, size, ":%d", port); | |||
| if (fmt) { | |||
| va_list vl; | |||
| int len = strlen(str); | |||
| va_start(vl, fmt); | |||
| vsnprintf(str + len, size > len ? size - len : 0, fmt, vl); | |||
| va_end(vl); | |||
| } | |||
| return strlen(str); | |||
| } | |||
| void ff_parse_key_value(const char *str, ff_parse_key_val_cb callback_get_buf, | |||
| void *context) | |||
| { | |||
| @@ -3948,75 +3904,6 @@ int ff_find_stream_index(AVFormatContext *s, int id) | |||
| return -1; | |||
| } | |||
| void ff_make_absolute_url(char *buf, int size, const char *base, | |||
| const char *rel) | |||
| { | |||
| char *sep, *path_query; | |||
| /* Absolute path, relative to the current server */ | |||
| if (base && strstr(base, "://") && rel[0] == '/') { | |||
| if (base != buf) | |||
| av_strlcpy(buf, base, size); | |||
| sep = strstr(buf, "://"); | |||
| if (sep) { | |||
| /* Take scheme from base url */ | |||
| if (rel[1] == '/') { | |||
| sep[1] = '\0'; | |||
| } else { | |||
| /* Take scheme and host from base url */ | |||
| sep += 3; | |||
| sep = strchr(sep, '/'); | |||
| if (sep) | |||
| *sep = '\0'; | |||
| } | |||
| } | |||
| av_strlcat(buf, rel, size); | |||
| return; | |||
| } | |||
| /* If rel actually is an absolute url, just copy it */ | |||
| if (!base || strstr(rel, "://") || rel[0] == '/') { | |||
| av_strlcpy(buf, rel, size); | |||
| return; | |||
| } | |||
| if (base != buf) | |||
| av_strlcpy(buf, base, size); | |||
| /* Strip off any query string from base */ | |||
| path_query = strchr(buf, '?'); | |||
| if (path_query != NULL) | |||
| *path_query = '\0'; | |||
| /* Is relative path just a new query part? */ | |||
| if (rel[0] == '?') { | |||
| av_strlcat(buf, rel, size); | |||
| return; | |||
| } | |||
| /* Remove the file name from the base url */ | |||
| sep = strrchr(buf, '/'); | |||
| if (sep) | |||
| sep[1] = '\0'; | |||
| else | |||
| buf[0] = '\0'; | |||
| while (av_strstart(rel, "../", NULL) && sep) { | |||
| /* Remove the path delimiter at the end */ | |||
| sep[0] = '\0'; | |||
| sep = strrchr(buf, '/'); | |||
| /* If the next directory name to pop off is "..", break here */ | |||
| if (!strcmp(sep ? &sep[1] : buf, "..")) { | |||
| /* Readd the slash we just removed */ | |||
| av_strlcat(buf, "/", size); | |||
| break; | |||
| } | |||
| /* Cut off the directory name */ | |||
| if (sep) | |||
| sep[1] = '\0'; | |||
| else | |||
| buf[0] = '\0'; | |||
| rel += 3; | |||
| } | |||
| av_strlcat(buf, rel, size); | |||
| } | |||
| int64_t ff_iso8601_to_unix_time(const char *datestr) | |||
| { | |||
| struct tm time1 = {0}, time2 = {0}; | |||