diff --git a/doc/APIchanges b/doc/APIchanges index 338e314102..7d25679490 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -15,6 +15,10 @@ libavutil: 2014-08-09 API changes, most recent first: +2015-01-11 - xxxxxxx - lavd 56.4.100 - avdevice.h + Add avdevice_list_input_sources(). + Add avdevice_list_output_sinks(). + 201x-xx-xx - xxxxxxx - lavc 56.10.0 - vdpau.h Add av_vdpau_get_surface_parameters(). diff --git a/libavdevice/Makefile b/libavdevice/Makefile index 6b8ab2e90a..872504bc6e 100644 --- a/libavdevice/Makefile +++ b/libavdevice/Makefile @@ -7,6 +7,7 @@ HEADERS = avdevice.h \ OBJS = alldevices.o \ avdevice.o \ + utils.o \ # input/output devices OBJS-$(CONFIG_ALSA_INDEV) += alsa-audio-common.o \ diff --git a/libavdevice/avdevice.c b/libavdevice/avdevice.c index 72e573d76e..72e1b67887 100644 --- a/libavdevice/avdevice.c +++ b/libavdevice/avdevice.c @@ -21,6 +21,7 @@ #include "libavutil/pixfmt.h" #include "libavcodec/avcodec.h" #include "avdevice.h" +#include "internal.h" #include "config.h" #include "libavutil/ffversion.h" @@ -208,6 +209,44 @@ int avdevice_list_devices(AVFormatContext *s, AVDeviceInfoList **device_list) return ret; } +static int list_devices_for_context(AVFormatContext *s, AVDictionary *options, + AVDeviceInfoList **device_list) +{ + AVDictionary *tmp = NULL; + int ret; + + av_dict_copy(&tmp, options, 0); + if ((ret = av_opt_set_dict2(s, &tmp, AV_OPT_SEARCH_CHILDREN)) < 0) + goto fail; + ret = avdevice_list_devices(s, device_list); + fail: + av_dict_free(&tmp); + avformat_free_context(s); + return ret; +} + +int avdevice_list_input_sources(AVInputFormat *device, const char *device_name, + AVDictionary *device_options, AVDeviceInfoList **device_list) +{ + AVFormatContext *s = NULL; + int ret; + + if ((ret = ff_alloc_input_device_context(&s, device, device_name)) < 0) + return ret; + return list_devices_for_context(s, device_options, device_list); +} + +int avdevice_list_output_sinks(AVOutputFormat *device, const char *device_name, + AVDictionary *device_options, AVDeviceInfoList **device_list) +{ + AVFormatContext *s = NULL; + int ret; + + if ((ret = avformat_alloc_output_context2(&s, device, device_name, NULL)) < 0) + return ret; + return list_devices_for_context(s, device_options, device_list); +} + void avdevice_free_list_devices(AVDeviceInfoList **device_list) { AVDeviceInfoList *list; diff --git a/libavdevice/avdevice.h b/libavdevice/avdevice.h index a39522819e..2d675b012d 100644 --- a/libavdevice/avdevice.h +++ b/libavdevice/avdevice.h @@ -484,4 +484,26 @@ int avdevice_list_devices(struct AVFormatContext *s, AVDeviceInfoList **device_l */ void avdevice_free_list_devices(AVDeviceInfoList **device_list); +/** + * List devices. + * + * Returns available device names and their parameters. + * These are convinient wrappers for avdevice_list_devices(). + * Device context is allocated and deallocated internally. + * + * @param device device format. May be NULL if device name is set. + * @param device_name device name. May be NULL if device format is set. + * @param device_options An AVDictionary filled with device-private options. May be NULL. + * The same options must be passed later to avformat_write_header() for output + * devices or avformat_open_input() for input devices, or at any other place + * that affects device-private options. + * @param[out] device_list list of autodetected devices + * @return count of autodetected devices, negative on error. + * @note device argument takes precedence over device_name when both are set. + */ +int avdevice_list_input_sources(struct AVInputFormat *device, const char *device_name, + AVDictionary *device_options, AVDeviceInfoList **device_list); +int avdevice_list_output_sinks(struct AVOutputFormat *device, const char *device_name, + AVDictionary *device_options, AVDeviceInfoList **device_list); + #endif /* AVDEVICE_AVDEVICE_H */ diff --git a/libavdevice/internal.h b/libavdevice/internal.h new file mode 100644 index 0000000000..3cd1b0686e --- /dev/null +++ b/libavdevice/internal.h @@ -0,0 +1,27 @@ +/* + * 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 + */ + +#ifndef AVDEVICE_INTERNAL_H +#define AVDEVICE_INTERNAL_H + +#include "libavformat/avformat.h" + +int ff_alloc_input_device_context(struct AVFormatContext **avctx, struct AVInputFormat *iformat, + const char *format); + +#endif diff --git a/libavdevice/utils.c b/libavdevice/utils.c new file mode 100644 index 0000000000..ccd7318012 --- /dev/null +++ b/libavdevice/utils.c @@ -0,0 +1,59 @@ +/* + * 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 "internal.h" +#include "libavutil/opt.h" +#include "libavformat/avformat.h" + +int ff_alloc_input_device_context(AVFormatContext **avctx, AVInputFormat *iformat, const char *format) +{ + AVFormatContext *s; + int ret = 0; + + *avctx = NULL; + if (!iformat && !format) + return AVERROR(EINVAL); + if (!(s = avformat_alloc_context())) + return AVERROR(ENOMEM); + + if (!iformat) + iformat = av_find_input_format(format); + if (!iformat || !iformat->priv_class || !AV_IS_INPUT_DEVICE(iformat->priv_class->category)) { + ret = AVERROR(EINVAL); + goto error; + } + s->iformat = iformat; + if (s->iformat->priv_data_size > 0) { + s->priv_data = av_mallocz(s->iformat->priv_data_size); + if (!s->priv_data) { + ret = AVERROR(ENOMEM); + goto error; + } + if (s->iformat->priv_class) { + *(const AVClass**)s->priv_data= s->iformat->priv_class; + av_opt_set_defaults(s->priv_data); + } + } else + s->priv_data = NULL; + + *avctx = s; + return 0; + error: + avformat_free_context(s); + return ret; +} diff --git a/libavdevice/version.h b/libavdevice/version.h index 3e427f024d..8de07f08b2 100644 --- a/libavdevice/version.h +++ b/libavdevice/version.h @@ -28,7 +28,7 @@ #include "libavutil/version.h" #define LIBAVDEVICE_VERSION_MAJOR 56 -#define LIBAVDEVICE_VERSION_MINOR 3 +#define LIBAVDEVICE_VERSION_MINOR 4 #define LIBAVDEVICE_VERSION_MICRO 100 #define LIBAVDEVICE_VERSION_INT AV_VERSION_INT(LIBAVDEVICE_VERSION_MAJOR, \