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
23 // #include "libavutil/error.h"
27
34
36 {
37 int ret;
38
39 /* set channel mixing parameters */
45 }
51 }
58
59 /* set resampling parameters */
62
63 /* select internal sample format if not specified by the user */
70 if (max_bps <= 2) {
74 } else {
75 if (max_bps <= 4) {
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 }
97 }
98
99 /* treat all mono as planar for easier comparison */
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:
254 return ret;
255 }
256
258 {
269
271 }
272
274 {
275 if (!*avr)
276 return;
280 }
281
284 {
285 int ret;
286
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);
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 */
303 av_dlog(avr,
"[FIFO] read from out_fifo to output\n");
304 av_dlog(avr,
"[end conversion]\n");
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);
316 if (ret < 0)
317 return ret;
318 av_dlog(avr,
"[end conversion]\n");
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 {
333 int ret, direct_output;
334
335 /* reset internal buffers */
340 }
345 }
350 }
351
352 av_dlog(avr,
"[start conversion]\n");
353
354 /* initialize output_buffer with output data */
356 if (output) {
360 if (ret < 0)
361 return ret;
363 }
364
365 if (input) {
366 /* initialize input_buffer with input data */
370 if (ret < 0)
371 return ret;
372 current_buffer = &input_buffer;
373
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);
382 if (ret < 0)
383 return ret;
384 current_buffer = &output_buffer;
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);
393 if (ret < 0)
394 return ret;
397 /* if needed, copy or convert input to in_buffer, and downmix if
398 applicable */
402 if (ret < 0)
403 return ret;
404 av_dlog(avr,
"[convert] %s to in_buffer\n", current_buffer->
name);
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);
414 if (ret < 0)
415 return ret;
416 }
419 av_dlog(avr,
"[downmix] in_buffer\n");
421 if (ret < 0)
422 return ret;
423 }
425 }
426 } else {
427 /* flush resampling buffer and/or output FIFO if input is NULL */
430 NULL);
431 current_buffer =
NULL;
432 }
433
436
438 resample_out = &output_buffer;
439 else
441 av_dlog(avr,
"[resample] %s to %s\n", current_buffer->
name,
444 current_buffer);
445 if (ret < 0)
446 return ret;
447
448 /* if resampling did not produce any samples, just return 0 */
450 av_dlog(avr,
"[end conversion]\n");
451 return 0;
452 }
453
454 current_buffer = resample_out;
455 }
456
458 av_dlog(avr,
"[upmix] %s\n", current_buffer->
name);
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");
468 }
469
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);
475 if (ret < 0)
476 return ret;
477
478 av_dlog(avr,
"[end conversion]\n");
480 } else {
483 if (ret < 0)
484 return ret;
485 av_dlog(avr,
"[convert] %s to out_buffer\n", current_buffer->
name);
487 current_buffer);
488 if (ret < 0)
489 return ret;
491 }
492 }
493
495 current_buffer);
496 }
497
500 {
501 int in_channels, out_channels, i, o;
502
505
508
513 }
514
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
529 {
530 int in_channels, out_channels, i, o;
531
534
537
542 }
543
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
568 }
569
570 memset(info, 0, sizeof(*info));
572
573 for (ch = 0; ch < in_channels; ch++) {
574 if (channel_map[ch] >= in_channels) {
577 }
578 if (channel_map[ch] < 0) {
582 }
else if (info->
input_map[channel_map[ch]] >= 0) {
586 } else {
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;
603 }
604
606 return 0;
607 }
608
610 {
612 }
613
615 {
616 if (!output)
619 }
620
622 {
624 }
625
627 {
628 #define LICENSE_PREFIX "libavresample license: "
630 }
631
633 {
634 return FFMPEG_CONFIGURATION;
635 }