diff options
author | Peter Ross <pross@xvid.org> | 2008-11-01 05:03:42 +0000 |
---|---|---|
committer | Peter Ross <pross@xvid.org> | 2008-11-01 05:03:42 +0000 |
commit | 0d72e7d0aebb03db1010d3e3180b287f3d9fc581 (patch) | |
tree | 333b9abf0bfa252a75494295b525ce2d9e4bc7db /libavcodec/audioconvert.c | |
parent | 3a57547e33cb859e0989da2acd553ebdf84e48ef (diff) | |
download | ffmpeg-0d72e7d0aebb03db1010d3e3180b287f3d9fc581.tar.gz |
Add audio channel layout API to libavcodec.
Originally committed as revision 15762 to svn://svn.ffmpeg.org/ffmpeg/trunk
Diffstat (limited to 'libavcodec/audioconvert.c')
-rw-r--r-- | libavcodec/audioconvert.c | 80 |
1 files changed, 80 insertions, 0 deletions
diff --git a/libavcodec/audioconvert.c b/libavcodec/audioconvert.c index f6a22bf0a4..9f147a17ba 100644 --- a/libavcodec/audioconvert.c +++ b/libavcodec/audioconvert.c @@ -27,6 +27,7 @@ #include "avcodec.h" #include "audioconvert.h" +#include <libavutil/avstring.h> typedef struct SampleFmtInfo { const char *name; @@ -70,6 +71,85 @@ void avcodec_sample_fmt_string (char *buf, int buf_size, int sample_fmt) } } +static const char* const channel_names[]={ + "FL", "FR", "FC", "LFE", "BL", "BR", "FLC", "FRC", + "BC", "SL", "SR", "TC", "TFL", "TFC", "TFR", "TBL", + "TBC", "TBR", + [29] = "DL", + [30] = "DR", +}; + +const char *get_channel_name(int channel_id) +{ + if (channel_id<0 || channel_id>=FF_ARRAY_ELEMS(channel_names)) + return NULL; + return channel_names[channel_id]; +} + +int64_t avcodec_guess_channel_layout(int nb_channels, enum CodecID codec_id, const char *fmt_name) +{ + switch(nb_channels) { + case 1: return CHANNEL_LAYOUT_MONO; + case 2: return CHANNEL_LAYOUT_STEREO; + case 3: return CHANNEL_LAYOUT_SURROUND; + case 4: return CHANNEL_LAYOUT_QUAD; + case 5: return CHANNEL_LAYOUT_5POINT0; + case 6: return CHANNEL_LAYOUT_5POINT1; + case 8: return CHANNEL_LAYOUT_7POINT1; + default: return 0; + } +} + +static const struct { + const char *name; + int nb_channels; + int64_t layout; +} const channel_layout_map[] = { + { "mono", 1, CHANNEL_LAYOUT_MONO }, + { "stereo", 2, CHANNEL_LAYOUT_STEREO }, + { "surround", 3, CHANNEL_LAYOUT_SURROUND }, + { "quad", 4, CHANNEL_LAYOUT_QUAD }, + { "5.0", 5, CHANNEL_LAYOUT_5POINT0 }, + { "5.1", 6, CHANNEL_LAYOUT_5POINT1 }, + { "5.1+downmix", 8, CHANNEL_LAYOUT_5POINT1|CHANNEL_LAYOUT_STEREO_DOWNMIX, }, + { "7.1", 8, CHANNEL_LAYOUT_7POINT1 }, + { "7.1(wide)", 8, CHANNEL_LAYOUT_7POINT1_WIDE }, + { "7.1+downmix", 10, CHANNEL_LAYOUT_7POINT1|CHANNEL_LAYOUT_STEREO_DOWNMIX, }, + { 0 } +}; + +void avcodec_get_channel_layout_string(char *buf, int buf_size, int nb_channels, int64_t channel_layout) +{ + int i; + + if (channel_layout==0) + channel_layout = avcodec_guess_channel_layout(nb_channels, CODEC_ID_NONE, NULL); + + for (i=0; channel_layout_map[i].name; i++) + if (nb_channels == channel_layout_map[i].nb_channels && + channel_layout == channel_layout_map[i].layout) { + snprintf(buf, buf_size, channel_layout_map[i].name); + return; + } + + snprintf(buf, buf_size, "%d channels", nb_channels); + if (channel_layout) { + int i,ch; + av_strlcat(buf, " (", buf_size); + for(i=0,ch=0; i<64; i++) { + if ((channel_layout & (1L<<i))) { + const char *name = get_channel_name(i); + if (name) { + if (ch>0) av_strlcat(buf, "|", buf_size); + av_strlcat(buf, name, buf_size); + } + ch++; + } + } + av_strlcat(buf, ")", buf_size); + } +} + struct AVAudioConvert { int in_channels, out_channels; int fmt_pair; |