Add audio channel layout API to libavcodec.
Originally committed as revision 15762 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
parent
3a57547e33
commit
0d72e7d0ae
@ -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;
|
||||
|
@ -54,6 +54,26 @@ const char *avcodec_get_sample_fmt_name(int sample_fmt);
|
||||
*/
|
||||
enum SampleFormat avcodec_get_sample_fmt(const char* name);
|
||||
|
||||
/**
|
||||
* @return NULL on error
|
||||
*/
|
||||
const char *avcodec_get_channel_name(int channel_id);
|
||||
|
||||
/**
|
||||
* Return description of channel layout
|
||||
*/
|
||||
void avcodec_get_channel_layout_string(char *buf, int buf_size, int nb_channels, int64_t channel_layout);
|
||||
|
||||
/**
|
||||
* Guess the channel layout
|
||||
* @param nb_channels
|
||||
* @param codec_id Codec identifier, or CODEC_ID_NONE if unknown
|
||||
* @param fmt_name Format name, or NULL if unknown
|
||||
* @return Channel layout mask
|
||||
*/
|
||||
int64_t avcodec_guess_channel_layout(int nb_channels, enum CodecID codec_id, const char *fmt_name);
|
||||
|
||||
|
||||
struct AVAudioConvert;
|
||||
typedef struct AVAudioConvert AVAudioConvert;
|
||||
|
||||
|
@ -30,7 +30,7 @@
|
||||
#include "libavutil/avutil.h"
|
||||
|
||||
#define LIBAVCODEC_VERSION_MAJOR 52
|
||||
#define LIBAVCODEC_VERSION_MINOR 1
|
||||
#define LIBAVCODEC_VERSION_MINOR 2
|
||||
#define LIBAVCODEC_VERSION_MICRO 0
|
||||
|
||||
#define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
|
||||
@ -346,6 +346,41 @@ enum SampleFormat {
|
||||
SAMPLE_FMT_NB ///< Number of sample formats. DO NOT USE if dynamically linking to libavcodec
|
||||
};
|
||||
|
||||
/* Audio channel masks */
|
||||
#define CHANNEL_FRONT_LEFT 0x00000001
|
||||
#define CHANNEL_FRONT_RIGHT 0x00000002
|
||||
#define CHANNEL_FRONT_CENTER 0x00000004
|
||||
#define CHANNEL_LOW_FREQUENCY 0x00000008
|
||||
#define CHANNEL_BACK_LEFT 0x00000010
|
||||
#define CHANNEL_BACK_RIGHT 0x00000020
|
||||
#define CHANNEL_FRONT_LEFT_OF_CENTER 0x00000040
|
||||
#define CHANNEL_FRONT_RIGHT_OF_CENTER 0x00000080
|
||||
#define CHANNEL_BACK_CENTER 0x00000100
|
||||
#define CHANNEL_SIDE_LEFT 0x00000200
|
||||
#define CHANNEL_SIDE_RIGHT 0x00000400
|
||||
#define CHANNEL_TOP_CENTER 0x00000800
|
||||
#define CHANNEL_TOP_FRONT_LEFT 0x00001000
|
||||
#define CHANNEL_TOP_FRONT_CENTER 0x00002000
|
||||
#define CHANNEL_TOP_FRONT_RIGHT 0x00004000
|
||||
#define CHANNEL_TOP_BACK_LEFT 0x00008000
|
||||
#define CHANNEL_TOP_BACK_CENTER 0x00010000
|
||||
#define CHANNEL_TOP_BACK_RIGHT 0x00020000
|
||||
#define CHANNEL_STEREO_LEFT 0x20000000 ///< Stereo downmix.
|
||||
#define CHANNEL_STEREO_RIGHT 0x40000000 ///< See CHANNEL_STEREO_LEFT.
|
||||
|
||||
/* Audio channel convenience macros */
|
||||
#define CHANNEL_LAYOUT_MONO (CHANNEL_FRONT_CENTER)
|
||||
#define CHANNEL_LAYOUT_STEREO (CHANNEL_FRONT_LEFT|CHANNEL_FRONT_RIGHT)
|
||||
#define CHANNEL_LAYOUT_SURROUND (CHANNEL_LAYOUT_STEREO|CHANNEL_FRONT_CENTER)
|
||||
#define CHANNEL_LAYOUT_QUAD (CHANNEL_LAYOUT_STEREO|CHANNEL_BACK_LEFT|CHANNEL_BACK_RIGHT)
|
||||
#define CHANNEL_LAYOUT_5POINT0 (CHANNEL_LAYOUT_SURROUND|CHANNEL_SIDE_LEFT|CHANNEL_SIDE_RIGHT)
|
||||
#define CHANNEL_LAYOUT_5POINT1 (CHANNEL_LAYOUT_5POINT0|CHANNEL_LOW_FREQUENCY)
|
||||
#define CHANNEL_LAYOUT_7POINT1 (CHANNEL_LAYOUT_5POINT1|CHANNEL_BACK_LEFT|CHANNEL_BACK_RIGHT)
|
||||
#define CHANNEL_LAYOUT_7POINT1_WIDE (CHANNEL_LAYOUT_SURROUND|CHANNEL_LOW_FREQUENCY|\
|
||||
CHANNEL_BACK_LEFT|CHANNEL_BACK_RIGHT|\
|
||||
CHANNEL_FRONT_LEFT_OF_CENTER|CHANNEL_FRONT_RIGHT_OF_CENTER)
|
||||
#define CHANNEL_LAYOUT_STEREO_DOWNMIX (CHANNEL_STEREO_LEFT|CHANNEL_STEREO_RIGHT)
|
||||
|
||||
/* in bytes */
|
||||
#define AVCODEC_MAX_AUDIO_FRAME_SIZE 192000 // 1 second of 48khz 32bit audio
|
||||
|
||||
@ -2198,12 +2233,15 @@ typedef struct AVCodecContext {
|
||||
*/
|
||||
int64_t timecode_frame_start;
|
||||
|
||||
#if LIBAVCODEC_VERSION_MAJOR < 53
|
||||
/**
|
||||
* Decoder should decode to this many channels if it can (0 for default)
|
||||
* - encoding: unused
|
||||
* - decoding: Set by user.
|
||||
* @deprecated Deprecated in favor of request_channel_layout.
|
||||
*/
|
||||
int request_channels;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Percentage of dynamic range compression to be applied by the decoder.
|
||||
@ -2228,6 +2266,20 @@ typedef struct AVCodecContext {
|
||||
* - decoding: set by libavcodec.
|
||||
*/
|
||||
int bits_per_raw_sample;
|
||||
|
||||
/**
|
||||
* Audio channel layout.
|
||||
* - encoding: set by user.
|
||||
* - decoding: set by libavcodec.
|
||||
*/
|
||||
int64_t channel_layout;
|
||||
|
||||
/**
|
||||
* Request decoder to use this channel layout if it can (0 for default)
|
||||
* - encoding: unused
|
||||
* - decoding: Set by user.
|
||||
*/
|
||||
int64_t request_channel_layout;
|
||||
} AVCodecContext;
|
||||
|
||||
/**
|
||||
@ -2269,6 +2321,7 @@ typedef struct AVCodec {
|
||||
const char *long_name;
|
||||
const int *supported_samplerates; ///< array of supported audio samplerates, or NULL if unknown, array is terminated by 0
|
||||
const enum SampleFormat *sample_fmts; ///< array of supported sample formats, or NULL if unknown, array is terminated by -1
|
||||
const int64_t *channel_layouts; ///< array of support channel layouts, or NULL if unknown. array is terminated by 0
|
||||
} AVCodec;
|
||||
|
||||
/**
|
||||
|
@ -740,6 +740,8 @@ static const AVOption options[]={
|
||||
{"drc_scale", "percentage of dynamic range compression to apply", OFFSET(drc_scale), FF_OPT_TYPE_FLOAT, 1.0, 0.0, 1.0, A|D},
|
||||
{"reservoir", "use bit reservoir", 0, FF_OPT_TYPE_CONST, CODEC_FLAG2_BIT_RESERVOIR, INT_MIN, INT_MAX, A|E, "flags2"},
|
||||
{"bits_per_raw_sample", NULL, OFFSET(bits_per_raw_sample), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX},
|
||||
{"channel_layout", NULL, OFFSET(channel_layout), FF_OPT_TYPE_INT64, DEFAULT, 0, INT64_MAX, A|E|D, "channel_layout"},
|
||||
{"request_channel_layout", NULL, OFFSET(request_channel_layout), FF_OPT_TYPE_INT64, DEFAULT, 0, INT64_MAX, A|D, "request_channel_layout"},
|
||||
{NULL},
|
||||
};
|
||||
|
||||
@ -1051,7 +1053,6 @@ void avcodec_string(char *buf, int buf_size, AVCodecContext *enc, int encode)
|
||||
const char *codec_name;
|
||||
AVCodec *p;
|
||||
char buf1[32];
|
||||
char channels_str[100];
|
||||
int bitrate;
|
||||
AVRational display_aspect_ratio;
|
||||
|
||||
@ -1131,26 +1132,12 @@ void avcodec_string(char *buf, int buf_size, AVCodecContext *enc, int encode)
|
||||
snprintf(buf, buf_size,
|
||||
"Audio: %s",
|
||||
codec_name);
|
||||
switch (enc->channels) {
|
||||
case 1:
|
||||
strcpy(channels_str, "mono");
|
||||
break;
|
||||
case 2:
|
||||
strcpy(channels_str, "stereo");
|
||||
break;
|
||||
case 6:
|
||||
strcpy(channels_str, "5:1");
|
||||
break;
|
||||
default:
|
||||
snprintf(channels_str, sizeof(channels_str), "%d channels", enc->channels);
|
||||
break;
|
||||
}
|
||||
if (enc->sample_rate) {
|
||||
snprintf(buf + strlen(buf), buf_size - strlen(buf),
|
||||
", %d Hz, %s",
|
||||
enc->sample_rate,
|
||||
channels_str);
|
||||
", %d Hz", enc->sample_rate);
|
||||
}
|
||||
av_strlcat(buf, ", ", buf_size);
|
||||
avcodec_get_channel_layout_string(buf + strlen(buf), buf_size - strlen(buf), enc->channels, enc->channel_layout);
|
||||
if (enc->sample_fmt != SAMPLE_FMT_NONE) {
|
||||
snprintf(buf + strlen(buf), buf_size - strlen(buf),
|
||||
", %s", avcodec_get_sample_fmt_name(enc->sample_fmt));
|
||||
|
Loading…
Reference in New Issue
Block a user