Browse code

Add audio channel layout API to libavcodec.

Originally committed as revision 15762 to svn://svn.ffmpeg.org/ffmpeg/trunk

Peter Ross authored on 2008/11/01 14:03:42
Showing 4 changed files
... ...
@@ -27,6 +27,7 @@
27 27
 
28 28
 #include "avcodec.h"
29 29
 #include "audioconvert.h"
30
+#include <libavutil/avstring.h>
30 31
 
31 32
 typedef struct SampleFmtInfo {
32 33
     const char *name;
... ...
@@ -70,6 +71,85 @@ void avcodec_sample_fmt_string (char *buf, int buf_size, int sample_fmt)
70 70
     }
71 71
 }
72 72
 
73
+static const char* const channel_names[]={
74
+    "FL", "FR", "FC", "LFE", "BL",  "BR",  "FLC", "FRC",
75
+    "BC", "SL", "SR", "TC",  "TFL", "TFC", "TFR", "TBL",
76
+    "TBC", "TBR",
77
+    [29] = "DL",
78
+    [30] = "DR",
79
+};
80
+
81
+const char *get_channel_name(int channel_id)
82
+{
83
+    if (channel_id<0 || channel_id>=FF_ARRAY_ELEMS(channel_names))
84
+        return NULL;
85
+    return channel_names[channel_id];
86
+}
87
+
88
+int64_t avcodec_guess_channel_layout(int nb_channels, enum CodecID codec_id, const char *fmt_name)
89
+{
90
+    switch(nb_channels) {
91
+    case 1: return CHANNEL_LAYOUT_MONO;
92
+    case 2: return CHANNEL_LAYOUT_STEREO;
93
+    case 3: return CHANNEL_LAYOUT_SURROUND;
94
+    case 4: return CHANNEL_LAYOUT_QUAD;
95
+    case 5: return CHANNEL_LAYOUT_5POINT0;
96
+    case 6: return CHANNEL_LAYOUT_5POINT1;
97
+    case 8: return CHANNEL_LAYOUT_7POINT1;
98
+    default: return 0;
99
+    }
100
+}
101
+
102
+static const struct {
103
+    const char *name;
104
+    int         nb_channels;
105
+    int64_t     layout;
106
+} const channel_layout_map[] = {
107
+    { "mono",        1,  CHANNEL_LAYOUT_MONO },
108
+    { "stereo",      2,  CHANNEL_LAYOUT_STEREO },
109
+    { "surround",    3,  CHANNEL_LAYOUT_SURROUND },
110
+    { "quad",        4,  CHANNEL_LAYOUT_QUAD },
111
+    { "5.0",         5,  CHANNEL_LAYOUT_5POINT0 },
112
+    { "5.1",         6,  CHANNEL_LAYOUT_5POINT1 },
113
+    { "5.1+downmix", 8,  CHANNEL_LAYOUT_5POINT1|CHANNEL_LAYOUT_STEREO_DOWNMIX, },
114
+    { "7.1",         8,  CHANNEL_LAYOUT_7POINT1 },
115
+    { "7.1(wide)",   8,  CHANNEL_LAYOUT_7POINT1_WIDE },
116
+    { "7.1+downmix", 10, CHANNEL_LAYOUT_7POINT1|CHANNEL_LAYOUT_STEREO_DOWNMIX, },
117
+    { 0 }
118
+};
119
+
120
+void avcodec_get_channel_layout_string(char *buf, int buf_size, int nb_channels, int64_t channel_layout)
121
+{
122
+    int i;
123
+
124
+    if (channel_layout==0)
125
+        channel_layout = avcodec_guess_channel_layout(nb_channels, CODEC_ID_NONE, NULL);
126
+
127
+    for (i=0; channel_layout_map[i].name; i++)
128
+        if (nb_channels    == channel_layout_map[i].nb_channels &&
129
+            channel_layout == channel_layout_map[i].layout) {
130
+            snprintf(buf, buf_size, channel_layout_map[i].name);
131
+            return;
132
+        }
133
+
134
+    snprintf(buf, buf_size, "%d channels", nb_channels);
135
+    if (channel_layout) {
136
+        int i,ch;
137
+        av_strlcat(buf, " (", buf_size);
138
+        for(i=0,ch=0; i<64; i++) {
139
+            if ((channel_layout & (1L<<i))) {
140
+                const char *name = get_channel_name(i);
141
+                if (name) {
142
+                    if (ch>0) av_strlcat(buf, "|", buf_size);
143
+                    av_strlcat(buf, name, buf_size);
144
+                }
145
+                ch++;
146
+            }
147
+        }
148
+        av_strlcat(buf, ")", buf_size);
149
+    }
150
+}
151
+
73 152
 struct AVAudioConvert {
74 153
     int in_channels, out_channels;
75 154
     int fmt_pair;
... ...
@@ -54,6 +54,26 @@ const char *avcodec_get_sample_fmt_name(int sample_fmt);
54 54
  */
55 55
 enum SampleFormat avcodec_get_sample_fmt(const char* name);
56 56
 
57
+/**
58
+ * @return NULL on error
59
+ */
60
+const char *avcodec_get_channel_name(int channel_id);
61
+
62
+/**
63
+ * Return description of channel layout
64
+ */
65
+void avcodec_get_channel_layout_string(char *buf, int buf_size, int nb_channels, int64_t channel_layout);
66
+
67
+/**
68
+ * Guess the channel layout
69
+ * @param nb_channels
70
+ * @param codec_id Codec identifier, or CODEC_ID_NONE if unknown
71
+ * @param fmt_name Format name, or NULL if unknown
72
+ * @return Channel layout mask
73
+ */
74
+int64_t avcodec_guess_channel_layout(int nb_channels, enum CodecID codec_id, const char *fmt_name);
75
+
76
+
57 77
 struct AVAudioConvert;
58 78
 typedef struct AVAudioConvert AVAudioConvert;
59 79
 
... ...
@@ -30,7 +30,7 @@
30 30
 #include "libavutil/avutil.h"
31 31
 
32 32
 #define LIBAVCODEC_VERSION_MAJOR 52
33
-#define LIBAVCODEC_VERSION_MINOR  1
33
+#define LIBAVCODEC_VERSION_MINOR  2
34 34
 #define LIBAVCODEC_VERSION_MICRO  0
35 35
 
36 36
 #define LIBAVCODEC_VERSION_INT  AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
... ...
@@ -346,6 +346,41 @@ enum SampleFormat {
346 346
     SAMPLE_FMT_NB               ///< Number of sample formats. DO NOT USE if dynamically linking to libavcodec
347 347
 };
348 348
 
349
+/* Audio channel masks */
350
+#define CHANNEL_FRONT_LEFT             0x00000001
351
+#define CHANNEL_FRONT_RIGHT            0x00000002
352
+#define CHANNEL_FRONT_CENTER           0x00000004
353
+#define CHANNEL_LOW_FREQUENCY          0x00000008
354
+#define CHANNEL_BACK_LEFT              0x00000010
355
+#define CHANNEL_BACK_RIGHT             0x00000020
356
+#define CHANNEL_FRONT_LEFT_OF_CENTER   0x00000040
357
+#define CHANNEL_FRONT_RIGHT_OF_CENTER  0x00000080
358
+#define CHANNEL_BACK_CENTER            0x00000100
359
+#define CHANNEL_SIDE_LEFT              0x00000200
360
+#define CHANNEL_SIDE_RIGHT             0x00000400
361
+#define CHANNEL_TOP_CENTER             0x00000800
362
+#define CHANNEL_TOP_FRONT_LEFT         0x00001000
363
+#define CHANNEL_TOP_FRONT_CENTER       0x00002000
364
+#define CHANNEL_TOP_FRONT_RIGHT        0x00004000
365
+#define CHANNEL_TOP_BACK_LEFT          0x00008000
366
+#define CHANNEL_TOP_BACK_CENTER        0x00010000
367
+#define CHANNEL_TOP_BACK_RIGHT         0x00020000
368
+#define CHANNEL_STEREO_LEFT            0x20000000  ///< Stereo downmix.
369
+#define CHANNEL_STEREO_RIGHT           0x40000000  ///< See CHANNEL_STEREO_LEFT.
370
+
371
+/* Audio channel convenience macros */
372
+#define CHANNEL_LAYOUT_MONO              (CHANNEL_FRONT_CENTER)
373
+#define CHANNEL_LAYOUT_STEREO            (CHANNEL_FRONT_LEFT|CHANNEL_FRONT_RIGHT)
374
+#define CHANNEL_LAYOUT_SURROUND          (CHANNEL_LAYOUT_STEREO|CHANNEL_FRONT_CENTER)
375
+#define CHANNEL_LAYOUT_QUAD              (CHANNEL_LAYOUT_STEREO|CHANNEL_BACK_LEFT|CHANNEL_BACK_RIGHT)
376
+#define CHANNEL_LAYOUT_5POINT0           (CHANNEL_LAYOUT_SURROUND|CHANNEL_SIDE_LEFT|CHANNEL_SIDE_RIGHT)
377
+#define CHANNEL_LAYOUT_5POINT1           (CHANNEL_LAYOUT_5POINT0|CHANNEL_LOW_FREQUENCY)
378
+#define CHANNEL_LAYOUT_7POINT1           (CHANNEL_LAYOUT_5POINT1|CHANNEL_BACK_LEFT|CHANNEL_BACK_RIGHT)
379
+#define CHANNEL_LAYOUT_7POINT1_WIDE      (CHANNEL_LAYOUT_SURROUND|CHANNEL_LOW_FREQUENCY|\
380
+                                          CHANNEL_BACK_LEFT|CHANNEL_BACK_RIGHT|\
381
+                                          CHANNEL_FRONT_LEFT_OF_CENTER|CHANNEL_FRONT_RIGHT_OF_CENTER)
382
+#define CHANNEL_LAYOUT_STEREO_DOWNMIX    (CHANNEL_STEREO_LEFT|CHANNEL_STEREO_RIGHT)
383
+
349 384
 /* in bytes */
