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
23 // #include "libavutil/error.h"
28
35
37 {
39
43 }
44
45 /* set channel mixing parameters */
51 }
57 }
64
65 /* set resampling parameters */
68
69 /* select internal sample format if not specified by the user */
76 if (max_bps <= 2) {
80 } else {
81 if (max_bps <= 4) {
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 }
103 }
104
105 /* we may need to add an extra conversion in order to remap channels if
106 the output format is not planar */
110 }
111
112 /* set sample format conversion parameters */
115 else
118
121 else
123
126
130 av_dlog(avr,
"remap channels during in_copy\n");
133 av_dlog(avr,
"remap channels during in_convert\n");
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;
149 else
156 else
163 else
170 }
171 #endif
172 } else
174
175 /* allocate buffers */
179 "in_buffer");
182 goto error;
183 }
184 }
188 "resample_out_buffer");
191 goto error;
192 }
193 }
199 goto error;
200 }
201 }
203 1024);
206 goto error;
207 }
208
209 /* setup contexts */
217 goto error;
218 }
219 }
224 else
232 goto error;
233 }
234 }
239 goto error;
240 }
241 }
246 goto error;
247 }
248 }
249
250 return 0;
251
252 error:
255 }
256
258 {
260 }
261
263 {
274
276 }
277
279 {
280 if (!*avr)
281 return;
285 }
286
289 {
291
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_dlog(avr,
"[FIFO] add %s to out_fifo\n", converted->
name);
301 if (ret < 0)
303 }
304
305 /* if the user specified an output buffer, read samples from the output
306 FIFO to the user output */
308 av_dlog(avr,
"[FIFO] read from out_fifo to output\n");
309 av_dlog(avr,
"[end conversion]\n");
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_dlog(avr,
"[copy] %s to output\n", converted->
name);
321 if (ret < 0)
323 av_dlog(avr,
"[end conversion]\n");
325 }
326 av_dlog(avr,
"[end conversion]\n");
327 return 0;
328 }
329
331 uint8_t **output,
int out_plane_size,
332 int out_samples,
uint8_t **input,
333 int in_plane_size, int in_samples)
334 {
338 int ret, direct_output;
339
340 /* reset internal buffers */
345 }
350 }
355 }
356
357 av_dlog(avr,
"[start conversion]\n");
358
359 /* initialize output_buffer with output data */
361 if (output) {
365 if (ret < 0)
368 }
369
370 if (input) {
371 /* initialize input_buffer with input data */
375 if (ret < 0)
377 current_buffer = &input_buffer;
378
381 /* in some rare cases we can copy input to output and upmix
382 directly in the output buffer */
383 av_dlog(avr,
"[copy] %s to output\n", current_buffer->
name);
387 if (ret < 0)
389 current_buffer = &output_buffer;
391 (!direct_output || out_samples < in_samples)) {
392 /* if remapping channels during output copy, we may need to
393 * use an intermediate buffer in order to remap before adding
394 * samples to the output fifo */
395 av_dlog(avr,
"[copy] %s to out_buffer\n", current_buffer->
name);
398 if (ret < 0)
402 /* if needed, copy or convert input to in_buffer, and downmix if
403 applicable */
407 if (ret < 0)
409 av_dlog(avr,
"[convert] %s to in_buffer\n", current_buffer->
name);
411 current_buffer);
412 if (ret < 0)
414 } else {
415 av_dlog(avr,
"[copy] %s to in_buffer\n", current_buffer->
name);
419 if (ret < 0)
421 }
424 av_dlog(avr,
"[downmix] in_buffer\n");
426 if (ret < 0)
428 }
430 }
431 } else {
432 /* flush resampling buffer and/or output FIFO if input is NULL */
435 NULL);
436 current_buffer =
NULL;
437 }
438
441
443 resample_out = &output_buffer;
444 else
446 av_dlog(avr,
"[resample] %s to %s\n",
447 current_buffer ? current_buffer->
name :
"null",
450 current_buffer);
451 if (ret < 0)
453
454 /* if resampling did not produce any samples, just return 0 */
456 av_dlog(avr,
"[end conversion]\n");
457 return 0;
458 }
459
460 current_buffer = resample_out;
461 }
462
464 av_dlog(avr,
"[upmix] %s\n", current_buffer->
name);
466 if (ret < 0)
468 }
469
470 /* if we resampled or upmixed directly to output, return here */
471 if (current_buffer == &output_buffer) {
472 av_dlog(avr,
"[end conversion]\n");
474 }
475
477 if (direct_output && out_samples >= current_buffer->
nb_samples) {
478 /* convert directly to output */
479 av_dlog(avr,
"[convert] %s to output\n", current_buffer->
name);
481 if (ret < 0)
483
484 av_dlog(avr,
"[end conversion]\n");
486 } else {
489 if (ret < 0)
491 av_dlog(avr,
"[convert] %s to out_buffer\n", current_buffer->
name);
493 current_buffer);
494 if (ret < 0)
497 }
498 }
499
501 current_buffer);
502 }
503
505 {
508 }
509
510 if (in) {
514 }
515
516 if (out) {
520 }
521
522 return 0;
523 }
524
527 {
529
530 if (in) {
535 }
536 }
537
538 if (out) {
543 }
544 }
545
547 }
548
551 {
554 int out_linesize = 0, in_linesize = 0;
555 int out_nb_samples = 0, in_nb_samples = 0;
556
557 if (out) {
561 }
562
563 if (in) {
567 }
568
570 out_nb_samples,
571 in_data, in_linesize,
572 in_nb_samples);
573
574 if (ret < 0) {
575 if (out)
578 }
579
580 if (out)
582
583 return 0;
584 }
585
587 {
588 int samples;
590 if (!bytes_per_sample)
592
593 samples = out->
linesize[0] / bytes_per_sample;
595 return samples;
596 } else {
598 return samples / channels;
599 }
600 }
601
604 {
606
612 setup = 1;
613 } else {
614 // return as is or reconfigure for input changes?
617 }
618
619 if (out) {
623 if (setup)
626 }
627 } else {
630 }
631 }
632
634 }
635
638 {
639 int in_channels, out_channels, i, o;
640
643
646
651 }
652
656 }
657
658 for (o = 0; o < out_channels; o++)
659 for (i = 0; i < in_channels; i++)
660 matrix[o * stride + i] = avr->
mix_matrix[o * in_channels + i];
661
662 return 0;
663 }
664
667 {
668 int in_channels, out_channels, i, o;
669
672
675
680 }
681
688
689 for (o = 0; o < out_channels; o++)
690 for (i = 0; i < in_channels; i++)
691 avr->
mix_matrix[o * in_channels + i] = matrix[o * stride + i];
692
693 return 0;
694 }
695
697 const int *channel_map)
698 {
700 int in_channels, ch, i;
701
706 }
707
708 memset(info, 0, sizeof(*info));
710
711 for (ch = 0; ch < in_channels; ch++) {
712 if (channel_map[ch] >= in_channels) {
715 }
716 if (channel_map[ch] < 0) {
720 }
else if (info->
input_map[channel_map[ch]] >= 0) {
724 } else {
728 }
729 }
730 /* Fill-in unmapped input channels with unmapped output channels.
731 This is used when remapping during conversion from interleaved to
732 planar format. */
733 for (ch = 0, i = 0; ch < in_channels && i < in_channels; ch++, i++) {
734 while (ch < in_channels && info->input_map[ch] >= 0)
735 ch++;
736 while (i < in_channels && info->channel_map[i] >= 0)
737 i++;
738 if (ch >= in_channels || i >= in_channels)
739 break;
741 }
742
744 return 0;
745 }
746
748 {
750 }
751
753 {
755
761 }
762
764
765 if (samples > INT_MAX)
767
768 return samples;
769 }
770
772 {
773 if (!output)
776 }
777
779 {
781 }
782
784 {
785 #define LICENSE_PREFIX "libavresample license: "
787 }
788
790 {
791 return FFMPEG_CONFIGURATION;
792 }