annotate libaf/af_lavcresample.c @ 16805:50fb26acbcba

processing audio is sometimes essential for a/v sync, so 1000l to whoever made rawvideo muxer disable audio!! with this patch, audio is processed but simply thrown away by the muxer. various 'error' conditions in rawvideo muxer are removed to make it work. feel free to re-add them if they can be done without breaking anything, but do not use printf !!!! btw old behavior can be obtained by manually specifying -nosound.
author rfelker
date Wed, 19 Oct 2005 05:44:27 +0000
parents 99c188fbdba4
children a9da2db9eb16
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
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
9 #include "../config.h"
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
10 #include "af.h"
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
11
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
12 #ifdef USE_LIBAVCODEC
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
13
13859
1b0d5a6ab7dc libavcodec.so headers patch by (Glenn Washburn <glenniii at mail dot utexas dot edu>)
michael
parents: 13730
diff changeset
14 #ifdef USE_LIBAVCODEC_SO
1b0d5a6ab7dc libavcodec.so headers patch by (Glenn Washburn <glenniii at mail dot utexas dot edu>)
michael
parents: 13730
diff changeset
15 #include <ffmpeg/avcodec.h>
1b0d5a6ab7dc libavcodec.so headers patch by (Glenn Washburn <glenniii at mail dot utexas dot edu>)
michael
parents: 13730
diff changeset
16 #include <ffmpeg/rational.h>
1b0d5a6ab7dc libavcodec.so headers patch by (Glenn Washburn <glenniii at mail dot utexas dot edu>)
michael
parents: 13730
diff changeset
17 #else
16168
99c188fbdba4 libavutil compile fix (working also with old libavcodec)
reimar
parents: 16167
diff changeset
18 #include "avcodec.h"
99c188fbdba4 libavutil compile fix (working also with old libavcodec)
reimar
parents: 16167
diff changeset
19 #include "rational.h"
13859
1b0d5a6ab7dc libavcodec.so headers patch by (Glenn Washburn <glenniii at mail dot utexas dot edu>)
michael
parents: 13730
diff changeset
20 #endif
13713
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
21
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
22 #define CHANS 6
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
23
13730
a45e901cc870 user selectable cutoff frequency
michael
parents: 13713
diff changeset
24 int64_t ff_gcd(int64_t a, int64_t b);
a45e901cc870 user selectable cutoff frequency
michael
parents: 13713
diff changeset
25
13713
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
26 // Data for specific instances of this filter
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
27 typedef struct af_resample_s{
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
28 struct AVResampleContext *avrctx;
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
29 int16_t *in[CHANS];
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
30 int in_alloc;
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
31 int index;
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
32
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
33 int filter_length;
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
34 int linear;
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
35 int phase_shift;
13730
a45e901cc870 user selectable cutoff frequency
michael
parents: 13713
diff changeset
36 double cutoff;
13713
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
37 }af_resample_t;
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
38
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
39
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
40 // Initialization and runtime control
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
41 static int control(struct af_instance_s* af, int cmd, void* arg)
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
42 {
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
43 af_resample_t* s = (af_resample_t*)af->setup;
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
44 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
45 int out_rate, test_output_res; // helpers for checking input format
13713
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
46
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
47 switch(cmd){
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
48 case AF_CONTROL_REINIT:
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
49 if((af->data->rate == data->rate) || (af->data->rate == 0))
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
50 return AF_DETACH;
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
51
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
52 af->data->nch = data->nch;
14213
3c56b18bbb0c Make filters request a supported input format instead of failing.
reimar
parents: 14186
diff changeset
53 if (af->data->nch > CHANS) af->data->nch = CHANS;
14245
815f03b7cee5 removing AFMT_ dependancy
alex
parents: 14213
diff changeset
54 af->data->format = AF_FORMAT_S16_NE;
13713
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
55 af->data->bps = 2;
14433
95bb94a930a3 always cancel down fractions (frac_t) to avoid overflows and playback
reimar
parents: 14283
diff changeset
56 af->mul.n = af->data->rate;
95bb94a930a3 always cancel down fractions (frac_t) to avoid overflows and playback
reimar
parents: 14283
diff changeset
57 af->mul.d = data->rate;
95bb94a930a3 always cancel down fractions (frac_t) to avoid overflows and playback
reimar
parents: 14283
diff changeset
58 af_frac_cancel(&af->mul);
13730
a45e901cc870 user selectable cutoff frequency
michael
parents: 13713
diff changeset
59 af->delay = 500*s->filter_length/(double)min(af->data->rate, data->rate);
13713
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
60
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
61 if(s->avrctx) av_resample_close(s->avrctx);
13730
a45e901cc870 user selectable cutoff frequency
michael
parents: 13713
diff changeset
62 s->avrctx= av_resample_init(af->mul.n, /*in_rate*/af->mul.d, s->filter_length, s->phase_shift, s->linear, s->cutoff);
13713
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
63
14213
3c56b18bbb0c Make filters request a supported input format instead of failing.
reimar
parents: 14186
diff changeset
64 // 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
65 out_rate = af->data->rate;
3c56b18bbb0c Make filters request a supported input format instead of failing.
reimar
parents: 14186
diff changeset
66 af->data->rate = data->rate;
3c56b18bbb0c Make filters request a supported input format instead of failing.
reimar
parents: 14186
diff changeset
67 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
68 af->data->rate = out_rate;
3c56b18bbb0c Make filters request a supported input format instead of failing.
reimar
parents: 14186
diff changeset
69 return test_output_res;
13713
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
70 case AF_CONTROL_COMMAND_LINE:{
13730
a45e901cc870 user selectable cutoff frequency
michael
parents: 13713
diff changeset
71 sscanf((char*)arg,"%d:%d:%d:%d:%lf", &af->data->rate, &s->filter_length, &s->linear, &s->phase_shift, &s->cutoff);
a45e901cc870 user selectable cutoff frequency
michael
parents: 13713
diff changeset
72 if(s->cutoff <= 0.0) s->cutoff= max(1.0 - 1.0/s->filter_length, 0.80);
13713
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
73 return AF_OK;
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
74 }
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
75 case AF_CONTROL_RESAMPLE_RATE | AF_CONTROL_SET:
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
76 af->data->rate = *(int*)arg;
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
77 return AF_OK;
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
78 }
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
79 return AF_UNKNOWN;
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
80 }
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
81
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
82 // Deallocate memory
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
83 static void uninit(struct af_instance_s* af)
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
84 {
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
85 if(af->data)
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
86 free(af->data);
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
87 if(af->setup){
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
88 af_resample_t *s = af->setup;
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
89 if(s->avrctx) av_resample_close(s->avrctx);
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
90 free(s);
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
91 }
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
92 }
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
93
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
94 // Filter data through filter
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
95 static af_data_t* play(struct af_instance_s* af, af_data_t* data)
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
96 {
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
97 af_resample_t *s = af->setup;
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
98 int i, j, consumed, ret;
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
99 int16_t *in = (int16_t*)data->audio;
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
100 int16_t *out;
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
101 int chans = data->nch;
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
102 int in_len = data->len/(2*chans);
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
103 int out_len = (in_len*af->mul.n) / af->mul.d + 10;
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
104 int16_t tmp[CHANS][out_len];
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
105
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
106 if(AF_OK != RESIZE_LOCAL_BUFFER(af,data))
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
107 return NULL;
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
108
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
109 out= (int16_t*)af->data->audio;
13730
a45e901cc870 user selectable cutoff frequency
michael
parents: 13713
diff changeset
110
a45e901cc870 user selectable cutoff frequency
michael
parents: 13713
diff changeset
111 out_len= min(out_len, af->data->len/(2*chans));
a45e901cc870 user selectable cutoff frequency
michael
parents: 13713
diff changeset
112
13713
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
113 if(s->in_alloc < in_len + s->index){
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
114 s->in_alloc= in_len + s->index;
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
115 for(i=0; i<chans; i++){
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
116 s->in[i]= realloc(s->in[i], s->in_alloc*sizeof(int16_t)); //FIXME free this maybe ;)
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
117 }
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
118 }
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
119
14283
91170dd147c6 faster packed<->planar conversation
michael
parents: 14245
diff changeset
120 if(chans==1){
91170dd147c6 faster packed<->planar conversation
michael
parents: 14245
diff changeset
121 memcpy(&s->in[0][s->index], in, in_len * sizeof(int16_t));
91170dd147c6 faster packed<->planar conversation
michael
parents: 14245
diff changeset
122 }else if(chans==2){
91170dd147c6 faster packed<->planar conversation
michael
parents: 14245
diff changeset
123 for(j=0; j<in_len; j++){
91170dd147c6 faster packed<->planar conversation
michael
parents: 14245
diff changeset
124 s->in[0][j + s->index]= *(in++);
91170dd147c6 faster packed<->planar conversation
michael
parents: 14245
diff changeset
125 s->in[1][j + s->index]= *(in++);
91170dd147c6 faster packed<->planar conversation
michael
parents: 14245
diff changeset
126 }
91170dd147c6 faster packed<->planar conversation
michael
parents: 14245
diff changeset
127 }else{
91170dd147c6 faster packed<->planar conversation
michael
parents: 14245
diff changeset
128 for(j=0; j<in_len; j++){
91170dd147c6 faster packed<->planar conversation
michael
parents: 14245
diff changeset
129 for(i=0; i<chans; i++){
91170dd147c6 faster packed<->planar conversation
michael
parents: 14245
diff changeset
130 s->in[i][j + s->index]= *(in++);
91170dd147c6 faster packed<->planar conversation
michael
parents: 14245
diff changeset
131 }
13713
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
132 }
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
133 }
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
134 in_len += s->index;
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
135
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
136 for(i=0; i<chans; i++){
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
137 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
138 }
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
139 out_len= ret;
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
140
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
141 s->index= in_len - consumed;
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
142 for(i=0; i<chans; i++){
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
143 memmove(s->in[i], s->in[i] + consumed, s->index*sizeof(int16_t));
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
144 }
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
145
14283
91170dd147c6 faster packed<->planar conversation
michael
parents: 14245
diff changeset
146 if(chans==1){
91170dd147c6 faster packed<->planar conversation
michael
parents: 14245
diff changeset
147 memcpy(out, tmp[0], out_len*sizeof(int16_t));
91170dd147c6 faster packed<->planar conversation
michael
parents: 14245
diff changeset
148 }else if(chans==2){
91170dd147c6 faster packed<->planar conversation
michael
parents: 14245
diff changeset
149 for(j=0; j<out_len; j++){
91170dd147c6 faster packed<->planar conversation
michael
parents: 14245
diff changeset
150 *(out++)= tmp[0][j];
91170dd147c6 faster packed<->planar conversation
michael
parents: 14245
diff changeset
151 *(out++)= tmp[1][j];
91170dd147c6 faster packed<->planar conversation
michael
parents: 14245
diff changeset
152 }
91170dd147c6 faster packed<->planar conversation
michael
parents: 14245
diff changeset
153 }else{
91170dd147c6 faster packed<->planar conversation
michael
parents: 14245
diff changeset
154 for(j=0; j<out_len; j++){
91170dd147c6 faster packed<->planar conversation
michael
parents: 14245
diff changeset
155 for(i=0; i<chans; i++){
91170dd147c6 faster packed<->planar conversation
michael
parents: 14245
diff changeset
156 *(out++)= tmp[i][j];
91170dd147c6 faster packed<->planar conversation
michael
parents: 14245
diff changeset
157 }
13713
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
158 }
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
159 }
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
160
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
161 data->audio = af->data->audio;
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
162 data->len = out_len*chans*2;
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
163 data->rate = af->data->rate;
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
164 return data;
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
165 }
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
166
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
167 static int 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
168 af_resample_t *s = calloc(1,sizeof(af_resample_t));
13713
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
169 af->control=control;
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
170 af->uninit=uninit;
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
171 af->play=play;
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
172 af->mul.n=1;
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
173 af->mul.d=1;
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
174 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
175 s->filter_length= 16;
5053490906c3 Initialize cutoff, too. Fixes crash when AF_CONTROL_COMMAND_LINE is not set.
reimar
parents: 13859
diff changeset
176 s->cutoff= max(1.0 - 1.0/s->filter_length, 0.80);
5053490906c3 Initialize cutoff, too. Fixes crash when AF_CONTROL_COMMAND_LINE is not set.
reimar
parents: 13859
diff changeset
177 s->phase_shift= 10;
5053490906c3 Initialize cutoff, too. Fixes crash when AF_CONTROL_COMMAND_LINE is not set.
reimar
parents: 13859
diff changeset
178 // 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
179 af->setup=s;
13713
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
180 return AF_OK;
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
181 }
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
182
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
183 af_info_t af_info_lavcresample = {
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
184 "Sample frequency conversion using libavcodec",
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
185 "lavcresample",
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
186 "Michael Niedermayer",
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
187 "",
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
188 AF_FLAGS_REENTRANT,
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
189 open
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
190 };
28bb0f15ac91 libavcodec resampling ...
michael
parents:
diff changeset
191 #endif