diff --git a/doc/APIchanges b/doc/APIchanges index f5f7e0c07f..109d550573 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -15,6 +15,9 @@ libavutil: 2015-08-28 API changes, most recent first: +2017-01-24 - xxxxxxx - lavu 55.45.100 - channel_layout.h + Add av_get_extended_channel_layout() + 2017-01-22 - xxxxxxx - lavu 55.44.100 - lfg.h Add av_lfg_init_from_data(). diff --git a/doc/utils.texi b/doc/utils.texi index df887c7768..30a962ac0e 100644 --- a/doc/utils.texi +++ b/doc/utils.texi @@ -724,6 +724,11 @@ layout for that number of channels (see the function @code{av_get_default_channel_layout}). Note that not all channel counts have a default layout. +@item +a number of channels, in decimal, followed by 'C', yielding an unknown channel +layout with the specified number of channels. Note that not all channel layout +specification strings support unknown channel layouts. + @item a channel layout mask, in hexadecimal starting with "0x" (see the @code{AV_CH_*} macros in @file{libavutil/channel_layout.h}. @@ -731,7 +736,7 @@ a channel layout mask, in hexadecimal starting with "0x" (see the Before libavutil version 53 the trailing character "c" to specify a number of channels was optional, but now it is required, while a channel layout mask can -also be specified as a decimal number (if and only if not followed by "c"). +also be specified as a decimal number (if and only if not followed by "c" or "C"). See also the function @code{av_get_channel_layout} defined in @file{libavutil/channel_layout.h}. diff --git a/libavutil/channel_layout.c b/libavutil/channel_layout.c index 26c87c96a8..3bd5ee29b7 100644 --- a/libavutil/channel_layout.c +++ b/libavutil/channel_layout.c @@ -152,6 +152,28 @@ uint64_t av_get_channel_layout(const char *name) return layout; } +int av_get_extended_channel_layout(const char *name, uint64_t* channel_layout, int* nb_channels) +{ + int nb = 0; + char *end; + uint64_t layout = av_get_channel_layout(name); + + if (layout) { + *channel_layout = layout; + *nb_channels = av_get_channel_layout_nb_channels(layout); + return 0; + } + + nb = strtol(name, &end, 10); + if (!errno && *end == 'C' && *(end + 1) == '\0' && nb > 0 && nb < 64) { + *channel_layout = 0; + *nb_channels = nb; + return 0; + } + + return AVERROR(EINVAL); +} + void av_bprint_channel_layout(struct AVBPrint *bp, int nb_channels, uint64_t channel_layout) { diff --git a/libavutil/channel_layout.h b/libavutil/channel_layout.h index 38c3337829..50bb8f03c5 100644 --- a/libavutil/channel_layout.h +++ b/libavutil/channel_layout.h @@ -141,6 +141,20 @@ enum AVMatrixEncoding { */ uint64_t av_get_channel_layout(const char *name); +/** + * Return a channel layout and the number of channels based on the specified name. + * + * This function is similar to (@see av_get_channel_layout), but can also parse + * unknown channel layout specifications. + * + * @param[in] name channel layout specification string + * @param[out] channel_layout parsed channel layout (0 if unknown) + * @param[out] nb_channels number of channels + * + * @return 0 on success, AVERROR(EINVAL) if the parsing fails. + */ +int av_get_extended_channel_layout(const char *name, uint64_t* channel_layout, int* nb_channels); + /** * Return a description of a channel layout. * If nb_channels is <= 0, it is guessed from the channel_layout. diff --git a/libavutil/version.h b/libavutil/version.h index 2e83ef279e..9d95086ac6 100644 --- a/libavutil/version.h +++ b/libavutil/version.h @@ -79,7 +79,7 @@ */ #define LIBAVUTIL_VERSION_MAJOR 55 -#define LIBAVUTIL_VERSION_MINOR 44 +#define LIBAVUTIL_VERSION_MINOR 45 #define LIBAVUTIL_VERSION_MICRO 100 #define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \