Mercurial > mplayer.hg
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 |
rev | line source |
---|---|
13713 | 1 // Copyright (c) 2004 Michael Niedermayer <michaelni@gmx.at> |
2 // #inlcude <GPL_v2.h> | |
3 | |
4 #include <stdio.h> | |
5 #include <stdlib.h> | |
6 #include <string.h> | |
7 #include <inttypes.h> | |
8 | |
9 #include "../config.h" | |
10 #include "af.h" | |
11 | |
12 #ifdef USE_LIBAVCODEC | |
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 | 21 |
22 #define CHANS 6 | |
23 | |
13730 | 24 int64_t ff_gcd(int64_t a, int64_t b); |
25 | |
13713 | 26 // Data for specific instances of this filter |
27 typedef struct af_resample_s{ | |
28 struct AVResampleContext *avrctx; | |
29 int16_t *in[CHANS]; | |
30 int in_alloc; | |
31 int index; | |
32 | |
33 int filter_length; | |
34 int linear; | |
35 int phase_shift; | |
13730 | 36 double cutoff; |
13713 | 37 }af_resample_t; |
38 | |
39 | |
40 // Initialization and runtime control | |
41 static int control(struct af_instance_s* af, int cmd, void* arg) | |
42 { | |
43 af_resample_t* s = (af_resample_t*)af->setup; | |
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 | 46 |
47 switch(cmd){ | |
48 case AF_CONTROL_REINIT: | |
49 if((af->data->rate == data->rate) || (af->data->rate == 0)) | |
50 return AF_DETACH; | |
51 | |
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 | 54 af->data->format = AF_FORMAT_S16_NE; |
13713 | 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 | 59 af->delay = 500*s->filter_length/(double)min(af->data->rate, data->rate); |
13713 | 60 |
61 if(s->avrctx) av_resample_close(s->avrctx); | |
13730 | 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 | 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 | 70 case AF_CONTROL_COMMAND_LINE:{ |
13730 | 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); | |
13713 | 73 return AF_OK; |
74 } | |
75 case AF_CONTROL_RESAMPLE_RATE | AF_CONTROL_SET: | |
76 af->data->rate = *(int*)arg; | |
77 return AF_OK; | |
78 } | |
79 return AF_UNKNOWN; | |
80 } | |
81 | |
82 // Deallocate memory | |
83 static void uninit(struct af_instance_s* af) | |
84 { | |
85 if(af->data) | |
86 free(af->data); | |
87 if(af->setup){ | |
88 af_resample_t *s = af->setup; | |
89 if(s->avrctx) av_resample_close(s->avrctx); | |
90 free(s); | |
91 } | |
92 } | |
93 | |
94 // Filter data through filter | |
95 static af_data_t* play(struct af_instance_s* af, af_data_t* data) | |
96 { | |
97 af_resample_t *s = af->setup; | |
98 int i, j, consumed, ret; | |
99 int16_t *in = (int16_t*)data->audio; | |
100 int16_t *out; | |
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]; | |
105 | |
106 if(AF_OK != RESIZE_LOCAL_BUFFER(af,data)) | |
107 return NULL; | |
108 | |
109 out= (int16_t*)af->data->audio; | |
13730 | 110 |
111 out_len= min(out_len, af->data->len/(2*chans)); | |
112 | |
13713 | 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 ;) | |
117 } | |
118 } | |
119 | |
14283 | 120 if(chans==1){ |
121 memcpy(&s->in[0][s->index], in, in_len * sizeof(int16_t)); | |
122 }else if(chans==2){ | |
123 for(j=0; j<in_len; j++){ | |
124 s->in[0][j + s->index]= *(in++); | |
125 s->in[1][j + s->index]= *(in++); | |
126 } | |
127 }else{ | |
128 for(j=0; j<in_len; j++){ | |
129 for(i=0; i<chans; i++){ | |
130 s->in[i][j + s->index]= *(in++); | |
131 } | |
13713 | 132 } |
133 } | |
134 in_len += s->index; | |
135 | |
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); | |
138 } | |
139 out_len= ret; | |
140 | |
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)); | |
144 } | |
145 | |
14283 | 146 if(chans==1){ |
147 memcpy(out, tmp[0], out_len*sizeof(int16_t)); | |
148 }else if(chans==2){ | |
149 for(j=0; j<out_len; j++){ | |
150 *(out++)= tmp[0][j]; | |
151 *(out++)= tmp[1][j]; | |
152 } | |
153 }else{ | |
154 for(j=0; j<out_len; j++){ | |
155 for(i=0; i<chans; i++){ | |
156 *(out++)= tmp[i][j]; | |
157 } | |
13713 | 158 } |
159 } | |
160 | |
161 data->audio = af->data->audio; | |
162 data->len = out_len*chans*2; | |
163 data->rate = af->data->rate; | |
164 return data; | |
165 } | |
166 | |
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 | 169 af->control=control; |
170 af->uninit=uninit; | |
171 af->play=play; | |
172 af->mul.n=1; | |
173 af->mul.d=1; | |
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 | 180 return AF_OK; |
181 } | |
182 | |
183 af_info_t af_info_lavcresample = { | |
184 "Sample frequency conversion using libavcodec", | |
185 "lavcresample", | |
186 "Michael Niedermayer", | |
187 "", | |
188 AF_FLAGS_REENTRANT, | |
189 open | |
190 }; | |
191 #endif |