Add an AVClass for AVDevice as the .child_class_next member for lavf's AVClass will no longer find devices. --- fftools/cmdutils.c | 10 +++++ fftools/ffmpeg_opt.c | 2 +- libavdevice/Makefile | 1 + libavdevice/avdevice.h | 1 + libavdevice/options.c | 115 +++++++++++++++++++++++++++++++++++++++++++++++++ libavformat/options.c | 37 ++++++++++------ 6 files changed, 151 insertions(+), 15 deletions(-) create mode 100644 libavdevice/options.c
diff --git a/fftools/cmdutils.c b/fftools/cmdutils.c index 956eb7b974..857bc31c0a 100644 --- a/fftools/cmdutils.c +++ b/fftools/cmdutils.c @@ -549,6 +549,9 @@ int opt_default(void *optctx, const char *opt, const char *arg) char opt_stripped[128]; const char *p; const AVClass *cc = avcodec_get_class(), *fc = avformat_get_class(); +#if CONFIG_AVDEVICE + const AVClass *dc = avdevice_get_class(); +#endif #if CONFIG_AVRESAMPLE const AVClass *rc = avresample_get_class(); #endif @@ -580,6 +583,13 @@ int opt_default(void *optctx, const char *opt, const char *arg) av_log(NULL, AV_LOG_VERBOSE, "Routing option %s to both codec and muxer layer\n", opt); consumed = 1; } +#if CONFIG_AVDEVICE + else if ((o = opt_find(&dc, opt, NULL, 0, + AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ))) { + av_dict_set(&format_opts, opt, arg, FLAGS); + consumed = 1; + } +#endif #if CONFIG_SWSCALE if (!consumed && (o = opt_find(&sc, opt, NULL, 0, AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ))) { diff --git a/fftools/ffmpeg_opt.c b/fftools/ffmpeg_opt.c index 45c26c391e..82944c903a 100644 --- a/fftools/ffmpeg_opt.c +++ b/fftools/ffmpeg_opt.c @@ -967,7 +967,7 @@ static int open_input_file(OptionsContext *o, const char *filename) { InputFile *f; AVFormatContext *ic; - const AVInputFormat *file_iformat = NULL; + AVInputFormat *file_iformat = NULL; int err, i, ret; int64_t timestamp; AVDictionary *unused_opts = NULL; diff --git a/libavdevice/Makefile b/libavdevice/Makefile index f11a6f2a86..65f7c2971d 100644 --- a/libavdevice/Makefile +++ b/libavdevice/Makefile @@ -7,6 +7,7 @@ HEADERS = avdevice.h \ OBJS = alldevices.o \ avdevice.o \ utils.o \ + options.o OBJS-$(HAVE_LIBC_MSVCRT) += file_open.o OBJS-$(CONFIG_SHARED) += reverse.o diff --git a/libavdevice/avdevice.h b/libavdevice/avdevice.h index dd6ad9365e..bacc2c3aad 100644 --- a/libavdevice/avdevice.h +++ b/libavdevice/avdevice.h @@ -535,6 +535,7 @@ int avdevice_list_input_sources(struct AVInputFormat *device, const char *device int avdevice_list_output_sinks(struct AVOutputFormat *device, const char *device_name, AVDictionary *device_options, AVDeviceInfoList **device_list); +const AVClass *avdevice_get_class(void); /** * @} */ diff --git a/libavdevice/options.c b/libavdevice/options.c new file mode 100644 index 0000000000..e9d79d7481 --- /dev/null +++ b/libavdevice/options.c @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2000, 2001, 2002 Fabrice Bellard + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ +#include "libavformat/avformat.h" + +#include "libavdevice/avdevice.h" + +#include "libavutil/internal.h" +#include "libavutil/opt.h" + +/** + * @file + * Options definition for AVFormatContext. + */ + +FF_DISABLE_DEPRECATION_WARNINGS +//#include "options_table.h" +static const AVOption avdevice_options[] = { +{ NULL }, +}; +FF_ENABLE_DEPRECATION_WARNINGS + +static const char* device_to_name(void* ptr) +{ + AVFormatContext* fc = (AVFormatContext*) ptr; + if(fc->iformat) return fc->iformat->name; + else if(fc->oformat) return fc->oformat->name; + else return "NULL"; +} + +static void *device_child_next(void *obj, void *prev) +{ + AVFormatContext *s = obj; + if (!prev && s->priv_data && + ((s->iformat && s->iformat->priv_class) || + s->oformat && s->oformat->priv_class)) + return s->priv_data; + if (s->pb && s->pb->av_class && prev != s->pb) + return s->pb; + return NULL; +} + +static const AVClass *device_child_class_next(const AVClass *prev) +{ + void *opaque = NULL; + const AVInputFormat *ifmt = NULL; + const AVOutputFormat *ofmt = NULL; + + while ((ifmt = av_indev_iterate(&opaque))) { + if (prev && ifmt->priv_class == prev) + goto next_demuxer; + } + opaque = NULL; + + while ((ofmt = av_outdev_iterate(&opaque))) { + if (prev && ofmt->priv_class == prev) + goto next_muxer; + } + opaque = NULL; + +next_demuxer: + while (ifmt = av_indev_iterate(&opaque)) { + if (ifmt->priv_class) + return ifmt->priv_class; + } + opaque = NULL; + +next_muxer: + while (ofmt = av_outdev_iterate(&opaque)) { + if (ofmt->priv_class) + return ofmt->priv_class; + } + + return NULL; +} + +static AVClassCategory get_category(void *ptr) +{ + AVFormatContext* s = ptr; + if(s->iformat) return AV_CLASS_CATEGORY_DEMUXER; + else return AV_CLASS_CATEGORY_MUXER; +} + +static const AVClass av_device_context_class = { + .class_name = "AVDeviceContext", + .item_name = device_to_name, + .option = avdevice_options, + .version = LIBAVUTIL_VERSION_INT, + .child_next = device_child_next, + .child_class_next = device_child_class_next, + .category = AV_CLASS_CATEGORY_MUXER, + .get_category = get_category, +}; + + +const AVClass *avdevice_get_class(void) +{ + return &av_device_context_class; +} diff --git a/libavformat/options.c b/libavformat/options.c index c188c23506..a170f3f133 100644 --- a/libavformat/options.c +++ b/libavformat/options.c @@ -55,28 +55,37 @@ static void *format_child_next(void *obj, void *prev) static const AVClass *format_child_class_next(const AVClass *prev) { - AVInputFormat *ifmt = NULL; - AVOutputFormat *ofmt = NULL; + void *opaque = NULL; + const AVInputFormat *ifmt = NULL; + const AVOutputFormat *ofmt = NULL; if (!prev) return &ff_avio_class; - while ((ifmt = av_iformat_next(ifmt))) - if (ifmt->priv_class == prev) - break; + while ((ifmt = av_demuxer_iterate(&opaque))) { + if (prev && ifmt->priv_class == prev) + goto next_demuxer; + } + opaque = NULL; - 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; + while ((ofmt = av_muxer_iterate(&opaque))) { + if (prev && ofmt->priv_class == prev) + goto next_muxer; + } + opaque = NULL; - while (ofmt = av_oformat_next(ofmt)) +next_demuxer: + while (ifmt = av_demuxer_iterate(&opaque)) { + if (ifmt->priv_class) + return ifmt->priv_class; + } + opaque = NULL; + +next_muxer: + while (ofmt = av_muxer_iterate(&opaque)) { if (ofmt->priv_class) return ofmt->priv_class; + } return NULL; } -- 2.14.3 (Apple Git-98) _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel