[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