1 /*
2 * Copyright (C) 2011-2013 Michael Niedermayer (michaelni@gmx.at)
3 *
4 * This file is part of libswresample
5 *
6 * libswresample 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 * libswresample 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 libswresample; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
26
27 #include <float.h>
28
30 #define C15DB 1.189207115
32 #define C_15DB 0.840896415
33 #define C_30DB M_SQRT1_2
34 #define C_45DB 0.594603558
36
38
39 //TODO split options array out?
40 #define OFFSET(x) offsetof(SwrContext,x)
41 #define PARAM AV_OPT_FLAG_AUDIO_PARAM
42
72
76
78
90
95
96 /* duplicate option in order to work with avconv */
98
102 {"precision" , "set soxr resampling precision (in bits)"
104 {"cheby" , "enable soxr Chebyshev passband & higher-precision irrational ratio approximation"
106 {"min_comp" , "set minimum difference between timestamps and audio data (in seconds) below which no timestamp compensation of either kind is applied"
108 {"min_hard_comp" , "set minimum difference between timestamps and audio data (in seconds) to trigger padding/trimming the data."
110 {"comp_duration" , "set duration (in seconds) over which data is stretched/squeezed to make it match the timestamps."
112 {"max_soft_comp" , "set maximum factor by which data is stretched/squeezed to make it match the timestamps."
114 {"async" , "simplified 1 parameter audio timestamp matching, 0(disabled), 1(filling and trimming), >1(maximum stretch/squeeze in samples per second)"
116 {"first_pts" , "Assume the first pts should be this value (in samples)."
118
123
128
130
132 {0}
133 };
134
136 return "SWR";
137 }
138
147 };
148
150 {
153 }
154
156 {
157 return FFMPEG_CONFIGURATION;
158 }
159
161 {
162 #define LICENSE_PREFIX "libswresample license: "
164 }
165
167 if(!s || s->
in_convert)
// s needs to be allocated but not initialized
170 return 0;
171 }
172
174 {
176 }
177
180 if(s){
183 }
185 }
186
190 int log_offset,
void *
log_ctx){
192 if(!s) return NULL;
193
196
208 }
209
214 }
215
218 memset(a, 0, sizeof(*a));
219 }
220
225 memset(s->
in.
ch, 0,
sizeof(s->
in.
ch));
239
241 }
242
245 if(s){
249 }
250
252 }
253
256
258
262 }
266 }
267
271 }
272
276 }
277
279 #if CONFIG_LIBSOXR
280 extern struct Resampler const soxr_resampler;
282 #endif
284 default:
287 }
288
291
293 av_log(s,
AV_LOG_WARNING,
"Input channel layout has a different number of channels than the number of used channels, ignoring layout\n");
294 s-> in_ch_layout= 0;
295 }
296
297 if(!s-> in_ch_layout)
301
304
315 }else{
318 }
319 }
320
327 }
328
331
337 } else
339
343 if (s->
async > 1.0001) {
345 }
346 }
347
349 s->
resample = s->
resampler->
init(s->
resample, s->
out_sample_rate, s->
in_sample_rate, s->
filter_size, s->
phase_shift, s->
linear_interp, s->
cutoff, s->
int_sample_fmt, s->
filter_type, s->
kaiser_beta, s->
precision, s->
cheby);
350 }else
358 return -1;
359 }
360
361 #define RSC 1 //FIXME finetune
368
369 if(!s->
in.ch_count){
372 return -1;
373 }
374
376 char l1[1024], l2[1024];
380 "but there is not enough information to do it\n", l1, l2);
381 return -1;
382 }
383
387
391
394 s-> in_sample_fmt, s->
in.ch_count, NULL, 0);
395 return 0;
396 }
397
402
405
409
415 }
420 }
421
425
428 }
429
432
435
436 return 0;
437 }
438
440 int i, countb;
442
445
446 if(a->
count >= count)
447 return 0;
448
449 count*=2;
450
453
456
463 }
467
468 return 1;
469 }
470
477 int ch;
479 memcpy(out->
ch[ch], in->
ch[ch], count*out->
bps);
480 }else
482 }
483
485 int i;
486 if(!in_arg){
487 memset(out->
ch, 0,
sizeof(out->
ch));
490 out->
ch[i]= in_arg[i];
491 }else{
493 out->
ch[i]= in_arg[0] + i*out->
bps;
494 }
495 }
496
498 int i;
501 in_arg[i]= out->
ch[i];
502 }else{
503 in_arg[0]= out->
ch[0];
504 }
505 }
506
507 /**
508 *
509 * out may be equal in.
510 */
512 int ch;
515 out->
ch[ch]= in->
ch[ch] + count*out->
bps;
516 }else{
517 for(ch=out->
ch_count-1; ch>=0; ch--)
519 }
520 }
521
522 /**
523 *
524 * @return number of samples output per channel
525 */
527 const AudioData * in_param,
int in_count){
529 int ret_sum=0;
530 int border=0;
532
536
537 tmp=out=*out_param;
538 in = *in_param;
539
540 do{
550
551 if(!in_count)
552 break;
558 border = 0;
559 }
560 }
561
568 in_count -= consumed;
570 }
571
572 //TODO is this check sane considering the advanced copy avoidance below
579 }else
582
583 if(in_count){
586
588 copy(&tmp, &in,
/*in_*/count);
595 continue;
596 if (padless) {
597 padless = 0;
598 continue;
599 }
600 }
601 break;
602 }while(1);
603
605
606 return ret_sum;
607 }
608
612 int ret /*, in_max*/;
614
618 return out_count;
619 }
620
621 // in_max= out_count*(int64_t)s->in_sample_rate / s->out_sample_rate + resample_filter_taps;
622 // in_count= FFMIN(in_count, in_in + 2 - s->hist_buffer_count);
623
630 }else{
634 }
637
639
641 midbuf= &midbuf_tmp;
643 preout= &preout_tmp;
644
647
649 midbuf= postin;
650
652 preout= midbuf;
653
656 if(preout==in){
657 out_count=
FFMIN(out_count, in_count);
//TODO check at the end if this is needed or redundant
658 av_assert0(s->
in.
planar);
//we only support planar internally so it has to be, we support copying non planar though
659 copy(out, in, out_count);
660 return out_count;
661 }
662 else if(preout==postin) preout= midbuf= postin=
out;
663 else if(preout==midbuf) preout= midbuf=
out;
665 }
666
667 if(in != postin){
669 }
670
672 if(postin != midbuf)
673 out_count=
resample(s, midbuf, out_count, postin, in_count);
674 if(midbuf != preout)
676 }else{
677 if(postin != midbuf)
679 if(midbuf != preout)
680 out_count=
resample(s, preout, out_count, midbuf, in_count);
681 }
682
683 if(preout != out && out_count){
686 int ch;
687 int dither_count=
FFMAX(out_count, 1<<16);
688
689 if (preout == in) {
693 }
694
697 if(ret)
701
704
707 int len1= out_count&~15;
708 int off = len1 * preout->
bps;
709
710 if(len1)
711 for(ch=0; ch<preout->
ch_count; ch++)
713 if(out_count != len1)
714 for(ch=0; ch<preout->
ch_count; ch++)
716 } else {
717 for(ch=0; ch<preout->
ch_count; ch++)
719 }
720 } else {
726 }
727 }
729 }
730 //FIXME packed doesn't need more than 1 chan here!
732 }
733 return out_count;
734 }
735
738 }
739
741 const uint8_t *in_arg [SWR_CH_MAX],
int in_count){
744
748 }
749
753 #define MAX_DROP_STEP 16384
756
758 s->
drop_output *= -1;
//FIXME find a less hackish solution
761 in_count = 0;
762 if(ret>0) {
764 continue;
765 }
766
768 return 0;
769 }
770
771 if(!in_arg){
778 return 0;
779 }
780 }else
782
784
789 return ret;
790 }else{
792 int ret2=0;
795 if(size){
798 if(ret<0)
807 }
808
809 if(in_count){
811
812 if(in_count > out_count) { //FIXME move after swr_convert_internal
818 }else
821 }
822
823 if(out_count){
824 size =
FFMIN(in_count, out_count);
826 if(ret<0)
831 }
832 if(in_count){
834 copy(&tmp, in, in_count);
836 }
837 }
840 return ret2;
841 }
842 }
843
846
848 return 0;
849
852 }
853
857
858 if(count <= 0)
859 return 0;
860
861 #define MAX_SILENCE_STEP 16384
866 }
867
870
873 } else
875
880 }
881
885 }else{
887 }
888 }
889
892
893 if (!s || compensation_distance < 0)
895 if (!compensation_distance && sample_delta)
900 if (ret < 0)
902 }
905 }else{
907 }
908 }
909
911 if(pts == INT64_MIN)
913
916
919 } else {
922
928 if(ret<0){
930 }
934 int comp = av_clipf(fdelta, -max_soft_compensation, max_soft_compensation) *
duration ;
935 av_log(s,
AV_LOG_VERBOSE,
"compensating audio timestamp drift:%f compensation:%d in:%d\n", fdelta, comp, duration);
937 }
938 }
939
941 }
942 }