[FFmpeg-devel] [PATCH 2/4] lavd: add device capabilities API

Lukasz Marek lukasz.m.luki at gmail.com
Wed Feb 5 21:54:57 CET 2014


On 05.02.2014 02:35, Don Moir wrote:
>
> ----- Original Message ----- From: "Lukasz Marek" <lukasz.m.luki at gmail.com>
> To: <ffmpeg-devel at ffmpeg.org>
> Cc: "Lukasz Marek" <lukasz.m.luki at gmail.com>
> Sent: Sunday, February 02, 2014 7:02 PM
> Subject: [FFmpeg-devel] [PATCH 2/4] lavd: add device capabilities API
>
>
>> Signed-off-by: Lukasz Marek <lukasz.m.luki at gmail.com>
>> ---
>> libavdevice/avdevice.c | 191 +++++++++++++++++++++++++++++++++++++++
>> libavdevice/avdevice.h | 238
>> +++++++++++++++++++++++++++++++++++++++++++++++++
>> libavdevice/version.h  |   2 +-
>> libavformat/avformat.h |  12 +++
>> libavformat/version.h  |   2 +-
>> 5 files changed, 443 insertions(+), 2 deletions(-)
>>
>> diff --git a/libavdevice/avdevice.c b/libavdevice/avdevice.c
>> index 51617fb..fa524a2 100644
>> --- a/libavdevice/avdevice.c
>> +++ b/libavdevice/avdevice.c
>> @@ -17,9 +17,48 @@
>>  */
>>
>> #include "libavutil/avassert.h"
>> +#include "libavcodec/avcodec.h"
>> #include "avdevice.h"
>> #include "config.h"
>>
>> +#define AVDEVICE_AV_PARAM     AV_OPT_FLAG_AUDIO_PARAM    |
>> AV_OPT_FLAG_VIDEO_PARAM
>> +#define AVDEVICE_DECENC_PARAM AV_OPT_FLAG_DECODING_PARAM |
>> AV_OPT_FLAG_ENCODING_PARAM
>> +#define AVDEVICE_ALL_PARAM    AVDEVICE_AV_PARAM          |
>> AVDEVICE_DECENC_PARAM
>> +
>> +const AVOption av_device_capabilities[] = {
>> +    { "__device_name",    "device name",
>> offsetof(AVDeviceCapabilities, device_name), AV_OPT_TYPE_STRING,
>> +        {.str = NULL}, 0, 0, AVDEVICE_ALL_PARAM },
>> +    { "__device_context",  "device context",
>> offsetof(AVDeviceCapabilities, device_context), AV_OPT_TYPE_POINTER,
>> +        {.str = NULL}, 0, 0, AVDEVICE_ALL_PARAM },
>> +    { "__codec",          "codec", offsetof(AVDeviceCapabilities,
>> codec), AV_OPT_TYPE_INT,
>> +        {.i64 = -1}, -1, INT_MAX, AVDEVICE_ALL_PARAM },
>> +    { "__format",         "format", offsetof(AVDeviceCapabilities,
>> format), AV_OPT_TYPE_INT,
>> +        {.i64 = -1}, -1, INT_MAX, AVDEVICE_ALL_PARAM },
>> +
>> +    { "__sample_rate",    "sample rate",
>> offsetof(AVDeviceCapabilities, sample_rate), AV_OPT_TYPE_INT,
>> +        {.i64 = -1}, -1, INT_MAX, AV_OPT_FLAG_AUDIO_PARAM |
>> AVDEVICE_DECENC_PARAM },
>> +    { "__channels",       "channels", offsetof(AVDeviceCapabilities,
>> channels), AV_OPT_TYPE_INT,
>> +        {.i64 = -1}, -1, INT_MAX, AV_OPT_FLAG_AUDIO_PARAM |
>> AVDEVICE_DECENC_PARAM },
>> +    { "__channel_layout", "channel layout",
>> offsetof(AVDeviceCapabilities, channel_layout), AV_OPT_TYPE_INT,
>> +        {.i64 = -1}, -1, INT_MAX, AV_OPT_FLAG_AUDIO_PARAM |
>> AVDEVICE_DECENC_PARAM },
>> +
>> +    { "__window_width",  "window width",
>> offsetof(AVDeviceCapabilities, window_width), AV_OPT_TYPE_INT,
>> +        {.i64 = -1}, -1, INT_MAX, AV_OPT_FLAG_VIDEO_PARAM |
>> AVDEVICE_DECENC_PARAM },
>> +    { "__window_height", "window height",
>> offsetof(AVDeviceCapabilities, window_height), AV_OPT_TYPE_INT,
>> +        {.i64 = -1}, -1, INT_MAX, AV_OPT_FLAG_VIDEO_PARAM |
>> AVDEVICE_DECENC_PARAM },
>> +    { "__frame_width",   "frame width",
>> offsetof(AVDeviceCapabilities, frame_width), AV_OPT_TYPE_INT,
>> +        {.i64 = -1}, -1, INT_MAX, AV_OPT_FLAG_VIDEO_PARAM |
>> AVDEVICE_DECENC_PARAM },
>> +    { "__frame_height",  "frame height",
>> offsetof(AVDeviceCapabilities, frame_height), AV_OPT_TYPE_INT,
>> +        {.i64 = -1}, -1, INT_MAX, AV_OPT_FLAG_VIDEO_PARAM |
>> AVDEVICE_DECENC_PARAM },
>> +    { "__fps",            "fps", offsetof(AVDeviceCapabilities, fps),
>> AV_OPT_TYPE_RATIONAL,
>> +        {.dbl = -1}, -1, INT_MAX, AV_OPT_FLAG_VIDEO_PARAM |
>> AVDEVICE_DECENC_PARAM },
>> +    { NULL }
>> +};
>> +
>> +#undef AVDEVICE_AV_PARAM
>> +#undef AVDEVICE_DECENC_PARAM
>> +#undef AVDEVICE_ALL_PARAM
>> +
>> unsigned avdevice_version(void)
>> {
>>     av_assert0(LIBAVDEVICE_VERSION_MICRO >= 100);
>> @@ -52,3 +91,155 @@ int avdevice_dev_to_app_control_message(struct
>> AVFormatContext *s, enum AVDevToA
>>         return AVERROR(ENOSYS);
>>     return s->control_message_cb(s, type, data, data_size);
>> }
>> +
>> +static const char * get_opt_name_from_cap_enum(enum
>> AVDeviceCapability capability)
>> +{
>> +    switch (capability) {
>> +    case AV_DEV_CAP_DEVICE_NAME:
>> +        return "__device_name";
>> +    case AV_DEV_CAP_CODEC_ID:
>> +        return "__codec";
>> +    case AV_DEV_CAP_FORMAT:
>> +        return "__format";
>> +    case AV_DEV_CAP_SAMPLE_RATE:
>> +        return "__sample_rate";
>> +    case AV_DEV_CAP_CHANNELS:
>> +        return "__channels";
>> +    case AV_DEV_CAP_CHANNEL_LAYOUT:
>> +        return "__channel_layout";
>> +    case AV_DEV_CAP_WINDOW_WIDTH:
>> +        return "__window_width";
>> +    case AV_DEV_CAP_WINDOW_HEIGHT:
>> +        return "__window_height";
>> +    case AV_DEV_CAP_FRAME_WIDTH:
>> +        return "__frame_width";
>> +    case AV_DEV_CAP_FRAME_HEIGHT:
>> +        return "__frame_height";
>> +    case AV_DEV_CAP_FPS:
>> +        return "__fps";
>> +    default:
>> +        break;
>> +    }
>> +    return NULL;
>> +}
>> +int avdevice_init_device_capabilities(AVFormatContext *s,
>> AVDictionary **device_options)
>> +{
>> +    int ret;
>> +    if ((ret = av_opt_set_pointer(s->priv_data, "__device_context", s,
>> +                                  AV_OPT_SEARCH_CHILDREN)) < 0)
>> +        return (ret == AVERROR_OPTION_NOT_FOUND) ? AVERROR(ENOSYS) :
>> ret;
>> +    if ((ret = av_opt_set_dict(s->priv_data, device_options)) < 0)
>> +        return ret;
>> +    return 0;
>> +}
>> +
>> +int avdevice_finish_device_capabilities(AVFormatContext *s,
>> +                                        AVDeviceCapabilities **spec,
>> +                                        enum AVDeviceApplyStrategy
>> strategy)
>> +{
>> +    if (!s->oformat || !s->oformat->apply_configuration)
>> +        return AVERROR(ENOSYS);
>> +    return s->oformat->apply_configuration(s, (void **)spec, strategy);
>> +}
>> +
>> +void avdevice_free_device_capabilities(AVDeviceCapabilities **spec)
>> +{
>> +    if (!spec || !(*spec))
>> +        return;
>> +    av_free((*spec)->device_name);
>> +    av_freep(spec);
>> +}
>> +
>> +int avdevice_get_device_capability(AVFormatContext *s, enum
>> AVDeviceCapability capability,
>> +                                   AVOptionRanges **allowed_values)
>> +{
>> +    const char *opt_name;
>> +    if (!s || !allowed_values ||
>> +        !(opt_name = get_opt_name_from_cap_enum(capability)))
>> +        return AVERROR(EINVAL);
>> +    return av_opt_query_ranges(allowed_values, s->priv_data,
>> opt_name, AV_OPT_SEARCH_CHILDREN);
>> +}
>> +
>> +int avdevice_set_device_capability_int(AVFormatContext *s,
>> +                                       enum AVDeviceCapability
>> capability, int64_t value)
>> +{
>> +    const char *opt_name;
>> +    if (!s || !(opt_name = get_opt_name_from_cap_enum(capability)))
>> +        return AVERROR(EINVAL);
>> +    switch (capability) {
>> +    case AV_DEV_CAP_CODEC_ID:
>> +    case AV_DEV_CAP_FORMAT:
>> +    case AV_DEV_CAP_SAMPLE_RATE:
>> +    case AV_DEV_CAP_CHANNELS:
>> +    case AV_DEV_CAP_CHANNEL_LAYOUT:
>> +    case AV_DEV_CAP_WINDOW_WIDTH:
>> +    case AV_DEV_CAP_WINDOW_HEIGHT:
>> +    case AV_DEV_CAP_FRAME_WIDTH:
>> +    case AV_DEV_CAP_FRAME_HEIGHT:
>> +        return av_opt_set_int(s->priv_data, opt_name, value,
>> AV_OPT_SEARCH_CHILDREN);
>> +    default:
>> +        break;
>> +    }
>> +    av_log(s, AV_LOG_ERROR, "Capability %s is not of integer
>> type.\n", opt_name);
>> +    return AVERROR(EINVAL);
>> +}
>> +
>> +int avdevice_set_device_capability_string(AVFormatContext *s,
>> +                                          enum AVDeviceCapability
>> capability,
>> +                                          const char *value)
>> +{
>> +    const char *opt_name;
>> +    if (!s || !(opt_name = get_opt_name_from_cap_enum(capability)))
>> +        return AVERROR(EINVAL);
>> +    switch (capability) {
>> +    case AV_DEV_CAP_DEVICE_NAME:
>> +        return av_opt_set(s->priv_data, opt_name, value,
>> AV_OPT_SEARCH_CHILDREN);
>> +    default:
>> +        break;
>> +    }
>> +    av_log(s, AV_LOG_ERROR, "Capability %s is not of string type.\n",
>> opt_name);
>> +    return AVERROR(EINVAL);
>> +}
>> +
>> +int avdevice_set_device_capability_q(AVFormatContext *s,
>> +                                     enum AVDeviceCapability capability,
>> +                                     AVRational value)
>> +{
>> +    const char *opt_name;
>> +    if (!s || !(opt_name = get_opt_name_from_cap_enum(capability)))
>> +        return AVERROR(EINVAL);
>> +    switch (capability) {
>> +    case AV_DEV_CAP_FPS:
>> +        return av_opt_set_q(s->priv_data, opt_name, value,
>> AV_OPT_SEARCH_CHILDREN);
>> +    default:
>> +        break;
>> +    }
>> +    av_log(s, AV_LOG_ERROR, "Capability %s is not of AVRational
>> type.\n", opt_name);
>> +    return AVERROR(EINVAL);
>> +}
>> +
>> +int avdevice_list_devices(AVFormatContext *s, AVDeviceInfoList
>> **device_list)
>> +{
>> +    if (!s->oformat || !s->oformat->get_device_list)
>> +        return AVERROR(ENOSYS);
>> +    return s->oformat->get_device_list(s, (void **)device_list);
>> +}
>> +
>> +void avdevice_free_list_devices(AVDeviceInfoList **device_list)
>> +{
>> +    AVDeviceInfoList *list;
>> +    AVDeviceInfo *dev;
>> +    int i;
>> +
>> +    if (!device_list || !(*device_list))
>> +        return;
>> +    list = *device_list;
>> +
>> +    for (i = 0; i < list->nb_devices; i++) {
>> +        dev = &list->devices[i];
>> +        av_free(dev->device_name);
>> +        av_free(dev->device_description);
>> +        av_free(dev);
>> +    }
>> +    av_freep(device_list);
>> +}
>> diff --git a/libavdevice/avdevice.h b/libavdevice/avdevice.h
>> index a6408ea..bfcca35 100644
>> --- a/libavdevice/avdevice.h
>> +++ b/libavdevice/avdevice.h
>> @@ -43,6 +43,9 @@
>>  * @}
>>  */
>>
>> +#include "libavutil/log.h"
>> +#include "libavutil/opt.h"
>> +#include "libavutil/dict.h"
>> #include "libavformat/avformat.h"
>>
>> /**
>> @@ -186,4 +189,239 @@ int avdevice_dev_to_app_control_message(struct
>> AVFormatContext *s,
>>                                         enum AVDevToAppMessageType type,
>>                                         void *data, size_t data_size);
>>
>> +/**
>> + * Structure describes device capabilites.
>> + *
>> + * It is used by devices in conjuntion with av_device_capabilities
>> AVOption table
>> + * to to implement capabilities probing API.
>> + */
>> +typedef struct AVDeviceCapabilities {
>> +    const AVClass *class;
>> +    char *device_name;
>> +    AVFormatContext *device_context;
>> +    enum AVCodecID codec;
>> +    int format;                          /**< AVSampleFormat or
>> AVPixelFormat */
>> +    int sample_rate;
>> +    int channels;
>> +    int64_t channel_layout;
>> +    int window_width;
>> +    int window_height;
>> +    int frame_width;
>> +    int frame_height;
>> +    AVRational fps;
>> +} AVDeviceCapabilities;
>> +
>> +extern const AVOption av_device_capabilities[];
>> +
>> +/**
>> + * Enumerates device capabilities that can be probed.
>> + */
>> +enum AVDeviceCapability {
>> +    /**
>> +     * Device name.
>> +     *
>> +     * set:  set the device to read capability of.
>> +     * get:  value previously set, use avdevice_list_devices()
>> +     *       to get full list of the devices.
>> +     * type: string.
>> +     */
>> +    AV_DEV_CAP_DEVICE_NAME,
>> +
>> +    /**
>> +     * Supported codecs.
>> +     *
>> +     * set:  limit following queries to configurations supporting the
>> codec.
>> +     * get:  list all supported codecs.
>> +     * type: int (enum AVCodecID).
>> +     */
>> +    AV_DEV_CAP_CODEC_ID,
>> +
>> +    /**
>> +     * Supported sample/pixel formats.
>> +     *
>> +     * set:  limit following queries to configurations supporting the
>> format.
>> +     * get:  list all supported formats.
>> +     * type: int (enum AVSampleFormat / enum AVPixelFormat).
>> +     */
>> +    AV_DEV_CAP_FORMAT,
>> +
>> +    /**
>> +     * Supported sample/pixel formats.
>> +     *
>> +     * set:  limit following queries to configurations supporting the
>> format.
>> +     * get:  list all supported formats.
>> +     * type: int (enum AVSampleFormat / enum AVPixelFormat).
>> +     */
>> +    AV_DEV_CAP_SAMPLE_RATE,
>> +
>> +    /**
>> +     * Supported channels count.
>> +     *
>> +     * set:  limit following queries to configurations supporting the
>> cannels count.
>> +     * get:  list all supported channels count.
>> +     * type: int.
>> +     */
>> +    AV_DEV_CAP_CHANNELS,
>> +
>> +    /**
>> +     * Supported cannel layouts.
>> +     *
>> +     * set:  limit following queries to configurations supporting the
>> cannel layouts.
>> +     * get:  list all supported cannel layouts.
>> +     * type: int.
>> +     */
>> +    AV_DEV_CAP_CHANNEL_LAYOUT,
>> +
>> +    /**
>> +     * Supported window width/height.
>> +     *
>> +     * set:  limit following queries to configurations supporting the
>> window width/height.
>> +     * get:  list range of supported window width/height.
>> +     * type: int.
>> +     */
>> +    AV_DEV_CAP_WINDOW_WIDTH,
>> +    AV_DEV_CAP_WINDOW_HEIGHT,
>> +
>> +    /**
>> +     * Supported frame width/height.
>> +     *
>> +     * set:  limit following queries to configurations supporting the
>> frame width/height.
>> +     * get:  list range of supported frame width/height.
>> +     * type: int.
>> +     */
>> +    AV_DEV_CAP_FRAME_WIDTH,
>> +    AV_DEV_CAP_FRAME_HEIGHT,
>> +
>> +    /**
>> +     * Supported frames per second.
>> +     *
>> +     * set:  limit following queries to configurations supporting the
>> fps.
>> +     * get:  list range of supported fps.
>> +     * type: int.
>> +     */
>> +    AV_DEV_CAP_FPS
>> +};
>> +
>> +enum AVDeviceApplyStrategy {
>> +    AVDeviceApplyStrategyAbandon,           /**< don't apply settings
>> to device */
>> +    AVDeviceApplyStrategyAbandonNotValid,   /**< don't apply settings
>> to device when invalid */
>> +    AVDeviceApplyFixToTheNearestValidValue, /**< adjust values to the
>> nearest valid value */
>> +    AVDeviceApplyFixToTheBestValidValue     /**< adjust values to the
>> best valid value */
>> +};
>> +
>> +/**
>> + * Function prepares the device to be probed.
>> + *
>> + * This function must be called before using
>> av_device_get_device_capability()
>> + * or av_device_set_device_capability_*().
>> + * avdevice_finish_device_capabilities() must be called afterwards.
>> + *
>> + * @param s              device context.
>> + * @param device_options device-specific options.
>> + * @return >= 0 on success, negative otherwise.
>> + */
>> +int avdevice_init_device_capabilities(AVFormatContext *s,
>> +                                      AVDictionary **device_options);
>> +
>> +/**
>> + * Apply set parameters to device context and release data allocated
>> + * by avdevice_init_device_capabilities().
>> + *
>> + * All set capabilities are validated and tested. When configuration
>> is not
>> + * working then adjustment takes place according to provided strategy.
>> + * After potential adjustments, set capabilities are applied and
>> device configuration.
>> + * Mapping between capablities and device settings are device-specific.
>> + * In particular output device may not apply all parameters to the
>> context,
>> + * but use stream properties when avformat_write_header() is called.
>> + *
>> + * @note: This may be useful to validate if input stream may be
>> passed directly
>> + *        to output device, but usually capabilites should be tested
>> one by one
>> + *        and correct values should be provided.
>> + *
>> + * @param s         device context
>> + * @param[out] spec returns device configuration. May be NULL. If not
>> NULL
>> + *                  then must be freed with
>> avdevice_free_device_capabilities().
>> + * @param strategy  fixing values strategy. Ignored when spec is not
>> provided.
>> + * @return >= 0 on success, negative otherwise.
>> + *         AVERROR(EINVAL) when strategy is not implemented.
>> + */
>> +int avdevice_finish_device_capabilities(AVFormatContext *s,
>> +                                        AVDeviceCapabilities **spec,
>> +                                        enum AVDeviceApplyStrategy
>> strategy);
>> +
>> +/**
>> + * Free AVDeviceCapabilities struct and its allocated data.
>> + *
>> + * @param spec structure to be freed
>> + */
>> +void avdevice_free_device_capabilities(AVDeviceCapabilities **spec);
>> +
>> +/**
>> + * Return range(s) of valid values for device capability.
>> + *
>> + * This function allow to get ranges of values for device capability.
>> + * Returned ranges takes into account real device capablities and
>> + * values previously set by avdevice_set_device_capability_* functions.
>> + * For example list of supported formats may dependes on the codec
>> set previously,
>> + * fps may depends on resolution or codec set previously.
>> + *
>> + * @param s           device context
>> + * @param capability  capability to be tested.
>> + * @param[out] ranges list of allowed ranges for selected capability.
>> + * @return >= 0 on success, negative otherwise.
>> + */
>> +int avdevice_get_device_capability(AVFormatContext *s,
>> +                                   enum AVDeviceCapability capability,
>> +                                   AVOptionRanges **ranges);
>> +
>> +/**
>> + * Set device capability.
>> + *
>> + * @param s     device context
>> + * @param value new value for capability
>> + * @return >= 0 on success, negative otherwise.
>> + */
>> +int avdevice_set_device_capability_int(AVFormatContext *s,
>> +                                       enum AVDeviceCapability
>> capability,
>> +                                       int64_t value);
>> +int avdevice_set_device_capability_string(AVFormatContext *s,
>> +                                          enum AVDeviceCapability
>> capability,
>> +                                          const char *value);
>> +int avdevice_set_device_capability_q(AVFormatContext *s,
>> +                                     enum AVDeviceCapability capability,
>> +                                     AVRational value);
>> +
>> +/**
>> + * Structure describes basic parameters of the device.
>> + */
>> +typedef struct AVDeviceInfo {
>> +    char *device_name;                   /**< device name, format
>> depends on device */
>> +    char *device_description;            /**< human friendly name */
>> +} AVDeviceInfo;
>> +
>> +/**
>> + * List of available devices.
>> + */
>> +typedef struct AVDeviceInfoList {
>> +    AVDeviceInfo *devices;               /**< list of autodetected
>> devices */
>> +    int nb_devices;                      /**< number of autodetected
>> devices */
>> +    int default_device;                  /**< index of default device */
>> +} AVDeviceInfoList;
>> +
>> +/**
>> + * List available devices.
>> + *
>> + * @param ofmt         device format.
>> + * @param[out] devices list of autodetected devices.
>> + * @return count of autodetected devices, negative on error.
>> + */
>> +int avdevice_list_devices(struct AVFormatContext *s, AVDeviceInfoList
>> **device_list);
>> +
>> +/**
>> + * Convinient function to free result of avdevice_list_devices().
>> + *
>> + * @param devices device list to be freed.
>> + */
>> +void avdevice_free_list_devices(AVDeviceInfoList **device_list);
>> +
>> #endif /* AVDEVICE_AVDEVICE_H */
>> diff --git a/libavdevice/version.h b/libavdevice/version.h
>> index a621775..0dedc73 100644
>> --- a/libavdevice/version.h
>> +++ b/libavdevice/version.h
>> @@ -28,7 +28,7 @@
>> #include "libavutil/version.h"
>>
>> #define LIBAVDEVICE_VERSION_MAJOR  55
>> -#define LIBAVDEVICE_VERSION_MINOR   7
>> +#define LIBAVDEVICE_VERSION_MINOR   8
>> #define LIBAVDEVICE_VERSION_MICRO 100
>>
>> #define LIBAVDEVICE_VERSION_INT
>> AV_VERSION_INT(LIBAVDEVICE_VERSION_MAJOR, \
>> diff --git a/libavformat/avformat.h b/libavformat/avformat.h
>> index 50b7108..58bed4e 100644
>> --- a/libavformat/avformat.h
>> +++ b/libavformat/avformat.h
>> @@ -458,6 +458,18 @@ typedef struct AVOutputFormat {
>>      */
>>     int (*control_message)(struct AVFormatContext *s, int type,
>>                            void *data, size_t data_size);
>> +    /**
>> +     * Returns device list with it properties.
>> +     * @see avdevice_list_devices() for more details.
>> +     */
>> +    int (*get_device_list)(struct AVFormatContext *s, void
>> **device_list);
>> +    /**
>> +     * Allows to apply device configuration via
>> avdevice_set_device_capability_*
>> +     * API with posibility to adjust not matching configuration.
>> +     * @see avdevice_finish_device_capabilities() for more details.
>> +     */
>> +    int (*apply_configuration)(struct AVFormatContext *s, void
>> **configuration,
>> +                               int strategy);
>> } AVOutputFormat;
>> /**
>>  * @}
>> diff --git a/libavformat/version.h b/libavformat/version.h
>> index 38945a5..0fcbe60 100644
>> --- a/libavformat/version.h
>> +++ b/libavformat/version.h
>> @@ -30,7 +30,7 @@
>> #include "libavutil/version.h"
>>
>> #define LIBAVFORMAT_VERSION_MAJOR 55
>> -#define LIBAVFORMAT_VERSION_MINOR 29
>> +#define LIBAVFORMAT_VERSION_MINOR 30
>> #define LIBAVFORMAT_VERSION_MICRO 100
>>
>> #define LIBAVFORMAT_VERSION_INT
>> AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \
>> --
>
> Hi Lukasz,
>
> I am not sure about your device list API.
>
> You have:
>
> typedef struct AVDeviceInfoList {
>     AVDeviceInfo *devices;               /**< list of autodetected
> devices */
>     int nb_devices;                      /**< number of autodetected
> devices */
>     int default_device;                  /**< index of default device */
> } AVDeviceInfoList;
>
> int avdevice_list_devices(struct AVFormatContext *s, AVDeviceInfoList
> **device_list);
>
> Not sure why I would need an AVFormatContext but I may missing something
> there.

To get dev cap you need context for options for example. In 
implementation you need to "open" device to check if configuration is 
really working or list properties ranges. For example pulse audio allows 
to play on remote server. You need to know that user wants to test 
remote server and its done by device options.

> Just not exactly clear so this is just what makes the most sense to me.
>
> 1)  in avdevice_list_devices,  identify type of video and or audio devices.

Make sure you distinguish device at lavd level (pulseaudio, alsa, oss 
for audio and fbdev, xv, opengl, sdl for video) and device names for 
each of them (sound outputs, sound cards etc).
This function list the second ones for given lavd device. Maybe function 
name should be changed to not confuse.

> 2)  Provide a list and their capabilites at same time. So maybe:
>
> typedef struct AVDeviceInfo {
>     char *device_name;                   /**< device name, format
> depends on device */
>     char *device_description;            /**< human friendly name */
>     // either list or count
>     int  n_capabilities;
>    AVDeviceCapabilities *capabilities;
> } AVDeviceInfo;
>
> I know you have ways of doing it, but it seems akward at best and then
> more work to first find devices and then lookup capabilities for each
> deivce. I see I must init something to get capabilities as well so just
> don't see how that falls in line well.

It was already discussed. I started with something similar, but 
unfortunately it is not suitable for all cases. You cannot just return 
list of capabilities because they can interact with each other and they 
may differ for each device name.

The simple flow I see for video output is:
pick lavd device.
list device names.
pick device name
start cap query
set frame_width/height
query codecs
set codec
query formats
set valid format in filterchain sink
finish cap queries

And I don't think it is too much complicated.

-- 
Best Regards,
Lukasz Marek

If you can't explain it simply, you don't understand it well enough. - 
Albert Einstein


More information about the ffmpeg-devel mailing list