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 urlcontext_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 = urlcontext_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  goto fail;
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 fail:
265  if (options == &tmp_opts)
266  av_dict_free(&tmp_opts);
267  return err;
268 }
269 
271 {
272  av_assert0(!*c);
273  if (s->prot->url_accept)
274  return s->prot->url_accept(s, c);
275  return AVERROR(EBADF);
276 }
277 
279 {
280  int ret;
281  URLContext *sc = s->opaque;
282  URLContext *cc = NULL;
283  ret = ffurl_accept(sc, &cc);
284  if (ret < 0)
285  return ret;
286  return ffio_fdopen(c, cc);
287 }
288 
290 {
291  int ret;
292  if (c->prot->url_handshake) {
293  ret = c->prot->url_handshake(c);
294  if (ret)
295  return ret;
296  }
297  c->is_connected = 1;
298  return 0;
299 }
300 
302 {
303  URLContext *cc = c->opaque;
304  return ffurl_handshake(cc);
305 }
306 
307 #define URL_SCHEME_CHARS \
308  "abcdefghijklmnopqrstuvwxyz" \
309  "ABCDEFGHIJKLMNOPQRSTUVWXYZ" \
310  "0123456789+-."
311 
312 static const struct URLProtocol *url_find_protocol(const char *filename)
313 {
314  const URLProtocol **protocols;
315  char proto_str[128], proto_nested[128], *ptr;
316  size_t proto_len = strspn(filename, URL_SCHEME_CHARS);
317  int i;
318 
319  if (filename[proto_len] != ':' &&
320  (strncmp(filename, "subfile,", 8) || !strchr(filename + proto_len + 1, ':')) ||
321  is_dos_path(filename))
322  strcpy(proto_str, "file");
323  else
324  av_strlcpy(proto_str, filename,
325  FFMIN(proto_len + 1, sizeof(proto_str)));
326 
327  av_strlcpy(proto_nested, proto_str, sizeof(proto_nested));
328  if ((ptr = strchr(proto_nested, '+')))
329  *ptr = '\0';
330 
331  protocols = ffurl_get_protocols(NULL, NULL);
332  if (!protocols)
333  return NULL;
334  for (i = 0; protocols[i]; i++) {
335  const URLProtocol *up = protocols[i];
336  if (!strcmp(proto_str, up->name)) {
337  av_freep(&protocols);
338  return up;
339  }
341  !strcmp(proto_nested, up->name)) {
342  av_freep(&protocols);
343  return up;
344  }
345  }
346  av_freep(&protocols);
347  if (av_strstart(filename, "https:", NULL) || av_strstart(filename, "tls:", NULL) ||
348  av_strstart(filename, "dtls:", NULL))
349  av_log(NULL, AV_LOG_WARNING, "https or dtls protocol not found, recompile FFmpeg with "
350  "openssl, gnutls or securetransport enabled.\n");
351 
352  return NULL;
353 }
354 
355 int ffurl_alloc(URLContext **puc, const char *filename, int flags,
356  const AVIOInterruptCB *int_cb)
357 {
358  const URLProtocol *p = NULL;
359 
360  p = url_find_protocol(filename);
361  if (p)
362  return url_alloc_for_protocol(puc, p, filename, flags, int_cb);
363 
364  *puc = NULL;
366 }
367 
368 int ffurl_open_whitelist(URLContext **puc, const char *filename, int flags,
370  const char *whitelist, const char* blacklist,
371  URLContext *parent)
372 {
373  AVDictionary *tmp_opts = NULL;
375  int ret = ffurl_alloc(puc, filename, flags, int_cb);
376  if (ret < 0)
377  return ret;
378  if (parent) {
379  ret = av_opt_copy(*puc, parent);
380  if (ret < 0)
381  goto fail;
382  }
383  if (options &&
384  (ret = av_opt_set_dict(*puc, options)) < 0)
385  goto fail;
386  if (options && (*puc)->prot->priv_data_class &&
387  (ret = av_opt_set_dict((*puc)->priv_data, options)) < 0)
388  goto fail;
389 
390  if (!options)
391  options = &tmp_opts;
392 
393  av_assert0(!whitelist ||
394  !(e=av_dict_get(*options, "protocol_whitelist", NULL, 0)) ||
395  !strcmp(whitelist, e->value));
396  av_assert0(!blacklist ||
397  !(e=av_dict_get(*options, "protocol_blacklist", NULL, 0)) ||
398  !strcmp(blacklist, e->value));
399 
400  if ((ret = av_dict_set(options, "protocol_whitelist", whitelist, 0)) < 0)
401  goto fail;
402 
403  if ((ret = av_dict_set(options, "protocol_blacklist", blacklist, 0)) < 0)
404  goto fail;
405 
406  if ((ret = av_opt_set_dict(*puc, options)) < 0)
407  goto fail;
408 
409  ret = ffurl_connect(*puc, options);
410 
411  if (!ret)
412  return 0;
413 fail:
414  ffurl_closep(puc);
415  return ret;
416 }
417 
419 {
420  AVIOContext *s;
421  uint8_t *buffer = NULL;
422  int buffer_size, max_packet_size;
423 
424  max_packet_size = h->max_packet_size;
425  if (max_packet_size) {
426  buffer_size = max_packet_size; /* no need to bufferize more than one packet */
427  } else {
428  buffer_size = IO_BUFFER_SIZE;
429  }
430  if (!(h->flags & AVIO_FLAG_WRITE) && h->is_streamed) {
431  if (buffer_size > INT_MAX/2)
432  return AVERROR(EINVAL);
433  buffer_size *= 2;
434  }
435  buffer = av_malloc(buffer_size);
436  if (!buffer)
437  return AVERROR(ENOMEM);
438 
439  *sp = avio_alloc_context(buffer, buffer_size, h->flags & AVIO_FLAG_WRITE, h,
441  if (!*sp) {
442  av_freep(&buffer);
443  return AVERROR(ENOMEM);
444  }
445  s = *sp;
446  if (h->protocol_whitelist) {
447  s->protocol_whitelist = av_strdup(h->protocol_whitelist);
448  if (!s->protocol_whitelist) {
449  avio_closep(sp);
450  return AVERROR(ENOMEM);
451  }
452  }
453  if (h->protocol_blacklist) {
454  s->protocol_blacklist = av_strdup(h->protocol_blacklist);
455  if (!s->protocol_blacklist) {
456  avio_closep(sp);
457  return AVERROR(ENOMEM);
458  }
459  }
460  s->direct = h->flags & AVIO_FLAG_DIRECT;
461 
462  s->seekable = h->is_streamed ? 0 : AVIO_SEEKABLE_NORMAL;
463  s->max_packet_size = max_packet_size;
464  s->min_packet_size = h->min_packet_size;
465  if(h->prot) {
466  s->read_pause = h->prot->url_read_pause;
467  s->read_seek = h->prot->url_read_seek;
468 
469  if (h->prot->url_read_seek)
470  s->seekable |= AVIO_SEEKABLE_TIME;
471  }
472  ((FFIOContext*)s)->short_seek_get = ffurl_get_short_seek;
473  s->av_class = &ff_avio_class;
474  return 0;
475 }
476 
477 int ffio_open_whitelist(AVIOContext **s, const char *filename, int flags,
479  const char *whitelist, const char *blacklist)
480 {
481  URLContext *h;
482  int err;
483 
484  *s = NULL;
485 
486  err = ffurl_open_whitelist(&h, filename, flags, int_cb, options, whitelist, blacklist, NULL);
487  if (err < 0)
488  return err;
489  err = ffio_fdopen(s, h);
490  if (err < 0) {
491  ffurl_close(h);
492  return err;
493  }
494  return 0;
495 }
496 
497 int avio_open2(AVIOContext **s, const char *filename, int flags,
499 {
500  return ffio_open_whitelist(s, filename, flags, int_cb, options, NULL, NULL);
501 }
502 
503 int avio_open(AVIOContext **s, const char *filename, int flags)
504 {
505  return avio_open2(s, filename, flags, NULL, NULL);
506 }
507 
508 
509 static inline int retry_transfer_wrapper(URLContext *h, uint8_t *buf,
510  const uint8_t *cbuf,
511  int size, int size_min,
512  int read)
513 {
514  int ret, len;
515  int fast_retries = 5;
516  int64_t wait_since = 0;
517 
518  len = 0;
519  while (len < size_min) {
520  if (ff_check_interrupt(&h->interrupt_callback))
521  return AVERROR_EXIT;
522  ret = read ? h->prot->url_read (h, buf + len, size - len):
523  h->prot->url_write(h, cbuf + len, size - len);
524  if (ret == AVERROR(EINTR))
525  continue;
526  if (h->flags & AVIO_FLAG_NONBLOCK)
527  return ret;
528  if (ret == AVERROR(EAGAIN)) {
529  ret = 0;
530  if (fast_retries) {
531  fast_retries--;
532  } else {
533  if (h->rw_timeout) {
534  if (!wait_since)
535  wait_since = av_gettime_relative();
536  else if (av_gettime_relative() > wait_since + h->rw_timeout)
537  return AVERROR(EIO);
538  }
539  av_usleep(1000);
540  }
541  } else if (ret == AVERROR_EOF)
542  return (len > 0) ? len : AVERROR_EOF;
543  else if (ret < 0)
544  return ret;
545  if (ret) {
546  fast_retries = FFMAX(fast_retries, 2);
547  wait_since = 0;
548  }
549  len += ret;
550  }
551  return len;
552 }
553 
554 int ffurl_read2(void *urlcontext, uint8_t *buf, int size)
555 {
556  URLContext *h = urlcontext;
557 
558  if (!(h->flags & AVIO_FLAG_READ))
559  return AVERROR(EIO);
560  return retry_transfer_wrapper(h, buf, NULL, size, 1, 1);
561 }
562 
563 int ffurl_read_complete(URLContext *h, unsigned char *buf, int size)
564 {
565  if (!(h->flags & AVIO_FLAG_READ))
566  return AVERROR(EIO);
567  return retry_transfer_wrapper(h, buf, NULL, size, size, 1);
568 }
569 
570 int ffurl_write2(void *urlcontext, const uint8_t *buf, int size)
571 {
572  URLContext *h = urlcontext;
573 
574  if (!(h->flags & AVIO_FLAG_WRITE))
575  return AVERROR(EIO);
576  /* avoid sending too big packets */
577  if (h->max_packet_size && size > h->max_packet_size)
578  return AVERROR(EIO);
579 
580  return retry_transfer_wrapper(h, NULL, buf, size, size, 0);
581 }
582 
583 int64_t ffurl_seek2(void *urlcontext, int64_t pos, int whence)
584 {
585  URLContext *h = urlcontext;
586  int64_t ret;
587 
588  if (!h->prot->url_seek)
589  return AVERROR(ENOSYS);
590  ret = h->prot->url_seek(h, pos, whence & ~AVSEEK_FORCE);
591  return ret;
592 }
593 
595 {
596  URLContext *h= *hh;
597  int ret = 0;
598  if (!h)
599  return 0; /* can happen when ffurl_open fails */
600 
601  if (h->is_connected && h->prot->url_close)
602  ret = h->prot->url_close(h);
603 #if CONFIG_NETWORK
604  if (h->prot->flags & URL_PROTOCOL_FLAG_NETWORK)
606 #endif
607  if (h->prot->priv_data_size) {
608  if (h->prot->priv_data_class)
609  av_opt_free(h->priv_data);
610  av_freep(&h->priv_data);
611  }
612  av_opt_free(h);
613  av_freep(hh);
614  return ret;
615 }
616 
618 {
619  return ffurl_closep(&h);
620 }
621 
623 {
624  FFIOContext *const ctx = ffiocontext(s);
625  URLContext *h;
626  int ret, error;
627 
628  if (!s)
629  return 0;
630 
631  avio_flush(s);
632  h = s->opaque;
633  s->opaque = NULL;
634 
635  av_freep(&s->buffer);
636  if (s->write_flag)
638  "Statistics: %"PRId64" bytes written, %d seeks, %d writeouts\n",
639  ctx->bytes_written, ctx->seek_count, ctx->writeout_count);
640  else
641  av_log(s, AV_LOG_VERBOSE, "Statistics: %"PRId64" bytes read, %d seeks\n",
642  ctx->bytes_read, ctx->seek_count);
643  av_opt_free(s);
644 
645  error = s->error;
647 
648  ret = ffurl_close(h);
649  if (ret < 0)
650  return ret;
651 
652  return error;
653 }
654 
656 {
657  int ret = avio_close(*s);
658  *s = NULL;
659  return ret;
660 }
661 
662 
663 const char *avio_find_protocol_name(const char *url)
664 {
665  const URLProtocol *p = url_find_protocol(url);
666 
667  return p ? p->name : NULL;
668 }
669 
670 int avio_check(const char *url, int flags)
671 {
672  URLContext *h;
673  int ret = ffurl_alloc(&h, url, flags, NULL);
674  if (ret < 0)
675  return ret;
676 
677  if (h->prot->url_check) {
678  ret = h->prot->url_check(h, flags);
679  } else {
680  ret = ffurl_connect(h, NULL);
681  if (ret >= 0)
682  ret = flags;
683  }
684 
685  ffurl_close(h);
686  return ret;
687 }
688 
689 int ffurl_move(const char *url_src, const char *url_dst)
690 {
691  URLContext *h_src, *h_dst;
692  int ret = ffurl_alloc(&h_src, url_src, AVIO_FLAG_READ_WRITE, NULL);
693  if (ret < 0)
694  return ret;
695  ret = ffurl_alloc(&h_dst, url_dst, AVIO_FLAG_WRITE, NULL);
696  if (ret < 0) {
697  ffurl_close(h_src);
698  return ret;
699  }
700 
701  if (h_src->prot == h_dst->prot && h_src->prot->url_move)
702  ret = h_src->prot->url_move(h_src, h_dst);
703  else
704  ret = AVERROR(ENOSYS);
705 
706  ffurl_close(h_src);
707  ffurl_close(h_dst);
708  return ret;
709 }
710 
711 int ffurl_delete(const char *url)
712 {
713  URLContext *h;
714  int ret = ffurl_alloc(&h, url, AVIO_FLAG_WRITE, NULL);
715  if (ret < 0)
716  return ret;
717 
718  if (h->prot->url_delete)
719  ret = h->prot->url_delete(h);
720  else
721  ret = AVERROR(ENOSYS);
722 
723  ffurl_close(h);
724  return ret;
725 }
726 
729 };
730 
732 {
733  URLContext *h = NULL;
735  int ret;
736  av_assert0(s);
737 
738  ctx = av_mallocz(sizeof(*ctx));
739  if (!ctx) {
740  ret = AVERROR(ENOMEM);
741  goto fail;
742  }
743 
744  if ((ret = ffurl_alloc(&h, url, AVIO_FLAG_READ, NULL)) < 0)
745  goto fail;
746 
747  if (h->prot->url_open_dir && h->prot->url_read_dir && h->prot->url_close_dir) {
748  if (options && h->prot->priv_data_class &&
749  (ret = av_opt_set_dict(h->priv_data, options)) < 0)
750  goto fail;
751  ret = h->prot->url_open_dir(h);
752  } else
753  ret = AVERROR(ENOSYS);
754  if (ret < 0)
755  goto fail;
756 
757  h->is_connected = 1;
758  ctx->url_context = h;
759  *s = ctx;
760  return 0;
761 
762  fail:
763  av_free(ctx);
764  *s = NULL;
765  ffurl_close(h);
766  return ret;
767 }
768 
770 {
771  URLContext *h;
772  int ret;
773 
774  if (!s || !s->url_context)
775  return AVERROR(EINVAL);
776  h = s->url_context;
777  if ((ret = h->prot->url_read_dir(h, next)) < 0)
779  return ret;
780 }
781 
783 {
784  URLContext *h;
785 
786  av_assert0(s);
787  if (!(*s) || !(*s)->url_context)
788  return AVERROR(EINVAL);
789  h = (*s)->url_context;
790  h->prot->url_close_dir(h);
791  ffurl_close(h);
792  av_freep(s);
793  *s = NULL;
794  return 0;
795 }
796 
798 {
799  if (!entry || !*entry)
800  return;
801  av_free((*entry)->name);
802  av_freep(entry);
803 }
804 
806 {
807  int64_t pos, size;
808 
809  size = ffurl_seek(h, 0, AVSEEK_SIZE);
810  if (size < 0) {
811  pos = ffurl_seek(h, 0, SEEK_CUR);
812  if ((size = ffurl_seek(h, -1, SEEK_END)) < 0)
813  return size;
814  size++;
815  ffurl_seek(h, pos, SEEK_SET);
816  }
817  return size;
818 }
819 
821 {
822  if (!h || !h->prot || !h->prot->url_get_file_handle)
823  return -1;
824  return h->prot->url_get_file_handle(h);
825 }
826 
827 int ffurl_get_multi_file_handle(URLContext *h, int **handles, int *numhandles)
828 {
829  if (!h || !h->prot)
830  return AVERROR(ENOSYS);
831  if (!h->prot->url_get_multi_file_handle) {
832  if (!h->prot->url_get_file_handle)
833  return AVERROR(ENOSYS);
834  *handles = av_malloc(sizeof(**handles));
835  if (!*handles)
836  return AVERROR(ENOMEM);
837  *numhandles = 1;
838  *handles[0] = h->prot->url_get_file_handle(h);
839  return 0;
840  }
841  return h->prot->url_get_multi_file_handle(h, handles, numhandles);
842 }
843 
844 int ffurl_get_short_seek(void *urlcontext)
845 {
846  URLContext *h = urlcontext;
847 
848  if (!h || !h->prot || !h->prot->url_get_short_seek)
849  return AVERROR(ENOSYS);
850  return h->prot->url_get_short_seek(h);
851 }
852 
854 {
855  if (!h || !h->prot || !h->prot->url_shutdown)
856  return AVERROR(ENOSYS);
857  return h->prot->url_shutdown(h, flags);
858 }
859 
861 {
862  if (cb && cb->callback)
863  return cb->callback(cb->opaque);
864  return 0;
865 }
866 
867 int ff_rename(const char *url_src, const char *url_dst, void *logctx)
868 {
869  int ret = ffurl_move(url_src, url_dst);
870  if (ret < 0)
871  av_log(logctx, AV_LOG_ERROR, "failed to rename file %s to %s: %s\n", url_src, url_dst, av_err2str(ret));
872  return ret;
873 }
error
static void error(const char *err)
Definition: target_bsf_fuzzer.c:32
flags
const SwsFlags flags[]
Definition: swscale.c:72
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:477
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:216
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:1672
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:247
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:278
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:301
int64_t
long long int64_t
Definition: coverity.c:34
urlcontext_options
static const AVOption urlcontext_options[]
Definition: avio.c:60
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:429
AVSEEK_SIZE
#define AVSEEK_SIZE
Passing this as the "whence" parameter to a seek function causes it to return the filesize without se...
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:503
IO_BUFFER_SIZE
#define IO_BUFFER_SIZE
Definition: avio.c:36
AV_LOG_VERBOSE
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:226
ffurl_close
int ffurl_close(URLContext *h)
Definition: avio.c:617
urlcontext_to_name
static const char * urlcontext_to_name(void *ptr)
Definition: avio.c:40
AVDictionary
Definition: dict.c:32
FFMAX
#define FFMAX(a, b)
Definition: macros.h:47
ff_network_close
void ff_network_close(void)
Definition: network.c:114
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:56
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:224
ffurl_get_short_seek
int ffurl_get_short_seek(void *urlcontext)
Return the current short seek threshold value for this URL.
Definition: avio.c:844
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:1943
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:77
av_opt_set
int av_opt_set(void *obj, const char *name, const char *val, int search_flags)
Definition: opt.c:825
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:860
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:867
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:797
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:210
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:60
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:368
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:782
AV_OPT_TYPE_INT64
@ AV_OPT_TYPE_INT64
Underlying C type is int64_t.
Definition: opt.h:263
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:42
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:231
ctx
static 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
av_mallocz
#define av_mallocz(s)
Definition: tableprint_vlc.h:31
avio_flush
void avio_flush(AVIOContext *s)
Force flushing of buffered data.
Definition: aviobuf.c:228
ffurl_accept
int ffurl_accept(URLContext *s, URLContext **c)
Accept an URLContext c on an URLContext s.
Definition: avio.c:270
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:76
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:445
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:689
av_default_item_name
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:242
ffurl_shutdown
int ffurl_shutdown(URLContext *h, int flags)
Signal the URLContext that we are done reading or writing the stream.
Definition: avio.c:853
URL_SCHEME_CHARS
#define URL_SCHEME_CHARS
Definition: avio.c:307
options
Definition: swscale.c:45
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:352
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:769
av_opt_copy
int av_opt_copy(void *dst, const void *src)
Copy options from src object into dest object.
Definition: opt.c:2145
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:827
i
#define i(width, name, range_min, range_max)
Definition: cbs_h264.c:63
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:122
URLProtocol::priv_data_class
const AVClass * priv_data_class
Definition: url.h:87
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:670
av_dict_free
void av_dict_free(AVDictionary **pm)
Free all the memory allocated for an AVDictionary struct and all keys and values.
Definition: dict.c:233
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:570
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:355
URLContext
Definition: url.h:35
av_malloc
#define av_malloc(s)
Definition: ops_asmgen.c:44
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:418
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
ff_avio_class
const AVClass ff_avio_class
Definition: avio.c:98
url.h
avio_open_dir
int avio_open_dir(AVIODirContext **s, const char *url, AVDictionary **options)
Open directory for reading.
Definition: avio.c:731
len
int len
Definition: vorbis_enc_data.h:426
int_cb
const AVIOInterruptCB int_cb
Definition: ffmpeg.c:312
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:594
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:81
ffurl_read2
int ffurl_read2(void *urlcontext, uint8_t *buf, int size)
Definition: avio.c:554
AVIODirContext
Definition: avio.c:727
ffurl_seek2
int64_t ffurl_seek2(void *urlcontext, int64_t pos, int whence)
Definition: avio.c:583
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
url_find_protocol
static const struct URLProtocol * url_find_protocol(const char *filename)
Definition: avio.c:312
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
Windows::Graphics::DirectX::Direct3D11::p
IDirect3DDxgiInterfaceAccess _COM_Outptr_ void ** p
Definition: vsrc_gfxcapture_winrt.hpp:53
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:509
AVSEEK_FORCE
#define AVSEEK_FORCE
OR'ing this flag into the "whence" parameter to a seek function causes it to seek by any means (like ...
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_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:356
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:497
av_strdup
#define av_strdup(s)
Definition: ops_asmgen.c:47
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:563
URLProtocol::priv_data_size
int priv_data_size
Definition: url.h:88
av_free
#define av_free(p)
Definition: tableprint_vlc.h:34
AVDictionaryEntry
Definition: dict.h:90
ffurl_handshake
int ffurl_handshake(URLContext *c)
Perform one step of the protocol handshake to accept a new client.
Definition: avio.c:289
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:655
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:35
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:86
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:728
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:663
avio_close
int avio_close(AVIOContext *s)
Close the resource accessed by the AVIOContext s and free it.
Definition: avio.c:622
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:805
h
h
Definition: vp9dsp_template.c:2070
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:1980
AVDictionaryEntry::value
char * value
Definition: dict.h:92
avstring.h
AV_OPT_TYPE_STRING
@ AV_OPT_TYPE_STRING
Underlying C type is a uint8_t* that is either NULL or points to a C string allocated with the av_mal...
Definition: opt.h:276
ffurl_delete
int ffurl_delete(const char *url)
Delete a resource.
Definition: avio.c:711
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:820
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:239