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/mem.h"
25 #include "libavutil/opt.h"
26 #include "libavutil/time.h"
27 #include "libavutil/avassert.h"
28 #include "avio_internal.h"
29 #include "os_support.h"
30 #include "internal.h"
31 #if CONFIG_NETWORK
32 #include "network.h"
33 #endif
34 #include "url.h"
35 
36 #define IO_BUFFER_SIZE 32768
37 
38 /** @name Logging context. */
39 /*@{*/
40 static const char *urlcontext_to_name(void *ptr)
41 {
42  URLContext *h = (URLContext *)ptr;
43  if (h->prot)
44  return h->prot->name;
45  else
46  return "NULL";
47 }
48 
49 static void *urlcontext_child_next(void *obj, void *prev)
50 {
51  URLContext *h = obj;
52  if (!prev && h->priv_data && h->prot->priv_data_class)
53  return h->priv_data;
54  return NULL;
55 }
56 
57 #define OFFSET(x) offsetof(URLContext,x)
58 #define E AV_OPT_FLAG_ENCODING_PARAM
59 #define D AV_OPT_FLAG_DECODING_PARAM
60 static const AVOption options[] = {
61  {"protocol_whitelist", "List of protocols that are allowed to be used", OFFSET(protocol_whitelist), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, D },
62  {"protocol_blacklist", "List of protocols that are not allowed to be used", OFFSET(protocol_blacklist), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, D },
63  {"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 },
64  { NULL }
65 };
66 
67 static const AVClass url_context_class = {
68  .class_name = "URLContext",
69  .item_name = urlcontext_to_name,
70  .option = options,
71  .version = LIBAVUTIL_VERSION_INT,
72  .child_next = urlcontext_child_next,
73  .child_class_iterate = ff_urlcontext_child_class_iterate,
74 };
75 /*@}*/
76 
77 static void *avio_child_next(void *obj, void *prev)
78 {
79  AVIOContext *s = obj;
80  return prev ? NULL : s->opaque;
81 }
82 
83 static const AVClass *child_class_iterate(void **iter)
84 {
85  const AVClass *c = *iter ? NULL : &url_context_class;
86  *iter = (void*)(uintptr_t)c;
87  return c;
88 }
89 
90 #define AVIOOFFSET(x) offsetof(AVIOContext,x)
91 #define E AV_OPT_FLAG_ENCODING_PARAM
92 #define D AV_OPT_FLAG_DECODING_PARAM
93 static const AVOption avio_options[] = {
94  {"protocol_whitelist", "List of protocols that are allowed to be used", AVIOOFFSET(protocol_whitelist), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, D },
95  { NULL },
96 };
97 
99  .class_name = "AVIOContext",
100  .item_name = av_default_item_name,
101  .version = LIBAVUTIL_VERSION_INT,
102  .option = avio_options,
103  .child_next = avio_child_next,
104  .child_class_iterate = child_class_iterate,
105 };
106 
108 {
109  if (!s)
110  return NULL;
111 
112  if (s->opaque && s->read_packet == ffurl_read2)
113  return s->opaque;
114  else
115  return NULL;
116 }
117 
118 static int url_alloc_for_protocol(URLContext **puc, const URLProtocol *up,
119  const char *filename, int flags,
120  const AVIOInterruptCB *int_cb)
121 {
122  URLContext *uc;
123  int err;
124 
125 #if CONFIG_NETWORK
127  return AVERROR(EIO);
128 #endif
129  if ((flags & AVIO_FLAG_READ) && !up->url_read) {
131  "Impossible to open the '%s' protocol for reading\n", up->name);
132  return AVERROR(EIO);
133  }
134  if ((flags & AVIO_FLAG_WRITE) && !up->url_write) {
136  "Impossible to open the '%s' protocol for writing\n", up->name);
137  return AVERROR(EIO);
138  }
139  uc = av_mallocz(sizeof(URLContext) + strlen(filename) + 1);
140  if (!uc) {
141  err = AVERROR(ENOMEM);
142  goto fail;
143  }
145  uc->filename = (char *)&uc[1];
146  strcpy(uc->filename, filename);
147  uc->prot = up;
148  uc->flags = flags;
149  uc->is_streamed = 0; /* default = not streamed */
150  uc->max_packet_size = 0; /* default: stream file */
151  if (up->priv_data_size) {
153  if (!uc->priv_data) {
154  err = AVERROR(ENOMEM);
155  goto fail;
156  }
157  if (up->priv_data_class) {
158  char *start;
159  *(const AVClass **)uc->priv_data = up->priv_data_class;
161  if (av_strstart(uc->filename, up->name, (const char**)&start) && *start == ',') {
162  int ret= 0;
163  char *p= start;
164  char sep= *++p;
165  char *key, *val;
166  p++;
167 
168  if (strcmp(up->name, "subfile"))
169  ret = AVERROR(EINVAL);
170 
171  while(ret >= 0 && (key= strchr(p, sep)) && p<key && (val = strchr(key+1, sep))){
172  *val= *key= 0;
173  ret = av_opt_set(uc->priv_data, p, key+1, 0);
175  av_log(uc, AV_LOG_ERROR, "Key '%s' not found.\n", p);
176  *val= *key= sep;
177  p= val+1;
178  }
179  if(ret<0 || p!=key){
180  av_log(uc, AV_LOG_ERROR, "Error parsing options string %s\n", start);
181  err = AVERROR(EINVAL);
182  goto fail;
183  }
184  memmove(start, key+1, strlen(key));
185  }
186  }
187  }
188  if (int_cb)
189  uc->interrupt_callback = *int_cb;
190 
191  *puc = uc;
192  return 0;
193 fail:
194  *puc = NULL;
195  if (uc)
196  av_freep(&uc->priv_data);
197  av_freep(&uc);
198 #if CONFIG_NETWORK
201 #endif
202  return err;
203 }
204 
206 {
207  int err;
208  AVDictionary *tmp_opts = NULL;
210 
211  if (!options)
212  options = &tmp_opts;
213 
214  // Check that URLContext was initialized correctly and lists are matching if set
215  av_assert0(!(e=av_dict_get(*options, "protocol_whitelist", NULL, 0)) ||
216  (uc->protocol_whitelist && !strcmp(uc->protocol_whitelist, e->value)));
217  av_assert0(!(e=av_dict_get(*options, "protocol_blacklist", NULL, 0)) ||
218  (uc->protocol_blacklist && !strcmp(uc->protocol_blacklist, e->value)));
219 
220  if (uc->protocol_whitelist && av_match_list(uc->prot->name, uc->protocol_whitelist, ',') <= 0) {
221  av_log(uc, AV_LOG_ERROR, "Protocol '%s' not on whitelist '%s'!\n", uc->prot->name, uc->protocol_whitelist);
222  return AVERROR(EINVAL);
223  }
224 
225  if (uc->protocol_blacklist && av_match_list(uc->prot->name, uc->protocol_blacklist, ',') > 0) {
226  av_log(uc, AV_LOG_ERROR, "Protocol '%s' on blacklist '%s'!\n", uc->prot->name, uc->protocol_blacklist);
227  return AVERROR(EINVAL);
228  }
229 
230  if (!uc->protocol_whitelist && uc->prot->default_whitelist) {
231  av_log(uc, AV_LOG_DEBUG, "Setting default whitelist '%s'\n", uc->prot->default_whitelist);
233  if (!uc->protocol_whitelist) {
234  return AVERROR(ENOMEM);
235  }
236  } else if (!uc->protocol_whitelist)
237  av_log(uc, AV_LOG_DEBUG, "No default whitelist set\n"); // This should be an error once all declare a default whitelist
238 
239  if ((err = av_dict_set(options, "protocol_whitelist", uc->protocol_whitelist, 0)) < 0)
240  return err;
241  if ((err = av_dict_set(options, "protocol_blacklist", uc->protocol_blacklist, 0)) < 0)
242  return err;
243 
244  err =
245  uc->prot->url_open2 ? uc->prot->url_open2(uc,
246  uc->filename,
247  uc->flags,
248  options) :
249  uc->prot->url_open(uc, uc->filename, uc->flags);
250 
251  av_dict_set(options, "protocol_whitelist", NULL, 0);
252  av_dict_set(options, "protocol_blacklist", NULL, 0);
253 
254  if (err)
255  return err;
256  uc->is_connected = 1;
257  /* We must be careful here as ffurl_seek() could be slow,
258  * for example for http */
259  if ((uc->flags & AVIO_FLAG_WRITE) || !strcmp(uc->prot->name, "file"))
260  if (!uc->is_streamed && ffurl_seek(uc, 0, SEEK_SET) < 0)
261  uc->is_streamed = 1;
262  return 0;
263 }
264 
266 {
267  av_assert0(!*c);
268  if (s->prot->url_accept)
269  return s->prot->url_accept(s, c);
270  return AVERROR(EBADF);
271 }
272 
274 {
275  int ret;
276  URLContext *sc = s->opaque;
277  URLContext *cc = NULL;
278  ret = ffurl_accept(sc, &cc);
279  if (ret < 0)
280  return ret;
281  return ffio_fdopen(c, cc);
282 }
283 
285 {
286  int ret;
287  if (c->prot->url_handshake) {
288  ret = c->prot->url_handshake(c);
289  if (ret)
290  return ret;
291  }
292  c->is_connected = 1;
293  return 0;
294 }
295 
297 {
298  URLContext *cc = c->opaque;
299  return ffurl_handshake(cc);
300 }
301 
302 #define URL_SCHEME_CHARS \
303  "abcdefghijklmnopqrstuvwxyz" \
304  "ABCDEFGHIJKLMNOPQRSTUVWXYZ" \
305  "0123456789+-."
306 
307 static const struct URLProtocol *url_find_protocol(const char *filename)
308 {
309  const URLProtocol **protocols;
310  char proto_str[128], proto_nested[128], *ptr;
311  size_t proto_len = strspn(filename, URL_SCHEME_CHARS);
312  int i;
313 
314  if (filename[proto_len] != ':' &&
315  (strncmp(filename, "subfile,", 8) || !strchr(filename + proto_len + 1, ':')) ||
316  is_dos_path(filename))
317  strcpy(proto_str, "file");
318  else
319  av_strlcpy(proto_str, filename,
320  FFMIN(proto_len + 1, sizeof(proto_str)));
321 
322  av_strlcpy(proto_nested, proto_str, sizeof(proto_nested));
323  if ((ptr = strchr(proto_nested, '+')))
324  *ptr = '\0';
325 
326  protocols = ffurl_get_protocols(NULL, NULL);
327  if (!protocols)
328  return NULL;
329  for (i = 0; protocols[i]; i++) {
330  const URLProtocol *up = protocols[i];
331  if (!strcmp(proto_str, up->name)) {
332  av_freep(&protocols);
333  return up;
334  }
336  !strcmp(proto_nested, up->name)) {
337  av_freep(&protocols);
338  return up;
339  }
340  }
341  av_freep(&protocols);
342  if (av_strstart(filename, "https:", NULL) || av_strstart(filename, "tls:", NULL))
343  av_log(NULL, AV_LOG_WARNING, "https protocol not found, recompile FFmpeg with "
344  "openssl, gnutls or securetransport enabled.\n");
345 
346  return NULL;
347 }
348 
349 int ffurl_alloc(URLContext **puc, const char *filename, int flags,
350  const AVIOInterruptCB *int_cb)
351 {
352  const URLProtocol *p = NULL;
353 
354  p = url_find_protocol(filename);
355  if (p)
356  return url_alloc_for_protocol(puc, p, filename, flags, int_cb);
357 
358  *puc = NULL;
360 }
361 
362 int ffurl_open_whitelist(URLContext **puc, const char *filename, int flags,
364  const char *whitelist, const char* blacklist,
365  URLContext *parent)
366 {
367  AVDictionary *tmp_opts = NULL;
369  int ret = ffurl_alloc(puc, filename, flags, int_cb);
370  if (ret < 0)
371  return ret;
372  if (parent) {
373  ret = av_opt_copy(*puc, parent);
374  if (ret < 0)
375  goto fail;
376  }
377  if (options &&
378  (ret = av_opt_set_dict(*puc, options)) < 0)
379  goto fail;
380  if (options && (*puc)->prot->priv_data_class &&
381  (ret = av_opt_set_dict((*puc)->priv_data, options)) < 0)
382  goto fail;
383 
384  if (!options)
385  options = &tmp_opts;
386 
387  av_assert0(!whitelist ||
388  !(e=av_dict_get(*options, "protocol_whitelist", NULL, 0)) ||
389  !strcmp(whitelist, e->value));
390  av_assert0(!blacklist ||
391  !(e=av_dict_get(*options, "protocol_blacklist", NULL, 0)) ||
392  !strcmp(blacklist, e->value));
393 
394  if ((ret = av_dict_set(options, "protocol_whitelist", whitelist, 0)) < 0)
395  goto fail;
396 
397  if ((ret = av_dict_set(options, "protocol_blacklist", blacklist, 0)) < 0)
398  goto fail;
399 
400  if ((ret = av_opt_set_dict(*puc, options)) < 0)
401  goto fail;
402 
403  ret = ffurl_connect(*puc, options);
404 
405  if (!ret)
406  return 0;
407 fail:
408  ffurl_closep(puc);
409  return ret;
410 }
411 
413 {
414  AVIOContext *s;
415  uint8_t *buffer = NULL;
416  int buffer_size, max_packet_size;
417 
418  max_packet_size = h->max_packet_size;
419  if (max_packet_size) {
420  buffer_size = max_packet_size; /* no need to bufferize more than one packet */
421  } else {
422  buffer_size = IO_BUFFER_SIZE;
423  }
424  if (!(h->flags & AVIO_FLAG_WRITE) && h->is_streamed) {
425  if (buffer_size > INT_MAX/2)
426  return AVERROR(EINVAL);
427  buffer_size *= 2;
428  }
429  buffer = av_malloc(buffer_size);
430  if (!buffer)
431  return AVERROR(ENOMEM);
432 
433  *sp = avio_alloc_context(buffer, buffer_size, h->flags & AVIO_FLAG_WRITE, h,
435  if (!*sp) {
436  av_freep(&buffer);
437  return AVERROR(ENOMEM);
438  }
439  s = *sp;
440  if (h->protocol_whitelist) {
441  s->protocol_whitelist = av_strdup(h->protocol_whitelist);
442  if (!s->protocol_whitelist) {
443  avio_closep(sp);
444  return AVERROR(ENOMEM);
445  }
446  }
447  if (h->protocol_blacklist) {
448  s->protocol_blacklist = av_strdup(h->protocol_blacklist);
449  if (!s->protocol_blacklist) {
450  avio_closep(sp);
451  return AVERROR(ENOMEM);
452  }
453  }
454  s->direct = h->flags & AVIO_FLAG_DIRECT;
455 
456  s->seekable = h->is_streamed ? 0 : AVIO_SEEKABLE_NORMAL;
457  s->max_packet_size = max_packet_size;
458  s->min_packet_size = h->min_packet_size;
459  if(h->prot) {
460  s->read_pause = h->prot->url_read_pause;
461  s->read_seek = h->prot->url_read_seek;
462 
463  if (h->prot->url_read_seek)
464  s->seekable |= AVIO_SEEKABLE_TIME;
465  }
466  ((FFIOContext*)s)->short_seek_get = ffurl_get_short_seek;
467  s->av_class = &ff_avio_class;
468  return 0;
469 }
470 
471 int ffio_open_whitelist(AVIOContext **s, const char *filename, int flags,
473  const char *whitelist, const char *blacklist)
474 {
475  URLContext *h;
476  int err;
477 
478  *s = NULL;
479 
480  err = ffurl_open_whitelist(&h, filename, flags, int_cb, options, whitelist, blacklist, NULL);
481  if (err < 0)
482  return err;
483  err = ffio_fdopen(s, h);
484  if (err < 0) {
485  ffurl_close(h);
486  return err;
487  }
488  return 0;
489 }
490 
491 int avio_open2(AVIOContext **s, const char *filename, int flags,
493 {
494  return ffio_open_whitelist(s, filename, flags, int_cb, options, NULL, NULL);
495 }
496 
497 int avio_open(AVIOContext **s, const char *filename, int flags)
498 {
499  return avio_open2(s, filename, flags, NULL, NULL);
500 }
501 
502 
503 static inline int retry_transfer_wrapper(URLContext *h, uint8_t *buf,
504  const uint8_t *cbuf,
505  int size, int size_min,
506  int read)
507 {
508  int ret, len;
509  int fast_retries = 5;
510  int64_t wait_since = 0;
511 
512  len = 0;
513  while (len < size_min) {
514  if (ff_check_interrupt(&h->interrupt_callback))
515  return AVERROR_EXIT;
516  ret = read ? h->prot->url_read (h, buf + len, size - len):
517  h->prot->url_write(h, cbuf + len, size - len);
518  if (ret == AVERROR(EINTR))
519  continue;
520  if (h->flags & AVIO_FLAG_NONBLOCK)
521  return ret;
522  if (ret == AVERROR(EAGAIN)) {
523  ret = 0;
524  if (fast_retries) {
525  fast_retries--;
526  } else {
527  if (h->rw_timeout) {
528  if (!wait_since)
529  wait_since = av_gettime_relative();
530  else if (av_gettime_relative() > wait_since + h->rw_timeout)
531  return AVERROR(EIO);
532  }
533  av_usleep(1000);
534  }
535  } else if (ret == AVERROR_EOF)
536  return (len > 0) ? len : AVERROR_EOF;
537  else if (ret < 0)
538  return ret;
539  if (ret) {
540  fast_retries = FFMAX(fast_retries, 2);
541  wait_since = 0;
542  }
543  len += ret;
544  }
545  return len;
546 }
547 
548 int ffurl_read2(void *urlcontext, uint8_t *buf, int size)
549 {
550  URLContext *h = urlcontext;
551 
552  if (!(h->flags & AVIO_FLAG_READ))
553  return AVERROR(EIO);
554  return retry_transfer_wrapper(h, buf, NULL, size, 1, 1);
555 }
556 
557 int ffurl_read_complete(URLContext *h, unsigned char *buf, int size)
558 {
559  if (!(h->flags & AVIO_FLAG_READ))
560  return AVERROR(EIO);
561  return retry_transfer_wrapper(h, buf, NULL, size, size, 1);
562 }
563 
564 int ffurl_write2(void *urlcontext, const uint8_t *buf, int size)
565 {
566  URLContext *h = urlcontext;
567 
568  if (!(h->flags & AVIO_FLAG_WRITE))
569  return AVERROR(EIO);
570  /* avoid sending too big packets */
571  if (h->max_packet_size && size > h->max_packet_size)
572  return AVERROR(EIO);
573 
574  return retry_transfer_wrapper(h, NULL, buf, size, size, 0);
575 }
576 
577 int64_t ffurl_seek2(void *urlcontext, int64_t pos, int whence)
578 {
579  URLContext *h = urlcontext;
580  int64_t ret;
581 
582  if (!h->prot->url_seek)
583  return AVERROR(ENOSYS);
584  ret = h->prot->url_seek(h, pos, whence & ~AVSEEK_FORCE);
585  return ret;
586 }
587 
589 {
590  URLContext *h= *hh;
591  int ret = 0;
592  if (!h)
593  return 0; /* can happen when ffurl_open fails */
594 
595  if (h->is_connected && h->prot->url_close)
596  ret = h->prot->url_close(h);
597 #if CONFIG_NETWORK
598  if (h->prot->flags & URL_PROTOCOL_FLAG_NETWORK)
600 #endif
601  if (h->prot->priv_data_size) {
602  if (h->prot->priv_data_class)
603  av_opt_free(h->priv_data);
604  av_freep(&h->priv_data);
605  }
606  av_opt_free(h);
607  av_freep(hh);
608  return ret;
609 }
610 
612 {
613  return ffurl_closep(&h);
614 }
615 
617 {
618  FFIOContext *const ctx = ffiocontext(s);
619  URLContext *h;
620  int ret, error;
621 
622  if (!s)
623  return 0;
624 
625  avio_flush(s);
626  h = s->opaque;
627  s->opaque = NULL;
628 
629  av_freep(&s->buffer);
630  if (s->write_flag)
632  "Statistics: %"PRId64" bytes written, %d seeks, %d writeouts\n",
633  ctx->bytes_written, ctx->seek_count, ctx->writeout_count);
634  else
635  av_log(s, AV_LOG_VERBOSE, "Statistics: %"PRId64" bytes read, %d seeks\n",
636  ctx->bytes_read, ctx->seek_count);
637  av_opt_free(s);
638 
639  error = s->error;
641 
642  ret = ffurl_close(h);
643  if (ret < 0)
644  return ret;
645 
646  return error;
647 }
648 
650 {
651  int ret = avio_close(*s);
652  *s = NULL;
653  return ret;
654 }
655 
656 
657 const char *avio_find_protocol_name(const char *url)
658 {
659  const URLProtocol *p = url_find_protocol(url);
660 
661  return p ? p->name : NULL;
662 }
663 
664 int avio_check(const char *url, int flags)
665 {
666  URLContext *h;
667  int ret = ffurl_alloc(&h, url, flags, NULL);
668  if (ret < 0)
669  return ret;
670 
671  if (h->prot->url_check) {
672  ret = h->prot->url_check(h, flags);
673  } else {
674  ret = ffurl_connect(h, NULL);
675  if (ret >= 0)
676  ret = flags;
677  }
678 
679  ffurl_close(h);
680  return ret;
681 }
682 
683 int ffurl_move(const char *url_src, const char *url_dst)
684 {
685  URLContext *h_src, *h_dst;
686  int ret = ffurl_alloc(&h_src, url_src, AVIO_FLAG_READ_WRITE, NULL);
687  if (ret < 0)
688  return ret;
689  ret = ffurl_alloc(&h_dst, url_dst, AVIO_FLAG_WRITE, NULL);
690  if (ret < 0) {
691  ffurl_close(h_src);
692  return ret;
693  }
694 
695  if (h_src->prot == h_dst->prot && h_src->prot->url_move)
696  ret = h_src->prot->url_move(h_src, h_dst);
697  else
698  ret = AVERROR(ENOSYS);
699 
700  ffurl_close(h_src);
701  ffurl_close(h_dst);
702  return ret;
703 }
704 
705 int ffurl_delete(const char *url)
706 {
707  URLContext *h;
708  int ret = ffurl_alloc(&h, url, AVIO_FLAG_WRITE, NULL);
709  if (ret < 0)
710  return ret;
711 
712  if (h->prot->url_delete)
713  ret = h->prot->url_delete(h);
714  else
715  ret = AVERROR(ENOSYS);
716 
717  ffurl_close(h);
718  return ret;
719 }
720 
723 };
724 
726 {
727  URLContext *h = NULL;
729  int ret;
730  av_assert0(s);
731 
732  ctx = av_mallocz(sizeof(*ctx));
733  if (!ctx) {
734  ret = AVERROR(ENOMEM);
735  goto fail;
736  }
737 
738  if ((ret = ffurl_alloc(&h, url, AVIO_FLAG_READ, NULL)) < 0)
739  goto fail;
740 
741  if (h->prot->url_open_dir && h->prot->url_read_dir && h->prot->url_close_dir) {
742  if (options && h->prot->priv_data_class &&
743  (ret = av_opt_set_dict(h->priv_data, options)) < 0)
744  goto fail;
745  ret = h->prot->url_open_dir(h);
746  } else
747  ret = AVERROR(ENOSYS);
748  if (ret < 0)
749  goto fail;
750 
751  h->is_connected = 1;
752  ctx->url_context = h;
753  *s = ctx;
754  return 0;
755 
756  fail:
757  av_free(ctx);
758  *s = NULL;
759  ffurl_close(h);
760  return ret;
761 }
762 
764 {
765  URLContext *h;
766  int ret;
767 
768  if (!s || !s->url_context)
769  return AVERROR(EINVAL);
770  h = s->url_context;
771  if ((ret = h->prot->url_read_dir(h, next)) < 0)
773  return ret;
774 }
775 
777 {
778  URLContext *h;
779 
780  av_assert0(s);
781  if (!(*s) || !(*s)->url_context)
782  return AVERROR(EINVAL);
783  h = (*s)->url_context;
784  h->prot->url_close_dir(h);
785  ffurl_close(h);
786  av_freep(s);
787  *s = NULL;
788  return 0;
789 }
790 
792 {
793  if (!entry || !*entry)
794  return;
795  av_free((*entry)->name);
796  av_freep(entry);
797 }
798 
800 {
801  int64_t pos, size;
802 
803  size = ffurl_seek(h, 0, AVSEEK_SIZE);
804  if (size < 0) {
805  pos = ffurl_seek(h, 0, SEEK_CUR);
806  if ((size = ffurl_seek(h, -1, SEEK_END)) < 0)
807  return size;
808  size++;
809  ffurl_seek(h, pos, SEEK_SET);
810  }
811  return size;
812 }
813 
815 {
816  if (!h || !h->prot || !h->prot->url_get_file_handle)
817  return -1;
818  return h->prot->url_get_file_handle(h);
819 }
820 
821 int ffurl_get_multi_file_handle(URLContext *h, int **handles, int *numhandles)
822 {
823  if (!h || !h->prot)
824  return AVERROR(ENOSYS);
825  if (!h->prot->url_get_multi_file_handle) {
826  if (!h->prot->url_get_file_handle)
827  return AVERROR(ENOSYS);
828  *handles = av_malloc(sizeof(**handles));
829  if (!*handles)
830  return AVERROR(ENOMEM);
831  *numhandles = 1;
832  *handles[0] = h->prot->url_get_file_handle(h);
833  return 0;
834  }
835  return h->prot->url_get_multi_file_handle(h, handles, numhandles);
836 }
837 
838 int ffurl_get_short_seek(void *urlcontext)
839 {
840  URLContext *h = urlcontext;
841 
842  if (!h || !h->prot || !h->prot->url_get_short_seek)
843  return AVERROR(ENOSYS);
844  return h->prot->url_get_short_seek(h);
845 }
846 
848 {
849  if (!h || !h->prot || !h->prot->url_shutdown)
850  return AVERROR(ENOSYS);
851  return h->prot->url_shutdown(h, flags);
852 }
853 
855 {
856  if (cb && cb->callback)
857  return cb->callback(cb->opaque);
858  return 0;
859 }
860 
861 int ff_rename(const char *url_src, const char *url_dst, void *logctx)
862 {
863  int ret = ffurl_move(url_src, url_dst);
864  if (ret < 0)
865  av_log(logctx, AV_LOG_ERROR, "failed to rename file %s to %s: %s\n", url_src, url_dst, av_err2str(ret));
866  return ret;
867 }
error
static void error(const char *err)
Definition: target_bsf_fuzzer.c:32
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:471
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:1640
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:90
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:242
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:273
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:126
avio_handshake
int avio_handshake(AVIOContext *c)
Perform one step of the protocol handshake to accept a new client.
Definition: avio.c:296
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:109
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:497
IO_BUFFER_SIZE
#define IO_BUFFER_SIZE
Definition: avio.c:36
AV_LOG_VERBOSE
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:196
ffurl_close
int ffurl_close(URLContext *h)
Definition: avio.c:611
urlcontext_to_name
static const char * urlcontext_to_name(void *ptr)
Definition: avio.c:40
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:838
avio_options
static const AVOption avio_options[]
Definition: avio.c:93
ffurl_connect
int ffurl_connect(URLContext *uc, AVDictionary **options)
Connect an URLContext that has been allocated by ffurl_alloc.
Definition: avio.c:205
av_opt_free
void av_opt_free(void *obj)
Free all allocated objects in obj.
Definition: opt.c:1910
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:740
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:854
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:861
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:791
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:118
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:362
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:776
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:49
avio_child_next
static void * avio_child_next(void *obj, void *prev)
Definition: avio.c:77
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:223
ffurl_accept
int ffurl_accept(URLContext *s, URLContext **c)
Accept an URLContext c on an URLContext s.
Definition: avio.c:265
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:92
NULL
#define NULL
Definition: coverity.c:32
urlcontext_child_next
static void * urlcontext_child_next(void *obj, void *prev)
Definition: avio.c:49
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:683
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:847
URL_SCHEME_CHARS
#define URL_SCHEME_CHARS
Definition: avio.c:302
time.h
ffio_geturlcontext
URLContext * ffio_geturlcontext(AVIOContext *s)
Return the URLContext associated with the AVIOContext.
Definition: avio.c:107
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:763
av_opt_copy
int av_opt_copy(void *dst, const void *src)
Copy options from src object into dest object.
Definition: opt.c:2110
AVIOContext
Bytestream IO Context.
Definition: avio.h:160
url_context_class
static const AVClass url_context_class
Definition: avio.c:67
OFFSET
#define OFFSET(x)
Definition: avio.c:57
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:821
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:664
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:564
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:349
URLContext
Definition: url.h:35
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:256
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:412
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
ff_avio_class
const AVClass ff_avio_class
Definition: avio.c:98
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:256
avio_open_dir
int avio_open_dir(AVIODirContext **s, const char *url, AVDictionary **options)
Open directory for reading.
Definition: avio.c:725
len
int len
Definition: vorbis_enc_data.h:426
int_cb
const AVIOInterruptCB int_cb
Definition: ffmpeg.c:306
child_class_iterate
static const AVClass * child_class_iterate(void **iter)
Definition: avio.c:83
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:588
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:548
AVIODirContext
Definition: avio.c:721
ffurl_seek2
int64_t ffurl_seek2(void *urlcontext, int64_t pos, int whence)
Definition: avio.c:577
URLContext::interrupt_callback
AVIOInterruptCB interrupt_callback
Definition: url.h:44
pos
unsigned int pos
Definition: spdifenc.c:414
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:60
url_find_protocol
static const struct URLProtocol * url_find_protocol(const char *filename)
Definition: avio.c:307
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:503
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:272
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
mem.h
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:491
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:557
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:284
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:649
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:722
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:657
flags
#define flags(name, subs,...)
Definition: cbs_av1.c:474
avio_close
int avio_close(AVIOContext *s)
Close the resource accessed by the AVIOContext s and free it.
Definition: avio.c:616
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:799
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:1947
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:705
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:814
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