350 385
 #define AVCODEC_MAX_AUDIO_FRAME_SIZE 192000 // 1 second of 48khz 32bit audio
351 386
 
... ...
@@ -2198,12 +2233,15 @@ typedef struct AVCodecContext {
2198 2198
      */
2199 2199
     int64_t timecode_frame_start;
2200 2200
 
2201
+#if LIBAVCODEC_VERSION_MAJOR < 53
2201 2202
     /**
2202 2203
      * Decoder should decode to this many channels if it can (0 for default)
2203 2204
      * - encoding: unused
2204 2205
      * - decoding: Set by user.
2206
+     * @deprecated Deprecated in favor of request_channel_layout.
2205 2207
      */
2206 2208
     int request_channels;
2209
+#endif
2207 2210
 
2208 2211
     /**
2209 2212
      * Percentage of dynamic range compression to be applied by the decoder.
... ...
@@ -2228,6 +2266,20 @@ typedef struct AVCodecContext {
2228 2228
      * - decoding: set by libavcodec.
2229 2229
      */
2230 2230
     int bits_per_raw_sample;
2231
+
2232
+    /**
2233
+     * Audio channel layout.
2234
+     * - encoding: set by user.
2235
+     * - decoding: set by libavcodec.
2236
+     */
2237
+    int64_t channel_layout;
2238
+
2239
+    /**
2240
+     * Request decoder to use this channel layout if it can (0 for default)
2241
+     * - encoding: unused
2242
+     * - decoding: Set by user.
2243
+     */
2244
+    int64_t request_channel_layout;
2231 2245
 } AVCodecContext;
