diff options
author | James Almer <jamrial@gmail.com> | 2024-02-13 14:30:15 -0300 |
---|---|---|
committer | James Almer <jamrial@gmail.com> | 2024-02-18 09:59:40 -0300 |
commit | b5911654c4300c6a15d81feddd43a6709494addb (patch) | |
tree | 1c72d1eca15cf4fef1c99e0266965b4df48b4d58 | |
parent | e06ce6d2b45edac4a2df04f304e18d4727417d24 (diff) | |
download | ffmpeg-b5911654c4300c6a15d81feddd43a6709494addb.tar.gz |
avutil/channel_layout: print known layout names in custom layout
If a custom layout is equivalent to a native one, check if it matches one of the
known layout names and print that instead.
Signed-off-by: James Almer <jamrial@gmail.com>
-rw-r--r-- | libavutil/channel_layout.c | 68 | ||||
-rw-r--r-- | tests/ref/fate/channel_layout | 4 |
2 files changed, 44 insertions, 28 deletions
diff --git a/libavutil/channel_layout.c b/libavutil/channel_layout.c index 7f51c076dc..8b3bf2f4af 100644 --- a/libavutil/channel_layout.c +++ b/libavutil/channel_layout.c @@ -679,6 +679,29 @@ int av_channel_layout_copy(AVChannelLayout *dst, const AVChannelLayout *src) return 0; } +static int64_t masked_description(const AVChannelLayout *channel_layout, int start_channel) +{ + uint64_t mask = 0; + for (int i = start_channel; i < channel_layout->nb_channels; i++) { + enum AVChannel ch = channel_layout->u.map[i].id; + if (ch >= 0 && ch < 63 && mask < (1ULL << ch)) + mask |= (1ULL << ch); + else + return AVERROR(EINVAL); + } + return mask; +} + +static int has_channel_names(const AVChannelLayout *channel_layout) +{ + if (channel_layout->order != AV_CHANNEL_ORDER_CUSTOM) + return 0; + for (int i = 0; i < channel_layout->nb_channels; i++) + if (channel_layout->u.map[i].name[0]) + return 1; + return 0; +} + /** * If the layout is n-th order standard-order ambisonic, with optional * extra non-diegetic channels at the end, return the order. @@ -746,9 +769,17 @@ static int try_describe_ambisonic(AVBPrint *bp, const AVChannelLayout *channel_l extra.nb_channels = av_popcount64(channel_layout->u.mask); extra.u.mask = channel_layout->u.mask; } else { - extra.order = AV_CHANNEL_ORDER_CUSTOM; - extra.nb_channels = channel_layout->nb_channels - nb_ambi_channels; - extra.u.map = channel_layout->u.map + nb_ambi_channels; + int64_t mask; + if (!has_channel_names(channel_layout) && + (mask = masked_description(channel_layout, nb_ambi_channels)) > 0) { + extra.order = AV_CHANNEL_ORDER_NATIVE; + extra.nb_channels = av_popcount64(mask); + extra.u.mask = mask; + } else { + extra.order = AV_CHANNEL_ORDER_CUSTOM; + extra.nb_channels = channel_layout->nb_channels - nb_ambi_channels; + extra.u.map = channel_layout->u.map + nb_ambi_channels; + } } av_bprint_chars(bp, '+', 1); @@ -774,9 +805,17 @@ int av_channel_layout_describe_bprint(const AVChannelLayout *channel_layout, // fall-through case AV_CHANNEL_ORDER_CUSTOM: if (channel_layout->order == AV_CHANNEL_ORDER_CUSTOM) { + int64_t mask; int res = try_describe_ambisonic(bp, channel_layout); if (res >= 0) return 0; + if (!has_channel_names(channel_layout) && + (mask = masked_description(channel_layout, 0)) > 0) { + AVChannelLayout native = { .order = AV_CHANNEL_ORDER_NATIVE, + .nb_channels = av_popcount64(mask), + .u.mask = mask }; + return av_channel_layout_describe_bprint(&native, bp); + } } if (channel_layout->nb_channels) av_bprintf(bp, "%d channels (", channel_layout->nb_channels); @@ -1037,29 +1076,6 @@ uint64_t av_channel_layout_subset(const AVChannelLayout *channel_layout, return ret; } -static int64_t masked_description(AVChannelLayout *channel_layout, int start_channel) -{ - uint64_t mask = 0; - for (int i = start_channel; i < channel_layout->nb_channels; i++) { - enum AVChannel ch = channel_layout->u.map[i].id; - if (ch >= 0 && ch < 63 && mask < (1ULL << ch)) - mask |= (1ULL << ch); - else - return AVERROR(EINVAL); - } - return mask; -} - -static int has_channel_names(AVChannelLayout *channel_layout) -{ - if (channel_layout->order != AV_CHANNEL_ORDER_CUSTOM) - return 0; - for (int i = 0; i < channel_layout->nb_channels; i++) - if (channel_layout->u.map[i].name[0]) - return 1; - return 0; -} - int av_channel_layout_retype(AVChannelLayout *channel_layout, enum AVChannelOrder order, int flags) { int allow_lossy = !(flags & AV_CHANNEL_LAYOUT_RETYPE_FLAG_LOSSLESS); diff --git a/tests/ref/fate/channel_layout b/tests/ref/fate/channel_layout index 1d1f1cb082..466fa78d9e 100644 --- a/tests/ref/fate/channel_layout +++ b/tests/ref/fate/channel_layout @@ -195,7 +195,7 @@ With "FL@Boo": CUSTOM (1 channels (FL@Boo)) With "stereo": NATIVE (stereo) ~~ UNSPEC (2 channels) == NATIVE (stereo) - == CUSTOM (2 channels (FL+FR)) + == CUSTOM (stereo) != AMBI With "FR+FL": CUSTOM (2 channels (FR+FL)) ~~ UNSPEC (2 channels) @@ -205,7 +205,7 @@ With "FR+FL": CUSTOM (2 channels (FR+FL)) With "ambisonic 2+stereo": AMBI (ambisonic 2+stereo) ~~ UNSPEC (11 channels) != NATIVE - == CUSTOM (ambisonic 2+2 channels (FL+FR)) + == CUSTOM (ambisonic 2+stereo) == AMBI (ambisonic 2+stereo) With "2C": UNSPEC (2 channels) == UNSPEC (2 channels) |