[FFmpeg-devel] [PATCH 1/4] lavf: add probe device API

Lukasz M lukasz.m.luki at gmail.com
Wed Dec 4 17:33:30 CET 2013


On 25 November 2013 21:42, Lukasz M <lukasz.m.luki at gmail.com> wrote:

> On 25 November 2013 15:16, Nicolas George <george at nsup.org> wrote:
>
>> Le duodi 22 brumaire, an CCXXII, Lukasz Marek a écrit :
>> > Adds new API dedicated for output devices.
>> >
>> > This API allows to
>> > - Test device with provided configuration
>> >   Audio devices params:
>> >     - device name
>> >     - codec
>> >     - sample format
>> >     - channel count
>> >     - channels layout
>> >     - sample rate
>> >   Video devices params:
>> >     - device name
>> >     - codec
>> >     - pixel format
>> >     - width (minimal width as input and real width as output)
>> >     - height (minimal height as input and real height as output)
>> >
>> > - Get all supported configurations matching provided filter.
>> >   Filter may contain any subset of Audio/Video device params.
>>
>> Just a few thought, especially linked to the compatibility of this API and
>> the cases I know best, i.e. mostly ALSA.
>>
>> >
>> > Behaviour of probe function can also be modified by flags.
>> >
>> > Signed-off-by: Lukasz Marek <lukasz.m.luki at gmail.com>
>> > ---
>> >  libavformat/avformat.h |   97
>> +++++++++++++++++++++++++++++++++++++++++++++++-
>> >  libavformat/utils.c    |   72 +++++++++++++++++++++++++++++++++++
>> >  2 files changed, 167 insertions(+), 2 deletions(-)
>> >
>> > diff --git a/libavformat/avformat.h b/libavformat/avformat.h
>> > index 6bd54ce..68b9269 100644
>> > --- a/libavformat/avformat.h
>> > +++ b/libavformat/avformat.h
>> > @@ -323,6 +323,28 @@ typedef struct AVFrac {
>> >      int64_t val, num, den;
>> >  } AVFrac;
>> >
>> > +/**
>> > + *
>> > + */
>> > +typedef struct AVDeviceConfig {
>>
>> > +    struct AVDeviceConfig *next;
>>
>> Minor: the rest of the API usually returns an array rather than a linked
>> list.
>>
>> > +    char* device_name;                  ///< device name, format
>> depends on device
>> > +    char* device_description;           ///< human friendly name
>>
>> Style, minor: * belongs with the variable name, not the type.
>>
>> > +    enum AVCodecID codec;               ///< codec
>> > +    int format;                         ///< format (AVPixelFormat /
>> AVSampleFormat)
>>
>> > +    union {
>> > +        struct {  // audio parameters
>> > +            int sample_rate;            ///< [in]: expected sample
>> rate,   [out]: device's default sample rate
>> > +            int channels;               ///< [in]: expected channel
>> count, [out]: device's default channel count
>> > +            int64_t channel_layout;     ///< [in]: expected layout,
>>      [out]: device's default layout
>> > +        };
>>
>> > +        struct {  // video parameters
>> > +            int width;                  ///< [in]: required width,
>>  [out]: maximum width
>> > +            int height;                 ///< [in]: required height,
>> [out]: maximum height
>> > +        };
>>
>> Some kind of frame rate information would probably be useful too.
>>
>> > +    } stream_info;
>>
>> IMHO, using an union is not worth the trouble.
>>
>> > +} AVDeviceConfig;
>>
>> I find this structure a bit strange: how does it express that the device
>> called "default" can support either stereo or 5.1? Or that /dev/video1 can
>> accept either RAWVIDEO/yuv420p or MJPEG?
>>
>
> I started with assumption that all should be done by one function - maybe
> that was wrong assumption.
>
> Audio case is not so easy as you may think.
> I tested it mostly on pulse and pulse can accept sampling rate 1-192kHz
> and any channel count, so I haven't taken this scenario into account to
> enumerate every working audio config.
> Now I think enumerating channel layout should be possible anyway.
>
> The scenarios I had in mind are:
> - check if stream can be written with its original params (channel count,
> sample rate, channel layout).
> - get device's default audio params (channel count, sample rate, channel
> layout).
> You will get these for each device/codec/format unless you filter it out.
>
> For video case:
> You will 2 entries as a result, one for each codec/format pair.
> So one for RAWVIDEO/yuv420p one for MJPEG/yuv420p.
>
> For both cases I think formats may be grouped so there is one entry for
> codec/all-codec-formats returned.
> But for audio raw codec it doesn't make big differenece.
>
>
>> I believe there are two dimensions in this kind of API: first, getting a
>> list of valid device names, to propose in GUIs; and, second, for any valid
>> device, getting the set of supported parameters.
>>
>
> After a while I started to think it is not the best approach to use just
> one function.
> One reason is that you pointer. For GUI you only need a names first.
> The second reason is to save some memory, by not duplicating device name
> so many times for no reason in fact.
>
> So,
> There could be one function to enumerate device names (system name and
> human friendly name)
> Second one to enumerate layouts. (also mostly for GUI)
> And third one to get/check other params, but still think to not enumerate
> all sample rates / channels, but just validate / get defaults.
>
>
>
>> Note that the first step may fail: for ALSA, the device name can be a
>> complex string containing parameters and chained plugins, building a
>> complete list is impossible. The same goes for devices that correspond to
>> entries in /dev: there is no way of knowing all automatic symlinks
>> configured on the system.
>
>
> OK, but how other tools handle this? I don't know ALSA, but I don't
> believe there is not way to return possible configs.
> One other hand I believe there may be problems sometimes with simple
> things. For example I couldn't find how to determine default pulse device.
> In API you just pass a NULL as device name, but cannot determine its real
> full name.
>
>
>>  > +
>> >  /*************************************************/
>> >  /* input/output formats */
>> >
>> > @@ -379,6 +401,14 @@ typedef struct AVProbeData {
>> >
>> >  #define AVFMT_SEEK_TO_PTS   0x4000000 /**< Seeking is based on PTS */
>> >
>> > +#define AV_PROBEDEV_DEFAULT_DEV                 0x0001  /**< Probe
>> default device only */
>>
>> > +#define AV_PROBEDEV_RAW_DATA                    0x0002  /**< Return
>> only raw codecs: AV_CODEC_ID_PCM_*,
>> > +
>>               AV_CODEC_ID_RAWVIDEO */
>>
>> What about hwaccel and similar?
>>
>
> You mean that some devices may need encoded streams? I added this to cover
> somehow that PCM audio is not just one codec, but bunch of them.
> You may specify specific codec in wanted configuration passed to
> probe_device.
>
>
>>
>> > +#define AV_PROBEDEV_ALLOW_STREAM_PARAM_CHANGES  0x0004  /**< Allow
>> modification of wanted stream
>> > +
>> parameteres when provided value is not supported.
>> > +                                                             Video
>> devices will update width and height for
>> > +                                                             screen
>> resolution. */
>> > +
>>
>> Allowing to request some kind of range would probably be more versatile:
>>
>>     int width;     ///< preferred width
>>     int width_min; ///< minimum possible width
>>     int width_max; ///< maximum possible width
>>
>
> Is there any use case of this?
>
>
I sent it only to Nicolas, forwarding to list.


More information about the ffmpeg-devel mailing list