aboutsummaryrefslogtreecommitdiffstats
path: root/libavformat/options.c
diff options
context:
space:
mode:
authorAnton Khirnov <anton@khirnov.net>2020-05-27 15:34:07 +0200
committerAnton Khirnov <anton@khirnov.net>2020-06-10 12:36:44 +0200
commit7aa7d68971e48f6bbf729a6feb318a17010d410f (patch)
tree1088e47a8dbd30816f0df22e5606a438df0c6d42 /libavformat/options.c
parent2cbd54451994523c334fd5ba88e16bd184701dd0 (diff)
downloadffmpeg-7aa7d68971e48f6bbf729a6feb318a17010d410f.tar.gz
AVFormatContext: switch to child_class_iterate()
Diffstat (limited to 'libavformat/options.c')
-rw-r--r--libavformat/options.c64
1 files changed, 64 insertions, 0 deletions
diff --git a/libavformat/options.c b/libavformat/options.c
index e14510504f..3160904fda 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,6 +54,8 @@ static void *format_child_next(void *obj, void *prev)
return NULL;
}
+#if FF_API_CHILD_CLASS_NEXT
+FF_DISABLE_DEPRECATION_WARNINGS
static const AVClass *format_child_class_next(const AVClass *prev)
{
AVInputFormat *ifmt = NULL;
@@ -80,6 +83,64 @@ static const AVClass *format_child_class_next(const AVClass *prev)
return NULL;
}
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
+
+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)
+{
+ // 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 (state == CHILD_CLASS_ITER_MUX) {
+ const AVOutputFormat *ofmt;
+
+ while ((ofmt = av_muxer_iterate(&val))) {
+ ret = ofmt->priv_class;
+ if (ret)
+ goto finish;
+ }
+
+ val = NULL;
+ state++;
+ }
+
+ if (state == CHILD_CLASS_ITER_DEMUX) {
+ const AVInputFormat *ifmt;
+
+ 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 +155,10 @@ static const AVClass av_format_context_class = {
.option = avformat_options,
.version = LIBAVUTIL_VERSION_INT,
.child_next = format_child_next,
+#if FF_API_CHILD_CLASS_NEXT
.child_class_next = format_child_class_next,
+#endif
+ .child_class_iterate = format_child_class_iterate,
.category = AV_CLASS_CATEGORY_MUXER,
.get_category = get_category,
};