00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "libavutil/common.h"
00022 #include "libavutil/dict.h"
00023
00024 #include "libavutil/log.h"
00025 #include "libavutil/mem.h"
00026 #include "libavutil/opt.h"
00027
00028 #include "avresample.h"
00029 #include "audio_data.h"
00030 #include "internal.h"
00031
00032 int avresample_open(AVAudioResampleContext *avr)
00033 {
00034 int ret;
00035
00036
00037 avr->in_channels = av_get_channel_layout_nb_channels(avr->in_channel_layout);
00038 if (avr->in_channels <= 0 || avr->in_channels > AVRESAMPLE_MAX_CHANNELS) {
00039 av_log(avr, AV_LOG_ERROR, "Invalid input channel layout: %"PRIu64"\n",
00040 avr->in_channel_layout);
00041 return AVERROR(EINVAL);
00042 }
00043 avr->out_channels = av_get_channel_layout_nb_channels(avr->out_channel_layout);
00044 if (avr->out_channels <= 0 || avr->out_channels > AVRESAMPLE_MAX_CHANNELS) {
00045 av_log(avr, AV_LOG_ERROR, "Invalid output channel layout: %"PRIu64"\n",
00046 avr->out_channel_layout);
00047 return AVERROR(EINVAL);
00048 }
00049 avr->resample_channels = FFMIN(avr->in_channels, avr->out_channels);
00050 avr->downmix_needed = avr->in_channels > avr->out_channels;
00051 avr->upmix_needed = avr->out_channels > avr->in_channels ||
00052 (!avr->downmix_needed && (avr->am->matrix ||
00053 avr->in_channel_layout != avr->out_channel_layout));
00054 avr->mixing_needed = avr->downmix_needed || avr->upmix_needed;
00055
00056
00057 avr->resample_needed = avr->in_sample_rate != avr->out_sample_rate ||
00058 avr->force_resampling;
00059
00060
00061 if (avr->internal_sample_fmt == AV_SAMPLE_FMT_NONE &&
00062 (avr->mixing_needed || avr->resample_needed)) {
00063 enum AVSampleFormat in_fmt = av_get_planar_sample_fmt(avr->in_sample_fmt);
00064 enum AVSampleFormat out_fmt = av_get_planar_sample_fmt(avr->out_sample_fmt);
00065 int max_bps = FFMAX(av_get_bytes_per_sample(in_fmt),
00066 av_get_bytes_per_sample(out_fmt));
00067 if (max_bps <= 2) {
00068 avr->internal_sample_fmt = AV_SAMPLE_FMT_S16P;
00069 } else if (avr->mixing_needed) {
00070 avr->internal_sample_fmt = AV_SAMPLE_FMT_FLTP;
00071 } else {
00072 if (max_bps <= 4) {
00073 if (in_fmt == AV_SAMPLE_FMT_S32P ||
00074 out_fmt == AV_SAMPLE_FMT_S32P) {
00075 if (in_fmt == AV_SAMPLE_FMT_FLTP ||
00076 out_fmt == AV_SAMPLE_FMT_FLTP) {
00077
00078 avr->internal_sample_fmt = AV_SAMPLE_FMT_DBLP;
00079 } else {
00080
00081 avr->internal_sample_fmt = AV_SAMPLE_FMT_S32P;
00082 }
00083 } else {
00084
00085 avr->internal_sample_fmt = AV_SAMPLE_FMT_FLTP;
00086 }
00087 } else {
00088
00089 avr->internal_sample_fmt = AV_SAMPLE_FMT_DBLP;
00090 }
00091 }
00092 av_log(avr, AV_LOG_DEBUG, "Using %s as internal sample format\n",
00093 av_get_sample_fmt_name(avr->internal_sample_fmt));
00094 }
00095
00096
00097 if (avr->in_channels == 1)
00098 avr->in_sample_fmt = av_get_planar_sample_fmt(avr->in_sample_fmt);
00099 if (avr->out_channels == 1)
00100 avr->out_sample_fmt = av_get_planar_sample_fmt(avr->out_sample_fmt);
00101 avr->in_convert_needed = (avr->resample_needed || avr->mixing_needed) &&
00102 avr->in_sample_fmt != avr->internal_sample_fmt;
00103 if (avr->resample_needed || avr->mixing_needed)
00104 avr->out_convert_needed = avr->internal_sample_fmt != avr->out_sample_fmt;
00105 else
00106 avr->out_convert_needed = avr->in_sample_fmt != avr->out_sample_fmt;
00107
00108
00109 if (avr->mixing_needed || avr->in_convert_needed) {
00110 avr->in_buffer = ff_audio_data_alloc(FFMAX(avr->in_channels, avr->out_channels),
00111 0, avr->internal_sample_fmt,
00112 "in_buffer");
00113 if (!avr->in_buffer) {
00114 ret = AVERROR(EINVAL);
00115 goto error;
00116 }
00117 }
00118 if (avr->resample_needed) {
00119 avr->resample_out_buffer = ff_audio_data_alloc(avr->out_channels,
00120 0, avr->internal_sample_fmt,
00121 "resample_out_buffer");
00122 if (!avr->resample_out_buffer) {
00123 ret = AVERROR(EINVAL);
00124 goto error;
00125 }
00126 }
00127 if (avr->out_convert_needed) {
00128 avr->out_buffer = ff_audio_data_alloc(avr->out_channels, 0,
00129 avr->out_sample_fmt, "out_buffer");
00130 if (!avr->out_buffer) {
00131 ret = AVERROR(EINVAL);
00132 goto error;
00133 }
00134 }
00135 avr->out_fifo = av_audio_fifo_alloc(avr->out_sample_fmt, avr->out_channels,
00136 1024);
00137 if (!avr->out_fifo) {
00138 ret = AVERROR(ENOMEM);
00139 goto error;
00140 }
00141
00142
00143 if (avr->in_convert_needed) {
00144 avr->ac_in = ff_audio_convert_alloc(avr, avr->internal_sample_fmt,
00145 avr->in_sample_fmt, avr->in_channels);
00146 if (!avr->ac_in) {
00147 ret = AVERROR(ENOMEM);
00148 goto error;
00149 }
00150 }
00151 if (avr->out_convert_needed) {
00152 enum AVSampleFormat src_fmt;
00153 if (avr->in_convert_needed)
00154 src_fmt = avr->internal_sample_fmt;
00155 else
00156 src_fmt = avr->in_sample_fmt;
00157 avr->ac_out = ff_audio_convert_alloc(avr, avr->out_sample_fmt, src_fmt,
00158 avr->out_channels);
00159 if (!avr->ac_out) {
00160 ret = AVERROR(ENOMEM);
00161 goto error;
00162 }
00163 }
00164 if (avr->resample_needed) {
00165 avr->resample = ff_audio_resample_init(avr);
00166 if (!avr->resample) {
00167 ret = AVERROR(ENOMEM);
00168 goto error;
00169 }
00170 }
00171 if (avr->mixing_needed) {
00172 ret = ff_audio_mix_init(avr);
00173 if (ret < 0)
00174 goto error;
00175 }
00176
00177 return 0;
00178
00179 error:
00180 avresample_close(avr);
00181 return ret;
00182 }
00183
00184 void avresample_close(AVAudioResampleContext *avr)
00185 {
00186 ff_audio_data_free(&avr->in_buffer);
00187 ff_audio_data_free(&avr->resample_out_buffer);
00188 ff_audio_data_free(&avr->out_buffer);
00189 av_audio_fifo_free(avr->out_fifo);
00190 avr->out_fifo = NULL;
00191 av_freep(&avr->ac_in);
00192 av_freep(&avr->ac_out);
00193 ff_audio_resample_free(&avr->resample);
00194 ff_audio_mix_close(avr->am);
00195 return;
00196 }
00197
00198 void avresample_free(AVAudioResampleContext **avr)
00199 {
00200 if (!*avr)
00201 return;
00202 avresample_close(*avr);
00203 av_freep(&(*avr)->am);
00204 av_opt_free(*avr);
00205 av_freep(avr);
00206 }
00207
00208 static int handle_buffered_output(AVAudioResampleContext *avr,
00209 AudioData *output, AudioData *converted)
00210 {
00211 int ret;
00212
00213 if (!output || av_audio_fifo_size(avr->out_fifo) > 0 ||
00214 (converted && output->allocated_samples < converted->nb_samples)) {
00215 if (converted) {
00216
00217
00218
00219 av_dlog(avr, "[FIFO] add %s to out_fifo\n", converted->name);
00220 ret = ff_audio_data_add_to_fifo(avr->out_fifo, converted, 0,
00221 converted->nb_samples);
00222 if (ret < 0)
00223 return ret;
00224 }
00225
00226
00227
00228 if (output && output->allocated_samples > 0) {
00229 av_dlog(avr, "[FIFO] read from out_fifo to output\n");
00230 av_dlog(avr, "[end conversion]\n");
00231 return ff_audio_data_read_from_fifo(avr->out_fifo, output,
00232 output->allocated_samples);
00233 }
00234 } else if (converted) {
00235
00236
00237 av_dlog(avr, "[copy] %s to output\n", converted->name);
00238 output->nb_samples = 0;
00239 ret = ff_audio_data_copy(output, converted);
00240 if (ret < 0)
00241 return ret;
00242 av_dlog(avr, "[end conversion]\n");
00243 return output->nb_samples;
00244 }
00245 av_dlog(avr, "[end conversion]\n");
00246 return 0;
00247 }
00248
00249 int attribute_align_arg avresample_convert(AVAudioResampleContext *avr,
00250 void **output, int out_plane_size,
00251 int out_samples, void **input,
00252 int in_plane_size, int in_samples)
00253 {
00254 AudioData input_buffer;
00255 AudioData output_buffer;
00256 AudioData *current_buffer;
00257 int ret;
00258
00259
00260 if (avr->in_buffer) {
00261 avr->in_buffer->nb_samples = 0;
00262 ff_audio_data_set_channels(avr->in_buffer,
00263 avr->in_buffer->allocated_channels);
00264 }
00265 if (avr->resample_out_buffer) {
00266 avr->resample_out_buffer->nb_samples = 0;
00267 ff_audio_data_set_channels(avr->resample_out_buffer,
00268 avr->resample_out_buffer->allocated_channels);
00269 }
00270 if (avr->out_buffer) {
00271 avr->out_buffer->nb_samples = 0;
00272 ff_audio_data_set_channels(avr->out_buffer,
00273 avr->out_buffer->allocated_channels);
00274 }
00275
00276 av_dlog(avr, "[start conversion]\n");
00277
00278
00279 if (output) {
00280 ret = ff_audio_data_init(&output_buffer, output, out_plane_size,
00281 avr->out_channels, out_samples,
00282 avr->out_sample_fmt, 0, "output");
00283 if (ret < 0)
00284 return ret;
00285 output_buffer.nb_samples = 0;
00286 }
00287
00288 if (input) {
00289
00290 ret = ff_audio_data_init(&input_buffer, input, in_plane_size,
00291 avr->in_channels, in_samples,
00292 avr->in_sample_fmt, 1, "input");
00293 if (ret < 0)
00294 return ret;
00295 current_buffer = &input_buffer;
00296
00297 if (avr->upmix_needed && !avr->in_convert_needed && !avr->resample_needed &&
00298 !avr->out_convert_needed && output && out_samples >= in_samples) {
00299
00300
00301 av_dlog(avr, "[copy] %s to output\n", current_buffer->name);
00302 ret = ff_audio_data_copy(&output_buffer, current_buffer);
00303 if (ret < 0)
00304 return ret;
00305 current_buffer = &output_buffer;
00306 } else if (avr->mixing_needed || avr->in_convert_needed) {
00307
00308
00309 if (avr->in_convert_needed) {
00310 ret = ff_audio_data_realloc(avr->in_buffer,
00311 current_buffer->nb_samples);
00312 if (ret < 0)
00313 return ret;
00314 av_dlog(avr, "[convert] %s to in_buffer\n", current_buffer->name);
00315 ret = ff_audio_convert(avr->ac_in, avr->in_buffer, current_buffer,
00316 current_buffer->nb_samples);
00317 if (ret < 0)
00318 return ret;
00319 } else {
00320 av_dlog(avr, "[copy] %s to in_buffer\n", current_buffer->name);
00321 ret = ff_audio_data_copy(avr->in_buffer, current_buffer);
00322 if (ret < 0)
00323 return ret;
00324 }
00325 ff_audio_data_set_channels(avr->in_buffer, avr->in_channels);
00326 if (avr->downmix_needed) {
00327 av_dlog(avr, "[downmix] in_buffer\n");
00328 ret = ff_audio_mix(avr->am, avr->in_buffer);
00329 if (ret < 0)
00330 return ret;
00331 }
00332 current_buffer = avr->in_buffer;
00333 }
00334 } else {
00335
00336 if (!avr->resample_needed)
00337 return handle_buffered_output(avr, output ? &output_buffer : NULL,
00338 NULL);
00339 current_buffer = NULL;
00340 }
00341
00342 if (avr->resample_needed) {
00343 AudioData *resample_out;
00344 int consumed = 0;
00345
00346 if (!avr->out_convert_needed && output && out_samples > 0)
00347 resample_out = &output_buffer;
00348 else
00349 resample_out = avr->resample_out_buffer;
00350 av_dlog(avr, "[resample] %s to %s\n", current_buffer->name,
00351 resample_out->name);
00352 ret = ff_audio_resample(avr->resample, resample_out,
00353 current_buffer, &consumed);
00354 if (ret < 0)
00355 return ret;
00356
00357
00358 if (resample_out->nb_samples == 0) {
00359 av_dlog(avr, "[end conversion]\n");
00360 return 0;
00361 }
00362
00363 current_buffer = resample_out;
00364 }
00365
00366 if (avr->upmix_needed) {
00367 av_dlog(avr, "[upmix] %s\n", current_buffer->name);
00368 ret = ff_audio_mix(avr->am, current_buffer);
00369 if (ret < 0)
00370 return ret;
00371 }
00372
00373
00374 if (current_buffer == &output_buffer) {
00375 av_dlog(avr, "[end conversion]\n");
00376 return current_buffer->nb_samples;
00377 }
00378
00379 if (avr->out_convert_needed) {
00380 if (output && out_samples >= current_buffer->nb_samples) {
00381
00382 av_dlog(avr, "[convert] %s to output\n", current_buffer->name);
00383 ret = ff_audio_convert(avr->ac_out, &output_buffer, current_buffer,
00384 current_buffer->nb_samples);
00385 if (ret < 0)
00386 return ret;
00387
00388 av_dlog(avr, "[end conversion]\n");
00389 return output_buffer.nb_samples;
00390 } else {
00391 ret = ff_audio_data_realloc(avr->out_buffer,
00392 current_buffer->nb_samples);
00393 if (ret < 0)
00394 return ret;
00395 av_dlog(avr, "[convert] %s to out_buffer\n", current_buffer->name);
00396 ret = ff_audio_convert(avr->ac_out, avr->out_buffer,
00397 current_buffer, current_buffer->nb_samples);
00398 if (ret < 0)
00399 return ret;
00400 current_buffer = avr->out_buffer;
00401 }
00402 }
00403
00404 return handle_buffered_output(avr, output ? &output_buffer : NULL,
00405 current_buffer);
00406 }
00407
00408 int avresample_available(AVAudioResampleContext *avr)
00409 {
00410 return av_audio_fifo_size(avr->out_fifo);
00411 }
00412
00413 int avresample_read(AVAudioResampleContext *avr, void **output, int nb_samples)
00414 {
00415 if (!output)
00416 return av_audio_fifo_drain(avr->out_fifo, nb_samples);
00417 return av_audio_fifo_read(avr->out_fifo, output, nb_samples);
00418 }
00419
00420 unsigned avresample_version(void)
00421 {
00422 return LIBAVRESAMPLE_VERSION_INT;
00423 }
00424
00425 const char *avresample_license(void)
00426 {
00427 #define LICENSE_PREFIX "libavresample license: "
00428 return LICENSE_PREFIX FFMPEG_LICENSE + sizeof(LICENSE_PREFIX) - 1;
00429 }
00430
00431 const char *avresample_configuration(void)
00432 {
00433 return FFMPEG_CONFIGURATION;
00434 }