From d96e377c394cc4664a91bfd2c24bbb80f42ea8de Mon Sep 17 00:00:00 2001 From: Stefano Sabatini Date: Fri, 4 Oct 2013 15:20:50 +0200 Subject: [PATCH] lavu/channel_layout: change av_get_channel_layout() behavior at the next bump The new syntax is preferred since it allows backward syntax compatibility with libswr when switching to the new option handling code with AV_OPT_TYPE_CHANNEL_LAYOUT. With the new parser the string: 1234 is interpreted as a channel layout mask, rather than as a number of channels, and thus it's compatible with the current way to set a channel layout as an integer (e.g. for the icl and ocl options) making use of integer option values. ff_get_channel_layout() with compat=0 will be used in the AV_OPT_TYPE_CHANNEL handler code. The user is encouraged to switch to the new forward compatible syntax, which requires to put a trailing "c" when specifying a layout as a number of channels. --- libavutil/channel_layout.c | 43 ++++++++++++++++++++++++++++++++++++-- libavutil/channel_layout.h | 7 ++++++- libavutil/internal.h | 5 +++++ libavutil/version.h | 3 +++ 4 files changed, 55 insertions(+), 3 deletions(-) diff --git a/libavutil/channel_layout.c b/libavutil/channel_layout.c index e5827605ea..2b85de31d9 100644 --- a/libavutil/channel_layout.c +++ b/libavutil/channel_layout.c @@ -103,7 +103,11 @@ static const struct { { "downmix", 2, AV_CH_LAYOUT_STEREO_DOWNMIX, }, }; +#if FF_API_GET_CHANNEL_LAYOUT_COMPAT +static uint64_t get_channel_layout_single(const char *name, int name_len, int compat) +#else static uint64_t get_channel_layout_single(const char *name, int name_len) +#endif { int i; char *end; @@ -120,16 +124,40 @@ static uint64_t get_channel_layout_single(const char *name, int name_len) !memcmp(channel_names[i].name, name, name_len)) return (int64_t)1 << i; i = strtol(name, &end, 10); - if (end - name == name_len || - (end + 1 - name == name_len && *end == 'c')) + +#if FF_API_GET_CHANNEL_LAYOUT_COMPAT + if (compat) { + if (end - name == name_len || + (end + 1 - name == name_len && *end == 'c')) { + layout = av_get_default_channel_layout(i); + if (end - name == name_len) { + av_log(NULL, AV_LOG_WARNING, + "Single channel layout '%.*s' is interpreted as a number of channels, " + "switch to the syntax '%.*sc' otherwise it will be interpreted as a " + "channel layout number in a later version\n", + name_len, name, name_len, name); + return layout; + } + } + } else { +#endif + if ((end + 1 - name == name_len && *end == 'c')) return av_get_default_channel_layout(i); +#if FF_API_GET_CHANNEL_LAYOUT_COMPAT + } +#endif + layout = strtoll(name, &end, 0); if (end - name == name_len) return FFMAX(layout, 0); return 0; } +#if FF_API_GET_CHANNEL_LAYOUT_COMPAT +uint64_t ff_get_channel_layout(const char *name, int compat) +#else uint64_t av_get_channel_layout(const char *name) +#endif { const char *n, *e; const char *name_end = name + strlen(name); @@ -137,7 +165,11 @@ uint64_t av_get_channel_layout(const char *name) for (n = name; n < name_end; n = e + 1) { for (e = n; e < name_end && *e != '+' && *e != '|'; e++); +#if FF_API_GET_CHANNEL_LAYOUT_COMPAT + layout_single = get_channel_layout_single(n, e - n, compat); +#else layout_single = get_channel_layout_single(n, e - n); +#endif if (!layout_single) return 0; layout |= layout_single; @@ -145,6 +177,13 @@ uint64_t av_get_channel_layout(const char *name) return layout; } +#if FF_API_GET_CHANNEL_LAYOUT_COMPAT +uint64_t av_get_channel_layout(const char *name) +{ + return ff_get_channel_layout(name, 1); +} +#endif + 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 2906098313..ba4f96d2d0 100644 --- a/libavutil/channel_layout.h +++ b/libavutil/channel_layout.h @@ -136,7 +136,12 @@ enum AVMatrixEncoding { * - a channel layout mask, in hexadecimal starting with "0x" (see the * AV_CH_* macros). * - * Example: "stereo+FC" = "2+FC" = "2c+1c" = "0x7" + * @warning Starting from the next major bump the trailing character + * 'c' to specify a number of channels will be required, while a + * channel layout mask could also be specified as a decimal number + * (if and only if not followed by "c"). + * + * Example: "stereo+FC" = "2c+FC" = "2c+1c" = "0x7" */ uint64_t av_get_channel_layout(const char *name); diff --git a/libavutil/internal.h b/libavutil/internal.h index 6bc426e925..68108769a6 100644 --- a/libavutil/internal.h +++ b/libavutil/internal.h @@ -39,6 +39,7 @@ #include "timer.h" #include "cpu.h" #include "dict.h" +#include "version.h" #if ARCH_X86 # include "x86/emms.h" @@ -219,4 +220,8 @@ void avpriv_request_sample(void *avc, */ int avpriv_open(const char *filename, int flags, ...); +#if FF_API_GET_CHANNEL_LAYOUT_COMPAT +uint64_t ff_get_channel_layout(const char *name, int compat); +#endif + #endif /* AVUTIL_INTERNAL_H */ diff --git a/libavutil/version.h b/libavutil/version.h index 41e479cce7..001b612d4e 100644 --- a/libavutil/version.h +++ b/libavutil/version.h @@ -138,6 +138,9 @@ #ifndef FF_API_VDPAU #define FF_API_VDPAU (LIBAVUTIL_VERSION_MAJOR < 53) #endif +#ifndef FF_API_GET_CHANNEL_LAYOUT_COMPAT +#define FF_API_GET_CHANNEL_LAYOUT_COMPAT (LIBAVUTIL_VERSION_MAJOR < 53) +#endif /** * @}