diff --git a/libavformat/avio.c b/libavformat/avio.c index 330d52cfec..9de435e073 100644 --- a/libavformat/avio.c +++ b/libavformat/avio.c @@ -73,7 +73,7 @@ static const AVClass *urlcontext_child_class_next(const AVClass *prev) } static const AVOption options[] = {{NULL}}; -static const AVClass urlcontext_class = { +const AVClass ffurl_context_class = { .class_name = "URLContext", .item_name = urlcontext_to_name, .option = options, @@ -135,7 +135,7 @@ static int url_alloc_for_protocol (URLContext **puc, struct URLProtocol *up, err = AVERROR(ENOMEM); goto fail; } - uc->av_class = &urlcontext_class; + uc->av_class = &ffurl_context_class; uc->filename = (char *) &uc[1]; strcpy(uc->filename, filename); uc->prot = up; diff --git a/libavformat/avio.h b/libavformat/avio.h index a4041cb770..b665bb3b3b 100644 --- a/libavformat/avio.h +++ b/libavformat/avio.h @@ -28,6 +28,7 @@ #include #include "libavutil/common.h" +#include "libavutil/dict.h" #include "libavutil/log.h" #include "libavformat/version.h" @@ -64,6 +65,21 @@ typedef struct { * function pointers specified in avio_alloc_context() */ typedef struct { +#if !FF_API_OLD_AVIO + /** + * A class for private options. + * + * If this AVIOContext is created by avio_open2(), av_class is set and + * passes the options down to protocols. + * + * If this AVIOContext is manually allocated, then av_class may be set by + * the caller. + * + * warning -- this field can be NULL, be sure to not pass this AVIOContext + * to any av_opt_* functions in that case. + */ + AVClass *av_class; +#endif unsigned char *buffer; /**< Start of the buffer. */ int buffer_size; /**< Maximum buffer size */ unsigned char *buf_ptr; /**< Current position in the buffer */ @@ -573,6 +589,26 @@ int avio_get_str16be(AVIOContext *pb, int maxlen, char *buf, int buflen); */ int avio_open(AVIOContext **s, const char *url, int flags); +/** + * Create and initialize a AVIOContext for accessing the + * resource indicated by url. + * @note When the resource indicated by url has been opened in + * read+write mode, the AVIOContext can be used only for writing. + * + * @param s Used to return the pointer to the created AVIOContext. + * In case of failure the pointed to value is set to NULL. + * @param flags flags which control how the resource indicated by url + * is to be opened + * @param int_cb an interrupt callback to be used at the protocols level + * @param options A dictionary filled with protocol-private options. On return + * this parameter will be destroyed and replaced with a dict containing options + * that were not found. May be NULL. + * @return 0 in case of success, a negative value corresponding to an + * AVERROR code in case of failure + */ +int avio_open2(AVIOContext **s, const char *url, int flags, + const AVIOInterruptCB *int_cb, AVDictionary **options); + /** * Close the resource accessed by the AVIOContext s and free it. * This function can only be used if s was opened by avio_open(). diff --git a/libavformat/avio_internal.h b/libavformat/avio_internal.h index 1369c43891..f2ccc36623 100644 --- a/libavformat/avio_internal.h +++ b/libavformat/avio_internal.h @@ -23,6 +23,10 @@ #include "avio.h" #include "url.h" +#include "libavutil/log.h" + +extern const AVClass ffio_url_class; + int ffio_init_context(AVIOContext *s, unsigned char *buffer, int buffer_size, diff --git a/libavformat/aviobuf.c b/libavformat/aviobuf.c index 246903baac..898f35d903 100644 --- a/libavformat/aviobuf.c +++ b/libavformat/aviobuf.c @@ -20,7 +20,10 @@ */ #include "libavutil/crc.h" +#include "libavutil/dict.h" #include "libavutil/intreadwrite.h" +#include "libavutil/log.h" +#include "libavutil/opt.h" #include "avformat.h" #include "avio.h" #include "avio_internal.h" @@ -37,6 +40,31 @@ */ #define SHORT_SEEK_THRESHOLD 4096 +#if !FF_API_OLD_AVIO +static void *ffio_url_child_next(void *obj, void *prev) +{ + AVIOContext *s = obj; + return prev ? NULL : s->opaque; +} + +static const AVClass *ffio_url_child_class_next(const AVClass *prev) +{ + return prev ? NULL : &ffurl_context_class; +} + +static const AVOption ffio_url_options[] = { + { NULL }, +}; + +const AVClass ffio_url_class = { + .class_name = "AVIOContext", + .item_name = av_default_item_name, + .version = LIBAVUTIL_VERSION_INT, + .option = ffio_url_options, + .child_next = ffio_url_child_next, + .child_class_next = ffio_url_child_class_next, +}; +#endif static void fill_buffer(AVIOContext *s); static int url_resetbuf(AVIOContext *s, int flags); @@ -856,6 +884,9 @@ int ffio_fdopen(AVIOContext **s, URLContext *h) (*s)->read_pause = (int (*)(void *, int))h->prot->url_read_pause; (*s)->read_seek = (int64_t (*)(void *, int, int64_t, int))h->prot->url_read_seek; } +#if !FF_API_OLD_AVIO + (*s)->av_class = &ffio_url_class; +#endif return 0; } @@ -928,11 +959,17 @@ int ffio_rewind_with_probe_data(AVIOContext *s, unsigned char *buf, int buf_size } int avio_open(AVIOContext **s, const char *filename, int flags) +{ + return avio_open2(s, filename, flags, NULL, NULL); +} + +int avio_open2(AVIOContext **s, const char *filename, int flags, + const AVIOInterruptCB *int_cb, AVDictionary **options) { URLContext *h; int err; - err = ffurl_open(&h, filename, flags, NULL, NULL); + err = ffurl_open(&h, filename, flags, int_cb, options); if (err < 0) return err; err = ffio_fdopen(s, h); diff --git a/libavformat/url.h b/libavformat/url.h index 1f04c8d530..ea8c7abb8f 100644 --- a/libavformat/url.h +++ b/libavformat/url.h @@ -29,12 +29,15 @@ #include "libavformat/version.h" #include "libavutil/dict.h" +#include "libavutil/log.h" #if !FF_API_OLD_AVIO #define URL_PROTOCOL_FLAG_NESTED_SCHEME 1 /*< The protocol name can be the first part of a nested protocol scheme */ extern int (*url_interrupt_cb)(void); +extern const AVClass ffurl_context_class; + typedef struct URLContext { const AVClass *av_class; /**< information for av_log(). Set by url_open(). */ struct URLProtocol *prot;