00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00028 #include "libavutil/avstring.h"
00029 #include "libavutil/libm.h"
00030 #include "libavcore/samplefmt.h"
00031 #include "avcodec.h"
00032 #include "audioconvert.h"
00033
00034 #if FF_API_OLD_SAMPLE_FMT
00035 const char *avcodec_get_sample_fmt_name(int sample_fmt)
00036 {
00037 return av_get_sample_fmt_name(sample_fmt);
00038 }
00039
00040 enum AVSampleFormat avcodec_get_sample_fmt(const char* name)
00041 {
00042 return av_get_sample_fmt(name);
00043 }
00044
00045 void avcodec_sample_fmt_string (char *buf, int buf_size, int sample_fmt)
00046 {
00047 av_get_sample_fmt_string(buf, buf_size, sample_fmt);
00048 }
00049 #endif
00050
00051 static const char* const channel_names[]={
00052 "FL", "FR", "FC", "LFE", "BL", "BR", "FLC", "FRC",
00053 "BC", "SL", "SR", "TC", "TFL", "TFC", "TFR", "TBL",
00054 "TBC", "TBR",
00055 [29] = "DL",
00056 [30] = "DR",
00057 };
00058
00059 static const char *get_channel_name(int channel_id)
00060 {
00061 if (channel_id<0 || channel_id>=FF_ARRAY_ELEMS(channel_names))
00062 return NULL;
00063 return channel_names[channel_id];
00064 }
00065
00066 int64_t avcodec_guess_channel_layout(int nb_channels, enum CodecID codec_id, const char *fmt_name)
00067 {
00068 switch(nb_channels) {
00069 case 1: return CH_LAYOUT_MONO;
00070 case 2: return CH_LAYOUT_STEREO;
00071 case 3: return CH_LAYOUT_SURROUND;
00072 case 4: return CH_LAYOUT_QUAD;
00073 case 5: return CH_LAYOUT_5POINT0;
00074 case 6: return CH_LAYOUT_5POINT1;
00075 case 8: return CH_LAYOUT_7POINT1;
00076 default: return 0;
00077 }
00078 }
00079
00080 static const struct {
00081 const char *name;
00082 int nb_channels;
00083 int64_t layout;
00084 } channel_layout_map[] = {
00085 { "mono", 1, CH_LAYOUT_MONO },
00086 { "stereo", 2, CH_LAYOUT_STEREO },
00087 { "4.0", 4, CH_LAYOUT_4POINT0 },
00088 { "quad", 4, CH_LAYOUT_QUAD },
00089 { "5.0", 5, CH_LAYOUT_5POINT0 },
00090 { "5.0", 5, CH_LAYOUT_5POINT0_BACK },
00091 { "5.1", 6, CH_LAYOUT_5POINT1 },
00092 { "5.1", 6, CH_LAYOUT_5POINT1_BACK },
00093 { "5.1+downmix", 8, CH_LAYOUT_5POINT1|CH_LAYOUT_STEREO_DOWNMIX, },
00094 { "7.1", 8, CH_LAYOUT_7POINT1 },
00095 { "7.1(wide)", 8, CH_LAYOUT_7POINT1_WIDE },
00096 { "7.1+downmix", 10, CH_LAYOUT_7POINT1|CH_LAYOUT_STEREO_DOWNMIX, },
00097 { 0 }
00098 };
00099
00100 int64_t avcodec_get_channel_layout(const char *name)
00101 {
00102 int i = 0;
00103 do {
00104 if (!strcmp(channel_layout_map[i].name, name))
00105 return channel_layout_map[i].layout;
00106 i++;
00107 } while (channel_layout_map[i].name);
00108
00109 return 0;
00110 }
00111
00112 void avcodec_get_channel_layout_string(char *buf, int buf_size, int nb_channels, int64_t channel_layout)
00113 {
00114 int i;
00115
00116 for (i=0; channel_layout_map[i].name; i++)
00117 if (nb_channels == channel_layout_map[i].nb_channels &&
00118 channel_layout == channel_layout_map[i].layout) {
00119 av_strlcpy(buf, channel_layout_map[i].name, buf_size);
00120 return;
00121 }
00122
00123 snprintf(buf, buf_size, "%d channels", nb_channels);
00124 if (channel_layout) {
00125 int i,ch;
00126 av_strlcat(buf, " (", buf_size);
00127 for(i=0,ch=0; i<64; i++) {
00128 if ((channel_layout & (1L<<i))) {
00129 const char *name = get_channel_name(i);
00130 if (name) {
00131 if (ch>0) av_strlcat(buf, "|", buf_size);
00132 av_strlcat(buf, name, buf_size);
00133 }
00134 ch++;
00135 }
00136 }
00137 av_strlcat(buf, ")", buf_size);
00138 }
00139 }
00140
00141 int avcodec_channel_layout_num_channels(int64_t channel_layout)
00142 {
00143 int count;
00144 uint64_t x = channel_layout;
00145 for (count = 0; x; count++)
00146 x &= x-1;
00147 return count;
00148 }
00149
00150 struct AVAudioConvert {
00151 int in_channels, out_channels;
00152 int fmt_pair;
00153 };
00154
00155 AVAudioConvert *av_audio_convert_alloc(enum AVSampleFormat out_fmt, int out_channels,
00156 enum AVSampleFormat in_fmt, int in_channels,
00157 const float *matrix, int flags)
00158 {
00159 AVAudioConvert *ctx;
00160 if (in_channels!=out_channels)
00161 return NULL;
00162 ctx = av_malloc(sizeof(AVAudioConvert));
00163 if (!ctx)
00164 return NULL;
00165 ctx->in_channels = in_channels;
00166 ctx->out_channels = out_channels;
00167 ctx->fmt_pair = out_fmt + AV_SAMPLE_FMT_NB*in_fmt;
00168 return ctx;
00169 }
00170
00171 void av_audio_convert_free(AVAudioConvert *ctx)
00172 {
00173 av_free(ctx);
00174 }
00175
00176 int av_audio_convert(AVAudioConvert *ctx,
00177 void * const out[6], const int out_stride[6],
00178 const void * const in[6], const int in_stride[6], int len)
00179 {
00180 int ch;
00181
00182
00183
00184 for(ch=0; ch<ctx->out_channels; ch++){
00185 const int is= in_stride[ch];
00186 const int os= out_stride[ch];
00187 const uint8_t *pi= in[ch];
00188 uint8_t *po= out[ch];
00189 uint8_t *end= po + os*len;
00190 if(!out[ch])
00191 continue;
00192
00193 #define CONV(ofmt, otype, ifmt, expr)\
00194 if(ctx->fmt_pair == ofmt + AV_SAMPLE_FMT_NB*ifmt){\
00195 do{\
00196 *(otype*)po = expr; pi += is; po += os;\
00197 }while(po < end);\
00198 }
00199
00200
00201
00202
00203 CONV(AV_SAMPLE_FMT_U8 , uint8_t, AV_SAMPLE_FMT_U8 , *(const uint8_t*)pi)
00204 else CONV(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_U8 , (*(const uint8_t*)pi - 0x80)<<8)
00205 else CONV(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_U8 , (*(const uint8_t*)pi - 0x80)<<24)
00206 else CONV(AV_SAMPLE_FMT_FLT, float , AV_SAMPLE_FMT_U8 , (*(const uint8_t*)pi - 0x80)*(1.0 / (1<<7)))
00207 else CONV(AV_SAMPLE_FMT_DBL, double , AV_SAMPLE_FMT_U8 , (*(const uint8_t*)pi - 0x80)*(1.0 / (1<<7)))
00208 else CONV(AV_SAMPLE_FMT_U8 , uint8_t, AV_SAMPLE_FMT_S16, (*(const int16_t*)pi>>8) + 0x80)
00209 else CONV(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_S16, *(const int16_t*)pi)
00210 else CONV(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_S16, *(const int16_t*)pi<<16)
00211 else CONV(AV_SAMPLE_FMT_FLT, float , AV_SAMPLE_FMT_S16, *(const int16_t*)pi*(1.0 / (1<<15)))
00212 else CONV(AV_SAMPLE_FMT_DBL, double , AV_SAMPLE_FMT_S16, *(const int16_t*)pi*(1.0 / (1<<15)))
00213 else CONV(AV_SAMPLE_FMT_U8 , uint8_t, AV_SAMPLE_FMT_S32, (*(const int32_t*)pi>>24) + 0x80)
00214 else CONV(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_S32, *(const int32_t*)pi>>16)
00215 else CONV(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_S32, *(const int32_t*)pi)
00216 else CONV(AV_SAMPLE_FMT_FLT, float , AV_SAMPLE_FMT_S32, *(const int32_t*)pi*(1.0 / (1<<31)))
00217 else CONV(AV_SAMPLE_FMT_DBL, double , AV_SAMPLE_FMT_S32, *(const int32_t*)pi*(1.0 / (1<<31)))
00218 else CONV(AV_SAMPLE_FMT_U8 , uint8_t, AV_SAMPLE_FMT_FLT, av_clip_uint8( lrintf(*(const float*)pi * (1<<7)) + 0x80))
00219 else CONV(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_FLT, av_clip_int16( lrintf(*(const float*)pi * (1<<15))))
00220 else CONV(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_FLT, av_clipl_int32(llrintf(*(const float*)pi * (1U<<31))))
00221 else CONV(AV_SAMPLE_FMT_FLT, float , AV_SAMPLE_FMT_FLT, *(const float*)pi)
00222 else CONV(AV_SAMPLE_FMT_DBL, double , AV_SAMPLE_FMT_FLT, *(const float*)pi)
00223 else CONV(AV_SAMPLE_FMT_U8 , uint8_t, AV_SAMPLE_FMT_DBL, av_clip_uint8( lrint(*(const double*)pi * (1<<7)) + 0x80))
00224 else CONV(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_DBL, av_clip_int16( lrint(*(const double*)pi * (1<<15))))
00225 else CONV(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_DBL, av_clipl_int32(llrint(*(const double*)pi * (1U<<31))))
00226 else CONV(AV_SAMPLE_FMT_FLT, float , AV_SAMPLE_FMT_DBL, *(const double*)pi)
00227 else CONV(AV_SAMPLE_FMT_DBL, double , AV_SAMPLE_FMT_DBL, *(const double*)pi)
00228 else return -1;
00229 }
00230 return 0;
00231 }