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