1cabdff1aSopenharmony_ci/* 2cabdff1aSopenharmony_ci * various utility functions for use within FFmpeg 3cabdff1aSopenharmony_ci * Copyright (c) 2000, 2001, 2002 Fabrice Bellard 4cabdff1aSopenharmony_ci * 5cabdff1aSopenharmony_ci * This file is part of FFmpeg. 6cabdff1aSopenharmony_ci * 7cabdff1aSopenharmony_ci * FFmpeg is free software; you can redistribute it and/or 8cabdff1aSopenharmony_ci * modify it under the terms of the GNU Lesser General Public 9cabdff1aSopenharmony_ci * License as published by the Free Software Foundation; either 10cabdff1aSopenharmony_ci * version 2.1 of the License, or (at your option) any later version. 11cabdff1aSopenharmony_ci * 12cabdff1aSopenharmony_ci * FFmpeg is distributed in the hope that it will be useful, 13cabdff1aSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of 14cabdff1aSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15cabdff1aSopenharmony_ci * Lesser General Public License for more details. 16cabdff1aSopenharmony_ci * 17cabdff1aSopenharmony_ci * You should have received a copy of the GNU Lesser General Public 18cabdff1aSopenharmony_ci * License along with FFmpeg; if not, write to the Free Software 19cabdff1aSopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20cabdff1aSopenharmony_ci */ 21cabdff1aSopenharmony_ci 22cabdff1aSopenharmony_ci#include <stdint.h> 23cabdff1aSopenharmony_ci 24cabdff1aSopenharmony_ci#include "config.h" 25cabdff1aSopenharmony_ci 26cabdff1aSopenharmony_ci#include "libavutil/avstring.h" 27cabdff1aSopenharmony_ci#include "libavutil/bprint.h" 28cabdff1aSopenharmony_ci#include "libavutil/internal.h" 29cabdff1aSopenharmony_ci#include "libavutil/thread.h" 30cabdff1aSopenharmony_ci#include "libavutil/time.h" 31cabdff1aSopenharmony_ci 32cabdff1aSopenharmony_ci#include "libavcodec/internal.h" 33cabdff1aSopenharmony_ci 34cabdff1aSopenharmony_ci#include "avformat.h" 35cabdff1aSopenharmony_ci#include "avio_internal.h" 36cabdff1aSopenharmony_ci#include "internal.h" 37cabdff1aSopenharmony_ci#if CONFIG_NETWORK 38cabdff1aSopenharmony_ci#include "network.h" 39cabdff1aSopenharmony_ci#endif 40cabdff1aSopenharmony_ci 41cabdff1aSopenharmony_cistatic AVMutex avformat_mutex = AV_MUTEX_INITIALIZER; 42cabdff1aSopenharmony_ci 43cabdff1aSopenharmony_ci/** 44cabdff1aSopenharmony_ci * @file 45cabdff1aSopenharmony_ci * various utility functions for use within FFmpeg 46cabdff1aSopenharmony_ci */ 47cabdff1aSopenharmony_ci 48cabdff1aSopenharmony_ciint ff_lock_avformat(void) 49cabdff1aSopenharmony_ci{ 50cabdff1aSopenharmony_ci return ff_mutex_lock(&avformat_mutex) ? -1 : 0; 51cabdff1aSopenharmony_ci} 52cabdff1aSopenharmony_ci 53cabdff1aSopenharmony_ciint ff_unlock_avformat(void) 54cabdff1aSopenharmony_ci{ 55cabdff1aSopenharmony_ci return ff_mutex_unlock(&avformat_mutex) ? -1 : 0; 56cabdff1aSopenharmony_ci} 57cabdff1aSopenharmony_ci 58cabdff1aSopenharmony_ci/* an arbitrarily chosen "sane" max packet size -- 50M */ 59cabdff1aSopenharmony_ci#define SANE_CHUNK_SIZE (50000000) 60cabdff1aSopenharmony_ci 61cabdff1aSopenharmony_ci/* Read the data in sane-sized chunks and append to pkt. 62cabdff1aSopenharmony_ci * Return the number of bytes read or an error. */ 63cabdff1aSopenharmony_cistatic int append_packet_chunked(AVIOContext *s, AVPacket *pkt, int size) 64cabdff1aSopenharmony_ci{ 65cabdff1aSopenharmony_ci int orig_size = pkt->size; 66cabdff1aSopenharmony_ci int ret; 67cabdff1aSopenharmony_ci 68cabdff1aSopenharmony_ci do { 69cabdff1aSopenharmony_ci int prev_size = pkt->size; 70cabdff1aSopenharmony_ci int read_size; 71cabdff1aSopenharmony_ci 72cabdff1aSopenharmony_ci /* When the caller requests a lot of data, limit it to the amount 73cabdff1aSopenharmony_ci * left in file or SANE_CHUNK_SIZE when it is not known. */ 74cabdff1aSopenharmony_ci read_size = size; 75cabdff1aSopenharmony_ci if (read_size > SANE_CHUNK_SIZE/10) { 76cabdff1aSopenharmony_ci read_size = ffio_limit(s, read_size); 77cabdff1aSopenharmony_ci // If filesize/maxsize is unknown, limit to SANE_CHUNK_SIZE 78cabdff1aSopenharmony_ci if (ffiocontext(s)->maxsize < 0) 79cabdff1aSopenharmony_ci read_size = FFMIN(read_size, SANE_CHUNK_SIZE); 80cabdff1aSopenharmony_ci } 81cabdff1aSopenharmony_ci 82cabdff1aSopenharmony_ci ret = av_grow_packet(pkt, read_size); 83cabdff1aSopenharmony_ci if (ret < 0) 84cabdff1aSopenharmony_ci break; 85cabdff1aSopenharmony_ci 86cabdff1aSopenharmony_ci ret = avio_read(s, pkt->data + prev_size, read_size); 87cabdff1aSopenharmony_ci if (ret != read_size) { 88cabdff1aSopenharmony_ci av_shrink_packet(pkt, prev_size + FFMAX(ret, 0)); 89cabdff1aSopenharmony_ci break; 90cabdff1aSopenharmony_ci } 91cabdff1aSopenharmony_ci 92cabdff1aSopenharmony_ci size -= read_size; 93cabdff1aSopenharmony_ci } while (size > 0); 94cabdff1aSopenharmony_ci if (size > 0) 95cabdff1aSopenharmony_ci pkt->flags |= AV_PKT_FLAG_CORRUPT; 96cabdff1aSopenharmony_ci 97cabdff1aSopenharmony_ci if (!pkt->size) 98cabdff1aSopenharmony_ci av_packet_unref(pkt); 99cabdff1aSopenharmony_ci return pkt->size > orig_size ? pkt->size - orig_size : ret; 100cabdff1aSopenharmony_ci} 101cabdff1aSopenharmony_ci 102cabdff1aSopenharmony_ciint av_get_packet(AVIOContext *s, AVPacket *pkt, int size) 103cabdff1aSopenharmony_ci{ 104cabdff1aSopenharmony_ci#if FF_API_INIT_PACKET 105cabdff1aSopenharmony_ciFF_DISABLE_DEPRECATION_WARNINGS 106cabdff1aSopenharmony_ci av_init_packet(pkt); 107cabdff1aSopenharmony_ci pkt->data = NULL; 108cabdff1aSopenharmony_ci pkt->size = 0; 109cabdff1aSopenharmony_ciFF_ENABLE_DEPRECATION_WARNINGS 110cabdff1aSopenharmony_ci#else 111cabdff1aSopenharmony_ci av_packet_unref(pkt); 112cabdff1aSopenharmony_ci#endif 113cabdff1aSopenharmony_ci pkt->pos = avio_tell(s); 114cabdff1aSopenharmony_ci 115cabdff1aSopenharmony_ci return append_packet_chunked(s, pkt, size); 116cabdff1aSopenharmony_ci} 117cabdff1aSopenharmony_ci 118cabdff1aSopenharmony_ciint av_append_packet(AVIOContext *s, AVPacket *pkt, int size) 119cabdff1aSopenharmony_ci{ 120cabdff1aSopenharmony_ci if (!pkt->size) 121cabdff1aSopenharmony_ci return av_get_packet(s, pkt, size); 122cabdff1aSopenharmony_ci return append_packet_chunked(s, pkt, size); 123cabdff1aSopenharmony_ci} 124cabdff1aSopenharmony_ci 125cabdff1aSopenharmony_ciint av_filename_number_test(const char *filename) 126cabdff1aSopenharmony_ci{ 127cabdff1aSopenharmony_ci char buf[1024]; 128cabdff1aSopenharmony_ci return filename && 129cabdff1aSopenharmony_ci (av_get_frame_filename(buf, sizeof(buf), filename, 1) >= 0); 130cabdff1aSopenharmony_ci} 131cabdff1aSopenharmony_ci 132cabdff1aSopenharmony_ci/**********************************************************/ 133cabdff1aSopenharmony_ci 134cabdff1aSopenharmony_ciunsigned int ff_codec_get_tag(const AVCodecTag *tags, enum AVCodecID id) 135cabdff1aSopenharmony_ci{ 136cabdff1aSopenharmony_ci while (tags->id != AV_CODEC_ID_NONE) { 137cabdff1aSopenharmony_ci if (tags->id == id) 138cabdff1aSopenharmony_ci return tags->tag; 139cabdff1aSopenharmony_ci tags++; 140cabdff1aSopenharmony_ci } 141cabdff1aSopenharmony_ci return 0; 142cabdff1aSopenharmony_ci} 143cabdff1aSopenharmony_ci 144cabdff1aSopenharmony_cienum AVCodecID ff_codec_get_id(const AVCodecTag *tags, unsigned int tag) 145cabdff1aSopenharmony_ci{ 146cabdff1aSopenharmony_ci for (int i = 0; tags[i].id != AV_CODEC_ID_NONE; i++) 147cabdff1aSopenharmony_ci if (tag == tags[i].tag) 148cabdff1aSopenharmony_ci return tags[i].id; 149cabdff1aSopenharmony_ci for (int i = 0; tags[i].id != AV_CODEC_ID_NONE; i++) 150cabdff1aSopenharmony_ci if (ff_toupper4(tag) == ff_toupper4(tags[i].tag)) 151cabdff1aSopenharmony_ci return tags[i].id; 152cabdff1aSopenharmony_ci return AV_CODEC_ID_NONE; 153cabdff1aSopenharmony_ci} 154cabdff1aSopenharmony_ci 155cabdff1aSopenharmony_cienum AVCodecID ff_get_pcm_codec_id(int bps, int flt, int be, int sflags) 156cabdff1aSopenharmony_ci{ 157cabdff1aSopenharmony_ci if (bps <= 0 || bps > 64) 158cabdff1aSopenharmony_ci return AV_CODEC_ID_NONE; 159cabdff1aSopenharmony_ci 160cabdff1aSopenharmony_ci if (flt) { 161cabdff1aSopenharmony_ci switch (bps) { 162cabdff1aSopenharmony_ci case 32: 163cabdff1aSopenharmony_ci return be ? AV_CODEC_ID_PCM_F32BE : AV_CODEC_ID_PCM_F32LE; 164cabdff1aSopenharmony_ci case 64: 165cabdff1aSopenharmony_ci return be ? AV_CODEC_ID_PCM_F64BE : AV_CODEC_ID_PCM_F64LE; 166cabdff1aSopenharmony_ci default: 167cabdff1aSopenharmony_ci return AV_CODEC_ID_NONE; 168cabdff1aSopenharmony_ci } 169cabdff1aSopenharmony_ci } else { 170cabdff1aSopenharmony_ci bps += 7; 171cabdff1aSopenharmony_ci bps >>= 3; 172cabdff1aSopenharmony_ci if (sflags & (1 << (bps - 1))) { 173cabdff1aSopenharmony_ci switch (bps) { 174cabdff1aSopenharmony_ci case 1: 175cabdff1aSopenharmony_ci return AV_CODEC_ID_PCM_S8; 176cabdff1aSopenharmony_ci case 2: 177cabdff1aSopenharmony_ci return be ? AV_CODEC_ID_PCM_S16BE : AV_CODEC_ID_PCM_S16LE; 178cabdff1aSopenharmony_ci case 3: 179cabdff1aSopenharmony_ci return be ? AV_CODEC_ID_PCM_S24BE : AV_CODEC_ID_PCM_S24LE; 180cabdff1aSopenharmony_ci case 4: 181cabdff1aSopenharmony_ci return be ? AV_CODEC_ID_PCM_S32BE : AV_CODEC_ID_PCM_S32LE; 182cabdff1aSopenharmony_ci case 8: 183cabdff1aSopenharmony_ci return be ? AV_CODEC_ID_PCM_S64BE : AV_CODEC_ID_PCM_S64LE; 184cabdff1aSopenharmony_ci default: 185cabdff1aSopenharmony_ci return AV_CODEC_ID_NONE; 186cabdff1aSopenharmony_ci } 187cabdff1aSopenharmony_ci } else { 188cabdff1aSopenharmony_ci switch (bps) { 189cabdff1aSopenharmony_ci case 1: 190cabdff1aSopenharmony_ci return AV_CODEC_ID_PCM_U8; 191cabdff1aSopenharmony_ci case 2: 192cabdff1aSopenharmony_ci return be ? AV_CODEC_ID_PCM_U16BE : AV_CODEC_ID_PCM_U16LE; 193cabdff1aSopenharmony_ci case 3: 194cabdff1aSopenharmony_ci return be ? AV_CODEC_ID_PCM_U24BE : AV_CODEC_ID_PCM_U24LE; 195cabdff1aSopenharmony_ci case 4: 196cabdff1aSopenharmony_ci return be ? AV_CODEC_ID_PCM_U32BE : AV_CODEC_ID_PCM_U32LE; 197cabdff1aSopenharmony_ci default: 198cabdff1aSopenharmony_ci return AV_CODEC_ID_NONE; 199cabdff1aSopenharmony_ci } 200cabdff1aSopenharmony_ci } 201cabdff1aSopenharmony_ci } 202cabdff1aSopenharmony_ci} 203cabdff1aSopenharmony_ci 204cabdff1aSopenharmony_ciunsigned int av_codec_get_tag(const AVCodecTag *const *tags, enum AVCodecID id) 205cabdff1aSopenharmony_ci{ 206cabdff1aSopenharmony_ci unsigned int tag; 207cabdff1aSopenharmony_ci if (!av_codec_get_tag2(tags, id, &tag)) 208cabdff1aSopenharmony_ci return 0; 209cabdff1aSopenharmony_ci return tag; 210cabdff1aSopenharmony_ci} 211cabdff1aSopenharmony_ci 212cabdff1aSopenharmony_ciint av_codec_get_tag2(const AVCodecTag * const *tags, enum AVCodecID id, 213cabdff1aSopenharmony_ci unsigned int *tag) 214cabdff1aSopenharmony_ci{ 215cabdff1aSopenharmony_ci for (int i = 0; tags && tags[i]; i++) { 216cabdff1aSopenharmony_ci const AVCodecTag *codec_tags = tags[i]; 217cabdff1aSopenharmony_ci while (codec_tags->id != AV_CODEC_ID_NONE) { 218cabdff1aSopenharmony_ci if (codec_tags->id == id) { 219cabdff1aSopenharmony_ci *tag = codec_tags->tag; 220cabdff1aSopenharmony_ci return 1; 221cabdff1aSopenharmony_ci } 222cabdff1aSopenharmony_ci codec_tags++; 223cabdff1aSopenharmony_ci } 224cabdff1aSopenharmony_ci } 225cabdff1aSopenharmony_ci return 0; 226cabdff1aSopenharmony_ci} 227cabdff1aSopenharmony_ci 228cabdff1aSopenharmony_cienum AVCodecID av_codec_get_id(const AVCodecTag *const *tags, unsigned int tag) 229cabdff1aSopenharmony_ci{ 230cabdff1aSopenharmony_ci for (int i = 0; tags && tags[i]; i++) { 231cabdff1aSopenharmony_ci enum AVCodecID id = ff_codec_get_id(tags[i], tag); 232cabdff1aSopenharmony_ci if (id != AV_CODEC_ID_NONE) 233cabdff1aSopenharmony_ci return id; 234cabdff1aSopenharmony_ci } 235cabdff1aSopenharmony_ci return AV_CODEC_ID_NONE; 236cabdff1aSopenharmony_ci} 237cabdff1aSopenharmony_ci 238cabdff1aSopenharmony_ciint ff_alloc_extradata(AVCodecParameters *par, int size) 239cabdff1aSopenharmony_ci{ 240cabdff1aSopenharmony_ci av_freep(&par->extradata); 241cabdff1aSopenharmony_ci par->extradata_size = 0; 242cabdff1aSopenharmony_ci 243cabdff1aSopenharmony_ci if (size < 0 || size >= INT32_MAX - AV_INPUT_BUFFER_PADDING_SIZE) 244cabdff1aSopenharmony_ci return AVERROR(EINVAL); 245cabdff1aSopenharmony_ci 246cabdff1aSopenharmony_ci par->extradata = av_malloc(size + AV_INPUT_BUFFER_PADDING_SIZE); 247cabdff1aSopenharmony_ci if (!par->extradata) 248cabdff1aSopenharmony_ci return AVERROR(ENOMEM); 249cabdff1aSopenharmony_ci 250cabdff1aSopenharmony_ci memset(par->extradata + size, 0, AV_INPUT_BUFFER_PADDING_SIZE); 251cabdff1aSopenharmony_ci par->extradata_size = size; 252cabdff1aSopenharmony_ci 253cabdff1aSopenharmony_ci return 0; 254cabdff1aSopenharmony_ci} 255cabdff1aSopenharmony_ci 256cabdff1aSopenharmony_ci/*******************************************************/ 257cabdff1aSopenharmony_ci 258cabdff1aSopenharmony_ciuint64_t ff_ntp_time(void) 259cabdff1aSopenharmony_ci{ 260cabdff1aSopenharmony_ci return (av_gettime() / 1000) * 1000 + NTP_OFFSET_US; 261cabdff1aSopenharmony_ci} 262cabdff1aSopenharmony_ci 263cabdff1aSopenharmony_ciuint64_t ff_get_formatted_ntp_time(uint64_t ntp_time_us) 264cabdff1aSopenharmony_ci{ 265cabdff1aSopenharmony_ci uint64_t ntp_ts, frac_part, sec; 266cabdff1aSopenharmony_ci uint32_t usec; 267cabdff1aSopenharmony_ci 268cabdff1aSopenharmony_ci //current ntp time in seconds and micro seconds 269cabdff1aSopenharmony_ci sec = ntp_time_us / 1000000; 270cabdff1aSopenharmony_ci usec = ntp_time_us % 1000000; 271cabdff1aSopenharmony_ci 272cabdff1aSopenharmony_ci //encoding in ntp timestamp format 273cabdff1aSopenharmony_ci frac_part = usec * 0xFFFFFFFFULL; 274cabdff1aSopenharmony_ci frac_part /= 1000000; 275cabdff1aSopenharmony_ci 276cabdff1aSopenharmony_ci if (sec > 0xFFFFFFFFULL) 277cabdff1aSopenharmony_ci av_log(NULL, AV_LOG_WARNING, "NTP time format roll over detected\n"); 278cabdff1aSopenharmony_ci 279cabdff1aSopenharmony_ci ntp_ts = sec << 32; 280cabdff1aSopenharmony_ci ntp_ts |= frac_part; 281cabdff1aSopenharmony_ci 282cabdff1aSopenharmony_ci return ntp_ts; 283cabdff1aSopenharmony_ci} 284cabdff1aSopenharmony_ci 285cabdff1aSopenharmony_ciuint64_t ff_parse_ntp_time(uint64_t ntp_ts) 286cabdff1aSopenharmony_ci{ 287cabdff1aSopenharmony_ci uint64_t sec = ntp_ts >> 32; 288cabdff1aSopenharmony_ci uint64_t frac_part = ntp_ts & 0xFFFFFFFFULL; 289cabdff1aSopenharmony_ci uint64_t usec = (frac_part * 1000000) / 0xFFFFFFFFULL; 290cabdff1aSopenharmony_ci 291cabdff1aSopenharmony_ci return (sec * 1000000) + usec; 292cabdff1aSopenharmony_ci} 293cabdff1aSopenharmony_ci 294cabdff1aSopenharmony_ciint av_get_frame_filename2(char *buf, int buf_size, const char *path, int number, int flags) 295cabdff1aSopenharmony_ci{ 296cabdff1aSopenharmony_ci const char *p; 297cabdff1aSopenharmony_ci char *q, buf1[20], c; 298cabdff1aSopenharmony_ci int nd, len, percentd_found; 299cabdff1aSopenharmony_ci 300cabdff1aSopenharmony_ci q = buf; 301cabdff1aSopenharmony_ci p = path; 302cabdff1aSopenharmony_ci percentd_found = 0; 303cabdff1aSopenharmony_ci for (;;) { 304cabdff1aSopenharmony_ci c = *p++; 305cabdff1aSopenharmony_ci if (c == '\0') 306cabdff1aSopenharmony_ci break; 307cabdff1aSopenharmony_ci if (c == '%') { 308cabdff1aSopenharmony_ci do { 309cabdff1aSopenharmony_ci nd = 0; 310cabdff1aSopenharmony_ci while (av_isdigit(*p)) { 311cabdff1aSopenharmony_ci if (nd >= INT_MAX / 10 - 255) 312cabdff1aSopenharmony_ci goto fail; 313cabdff1aSopenharmony_ci nd = nd * 10 + *p++ - '0'; 314cabdff1aSopenharmony_ci } 315cabdff1aSopenharmony_ci c = *p++; 316cabdff1aSopenharmony_ci } while (av_isdigit(c)); 317cabdff1aSopenharmony_ci 318cabdff1aSopenharmony_ci switch (c) { 319cabdff1aSopenharmony_ci case '%': 320cabdff1aSopenharmony_ci goto addchar; 321cabdff1aSopenharmony_ci case 'd': 322cabdff1aSopenharmony_ci if (!(flags & AV_FRAME_FILENAME_FLAGS_MULTIPLE) && percentd_found) 323cabdff1aSopenharmony_ci goto fail; 324cabdff1aSopenharmony_ci percentd_found = 1; 325cabdff1aSopenharmony_ci if (number < 0) 326cabdff1aSopenharmony_ci nd += 1; 327cabdff1aSopenharmony_ci snprintf(buf1, sizeof(buf1), "%0*d", nd, number); 328cabdff1aSopenharmony_ci len = strlen(buf1); 329cabdff1aSopenharmony_ci if ((q - buf + len) > buf_size - 1) 330cabdff1aSopenharmony_ci goto fail; 331cabdff1aSopenharmony_ci memcpy(q, buf1, len); 332cabdff1aSopenharmony_ci q += len; 333cabdff1aSopenharmony_ci break; 334cabdff1aSopenharmony_ci default: 335cabdff1aSopenharmony_ci goto fail; 336cabdff1aSopenharmony_ci } 337cabdff1aSopenharmony_ci } else { 338cabdff1aSopenharmony_ciaddchar: 339cabdff1aSopenharmony_ci if ((q - buf) < buf_size - 1) 340cabdff1aSopenharmony_ci *q++ = c; 341cabdff1aSopenharmony_ci } 342cabdff1aSopenharmony_ci } 343cabdff1aSopenharmony_ci if (!percentd_found) 344cabdff1aSopenharmony_ci goto fail; 345cabdff1aSopenharmony_ci *q = '\0'; 346cabdff1aSopenharmony_ci return 0; 347cabdff1aSopenharmony_cifail: 348cabdff1aSopenharmony_ci *q = '\0'; 349cabdff1aSopenharmony_ci return -1; 350cabdff1aSopenharmony_ci} 351cabdff1aSopenharmony_ci 352cabdff1aSopenharmony_ciint av_get_frame_filename(char *buf, int buf_size, const char *path, int number) 353cabdff1aSopenharmony_ci{ 354cabdff1aSopenharmony_ci return av_get_frame_filename2(buf, buf_size, path, number, 0); 355cabdff1aSopenharmony_ci} 356cabdff1aSopenharmony_ci 357cabdff1aSopenharmony_civoid av_url_split(char *proto, int proto_size, 358cabdff1aSopenharmony_ci char *authorization, int authorization_size, 359cabdff1aSopenharmony_ci char *hostname, int hostname_size, 360cabdff1aSopenharmony_ci int *port_ptr, char *path, int path_size, const char *url) 361cabdff1aSopenharmony_ci{ 362cabdff1aSopenharmony_ci const char *p, *ls, *at, *at2, *col, *brk; 363cabdff1aSopenharmony_ci 364cabdff1aSopenharmony_ci if (port_ptr) 365cabdff1aSopenharmony_ci *port_ptr = -1; 366cabdff1aSopenharmony_ci if (proto_size > 0) 367cabdff1aSopenharmony_ci proto[0] = 0; 368cabdff1aSopenharmony_ci if (authorization_size > 0) 369cabdff1aSopenharmony_ci authorization[0] = 0; 370cabdff1aSopenharmony_ci if (hostname_size > 0) 371cabdff1aSopenharmony_ci hostname[0] = 0; 372cabdff1aSopenharmony_ci if (path_size > 0) 373cabdff1aSopenharmony_ci path[0] = 0; 374cabdff1aSopenharmony_ci 375cabdff1aSopenharmony_ci /* parse protocol */ 376cabdff1aSopenharmony_ci if ((p = strchr(url, ':'))) { 377cabdff1aSopenharmony_ci av_strlcpy(proto, url, FFMIN(proto_size, p + 1 - url)); 378cabdff1aSopenharmony_ci p++; /* skip ':' */ 379cabdff1aSopenharmony_ci if (*p == '/') 380cabdff1aSopenharmony_ci p++; 381cabdff1aSopenharmony_ci if (*p == '/') 382cabdff1aSopenharmony_ci p++; 383cabdff1aSopenharmony_ci } else { 384cabdff1aSopenharmony_ci /* no protocol means plain filename */ 385cabdff1aSopenharmony_ci av_strlcpy(path, url, path_size); 386cabdff1aSopenharmony_ci return; 387cabdff1aSopenharmony_ci } 388cabdff1aSopenharmony_ci 389cabdff1aSopenharmony_ci /* separate path from hostname */ 390cabdff1aSopenharmony_ci ls = p + strcspn(p, "/?#"); 391cabdff1aSopenharmony_ci av_strlcpy(path, ls, path_size); 392cabdff1aSopenharmony_ci 393cabdff1aSopenharmony_ci /* the rest is hostname, use that to parse auth/port */ 394cabdff1aSopenharmony_ci if (ls != p) { 395cabdff1aSopenharmony_ci /* authorization (user[:pass]@hostname) */ 396cabdff1aSopenharmony_ci at2 = p; 397cabdff1aSopenharmony_ci while ((at = strchr(p, '@')) && at < ls) { 398cabdff1aSopenharmony_ci av_strlcpy(authorization, at2, 399cabdff1aSopenharmony_ci FFMIN(authorization_size, at + 1 - at2)); 400cabdff1aSopenharmony_ci p = at + 1; /* skip '@' */ 401cabdff1aSopenharmony_ci } 402cabdff1aSopenharmony_ci 403cabdff1aSopenharmony_ci if (*p == '[' && (brk = strchr(p, ']')) && brk < ls) { 404cabdff1aSopenharmony_ci /* [host]:port */ 405cabdff1aSopenharmony_ci av_strlcpy(hostname, p + 1, 406cabdff1aSopenharmony_ci FFMIN(hostname_size, brk - p)); 407cabdff1aSopenharmony_ci if (brk[1] == ':' && port_ptr) 408cabdff1aSopenharmony_ci *port_ptr = atoi(brk + 2); 409cabdff1aSopenharmony_ci } else if ((col = strchr(p, ':')) && col < ls) { 410cabdff1aSopenharmony_ci av_strlcpy(hostname, p, 411cabdff1aSopenharmony_ci FFMIN(col + 1 - p, hostname_size)); 412cabdff1aSopenharmony_ci if (port_ptr) 413cabdff1aSopenharmony_ci *port_ptr = atoi(col + 1); 414cabdff1aSopenharmony_ci } else 415cabdff1aSopenharmony_ci av_strlcpy(hostname, p, 416cabdff1aSopenharmony_ci FFMIN(ls + 1 - p, hostname_size)); 417cabdff1aSopenharmony_ci } 418cabdff1aSopenharmony_ci} 419cabdff1aSopenharmony_ci 420cabdff1aSopenharmony_ciint ff_mkdir_p(const char *path) 421cabdff1aSopenharmony_ci{ 422cabdff1aSopenharmony_ci int ret = 0; 423cabdff1aSopenharmony_ci char *temp = av_strdup(path); 424cabdff1aSopenharmony_ci char *pos = temp; 425cabdff1aSopenharmony_ci char tmp_ch = '\0'; 426cabdff1aSopenharmony_ci 427cabdff1aSopenharmony_ci if (!path || !temp) { 428cabdff1aSopenharmony_ci return -1; 429cabdff1aSopenharmony_ci } 430cabdff1aSopenharmony_ci 431cabdff1aSopenharmony_ci if (!av_strncasecmp(temp, "/", 1) || !av_strncasecmp(temp, "\\", 1)) { 432cabdff1aSopenharmony_ci pos++; 433cabdff1aSopenharmony_ci } else if (!av_strncasecmp(temp, "./", 2) || !av_strncasecmp(temp, ".\\", 2)) { 434cabdff1aSopenharmony_ci pos += 2; 435cabdff1aSopenharmony_ci } 436cabdff1aSopenharmony_ci 437cabdff1aSopenharmony_ci for ( ; *pos != '\0'; ++pos) { 438cabdff1aSopenharmony_ci if (*pos == '/' || *pos == '\\') { 439cabdff1aSopenharmony_ci tmp_ch = *pos; 440cabdff1aSopenharmony_ci *pos = '\0'; 441cabdff1aSopenharmony_ci ret = mkdir(temp, 0755); 442cabdff1aSopenharmony_ci *pos = tmp_ch; 443cabdff1aSopenharmony_ci } 444cabdff1aSopenharmony_ci } 445cabdff1aSopenharmony_ci 446cabdff1aSopenharmony_ci if ((*(pos - 1) != '/') && (*(pos - 1) != '\\')) { 447cabdff1aSopenharmony_ci ret = mkdir(temp, 0755); 448cabdff1aSopenharmony_ci } 449cabdff1aSopenharmony_ci 450cabdff1aSopenharmony_ci av_free(temp); 451cabdff1aSopenharmony_ci return ret; 452cabdff1aSopenharmony_ci} 453cabdff1aSopenharmony_ci 454cabdff1aSopenharmony_cichar *ff_data_to_hex(char *buff, const uint8_t *src, int s, int lowercase) 455cabdff1aSopenharmony_ci{ 456cabdff1aSopenharmony_ci static const char hex_table_uc[16] = { '0', '1', '2', '3', 457cabdff1aSopenharmony_ci '4', '5', '6', '7', 458cabdff1aSopenharmony_ci '8', '9', 'A', 'B', 459cabdff1aSopenharmony_ci 'C', 'D', 'E', 'F' }; 460cabdff1aSopenharmony_ci static const char hex_table_lc[16] = { '0', '1', '2', '3', 461cabdff1aSopenharmony_ci '4', '5', '6', '7', 462cabdff1aSopenharmony_ci '8', '9', 'a', 'b', 463cabdff1aSopenharmony_ci 'c', 'd', 'e', 'f' }; 464cabdff1aSopenharmony_ci const char *hex_table = lowercase ? hex_table_lc : hex_table_uc; 465cabdff1aSopenharmony_ci 466cabdff1aSopenharmony_ci for (int i = 0; i < s; i++) { 467cabdff1aSopenharmony_ci buff[i * 2] = hex_table[src[i] >> 4]; 468cabdff1aSopenharmony_ci buff[i * 2 + 1] = hex_table[src[i] & 0xF]; 469cabdff1aSopenharmony_ci } 470cabdff1aSopenharmony_ci buff[2 * s] = '\0'; 471cabdff1aSopenharmony_ci 472cabdff1aSopenharmony_ci return buff; 473cabdff1aSopenharmony_ci} 474cabdff1aSopenharmony_ci 475cabdff1aSopenharmony_ciint ff_hex_to_data(uint8_t *data, const char *p) 476cabdff1aSopenharmony_ci{ 477cabdff1aSopenharmony_ci int c, len, v; 478cabdff1aSopenharmony_ci 479cabdff1aSopenharmony_ci len = 0; 480cabdff1aSopenharmony_ci v = 1; 481cabdff1aSopenharmony_ci for (;;) { 482cabdff1aSopenharmony_ci p += strspn(p, SPACE_CHARS); 483cabdff1aSopenharmony_ci if (*p == '\0') 484cabdff1aSopenharmony_ci break; 485cabdff1aSopenharmony_ci c = av_toupper((unsigned char) *p++); 486cabdff1aSopenharmony_ci if (c >= '0' && c <= '9') 487cabdff1aSopenharmony_ci c = c - '0'; 488cabdff1aSopenharmony_ci else if (c >= 'A' && c <= 'F') 489cabdff1aSopenharmony_ci c = c - 'A' + 10; 490cabdff1aSopenharmony_ci else 491cabdff1aSopenharmony_ci break; 492cabdff1aSopenharmony_ci v = (v << 4) | c; 493cabdff1aSopenharmony_ci if (v & 0x100) { 494cabdff1aSopenharmony_ci if (data) 495cabdff1aSopenharmony_ci data[len] = v; 496cabdff1aSopenharmony_ci len++; 497cabdff1aSopenharmony_ci v = 1; 498cabdff1aSopenharmony_ci } 499cabdff1aSopenharmony_ci } 500cabdff1aSopenharmony_ci return len; 501cabdff1aSopenharmony_ci} 502cabdff1aSopenharmony_ci 503cabdff1aSopenharmony_civoid ff_parse_key_value(const char *str, ff_parse_key_val_cb callback_get_buf, 504cabdff1aSopenharmony_ci void *context) 505cabdff1aSopenharmony_ci{ 506cabdff1aSopenharmony_ci const char *ptr = str; 507cabdff1aSopenharmony_ci 508cabdff1aSopenharmony_ci /* Parse key=value pairs. */ 509cabdff1aSopenharmony_ci for (;;) { 510cabdff1aSopenharmony_ci const char *key; 511cabdff1aSopenharmony_ci char *dest = NULL, *dest_end; 512cabdff1aSopenharmony_ci int key_len, dest_len = 0; 513cabdff1aSopenharmony_ci 514cabdff1aSopenharmony_ci /* Skip whitespace and potential commas. */ 515cabdff1aSopenharmony_ci while (*ptr && (av_isspace(*ptr) || *ptr == ',')) 516cabdff1aSopenharmony_ci ptr++; 517cabdff1aSopenharmony_ci if (!*ptr) 518cabdff1aSopenharmony_ci break; 519cabdff1aSopenharmony_ci 520cabdff1aSopenharmony_ci key = ptr; 521cabdff1aSopenharmony_ci 522cabdff1aSopenharmony_ci if (!(ptr = strchr(key, '='))) 523cabdff1aSopenharmony_ci break; 524cabdff1aSopenharmony_ci ptr++; 525cabdff1aSopenharmony_ci key_len = ptr - key; 526cabdff1aSopenharmony_ci 527cabdff1aSopenharmony_ci callback_get_buf(context, key, key_len, &dest, &dest_len); 528cabdff1aSopenharmony_ci dest_end = dest ? dest + dest_len - 1 : NULL; 529cabdff1aSopenharmony_ci 530cabdff1aSopenharmony_ci if (*ptr == '\"') { 531cabdff1aSopenharmony_ci ptr++; 532cabdff1aSopenharmony_ci while (*ptr && *ptr != '\"') { 533cabdff1aSopenharmony_ci if (*ptr == '\\') { 534cabdff1aSopenharmony_ci if (!ptr[1]) 535cabdff1aSopenharmony_ci break; 536cabdff1aSopenharmony_ci if (dest && dest < dest_end) 537cabdff1aSopenharmony_ci *dest++ = ptr[1]; 538cabdff1aSopenharmony_ci ptr += 2; 539cabdff1aSopenharmony_ci } else { 540cabdff1aSopenharmony_ci if (dest && dest < dest_end) 541cabdff1aSopenharmony_ci *dest++ = *ptr; 542cabdff1aSopenharmony_ci ptr++; 543cabdff1aSopenharmony_ci } 544cabdff1aSopenharmony_ci } 545cabdff1aSopenharmony_ci if (*ptr == '\"') 546cabdff1aSopenharmony_ci ptr++; 547cabdff1aSopenharmony_ci } else { 548cabdff1aSopenharmony_ci for (; *ptr && !(av_isspace(*ptr) || *ptr == ','); ptr++) 549cabdff1aSopenharmony_ci if (dest && dest < dest_end) 550cabdff1aSopenharmony_ci *dest++ = *ptr; 551cabdff1aSopenharmony_ci } 552cabdff1aSopenharmony_ci if (dest) 553cabdff1aSopenharmony_ci *dest = 0; 554cabdff1aSopenharmony_ci } 555cabdff1aSopenharmony_ci} 556cabdff1aSopenharmony_ci 557cabdff1aSopenharmony_ciint avformat_network_init(void) 558cabdff1aSopenharmony_ci{ 559cabdff1aSopenharmony_ci#if CONFIG_NETWORK 560cabdff1aSopenharmony_ci int ret; 561cabdff1aSopenharmony_ci if ((ret = ff_network_init()) < 0) 562cabdff1aSopenharmony_ci return ret; 563cabdff1aSopenharmony_ci if ((ret = ff_tls_init()) < 0) 564cabdff1aSopenharmony_ci return ret; 565cabdff1aSopenharmony_ci#endif 566cabdff1aSopenharmony_ci return 0; 567cabdff1aSopenharmony_ci} 568cabdff1aSopenharmony_ci 569cabdff1aSopenharmony_ciint avformat_network_deinit(void) 570cabdff1aSopenharmony_ci{ 571cabdff1aSopenharmony_ci#if CONFIG_NETWORK 572cabdff1aSopenharmony_ci ff_network_close(); 573cabdff1aSopenharmony_ci ff_tls_deinit(); 574cabdff1aSopenharmony_ci#endif 575cabdff1aSopenharmony_ci return 0; 576cabdff1aSopenharmony_ci} 577cabdff1aSopenharmony_ci 578cabdff1aSopenharmony_ciint ff_is_http_proto(const char *filename) { 579cabdff1aSopenharmony_ci const char *proto = avio_find_protocol_name(filename); 580cabdff1aSopenharmony_ci return proto ? (!av_strcasecmp(proto, "http") || !av_strcasecmp(proto, "https")) : 0; 581cabdff1aSopenharmony_ci} 582cabdff1aSopenharmony_ci 583cabdff1aSopenharmony_ciint ff_bprint_to_codecpar_extradata(AVCodecParameters *par, struct AVBPrint *buf) 584cabdff1aSopenharmony_ci{ 585cabdff1aSopenharmony_ci int ret; 586cabdff1aSopenharmony_ci char *str; 587cabdff1aSopenharmony_ci 588cabdff1aSopenharmony_ci ret = av_bprint_finalize(buf, &str); 589cabdff1aSopenharmony_ci if (ret < 0) 590cabdff1aSopenharmony_ci return ret; 591cabdff1aSopenharmony_ci if (!av_bprint_is_complete(buf)) { 592cabdff1aSopenharmony_ci av_free(str); 593cabdff1aSopenharmony_ci return AVERROR(ENOMEM); 594cabdff1aSopenharmony_ci } 595cabdff1aSopenharmony_ci 596cabdff1aSopenharmony_ci par->extradata = str; 597cabdff1aSopenharmony_ci /* Note: the string is NUL terminated (so extradata can be read as a 598cabdff1aSopenharmony_ci * string), but the ending character is not accounted in the size (in 599cabdff1aSopenharmony_ci * binary formats you are likely not supposed to mux that character). When 600cabdff1aSopenharmony_ci * extradata is copied, it is also padded with AV_INPUT_BUFFER_PADDING_SIZE 601cabdff1aSopenharmony_ci * zeros. */ 602cabdff1aSopenharmony_ci par->extradata_size = buf->len; 603cabdff1aSopenharmony_ci return 0; 604cabdff1aSopenharmony_ci} 605