X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavutil%2Faudioconvert.c;h=e17f52ee59486eca4b60bda568a4bdb8eece9c0c;hb=972cad77fa13ae312650dd0b7b99e484ffcb7949;hp=aa652a66b1061bc09ed9c8a3b0add6881a6a77fa;hpb=2e0c360abd74b94991aa9a271cadc72aae1471c2;p=ffmpeg diff --git a/libavutil/audioconvert.c b/libavutil/audioconvert.c index aa652a66b10..e17f52ee594 100644 --- a/libavutil/audioconvert.c +++ b/libavutil/audioconvert.c @@ -26,6 +26,7 @@ #include "avstring.h" #include "avutil.h" #include "audioconvert.h" +#include "bprint.h" static const char * const channel_names[] = { [0] = "FL", /* front left */ @@ -80,19 +81,16 @@ static const struct { { "4.1", 5, AV_CH_LAYOUT_4POINT1 }, { "5.1", 6, AV_CH_LAYOUT_5POINT1_BACK }, { "5.1(side)", 6, AV_CH_LAYOUT_5POINT1 }, -// { "5.1+downmix", 8, AV_CH_LAYOUT_5POINT1|AV_CH_LAYOUT_STEREO_DOWNMIX, }, { "6.0", 6, AV_CH_LAYOUT_6POINT0 }, { "6.0(front)", 6, AV_CH_LAYOUT_6POINT0_FRONT }, { "hexagonal", 6, AV_CH_LAYOUT_HEXAGONAL }, { "6.1", 7, AV_CH_LAYOUT_6POINT1 }, { "6.1", 7, AV_CH_LAYOUT_6POINT1_BACK }, { "6.1(front)", 7, AV_CH_LAYOUT_6POINT1_FRONT }, -// { "6.1+downmix", 9, AV_CH_LAYOUT_6POINT1|AV_CH_LAYOUT_STEREO_DOWNMIX, }, { "7.0", 7, AV_CH_LAYOUT_7POINT0 }, { "7.0(front)", 7, AV_CH_LAYOUT_7POINT0_FRONT }, { "7.1", 8, AV_CH_LAYOUT_7POINT1 }, { "7.1(wide)", 8, AV_CH_LAYOUT_7POINT1_WIDE }, -// { "7.1+downmix", 10, AV_CH_LAYOUT_7POINT1|AV_CH_LAYOUT_STEREO_DOWNMIX, }, { "octagonal", 8, AV_CH_LAYOUT_OCTAGONAL }, { "downmix", 2, AV_CH_LAYOUT_STEREO_DOWNMIX, }, }; @@ -139,8 +137,8 @@ uint64_t av_get_channel_layout(const char *name) return layout; } -void av_get_channel_layout_string(char *buf, int buf_size, - int nb_channels, uint64_t channel_layout) +void av_bprint_channel_layout(struct AVBPrint *bp, + int nb_channels, uint64_t channel_layout) { int i; @@ -150,36 +148,41 @@ void av_get_channel_layout_string(char *buf, int buf_size, for (i = 0; i < FF_ARRAY_ELEMS(channel_layout_map); i++) if (nb_channels == channel_layout_map[i].nb_channels && channel_layout == channel_layout_map[i].layout) { - av_strlcpy(buf, channel_layout_map[i].name, buf_size); + av_bprintf(bp, "%s", channel_layout_map[i].name); return; } - snprintf(buf, buf_size, "%d channels", nb_channels); + av_bprintf(bp, "%d channels", nb_channels); if (channel_layout) { int i, ch; - av_strlcat(buf, " (", buf_size); + av_bprintf(bp, " ("); for (i = 0, ch = 0; i < 64; i++) { if ((channel_layout & (UINT64_C(1) << i))) { const char *name = get_channel_name(i); if (name) { if (ch > 0) - av_strlcat(buf, "+", buf_size); - av_strlcat(buf, name, buf_size); + av_bprintf(bp, "+"); + av_bprintf(bp, "%s", name); } ch++; } } - av_strlcat(buf, ")", buf_size); + av_bprintf(bp, ")"); } } +void av_get_channel_layout_string(char *buf, int buf_size, + int nb_channels, uint64_t channel_layout) +{ + AVBPrint bp; + + av_bprint_init_for_buffer(&bp, buf, buf_size); + av_bprint_channel_layout(&bp, nb_channels, channel_layout); +} + int av_get_channel_layout_nb_channels(uint64_t channel_layout) { - int count; - uint64_t x = channel_layout; - for (count = 0; x; count++) - x &= x-1; // unset lowest set bit - return count; + return av_popcount64(channel_layout); } int64_t av_get_default_channel_layout(int nb_channels) { @@ -189,3 +192,38 @@ int64_t av_get_default_channel_layout(int nb_channels) { return channel_layout_map[i].layout; return 0; } + +int av_get_channel_layout_channel_index(uint64_t channel_layout, + uint64_t channel) +{ + if (!(channel_layout & channel) || + av_get_channel_layout_nb_channels(channel) != 1) + return AVERROR(EINVAL); + channel_layout &= channel - 1; + return av_get_channel_layout_nb_channels(channel_layout); +} + +const char *av_get_channel_name(uint64_t channel) +{ + int i; + if (av_get_channel_layout_nb_channels(channel) != 1) + return NULL; + for (i = 0; i < 64; i++) + if ((1ULL<