Mercurial > libavcodec.hg
comparison resample.c @ 8806:cbeaa8c0fe4f libavcodec
extend resampling API, add S16 internal conversion
author | bcoudurier |
---|---|
date | Wed, 11 Feb 2009 22:57:10 +0000 |
parents | e9d9d946f213 |
children | 28b706b75b00 |
comparison
equal
deleted
inserted
replaced
8805:eda229beb608 | 8806:cbeaa8c0fe4f |
---|---|
23 * @file libavcodec/resample.c | 23 * @file libavcodec/resample.c |
24 * samplerate conversion for both audio and video | 24 * samplerate conversion for both audio and video |
25 */ | 25 */ |
26 | 26 |
27 #include "avcodec.h" | 27 #include "avcodec.h" |
28 #include "audioconvert.h" | |
29 #include "opt.h" | |
28 | 30 |
29 struct AVResampleContext; | 31 struct AVResampleContext; |
30 | 32 |
33 static const char *context_to_name(void *ptr) | |
34 { | |
35 return "audioresample"; | |
36 } | |
37 | |
38 static const AVOption options[] = {{NULL}}; | |
39 static const AVClass audioresample_context_class = { "ReSampleContext", context_to_name, options }; | |
40 | |
31 struct ReSampleContext { | 41 struct ReSampleContext { |
42 const AVClass *av_class; | |
32 struct AVResampleContext *resample_context; | 43 struct AVResampleContext *resample_context; |
33 short *temp[2]; | 44 short *temp[2]; |
34 int temp_len; | 45 int temp_len; |
35 float ratio; | 46 float ratio; |
36 /* channel convert */ | 47 /* channel convert */ |
37 int input_channels, output_channels, filter_channels; | 48 int input_channels, output_channels, filter_channels; |
49 AVAudioConvert *convert_ctx[2]; | |
50 enum SampleFormat sample_fmt[2]; ///< input and output sample format | |
51 unsigned sample_size[2]; ///< size of one sample in sample_fmt | |
52 short *buffer[2]; ///< buffers used for conversion to S16 | |
53 unsigned buffer_size[2]; ///< sizes of allocated buffers | |
38 }; | 54 }; |
39 | 55 |
40 /* n1: number of samples */ | 56 /* n1: number of samples */ |
41 static void stereo_to_mono(short *output, short *input, int n1) | 57 static void stereo_to_mono(short *output, short *input, int n1) |
42 { | 58 { |
124 *output++ = 0; /* right surroud */ | 140 *output++ = 0; /* right surroud */ |
125 *output++ = 0; /* low freq */ | 141 *output++ = 0; /* low freq */ |
126 } | 142 } |
127 } | 143 } |
128 | 144 |
129 ReSampleContext *audio_resample_init(int output_channels, int input_channels, | 145 ReSampleContext *av_audio_resample_init(int output_channels, int input_channels, |
130 int output_rate, int input_rate) | 146 int output_rate, int input_rate, |
147 enum SampleFormat sample_fmt_out, | |
148 enum SampleFormat sample_fmt_in, | |
149 int filter_length, int log2_phase_count, | |
150 int linear, double cutoff) | |
131 { | 151 { |
132 ReSampleContext *s; | 152 ReSampleContext *s; |
133 | 153 |
134 if ( input_channels > 2) | 154 if ( input_channels > 2) |
135 { | 155 { |
150 s->output_channels = output_channels; | 170 s->output_channels = output_channels; |
151 | 171 |
152 s->filter_channels = s->input_channels; | 172 s->filter_channels = s->input_channels; |
153 if (s->output_channels < s->filter_channels) | 173 if (s->output_channels < s->filter_channels) |
154 s->filter_channels = s->output_channels; | 174 s->filter_channels = s->output_channels; |
175 | |
176 s->sample_fmt [0] = sample_fmt_in; | |
177 s->sample_fmt [1] = sample_fmt_out; | |
178 s->sample_size[0] = av_get_bits_per_sample_format(s->sample_fmt[0])>>3; | |
179 s->sample_size[1] = av_get_bits_per_sample_format(s->sample_fmt[1])>>3; | |
180 | |
181 if (s->sample_fmt[0] != SAMPLE_FMT_S16) { | |
182 if (!(s->convert_ctx[0] = av_audio_convert_alloc(SAMPLE_FMT_S16, 1, | |
183 s->sample_fmt[0], 1, NULL, 0))) { | |
184 av_log(s, AV_LOG_ERROR, | |
185 "Cannot convert %s sample format to s16 sample format\n", | |
186 avcodec_get_sample_fmt_name(s->sample_fmt[0])); | |
187 av_free(s); | |
188 return NULL; | |
189 } | |
190 } | |
191 | |
192 if (s->sample_fmt[1] != SAMPLE_FMT_S16) { | |
193 if (!(s->convert_ctx[1] = av_audio_convert_alloc(s->sample_fmt[1], 1, | |
194 SAMPLE_FMT_S16, 1, NULL, 0))) { | |
195 av_log(s, AV_LOG_ERROR, | |
196 "Cannot convert s16 sample format to %s sample format\n", | |
197 avcodec_get_sample_fmt_name(s->sample_fmt[1])); | |
198 av_audio_convert_free(s->convert_ctx[0]); | |
199 av_free(s); | |
200 return NULL; | |
201 } | |
202 } | |
155 | 203 |
156 /* | 204 /* |
157 * AC-3 output is the only case where filter_channels could be greater than 2. | 205 * AC-3 output is the only case where filter_channels could be greater than 2. |
158 * input channels can't be greater than 2, so resample the 2 channels and then | 206 * input channels can't be greater than 2, so resample the 2 channels and then |
159 * expand to 6 channels after the resampling. | 207 * expand to 6 channels after the resampling. |
160 */ | 208 */ |
161 if(s->filter_channels>2) | 209 if(s->filter_channels>2) |
162 s->filter_channels = 2; | 210 s->filter_channels = 2; |
163 | 211 |
164 #define TAPS 16 | 212 #define TAPS 16 |
165 s->resample_context= av_resample_init(output_rate, input_rate, TAPS, 10, 0, 0.8); | 213 s->resample_context= av_resample_init(output_rate, input_rate, |
214 filter_length, log2_phase_count, linear, cutoff); | |
215 | |
216 s->av_class= &audioresample_context_class; | |
166 | 217 |
167 return s; | 218 return s; |
168 } | 219 } |
220 | |
221 #if LIBAVCODEC_VERSION_MAJOR < 53 | |
222 ReSampleContext *audio_resample_init(int output_channels, int input_channels, | |
223 int output_rate, int input_rate) | |
224 { | |
225 return av_audio_resample_init(output_channels, input_channels, | |
226 output_rate, input_rate, | |
227 SAMPLE_FMT_S16, SAMPLE_FMT_S16, | |
228 TAPS, 10, 0, 0.8); | |
229 } | |
230 #endif | |
169 | 231 |
170 /* resample audio. 'nb_samples' is the number of input samples */ | 232 /* resample audio. 'nb_samples' is the number of input samples */ |
171 /* XXX: optimize it ! */ | 233 /* XXX: optimize it ! */ |
172 int audio_resample(ReSampleContext *s, short *output, short *input, int nb_samples) | 234 int audio_resample(ReSampleContext *s, short *output, short *input, int nb_samples) |
173 { | 235 { |
174 int i, nb_samples1; | 236 int i, nb_samples1; |
175 short *bufin[2]; | 237 short *bufin[2]; |
176 short *bufout[2]; | 238 short *bufout[2]; |
177 short *buftmp2[2], *buftmp3[2]; | 239 short *buftmp2[2], *buftmp3[2]; |
240 short *output_bak = NULL; | |
178 int lenout; | 241 int lenout; |
179 | 242 |
180 if (s->input_channels == s->output_channels && s->ratio == 1.0 && 0) { | 243 if (s->input_channels == s->output_channels && s->ratio == 1.0 && 0) { |
181 /* nothing to do */ | 244 /* nothing to do */ |
182 memcpy(output, input, nb_samples * s->input_channels * sizeof(short)); | 245 memcpy(output, input, nb_samples * s->input_channels * sizeof(short)); |
183 return nb_samples; | 246 return nb_samples; |
247 } | |
248 | |
249 if (s->sample_fmt[0] != SAMPLE_FMT_S16) { | |
250 int istride[1] = { s->sample_size[0] }; | |
251 int ostride[1] = { 2 }; | |
252 const void *ibuf[1] = { input }; | |
253 void *obuf[1]; | |
254 unsigned input_size = nb_samples*s->input_channels*s->sample_size[0]; | |
255 | |
256 if (!s->buffer_size[0] || s->buffer_size[0] < input_size) { | |
257 av_free(s->buffer[0]); | |
258 s->buffer_size[0] = input_size; | |
259 s->buffer[0] = av_malloc(s->buffer_size[0]); | |
260 if (!s->buffer[0]) { | |
261 av_log(s, AV_LOG_ERROR, "Could not allocate buffer\n"); | |
262 return 0; | |
263 } | |
264 } | |
265 | |
266 obuf[0] = s->buffer[0]; | |
267 | |
268 if (av_audio_convert(s->convert_ctx[0], obuf, ostride, | |
269 ibuf, istride, nb_samples*s->input_channels) < 0) { | |
270 av_log(s, AV_LOG_ERROR, "Audio sample format conversion failed\n"); | |
271 return 0; | |
272 } | |
273 | |
274 input = s->buffer[0]; | |
275 } | |
276 | |
277 lenout= 4*nb_samples * s->ratio + 16; | |
278 | |
279 if (s->sample_fmt[1] != SAMPLE_FMT_S16) { | |
280 output_bak = output; | |
281 | |
282 if (!s->buffer_size[1] || s->buffer_size[1] < lenout) { | |
283 av_free(s->buffer[1]); | |
284 s->buffer_size[1] = lenout; | |
285 s->buffer[1] = av_malloc(s->buffer_size[1]); | |
286 if (!s->buffer[1]) { | |
287 av_log(s, AV_LOG_ERROR, "Could not allocate buffer\n"); | |
288 return 0; | |
289 } | |
290 } | |
291 | |
292 output = s->buffer[1]; | |
184 } | 293 } |
185 | 294 |
186 /* XXX: move those malloc to resample init code */ | 295 /* XXX: move those malloc to resample init code */ |
187 for(i=0; i<s->filter_channels; i++){ | 296 for(i=0; i<s->filter_channels; i++){ |
188 bufin[i]= av_malloc( (nb_samples + s->temp_len) * sizeof(short) ); | 297 bufin[i]= av_malloc( (nb_samples + s->temp_len) * sizeof(short) ); |
189 memcpy(bufin[i], s->temp[i], s->temp_len * sizeof(short)); | 298 memcpy(bufin[i], s->temp[i], s->temp_len * sizeof(short)); |
190 buftmp2[i] = bufin[i] + s->temp_len; | 299 buftmp2[i] = bufin[i] + s->temp_len; |
191 } | 300 } |
192 | 301 |
193 /* make some zoom to avoid round pb */ | 302 /* make some zoom to avoid round pb */ |
194 lenout= 4*nb_samples * s->ratio + 16; | |
195 bufout[0]= av_malloc( lenout * sizeof(short) ); | 303 bufout[0]= av_malloc( lenout * sizeof(short) ); |
196 bufout[1]= av_malloc( lenout * sizeof(short) ); | 304 bufout[1]= av_malloc( lenout * sizeof(short) ); |
197 | 305 |
198 if (s->input_channels == 2 && | 306 if (s->input_channels == 2 && |
199 s->output_channels == 1) { | 307 s->output_channels == 1) { |
231 stereo_mux(output, buftmp3[0], buftmp3[1], nb_samples1); | 339 stereo_mux(output, buftmp3[0], buftmp3[1], nb_samples1); |
232 } else if (s->output_channels == 6) { | 340 } else if (s->output_channels == 6) { |
233 ac3_5p1_mux(output, buftmp3[0], buftmp3[1], nb_samples1); | 341 ac3_5p1_mux(output, buftmp3[0], buftmp3[1], nb_samples1); |
234 } | 342 } |
235 | 343 |
344 if (s->sample_fmt[1] != SAMPLE_FMT_S16) { | |
345 int istride[1] = { 2 }; | |
346 int ostride[1] = { s->sample_size[1] }; | |
347 const void *ibuf[1] = { output }; | |
348 void *obuf[1] = { output_bak }; | |
349 | |
350 if (av_audio_convert(s->convert_ctx[1], obuf, ostride, | |
351 ibuf, istride, nb_samples1*s->output_channels) < 0) { | |
352 av_log(s, AV_LOG_ERROR, "Audio sample format convertion failed\n"); | |
353 return 0; | |
354 } | |
355 } | |
356 | |
236 for(i=0; i<s->filter_channels; i++) | 357 for(i=0; i<s->filter_channels; i++) |
237 av_free(bufin[i]); | 358 av_free(bufin[i]); |
238 | 359 |
239 av_free(bufout[0]); | 360 av_free(bufout[0]); |
240 av_free(bufout[1]); | 361 av_free(bufout[1]); |
244 void audio_resample_close(ReSampleContext *s) | 365 void audio_resample_close(ReSampleContext *s) |
245 { | 366 { |
246 av_resample_close(s->resample_context); | 367 av_resample_close(s->resample_context); |
247 av_freep(&s->temp[0]); | 368 av_freep(&s->temp[0]); |
248 av_freep(&s->temp[1]); | 369 av_freep(&s->temp[1]); |
370 av_freep(&s->buffer[0]); | |
371 av_freep(&s->buffer[1]); | |
372 av_audio_convert_free(s->convert_ctx[0]); | |
373 av_audio_convert_free(s->convert_ctx[1]); | |
249 av_free(s); | 374 av_free(s); |
250 } | 375 } |