The interrupt callback has to be passed in during opening (setting it after opening isn't enough), since a blocking open couldn't be interrupted otherwise. Options are passed down to procotols and also need to be available during open() in most cases. Signed-off-by: Anton Khirnov <anton@khirnov.net>tags/n0.9
| @@ -73,7 +73,7 @@ static const AVClass *urlcontext_child_class_next(const AVClass *prev) | |||||
| } | } | ||||
| static const AVOption options[] = {{NULL}}; | static const AVOption options[] = {{NULL}}; | ||||
| static const AVClass urlcontext_class = { | |||||
| const AVClass ffurl_context_class = { | |||||
| .class_name = "URLContext", | .class_name = "URLContext", | ||||
| .item_name = urlcontext_to_name, | .item_name = urlcontext_to_name, | ||||
| .option = options, | .option = options, | ||||
| @@ -135,7 +135,7 @@ static int url_alloc_for_protocol (URLContext **puc, struct URLProtocol *up, | |||||
| err = AVERROR(ENOMEM); | err = AVERROR(ENOMEM); | ||||
| goto fail; | goto fail; | ||||
| } | } | ||||
| uc->av_class = &urlcontext_class; | |||||
| uc->av_class = &ffurl_context_class; | |||||
| uc->filename = (char *) &uc[1]; | uc->filename = (char *) &uc[1]; | ||||
| strcpy(uc->filename, filename); | strcpy(uc->filename, filename); | ||||
| uc->prot = up; | uc->prot = up; | ||||
| @@ -28,6 +28,7 @@ | |||||
| #include <stdint.h> | #include <stdint.h> | ||||
| #include "libavutil/common.h" | #include "libavutil/common.h" | ||||
| #include "libavutil/dict.h" | |||||
| #include "libavutil/log.h" | #include "libavutil/log.h" | ||||
| #include "libavformat/version.h" | #include "libavformat/version.h" | ||||
| @@ -64,6 +65,21 @@ typedef struct { | |||||
| * function pointers specified in avio_alloc_context() | * function pointers specified in avio_alloc_context() | ||||
| */ | */ | ||||
| typedef struct { | 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. */ | unsigned char *buffer; /**< Start of the buffer. */ | ||||
| int buffer_size; /**< Maximum buffer size */ | int buffer_size; /**< Maximum buffer size */ | ||||
| unsigned char *buf_ptr; /**< Current position in the buffer */ | 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); | 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. | * Close the resource accessed by the AVIOContext s and free it. | ||||
| * This function can only be used if s was opened by avio_open(). | * This function can only be used if s was opened by avio_open(). | ||||
| @@ -23,6 +23,10 @@ | |||||
| #include "avio.h" | #include "avio.h" | ||||
| #include "url.h" | #include "url.h" | ||||
| #include "libavutil/log.h" | |||||
| extern const AVClass ffio_url_class; | |||||
| int ffio_init_context(AVIOContext *s, | int ffio_init_context(AVIOContext *s, | ||||
| unsigned char *buffer, | unsigned char *buffer, | ||||
| int buffer_size, | int buffer_size, | ||||
| @@ -20,7 +20,10 @@ | |||||
| */ | */ | ||||
| #include "libavutil/crc.h" | #include "libavutil/crc.h" | ||||
| #include "libavutil/dict.h" | |||||
| #include "libavutil/intreadwrite.h" | #include "libavutil/intreadwrite.h" | ||||
| #include "libavutil/log.h" | |||||
| #include "libavutil/opt.h" | |||||
| #include "avformat.h" | #include "avformat.h" | ||||
| #include "avio.h" | #include "avio.h" | ||||
| #include "avio_internal.h" | #include "avio_internal.h" | ||||
| @@ -37,6 +40,31 @@ | |||||
| */ | */ | ||||
| #define SHORT_SEEK_THRESHOLD 4096 | #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 void fill_buffer(AVIOContext *s); | ||||
| static int url_resetbuf(AVIOContext *s, int flags); | 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_pause = (int (*)(void *, int))h->prot->url_read_pause; | ||||
| (*s)->read_seek = (int64_t (*)(void *, int, int64_t, int))h->prot->url_read_seek; | (*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; | 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) | 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; | URLContext *h; | ||||
| int err; | int err; | ||||
| err = ffurl_open(&h, filename, flags, NULL, NULL); | |||||
| err = ffurl_open(&h, filename, flags, int_cb, options); | |||||
| if (err < 0) | if (err < 0) | ||||
| return err; | return err; | ||||
| err = ffio_fdopen(s, h); | err = ffio_fdopen(s, h); | ||||
| @@ -29,12 +29,15 @@ | |||||
| #include "libavformat/version.h" | #include "libavformat/version.h" | ||||
| #include "libavutil/dict.h" | #include "libavutil/dict.h" | ||||
| #include "libavutil/log.h" | |||||
| #if !FF_API_OLD_AVIO | #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 */ | #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 int (*url_interrupt_cb)(void); | ||||
| extern const AVClass ffurl_context_class; | |||||
| typedef struct URLContext { | typedef struct URLContext { | ||||
| const AVClass *av_class; /**< information for av_log(). Set by url_open(). */ | const AVClass *av_class; /**< information for av_log(). Set by url_open(). */ | ||||
| struct URLProtocol *prot; | struct URLProtocol *prot; | ||||