2232 2246
 
2233 2247
 /**
... ...
@@ -2269,6 +2321,7 @@ typedef struct AVCodec {
2269 2269
     const char *long_name;
2270 2270
     const int *supported_samplerates;       ///< array of supported audio samplerates, or NULL if unknown, array is terminated by 0
2271 2271
     const enum SampleFormat *sample_fmts;   ///< array of supported sample formats, or NULL if unknown, array is terminated by -1
2272
+    const int64_t *channel_layouts;         ///< array of support channel layouts, or NULL if unknown. array is terminated by 0
2272 2273
 } AVCodec;
2273 2274
 
2274 2275
 /**
... ...
@@ -740,6 +740,8 @@ static const AVOption options[]={
740 740
 {"drc_scale", "percentage of dynamic range compression to apply", OFFSET(drc_scale), FF_OPT_TYPE_FLOAT, 1.0, 0.0, 1.0, A|D},
741 741
 {"reservoir", "use bit reservoir", 0, FF_OPT_TYPE_CONST, CODEC_FLAG2_BIT_RESERVOIR, INT_MIN, INT_MAX, A|E, "flags2"},
742 742
 {"bits_per_raw_sample", NULL, OFFSET(bits_per_raw_sample), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX},
743
+{"channel_layout", NULL, OFFSET(channel_layout), FF_OPT_TYPE_INT64, DEFAULT, 0, INT64_MAX, A|E|D, "channel_layout"},
744
+{"request_channel_layout", NULL, OFFSET(request_channel_layout), FF_OPT_TYPE_INT64, DEFAULT, 0, INT64_MAX, A|D, "request_channel_layout"},
743 745
 {NULL},
744 746
 };
745 747
 
... ...
@@ -1051,7 +1053,6 @@ void avcodec_string(char *buf, int buf_size, AVCodecContext *enc, int encode)
1051 1051
     const char *codec_name;
1052 1052
     AVCodec *p;
1053 1053
     char buf1[32];
1054
-    char channels_str[100];
1055 1054
     int bitrate;
1056 1055
     AVRational display_aspect_ratio;
1057 1056
 
... ...
@@ -1131,26 +1132,12 @@ void avcodec_string(char *buf, int buf_size, AVCodecContext *enc, int encode)
1131 1131
         snprintf(buf, buf_size,
1132 1132
                  "Audio: %s",
1133 1133
                  codec_name);
1134
-        switch (enc->channels) {
1135
-            case 1:
1136
-                strcpy(channels_str, "mono");
1137
-                break;
1138
-            case 2:
1139
-                strcpy(channels_str, "stereo");
1140
-                break;
1141
-            case 6:
1142
-                strcpy(channels_str, "5:1");
1143
-                break;
1144
-            default:
1145
-                snprintf(channels_str, sizeof(channels_str), "%d channels", enc->channels);
1146
-                break;
1147
-        }
1148 1134
         if (enc->sample_rate) {
1149 1135
             snprintf(buf + strlen(buf), buf_size - strlen(buf),
1150
-                     ", %d Hz, %s",
1151
-                     enc->sample_rate,
1152
-                     channels_str);
1136
+                     ", %d Hz", enc->sample_rate);
1153 1137
         }
1138
+        av_strlcat(buf, ", ", buf_size);
1139
+        avcodec_get_channel_layout_string(buf + strlen(buf), buf_size - strlen(buf), enc->channels, enc->channel_layout);
1154 1140
         if (enc->sample_fmt != SAMPLE_FMT_NONE) {
1155 1141
             snprintf(buf + strlen(buf), buf_size - strlen(buf),
1156 1142
                      ", %s", avcodec_get_sample_fmt_name(enc->sample_fmt));