annotate libaf/af_lavcresample.c @ 24900:9079c9745ff9

A/V sync: take audio filter buffers into account Substract the delay caused by filter buffering when calculating currently playing audio position. This matters for af_scaletempo which buffers significant and varying amounts of data. For other current filters the effect is normally insignificant. Instead of the old time-based filter delay field (which was ignored) this version stores the per-filter delay in units of bytes input read without corresponding output. This allows the current scaletempo behavior where other filters before and after it can see the same nominal samplerate even though the real duration of the data varies; in this case the other filters can not know the delay they're causing in terms of real time.
author uau
date Thu, 01 Nov 2007 06:52:50 +0000
parents b2402b4f0afa
children 867ee1c2114b
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
13713
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
1 // Copyright (c) 2004 Michael Niedermayer <michaelni@gmx.at>
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
2 // #inlcude <GPL_v2.h>
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
3
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
4 #include <stdio.h>
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
5 #include <stdlib.h>
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
6 #include <string.h>
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
7 #include <inttypes.h>
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
8
16982
a9da2db9eb16 Unify include paths by adding -I.. to CFLAGS.
diego
parents: 16168
diff changeset
9 #include "config.h"
13713
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
10 #include "af.h"
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
11
13859
1b0d5a6ab7dc libavcodec.so headers patch by (Glenn Washburn <glenniii at mail dot utexas dot edu>)
michael
parents: 13730
diff changeset
12 #ifdef USE_LIBAVCODEC_SO
1b0d5a6ab7dc libavcodec.so headers patch by (Glenn Washburn <glenniii at mail dot utexas dot edu>)
michael
parents: 13730
diff changeset
13 #include <ffmpeg/avcodec.h>
1b0d5a6ab7dc libavcodec.so headers patch by (Glenn Washburn <glenniii at mail dot utexas dot edu>)
michael
parents: 13730
diff changeset
14 #include <ffmpeg/rational.h>
1b0d5a6ab7dc libavcodec.so headers patch by (Glenn Washburn <glenniii at mail dot utexas dot edu>)
michael
parents: 13730
diff changeset
15 #else
16168
99c188fbdba4 libavutil compile fix (working also with old libavcodec)
reimar
parents: 16167
diff changeset
16 #include "avcodec.h"
99c188fbdba4 libavutil compile fix (working also with old libavcodec)
reimar
parents: 16167
diff changeset
17 #include "rational.h"
13859
1b0d5a6ab7dc libavcodec.so headers patch by (Glenn Washburn <glenniii at mail dot utexas dot edu>)
michael
parents: 13730
diff changeset
18 #endif
13713
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
19
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
20 // Data for specific instances of this filter
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
21 typedef struct af_resample_s{
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
22 struct AVResampleContext *avrctx;
22178
c4d9550c9faf Use AF_NCH for max number of channels instead of private CHANS define.
uau
parents: 17522
diff changeset
23 int16_t *in[AF_NCH];
13713
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
24 int in_alloc;
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
25 int index;
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
26
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
27 int filter_length;
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
28 int linear;
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
29 int phase_shift;
13730
a45e901cc870 user selectable cutoff frequency
michael
parents: 13713
diff changeset
30 double cutoff;
13713
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
31 }af_resample_t;
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
32
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
33
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
34 // Initialization and runtime control
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
35 static int control(struct af_instance_s* af, int cmd, void* arg)
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
36 {
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
37 af_resample_t* s = (af_resample_t*)af->setup;
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
38 af_data_t *data= (af_data_t*)arg;
14213
3c56b18bbb0c Make filters request a supported input format instead of failing.
reimar
parents: 14186
diff changeset
39 int out_rate, test_output_res; // helpers for checking input format
13713
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
40
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
41 switch(cmd){
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
42 case AF_CONTROL_REINIT:
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
43 if((af->data->rate == data->rate) || (af->data->rate == 0))
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
44 return AF_DETACH;
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
45
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
46 af->data->nch = data->nch;
22178
c4d9550c9faf Use AF_NCH for max number of channels instead of private CHANS define.
uau
parents: 17522
diff changeset
47 if (af->data->nch > AF_NCH) af->data->nch = AF_NCH;
14245
815f03b7cee5 removing AFMT_ dependancy
alex
parents: 14213
diff changeset
48 af->data->format = AF_FORMAT_S16_NE;
13713
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
49 af->data->bps = 2;
24888
b2402b4f0afa libaf: change filter input/output ratio calculations
uau
parents: 23623
diff changeset
50 af->mul = (double)af->data->rate / data->rate;
24900
9079c9745ff9 A/V sync: take audio filter buffers into account
uau
parents: 24888
diff changeset
51 af->delay = af->data->nch * s->filter_length / min(af->mul, 1); // *bps*.5
13713
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
52
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
53 if(s->avrctx) av_resample_close(s->avrctx);
24888
b2402b4f0afa libaf: change filter input/output ratio calculations
uau
parents: 23623
diff changeset
54 s->avrctx= av_resample_init(af->data->rate, /*in_rate*/data->rate, s->filter_length, s->phase_shift, s->linear, s->cutoff);
13713
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
55
14213
3c56b18bbb0c Make filters request a supported input format instead of failing.
reimar
parents: 14186
diff changeset
56 // hack to make af_test_output ignore the samplerate change
3c56b18bbb0c Make filters request a supported input format instead of failing.
reimar
parents: 14186
diff changeset
57 out_rate = af->data->rate;
3c56b18bbb0c Make filters request a supported input format instead of failing.
reimar
parents: 14186
diff changeset
58 af->data->rate = data->rate;
3c56b18bbb0c Make filters request a supported input format instead of failing.
reimar
parents: 14186
diff changeset
59 test_output_res = af_test_output(af, (af_data_t*)arg);
3c56b18bbb0c Make filters request a supported input format instead of failing.
reimar
parents: 14186
diff changeset
60 af->data->rate = out_rate;
3c56b18bbb0c Make filters request a supported input format instead of failing.
reimar
parents: 14186
diff changeset
61 return test_output_res;
13713
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
62 case AF_CONTROL_COMMAND_LINE:{
22755
dfe4db89562c reasonable cutoff frequency default
michael
parents: 22746
diff changeset
63 s->cutoff= 0.0;
13730
a45e901cc870 user selectable cutoff frequency
michael
parents: 13713
diff changeset
64 sscanf((char*)arg,"%d:%d:%d:%d:%lf", &af->data->rate, &s->filter_length, &s->linear, &s->phase_shift, &s->cutoff);
22755
dfe4db89562c reasonable cutoff frequency default
michael
parents: 22746
diff changeset
65 if(s->cutoff <= 0.0) s->cutoff= max(1.0 - 6.5/(s->filter_length+8), 0.80);
13713
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
66 return AF_OK;
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
67 }
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
68 case AF_CONTROL_RESAMPLE_RATE | AF_CONTROL_SET:
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
69 af->data->rate = *(int*)arg;
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
70 return AF_OK;
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
71 }
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
72 return AF_UNKNOWN;
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
73 }
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
74
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
75 // Deallocate memory
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
76 static void uninit(struct af_instance_s* af)
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
77 {
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
78 if(af->data)
22179
ecf562795caf Fix memory leaks.
uau
parents: 22178
diff changeset
79 free(af->data->audio);
ecf562795caf Fix memory leaks.
uau
parents: 22178
diff changeset
80 free(af->data);
13713
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
81 if(af->setup){
22182
c4fbdc3daed9 Move variable declaration to appropriate place
reimar
parents: 22181
diff changeset
82 int i;
13713
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
83 af_resample_t *s = af->setup;
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
84 if(s->avrctx) av_resample_close(s->avrctx);
22181
e99ebf35812b Cosmetics: remove tabs added in last commit from otherwise tab-free file.
reimar
parents: 22179
diff changeset
85 for (i=0; i < AF_NCH; i++)
e99ebf35812b Cosmetics: remove tabs added in last commit from otherwise tab-free file.
reimar
parents: 22179
diff changeset
86 free(s->in[i]);
13713
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
87 free(s);
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
88 }
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
89 }
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
90
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
91 // Filter data through filter
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
92 static af_data_t* play(struct af_instance_s* af, af_data_t* data)
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
93 {
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
94 af_resample_t *s = af->setup;
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
95 int i, j, consumed, ret;
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
96 int16_t *in = (int16_t*)data->audio;
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
97 int16_t *out;
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
98 int chans = data->nch;
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
99 int in_len = data->len/(2*chans);
24888
b2402b4f0afa libaf: change filter input/output ratio calculations
uau
parents: 23623
diff changeset
100 int out_len = in_len * af->mul + 10;
22178
c4d9550c9faf Use AF_NCH for max number of channels instead of private CHANS define.
uau
parents: 17522
diff changeset
101 int16_t tmp[AF_NCH][out_len];
13713
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
102
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
103 if(AF_OK != RESIZE_LOCAL_BUFFER(af,data))
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
104 return NULL;
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
105
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
106 out= (int16_t*)af->data->audio;
13730
a45e901cc870 user selectable cutoff frequency
michael
parents: 13713
diff changeset
107
a45e901cc870 user selectable cutoff frequency
michael
parents: 13713
diff changeset
108 out_len= min(out_len, af->data->len/(2*chans));
a45e901cc870 user selectable cutoff frequency
michael
parents: 13713
diff changeset
109
13713
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
110 if(s->in_alloc < in_len + s->index){
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
111 s->in_alloc= in_len + s->index;
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
112 for(i=0; i<chans; i++){
22179
ecf562795caf Fix memory leaks.
uau
parents: 22178
diff changeset
113 s->in[i]= realloc(s->in[i], s->in_alloc*sizeof(int16_t));
13713
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
114 }
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
115 }
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
116
14283
91170dd147c6 faster packed<->planar conversation
michael
parents: 14245
diff changeset
117 if(chans==1){
91170dd147c6 faster packed<->planar conversation
michael
parents: 14245
diff changeset
118 memcpy(&s->in[0][s->index], in, in_len * sizeof(int16_t));
91170dd147c6 faster packed<->planar conversation
michael
parents: 14245
diff changeset
119 }else if(chans==2){
91170dd147c6 faster packed<->planar conversation
michael
parents: 14245
diff changeset
120 for(j=0; j<in_len; j++){
91170dd147c6 faster packed<->planar conversation
michael
parents: 14245
diff changeset
121 s->in[0][j + s->index]= *(in++);
91170dd147c6 faster packed<->planar conversation
michael
parents: 14245
diff changeset
122 s->in[1][j + s->index]= *(in++);
91170dd147c6 faster packed<->planar conversation
michael
parents: 14245
diff changeset
123 }
91170dd147c6 faster packed<->planar conversation
michael
parents: 14245
diff changeset
124 }else{
91170dd147c6 faster packed<->planar conversation
michael
parents: 14245
diff changeset
125 for(j=0; j<in_len; j++){
91170dd147c6 faster packed<->planar conversation
michael
parents: 14245
diff changeset
126 for(i=0; i<chans; i++){
91170dd147c6 faster packed<->planar conversation
michael
parents: 14245
diff changeset
127 s->in[i][j + s->index]= *(in++);
91170dd147c6 faster packed<->planar conversation
michael
parents: 14245
diff changeset
128 }
13713
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
129 }
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
130 }
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
131 in_len += s->index;
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
132
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
133 for(i=0; i<chans; i++){
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
134 ret= av_resample(s->avrctx, tmp[i], s->in[i], &consumed, in_len, out_len, i+1 == chans);
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
135 }
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
136 out_len= ret;
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
137
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
138 s->index= in_len - consumed;
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
139 for(i=0; i<chans; i++){
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
140 memmove(s->in[i], s->in[i] + consumed, s->index*sizeof(int16_t));
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
141 }
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
142
14283
91170dd147c6 faster packed<->planar conversation
michael
parents: 14245
diff changeset
143 if(chans==1){
91170dd147c6 faster packed<->planar conversation
michael
parents: 14245
diff changeset
144 memcpy(out, tmp[0], out_len*sizeof(int16_t));
91170dd147c6 faster packed<->planar conversation
michael
parents: 14245
diff changeset
145 }else if(chans==2){
91170dd147c6 faster packed<->planar conversation
michael
parents: 14245
diff changeset
146 for(j=0; j<out_len; j++){
91170dd147c6 faster packed<->planar conversation
michael
parents: 14245
diff changeset
147 *(out++)= tmp[0][j];
91170dd147c6 faster packed<->planar conversation
michael
parents: 14245
diff changeset
148 *(out++)= tmp[1][j];
91170dd147c6 faster packed<->planar conversation
michael
parents: 14245
diff changeset
149 }
91170dd147c6 faster packed<->planar conversation
michael
parents: 14245
diff changeset
150 }else{
91170dd147c6 faster packed<->planar conversation
michael
parents: 14245
diff changeset
151 for(j=0; j<out_len; j++){
91170dd147c6 faster packed<->planar conversation
michael
parents: 14245
diff changeset
152 for(i=0; i<chans; i++){
91170dd147c6 faster packed<->planar conversation
michael
parents: 14245
diff changeset
153 *(out++)= tmp[i][j];
91170dd147c6 faster packed<->planar conversation
michael
parents: 14245
diff changeset
154 }
13713
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
155 }
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
156 }
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
157
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
158 data->audio = af->data->audio;
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
159 data->len = out_len*chans*2;
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
160 data->rate = af->data->rate;
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
161 return data;
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
162 }
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
163
22746
fd6f824ef894 Rename open to af_open so as not to conflict with a previous header definition.
diego
parents: 22182
diff changeset
164 static int af_open(af_instance_t* af){
14186
5053490906c3 Initialize cutoff, too. Fixes crash when AF_CONTROL_COMMAND_LINE is not set.
reimar
parents: 13859
diff changeset
165 af_resample_t *s = calloc(1,sizeof(af_resample_t));
13713
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
166 af->control=control;
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
167 af->uninit=uninit;
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
168 af->play=play;
24888
b2402b4f0afa libaf: change filter input/output ratio calculations
uau
parents: 23623
diff changeset
169 af->mul=1;
13713
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
170 af->data=calloc(1,sizeof(af_data_t));
14186
5053490906c3 Initialize cutoff, too. Fixes crash when AF_CONTROL_COMMAND_LINE is not set.
reimar
parents: 13859
diff changeset
171 s->filter_length= 16;
22755
dfe4db89562c reasonable cutoff frequency default
michael
parents: 22746
diff changeset
172 s->cutoff= max(1.0 - 6.5/(s->filter_length+8), 0.80);
14186
5053490906c3 Initialize cutoff, too. Fixes crash when AF_CONTROL_COMMAND_LINE is not set.
reimar
parents: 13859
diff changeset
173 s->phase_shift= 10;
5053490906c3 Initialize cutoff, too. Fixes crash when AF_CONTROL_COMMAND_LINE is not set.
reimar
parents: 13859
diff changeset
174 // s->setup = RSMP_INT | FREQ_SLOPPY;
5053490906c3 Initialize cutoff, too. Fixes crash when AF_CONTROL_COMMAND_LINE is not set.
reimar
parents: 13859
diff changeset
175 af->setup=s;
13713
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
176 return AF_OK;
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
177 }
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
178
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
179 af_info_t af_info_lavcresample = {
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
180 "Sample frequency conversion using libavcodec",
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
181 "lavcresample",
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
182 "Michael Niedermayer",
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
183 "",
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
184 AF_FLAGS_REENTRANT,
22746
fd6f824ef894 Rename open to af_open so as not to conflict with a previous header definition.
diego
parents: 22182
diff changeset
185 af_open
13713
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
186 };