libavresample/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 
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 {
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 
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 }
int in_channels
number of input channels
AudioConvert * ac_in
input sample format conversion context
const char * name
name for debug logging
Definition: audio_data.h:53
int ff_audio_data_realloc(AudioData *a, int nb_samples)
Reallocate AudioData.
Definition: audio_data.c:153
#define LIBAVRESAMPLE_VERSION_INT
int input_map[AVRESAMPLE_MAX_CHANNELS]
dest index of each input channel
AudioData * out_buffer
buffer for converted output
Audio buffer used for intermediate storage between conversion phases.
Definition: oss_audio.c:46
memory handling functions
int ff_audio_data_add_to_fifo(AVAudioFifo *af, AudioData *a, int offset, int nb_samples)
Add samples in AudioData to an AVAudioFifo.
Definition: audio_data.c:342
int do_zero
zeroing needed
AudioData * ff_audio_data_alloc(int channels, int nb_samples, enum AVSampleFormat sample_fmt, const char *name)
Allocate AudioData.
Definition: audio_data.c:110
int avresample_read(AVAudioResampleContext *avr, uint8_t **output, int nb_samples)
Read samples from the output FIFO.
double * mix_matrix
mix matrix only used if avresample_set_matrix() is called before avresample_open() ...
uint64_t out_channel_layout
output channel layout
int ff_audio_convert(AudioConvert *ac, AudioData *out, AudioData *in)
Convert audio data from one sample format to another.
av_dlog(ac->avr,"%d samples - audio_convert: %s to %s (%s)\n", len, av_get_sample_fmt_name(ac->in_fmt), av_get_sample_fmt_name(ac->out_fmt), use_generic?ac->func_descr_generic:ac->func_descr)
void av_audio_fifo_free(AVAudioFifo *af)
Free an AVAudioFifo.
Definition: audio_fifo.c:45
int avresample_set_channel_mapping(AVAudioResampleContext *avr, const int *channel_map)
Set a customized input channel mapping.
int stride
Definition: mace.c:144
int ff_audio_mix(AudioMix *am, AudioData *src)
Apply channel mixing to audio data using the current mixing matrix.
Definition: audio_mix.c:428
int channel_zero[AVRESAMPLE_MAX_CHANNELS]
dest index to zero
#define FFMPEG_LICENSE
Definition: config.h:5
void avresample_free(AVAudioResampleContext **avr)
Free AVAudioResampleContext and associated AVOption values.
int nb_samples
current number of samples
Definition: audio_data.h:41
void av_freep(void *arg)
Free a memory block which has been allocated with av_malloc(z)() or av_realloc() and set the pointer ...
Definition: mem.c:198
AudioData * in_buffer
buffer for converted input
int av_audio_fifo_read(AVAudioFifo *af, void **data, int nb_samples)
Read data from an AVAudioFifo.
Definition: audio_fifo.c:139
Public dictionary API.
int allocated_channels
allocated channel count
Definition: audio_data.h:44
uint8_t
AVOptions.
int out_channels
number of output channels
static int handle_buffered_output(AVAudioResampleContext *avr, AudioData *output, AudioData *converted)
#define LICENSE_PREFIX
int ff_audio_mix_set_matrix(AudioMix *am, const double *matrix, int stride)
Set the current mixing matrix.
Definition: audio_mix.c:650
enum AVSampleFormat av_get_planar_sample_fmt(enum AVSampleFormat sample_fmt)
Get the planar alternative form of the given sample format.
Definition: samplefmt.c:82
const char * avresample_license(void)
Return the libavresample license.
signed 32 bits, planar
Definition: samplefmt.h:59
int av_audio_fifo_size(AVAudioFifo *af)
Get the current number of samples in the AVAudioFifo available for reading.
Definition: audio_fifo.c:186
AudioConvert * ff_audio_convert_alloc(AVAudioResampleContext *avr, enum AVSampleFormat out_fmt, enum AVSampleFormat in_fmt, int channels, int sample_rate, int apply_map)
Allocate and initialize AudioConvert context for sample format conversion.
void avresample_close(AVAudioResampleContext *avr)
Close AVAudioResampleContext.
float, planar
Definition: samplefmt.h:60
AudioMix * am
channel mixing context
int ff_audio_data_set_channels(AudioData *a, int channels)
Definition: audio_data.c:51
int ff_audio_resample(ResampleContext *c, AudioData *dst, AudioData *src)
Resample audio data.
AVAudioFifo * av_audio_fifo_alloc(enum AVSampleFormat sample_fmt, int channels, int nb_samples)
Allocate an AVAudioFifo.
Definition: audio_fifo.c:60
int out_convert_needed
output sample format conversion is needed
int av_get_channel_layout_nb_channels(uint64_t channel_layout)
Return the number of channels in the channel layout.
these buffered frames must be flushed immediately if a new input produces new the filter must not call request_frame to get more It must just process the frame or queue it The task of requesting more frames is left to the filter s request_frame method or the application If a filter has several the filter must be ready for frames arriving randomly on any input any filter with several inputs will most likely require some kind of queuing mechanism It is perfectly acceptable to have a limited queue and to drop frames when the inputs are too unbalanced request_frame This method is called when a frame is wanted on an output For an input
void av_log(void *avcl, int level, const char *fmt,...)
Definition: log.c:246
void ff_audio_convert_free(AudioConvert **ac)
Free AudioConvert.
AudioConvert * ac_out
output sample format conversion context
#define FFMAX(a, b)
Definition: common.h:56
int ff_audio_data_read_from_fifo(AVAudioFifo *af, AudioData *a, int nb_samples)
Read samples from an AVAudioFifo to AudioData.
Definition: audio_data.c:357
int channel_copy[AVRESAMPLE_MAX_CHANNELS]
dest index to copy from
int upmix_needed
upmixing is needed
ResampleContext * resample
resampling context
MIPS optimizations info
Definition: mips.txt:2
external API header
#define FFMIN(a, b)
Definition: common.h:58
int do_remap
remap needed
ret
Definition: avfilter.c:821
int ff_audio_data_init(AudioData *a, uint8_t **src, int plane_size, int channels, int nb_samples, enum AVSampleFormat sample_fmt, int read_only, const char *name)
Initialize AudioData using a given source.
Definition: audio_data.c:65
uint64_t in_channel_layout
input channel layout
const char * av_get_sample_fmt_name(enum AVSampleFormat sample_fmt)
Return the name of sample_fmt, or NULL if sample_fmt is not recognized.
Definition: samplefmt.c:47
int avresample_set_matrix(AVAudioResampleContext *avr, const double *matrix, int stride)
Set channel mixing matrix.
int av_get_bytes_per_sample(enum AVSampleFormat sample_fmt)
Return number of bytes per sample.
Definition: samplefmt.c:104
int in_sample_rate
input sample rate
#define attribute_align_arg
int avresample_get_matrix(AVAudioResampleContext *avr, double *matrix, int stride)
Get the current channel mixing matrix.
NULL
Definition: eval.c:55
int avresample_available(AVAudioResampleContext *avr)
Return the number of available samples in the output FIFO.
void ff_audio_resample_free(ResampleContext **c)
Free a ResampleContext.
AVAudioFifo * out_fifo
FIFO for output samples.
#define AVRESAMPLE_MAX_CHANNELS
Definition: avresample.h:103
enum AVSampleFormat internal_sample_fmt
internal sample format
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:148
int force_resampling
force resampling
void ff_audio_mix_free(AudioMix **am_p)
Free an AudioMix context.
Definition: audio_mix.c:409
int in_copy_needed
input data copy is needed
const char * avresample_configuration(void)
Return the libavresample build-time configuration.
void * av_malloc(size_t size)
Allocate a block of size bytes with alignment suitable for all memory accesses (including vectors if ...
Definition: mem.c:73
ResampleContext * ff_audio_resample_init(AVAudioResampleContext *avr)
Allocate and initialize a ResampleContext.
int av_sample_fmt_is_planar(enum AVSampleFormat sample_fmt)
Check if the sample format is planar.
Definition: samplefmt.c:118
synthesis window for stochastic i
int av_audio_fifo_drain(AVAudioFifo *af, int nb_samples)
Drain data from an AVAudioFifo.
Definition: audio_fifo.c:159
enum AVSampleFormat in_sample_fmt
input sample format
The official guide to swscale for confused that consecutive non overlapping rectangles of slice_bottom special converter These generally are unscaled converters of common like for each output line the vertical scaler pulls lines from a ring buffer When the ring buffer does not contain the wanted then it is pulled from the input slice through the input converter and horizontal scaler The result is also stored in the ring buffer to serve future vertical scaler requests When no more output can be generated because lines from a future slice would be then all remaining lines in the current slice are converted
Definition: swscale.txt:33
int attribute_align_arg avresample_convert(AVAudioResampleContext *avr, uint8_t **output, int out_plane_size, int out_samples, uint8_t **input, int in_plane_size, int in_samples)
Convert input samples and write them to the output FIFO.
int in_convert_needed
input sample format conversion is needed
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFilterBuffer structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later.That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another.Buffer references ownership and permissions
int channel_map[AVRESAMPLE_MAX_CHANNELS]
source index of each output channel, -1 if not remapped
enum AVSampleFormat out_sample_fmt
output sample format
int ff_audio_data_copy(AudioData *dst, AudioData *src, ChannelMapInfo *map)
Copy data from one AudioData to another.
Definition: audio_data.c:216
void av_opt_free(void *obj)
Free all string and binary options in obj.
Definition: opt.c:1194
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:162
common internal and external API header
int resample_channels
number of channels used for resampling
AudioData * resample_out_buffer
buffer for output from resampler
int resample_needed
resampling is needed
int do_copy
copy needed
AVSampleFormat
Audio Sample Formats.
Definition: samplefmt.h:49
these buffered frames must be flushed immediately if a new input produces new output(Example:frame rate-doubling filter:filter_frame must(1) flush the second copy of the previous frame, if it is still there,(2) push the first copy of the incoming frame,(3) keep the second copy for later.) If the input frame is not enough to produce output
AudioMix * ff_audio_mix_alloc(AVAudioResampleContext *avr)
Allocate and initialize an AudioMix context.
Definition: audio_mix.c:341
#define FFMPEG_CONFIGURATION
Definition: config.h:4
unsigned avresample_version(void)
Return the LIBAVRESAMPLE_VERSION_INT constant.
int allocated_samples
number of samples the buffer can hold
Definition: audio_data.h:40
signed 16 bits, planar
Definition: samplefmt.h:58
int out_sample_rate
output sample rate
void ff_audio_data_free(AudioData **a)
Free AudioData.
Definition: audio_data.c:208
int downmix_needed
downmixing is needed
int avresample_open(AVAudioResampleContext *avr)
Initialize AVAudioResampleContext.
double, planar
Definition: samplefmt.h:61
int mixing_needed
either upmixing or downmixing is needed
int ff_audio_mix_get_matrix(AudioMix *am, double *matrix, int stride)
Get the current mixing matrix.
Definition: audio_mix.c:483