ffmpeg / libavcodec / audioconvert.c @ 2912e87a
History | View | Annotate | Download (6.3 KB)
1 |
/*
|
---|---|
2 |
* audio conversion
|
3 |
* Copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at>
|
4 |
*
|
5 |
* This file is part of Libav.
|
6 |
*
|
7 |
* Libav is free software; you can redistribute it and/or
|
8 |
* modify it under the terms of the GNU Lesser General Public
|
9 |
* License as published by the Free Software Foundation; either
|
10 |
* version 2.1 of the License, or (at your option) any later version.
|
11 |
*
|
12 |
* Libav is distributed in the hope that it will be useful,
|
13 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
15 |
* Lesser General Public License for more details.
|
16 |
*
|
17 |
* You should have received a copy of the GNU Lesser General Public
|
18 |
* License along with Libav; if not, write to the Free Software
|
19 |
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
20 |
*/
|
21 |
|
22 |
/**
|
23 |
* @file
|
24 |
* audio conversion
|
25 |
* @author Michael Niedermayer <michaelni@gmx.at>
|
26 |
*/
|
27 |
|
28 |
#include "libavutil/avstring.h" |
29 |
#include "libavutil/libm.h" |
30 |
#include "libavutil/samplefmt.h" |
31 |
#include "avcodec.h" |
32 |
#include "audioconvert.h" |
33 |
|
34 |
#if FF_API_OLD_SAMPLE_FMT
|
35 |
const char *avcodec_get_sample_fmt_name(int sample_fmt) |
36 |
{ |
37 |
return av_get_sample_fmt_name(sample_fmt);
|
38 |
} |
39 |
|
40 |
enum AVSampleFormat avcodec_get_sample_fmt(const char* name) |
41 |
{ |
42 |
return av_get_sample_fmt(name);
|
43 |
} |
44 |
|
45 |
void avcodec_sample_fmt_string (char *buf, int buf_size, int sample_fmt) |
46 |
{ |
47 |
av_get_sample_fmt_string(buf, buf_size, sample_fmt); |
48 |
} |
49 |
#endif
|
50 |
|
51 |
int64_t avcodec_guess_channel_layout(int nb_channels, enum CodecID codec_id, const char *fmt_name) |
52 |
{ |
53 |
switch(nb_channels) {
|
54 |
case 1: return AV_CH_LAYOUT_MONO; |
55 |
case 2: return AV_CH_LAYOUT_STEREO; |
56 |
case 3: return AV_CH_LAYOUT_SURROUND; |
57 |
case 4: return AV_CH_LAYOUT_QUAD; |
58 |
case 5: return AV_CH_LAYOUT_5POINT0; |
59 |
case 6: return AV_CH_LAYOUT_5POINT1; |
60 |
case 8: return AV_CH_LAYOUT_7POINT1; |
61 |
default: return 0; |
62 |
} |
63 |
} |
64 |
|
65 |
#if FF_API_OLD_AUDIOCONVERT
|
66 |
int64_t avcodec_get_channel_layout(const char *name) |
67 |
{ |
68 |
return av_get_channel_layout(name);
|
69 |
} |
70 |
|
71 |
void avcodec_get_channel_layout_string(char *buf, int buf_size, int nb_channels, int64_t channel_layout) |
72 |
{ |
73 |
av_get_channel_layout_string(buf, buf_size, nb_channels, channel_layout); |
74 |
} |
75 |
|
76 |
int avcodec_channel_layout_num_channels(int64_t channel_layout)
|
77 |
{ |
78 |
return av_get_channel_layout_nb_channels(channel_layout);
|
79 |
} |
80 |
#endif
|
81 |
|
82 |
struct AVAudioConvert {
|
83 |
int in_channels, out_channels;
|
84 |
int fmt_pair;
|
85 |
}; |
86 |
|
87 |
AVAudioConvert *av_audio_convert_alloc(enum AVSampleFormat out_fmt, int out_channels, |
88 |
enum AVSampleFormat in_fmt, int in_channels, |
89 |
const float *matrix, int flags) |
90 |
{ |
91 |
AVAudioConvert *ctx; |
92 |
if (in_channels!=out_channels)
|
93 |
return NULL; /* FIXME: not supported */ |
94 |
ctx = av_malloc(sizeof(AVAudioConvert));
|
95 |
if (!ctx)
|
96 |
return NULL; |
97 |
ctx->in_channels = in_channels; |
98 |
ctx->out_channels = out_channels; |
99 |
ctx->fmt_pair = out_fmt + AV_SAMPLE_FMT_NB*in_fmt; |
100 |
return ctx;
|
101 |
} |
102 |
|
103 |
void av_audio_convert_free(AVAudioConvert *ctx)
|
104 |
{ |
105 |
av_free(ctx); |
106 |
} |
107 |
|
108 |
int av_audio_convert(AVAudioConvert *ctx,
|
109 |
void * const out[6], const int out_stride[6], |
110 |
const void * const in[6], const int in_stride[6], int len) |
111 |
{ |
112 |
int ch;
|
113 |
|
114 |
//FIXME optimize common cases
|
115 |
|
116 |
for(ch=0; ch<ctx->out_channels; ch++){ |
117 |
const int is= in_stride[ch]; |
118 |
const int os= out_stride[ch]; |
119 |
const uint8_t *pi= in[ch];
|
120 |
uint8_t *po= out[ch]; |
121 |
uint8_t *end= po + os*len; |
122 |
if(!out[ch])
|
123 |
continue;
|
124 |
|
125 |
#define CONV(ofmt, otype, ifmt, expr)\
|
126 |
if(ctx->fmt_pair == ofmt + AV_SAMPLE_FMT_NB*ifmt){\
|
127 |
do{\
|
128 |
*(otype*)po = expr; pi += is; po += os;\ |
129 |
}while(po < end);\
|
130 |
} |
131 |
|
132 |
//FIXME put things below under ifdefs so we do not waste space for cases no codec will need
|
133 |
//FIXME rounding ?
|
134 |
|
135 |
CONV(AV_SAMPLE_FMT_U8 , uint8_t, AV_SAMPLE_FMT_U8 , *(const uint8_t*)pi)
|
136 |
else CONV(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_U8 , (*(const uint8_t*)pi - 0x80)<<8) |
137 |
else CONV(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_U8 , (*(const uint8_t*)pi - 0x80)<<24) |
138 |
else CONV(AV_SAMPLE_FMT_FLT, float , AV_SAMPLE_FMT_U8 , (*(const uint8_t*)pi - 0x80)*(1.0 / (1<<7))) |
139 |
else CONV(AV_SAMPLE_FMT_DBL, double , AV_SAMPLE_FMT_U8 , (*(const uint8_t*)pi - 0x80)*(1.0 / (1<<7))) |
140 |
else CONV(AV_SAMPLE_FMT_U8 , uint8_t, AV_SAMPLE_FMT_S16, (*(const int16_t*)pi>>8) + 0x80) |
141 |
else CONV(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_S16, *(const int16_t*)pi) |
142 |
else CONV(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_S16, *(const int16_t*)pi<<16) |
143 |
else CONV(AV_SAMPLE_FMT_FLT, float , AV_SAMPLE_FMT_S16, *(const int16_t*)pi*(1.0 / (1<<15))) |
144 |
else CONV(AV_SAMPLE_FMT_DBL, double , AV_SAMPLE_FMT_S16, *(const int16_t*)pi*(1.0 / (1<<15))) |
145 |
else CONV(AV_SAMPLE_FMT_U8 , uint8_t, AV_SAMPLE_FMT_S32, (*(const int32_t*)pi>>24) + 0x80) |
146 |
else CONV(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_S32, *(const int32_t*)pi>>16) |
147 |
else CONV(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_S32, *(const int32_t*)pi) |
148 |
else CONV(AV_SAMPLE_FMT_FLT, float , AV_SAMPLE_FMT_S32, *(const int32_t*)pi*(1.0 / (1<<31))) |
149 |
else CONV(AV_SAMPLE_FMT_DBL, double , AV_SAMPLE_FMT_S32, *(const int32_t*)pi*(1.0 / (1<<31))) |
150 |
else CONV(AV_SAMPLE_FMT_U8 , uint8_t, AV_SAMPLE_FMT_FLT, av_clip_uint8( lrintf(*(const float*)pi * (1<<7)) + 0x80)) |
151 |
else CONV(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_FLT, av_clip_int16( lrintf(*(const float*)pi * (1<<15)))) |
152 |
else CONV(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_FLT, av_clipl_int32(llrintf(*(const float*)pi * (1U<<31)))) |
153 |
else CONV(AV_SAMPLE_FMT_FLT, float , AV_SAMPLE_FMT_FLT, *(const float*)pi) |
154 |
else CONV(AV_SAMPLE_FMT_DBL, double , AV_SAMPLE_FMT_FLT, *(const float*)pi) |
155 |
else CONV(AV_SAMPLE_FMT_U8 , uint8_t, AV_SAMPLE_FMT_DBL, av_clip_uint8( lrint(*(const double*)pi * (1<<7)) + 0x80)) |
156 |
else CONV(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_DBL, av_clip_int16( lrint(*(const double*)pi * (1<<15)))) |
157 |
else CONV(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_DBL, av_clipl_int32(llrint(*(const double*)pi * (1U<<31)))) |
158 |
else CONV(AV_SAMPLE_FMT_FLT, float , AV_SAMPLE_FMT_DBL, *(const double*)pi) |
159 |
else CONV(AV_SAMPLE_FMT_DBL, double , AV_SAMPLE_FMT_DBL, *(const double*)pi) |
160 |
else return -1; |
161 |
} |
162 |
return 0; |
163 |
} |