FFmpeg
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
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_strstart(filename, "dtls:", NULL))
344  av_log(NULL, AV_LOG_WARNING, "https or dtls protocol not found, recompile FFmpeg with "
345  "openssl, gnutls or securetransport enabled.\n");
346 
347  return NULL;
348 }
349 
350 int ffurl_alloc(URLContext **puc, const char *filename, int flags,
351  const AVIOInterruptCB *int_cb)
352 {
353  const URLProtocol *p = NULL;
354 
355  p = url_find_protocol(filename);
356  if (p)
357  return url_alloc_for_protocol(puc, p, filename, flags, int_cb);
358 
359  *puc = NULL;
361 }
362 
363 int ffurl_open_whitelist(URLContext **puc, const char *filename, int flags,
365  const char *whitelist, const char* blacklist,
366  URLContext *parent)
367 {
368  AVDictionary *tmp_opts = NULL;
370  int ret = ffurl_alloc(puc, filename, flags, int_cb);
371  if (ret < 0)
372  return ret;
373  if (parent) {
374  ret = av_opt_copy(*puc, parent);
375  if (ret < 0)
376  goto fail;
377  }
378  if (options &&
379  (ret = av_opt_set_dict(*puc, options)) < 0)
380  goto fail;
381  if (options && (*puc)->prot->priv_data_class &&
382  (ret = av_opt_set_dict((*puc)->priv_data, options)) < 0)
383  goto fail;
384 
385  if (!options)
386  options = &tmp_opts;
387 
388  av_assert0(!whitelist ||
389  !(e=av_dict_get(*options, "protocol_whitelist", NULL, 0)) ||
390  !strcmp(whitelist, e->value));
391  av_assert0(!blacklist ||
392  !(e=av_dict_get(*options, "protocol_blacklist", NULL, 0)) ||
393  !strcmp(blacklist, e->value));
394 
395  if ((ret = av_dict_set(options, "protocol_whitelist", whitelist, 0)) < 0)
396  goto fail;
397 
398  if ((ret = av_dict_set(options, "protocol_blacklist", blacklist, 0)) < 0)
399  goto fail;
400 
401  if ((ret = av_opt_set_dict(*puc, options)) < 0)
402  goto fail;
403 
404  ret = ffurl_connect(*puc, options);
405 
406  if (!ret)
407  return 0;
408 fail:
409  ffurl_closep(puc);
410  return ret;
411 }
412 
414 {
415  AVIOContext *s;
416  uint8_t *buffer = NULL;
417  int buffer_size, max_packet_size;
418 
419  max_packet_size = h->max_packet_size;
420  if (max_packet_size) {
421  buffer_size = max_packet_size; /* no need to bufferize more than one packet */
422  } else {
423  buffer_size = IO_BUFFER_SIZE;
424  }
425  if (!(h->flags & AVIO_FLAG_WRITE) && h->is_streamed) {
426  if (buffer_size > INT_MAX/2)
427  return AVERROR(EINVAL);
428  buffer_size *= 2;
429  }
430  buffer = av_malloc(buffer_size);
431  if (!buffer)
432  return AVERROR(ENOMEM);
433 
434  *sp = avio_alloc_context(buffer, buffer_size, h->flags & AVIO_FLAG_WRITE, h,
436  if (!*sp) {
437  av_freep(&buffer);
438  return AVERROR(ENOMEM);
439  }
440  s = *sp;
441  if (h->protocol_whitelist) {
442  s->protocol_whitelist = av_strdup(h->protocol_whitelist);
443  if (!s->protocol_whitelist) {
444  avio_closep(sp);
445  return AVERROR(ENOMEM);
446  }
447  }
448  if (h->protocol_blacklist) {
449  s->protocol_blacklist = av_strdup(h->protocol_blacklist);
450  if (!s->protocol_blacklist) {
451  avio_closep(sp);
452  return AVERROR(ENOMEM);
453  }
454  }
455  s->direct = h->flags & AVIO_FLAG_DIRECT;
456 
457  s->seekable = h->is_streamed ? 0 : AVIO_SEEKABLE_NORMAL;
458  s->max_packet_size = max_packet_size;
459  s->min_packet_size = h->min_packet_size;
460  if(h->prot) {
461  s->read_pause = h->prot->url_read_pause;
462  s->read_seek = h->prot->url_read_seek;
463 
464  if (h->prot->url_read_seek)
465  s->seekable |= AVIO_SEEKABLE_TIME;
466  }
467  ((FFIOContext*)s)->short_seek_get = ffurl_get_short_seek;
468  s->av_class = &ff_avio_class;
469  return 0;
470 }
471 
472 int ffio_open_whitelist(AVIOContext **s, const char *filename, int flags,
474  const char *whitelist, const char *blacklist)
475 {
476  URLContext *h;
477  int err;
478 
479  *s = NULL;
480 
481  err = ffurl_open_whitelist(&h, filename, flags, int_cb, options, whitelist, blacklist, NULL);
482  if (err < 0)
483  return err;
484  err = ffio_fdopen(s, h);
485  if (err < 0) {
486  ffurl_close(h);
487  return err;
488  }
489  return 0;
490 }
491 
492 int avio_open2(AVIOContext **s, const char *filename, int flags,
494 {
495  return ffio_open_whitelist(s, filename, flags, int_cb, options, NULL, NULL);
496 }
497 
498 int avio_open(AVIOContext **s, const char *filename, int flags)
499 {
500  return avio_open2(s, filename, flags, NULL, NULL);
501 }
502 
503 
504 static inline int retry_transfer_wrapper(URLContext *h, uint8_t *buf,
505  const uint8_t *cbuf,
506  int size, int size_min,
507  int read)
508 {
509  int ret, len;
510  int fast_retries = 5;
511  int64_t wait_since = 0;
512 
513  len = 0;
514  while (len < size_min) {
515  if (ff_check_interrupt(&h->interrupt_callback))
516  return AVERROR_EXIT;
517  ret = read ? h->prot->url_read (h, buf + len, size - len):
518  h->prot->url_write(h, cbuf + len, size - len);
519  if (ret == AVERROR(EINTR))
520  continue;
521  if (h->flags & AVIO_FLAG_NONBLOCK)
522  return ret;
523  if (ret == AVERROR(EAGAIN)) {
524  ret = 0;
525  if (fast_retries) {
526  fast_retries--;
527  } else {
528  if (h->rw_timeout) {
529  if (!wait_since)
530  wait_since = av_gettime_relative();
531  else if (av_gettime_relative() > wait_since + h->rw_timeout)
532  return AVERROR(EIO);
533  }
534  av_usleep(1000);
535  }
536  } else if (ret == AVERROR_EOF)
537  return (len > 0) ? len : AVERROR_EOF;
538  else if (ret < 0)
539  return ret;
540  if (ret) {
541  fast_retries = FFMAX(fast_retries, 2);
542  wait_since = 0;
543  }
544  len += ret;
545  }
546  return len;
547 }
548 
549 int ffurl_read2(void *urlcontext, uint8_t *buf, int size)
550 {
551  URLContext *h = urlcontext;
552 
553  if (!(h->flags & AVIO_FLAG_READ))
554  return AVERROR(EIO);
555  return retry_transfer_wrapper(h, buf, NULL, size, 1, 1);
556 }
557 
558 int ffurl_read_complete(URLContext *h, unsigned char *buf, int size)
559 {
560  if (!(h->flags & AVIO_FLAG_READ))
561  return AVERROR(EIO);
562  return retry_transfer_wrapper(h, buf, NULL, size, size, 1);
563 }
564 
565 int ffurl_write2(void *urlcontext, const uint8_t *buf, int size)
566 {
567  URLContext *h = urlcontext;
568 
569  if (!(h->flags & AVIO_FLAG_WRITE))
570  return AVERROR(EIO);
571  /* avoid sending too big packets */
572  if (h->max_packet_size && size > h->max_packet_size)
573  return AVERROR(EIO);
574 
575  return retry_transfer_wrapper(h, NULL, buf, size, size, 0);
576 }
577 
578 int64_t ffurl_seek2(void *urlcontext, int64_t pos, int whence)
579 {
580  URLContext *h = urlcontext;
581  int64_t ret;
582 
583  if (!h->prot->url_seek)
584  return AVERROR(ENOSYS);
585  ret = h->prot->url_seek(h, pos, whence & ~AVSEEK_FORCE);
586  return ret;
587 }
588 
590 {
591  URLContext *h= *hh;
592  int ret = 0;
593  if (!h)
594  return 0; /* can happen when ffurl_open fails */
595 
596  if (h->is_connected && h->prot->url_close)
597  ret = h->prot->url_close(h);
598 #if CONFIG_NETWORK
599  if (h->prot->flags & URL_PROTOCOL_FLAG_NETWORK)
601 #endif
602  if (h->prot->priv_data_size) {
603  if (h->prot->priv_data_class)
604  av_opt_free(h->priv_data);
605  av_freep(&h->priv_data);
606  }
607  av_opt_free(h);
608  av_freep(hh);
609  return ret;
610 }
611 
613 {
614  return ffurl_closep(&h);
615 }
616 
618 {
619  FFIOContext *const ctx = ffiocontext(s);
620  URLContext *h;
621  int ret, error;
622 
623  if (!s)
624  return 0;
625 
626  avio_flush(s);
627  h = s->opaque;
628  s->opaque = NULL;
629 
630  av_freep(&s->buffer);
631  if (s->write_flag)
633  "Statistics: %"PRId64" bytes written, %d seeks, %d writeouts\n",
634  ctx->bytes_written, ctx->seek_count, ctx->writeout_count);
635  else
636  av_log(s, AV_LOG_VERBOSE, "Statistics: %"PRId64" bytes read, %d seeks\n",
637  ctx->bytes_read, ctx->seek_count);
638  av_opt_free(s);
639 
640  error = s->error;
642 
643  ret = ffurl_close(h);
644  if (ret < 0)
645  return ret;
646 
647  return error;
648 }
649 
651 {
652  int ret = avio_close(*s);
653  *s = NULL;
654  return ret;
655 }
656 
657 
658 const char *avio_find_protocol_name(const char *url)
659 {
660  const URLProtocol *p = url_find_protocol(url);
661 
662  return p ? p->name : NULL;
663 }
664 
665 int avio_check(const char *url, int flags)
666 {
667  URLContext *h;
668  int ret = ffurl_alloc(&h, url, flags, NULL);
669  if (ret < 0)
670  return ret;
671 
672  if (h->prot->url_check) {
673  ret = h->prot->url_check(h, flags);
674  } else {
675  ret = ffurl_connect(h, NULL);
676  if (ret >= 0)
677  ret = flags;
678  }
679 
680  ffurl_close(h);
681  return ret;
682 }
683 
684 int ffurl_move(const char *url_src, const char *url_dst)
685 {
686  URLContext *h_src, *h_dst;
687  int ret = ffurl_alloc(&h_src, url_src, AVIO_FLAG_READ_WRITE, NULL);
688  if (ret < 0)
689  return ret;
690  ret = ffurl_alloc(&h_dst, url_dst, AVIO_FLAG_WRITE, NULL);
691  if (ret < 0) {
692  ffurl_close(h_src);
693  return ret;
694  }
695 
696  if (h_src->prot == h_dst->prot && h_src->prot->url_move)
697  ret = h_src->prot->url_move(h_src, h_dst);
698  else
699  ret = AVERROR(ENOSYS);
700 
701  ffurl_close(h_src);
702  ffurl_close(h_dst);
703  return ret;
704 }
705 
706 int ffurl_delete(const char *url)
707 {
708  URLContext *h;
709  int ret = ffurl_alloc(&h, url, AVIO_FLAG_WRITE, NULL);
710  if (ret < 0)
711  return ret;
712 
713  if (h->prot->url_delete)
714  ret = h->prot->url_delete(h);
715  else
716  ret = AVERROR(ENOSYS);
717 
718  ffurl_close(h);
719  return ret;
720 }
721 
724 };
725 
727 {
728  URLContext *h = NULL;
730  int ret;
731  av_assert0(s);
732 
733  ctx = av_mallocz(sizeof(*ctx));
734  if (!ctx) {
735  ret = AVERROR(ENOMEM);
736  goto fail;
737  }
738 
739  if ((ret = ffurl_alloc(&h, url, AVIO_FLAG_READ, NULL)) < 0)
740  goto fail;
741 
742  if (h->prot->url_open_dir && h->prot->url_read_dir && h->prot->url_close_dir) {
743  if (options && h->prot->priv_data_class &&
744  (ret = av_opt_set_dict(h->priv_data, options)) < 0)
745  goto fail;
746  ret = h->prot->url_open_dir(h);
747  } else
748  ret = AVERROR(ENOSYS);
749  if (ret < 0)
750  goto fail;
751 
752  h->is_connected = 1;
753  ctx->url_context = h;
754  *s = ctx;
755  return 0;
756 
757  fail:
758  av_free(ctx);
759  *s = NULL;
760  ffurl_close(h);
761  return ret;
762 }
763 
765 {
766  URLContext *h;
767  int ret;
768 
769  if (!s || !s->url_context)
770  return AVERROR(EINVAL);
771  h = s->url_context;
772  if ((ret = h->prot->url_read_dir(h, next)) < 0)
774  return ret;
775 }
776 
778 {
779  URLContext *h;
780 
781  av_assert0(s);
782  if (!(*s) || !(*s)->url_context)
783  return AVERROR(EINVAL);
784  h = (*s)->url_context;
785  h->prot->url_close_dir(h);
786  ffurl_close(h);
787  av_freep(s);
788  *s = NULL;
789  return 0;
790 }
791 
793 {
794  if (!entry || !*entry)
795  return;
796  av_free((*entry)->name);
797  av_freep(entry);
798 }
799 
801 {
802  int64_t pos, size;
803 
804  size = ffurl_seek(h, 0, AVSEEK_SIZE);
805  if (size < 0) {
806  pos = ffurl_seek(h, 0, SEEK_CUR);
807  if ((size = ffurl_seek(h, -1, SEEK_END)) < 0)
808  return size;
809  size++;
810  ffurl_seek(h, pos, SEEK_SET);
811  }
812  return size;
813 }
814 
816 {
817  if (!h || !h->prot || !h->prot->url_get_file_handle)
818  return -1;
819  return h->prot->url_get_file_handle(h);
820 }
821 
822 int ffurl_get_multi_file_handle(URLContext *h, int **handles, int *numhandles)
823 {
824  if (!h || !h->prot)
825  return AVERROR(ENOSYS);
826  if (!h->prot->url_get_multi_file_handle) {
827  if (!h->prot->url_get_file_handle)
828  return AVERROR(ENOSYS);
829  *handles = av_malloc(sizeof(**handles));
830  if (!*handles)
831  return AVERROR(ENOMEM);
832  *numhandles = 1;
833  *handles[0] = h->prot->url_get_file_handle(h);
834  return 0;
835  }
836  return h->prot->url_get_multi_file_handle(h, handles, numhandles);
837 }
838 
839 int ffurl_get_short_seek(void *urlcontext)
840 {
841  URLContext *h = urlcontext;
842 
843  if (!h || !h->prot || !h->prot->url_get_short_seek)
844  return AVERROR(ENOSYS);
845  return h->prot->url_get_short_seek(h);
846 }
847 
849 {
850  if (!h || !h->prot || !h->prot->url_shutdown)
851  return AVERROR(ENOSYS);
852  return h->prot->url_shutdown(h, flags);
853 }
854 
856 {
857  if (cb && cb->callback)
858  return cb->callback(cb->opaque);
859  return 0;
860 }
861 
862 int ff_rename(const char *url_src, const char *url_dst, void *logctx)
863 {
864  int ret = ffurl_move(url_src, url_dst);
865  if (ret < 0)
866  av_log(logctx, AV_LOG_ERROR, "failed to rename file %s to %s: %s\n", url_src, url_dst, av_err2str(ret));
867  return ret;
868 }
error
static void error(const char *err)
Definition: target_bsf_fuzzer.c:32
flags
const SwsFlags flags[]
Definition: swscale.c:61
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:472
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:1678
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: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
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:109
AVOption
AVOption.
Definition: opt.h:429
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:498
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:612
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:121
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:63
av_malloc
#define av_malloc(s)
Definition: tableprint_vlc.h:31
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:85
URLContext::is_connected
int is_connected
Definition: url.h:43
fail
#define fail()
Definition: checkasm.h:196
ffurl_get_short_seek
int ffurl_get_short_seek(void *urlcontext)
Return the current short seek threshold value for this URL.
Definition: avio.c:839
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:1949
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:835
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:855
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:862
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:792
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:363
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:777
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:41
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
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:125
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: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:684
av_default_item_name
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:240
ffurl_shutdown
int ffurl_shutdown(URLContext *h, int flags)
Signal the URLContext that we are done reading or writing the stream.
Definition: avio.c:848
URL_SCHEME_CHARS
#define URL_SCHEME_CHARS
Definition: avio.c:302
options
Definition: swscale.c:43
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:764
av_opt_copy
int av_opt_copy(void *dst, const void *src)
Copy options from src object into dest object.
Definition: opt.c:2151
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:822
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:665
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:565
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:350
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:413
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:726
len
int len
Definition: vorbis_enc_data.h:426
int_cb
const AVIOInterruptCB int_cb
Definition: ffmpeg.c:308
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:589
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:549
AVIODirContext
Definition: avio.c:722
ffurl_seek2
int64_t ffurl_seek2(void *urlcontext, int64_t pos, int whence)
Definition: avio.c:578
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:504
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: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:492
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:558
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: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:650
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:723
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:658
avio_close
int avio_close(AVIOContext *s)
Close the resource accessed by the AVIOContext s and free it.
Definition: avio.c:617
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:800
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:1986
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:706
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:815
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