FFmpeg
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
utils.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2012 Justin Ruggles <justin.ruggles@gmail.com>
3  *
4  * This file is part of Libav.
5  *
6  * Libav is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * Libav is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with Libav; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20 
21 #include "libavutil/common.h"
22 #include "libavutil/dict.h"
23 // #include "libavutil/error.h"
24 #include "libavutil/log.h"
25 #include "libavutil/mem.h"
26 #include "libavutil/opt.h"
27 
28 #include "avresample.h"
29 #include "internal.h"
30 #include "audio_data.h"
31 #include "audio_convert.h"
32 #include "audio_mix.h"
33 #include "resample.h"
34 
36 {
37  int ret;
38 
39  /* set channel mixing parameters */
41  if (avr->in_channels <= 0 || avr->in_channels > AVRESAMPLE_MAX_CHANNELS) {
42  av_log(avr, AV_LOG_ERROR, "Invalid input channel layout: %"PRIu64"\n",
43  avr->in_channel_layout);
44  return AVERROR(EINVAL);
45  }
47  if (avr->out_channels <= 0 || avr->out_channels > AVRESAMPLE_MAX_CHANNELS) {
48  av_log(avr, AV_LOG_ERROR, "Invalid output channel layout: %"PRIu64"\n",
49  avr->out_channel_layout);
50  return AVERROR(EINVAL);
51  }
53  avr->downmix_needed = avr->in_channels > avr->out_channels;
54  avr->upmix_needed = avr->out_channels > avr->in_channels ||
55  (!avr->downmix_needed && (avr->mix_matrix ||
57  avr->mixing_needed = avr->downmix_needed || avr->upmix_needed;
58 
59  /* set resampling parameters */
60  avr->resample_needed = avr->in_sample_rate != avr->out_sample_rate ||
61  avr->force_resampling;
62 
63  /* select internal sample format if not specified by the user */
65  (avr->mixing_needed || avr->resample_needed)) {
68  int max_bps = FFMAX(av_get_bytes_per_sample(in_fmt),
69  av_get_bytes_per_sample(out_fmt));
70  if (max_bps <= 2) {
72  } else if (avr->mixing_needed) {
74  } else {
75  if (max_bps <= 4) {
76  if (in_fmt == AV_SAMPLE_FMT_S32P ||
77  out_fmt == AV_SAMPLE_FMT_S32P) {
78  if (in_fmt == AV_SAMPLE_FMT_FLTP ||
79  out_fmt == AV_SAMPLE_FMT_FLTP) {
80  /* if one is s32 and the other is flt, use dbl */
82  } else {
83  /* if one is s32 and the other is s32, s16, or u8, use s32 */
85  }
86  } else {
87  /* if one is flt and the other is flt, s16 or u8, use flt */
89  }
90  } else {
91  /* if either is dbl, use dbl */
93  }
94  }
95  av_log(avr, AV_LOG_DEBUG, "Using %s as internal sample format\n",
97  }
98 
99  /* treat all mono as planar for easier comparison */
100  if (avr->in_channels == 1)
102  if (avr->out_channels == 1)
104 
105  /* we may need to add an extra conversion in order to remap channels if
106  the output format is not planar */
107  if (avr->use_channel_map && !avr->mixing_needed && !avr->resample_needed &&
110  }
111 
112  /* set sample format conversion parameters */
113  if (avr->resample_needed || avr->mixing_needed)
115  else
116  avr->in_convert_needed = avr->use_channel_map &&
118 
119  if (avr->resample_needed || avr->mixing_needed || avr->in_convert_needed)
121  else
122  avr->out_convert_needed = avr->in_sample_fmt != avr->out_sample_fmt;
123 
124  avr->in_copy_needed = !avr->in_convert_needed && (avr->mixing_needed ||
125  (avr->use_channel_map && avr->resample_needed));
126 
127  if (avr->use_channel_map) {
128  if (avr->in_copy_needed) {
129  avr->remap_point = REMAP_IN_COPY;
130  av_dlog(avr, "remap channels during in_copy\n");
131  } else if (avr->in_convert_needed) {
133  av_dlog(avr, "remap channels during in_convert\n");
134  } else if (avr->out_convert_needed) {
136  av_dlog(avr, "remap channels during out_convert\n");
137  } else {
139  av_dlog(avr, "remap channels during out_copy\n");
140  }
141 
142 #ifdef DEBUG
143  {
144  int ch;
145  av_dlog(avr, "output map: ");
146  if (avr->ch_map_info.do_remap)
147  for (ch = 0; ch < avr->in_channels; ch++)
148  av_dlog(avr, " % 2d", avr->ch_map_info.channel_map[ch]);
149  else
150  av_dlog(avr, "n/a");
151  av_dlog(avr, "\n");
152  av_dlog(avr, "copy map: ");
153  if (avr->ch_map_info.do_copy)
154  for (ch = 0; ch < avr->in_channels; ch++)
155  av_dlog(avr, " % 2d", avr->ch_map_info.channel_copy[ch]);
156  else
157  av_dlog(avr, "n/a");
158  av_dlog(avr, "\n");
159  av_dlog(avr, "zero map: ");
160  if (avr->ch_map_info.do_zero)
161  for (ch = 0; ch < avr->in_channels; ch++)
162  av_dlog(avr, " % 2d", avr->ch_map_info.channel_zero[ch]);
163  else
164  av_dlog(avr, "n/a");
165  av_dlog(avr, "\n");
166  av_dlog(avr, "input map: ");
167  for (ch = 0; ch < avr->in_channels; ch++)
168  av_dlog(avr, " % 2d", avr->ch_map_info.input_map[ch]);
169  av_dlog(avr, "\n");
170  }
171 #endif
172  } else
173  avr->remap_point = REMAP_NONE;
174 
175  /* allocate buffers */
176  if (avr->in_copy_needed || avr->in_convert_needed) {
178  0, avr->internal_sample_fmt,
179  "in_buffer");
180  if (!avr->in_buffer) {
181  ret = AVERROR(EINVAL);
182  goto error;
183  }
184  }
185  if (avr->resample_needed) {
187  0, avr->internal_sample_fmt,
188  "resample_out_buffer");
189  if (!avr->resample_out_buffer) {
190  ret = AVERROR(EINVAL);
191  goto error;
192  }
193  }
194  if (avr->out_convert_needed) {
196  avr->out_sample_fmt, "out_buffer");
197  if (!avr->out_buffer) {
198  ret = AVERROR(EINVAL);
199  goto error;
200  }
201  }
203  1024);
204  if (!avr->out_fifo) {
205  ret = AVERROR(ENOMEM);
206  goto error;
207  }
208 
209  /* setup contexts */
210  if (avr->in_convert_needed) {
212  avr->in_sample_fmt, avr->in_channels,
213  avr->in_sample_rate,
214  avr->remap_point == REMAP_IN_CONVERT);
215  if (!avr->ac_in) {
216  ret = AVERROR(ENOMEM);
217  goto error;
218  }
219  }
220  if (avr->out_convert_needed) {
221  enum AVSampleFormat src_fmt;
222  if (avr->in_convert_needed)
223  src_fmt = avr->internal_sample_fmt;
224  else
225  src_fmt = avr->in_sample_fmt;
226  avr->ac_out = ff_audio_convert_alloc(avr, avr->out_sample_fmt, src_fmt,
227  avr->out_channels,
228  avr->out_sample_rate,
230  if (!avr->ac_out) {
231  ret = AVERROR(ENOMEM);
232  goto error;
233  }
234  }
235  if (avr->resample_needed) {
236  avr->resample = ff_audio_resample_init(avr);
237  if (!avr->resample) {
238  ret = AVERROR(ENOMEM);
239  goto error;
240  }
241  }
242  if (avr->mixing_needed) {
243  avr->am = ff_audio_mix_alloc(avr);
244  if (!avr->am) {
245  ret = AVERROR(ENOMEM);
246  goto error;
247  }
248  }
249 
250  return 0;
251 
252 error:
253  avresample_close(avr);
254  return ret;
255 }
256 
258 {
263  avr->out_fifo = NULL;
267  ff_audio_mix_free(&avr->am);
268  av_freep(&avr->mix_matrix);
269 
270  avr->use_channel_map = 0;
271 }
272 
274 {
275  if (!*avr)
276  return;
277  avresample_close(*avr);
278  av_opt_free(*avr);
279  av_freep(avr);
280 }
281 
283  AudioData *output, AudioData *converted)
284 {
285  int ret;
286 
287  if (!output || av_audio_fifo_size(avr->out_fifo) > 0 ||
288  (converted && output->allocated_samples < converted->nb_samples)) {
289  if (converted) {
290  /* if there are any samples in the output FIFO or if the
291  user-supplied output buffer is not large enough for all samples,
292  we add to the output FIFO */
293  av_dlog(avr, "[FIFO] add %s to out_fifo\n", converted->name);
294  ret = ff_audio_data_add_to_fifo(avr->out_fifo, converted, 0,
295  converted->nb_samples);
296  if (ret < 0)
297  return ret;
298  }
299 
300  /* if the user specified an output buffer, read samples from the output
301  FIFO to the user output */
302  if (output && output->allocated_samples > 0) {
303  av_dlog(avr, "[FIFO] read from out_fifo to output\n");
304  av_dlog(avr, "[end conversion]\n");
305  return ff_audio_data_read_from_fifo(avr->out_fifo, output,
306  output->allocated_samples);
307  }
308  } else if (converted) {
309  /* copy directly to output if it is large enough or there is not any
310  data in the output FIFO */
311  av_dlog(avr, "[copy] %s to output\n", converted->name);
312  output->nb_samples = 0;
313  ret = ff_audio_data_copy(output, converted,
314  avr->remap_point == REMAP_OUT_COPY ?
315  &avr->ch_map_info : NULL);
316  if (ret < 0)
317  return ret;
318  av_dlog(avr, "[end conversion]\n");
319  return output->nb_samples;
320  }
321  av_dlog(avr, "[end conversion]\n");
322  return 0;
323 }
324 
326  uint8_t **output, int out_plane_size,
327  int out_samples, uint8_t **input,
328  int in_plane_size, int in_samples)
329 {
330  AudioData input_buffer;
331  AudioData output_buffer;
332  AudioData *current_buffer;
333  int ret, direct_output;
334 
335  /* reset internal buffers */
336  if (avr->in_buffer) {
337  avr->in_buffer->nb_samples = 0;
340  }
341  if (avr->resample_out_buffer) {
345  }
346  if (avr->out_buffer) {
347  avr->out_buffer->nb_samples = 0;
350  }
351 
352  av_dlog(avr, "[start conversion]\n");
353 
354  /* initialize output_buffer with output data */
355  direct_output = output && av_audio_fifo_size(avr->out_fifo) == 0;
356  if (output) {
357  ret = ff_audio_data_init(&output_buffer, output, out_plane_size,
358  avr->out_channels, out_samples,
359  avr->out_sample_fmt, 0, "output");
360  if (ret < 0)
361  return ret;
362  output_buffer.nb_samples = 0;
363  }
364 
365  if (input) {
366  /* initialize input_buffer with input data */
367  ret = ff_audio_data_init(&input_buffer, input, in_plane_size,
368  avr->in_channels, in_samples,
369  avr->in_sample_fmt, 1, "input");
370  if (ret < 0)
371  return ret;
372  current_buffer = &input_buffer;
373 
374  if (avr->upmix_needed && !avr->in_convert_needed && !avr->resample_needed &&
375  !avr->out_convert_needed && direct_output && out_samples >= in_samples) {
376  /* in some rare cases we can copy input to output and upmix
377  directly in the output buffer */
378  av_dlog(avr, "[copy] %s to output\n", current_buffer->name);
379  ret = ff_audio_data_copy(&output_buffer, current_buffer,
380  avr->remap_point == REMAP_OUT_COPY ?
381  &avr->ch_map_info : NULL);
382  if (ret < 0)
383  return ret;
384  current_buffer = &output_buffer;
385  } else if (avr->remap_point == REMAP_OUT_COPY &&
386  (!direct_output || out_samples < in_samples)) {
387  /* if remapping channels during output copy, we may need to
388  * use an intermediate buffer in order to remap before adding
389  * samples to the output fifo */
390  av_dlog(avr, "[copy] %s to out_buffer\n", current_buffer->name);
391  ret = ff_audio_data_copy(avr->out_buffer, current_buffer,
392  &avr->ch_map_info);
393  if (ret < 0)
394  return ret;
395  current_buffer = avr->out_buffer;
396  } else if (avr->in_copy_needed || avr->in_convert_needed) {
397  /* if needed, copy or convert input to in_buffer, and downmix if
398  applicable */
399  if (avr->in_convert_needed) {
400  ret = ff_audio_data_realloc(avr->in_buffer,
401  current_buffer->nb_samples);
402  if (ret < 0)
403  return ret;
404  av_dlog(avr, "[convert] %s to in_buffer\n", current_buffer->name);
405  ret = ff_audio_convert(avr->ac_in, avr->in_buffer,
406  current_buffer);
407  if (ret < 0)
408  return ret;
409  } else {
410  av_dlog(avr, "[copy] %s to in_buffer\n", current_buffer->name);
411  ret = ff_audio_data_copy(avr->in_buffer, current_buffer,
412  avr->remap_point == REMAP_IN_COPY ?
413  &avr->ch_map_info : NULL);
414  if (ret < 0)
415  return ret;
416  }
418  if (avr->downmix_needed) {
419  av_dlog(avr, "[downmix] in_buffer\n");
420  ret = ff_audio_mix(avr->am, avr->in_buffer);
421  if (ret < 0)
422  return ret;
423  }
424  current_buffer = avr->in_buffer;
425  }
426  } else {
427  /* flush resampling buffer and/or output FIFO if input is NULL */
428  if (!avr->resample_needed)
429  return handle_buffered_output(avr, output ? &output_buffer : NULL,
430  NULL);
431  current_buffer = NULL;
432  }
433 
434  if (avr->resample_needed) {
435  AudioData *resample_out;
436 
437  if (!avr->out_convert_needed && direct_output && out_samples > 0)
438  resample_out = &output_buffer;
439  else
440  resample_out = avr->resample_out_buffer;
441  av_dlog(avr, "[resample] %s to %s\n", current_buffer->name,
442  resample_out->name);
443  ret = ff_audio_resample(avr->resample, resample_out,
444  current_buffer);
445  if (ret < 0)
446  return ret;
447 
448  /* if resampling did not produce any samples, just return 0 */
449  if (resample_out->nb_samples == 0) {
450  av_dlog(avr, "[end conversion]\n");
451  return 0;
452  }
453 
454  current_buffer = resample_out;
455  }
456 
457  if (avr->upmix_needed) {
458  av_dlog(avr, "[upmix] %s\n", current_buffer->name);
459  ret = ff_audio_mix(avr->am, current_buffer);
460  if (ret < 0)
461  return ret;
462  }
463 
464  /* if we resampled or upmixed directly to output, return here */
465  if (current_buffer == &output_buffer) {
466  av_dlog(avr, "[end conversion]\n");
467  return current_buffer->nb_samples;
468  }
469 
470  if (avr->out_convert_needed) {
471  if (direct_output && out_samples >= current_buffer->nb_samples) {
472  /* convert directly to output */
473  av_dlog(avr, "[convert] %s to output\n", current_buffer->name);
474  ret = ff_audio_convert(avr->ac_out, &output_buffer, current_buffer);
475  if (ret < 0)
476  return ret;
477 
478  av_dlog(avr, "[end conversion]\n");
479  return output_buffer.nb_samples;
480  } else {
482  current_buffer->nb_samples);
483  if (ret < 0)
484  return ret;
485  av_dlog(avr, "[convert] %s to out_buffer\n", current_buffer->name);
486  ret = ff_audio_convert(avr->ac_out, avr->out_buffer,
487  current_buffer);
488  if (ret < 0)
489  return ret;
490  current_buffer = avr->out_buffer;
491  }
492  }
493 
494  return handle_buffered_output(avr, output ? &output_buffer : NULL,
495  current_buffer);
496 }
497 
499  int stride)
500 {
501  int in_channels, out_channels, i, o;
502 
503  if (avr->am)
504  return ff_audio_mix_get_matrix(avr->am, matrix, stride);
505 
508 
509  if ( in_channels <= 0 || in_channels > AVRESAMPLE_MAX_CHANNELS ||
510  out_channels <= 0 || out_channels > AVRESAMPLE_MAX_CHANNELS) {
511  av_log(avr, AV_LOG_ERROR, "Invalid channel layouts\n");
512  return AVERROR(EINVAL);
513  }
514 
515  if (!avr->mix_matrix) {
516  av_log(avr, AV_LOG_ERROR, "matrix is not set\n");
517  return AVERROR(EINVAL);
518  }
519 
520  for (o = 0; o < out_channels; o++)
521  for (i = 0; i < in_channels; i++)
522  matrix[o * stride + i] = avr->mix_matrix[o * in_channels + i];
523 
524  return 0;
525 }
526 
527 int avresample_set_matrix(AVAudioResampleContext *avr, const double *matrix,
528  int stride)
529 {
530  int in_channels, out_channels, i, o;
531 
532  if (avr->am)
533  return ff_audio_mix_set_matrix(avr->am, matrix, stride);
534 
537 
538  if ( in_channels <= 0 || in_channels > AVRESAMPLE_MAX_CHANNELS ||
539  out_channels <= 0 || out_channels > AVRESAMPLE_MAX_CHANNELS) {
540  av_log(avr, AV_LOG_ERROR, "Invalid channel layouts\n");
541  return AVERROR(EINVAL);
542  }
543 
544  if (avr->mix_matrix)
545  av_freep(&avr->mix_matrix);
546  avr->mix_matrix = av_malloc(in_channels * out_channels *
547  sizeof(*avr->mix_matrix));
548  if (!avr->mix_matrix)
549  return AVERROR(ENOMEM);
550 
551  for (o = 0; o < out_channels; o++)
552  for (i = 0; i < in_channels; i++)
553  avr->mix_matrix[o * in_channels + i] = matrix[o * stride + i];
554 
555  return 0;
556 }
557 
559  const int *channel_map)
560 {
561  ChannelMapInfo *info = &avr->ch_map_info;
562  int in_channels, ch, i;
563 
565  if (in_channels <= 0 || in_channels > AVRESAMPLE_MAX_CHANNELS) {
566  av_log(avr, AV_LOG_ERROR, "Invalid input channel layout\n");
567  return AVERROR(EINVAL);
568  }
569 
570  memset(info, 0, sizeof(*info));
571  memset(info->input_map, -1, sizeof(info->input_map));
572 
573  for (ch = 0; ch < in_channels; ch++) {
574  if (channel_map[ch] >= in_channels) {
575  av_log(avr, AV_LOG_ERROR, "Invalid channel map\n");
576  return AVERROR(EINVAL);
577  }
578  if (channel_map[ch] < 0) {
579  info->channel_zero[ch] = 1;
580  info->channel_map[ch] = -1;
581  info->do_zero = 1;
582  } else if (info->input_map[channel_map[ch]] >= 0) {
583  info->channel_copy[ch] = info->input_map[channel_map[ch]];
584  info->channel_map[ch] = -1;
585  info->do_copy = 1;
586  } else {
587  info->channel_map[ch] = channel_map[ch];
588  info->input_map[channel_map[ch]] = ch;
589  info->do_remap = 1;
590  }
591  }
592  /* Fill-in unmapped input channels with unmapped output channels.
593  This is used when remapping during conversion from interleaved to
594  planar format. */
595  for (ch = 0, i = 0; ch < in_channels && i < in_channels; ch++, i++) {
596  while (ch < in_channels && info->input_map[ch] >= 0)
597  ch++;
598  while (i < in_channels && info->channel_map[i] >= 0)
599  i++;
600  if (ch >= in_channels || i >= in_channels)
601  break;
602  info->input_map[ch] = i;
603  }
604 
605  avr->use_channel_map = 1;
606  return 0;
607 }
608 
610 {
611  return av_audio_fifo_size(avr->out_fifo);
612 }
613 
614 int avresample_read(AVAudioResampleContext *avr, uint8_t **output, int nb_samples)
615 {
616  if (!output)
617  return av_audio_fifo_drain(avr->out_fifo, nb_samples);
618  return av_audio_fifo_read(avr->out_fifo, (void**)output, nb_samples);
619 }
620 
621 unsigned avresample_version(void)
622 {
624 }
625 
626 const char *avresample_license(void)
627 {
628 #define LICENSE_PREFIX "libavresample license: "
629  return LICENSE_PREFIX FFMPEG_LICENSE + sizeof(LICENSE_PREFIX) - 1;
630 }
631 
632 const char *avresample_configuration(void)
633 {
634  return FFMPEG_CONFIGURATION;
635 }