diff options
author | Marton Balint <cus@passwd.hu> | 2024-03-09 21:01:38 +0100 |
---|---|---|
committer | Marton Balint <cus@passwd.hu> | 2024-03-16 19:49:39 +0100 |
commit | ed6207274e693128d8206a72487cc53335055cb3 (patch) | |
tree | 0894f46d9483d6f6fd2eb204474c995d0fa5406c /libavutil | |
parent | 44b2769619242ab3746d6477b88f5d5345a591ee (diff) | |
download | ffmpeg-ed6207274e693128d8206a72487cc53335055cb3.tar.gz |
avutil/channel_layout: add AV_CHANNEL_LAYOUT_RETYPE_FLAG_CANONICAL
Signed-off-by: Marton Balint <cus@passwd.hu>
Diffstat (limited to 'libavutil')
-rw-r--r-- | libavutil/channel_layout.c | 30 | ||||
-rw-r--r-- | libavutil/channel_layout.h | 7 | ||||
-rw-r--r-- | libavutil/version.h | 2 |
3 files changed, 38 insertions, 1 deletions
diff --git a/libavutil/channel_layout.c b/libavutil/channel_layout.c index 8c1b3362f7..d3abb2dc42 100644 --- a/libavutil/channel_layout.c +++ b/libavutil/channel_layout.c @@ -553,6 +553,33 @@ static int ambisonic_order(const AVChannelLayout *channel_layout) return order; } +static enum AVChannelOrder canonical_order(AVChannelLayout *channel_layout) +{ + int has_known_channel = 0; + int order; + + if (channel_layout->order != AV_CHANNEL_ORDER_CUSTOM) + return channel_layout->order; + + if (has_channel_names(channel_layout)) + return AV_CHANNEL_ORDER_CUSTOM; + + for (int i = 0; i < channel_layout->nb_channels && !has_known_channel; i++) + if (channel_layout->u.map[i].id != AV_CHAN_UNKNOWN) + has_known_channel = 1; + if (!has_known_channel) + return AV_CHANNEL_ORDER_UNSPEC; + + if (masked_description(channel_layout, 0) > 0) + return AV_CHANNEL_ORDER_NATIVE; + + order = ambisonic_order(channel_layout); + if (order >= 0 && masked_description(channel_layout, (order + 1) * (order + 1)) >= 0) + return AV_CHANNEL_ORDER_AMBISONIC; + + return AV_CHANNEL_ORDER_CUSTOM; +} + /** * If the custom layout is n-th order standard-order ambisonic, with optional * extra non-diegetic channels at the end, write its string description in bp. @@ -892,6 +919,9 @@ int av_channel_layout_retype(AVChannelLayout *channel_layout, enum AVChannelOrde if (!av_channel_layout_check(channel_layout)) return AVERROR(EINVAL); + if (flags & AV_CHANNEL_LAYOUT_RETYPE_FLAG_CANONICAL) + order = canonical_order(channel_layout); + if (channel_layout->order == order) return 0; diff --git a/libavutil/channel_layout.h b/libavutil/channel_layout.h index 10ffe74468..a1e9b08064 100644 --- a/libavutil/channel_layout.h +++ b/libavutil/channel_layout.h @@ -681,6 +681,13 @@ int av_channel_layout_compare(const AVChannelLayout *chl, const AVChannelLayout #define AV_CHANNEL_LAYOUT_RETYPE_FLAG_LOSSLESS (1 << 0) /** + * The specified retype target order is ignored and the simplest possible + * (canonical) order is used for which the input layout can be losslessy + * represented. + */ +#define AV_CHANNEL_LAYOUT_RETYPE_FLAG_CANONICAL (1 << 1) + +/** * Change the AVChannelOrder of a channel layout. * * Change of AVChannelOrder can be either lossless or lossy. In case of a diff --git a/libavutil/version.h b/libavutil/version.h index 09f8cdc292..57cad02ec0 100644 --- a/libavutil/version.h +++ b/libavutil/version.h @@ -79,7 +79,7 @@ */ #define LIBAVUTIL_VERSION_MAJOR 59 -#define LIBAVUTIL_VERSION_MINOR 1 +#define LIBAVUTIL_VERSION_MINOR 2 #define LIBAVUTIL_VERSION_MICRO 100 #define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ |