FFmpeg
avio.c
Go to the documentation of this file.
1 /*
2  * unbuffered I/O
3  * Copyright (c) 2001 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 "libavutil/avstring.h"
23 #include "libavutil/dict.h"
24 #include "libavutil/opt.h"
25 #include "libavutil/time.h"
26 #include "libavutil/avassert.h"
27 #include "avio_internal.h"
28 #include "os_support.h"
29 #include "internal.h"
30 #if CONFIG_NETWORK
31 #include "network.h"
32 #endif
33 #include "url.h"
34 
35 #define IO_BUFFER_SIZE 32768
36 
37 /** @name Logging context. */
38 /*@{*/
39 static const char *urlcontext_to_name(void *ptr)
40 {
41  URLContext *h = (URLContext *)ptr;
42  if (h->prot)
43  return h->prot->name;
44  else
45  return "NULL";
46 }
47 
48 static void *urlcontext_child_next(void *obj, void *prev)
49 {
50  URLContext *h = obj;
51  if (!prev && h->priv_data && h->prot->priv_data_class)
52  return h->priv_data;
53  return NULL;
54 }
55 
56 #define OFFSET(x) offsetof(URLContext,x)
57 #define E AV_OPT_FLAG_ENCODING_PARAM
58 #define D AV_OPT_FLAG_DECODING_PARAM
59 static const AVOption options[] = {
60  {"protocol_whitelist", "List of protocols that are allowed to be used", OFFSET(protocol_whitelist), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, D },
61  {"protocol_blacklist", "List of protocols that are not allowed to be used", OFFSET(protocol_blacklist), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, D },
62  {"rw_timeout", "Timeout for IO operations (in microseconds)", offsetof(URLContext, rw_timeout), AV_OPT_TYPE_INT64, { .i64 = 0 }, 0, INT64_MAX, AV_OPT_FLAG_ENCODING_PARAM | AV_OPT_FLAG_DECODING_PARAM },
63  { NULL }
64 };
65 
66 static const AVClass url_context_class = {
67  .class_name = "URLContext",
68  .item_name = urlcontext_to_name,
69  .option = options,
70  .version = LIBAVUTIL_VERSION_INT,
71  .child_next = urlcontext_child_next,
72  .child_class_iterate = ff_urlcontext_child_class_iterate,
73 };
74 /*@}*/
75 
76 static void *avio_child_next(void *obj, void *prev)
77 {
78  AVIOContext *s = obj;
79  return prev ? NULL : s->opaque;
80 }
81 
82 static const AVClass *child_class_iterate(void **iter)
83 {
84  const AVClass *c = *iter ? NULL : &url_context_class;
85  *iter = (void*)(uintptr_t)c;
86  return c;
87 }
88 
89 #define AVIOOFFSET(x) offsetof(AVIOContext,x)
90 #define E AV_OPT_FLAG_ENCODING_PARAM
91 #define D AV_OPT_FLAG_DECODING_PARAM
92 static const AVOption avio_options[] = {
93  {"protocol_whitelist", "List of protocols that are allowed to be used", AVIOOFFSET(protocol_whitelist), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, D },
94  { NULL },
95 };
96 
98  .class_name = "AVIOContext",
99  .item_name = av_default_item_name,
100  .version = LIBAVUTIL_VERSION_INT,
101  .option = avio_options,
102  .child_next = avio_child_next,
103  .child_class_iterate = child_class_iterate,
104 };
105 
107 {
108  if (!s)
109  return NULL;
110 
111  if (s->opaque && s->read_packet == ffurl_read2)
112  return s->opaque;
113  else
114  return NULL;
115 }
116 
117 static int url_alloc_for_protocol(URLContext **puc, const URLProtocol *up,
118  const char *filename, int flags,
119  const AVIOInterruptCB *int_cb)
120 {
121  URLContext *uc;
122  int err;
123 
124 #if CONFIG_NETWORK
126  return AVERROR(EIO);
127 #endif
128  if ((flags & AVIO_FLAG_READ) && !up->url_read) {
130  "Impossible to open the '%s' protocol for reading\n", up->name);
131  return AVERROR(EIO);
132  }
133  if ((flags & AVIO_FLAG_WRITE) && !up->url_write) {
135  "Impossible to open the '%s' protocol for writing\n", up->name);
136  return AVERROR(EIO);
137  }
138  uc = av_mallocz(sizeof(URLContext) + strlen(filename) + 1);
139  if (!uc) {
140  err = AVERROR(ENOMEM);
141  goto fail;
142  }
144  uc->filename = (char *)&uc[1];
145  strcpy(uc->filename, filename);
146  uc->prot = up;
147  uc->flags = flags;
148  uc->is_streamed = 0; /* default = not streamed */
149  uc->max_packet_size = 0; /* default: stream file */
150  if (up->priv_data_size) {
152  if (!uc->priv_data) {
153  err = AVERROR(ENOMEM);
154  goto fail;
155  }
156  if (up->priv_data_class) {
157  char *start;
158  *(const AVClass **)uc->priv_data = up->priv_data_class;
160  if (av_strstart(uc->filename, up->name, (const char**)&start) && *start == ',') {
161  int ret= 0;
162  char *p= start;
163  char sep= *++p;
164  char *key, *val;
165  p++;
166 
167  if (strcmp(up->name, "subfile"))
168  ret = AVERROR(EINVAL);
169 
170  while(ret >= 0 && (key= strchr(p, sep)) && p<key && (val = strchr(key+1, sep))){
171  *val= *key= 0;
172  ret = av_opt_set(uc->priv_data, p, key+1, 0);
174  av_log(uc, AV_LOG_ERROR, "Key '%s' not found.\n", p);
175  *val= *key= sep;
176  p= val+1;
177  }
178  if(ret<0 || p!=key){
179  av_log(uc, AV_LOG_ERROR, "Error parsing options string %s\n", start);
180  err = AVERROR(EINVAL);
181  goto fail;
182  }
183  memmove(start, key+1, strlen(key));
184  }
185  }
186  }
187  if (int_cb)
188  uc->interrupt_callback = *int_cb;
189 
190  *puc = uc;
191  return 0;
192 fail:
193  *puc = NULL;
194  if (uc)
195  av_freep(&uc->priv_data);
196  av_freep(&uc);
197 #if CONFIG_NETWORK
200 #endif
201  return err;
202 }
203 
205 {
206  int err;
207  AVDictionary *tmp_opts = NULL;
209 
210  if (!options)
211  options = &tmp_opts;
212 
213  // Check that URLContext was initialized correctly and lists are matching if set
214  av_assert0(!(e=av_dict_get(*options, "protocol_whitelist", NULL, 0)) ||
215  (uc->protocol_whitelist && !strcmp(uc->protocol_whitelist, e->value)));
216  av_assert0(!(e=av_dict_get(*options, "protocol_blacklist", NULL, 0)) ||
217  (uc->protocol_blacklist && !strcmp(uc->protocol_blacklist, e->value)));
218 
219  if (uc->protocol_whitelist && av_match_list(uc->prot->name, uc->protocol_whitelist, ',') <= 0) {
220  av_log(uc, AV_LOG_ERROR, "Protocol '%s' not on whitelist '%s'!\n", uc->prot->name, uc->protocol_whitelist);
221  return AVERROR(EINVAL);
222  }
223 
224  if (uc->protocol_blacklist && av_match_list(uc->prot->name, uc->protocol_blacklist, ',') > 0) {
225  av_log(uc, AV_LOG_ERROR, "Protocol '%s' on blacklist '%s'!\n", uc->prot->name, uc->protocol_blacklist);
226  return AVERROR(EINVAL);
227  }
228 
229  if (!uc->protocol_whitelist && uc->prot->default_whitelist) {
230  av_log(uc, AV_LOG_DEBUG, "Setting default whitelist '%s'\n", uc->prot->default_whitelist);
232  if (!uc->protocol_whitelist) {
233  return AVERROR(ENOMEM);
234  }
235  } else if (!uc->protocol_whitelist)
236  av_log(uc, AV_LOG_DEBUG, "No default whitelist set\n"); // This should be an error once all declare a default whitelist
237 
238  if ((err = av_dict_set(options, "protocol_whitelist", uc->protocol_whitelist, 0)) < 0)
239  return err;
240  if ((err = av_dict_set(options, "protocol_blacklist", uc->protocol_blacklist, 0)) < 0)
241  return err;
242 
243  err =
244  uc->prot->url_open2 ? uc->prot->url_open2(uc,
245  uc->filename,
246  uc->flags,
247  options) :
248  uc->prot->url_open(uc, uc->filename, uc->flags);
249 
250  av_dict_set(options, "protocol_whitelist", NULL, 0);
251  av_dict_set(options, "protocol_blacklist", NULL, 0);
252 
253  if (err)
254  return err;
255  uc->is_connected = 1;
256  /* We must be careful here as ffurl_seek() could be slow,
257  * for example for http */
258  if ((uc->flags & AVIO_FLAG_WRITE) || !strcmp(uc->prot->name, "file"))
259  if (!uc->is_streamed && ffurl_seek(uc, 0, SEEK_SET) < 0)
260  uc->is_streamed = 1;
261  return 0;
262 }
263 
265 {
266  av_assert0(!*c);
267  if (s->prot->url_accept)
268  return s->prot->url_accept(s, c);
269  return AVERROR(EBADF);
270 }
271 
273 {
274  int ret;
275  URLContext *sc = s->opaque;
276  URLContext *cc = NULL;
277  ret = ffurl_accept(sc, &cc);
278  if (ret < 0)
279  return ret;
280  return ffio_fdopen(c, cc);
281 }
282 
284 {
285  int ret;
286  if (c->prot->url_handshake) {
287  ret = c->prot->url_handshake(c);
288  if (ret)
289  return ret;
290  }
291  c->is_connected = 1;
292  return 0;
293 }
294 
296 {
297  URLContext *cc = c->opaque;
298  return ffurl_handshake(cc);
299 }
300 
301 #define URL_SCHEME_CHARS \
302  "abcdefghijklmnopqrstuvwxyz" \
303  "ABCDEFGHIJKLMNOPQRSTUVWXYZ" \
304  "0123456789+-."
305 
306 static const struct URLProtocol *url_find_protocol(const char *filename)
307 {
308  const URLProtocol **protocols;
309  char proto_str[128], proto_nested[128], *ptr;
310  size_t proto_len = strspn(filename, URL_SCHEME_CHARS);
311  int i;
312 
313  if (filename[proto_len] != ':' &&
314  (strncmp(filename, "subfile,", 8) || !strchr(filename + proto_len + 1, ':')) ||
315  is_dos_path(filename))
316  strcpy(proto_str, "file");
317  else
318  av_strlcpy(proto_str, filename,
319  FFMIN(proto_len + 1, sizeof(proto_str)));
320 
321  av_strlcpy(proto_nested, proto_str, sizeof(proto_nested));
322  if ((ptr = strchr(proto_nested, '+')))
323  *ptr = '\0';
324 
325  protocols = ffurl_get_protocols(NULL, NULL);
326  if (!protocols)
327  return NULL;
328  for (i = 0; protocols[i]; i++) {
329  const URLProtocol *up = protocols[i];
330  if (!strcmp(proto_str, up->name)) {
331  av_freep(&protocols);
332  return up;
333  }
335  !strcmp(proto_nested, up->name)) {
336  av_freep(&protocols);
337  return up;
338  }
339  }
340  av_freep(&protocols);
341  if (av_strstart(filename, "https:", NULL) || av_strstart(filename, "tls:", NULL))
342  av_log(NULL, AV_LOG_WARNING, "https protocol not found, recompile FFmpeg with "
343  "openssl, gnutls or securetransport enabled.\n");
344 
345  return NULL;
346 }
347 
348 int ffurl_alloc(URLContext **puc, const char *filename, int flags,
349  const AVIOInterruptCB *int_cb)
350 {
351  const URLProtocol *p = NULL;
352 
353  p = url_find_protocol(filename);
354  if (p)
355  return url_alloc_for_protocol(puc, p, filename, flags, int_cb);
356 
357  *puc = NULL;
359 }
360 
361 int ffurl_open_whitelist(URLContext **puc, const char *filename, int flags,
363  const char *whitelist, const char* blacklist,
364  URLContext *parent)
365 {
366  AVDictionary *tmp_opts = NULL;
368  int ret = ffurl_alloc(puc, filename, flags, int_cb);
369  if (ret < 0)
370  return ret;
371  if (parent) {
372  ret = av_opt_copy(*puc, parent);
373  if (ret < 0)
374  goto fail;
375  }
376  if (options &&
377  (ret = av_opt_set_dict(*puc, options)) < 0)
378  goto fail;
379  if (options && (*puc)->prot->priv_data_class &&
380  (ret = av_opt_set_dict((*puc)->priv_data, options)) < 0)
381  goto fail;
382 
383  if (!options)
384  options = &tmp_opts;
385 
386  av_assert0(!whitelist ||
387  !(e=av_dict_get(*options, "protocol_whitelist", NULL, 0)) ||
388  !strcmp(whitelist, e->value));
389  av_assert0(!blacklist ||
390  !(e=av_dict_get(*options, "protocol_blacklist", NULL, 0)) ||
391  !strcmp(blacklist, e->value));
392 
393  if ((ret = av_dict_set(options, "protocol_whitelist", whitelist, 0)) < 0)
394  goto fail;
395 
396  if ((ret = av_dict_set(options, "protocol_blacklist", blacklist, 0)) < 0)
397  goto fail;
398 
399  if ((ret = av_opt_set_dict(*puc, options)) < 0)
400  goto fail;
401 
402  ret = ffurl_connect(*puc, options);
403 
404  if (!ret)
405  return 0;
406 fail:
407  ffurl_closep(puc);
408  return ret;
409 }
410 
412 {
413  AVIOContext *s;
414  uint8_t *buffer = NULL;
415  int buffer_size, max_packet_size;
416 
417  max_packet_size = h->max_packet_size;
418  if (max_packet_size) {
419  buffer_size = max_packet_size; /* no need to bufferize more than one packet */
420  } else {
421  buffer_size = IO_BUFFER_SIZE;
422  }
423  if (!(h->flags & AVIO_FLAG_WRITE) && h->is_streamed) {
424  if (buffer_size > INT_MAX/2)
425  return AVERROR(EINVAL);
426  buffer_size *= 2;
427  }
428  buffer = av_malloc(buffer_size);
429  if (!buffer)
430  return AVERROR(ENOMEM);
431 
432  *sp = avio_alloc_context(buffer, buffer_size, h->flags & AVIO_FLAG_WRITE, h,
434  if (!*sp) {
435  av_freep(&buffer);
436  return AVERROR(ENOMEM);
437  }
438  s = *sp;
439  if (h->protocol_whitelist) {
440  s->protocol_whitelist = av_strdup(h->protocol_whitelist);
441  if (!s->protocol_whitelist) {
442  avio_closep(sp);
443  return AVERROR(ENOMEM);
444  }
445  }
446  if (h->protocol_blacklist) {
447  s->protocol_blacklist = av_strdup(h->protocol_blacklist);
448  if (!s->protocol_blacklist) {
449  avio_closep(sp);
450  return AVERROR(ENOMEM);
451  }
452  }
453  s->direct = h->flags & AVIO_FLAG_DIRECT;
454 
455  s->seekable = h->is_streamed ? 0 : AVIO_SEEKABLE_NORMAL;
456  s->max_packet_size = max_packet_size;
457  s->min_packet_size = h->min_packet_size;
458  if(h->prot) {
459  s->read_pause = h->prot->url_read_pause;
460  s->read_seek = h->prot->url_read_seek;
461 
462  if (h->prot->url_read_seek)
463  s->seekable |= AVIO_SEEKABLE_TIME;
464  }
465  ((FFIOContext*)s)->short_seek_get = ffurl_get_short_seek;
466  s->av_class = &ff_avio_class;
467  return 0;
468 }
469 
470 int ffio_open_whitelist(AVIOContext **s, const char *filename, int flags,
472  const char *whitelist, const char *blacklist)
473 {
474  URLContext *h;
475  int err;
476 
477  *s = NULL;
478 
479  err = ffurl_open_whitelist(&h, filename, flags, int_cb, options, whitelist, blacklist, NULL);
480  if (err < 0)
481  return err;
482  err = ffio_fdopen(s, h);
483  if (err < 0) {
484  ffurl_close(h);
485  return err;
486  }
487  return 0;
488 }
489 
490 int avio_open2(AVIOContext **s, const char *filename, int flags,
492 {
493  return ffio_open_whitelist(s, filename, flags, int_cb, options, NULL, NULL);
494 }
495 
496 int avio_open(AVIOContext **s, const char *filename, int flags)
497 {
498  return avio_open2(s, filename, flags, NULL, NULL);
499 }
500 
501 
502 static inline int retry_transfer_wrapper(URLContext *h, uint8_t *buf,
503  const uint8_t *cbuf,
504  int size, int size_min,
505  int read)
506 {
507  int ret, len;
508  int fast_retries = 5;
509  int64_t wait_since = 0;
510 
511  len = 0;
512  while (len < size_min) {
513  if (ff_check_interrupt(&h->interrupt_callback))
514  return AVERROR_EXIT;
515  ret = read ? h->prot->url_read (h, buf + len, size - len):
516  h->prot->url_write(h, cbuf + len, size - len);
517  if (ret == AVERROR(EINTR))
518  continue;
519  if (h->flags & AVIO_FLAG_NONBLOCK)
520  return ret;
521  if (ret == AVERROR(EAGAIN)) {
522  ret = 0;
523  if (fast_retries) {
524  fast_retries--;
525  } else {
526  if (h->rw_timeout) {
527  if (!wait_since)
528  wait_since = av_gettime_relative();
529  else if (av_gettime_relative() > wait_since + h->rw_timeout)
530  return AVERROR(EIO);
531  }
532  av_usleep(1000);
533  }
534  } else if (ret == AVERROR_EOF)
535  return (len > 0) ? len : AVERROR_EOF;
536  else if (ret < 0)
537  return ret;
538  if (ret) {
539  fast_retries = FFMAX(fast_retries, 2);
540  wait_since = 0;
541  }
542  len += ret;
543  }
544  return len;
545 }
546 
547 int ffurl_read2(void *urlcontext, uint8_t *buf, int size)
548 {
549  URLContext *h = urlcontext;
550 
551  if (!(h->flags & AVIO_FLAG_READ))
552  return AVERROR(EIO);
553  return retry_transfer_wrapper(h, buf, NULL, size, 1, 1);
554 }
555 
556 int ffurl_read_complete(URLContext *h, unsigned char *buf, int size)
557 {
558  if (!(h->flags & AVIO_FLAG_READ))
559  return AVERROR(EIO);
560  return retry_transfer_wrapper(h, buf, NULL, size, size, 1);
561 }
562 
563 int ffurl_write2(void *urlcontext, const uint8_t *buf, int size)
564 {
565  URLContext *h = urlcontext;
566 
567  if (!(h->flags & AVIO_FLAG_WRITE))
568  return AVERROR(EIO);
569  /* avoid sending too big packets */
570  if (h->max_packet_size && size > h->max_packet_size)
571  return AVERROR(EIO);
572 
573  return retry_transfer_wrapper(h, NULL, buf, size, size, 0);
574 }
575 
576 int64_t ffurl_seek2(void *urlcontext, int64_t pos, int whence)
577 {
578  URLContext *h = urlcontext;
579  int64_t ret;
580 
581  if (!h->prot->url_seek)
582  return AVERROR(ENOSYS);
583  ret = h->prot->url_seek(h, pos, whence & ~AVSEEK_FORCE);
584  return ret;
585 }
586 
588 {
589  URLContext *h= *hh;
590  int ret = 0;
591  if (!h)
592  return 0; /* can happen when ffurl_open fails */
593 
594  if (h->is_connected && h->prot->url_close)
595  ret = h->prot->url_close(h);
596 #if CONFIG_NETWORK
597  if (h->prot->flags & URL_PROTOCOL_FLAG_NETWORK)
599 #endif
600  if (h->prot->priv_data_size) {
601  if (h->prot->priv_data_class)
602  av_opt_free(h->priv_data);
603  av_freep(&h->priv_data);
604  }
605  av_opt_free(h);
606  av_freep(hh);
607  return ret;
608 }
609 
611 {
612  return ffurl_closep(&h);
613 }
614 
616 {
617  FFIOContext *const ctx = ffiocontext(s);
618  URLContext *h;
619  int ret, error;
620 
621  if (!s)
622  return 0;
623 
624  avio_flush(s);
625  h = s->opaque;
626  s->opaque = NULL;
627 
628  av_freep(&s->buffer);
629  if (s->write_flag)
631  "Statistics: %"PRId64" bytes written, %d seeks, %d writeouts\n",
632  ctx->bytes_written, ctx->seek_count, ctx->writeout_count);
633  else
634  av_log(s, AV_LOG_VERBOSE, "Statistics: %"PRId64" bytes read, %d seeks\n",
635  ctx->bytes_read, ctx->seek_count);
636  av_opt_free(s);
637 
638  error = s->error;
640 
641  ret = ffurl_close(h);
642  if (ret < 0)
643  return ret;
644 
645  return error;
646 }
647 
649 {
650  int ret = avio_close(*s);
651  *s = NULL;
652  return ret;
653 }
654 
655 
656 const char *avio_find_protocol_name(const char *url)
657 {
658  const URLProtocol *p = url_find_protocol(url);
659 
660  return p ? p->name : NULL;
661 }
662 
663 int avio_check(const char *url, int flags)
664 {
665  URLContext *h;
666  int ret = ffurl_alloc(&h, url, flags, NULL);
667  if (ret < 0)
668  return ret;
669 
670  if (h->prot->url_check) {
671  ret = h->prot->url_check(h, flags);
672  } else {
673  ret = ffurl_connect(h, NULL);
674  if (ret >= 0)
675  ret = flags;
676  }
677 
678  ffurl_close(h);
679  return ret;
680 }
681 
682 int ffurl_move(const char *url_src, const char *url_dst)
683 {
684  URLContext *h_src, *h_dst;
685  int ret = ffurl_alloc(&h_src, url_src, AVIO_FLAG_READ_WRITE, NULL);
686  if (ret < 0)
687  return ret;
688  ret = ffurl_alloc(&h_dst, url_dst, AVIO_FLAG_WRITE, NULL);
689  if (ret < 0) {
690  ffurl_close(h_src);
691  return ret;
692  }
693 
694  if (h_src->prot == h_dst->prot && h_src->prot->url_move)
695  ret = h_src->prot->url_move(h_src, h_dst);
696  else
697  ret = AVERROR(ENOSYS);
698 
699  ffurl_close(h_src);
700  ffurl_close(h_dst);
701  return ret;
702 }
703 
704 int ffurl_delete(const char *url)
705 {
706  URLContext *h;
707  int ret = ffurl_alloc(&h, url, AVIO_FLAG_WRITE, NULL);
708  if (ret < 0)
709  return ret;
710 
711  if (h->prot->url_delete)
712  ret = h->prot->url_delete(h);
713  else
714  ret = AVERROR(ENOSYS);
715 
716  ffurl_close(h);
717  return ret;
718 }
719 
722 };
723 
725 {
726  URLContext *h = NULL;
728  int ret;
729  av_assert0(s);
730 
731  ctx = av_mallocz(sizeof(*ctx));
732  if (!ctx) {
733  ret = AVERROR(ENOMEM);
734  goto fail;
735  }
736 
737  if ((ret = ffurl_alloc(&h, url, AVIO_FLAG_READ, NULL)) < 0)
738  goto fail;
739 
740  if (h->prot->url_open_dir && h->prot->url_read_dir && h->prot->url_close_dir) {
741  if (options && h->prot->priv_data_class &&
742  (ret = av_opt_set_dict(h->priv_data, options)) < 0)
743  goto fail;
744  ret = h->prot->url_open_dir(h);
745  } else
746  ret = AVERROR(ENOSYS);
747  if (ret < 0)
748  goto fail;
749 
750  h->is_connected = 1;
751  ctx->url_context = h;
752  *s = ctx;
753  return 0;
754 
755  fail:
756  av_free(ctx);
757  *s = NULL;
758  ffurl_close(h);
759  return ret;
760 }
761 
763 {
764  URLContext *h;
765  int ret;
766 
767  if (!s || !s->url_context)
768  return AVERROR(EINVAL);
769  h = s->url_context;
770  if ((ret = h->prot->url_read_dir(h, next)) < 0)
772  return ret;
773 }
774 
776 {
777  URLContext *h;
778 
779  av_assert0(s);
780  if (!(*s) || !(*s)->url_context)
781  return AVERROR(EINVAL);
782  h = (*s)->url_context;
783  h->prot->url_close_dir(h);
784  ffurl_close(h);
785  av_freep(s);
786  *s = NULL;
787  return 0;
788 }
789 
791 {
792  if (!entry || !*entry)
793  return;
794  av_free((*entry)->name);
795  av_freep(entry);
796 }
797 
799 {
800  int64_t pos, size;
801 
802  size = ffurl_seek(h, 0, AVSEEK_SIZE);
803  if (size < 0) {
804  pos = ffurl_seek(h, 0, SEEK_CUR);
805  if ((size = ffurl_seek(h, -1, SEEK_END)) < 0)
806  return size;
807  size++;
808  ffurl_seek(h, pos, SEEK_SET);
809  }
810  return size;
811 }
812 
814 {
815  if (!h || !h->prot || !h->prot->url_get_file_handle)
816  return -1;
817  return h->prot->url_get_file_handle(h);
818 }
819 
820 int ffurl_get_multi_file_handle(URLContext *h, int **handles, int *numhandles)
821 {
822  if (!h || !h->prot)
823  return AVERROR(ENOSYS);
824  if (!h->prot->url_get_multi_file_handle) {
825  if (!h->prot->url_get_file_handle)
826  return AVERROR(ENOSYS);
827  *handles = av_malloc(sizeof(**handles));
828  if (!*handles)
829  return AVERROR(ENOMEM);
830  *numhandles = 1;
831  *handles[0] = h->prot->url_get_file_handle(h);
832  return 0;
833  }
834  return h->prot->url_get_multi_file_handle(h, handles, numhandles);
835 }
836 
837 int ffurl_get_short_seek(void *urlcontext)
838 {
839  URLContext *h = urlcontext;
840 
841  if (!h || !h->prot || !h->prot->url_get_short_seek)
842  return AVERROR(ENOSYS);
843  return h->prot->url_get_short_seek(h);
844 }
845 
847 {
848  if (!h || !h->prot || !h->prot->url_shutdown)
849  return AVERROR(ENOSYS);
850  return h->prot->url_shutdown(h, flags);
851 }
852 
854 {
855  if (cb && cb->callback)
856  return cb->callback(cb->opaque);
857  return 0;
858 }
859 
860 int ff_rename(const char *url_src, const char *url_dst, void *logctx)
861 {
862  int ret = ffurl_move(url_src, url_dst);
863  if (ret < 0)
864  av_log(logctx, AV_LOG_ERROR, "failed to rename file %s to %s: %s\n", url_src, url_dst, av_err2str(ret));
865  return ret;
866 }
error
static void error(const char *err)
Definition: target_bsf_fuzzer.c:31
ffurl_seek
static int64_t ffurl_seek(URLContext *h, int64_t pos, int whence)
Change the position that will be used by the next read/write operation on the resource accessed by h.
Definition: url.h:222
av_gettime_relative
int64_t av_gettime_relative(void)
Get the current time in microseconds since some unspecified starting point.
Definition: time.c:56
ffio_open_whitelist
int ffio_open_whitelist(AVIOContext **s, const char *filename, int flags, const AVIOInterruptCB *int_cb, AVDictionary **options, const char *whitelist, const char *blacklist)
Definition: avio.c:470
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:186
entry
#define entry
Definition: aom_film_grain_template.c:66
av_opt_set_defaults
void av_opt_set_defaults(void *s)
Set the values of all AVOption fields to their default values.
Definition: opt.c:1638
AVERROR
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
opt.h
AVIOOFFSET
#define AVIOOFFSET(x)
Definition: avio.c:89
URLContext::filename
char * filename
specified URL
Definition: url.h:39
URL_PROTOCOL_FLAG_NETWORK
#define URL_PROTOCOL_FLAG_NETWORK
Definition: url.h:33
URLProtocol::url_read
int(* url_read)(URLContext *h, unsigned char *buf, int size)
Read data from the protocol.
Definition: url.h:75
cb
static double cb(void *priv, double x, double y)
Definition: vf_geq.c:241
ffiocontext
static av_always_inline FFIOContext * ffiocontext(AVIOContext *ctx)
Definition: avio_internal.h:81
avio_accept
int avio_accept(AVIOContext *s, AVIOContext **c)
Accept and allocate a client context on a server context.
Definition: avio.c:272
AVERROR_EOF
#define AVERROR_EOF
End of file.
Definition: error.h:57
AVIO_FLAG_READ_WRITE
#define AVIO_FLAG_READ_WRITE
read-write pseudo flag
Definition: avio.h:619
avio_context_free
void avio_context_free(AVIOContext **s)
Free the supplied IO context and everything associated with it.
Definition: aviobuf.c:125
avio_handshake
int avio_handshake(AVIOContext *c)
Perform one step of the protocol handshake to accept a new client.
Definition: avio.c:295
int64_t
long long int64_t
Definition: coverity.c:34
URLContext::max_packet_size
int max_packet_size
if non zero, the stream is packetized with this max packet size
Definition: url.h:41
avio_alloc_context
AVIOContext * avio_alloc_context(unsigned char *buffer, int buffer_size, int write_flag, void *opaque, int(*read_packet)(void *opaque, uint8_t *buf, int buf_size), int(*write_packet)(void *opaque, const uint8_t *buf, int buf_size), int64_t(*seek)(void *opaque, int64_t offset, int whence))
Allocate and initialize an AVIOContext for buffered I/O.
Definition: aviobuf.c:108
AVOption
AVOption.
Definition: opt.h:346
AVSEEK_SIZE
#define AVSEEK_SIZE
ORing this as the "whence" parameter to a seek function causes it to return the filesize without seek...
Definition: avio.h:468
avio_open
int avio_open(AVIOContext **s, const char *filename, int flags)
Create and initialize a AVIOContext for accessing the resource indicated by url.
Definition: avio.c:496
IO_BUFFER_SIZE
#define IO_BUFFER_SIZE
Definition: avio.c:35
AV_LOG_VERBOSE
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:196
ffurl_close
int ffurl_close(URLContext *h)
Definition: avio.c:610
urlcontext_to_name
static const char * urlcontext_to_name(void *ptr)
Definition: avio.c:39
AVDictionary
Definition: dict.c:34
FFMAX
#define FFMAX(a, b)
Definition: macros.h:47
ff_network_close
void ff_network_close(void)
Definition: network.c:116
URLProtocol
Definition: url.h:51
os_support.h
FFIOContext
Definition: avio_internal.h:28
ff_network_init
int ff_network_init(void)
Definition: network.c:58
av_malloc
#define av_malloc(s)
Definition: tableprint_vlc.h:30
AVIOInterruptCB
Callback for checking whether to abort blocking functions.
Definition: avio.h:59
ff_urlcontext_child_class_iterate
const AVClass * ff_urlcontext_child_class_iterate(void **iter)
Definition: protocols.c:84
URLContext::is_connected
int is_connected
Definition: url.h:43
fail
#define fail()
Definition: checkasm.h:179
ffurl_get_short_seek
int ffurl_get_short_seek(void *urlcontext)
Return the current short seek threshold value for this URL.
Definition: avio.c:837
avio_options
static const AVOption avio_options[]
Definition: avio.c:92
ffurl_connect
int ffurl_connect(URLContext *uc, AVDictionary **options)
Connect an URLContext that has been allocated by ffurl_alloc.
Definition: avio.c:204
av_opt_free
void av_opt_free(void *obj)
Free all allocated objects in obj.
Definition: opt.c:1908
AVERROR_OPTION_NOT_FOUND
#define AVERROR_OPTION_NOT_FOUND
Option not found.
Definition: error.h:63
val
static double val(void *priv, double ch)
Definition: aeval.c:78
av_opt_set
int av_opt_set(void *obj, const char *name, const char *val, int search_flags)
Definition: opt.c:738
ff_check_interrupt
int ff_check_interrupt(AVIOInterruptCB *cb)
Check if the user has requested to interrupt a blocking function associated with cb.
Definition: avio.c:853
ff_rename
int ff_rename(const char *url_src, const char *url_dst, void *logctx)
Wrap ffurl_move() and log if error happens.
Definition: avio.c:860
URLProtocol::url_open
int(* url_open)(URLContext *h, const char *url, int flags)
Definition: url.h:53
URLContext::priv_data
void * priv_data
Definition: url.h:38
avio_free_directory_entry
void avio_free_directory_entry(AVIODirEntry **entry)
Free entry allocated by avio_read_dir().
Definition: avio.c:790
URLProtocol::flags
int flags
Definition: url.h:89
avassert.h
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:180
url_alloc_for_protocol
static int url_alloc_for_protocol(URLContext **puc, const URLProtocol *up, const char *filename, int flags, const AVIOInterruptCB *int_cb)
Definition: avio.c:117
av_dict_get
AVDictionaryEntry * av_dict_get(const AVDictionary *m, const char *key, const AVDictionaryEntry *prev, int flags)
Get a dictionary entry with matching key.
Definition: dict.c:62
ffurl_open_whitelist
int ffurl_open_whitelist(URLContext **puc, const char *filename, int flags, const AVIOInterruptCB *int_cb, AVDictionary **options, const char *whitelist, const char *blacklist, URLContext *parent)
Create an URLContext for accessing to the resource indicated by url, and open it.
Definition: avio.c:361
s
#define s(width, name)
Definition: cbs_vp9.c:198
is_dos_path
static int is_dos_path(const char *path)
Definition: os_support.h:98
URLContext::flags
int flags
Definition: url.h:40
avio_close_dir
int avio_close_dir(AVIODirContext **s)
Close directory.
Definition: avio.c:775
AV_OPT_TYPE_INT64
@ AV_OPT_TYPE_INT64
Definition: opt.h:236
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:40
AVIO_FLAG_WRITE
#define AVIO_FLAG_WRITE
write-only
Definition: avio.h:618
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:201
ctx
AVFormatContext * ctx
Definition: movenc.c:48
avio_child_next
static void * avio_child_next(void *obj, void *prev)
Definition: avio.c:76
key
const char * key
Definition: hwcontext_opencl.c:189
av_usleep
int av_usleep(unsigned usec)
Sleep for a period of time.
Definition: time.c:84
avio_flush
void avio_flush(AVIOContext *s)
Force flushing of buffered data.
Definition: aviobuf.c:222
ffurl_accept
int ffurl_accept(URLContext *s, URLContext **c)
Accept an URLContext c on an URLContext s.
Definition: avio.c:264
internal.h
LIBAVUTIL_VERSION_INT
#define LIBAVUTIL_VERSION_INT
Definition: version.h:85
ffurl_get_protocols
const URLProtocol ** ffurl_get_protocols(const char *whitelist, const char *blacklist)
Construct a list of protocols matching a given whitelist and/or blacklist.
Definition: protocols.c:124
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:66
URLContext::protocol_whitelist
const char * protocol_whitelist
Definition: url.h:46
D
#define D
Definition: avio.c:91
NULL
#define NULL
Definition: coverity.c:32
urlcontext_child_next
static void * urlcontext_child_next(void *obj, void *prev)
Definition: avio.c:48
av_match_list
int av_match_list(const char *name, const char *list, char separator)
Check if a name is in a list.
Definition: avstring.c:444
URLContext::protocol_blacklist
const char * protocol_blacklist
Definition: url.h:47
ffurl_move
int ffurl_move(const char *url_src, const char *url_dst)
Move or rename a resource.
Definition: avio.c:682
av_default_item_name
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:237
ffurl_shutdown
int ffurl_shutdown(URLContext *h, int flags)
Signal the URLContext that we are done reading or writing the stream.
Definition: avio.c:846
URL_SCHEME_CHARS
#define URL_SCHEME_CHARS
Definition: avio.c:301
time.h
ffio_geturlcontext
URLContext * ffio_geturlcontext(AVIOContext *s)
Return the URLContext associated with the AVIOContext.
Definition: avio.c:106
AV_OPT_FLAG_ENCODING_PARAM
#define AV_OPT_FLAG_ENCODING_PARAM
A generic parameter which can be set by the user for muxing or encoding.
Definition: opt.h:269
c
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
Definition: undefined.txt:32
avio_read_dir
int avio_read_dir(AVIODirContext *s, AVIODirEntry **next)
Get next directory entry.
Definition: avio.c:762
av_opt_copy
int av_opt_copy(void *dst, const void *src)
Copy options from src object into dest object.
Definition: opt.c:2105
AVIOContext
Bytestream IO Context.
Definition: avio.h:160
url_context_class
static const AVClass url_context_class
Definition: avio.c:66
OFFSET
#define OFFSET(x)
Definition: avio.c:56
ffurl_get_multi_file_handle
int ffurl_get_multi_file_handle(URLContext *h, int **handles, int *numhandles)
Return the file descriptors associated with this URL.
Definition: avio.c:820
av_err2str
#define av_err2str(errnum)
Convenience macro, the return value should be used only directly in function arguments but never stan...
Definition: error.h:121
URLProtocol::priv_data_class
const AVClass * priv_data_class
Definition: url.h:87
sp
#define sp
Definition: regdef.h:63
URL_PROTOCOL_FLAG_NESTED_SCHEME
#define URL_PROTOCOL_FLAG_NESTED_SCHEME
Definition: url.h:32
size
int size
Definition: twinvq_data.h:10344
AVIODirEntry
Describes single entry of the directory.
Definition: avio.h:87
URLProtocol::name
const char * name
Definition: url.h:52
AVIO_SEEKABLE_TIME
#define AVIO_SEEKABLE_TIME
Seeking by timestamp with avio_seek_time() is possible.
Definition: avio.h:46
URLProtocol::default_whitelist
const char * default_whitelist
Definition: url.h:96
avio_check
int avio_check(const char *url, int flags)
Return AVIO_FLAG_* access flags corresponding to the access permissions of the resource in url,...
Definition: avio.c:663
av_strstart
int av_strstart(const char *str, const char *pfx, const char **ptr)
Return non-zero if pfx is a prefix of str.
Definition: avstring.c:36
ffurl_write2
int ffurl_write2(void *urlcontext, const uint8_t *buf, int size)
Definition: avio.c:563
ffurl_alloc
int ffurl_alloc(URLContext **puc, const char *filename, int flags, const AVIOInterruptCB *int_cb)
Create a URLContext for accessing to the resource indicated by url, but do not initiate the connectio...
Definition: avio.c:348
URLContext
Definition: url.h:35
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:255
avio_internal.h
URLContext::prot
const struct URLProtocol * prot
Definition: url.h:37
ffio_fdopen
int ffio_fdopen(AVIOContext **sp, URLContext *h)
Create and initialize a AVIOContext for accessing the resource referenced by the URLContext h.
Definition: avio.c:411
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
ff_avio_class
const AVClass ff_avio_class
Definition: avio.c:97
url.h
av_mallocz
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
Definition: mem.c:254
avio_open_dir
int avio_open_dir(AVIODirContext **s, const char *url, AVDictionary **options)
Open directory for reading.
Definition: avio.c:724
len
int len
Definition: vorbis_enc_data.h:426
int_cb
const AVIOInterruptCB int_cb
Definition: ffmpeg.c:328
child_class_iterate
static const AVClass * child_class_iterate(void **iter)
Definition: avio.c:82
ffurl_closep
int ffurl_closep(URLContext **hh)
Close the resource accessed by the URLContext h, and free the memory used by it.
Definition: avio.c:587
ret
ret
Definition: filter_design.txt:187
AVClass::class_name
const char * class_name
The name of the class; usually it is the same name as the context structure type to which the AVClass...
Definition: log.h:71
ffurl_read2
int ffurl_read2(void *urlcontext, uint8_t *buf, int size)
Definition: avio.c:547
AVIODirContext
Definition: avio.c:720
ffurl_seek2
int64_t ffurl_seek2(void *urlcontext, int64_t pos, int whence)
Definition: avio.c:576
URLContext::interrupt_callback
AVIOInterruptCB interrupt_callback
Definition: url.h:44
pos
unsigned int pos
Definition: spdifenc.c:413
dict.h
URLProtocol::url_move
int(* url_move)(URLContext *h_src, URLContext *h_dst)
Definition: url.h:95
network.h
options
static const AVOption options[]
Definition: avio.c:59
url_find_protocol
static const struct URLProtocol * url_find_protocol(const char *filename)
Definition: avio.c:306
AVIO_SEEKABLE_NORMAL
#define AVIO_SEEKABLE_NORMAL
Seeking works like for a local file.
Definition: avio.h:41
buffer
the frame and frame reference mechanism is intended to as much as expensive copies of that data while still allowing the filters to produce correct results The data is stored in buffers represented by AVFrame structures Several references can point to the same frame buffer
Definition: filter_design.txt:49
URLContext::av_class
const AVClass * av_class
information for av_log().
Definition: url.h:36
retry_transfer_wrapper
static int retry_transfer_wrapper(URLContext *h, uint8_t *buf, const uint8_t *cbuf, int size, int size_min, int read)
Definition: avio.c:502
AVSEEK_FORCE
#define AVSEEK_FORCE
Passing this flag as the "whence" parameter to a seek function causes it to seek by any means (like r...
Definition: avio.h:476
URLContext::is_streamed
int is_streamed
true if streamed (no seek possible), default = false
Definition: url.h:42
AVIO_FLAG_DIRECT
#define AVIO_FLAG_DIRECT
Use direct mode.
Definition: avio.h:644
AVIO_FLAG_READ
#define AVIO_FLAG_READ
read-only
Definition: avio.h:617
av_strdup
char * av_strdup(const char *s)
Duplicate a string.
Definition: mem.c:270
AV_OPT_FLAG_DECODING_PARAM
#define AV_OPT_FLAG_DECODING_PARAM
A generic parameter which can be set by the user for demuxing or decoding.
Definition: opt.h:273
avio_open2
int avio_open2(AVIOContext **s, const char *filename, int flags, const AVIOInterruptCB *int_cb, AVDictionary **options)
Create and initialize a AVIOContext for accessing the resource indicated by url.
Definition: avio.c:490
ffurl_read_complete
int ffurl_read_complete(URLContext *h, unsigned char *buf, int size)
Read as many bytes as possible (up to size), calling the read function multiple times if necessary.
Definition: avio.c:556
URLProtocol::priv_data_size
int priv_data_size
Definition: url.h:88
av_free
#define av_free(p)
Definition: tableprint_vlc.h:33
AVDictionaryEntry
Definition: dict.h:89
ffurl_handshake
int ffurl_handshake(URLContext *c)
Perform one step of the protocol handshake to accept a new client.
Definition: avio.c:283
AVIO_FLAG_NONBLOCK
#define AVIO_FLAG_NONBLOCK
Use non-blocking mode.
Definition: avio.h:636
avio_closep
int avio_closep(AVIOContext **s)
Close the resource accessed by the AVIOContext *s, free it and set the pointer pointing to it to NULL...
Definition: avio.c:648
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:34
av_dict_set
int av_dict_set(AVDictionary **pm, const char *key, const char *value, int flags)
Set the given entry in *pm, overwriting an existing entry.
Definition: dict.c:88
URLProtocol::url_write
int(* url_write)(URLContext *h, const unsigned char *buf, int size)
Definition: url.h:76
AVIODirContext::url_context
struct URLContext * url_context
Definition: avio.c:721
avio_find_protocol_name
const char * avio_find_protocol_name(const char *url)
Return the name of the protocol that will handle the passed URL.
Definition: avio.c:656
flags
#define flags(name, subs,...)
Definition: cbs_av1.c:482
avio_close
int avio_close(AVIOContext *s)
Close the resource accessed by the AVIOContext s and free it.
Definition: avio.c:615
av_strlcpy
size_t av_strlcpy(char *dst, const char *src, size_t size)
Copy the string src to dst, but no more than size - 1 bytes, and null-terminate dst.
Definition: avstring.c:85
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
ffurl_size
int64_t ffurl_size(URLContext *h)
Return the filesize of the resource accessed by h, AVERROR(ENOSYS) if the operation is not supported ...
Definition: avio.c:798
h
h
Definition: vp9dsp_template.c:2038
AVERROR_EXIT
#define AVERROR_EXIT
Immediate exit was requested; the called function should not be restarted.
Definition: error.h:58
av_opt_set_dict
int av_opt_set_dict(void *obj, AVDictionary **options)
Set all the options from a given dictionary on an object.
Definition: opt.c:1945
AVDictionaryEntry::value
char * value
Definition: dict.h:91
avstring.h
AV_OPT_TYPE_STRING
@ AV_OPT_TYPE_STRING
Definition: opt.h:239
ffurl_delete
int ffurl_delete(const char *url)
Delete a resource.
Definition: avio.c:704
AVERROR_PROTOCOL_NOT_FOUND
#define AVERROR_PROTOCOL_NOT_FOUND
Protocol not found.
Definition: error.h:65
ffurl_get_file_handle
int ffurl_get_file_handle(URLContext *h)
Return the file descriptor associated with this URL.
Definition: avio.c:813
URLProtocol::url_open2
int(* url_open2)(URLContext *h, const char *url, int flags, AVDictionary **options)
This callback is to be used by protocols which open further nested protocols.
Definition: url.h:59
read
static uint32_t BS_FUNC() read(BSCTX *bc, unsigned int n)
Return n bits from the buffer, n has to be in the 0-32 range.
Definition: bitstream_template.h:231