1 // Copyright (c) 2004 Michael Niedermayer <michaelni@gmx.at>
14 #ifdef USE_LIBAVCODEC_SO
15 #include <ffmpeg/avcodec.h>
16 #include <ffmpeg/rational.h>
18 #include "../libavcodec/avcodec.h"
19 #include "../libavcodec/rational.h"
24 int64_t ff_gcd(int64_t a
, int64_t b
);
26 // Data for specific instances of this filter
27 typedef struct af_resample_s
{
28 struct AVResampleContext
*avrctx
;
40 // Initialization and runtime control
41 static int control(struct af_instance_s
* af
, int cmd
, void* arg
)
43 af_resample_t
* s
= (af_resample_t
*)af
->setup
;
44 af_data_t
*data
= (af_data_t
*)arg
;
45 int out_rate
, test_output_res
; // helpers for checking input format
48 case AF_CONTROL_REINIT
:
49 if((af
->data
->rate
== data
->rate
) || (af
->data
->rate
== 0))
52 af
->data
->nch
= data
->nch
;
53 if (af
->data
->nch
> CHANS
) af
->data
->nch
= CHANS
;
54 af
->data
->format
= AF_FORMAT_S16_NE
;
56 af
->mul
.n
= af
->data
->rate
;
57 af
->mul
.d
= data
->rate
;
58 af_frac_cancel(&af
->mul
);
59 af
->delay
= 500*s
->filter_length
/(double)min(af
->data
->rate
, data
->rate
);
61 if(s
->avrctx
) av_resample_close(s
->avrctx
);
62 s
->avrctx
= av_resample_init(af
->mul
.n
, /*in_rate*/af
->mul
.d
, s
->filter_length
, s
->phase_shift
, s
->linear
, s
->cutoff
);
64 // hack to make af_test_output ignore the samplerate change
65 out_rate
= af
->data
->rate
;
66 af
->data
->rate
= data
->rate
;
67 test_output_res
= af_test_output(af
, (af_data_t
*)arg
);
68 af
->data
->rate
= out_rate
;
69 return test_output_res
;
70 case AF_CONTROL_COMMAND_LINE
:{
71 sscanf((char*)arg
,"%d:%d:%d:%d:%lf", &af
->data
->rate
, &s
->filter_length
, &s
->linear
, &s
->phase_shift
, &s
->cutoff
);
72 if(s
->cutoff
<= 0.0) s
->cutoff
= max(1.0 - 1.0/s
->filter_length
, 0.80);
75 case AF_CONTROL_RESAMPLE_RATE
| AF_CONTROL_SET
:
76 af
->data
->rate
= *(int*)arg
;
83 static void uninit(struct af_instance_s
* af
)
88 af_resample_t
*s
= af
->setup
;
89 if(s
->avrctx
) av_resample_close(s
->avrctx
);
94 // Filter data through filter
95 static af_data_t
* play(struct af_instance_s
* af
, af_data_t
* data
)
97 af_resample_t
*s
= af
->setup
;
98 int i
, j
, consumed
, ret
;
99 int16_t *in
= (int16_t*)data
->audio
;
101 int chans
= data
->nch
;
102 int in_len
= data
->len
/(2*chans
);
103 int out_len
= (in_len
*af
->mul
.n
) / af
->mul
.d
+ 10;
104 int16_t tmp
[CHANS
][out_len
];
106 if(AF_OK
!= RESIZE_LOCAL_BUFFER(af
,data
))
109 out
= (int16_t*)af
->data
->audio
;
111 out_len
= min(out_len
, af
->data
->len
/(2*chans
));
113 if(s
->in_alloc
< in_len
+ s
->index
){
114 s
->in_alloc
= in_len
+ s
->index
;
115 for(i
=0; i
<chans
; i
++){
116 s
->in
[i
]= realloc(s
->in
[i
], s
->in_alloc
*sizeof(int16_t)); //FIXME free this maybe ;)
121 memcpy(&s
->in
[0][s
->index
], in
, in_len
* sizeof(int16_t));
123 for(j
=0; j
<in_len
; j
++){
124 s
->in
[0][j
+ s
->index
]= *(in
++);
125 s
->in
[1][j
+ s
->index
]= *(in
++);
128 for(j
=0; j
<in_len
; j
++){
129 for(i
=0; i
<chans
; i
++){
130 s
->in
[i
][j
+ s
->index
]= *(in
++);
136 for(i
=0; i
<chans
; i
++){
137 ret
= av_resample(s
->avrctx
, tmp
[i
], s
->in
[i
], &consumed
, in_len
, out_len
, i
+1 == chans
);
141 s
->index
= in_len
- consumed
;
142 for(i
=0; i
<chans
; i
++){
143 memmove(s
->in
[i
], s
->in
[i
] + consumed
, s
->index
*sizeof(int16_t));
147 memcpy(out
, tmp
[0], out_len
*sizeof(int16_t));
149 for(j
=0; j
<out_len
; j
++){
154 for(j
=0; j
<out_len
; j
++){
155 for(i
=0; i
<chans
; i
++){
161 data
->audio
= af
->data
->audio
;
162 data
->len
= out_len
*chans
*2;
163 data
->rate
= af
->data
->rate
;
167 static int open(af_instance_t
* af
){
168 af_resample_t
*s
= calloc(1,sizeof(af_resample_t
));
174 af
->data
=calloc(1,sizeof(af_data_t
));
175 s
->filter_length
= 16;
176 s
->cutoff
= max(1.0 - 1.0/s
->filter_length
, 0.80);
178 // s->setup = RSMP_INT | FREQ_SLOPPY;
183 af_info_t af_info_lavcresample
= {
184 "Sample frequency conversion using libavcodec",
186 "Michael Niedermayer",