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
223 if(s){
238 }
239
241 }
242
256 memset(s->
in.
ch, 0,
sizeof(s->
in.
ch));
262
264
268 }
272 }
273
277 }
278
282 }
283
285 #if CONFIG_LIBSOXR
286 extern struct Resampler const soxr_resampler;
288 #endif
290 default:
293 }
294
297
299 av_log(s,
AV_LOG_WARNING,
"Input channel layout has a different number of channels than the number of used channels, ignoring layout\n");
300 s-> in_ch_layout= 0;
301 }
302
303 if(!s-> in_ch_layout)
307
310
321 }else{
324 }
325 }
326
333 }
334
337
343 } else
345
349 if (s->
async > 1.0001) {
351 }
352 }
353
355 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);
356 }else
364 return -1;
365 }
366
367 #define RSC 1 //FIXME finetune
374
375 if(!s->
in.ch_count){
378 return -1;
379 }
380
382 char l1[1024], l2[1024];
386 "but there is not enough information to do it\n", l1, l2);
387 return -1;
388 }
389
393
397
400 s-> in_sample_fmt, s->
in.ch_count, NULL, 0);
401 return 0;
402 }
403
408
411
415
421 }
426 }
427
431
434 }
435
438
441
442 return 0;
443 }
444
446 int i, countb;
448
449 if(count < 0 || count > INT_MAX/2/a->
bps/a->
ch_count)
451
452 if(a->
count >= count)
453 return 0;
454
455 count*=2;
456
459
462
469 }
473
474 return 1;
475 }
476
483 int ch;
485 memcpy(out->
ch[ch], in->
ch[ch], count*out->
bps);
486 }else
488 }
489
491 int i;
492 if(!in_arg){
493 memset(out->
ch, 0,
sizeof(out->
ch));
496 out->
ch[i]= in_arg[i];
497 }else{
499 out->
ch[i]= in_arg[0] + i*out->
bps;
500 }
501 }
502
504 int i;
507 in_arg[i]= out->
ch[i];
508 }else{
509 in_arg[0]= out->
ch[0];
510 }
511 }
512
513 /**
514 *
515 * out may be equal in.
516 */
518 int ch;
521 out->
ch[ch]= in->
ch[ch] + count*out->
bps;
522 }else{
523 for(ch=out->
ch_count-1; ch>=0; ch--)
525 }
526 }
527
528 /**
529 *
530 * @return number of samples output per channel
531 */
533 const AudioData * in_param,
int in_count){
535 int ret_sum=0;
536 int border=0;
537
541
542 tmp=out=*out_param;
543 in = *in_param;
544
545 do{
555
556 if(!in_count)
557 break;
563 border = 0;
564 }
565 }
566
573 in_count -= consumed;
575 }
576
577 //TODO is this check sane considering the advanced copy avoidance below
584 }else
587
588 if(in_count){
591
593 copy(&tmp, &in,
/*in_*/count);
600 continue;
601 }
602 break;
603 }while(1);
604
606
607 return ret_sum;
608 }
609
613 int ret /*, in_max*/;
615
619 return out_count;
620 }
621
622 // in_max= out_count*(int64_t)s->in_sample_rate / s->out_sample_rate + resample_filter_taps;
623 // in_count= FFMIN(in_count, in_in + 2 - s->hist_buffer_count);
624
631 }else{
635 }
638
640
642 midbuf= &midbuf_tmp;
644 preout= &preout_tmp;
645
648
650 midbuf= postin;
651
653 preout= midbuf;
654
657 if(preout==in){
658 out_count=
FFMIN(out_count, in_count);
//TODO check at the end if this is needed or redundant
659 av_assert0(s->
in.
planar);
//we only support planar internally so it has to be, we support copying non planar though
660 copy(out, in, out_count);
661 return out_count;
662 }
663 else if(preout==postin) preout= midbuf= postin=
out;
664 else if(preout==midbuf) preout= midbuf=
out;
666 }
667
668 if(in != postin){
670 }
671
673 if(postin != midbuf)
674 out_count=
resample(s, midbuf, out_count, postin, in_count);
675 if(midbuf != preout)
677 }else{
678 if(postin != midbuf)
680 if(midbuf != preout)
681 out_count=
resample(s, preout, out_count, midbuf, in_count);
682 }
683
684 if(preout != out && out_count){
687 int ch;
688 int dither_count=
FFMAX(out_count, 1<<16);
689
690 if (preout == in) {
694 }
695
698 if(ret)
702
705
708 int len1= out_count&~15;
709 int off = len1 * preout->
bps;
710
711 if(len1)
712 for(ch=0; ch<preout->
ch_count; ch++)
714 if(out_count != len1)
715 for(ch=0; ch<preout->
ch_count; ch++)
717 } else {
718 for(ch=0; ch<preout->
ch_count; ch++)
720 }
721 } else {
727 }
728 }
730 }
731 //FIXME packed doesn't need more than 1 chan here!
733 }
734 return out_count;
735 }
736
738 const uint8_t *in_arg [SWR_CH_MAX],
int in_count){
741
745 #define MAX_DROP_STEP 16384
748
750 s->
drop_output *= -1;
//FIXME find a less hackish solution
753 in_count = 0;
754 if(ret>0) {
756 continue;
757 }
758
760 return 0;
761 }
762
763 if(!in_arg){
770 return 0;
771 }
772 }else
774
776
781 return ret;
782 }else{
784 int ret2=0;
787 if(size){
790 if(ret<0)
799 }
800
801 if(in_count){
803
804 if(in_count > out_count) { //FIXME move after swr_convert_internal
810 }else
813 }
814
815 if(out_count){
816 size =
FFMIN(in_count, out_count);
818 if(ret<0)
823 }
824 if(in_count){
826 copy(&tmp, in, in_count);
828 }
829 }
832 return ret2;
833 }
834 }
835
838
840 return 0;
841
844 }
845
849
850 if(count <= 0)
851 return 0;
852
853 #define MAX_SILENCE_STEP 16384
858 }
859
862
865 } else
867
872 }
873
877 }else{
879 }
880 }
881
884
885 if (!s || compensation_distance < 0)
887 if (!compensation_distance && sample_delta)
892 if (ret < 0)
894 }
897 }else{
899 }
900 }
901
903 if(pts == INT64_MIN)
905
908
911 } else {
914
920 if(ret<0){
922 }
926 int comp = av_clipf(fdelta, -max_soft_compensation, max_soft_compensation) *
duration ;
927 av_log(s,
AV_LOG_VERBOSE,
"compensating audio timestamp drift:%f compensation:%d in:%d\n", fdelta, comp, duration);
929 }
930 }
931
933 }
934 }