#include "avio_internal.h"
#include "internal.h"
+#include "libavutil/avassert.h"
#include "libavutil/internal.h"
#include "libavutil/opt.h"
return NULL;
}
+#if FF_API_CHILD_CLASS_NEXT
static const AVClass *format_child_class_next(const AVClass *prev)
{
- AVInputFormat *ifmt = NULL;
- AVOutputFormat *ofmt = NULL;
+ const AVInputFormat *ifmt = NULL;
+ const AVOutputFormat *ofmt = NULL;
+ void *ifmt_iter = NULL, *ofmt_iter = NULL;
if (!prev)
return &ff_avio_class;
- while ((ifmt = av_iformat_next(ifmt)))
+ while ((ifmt = av_demuxer_iterate(&ifmt_iter)))
if (ifmt->priv_class == prev)
break;
- if (!ifmt)
- while ((ofmt = av_oformat_next(ofmt)))
+ if (!ifmt) {
+ ifmt_iter = NULL;
+ while ((ofmt = av_muxer_iterate(&ofmt_iter)))
if (ofmt->priv_class == prev)
break;
- if (!ofmt)
- while (ifmt = av_iformat_next(ifmt))
+ }
+ if (!ofmt) {
+ ofmt_iter = NULL;
+ while ((ifmt = av_demuxer_iterate(&ifmt_iter)))
if (ifmt->priv_class)
return ifmt->priv_class;
+ }
- while (ofmt = av_oformat_next(ofmt))
+ while ((ofmt = av_muxer_iterate(&ofmt_iter)))
if (ofmt->priv_class)
return ofmt->priv_class;
return NULL;
}
+#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)
{
.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,
};
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);
}
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;