X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavformat%2Foptions.c;h=dccb6faa730c11b976ce4df2d06bac8bf71a5cdc;hb=0bf3a7361d17d596a5044882098f56817db0e103;hp=c188c23506a20b8a3c545f53b086b9d671bee891;hpb=06476249cd2332e30b66576633b2827adf3478dd;p=ffmpeg diff --git a/libavformat/options.c b/libavformat/options.c index c188c23506a..dccb6faa730 100644 --- a/libavformat/options.c +++ b/libavformat/options.c @@ -21,6 +21,7 @@ #include "avio_internal.h" #include "internal.h" +#include "libavutil/avassert.h" #include "libavutil/internal.h" #include "libavutil/opt.h" @@ -53,32 +54,60 @@ static void *format_child_next(void *obj, void *prev) return NULL; } -static const AVClass *format_child_class_next(const AVClass *prev) +enum { + CHILD_CLASS_ITER_AVIO = 0, + CHILD_CLASS_ITER_MUX, + CHILD_CLASS_ITER_DEMUX, + CHILD_CLASS_ITER_DONE, + +}; + +#define ITER_STATE_SHIFT 16 + +static const AVClass *format_child_class_iterate(void **iter) { - AVInputFormat *ifmt = NULL; - AVOutputFormat *ofmt = NULL; + // we use the low 16 bits of iter as the value to be passed to + // av_(de)muxer_iterate() + void *val = (void*)(((uintptr_t)*iter) & ((1 << ITER_STATE_SHIFT) - 1)); + unsigned int state = ((uintptr_t)*iter) >> ITER_STATE_SHIFT; + const AVClass *ret = NULL; + + if (state == CHILD_CLASS_ITER_AVIO) { + ret = &ff_avio_class; + state++; + goto finish; + } - if (!prev) - return &ff_avio_class; + if (state == CHILD_CLASS_ITER_MUX) { + const AVOutputFormat *ofmt; - while ((ifmt = av_iformat_next(ifmt))) - if (ifmt->priv_class == prev) - break; + while ((ofmt = av_muxer_iterate(&val))) { + ret = ofmt->priv_class; + if (ret) + goto finish; + } - if (!ifmt) - while ((ofmt = av_oformat_next(ofmt))) - if (ofmt->priv_class == prev) - break; - if (!ofmt) - while (ifmt = av_iformat_next(ifmt)) - if (ifmt->priv_class) - return ifmt->priv_class; + val = NULL; + state++; + } - while (ofmt = av_oformat_next(ofmt)) - if (ofmt->priv_class) - return ofmt->priv_class; + if (state == CHILD_CLASS_ITER_DEMUX) { + const AVInputFormat *ifmt; - return NULL; + while ((ifmt = av_demuxer_iterate(&val))) { + ret = ifmt->priv_class; + if (ret) + goto finish; + } + val = NULL; + state++; + } + +finish: + // make sure none av_(de)muxer_iterate does not set the high bits of val + av_assert0(!((uintptr_t)val >> ITER_STATE_SHIFT)); + *iter = (void*)((uintptr_t)val | (state << ITER_STATE_SHIFT)); + return ret; } static AVClassCategory get_category(void *ptr) @@ -94,7 +123,7 @@ static const AVClass av_format_context_class = { .option = avformat_options, .version = LIBAVUTIL_VERSION_INT, .child_next = format_child_next, - .child_class_next = format_child_class_next, + .child_class_iterate = format_child_class_iterate, .category = AV_CLASS_CATEGORY_MUXER, .get_category = get_category, }; @@ -114,13 +143,6 @@ static int io_open_default(AVFormatContext *s, AVIOContext **pb, av_log(s, loglevel, "Opening \'%s\' for %s\n", url, flags & AVIO_FLAG_WRITE ? "writing" : "reading"); -#if FF_API_OLD_OPEN_CALLBACKS -FF_DISABLE_DEPRECATION_WARNINGS - if (s->open_cb) - return s->open_cb(s, pb, url, flags, &s->interrupt_callback, options); -FF_ENABLE_DEPRECATION_WARNINGS -#endif - return ffio_open_whitelist(pb, url, flags, &s->interrupt_callback, options, s->protocol_whitelist, s->protocol_blacklist); } @@ -144,15 +166,26 @@ static void avformat_get_context_defaults(AVFormatContext *s) AVFormatContext *avformat_alloc_context(void) { AVFormatContext *ic; + AVFormatInternal *internal; ic = av_malloc(sizeof(AVFormatContext)); if (!ic) return ic; - avformat_get_context_defaults(ic); - ic->internal = av_mallocz(sizeof(*ic->internal)); - if (!ic->internal) { - avformat_free_context(ic); + internal = av_mallocz(sizeof(*internal)); + if (!internal) { + av_free(ic); + return NULL; + } + internal->pkt = av_packet_alloc(); + internal->parse_pkt = av_packet_alloc(); + if (!internal->pkt || !internal->parse_pkt) { + av_packet_free(&internal->pkt); + av_packet_free(&internal->parse_pkt); + av_free(internal); + av_free(ic); return NULL; } + avformat_get_context_defaults(ic); + ic->internal = internal; ic->internal->offset = AV_NOPTS_VALUE; ic->internal->raw_packet_buffer_remaining_size = RAW_PACKET_BUFFER_SIZE; ic->internal->shortest_end = AV_NOPTS_VALUE;