FFmpeg
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 FFmpeg.
5  *
6  * FFmpeg 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  * FFmpeg 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 FFmpeg; 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/frame.h"
25 #include "libavutil/log.h"
26 #include "libavutil/mem.h"
27 #include "libavutil/opt.h"
28 
29 #include "avresample.h"
30 #include "internal.h"
31 #include "audio_data.h"
32 #include "audio_convert.h"
33 #include "audio_mix.h"
34 #include "resample.h"
35 
37 {
38  int ret;
39 
40  if (avresample_is_open(avr)) {
41  av_log(avr, AV_LOG_ERROR, "The resampling context is already open.\n");
42  return AVERROR(EINVAL);
43  }
44 
45  /* set channel mixing parameters */
47  if (avr->in_channels <= 0 || avr->in_channels > AVRESAMPLE_MAX_CHANNELS) {
48  av_log(avr, AV_LOG_ERROR, "Invalid input channel layout: %"PRIu64"\n",
49  avr->in_channel_layout);
50  return AVERROR(EINVAL);
51  }
53  if (avr->out_channels <= 0 || avr->out_channels > AVRESAMPLE_MAX_CHANNELS) {
54  av_log(avr, AV_LOG_ERROR, "Invalid output channel layout: %"PRIu64"\n",
55  avr->out_channel_layout);
56  return AVERROR(EINVAL);
57  }
59  avr->downmix_needed = avr->in_channels > avr->out_channels;
60  avr->upmix_needed = avr->out_channels > avr->in_channels ||
61  (!avr->downmix_needed && (avr->mix_matrix ||
63  avr->mixing_needed = avr->downmix_needed || avr->upmix_needed;
64 
65  /* set resampling parameters */
66  avr->resample_needed = avr->in_sample_rate != avr->out_sample_rate ||
67  avr->force_resampling;
68 
69  /* select internal sample format if not specified by the user */
71  (avr->mixing_needed || avr->resample_needed)) {
74  int max_bps = FFMAX(av_get_bytes_per_sample(in_fmt),
75  av_get_bytes_per_sample(out_fmt));
76  if (max_bps <= 2) {
78  } else if (avr->mixing_needed) {
80  } else {
81  if (max_bps <= 4) {
82  if (in_fmt == AV_SAMPLE_FMT_S32P ||
83  out_fmt == AV_SAMPLE_FMT_S32P) {
84  if (in_fmt == AV_SAMPLE_FMT_FLTP ||
85  out_fmt == AV_SAMPLE_FMT_FLTP) {
86  /* if one is s32 and the other is flt, use dbl */
88  } else {
89  /* if one is s32 and the other is s32, s16, or u8, use s32 */
91  }
92  } else {
93  /* if one is flt and the other is flt, s16 or u8, use flt */
95  }
96  } else {
97  /* if either is dbl, use dbl */
99  }
100  }
101  av_log(avr, AV_LOG_DEBUG, "Using %s as internal sample format\n",
103  }
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_log(avr, AV_LOG_TRACE, "remap channels during in_copy\n");
131  } else if (avr->in_convert_needed) {
133  av_log(avr, AV_LOG_TRACE, "remap channels during in_convert\n");
134  } else if (avr->out_convert_needed) {
136  av_log(avr, AV_LOG_TRACE, "remap channels during out_convert\n");
137  } else {
139  av_log(avr, AV_LOG_TRACE, "remap channels during out_copy\n");
140  }
141 
142 #ifdef DEBUG
143  {
144  int ch;
145  av_log(avr, AV_LOG_TRACE, "output map: ");
146  if (avr->ch_map_info.do_remap)
147  for (ch = 0; ch < avr->in_channels; ch++)
148  av_log(avr, AV_LOG_TRACE, " % 2d", avr->ch_map_info.channel_map[ch]);
149  else
150  av_log(avr, AV_LOG_TRACE, "n/a");
151  av_log(avr, AV_LOG_TRACE, "\n");
152  av_log(avr, AV_LOG_TRACE, "copy map: ");
153  if (avr->ch_map_info.do_copy)
154  for (ch = 0; ch < avr->in_channels; ch++)
155  av_log(avr, AV_LOG_TRACE, " % 2d", avr->ch_map_info.channel_copy[ch]);
156  else
157  av_log(avr, AV_LOG_TRACE, "n/a");
158  av_log(avr, AV_LOG_TRACE, "\n");
159  av_log(avr, AV_LOG_TRACE, "zero map: ");
160  if (avr->ch_map_info.do_zero)
161  for (ch = 0; ch < avr->in_channels; ch++)
162  av_log(avr, AV_LOG_TRACE, " % 2d", avr->ch_map_info.channel_zero[ch]);
163  else
164  av_log(avr, AV_LOG_TRACE, "n/a");
165  av_log(avr, AV_LOG_TRACE, "\n");
166  av_log(avr, AV_LOG_TRACE, "input map: ");
167  for (ch = 0; ch < avr->in_channels; ch++)
168  av_log(avr, AV_LOG_TRACE, " % 2d", avr->ch_map_info.input_map[ch]);
169  av_log(avr, AV_LOG_TRACE, "\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  1024, 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 {
259  return !!avr->out_fifo;
260 }
261 
263 {
268  avr->out_fifo = NULL;
272  ff_audio_mix_free(&avr->am);
273  av_freep(&avr->mix_matrix);
274 
275  avr->use_channel_map = 0;
276 }
277 
279 {
280  if (!*avr)
281  return;
282  avresample_close(*avr);
283  av_opt_free(*avr);
284  av_freep(avr);
285 }
286 
289 {
290  int ret;
291 
292  if (!output || av_audio_fifo_size(avr->out_fifo) > 0 ||
293  (converted && output->allocated_samples < converted->nb_samples)) {
294  if (converted) {
295  /* if there are any samples in the output FIFO or if the
296  user-supplied output buffer is not large enough for all samples,
297  we add to the output FIFO */
298  av_log(avr, AV_LOG_TRACE, "[FIFO] add %s to out_fifo\n", converted->name);
299  ret = ff_audio_data_add_to_fifo(avr->out_fifo, converted, 0,
300  converted->nb_samples);
301  if (ret < 0)
302  return ret;
303  }
304 
305  /* if the user specified an output buffer, read samples from the output
306  FIFO to the user output */
307  if (output && output->allocated_samples > 0) {
308  av_log(avr, AV_LOG_TRACE, "[FIFO] read from out_fifo to output\n");
309  av_log(avr, AV_LOG_TRACE, "[end conversion]\n");
310  return ff_audio_data_read_from_fifo(avr->out_fifo, output,
311  output->allocated_samples);
312  }
313  } else if (converted) {
314  /* copy directly to output if it is large enough or there is not any
315  data in the output FIFO */
316  av_log(avr, AV_LOG_TRACE, "[copy] %s to output\n", converted->name);
317  output->nb_samples = 0;
318  ret = ff_audio_data_copy(output, converted,
319  avr->remap_point == REMAP_OUT_COPY ?
320  &avr->ch_map_info : NULL);
321  if (ret < 0)
322  return ret;
323  av_log(avr, AV_LOG_TRACE, "[end conversion]\n");
324  return output->nb_samples;
325  }
326  av_log(avr, AV_LOG_TRACE, "[end conversion]\n");
327  return 0;
328 }
329 
330 int attribute_align_arg avresample_convert(AVAudioResampleContext *avr,
331  uint8_t **output, int out_plane_size,
332  int out_samples,
333  uint8_t * const *input,
334  int in_plane_size, int in_samples)
335 {
336  AudioData input_buffer;
337  AudioData output_buffer;
338  AudioData *current_buffer;
339  int ret, direct_output;
340 
341  /* reset internal buffers */
342  if (avr->in_buffer) {
343  avr->in_buffer->nb_samples = 0;
346  }
347  if (avr->resample_out_buffer) {
351  }
352  if (avr->out_buffer) {
353  avr->out_buffer->nb_samples = 0;
356  }
357 
358  av_log(avr, AV_LOG_TRACE, "[start conversion]\n");
359 
360  /* initialize output_buffer with output data */
361  direct_output = output && av_audio_fifo_size(avr->out_fifo) == 0;
362  if (output) {
363  ret = ff_audio_data_init(&output_buffer, output, out_plane_size,
364  avr->out_channels, out_samples,
365  avr->out_sample_fmt, 0, "output");
366  if (ret < 0)
367  return ret;
368  output_buffer.nb_samples = 0;
369  }
370 
371  if (input) {
372  /* initialize input_buffer with input data */
373  ret = ff_audio_data_init(&input_buffer, input, in_plane_size,
374  avr->in_channels, in_samples,
375  avr->in_sample_fmt, 1, "input");
376  if (ret < 0)
377  return ret;
378  current_buffer = &input_buffer;
379 
380  if (avr->upmix_needed && !avr->in_convert_needed && !avr->resample_needed &&
381  !avr->out_convert_needed && direct_output && out_samples >= in_samples) {
382  /* in some rare cases we can copy input to output and upmix
383  directly in the output buffer */
384  av_log(avr, AV_LOG_TRACE, "[copy] %s to output\n", current_buffer->name);
385  ret = ff_audio_data_copy(&output_buffer, current_buffer,
386  avr->remap_point == REMAP_OUT_COPY ?
387  &avr->ch_map_info : NULL);
388  if (ret < 0)
389  return ret;
390  current_buffer = &output_buffer;
391  } else if (avr->remap_point == REMAP_OUT_COPY &&
392  (!direct_output || out_samples < in_samples)) {
393  /* if remapping channels during output copy, we may need to
394  * use an intermediate buffer in order to remap before adding
395  * samples to the output fifo */
396  av_log(avr, AV_LOG_TRACE, "[copy] %s to out_buffer\n", current_buffer->name);
397  ret = ff_audio_data_copy(avr->out_buffer, current_buffer,
398  &avr->ch_map_info);
399  if (ret < 0)
400  return ret;
401  current_buffer = avr->out_buffer;
402  } else if (avr->in_copy_needed || avr->in_convert_needed) {
403  /* if needed, copy or convert input to in_buffer, and downmix if
404  applicable */
405  if (avr->in_convert_needed) {
406  ret = ff_audio_data_realloc(avr->in_buffer,
407  current_buffer->nb_samples);
408  if (ret < 0)
409  return ret;
410  av_log(avr, AV_LOG_TRACE, "[convert] %s to in_buffer\n", current_buffer->name);
411  ret = ff_audio_convert(avr->ac_in, avr->in_buffer,
412  current_buffer);
413  if (ret < 0)
414  return ret;
415  } else {
416  av_log(avr, AV_LOG_TRACE, "[copy] %s to in_buffer\n", current_buffer->name);
417  ret = ff_audio_data_copy(avr->in_buffer, current_buffer,
418  avr->remap_point == REMAP_IN_COPY ?
419  &avr->ch_map_info : NULL);
420  if (ret < 0)
421  return ret;
422  }
424  if (avr->downmix_needed) {
425  av_log(avr, AV_LOG_TRACE, "[downmix] in_buffer\n");
426  ret = ff_audio_mix(avr->am, avr->in_buffer);
427  if (ret < 0)
428  return ret;
429  }
430  current_buffer = avr->in_buffer;
431  }
432  } else {
433  /* flush resampling buffer and/or output FIFO if input is NULL */
434  if (!avr->resample_needed)
435  return handle_buffered_output(avr, output ? &output_buffer : NULL,
436  NULL);
437  current_buffer = NULL;
438  }
439 
440  if (avr->resample_needed) {
441  AudioData *resample_out;
442 
443  if (!avr->out_convert_needed && direct_output && out_samples > 0)
444  resample_out = &output_buffer;
445  else
446  resample_out = avr->resample_out_buffer;
447  av_log(avr, AV_LOG_TRACE, "[resample] %s to %s\n",
448  current_buffer ? current_buffer->name : "null",
449  resample_out->name);
450  ret = ff_audio_resample(avr->resample, resample_out,
451  current_buffer);
452  if (ret < 0)
453  return ret;
454 
455  /* if resampling did not produce any samples, just return 0 */
456  if (resample_out->nb_samples == 0) {
457  av_log(avr, AV_LOG_TRACE, "[end conversion]\n");
458  return 0;
459  }
460 
461  current_buffer = resample_out;
462  }
463 
464  if (avr->upmix_needed) {
465  av_log(avr, AV_LOG_TRACE, "[upmix] %s\n", current_buffer->name);
466  ret = ff_audio_mix(avr->am, current_buffer);
467  if (ret < 0)
468  return ret;
469  }
470 
471  /* if we resampled or upmixed directly to output, return here */
472  if (current_buffer == &output_buffer) {
473  av_log(avr, AV_LOG_TRACE, "[end conversion]\n");
474  return current_buffer->nb_samples;
475  }
476 
477  if (avr->out_convert_needed) {
478  if (direct_output && out_samples >= current_buffer->nb_samples) {
479  /* convert directly to output */
480  av_log(avr, AV_LOG_TRACE, "[convert] %s to output\n", current_buffer->name);
481  ret = ff_audio_convert(avr->ac_out, &output_buffer, current_buffer);
482  if (ret < 0)
483  return ret;
484 
485  av_log(avr, AV_LOG_TRACE, "[end conversion]\n");
486  return output_buffer.nb_samples;
487  } else {
489  current_buffer->nb_samples);
490  if (ret < 0)
491  return ret;
492  av_log(avr, AV_LOG_TRACE, "[convert] %s to out_buffer\n", current_buffer->name);
493  ret = ff_audio_convert(avr->ac_out, avr->out_buffer,
494  current_buffer);
495  if (ret < 0)
496  return ret;
497  current_buffer = avr->out_buffer;
498  }
499  }
500 
501  return handle_buffered_output(avr, output ? &output_buffer : NULL,
502  current_buffer);
503 }
504 
506 {
507  if (avresample_is_open(avr)) {
508  avresample_close(avr);
509  }
510 
511  if (in) {
513  avr->in_sample_rate = in->sample_rate;
514  avr->in_sample_fmt = in->format;
515  }
516 
517  if (out) {
519  avr->out_sample_rate = out->sample_rate;
520  avr->out_sample_fmt = out->format;
521  }
522 
523  return 0;
524 }
525 
527  AVFrame *out, AVFrame *in)
528 {
529  int ret = 0;
530 
531  if (in) {
532  if (avr->in_channel_layout != in->channel_layout ||
533  avr->in_sample_rate != in->sample_rate ||
534  avr->in_sample_fmt != in->format) {
535  ret |= AVERROR_INPUT_CHANGED;
536  }
537  }
538 
539  if (out) {
540  if (avr->out_channel_layout != out->channel_layout ||
541  avr->out_sample_rate != out->sample_rate ||
542  avr->out_sample_fmt != out->format) {
543  ret |= AVERROR_OUTPUT_CHANGED;
544  }
545  }
546 
547  return ret;
548 }
549 
550 static inline int convert_frame(AVAudioResampleContext *avr,
551  AVFrame *out, AVFrame *in)
552 {
553  int ret;
554  uint8_t **out_data = NULL, **in_data = NULL;
555  int out_linesize = 0, in_linesize = 0;
556  int out_nb_samples = 0, in_nb_samples = 0;
557 
558  if (out) {
559  out_data = out->extended_data;
560  out_linesize = out->linesize[0];
561  out_nb_samples = out->nb_samples;
562  }
563 
564  if (in) {
565  in_data = in->extended_data;
566  in_linesize = in->linesize[0];
567  in_nb_samples = in->nb_samples;
568  }
569 
570  ret = avresample_convert(avr, out_data, out_linesize,
571  out_nb_samples,
572  in_data, in_linesize,
573  in_nb_samples);
574 
575  if (ret < 0) {
576  if (out)
577  out->nb_samples = 0;
578  return ret;
579  }
580 
581  if (out)
582  out->nb_samples = ret;
583 
584  return 0;
585 }
586 
587 static inline int available_samples(AVFrame *out)
588 {
589  int samples;
590  int bytes_per_sample = av_get_bytes_per_sample(out->format);
591  if (!bytes_per_sample)
592  return AVERROR(EINVAL);
593 
594  samples = out->linesize[0] / bytes_per_sample;
595  if (av_sample_fmt_is_planar(out->format)) {
596  return samples;
597  } else {
599  return samples / channels;
600  }
601 }
602 
604  AVFrame *out, AVFrame *in)
605 {
606  int ret, setup = 0;
607 
608  if (!avresample_is_open(avr)) {
609  if ((ret = avresample_config(avr, out, in)) < 0)
610  return ret;
611  if ((ret = avresample_open(avr)) < 0)
612  return ret;
613  setup = 1;
614  } else {
615  // return as is or reconfigure for input changes?
616  if ((ret = config_changed(avr, out, in)))
617  return ret;
618  }
619 
620  if (out) {
621  if (!out->linesize[0]) {
623  if ((ret = av_frame_get_buffer(out, 0)) < 0) {
624  if (setup)
625  avresample_close(avr);
626  return ret;
627  }
628  } else {
629  if (!out->nb_samples)
630  out->nb_samples = available_samples(out);
631  }
632  }
633 
634  return convert_frame(avr, out, in);
635 }
636 
638  int stride)
639 {
640  int in_channels, out_channels, i, o;
641 
642  if (avr->am)
643  return ff_audio_mix_get_matrix(avr->am, matrix, stride);
644 
647 
648  if ( in_channels <= 0 || in_channels > AVRESAMPLE_MAX_CHANNELS ||
649  out_channels <= 0 || out_channels > AVRESAMPLE_MAX_CHANNELS) {
650  av_log(avr, AV_LOG_ERROR, "Invalid channel layouts\n");
651  return AVERROR(EINVAL);
652  }
653 
654  if (!avr->mix_matrix) {
655  av_log(avr, AV_LOG_ERROR, "matrix is not set\n");
656  return AVERROR(EINVAL);
657  }
658 
659  for (o = 0; o < out_channels; o++)
660  for (i = 0; i < in_channels; i++)
661  matrix[o * stride + i] = avr->mix_matrix[o * in_channels + i];
662 
663  return 0;
664 }
665 
666 int avresample_set_matrix(AVAudioResampleContext *avr, const double *matrix,
667  int stride)
668 {
669  int in_channels, out_channels, i, o;
670 
671  if (avr->am)
672  return ff_audio_mix_set_matrix(avr->am, matrix, stride);
673 
676 
677  if ( in_channels <= 0 || in_channels > AVRESAMPLE_MAX_CHANNELS ||
678  out_channels <= 0 || out_channels > AVRESAMPLE_MAX_CHANNELS) {
679  av_log(avr, AV_LOG_ERROR, "Invalid channel layouts\n");
680  return AVERROR(EINVAL);
681  }
682 
683  if (avr->mix_matrix)
684  av_freep(&avr->mix_matrix);
685  avr->mix_matrix = av_malloc(in_channels * out_channels *
686  sizeof(*avr->mix_matrix));
687  if (!avr->mix_matrix)
688  return AVERROR(ENOMEM);
689 
690  for (o = 0; o < out_channels; o++)
691  for (i = 0; i < in_channels; i++)
692  avr->mix_matrix[o * in_channels + i] = matrix[o * stride + i];
693 
694  return 0;
695 }
696 
698  const int *channel_map)
699 {
701  int in_channels, ch, i;
702 
704  if (in_channels <= 0 || in_channels > AVRESAMPLE_MAX_CHANNELS) {
705  av_log(avr, AV_LOG_ERROR, "Invalid input channel layout\n");
706  return AVERROR(EINVAL);
707  }
708 
709  memset(info, 0, sizeof(*info));
710  memset(info->input_map, -1, sizeof(info->input_map));
711 
712  for (ch = 0; ch < in_channels; ch++) {
713  if (channel_map[ch] >= in_channels) {
714  av_log(avr, AV_LOG_ERROR, "Invalid channel map\n");
715  return AVERROR(EINVAL);
716  }
717  if (channel_map[ch] < 0) {
718  info->channel_zero[ch] = 1;
719  info->channel_map[ch] = -1;
720  info->do_zero = 1;
721  } else if (info->input_map[channel_map[ch]] >= 0) {
722  info->channel_copy[ch] = info->input_map[channel_map[ch]];
723  info->channel_map[ch] = -1;
724  info->do_copy = 1;
725  } else {
726  info->channel_map[ch] = channel_map[ch];
727  info->input_map[channel_map[ch]] = ch;
728  info->do_remap = 1;
729  }
730  }
731  /* Fill-in unmapped input channels with unmapped output channels.
732  This is used when remapping during conversion from interleaved to
733  planar format. */
734  for (ch = 0, i = 0; ch < in_channels && i < in_channels; ch++, i++) {
735  while (ch < in_channels && info->input_map[ch] >= 0)
736  ch++;
737  while (i < in_channels && info->channel_map[i] >= 0)
738  i++;
739  if (ch >= in_channels || i >= in_channels)
740  break;
741  info->input_map[ch] = i;
742  }
743 
744  avr->use_channel_map = 1;
745  return 0;
746 }
747 
749 {
750  return av_audio_fifo_size(avr->out_fifo);
751 }
752 
754 {
755  int64_t samples = avresample_get_delay(avr) + (int64_t)in_nb_samples;
756 
757  if (avr->resample_needed) {
758  samples = av_rescale_rnd(samples,
759  avr->out_sample_rate,
760  avr->in_sample_rate,
761  AV_ROUND_UP);
762  }
763 
764  samples += avresample_available(avr);
765 
766  if (samples > INT_MAX)
767  return AVERROR(EINVAL);
768 
769  return samples;
770 }
771 
773 {
774  if (!output)
775  return av_audio_fifo_drain(avr->out_fifo, nb_samples);
776  return av_audio_fifo_read(avr->out_fifo, (void**)output, nb_samples);
777 }
778 
779 unsigned avresample_version(void)
780 {
782 }
783 
784 const char *avresample_license(void)
785 {
786 #define LICENSE_PREFIX "libavresample license: "
787  return LICENSE_PREFIX FFMPEG_LICENSE + sizeof(LICENSE_PREFIX) - 1;
788 }
789 
790 const char *avresample_configuration(void)
791 {
792  return FFMPEG_CONFIGURATION;
793 }
const char * avresample_license(void)
Definition: utils.c:784
float, planar
Definition: samplefmt.h:69
int in_channels
number of input channels
Definition: internal.h:77
#define NULL
Definition: coverity.c:32
int avresample_set_matrix(AVAudioResampleContext *avr, const double *matrix, int stride)
Definition: utils.c:666
AudioConvert * ac_in
input sample format conversion context
Definition: internal.h:93
const char * name
name for debug logging
Definition: audio_data.h:55
AVAudioFifo * av_audio_fifo_alloc(enum AVSampleFormat sample_fmt, int channels, int nb_samples)
Allocate an AVAudioFifo.
Definition: audio_fifo.c:59
int av_audio_fifo_read(AVAudioFifo *af, void **data, int nb_samples)
Read data from an AVAudioFifo.
Definition: audio_fifo.c:181
int ff_audio_data_realloc(AudioData *a, int nb_samples)
Reallocate AudioData.
Definition: audio_data.c:162
This structure describes decoded (raw) audio or video data.
Definition: frame.h:295
int avresample_open(AVAudioResampleContext *avr)
Definition: utils.c:36
#define LIBAVRESAMPLE_VERSION_INT
Definition: version.h:34
int avresample_read(AVAudioResampleContext *avr, uint8_t **output, int nb_samples)
Definition: utils.c:772
int input_map[AVRESAMPLE_MAX_CHANNELS]
dest index of each input channel
Definition: internal.h:50
AudioData * out_buffer
buffer for converted output
Definition: internal.h:90
Audio buffer used for intermediate storage between conversion phases.
Definition: audio_data.h:37
attribute_deprecated int avresample_get_delay(AVAudioResampleContext *avr)
Definition: resample.c:438
static int config_changed(AVAudioResampleContext *avr, AVFrame *out, AVFrame *in)
Definition: utils.c:526
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:351
int do_zero
zeroing needed
Definition: internal.h:49
AudioData * ff_audio_data_alloc(int channels, int nb_samples, enum AVSampleFormat sample_fmt, const char *name)
Allocate AudioData.
Definition: audio_data.c:119
static int convert_frame(AVAudioResampleContext *avr, AVFrame *out, AVFrame *in)
Definition: utils.c:550
double * mix_matrix
mix matrix only used if avresample_set_matrix() is called before avresample_open() ...
Definition: internal.h:103
uint64_t out_channel_layout
output channel layout
Definition: internal.h:59
channels
Definition: aptx.c:30
void av_audio_fifo_free(AVAudioFifo *af)
Free an AVAudioFifo.
Definition: audio_fifo.c:45
uint8_t pi<< 24) CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_U8,(uint64_t)((*(const uint8_t *) pi-0x80U))<< 56) CONV_FUNC(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_U8,(*(const uint8_t *) pi-0x80)*(1.0f/(1<< 7))) CONV_FUNC(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_U8,(*(const uint8_t *) pi-0x80)*(1.0/(1<< 7))) CONV_FUNC(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S16,(*(const int16_t *) pi >>8)+0x80) CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_S16,(uint64_t)(*(const int16_t *) pi)<< 48) CONV_FUNC(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S16,*(const int16_t *) pi *(1.0f/(1<< 15))) CONV_FUNC(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S16,*(const int16_t *) pi *(1.0/(1<< 15))) CONV_FUNC(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S32,(*(const int32_t *) pi >>24)+0x80) CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_S32,(uint64_t)(*(const int32_t *) pi)<< 32) CONV_FUNC(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S32,*(const int32_t *) pi *(1.0f/(1U<< 31))) CONV_FUNC(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S32,*(const int32_t *) pi *(1.0/(1U<< 31))) CONV_FUNC(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S64,(*(const int64_t *) pi >>56)+0x80) CONV_FUNC(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S64,*(const int64_t *) pi *(1.0f/(INT64_C(1)<< 63))) CONV_FUNC(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S64,*(const int64_t *) pi *(1.0/(INT64_C(1)<< 63))) CONV_FUNC(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_FLT, av_clip_uint8(lrintf(*(const float *) pi *(1<< 7))+0x80)) CONV_FUNC(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_FLT, av_clip_int16(lrintf(*(const float *) pi *(1<< 15)))) CONV_FUNC(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_FLT, av_clipl_int32(llrintf(*(const float *) pi *(1U<< 31)))) CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_FLT, llrintf(*(const float *) pi *(INT64_C(1)<< 63))) CONV_FUNC(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_DBL, av_clip_uint8(lrint(*(const double *) pi *(1<< 7))+0x80)) CONV_FUNC(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_DBL, av_clip_int16(lrint(*(const double *) pi *(1<< 15)))) CONV_FUNC(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_DBL, av_clipl_int32(llrint(*(const double *) pi *(1U<< 31)))) CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_DBL, llrint(*(const double *) pi *(INT64_C(1)<< 63)))#define FMT_PAIR_FUNC(out, in) static conv_func_type *const fmt_pair_to_conv_functions[AV_SAMPLE_FMT_NB *AV_SAMPLE_FMT_NB]={FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_S64), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S64), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_S64), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S64), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_S64), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_S64),};static void cpy1(uint8_t **dst, const uint8_t **src, int len){memcpy(*dst,*src, len);}static void cpy2(uint8_t **dst, const uint8_t **src, int len){memcpy(*dst,*src, 2 *len);}static void cpy4(uint8_t **dst, const uint8_t **src, int len){memcpy(*dst,*src, 4 *len);}static void cpy8(uint8_t **dst, const uint8_t **src, int len){memcpy(*dst,*src, 8 *len);}AudioConvert *swri_audio_convert_alloc(enum AVSampleFormat out_fmt, enum AVSampleFormat in_fmt, int channels, const int *ch_map, int flags){AudioConvert *ctx;conv_func_type *f=fmt_pair_to_conv_functions[av_get_packed_sample_fmt(out_fmt)+AV_SAMPLE_FMT_NB *av_get_packed_sample_fmt(in_fmt)];if(!f) return NULL;ctx=av_mallocz(sizeof(*ctx));if(!ctx) return NULL;if(channels==1){in_fmt=av_get_planar_sample_fmt(in_fmt);out_fmt=av_get_planar_sample_fmt(out_fmt);}ctx->channels=channels;ctx->conv_f=f;ctx->ch_map=ch_map;if(in_fmt==AV_SAMPLE_FMT_U8||in_fmt==AV_SAMPLE_FMT_U8P) memset(ctx->silence, 0x80, sizeof(ctx->silence));if(out_fmt==in_fmt &&!ch_map){switch(av_get_bytes_per_sample(in_fmt)){case 1:ctx->simd_f=cpy1;break;case 2:ctx->simd_f=cpy2;break;case 4:ctx->simd_f=cpy4;break;case 8:ctx->simd_f=cpy8;break;}}if(HAVE_X86ASM &&1) swri_audio_convert_init_x86(ctx, out_fmt, in_fmt, channels);if(ARCH_ARM) swri_audio_convert_init_arm(ctx, out_fmt, in_fmt, channels);if(ARCH_AARCH64) swri_audio_convert_init_aarch64(ctx, out_fmt, in_fmt, channels);return ctx;}void swri_audio_convert_free(AudioConvert **ctx){av_freep(ctx);}int swri_audio_convert(AudioConvert *ctx, AudioData *out, AudioData *in, int len){int ch;int off=0;const int os=(out->planar?1:out->ch_count)*out->bps;unsigned misaligned=0;av_assert0(ctx->channels==out->ch_count);if(ctx->in_simd_align_mask){int planes=in->planar?in->ch_count:1;unsigned m=0;for(ch=0;ch< planes;ch++) m|=(intptr_t) in->ch[ch];misaligned|=m &ctx->in_simd_align_mask;}if(ctx->out_simd_align_mask){int planes=out->planar?out->ch_count:1;unsigned m=0;for(ch=0;ch< planes;ch++) m|=(intptr_t) out->ch[ch];misaligned|=m &ctx->out_simd_align_mask;}if(ctx->simd_f &&!ctx->ch_map &&!misaligned){off=len &~15;av_assert1(off >=0);av_assert1(off<=len);av_assert2(ctx->channels==SWR_CH_MAX||!in->ch[ctx->channels]);if(off >0){if(out->planar==in->planar){int planes=out->planar?out->ch_count:1;for(ch=0;ch< planes;ch++){ctx->simd_f(out-> ch ch
Definition: audioconvert.c:56
int attribute_align_arg avresample_convert(AVAudioResampleContext *avr, uint8_t **output, int out_plane_size, int out_samples, uint8_t *const *input, int in_plane_size, int in_samples)
Definition: utils.c:330
int ff_audio_convert(AudioConvert *ac, AudioData *out, AudioData *in)
Convert audio data from one sample format to another.
double, planar
Definition: samplefmt.h:70
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 avresample_convert_frame(AVAudioResampleContext *avr, AVFrame *out, AVFrame *in)
Definition: utils.c:603
int channel_zero[AVRESAMPLE_MAX_CHANNELS]
dest index to zero
Definition: internal.h:48
int nb_samples
current number of samples
Definition: audio_data.h:43
int av_get_channel_layout_nb_channels(uint64_t channel_layout)
Return the number of channels in the channel layout.
AudioData * in_buffer
buffer for converted input
Definition: internal.h:88
Public dictionary API.
int allocated_channels
allocated channel count
Definition: audio_data.h:46
uint8_t
Round toward +infinity.
Definition: mathematics.h:83
#define av_malloc(s)
AVOptions.
int out_channels
number of output channels
Definition: internal.h:78
#define AV_LOG_TRACE
Extremely verbose debugging, useful for libav* development.
Definition: log.h:202
static int handle_buffered_output(AVAudioResampleContext *avr, AudioData *output, AudioData *converted)
Definition: utils.c:287
filter_frame For filters that do not use the this method is called when a frame is pushed to the filter s input It can be called at any time except in a reentrant way If the input frame is enough to produce output
#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:653
int ff_sample_fmt_is_planar(enum AVSampleFormat sample_fmt, int channels)
Definition: audio_data.c:51
enum AVSampleFormat av_get_planar_sample_fmt(enum AVSampleFormat sample_fmt)
Get the planar alternative form of the given sample format.
Definition: samplefmt.c:84
int avresample_get_out_samples(AVAudioResampleContext *avr, int in_nb_samples)
Definition: utils.c:753
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.
#define av_log(a,...)
void avresample_close(AVAudioResampleContext *avr)
Definition: utils.c:262
AudioMix * am
channel mixing context
Definition: internal.h:96
int av_sample_fmt_is_planar(enum AVSampleFormat sample_fmt)
Check if the sample format is planar.
Definition: samplefmt.c:112
int ff_audio_data_set_channels(AudioData *a, int channels)
Definition: audio_data.c:59
int ff_audio_resample(ResampleContext *c, AudioData *dst, AudioData *src)
Resample audio data.
Definition: resample.c:334
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:259
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
int out_convert_needed
output sample format conversion is needed
Definition: internal.h:85
int ff_audio_data_init(AudioData *a, uint8_t *const *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:73
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:197
int avresample_config(AVAudioResampleContext *avr, AVFrame *out, AVFrame *in)
Definition: utils.c:505
void ff_audio_convert_free(AudioConvert **ac)
Free AudioConvert.
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:49
AudioConvert * ac_out
output sample format conversion context
Definition: internal.h:94
#define FFMAX(a, b)
Definition: common.h:94
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:366
int avresample_available(AVAudioResampleContext *avr)
Definition: utils.c:748
reference-counted frame API
int channel_copy[AVRESAMPLE_MAX_CHANNELS]
dest index to copy from
Definition: internal.h:46
uint64_t channel_layout
Channel layout of the audio data.
Definition: frame.h:472
int upmix_needed
upmixing is needed
Definition: internal.h:81
ResampleContext * resample
resampling context
Definition: internal.h:95
int avresample_get_matrix(AVAudioResampleContext *avr, double *matrix, int stride)
Definition: utils.c:637
int av_audio_fifo_size(AVAudioFifo *af)
Get the current number of samples in the AVAudioFifo available for reading.
Definition: audio_fifo.c:228
MIPS optimizations info
Definition: mips.txt:2
enum RemapPoint remap_point
Definition: internal.h:106
external API header
#define FFMIN(a, b)
Definition: common.h:96
int do_remap
remap needed
Definition: internal.h:45
signed 32 bits, planar
Definition: samplefmt.h:68
const char * avresample_configuration(void)
Definition: utils.c:790
unsigned avresample_version(void)
Definition: utils.c:779
#define AVERROR_INPUT_CHANGED
Input changed between calls. Reconfiguration is required. (can be OR-ed with AVERROR_OUTPUT_CHANGED) ...
Definition: error.h:73
ChannelMapInfo ch_map_info
Definition: internal.h:107
uint64_t in_channel_layout
input channel layout
Definition: internal.h:56
int64_t av_rescale_rnd(int64_t a, int64_t b, int64_t c, enum AVRounding rnd)
Rescale a 64-bit integer with specified rounding.
Definition: mathematics.c:58
static void error(const char *err)
int in_sample_rate
input sample rate
Definition: internal.h:58
int format
format of the frame, -1 if unknown or unset Values correspond to enum AVPixelFormat for video frames...
Definition: frame.h:368
int avresample_is_open(AVAudioResampleContext *avr)
Definition: utils.c:257
void ff_audio_resample_free(ResampleContext **c)
Free a ResampleContext.
Definition: resample.c:224
AVSampleFormat
Audio sample formats.
Definition: samplefmt.h:58
AVAudioFifo * out_fifo
FIFO for output samples.
Definition: internal.h:91
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
Definition: frame.h:326
int avresample_set_channel_mapping(AVAudioResampleContext *avr, const int *channel_map)
Definition: utils.c:697
#define AVRESAMPLE_MAX_CHANNELS
Definition: avresample.h:104
enum AVSampleFormat internal_sample_fmt
internal sample format
Definition: internal.h:62
int force_resampling
force resampling
Definition: internal.h:68
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
Definition: internal.h:86
uint8_t pi<< 24) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_U8, uint8_t,(*(const uint8_t *) pi-0x80)*(1.0f/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_U8, uint8_t,(*(const uint8_t *) pi-0x80)*(1.0/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S16, int16_t,(*(const int16_t *) pi >> 8)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S16, int16_t,*(const int16_t *) pi *(1.0f/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S16, int16_t,*(const int16_t *) pi *(1.0/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S32, int32_t,(*(const int32_t *) pi >> 24)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S32, int32_t,*(const int32_t *) pi *(1.0f/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S32, int32_t,*(const int32_t *) pi *(1.0/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_FLT, float, av_clip_uint8(lrintf(*(const float *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_FLT, float, av_clip_int16(lrintf(*(const float *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_FLT, float, av_clipl_int32(llrintf(*(const float *) pi *(1U<< 31)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_DBL, double, av_clip_uint8(lrint(*(const double *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_DBL, double, av_clip_int16(lrint(*(const double *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_DBL, double, av_clipl_int32(llrint(*(const double *) pi *(1U<< 31))))#define SET_CONV_FUNC_GROUP(ofmt, ifmt) static void set_generic_function(AudioConvert *ac){}void ff_audio_convert_free(AudioConvert **ac){if(!*ac) return;ff_dither_free(&(*ac) ->dc);av_freep(ac);}AudioConvert *ff_audio_convert_alloc(AVAudioResampleContext *avr, enum AVSampleFormat out_fmt, enum AVSampleFormat in_fmt, int channels, int sample_rate, int apply_map){AudioConvert *ac;int in_planar, out_planar;ac=av_mallocz(sizeof(*ac));if(!ac) return NULL;ac->avr=avr;ac->out_fmt=out_fmt;ac->in_fmt=in_fmt;ac->channels=channels;ac->apply_map=apply_map;if(avr->dither_method!=AV_RESAMPLE_DITHER_NONE &&av_get_packed_sample_fmt(out_fmt)==AV_SAMPLE_FMT_S16 &&av_get_bytes_per_sample(in_fmt) > 2){ac->dc=ff_dither_alloc(avr, out_fmt, in_fmt, channels, sample_rate, apply_map);if(!ac->dc){av_free(ac);return NULL;}return ac;}in_planar=ff_sample_fmt_is_planar(in_fmt, channels);out_planar=ff_sample_fmt_is_planar(out_fmt, channels);if(in_planar==out_planar){ac->func_type=CONV_FUNC_TYPE_FLAT;ac->planes=in_planar?ac->channels:1;}else if(in_planar) ac->func_type=CONV_FUNC_TYPE_INTERLEAVE;else ac->func_type=CONV_FUNC_TYPE_DEINTERLEAVE;set_generic_function(ac);if(ARCH_AARCH64) ff_audio_convert_init_aarch64(ac);if(ARCH_ARM) ff_audio_convert_init_arm(ac);if(ARCH_X86) ff_audio_convert_init_x86(ac);return ac;}int ff_audio_convert(AudioConvert *ac, AudioData *out, AudioData *in){int use_generic=1;int len=in->nb_samples;int p;if(ac->dc){av_log(ac->avr, AV_LOG_TRACE,"%d samples - audio_convert: %s to %s (dithered)\n", len, av_get_sample_fmt_name(ac->in_fmt), av_get_sample_fmt_name(ac->out_fmt));return ff_convert_dither(ac-> in
int sample_rate
Sample rate of the audio data.
Definition: frame.h:467
ResampleContext * ff_audio_resample_init(AVAudioResampleContext *avr)
Allocate and initialize a ResampleContext.
Definition: resample.c:120
enum AVSampleFormat in_sample_fmt
input sample format
Definition: internal.h:57
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
and forward the test the status of outputs and forward it to the corresponding return FFERROR_NOT_READY If the filters stores internally one or a few frame for some input
int in_convert_needed
input sample format conversion is needed
Definition: internal.h:84
int av_frame_get_buffer(AVFrame *frame, int align)
Allocate new buffer(s) for audio or video data.
Definition: frame.c:324
int channel_map[AVRESAMPLE_MAX_CHANNELS]
source index of each output channel, -1 if not remapped
Definition: internal.h:44
int av_get_bytes_per_sample(enum AVSampleFormat sample_fmt)
Return number of bytes per sample.
Definition: samplefmt.c:106
#define AVERROR_OUTPUT_CHANGED
Output changed between calls. Reconfiguration is required. (can be OR-ed with AVERROR_INPUT_CHANGED) ...
Definition: error.h:74
enum AVSampleFormat out_sample_fmt
output sample format
Definition: internal.h:60
int av_audio_fifo_drain(AVAudioFifo *af, int nb_samples)
Drain data from an AVAudioFifo.
Definition: audio_fifo.c:201
int ff_audio_data_copy(AudioData *dst, AudioData *src, ChannelMapInfo *map)
Copy data from one AudioData to another.
Definition: audio_data.c:225
GLint GLenum GLboolean GLsizei stride
Definition: opengl_enc.c:104
void av_opt_free(void *obj)
Free all allocated objects in obj.
Definition: opt.c:1558
common internal and external API header
int resample_channels
number of channels used for resampling
Definition: internal.h:79
AudioData * resample_out_buffer
buffer for output from resampler
Definition: internal.h:89
int resample_needed
resampling is needed
Definition: internal.h:83
int do_copy
copy needed
Definition: internal.h:47
AudioMix * ff_audio_mix_alloc(AVAudioResampleContext *avr)
Allocate and initialize an AudioMix context.
Definition: audio_mix.c:341
void avresample_free(AVAudioResampleContext **avr)
Definition: utils.c:278
int allocated_samples
number of samples the buffer can hold
Definition: audio_data.h:42
FILE * out
Definition: movenc.c:54
Filter the word “frame” indicates either a video frame or a group of audio samples
#define av_freep(p)
int out_sample_rate
output sample rate
Definition: internal.h:61
void ff_audio_data_free(AudioData **a)
Free AudioData.
Definition: audio_data.c:217
signed 16 bits, planar
Definition: samplefmt.h:67
int downmix_needed
downmixing is needed
Definition: internal.h:80
static int available_samples(AVFrame *out)
Definition: utils.c:587
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame 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.Frame references ownership and permissions
uint8_t ** extended_data
pointers to the data planes/channels.
Definition: frame.h:342
int nb_samples
number of audio samples (per channel) described by this frame
Definition: frame.h:361
int mixing_needed
either upmixing or downmixing is needed
Definition: internal.h:82
int ff_audio_mix_get_matrix(AudioMix *am, double *matrix, int stride)
Get the current mixing matrix.
Definition: audio_mix.c:483