1
0
mirror of https://github.com/FFmpeg/FFmpeg.git synced 2025-01-08 13:22:53 +02:00

AVFormatContext: switch to child_class_iterate()

This commit is contained in:
Anton Khirnov 2020-05-27 15:34:07 +02:00
parent 2cbd544519
commit 7aa7d68971

View 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,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,
};