00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00026 #include "avstring.h"
00027 #include "avutil.h"
00028 #include "audioconvert.h"
00029
00030 static const char * const channel_names[] = {
00031 [0] = "FL",
00032 [1] = "FR",
00033 [2] = "FC",
00034 [3] = "LFE",
00035 [4] = "BL",
00036 [5] = "BR",
00037 [6] = "FLC",
00038 [7] = "FRC",
00039 [8] = "BC",
00040 [9] = "SL",
00041 [10] = "SR",
00042 [11] = "TC",
00043 [12] = "TFL",
00044 [13] = "TFC",
00045 [14] = "TFR",
00046 [15] = "TBL",
00047 [16] = "TBC",
00048 [17] = "TBR",
00049 [29] = "DL",
00050 [30] = "DR",
00051 };
00052
00053 static const char *get_channel_name(int channel_id)
00054 {
00055 if (channel_id < 0 || channel_id >= FF_ARRAY_ELEMS(channel_names))
00056 return NULL;
00057 return channel_names[channel_id];
00058 }
00059
00060 static const struct {
00061 const char *name;
00062 int nb_channels;
00063 uint64_t layout;
00064 } channel_layout_map[] = {
00065 { "mono", 1, AV_CH_LAYOUT_MONO },
00066 { "stereo", 2, AV_CH_LAYOUT_STEREO },
00067 { "4.0", 4, AV_CH_LAYOUT_4POINT0 },
00068 { "quad", 4, AV_CH_LAYOUT_QUAD },
00069 { "5.0", 5, AV_CH_LAYOUT_5POINT0 },
00070 { "5.0", 5, AV_CH_LAYOUT_5POINT0_BACK },
00071 { "5.1", 6, AV_CH_LAYOUT_5POINT1 },
00072 { "5.1", 6, AV_CH_LAYOUT_5POINT1_BACK },
00073 { "5.1+downmix", 8, AV_CH_LAYOUT_5POINT1|AV_CH_LAYOUT_STEREO_DOWNMIX, },
00074 { "7.1", 8, AV_CH_LAYOUT_7POINT1 },
00075 { "7.1(wide)", 8, AV_CH_LAYOUT_7POINT1_WIDE },
00076 { "7.1+downmix", 10, AV_CH_LAYOUT_7POINT1|AV_CH_LAYOUT_STEREO_DOWNMIX, },
00077 { 0 }
00078 };
00079
00080 uint64_t av_get_channel_layout(const char *name)
00081 {
00082 int i = 0;
00083 do {
00084 if (!strcmp(channel_layout_map[i].name, name))
00085 return channel_layout_map[i].layout;
00086 i++;
00087 } while (channel_layout_map[i].name);
00088
00089 return 0;
00090 }
00091
00092 void av_get_channel_layout_string(char *buf, int buf_size,
00093 int nb_channels, uint64_t channel_layout)
00094 {
00095 int i;
00096
00097 if (nb_channels <= 0)
00098 nb_channels = av_get_channel_layout_nb_channels(channel_layout);
00099
00100 for (i = 0; channel_layout_map[i].name; i++)
00101 if (nb_channels == channel_layout_map[i].nb_channels &&
00102 channel_layout == channel_layout_map[i].layout) {
00103 av_strlcpy(buf, channel_layout_map[i].name, buf_size);
00104 return;
00105 }
00106
00107 snprintf(buf, buf_size, "%d channels", nb_channels);
00108 if (channel_layout) {
00109 int i, ch;
00110 av_strlcat(buf, " (", buf_size);
00111 for (i = 0, ch = 0; i < 64; i++) {
00112 if ((channel_layout & (UINT64_C(1) << i))) {
00113 const char *name = get_channel_name(i);
00114 if (name) {
00115 if (ch > 0)
00116 av_strlcat(buf, "|", buf_size);
00117 av_strlcat(buf, name, buf_size);
00118 }
00119 ch++;
00120 }
00121 }
00122 av_strlcat(buf, ")", buf_size);
00123 }
00124 }
00125
00126 int av_get_channel_layout_nb_channels(uint64_t channel_layout)
00127 {
00128 int count;
00129 uint64_t x = channel_layout;
00130 for (count = 0; x; count++)
00131 x &= x-1;
00132 return count;
00133 }