[FFmpeg-devel] [PATCH 1/4] lavf: add probe device API
Michael Niedermayer
michaelni at gmx.at
Thu Dec 5 00:55:11 CET 2013
On Wed, Dec 04, 2013 at 05:30:57PM +0100, Lukasz M wrote:
> On 25 November 2013 17:30, wm4 <nfxjfg at googlemail.com> wrote:
>
> > On Tue, 12 Nov 2013 00:11:59 +0100
> > Lukasz Marek <lukasz.m.luki at gmail.com> wrote:
> >
> > > 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.
> > >
> > > 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;
> > > + char* device_name; ///< device name, format
> > depends on device
> > > + char* device_description; ///< human friendly name
> > > + 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
> > > + };
> > > + } stream_info;
> > > +} AVDeviceConfig;
> > > +
> > > /*************************************************/
> > > /* 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 */
> > > +#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. */
> > > +
> > > /**
> > > * @addtogroup lavf_encoding
> > > * @{
> > > @@ -453,6 +483,11 @@ typedef struct AVOutputFormat {
> > >
> > > void (*get_output_timestamp)(struct AVFormatContext *s, int stream,
> > > int64_t *dts, int64_t *wall);
> > > +
> > > + /**
> > > + * Probe device. See avformat_probe_device() for more details.
> > > + */
> > > + AVDeviceConfig* (*probe_device)(AVDeviceConfig *wanted, int flags,
> > AVDictionary *opts);
> > > } AVOutputFormat;
> > > /**
> > > * @}
> > > @@ -1954,7 +1989,6 @@ enum AVCodecID av_guess_codec(AVOutputFormat *fmt,
> > const char *short_name,
> > > int av_get_output_timestamp(struct AVFormatContext *s, int stream,
> > > int64_t *dts, int64_t *wall);
> > >
> > > -
> > > /**
> > > * @}
> > > */
> > > @@ -2164,6 +2198,66 @@ int av_match_ext(const char *filename, const char
> > *extensions);
> > > int avformat_query_codec(AVOutputFormat *ofmt, enum AVCodecID codec_id,
> > int std_compliance);
> > >
> > > /**
> > > + * Probe device and return all valid configurations that are working on
> > hardware.
> > > + *
> > > + * Some audio device system may use any sample rate and channel count.
> > > + * Audio devices will not return all possible stream parameters (sample
> > rate, channel count/layout),
> > > + * but will return all device names and all codec/format pairs.
> > > + * Stream parameters will be copied from wanted configuration or
> > default device values will
> > > + * be used when no wanted value specified.
> > > + * Stream defaults will also be copied from default device values when
> > provided
> > > + * configuration is invalid and AV_PROBEDEV_ALLOW_STREAM_PARAM_CHANGES
> > flag is set.
> > > + *
> > > + * Video devices will return all devices that fulfill wanted
> > configuration.
> > > + * They will set width/height with screen resolution when
> > AV_PROBEDEV_ALLOW_STREAM_PARAM_CHANGES flag is set.
> > > + *
> > > + * When AV_PROBEDEV_DEFAULT_DEV flag is provided then only default
> > device is returned.
> > > + * This flag has precedence over devices requested by wanted
> > configuration or options.
> > > + * When default device cannot be determined, then random one device is
> > returned.
> > > + *
> > > + * When AV_PROBEDEV_RAW_DATA flag is provided then only raw codec will
> > be returned.
> > > + * It is supposed to be useful when filters are used.
> > > + *
> > > + * @param ofmt output device context.
> > > + * @param[out] valid all valid configurations or NULL when no valid
> > configuration detected.
> > > + * Returned value must be freed with
> > avformat_free_device_config().
> > > + * @param wanted expected configuration. May be NULL or not fully
> > filled.
> > > + * @param flags combination of AV_PROBE_DEVICE_*.
> > > + * @param opts device options. Meaning of options is device dependent.
> > > + * If any option is also available in wanted configuration then
> > wanted
> > > + * configuration has precedence.
> > > + * @return 0 on success, negative otherwise.
> > > + * @note AVERROR_PATCHWELCOME is returned when device doesn't implement
> > this function.
> > > + * In this case, negative result doesn't mean tested
> > configuration is invalid.
> > > + */
> > > +int avformat_probe_device(AVOutputFormat *ofmt, AVDeviceConfig **valid,
> > > + AVDeviceConfig *wanted, int flags,
> > AVDictionary *opts);
> > > +
> > > +/**
> > > + * Free device configuration and its internal data.
> > > + *
> > > + * @param config data to be freed.
> > > + */
> > > +void avformat_free_device_config(AVDeviceConfig **config);
> > > +
> > > +/**
> > > + * Initialize configuration with default values.
> > > + *
> > > + * @param config configuration to initialize.
> > > + *
> > > + * @note Function doesn't free internal data.
> > > + */
> > > +void avformat_device_config_defaults(AVDeviceConfig *config);
> > > +
> > > +/**
> > > + * Copy device configuration.
> > > + *
> > > + * @param config configuration to be copied.
> > > + * @return deep copy of device configuration.
> > > + */
> > > +AVDeviceConfig* avformat_copy_device_config(AVDeviceConfig* config);
> > > +
> > > +/**
> > > * @defgroup riff_fourcc RIFF FourCCs
> > > * @{
> > > * Get the tables mapping RIFF FourCCs to libavcodec AVCodecIDs. The
> > tables are
> > > @@ -2235,7 +2329,6 @@ int
> > avformat_match_stream_specifier(AVFormatContext *s, AVStream *st,
> > >
> > > int avformat_queue_attached_pictures(AVFormatContext *s);
> > >
> > > -
> > > /**
> > > * @}
> > > */
> > > diff --git a/libavformat/utils.c b/libavformat/utils.c
> > > index f02312f..d71e9ad 100644
> > > --- a/libavformat/utils.c
> > > +++ b/libavformat/utils.c
> > > @@ -4008,6 +4008,78 @@ int avformat_query_codec(AVOutputFormat *ofmt,
> > enum AVCodecID codec_id, int std_
> > > return AVERROR_PATCHWELCOME;
> > > }
> > >
> > > +int avformat_probe_device(AVOutputFormat *ofmt, AVDeviceConfig **valid,
> > > + AVDeviceConfig *wanted, int flags,
> > AVDictionary *opts)
> > > +{
> > > + if (!valid)
> > > + return -1;
> > > + *valid = NULL;
> > > + if (!ofmt)
> > > + return -1;
> > > + if (!ofmt->probe_device)
> > > + return AVERROR_PATCHWELCOME;
> > > +
> > > + if (wanted && wanted->codec != AV_CODEC_ID_NONE && wanted->format
> > != -1) {
> > > + int i;
> > > + AVCodec *codec = avcodec_find_encoder(wanted->codec);
> > > + if (!codec)
> > > + return -1;
> > > + if (codec->sample_fmts)
> > > + for (i = 0;; i++) {
> > > + if (wanted->format == codec->sample_fmts[i])
> > > + break;
> > > + if (codec->sample_fmts[i] == -1)
> > > + return -1;
> > > + }
> > > + if (codec->pix_fmts)
> > > + for (i = 0;; i++) {
> > > + if (wanted->format == codec->pix_fmts[i])
> > > + break;
> > > + if (codec->pix_fmts[i] == -1)
> > > + return -1;
> > > + }
> > > + }
> > > +
> > > + *valid = ofmt->probe_device(wanted, flags, opts);
> > > + return 0;
> > > +}
> > > +
> > > +void avformat_free_device_config(AVDeviceConfig **config)
> > > +{
> > > + AVDeviceConfig *current, *next;
> > > + if (!config)
> > > + return;
> > > +
> > > + next = *config;
> > > + while (next) {
> > > + current = next;
> > > + next = current->next;
> > > + av_free(current->device_name);
> > > + av_free(current->device_description);
> > > + av_free(current);
> > > + }
> > > + *config = NULL;
> > > +}
> > > +
> > > +void avformat_device_config_defaults(AVDeviceConfig *config)
> > > +{
> > > + if (!config)
> > > + return;
> > > + memset(config, 0, sizeof(AVDeviceConfig));
> > > + config->format = -1; /* AV_PIX_FMT_NONE or AV_SAMPLE_FMT_NONE */
> > > +}
> > > +
> > > +AVDeviceConfig* avformat_copy_device_config(AVDeviceConfig* config)
> > > +{
> > > + AVDeviceConfig *copy = av_memdup(config, sizeof(AVDeviceConfig));
> > > + if (copy) {
> > > + copy->next = NULL;
> > > + copy->device_name = av_strdup(config->device_name);
> > > + copy->device_description =
> > av_strdup(config->device_description);
> > > + }
> > > + return copy;
> > > +}
> > > +
> > > int avformat_network_init(void)
> > > {
> > > #if CONFIG_NETWORK
> >
> > Has anyone thought of the idea that the (de)muxer API is maybe not the
> > best way to handle I/O devices? I think even messing it into
> > libavfilter might make more sense. Or making a new API.
> >
>
> But how you want to keep backward compatibility when you move it somewhere
> else?
> I'd like to develop devices, but some decisions about that would be great.
if someone posts a patch that extends the API and that is needed for
some also posted device code.
and noone else comes up with a better patch and the patch has no ABI
issues (future extendbility, compatibility for example) and noone has
major objections then ill apply it.
> I'm finishing opengl device which I want to use and I will have to extend
> API to make it useful.
> Personally I don't mind submitting everything to open source, but without
> API extension I will sooner or later finish with my own fork.
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel at ffmpeg.org
> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
--
Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB
Opposition brings concord. Out of discord comes the fairest harmony.
-- Heraclitus
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: Digital signature
URL: <http://ffmpeg.org/pipermail/ffmpeg-devel/attachments/20131205/b1f788e8/attachment.asc>
More information about the ffmpeg-devel
mailing list