]> git.sesse.net Git - ffmpeg/blobdiff - libavformat/options.c
avutil: remove deprecated AVClass.child_class_next
[ffmpeg] / libavformat / options.c
index c188c23506a20b8a3c545f53b086b9d671bee891..dccb6faa730c11b976ce4df2d06bac8bf71a5cdc 100644 (file)
@@ -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;