Mercurial > mplayer.hg
annotate libaf/af_lavcresample.c @ 27319:09cf111f68b8
Revert to previous dependency checking behavior.
Take included header files into account when generating dependency files.
This has problems when header files are removed or renamed, but does not
silently miscompile files.
author | diego |
---|---|
date | Sat, 26 Jul 2008 18:36:48 +0000 |
parents | b3a38b361fef |
children | 0f1b5b68af32 |
rev | line source |
---|---|
25529
867ee1c2114b
Relicense GPL v2 files as GPL v2+ and add proper license headers.
diego
parents:
24900
diff
changeset
|
1 /* |
867ee1c2114b
Relicense GPL v2 files as GPL v2+ and add proper license headers.
diego
parents:
24900
diff
changeset
|
2 * Copyright (c) 2004 Michael Niedermayer <michaelni@gmx.at> |
867ee1c2114b
Relicense GPL v2 files as GPL v2+ and add proper license headers.
diego
parents:
24900
diff
changeset
|
3 * |
867ee1c2114b
Relicense GPL v2 files as GPL v2+ and add proper license headers.
diego
parents:
24900
diff
changeset
|
4 * This file is part of MPlayer. |
867ee1c2114b
Relicense GPL v2 files as GPL v2+ and add proper license headers.
diego
parents:
24900
diff
changeset
|
5 * |
867ee1c2114b
Relicense GPL v2 files as GPL v2+ and add proper license headers.
diego
parents:
24900
diff
changeset
|
6 * MPlayer is free software; you can redistribute it and/or modify |
867ee1c2114b
Relicense GPL v2 files as GPL v2+ and add proper license headers.
diego
parents:
24900
diff
changeset
|
7 * it under the terms of the GNU General Public License as published by |
867ee1c2114b
Relicense GPL v2 files as GPL v2+ and add proper license headers.
diego
parents:
24900
diff
changeset
|
8 * the Free Software Foundation; either version 2 of the License, or |
867ee1c2114b
Relicense GPL v2 files as GPL v2+ and add proper license headers.
diego
parents:
24900
diff
changeset
|
9 * (at your option) any later version. |
867ee1c2114b
Relicense GPL v2 files as GPL v2+ and add proper license headers.
diego
parents:
24900
diff
changeset
|
10 * |
867ee1c2114b
Relicense GPL v2 files as GPL v2+ and add proper license headers.
diego
parents:
24900
diff
changeset
|
11 * MPlayer is distributed in the hope that it will be useful, |
867ee1c2114b
Relicense GPL v2 files as GPL v2+ and add proper license headers.
diego
parents:
24900
diff
changeset
|
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
867ee1c2114b
Relicense GPL v2 files as GPL v2+ and add proper license headers.
diego
parents:
24900
diff
changeset
|
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
867ee1c2114b
Relicense GPL v2 files as GPL v2+ and add proper license headers.
diego
parents:
24900
diff
changeset
|
14 * GNU General Public License for more details. |
867ee1c2114b
Relicense GPL v2 files as GPL v2+ and add proper license headers.
diego
parents:
24900
diff
changeset
|
15 * |
26740
b3a38b361fef
Use standard license headers with standard formatting.
diego
parents:
26069
diff
changeset
|
16 * You should have received a copy of the GNU General Public License along |
b3a38b361fef
Use standard license headers with standard formatting.
diego
parents:
26069
diff
changeset
|
17 * with MPlayer; if not, write to the Free Software Foundation, Inc., |
b3a38b361fef
Use standard license headers with standard formatting.
diego
parents:
26069
diff
changeset
|
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
25529
867ee1c2114b
Relicense GPL v2 files as GPL v2+ and add proper license headers.
diego
parents:
24900
diff
changeset
|
19 */ |
13713 | 20 |
21 #include <stdio.h> | |
22 #include <stdlib.h> | |
23 #include <string.h> | |
24 #include <inttypes.h> | |
25 | |
16982 | 26 #include "config.h" |
13713 | 27 #include "af.h" |
26069
1318e956c092
FFmpeg now uses different (unified) #include paths.
diego
parents:
25529
diff
changeset
|
28 #include "libavcodec/avcodec.h" |
1318e956c092
FFmpeg now uses different (unified) #include paths.
diego
parents:
25529
diff
changeset
|
29 #include "libavutil/rational.h" |
13713 | 30 |
31 // Data for specific instances of this filter | |
32 typedef struct af_resample_s{ | |
33 struct AVResampleContext *avrctx; | |
22178
c4d9550c9faf
Use AF_NCH for max number of channels instead of private CHANS define.
uau
parents:
17522
diff
changeset
|
34 int16_t *in[AF_NCH]; |
13713 | 35 int in_alloc; |
36 int index; | |
37 | |
38 int filter_length; | |
39 int linear; | |
40 int phase_shift; | |
13730 | 41 double cutoff; |
13713 | 42 }af_resample_t; |
43 | |
44 | |
45 // Initialization and runtime control | |
46 static int control(struct af_instance_s* af, int cmd, void* arg) | |
47 { | |
48 af_resample_t* s = (af_resample_t*)af->setup; | |
49 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
|
50 int out_rate, test_output_res; // helpers for checking input format |
13713 | 51 |
52 switch(cmd){ | |
53 case AF_CONTROL_REINIT: | |
54 if((af->data->rate == data->rate) || (af->data->rate == 0)) | |
55 return AF_DETACH; | |
56 | |
57 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
|
58 if (af->data->nch > AF_NCH) af->data->nch = AF_NCH; |
14245 | 59 af->data->format = AF_FORMAT_S16_NE; |
13713 | 60 af->data->bps = 2; |
24888 | 61 af->mul = (double)af->data->rate / data->rate; |
24900 | 62 af->delay = af->data->nch * s->filter_length / min(af->mul, 1); // *bps*.5 |
13713 | 63 |
64 if(s->avrctx) av_resample_close(s->avrctx); | |
24888 | 65 s->avrctx= av_resample_init(af->data->rate, /*in_rate*/data->rate, s->filter_length, s->phase_shift, s->linear, s->cutoff); |
13713 | 66 |
14213
3c56b18bbb0c
Make filters request a supported input format instead of failing.
reimar
parents:
14186
diff
changeset
|
67 // 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
|
68 out_rate = af->data->rate; |
3c56b18bbb0c
Make filters request a supported input format instead of failing.
reimar
parents:
14186
diff
changeset
|
69 af->data->rate = data->rate; |
3c56b18bbb0c
Make filters request a supported input format instead of failing.
reimar
parents:
14186
diff
changeset
|
70 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
|
71 af->data->rate = out_rate; |
3c56b18bbb0c
Make filters request a supported input format instead of failing.
reimar
parents:
14186
diff
changeset
|
72 return test_output_res; |
13713 | 73 case AF_CONTROL_COMMAND_LINE:{ |
22755 | 74 s->cutoff= 0.0; |
13730 | 75 sscanf((char*)arg,"%d:%d:%d:%d:%lf", &af->data->rate, &s->filter_length, &s->linear, &s->phase_shift, &s->cutoff); |
22755 | 76 if(s->cutoff <= 0.0) s->cutoff= max(1.0 - 6.5/(s->filter_length+8), 0.80); |
13713 | 77 return AF_OK; |
78 } | |
79 case AF_CONTROL_RESAMPLE_RATE | AF_CONTROL_SET: | |
80 af->data->rate = *(int*)arg; | |
81 return AF_OK; | |
82 } | |
83 return AF_UNKNOWN; | |
84 } | |
85 | |
86 // Deallocate memory | |
87 static void uninit(struct af_instance_s* af) | |
88 { | |
89 if(af->data) | |
22179 | 90 free(af->data->audio); |
91 free(af->data); | |
13713 | 92 if(af->setup){ |
22182 | 93 int i; |
13713 | 94 af_resample_t *s = af->setup; |
95 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
|
96 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
|
97 free(s->in[i]); |
13713 | 98 free(s); |
99 } | |
100 } | |
101 | |
102 // Filter data through filter | |
103 static af_data_t* play(struct af_instance_s* af, af_data_t* data) | |
104 { | |
105 af_resample_t *s = af->setup; | |
106 int i, j, consumed, ret; | |
107 int16_t *in = (int16_t*)data->audio; | |
108 int16_t *out; | |
109 int chans = data->nch; | |
110 int in_len = data->len/(2*chans); | |
24888 | 111 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
|
112 int16_t tmp[AF_NCH][out_len]; |
13713 | 113 |
114 if(AF_OK != RESIZE_LOCAL_BUFFER(af,data)) | |
115 return NULL; | |
116 | |
117 out= (int16_t*)af->data->audio; | |
13730 | 118 |
119 out_len= min(out_len, af->data->len/(2*chans)); | |
120 | |
13713 | 121 if(s->in_alloc < in_len + s->index){ |
122 s->in_alloc= in_len + s->index; | |
123 for(i=0; i<chans; i++){ | |
22179 | 124 s->in[i]= realloc(s->in[i], s->in_alloc*sizeof(int16_t)); |
13713 | 125 } |
126 } | |
127 | |
14283 | 128 if(chans==1){ |
129 memcpy(&s->in[0][s->index], in, in_len * sizeof(int16_t)); | |
130 }else if(chans==2){ | |
131 for(j=0; j<in_len; j++){ | |
132 s->in[0][j + s->index]= *(in++); | |
133 s->in[1][j + s->index]= *(in++); | |
134 } | |
135 }else{ | |
136 for(j=0; j<in_len; j++){ | |
137 for(i=0; i<chans; i++){ | |
138 s->in[i][j + s->index]= *(in++); | |
139 } | |
13713 | 140 } |
141 } | |
142 in_len += s->index; | |
143 | |
144 for(i=0; i<chans; i++){ | |
145 ret= av_resample(s->avrctx, tmp[i], s->in[i], &consumed, in_len, out_len, i+1 == chans); | |
146 } | |
147 out_len= ret; | |
148 | |
149 s->index= in_len - consumed; | |
150 for(i=0; i<chans; i++){ | |
151 memmove(s->in[i], s->in[i] + consumed, s->index*sizeof(int16_t)); | |
152 } | |
153 | |
14283 | 154 if(chans==1){ |
155 memcpy(out, tmp[0], out_len*sizeof(int16_t)); | |
156 }else if(chans==2){ | |
157 for(j=0; j<out_len; j++){ | |
158 *(out++)= tmp[0][j]; | |
159 *(out++)= tmp[1][j]; | |
160 } | |
161 }else{ | |
162 for(j=0; j<out_len; j++){ | |
163 for(i=0; i<chans; i++){ | |
164 *(out++)= tmp[i][j]; | |
165 } | |
13713 | 166 } |
167 } | |
168 | |
169 data->audio = af->data->audio; | |
170 data->len = out_len*chans*2; | |
171 data->rate = af->data->rate; | |
172 return data; | |
173 } | |
174 | |
22746
fd6f824ef894
Rename open to af_open so as not to conflict with a previous header definition.
diego
parents:
22182
diff
changeset
|
175 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
|
176 af_resample_t *s = calloc(1,sizeof(af_resample_t)); |
13713 | 177 af->control=control; |
178 af->uninit=uninit; | |
179 af->play=play; | |
24888 | 180 af->mul=1; |
13713 | 181 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
|
182 s->filter_length= 16; |
22755 | 183 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
|
184 s->phase_shift= 10; |
5053490906c3
Initialize cutoff, too. Fixes crash when AF_CONTROL_COMMAND_LINE is not set.
reimar
parents:
13859
diff
changeset
|
185 // 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
|
186 af->setup=s; |
13713 | 187 return AF_OK; |
188 } | |
189 | |
190 af_info_t af_info_lavcresample = { | |
191 "Sample frequency conversion using libavcodec", | |
192 "lavcresample", | |
193 "Michael Niedermayer", | |
194 "", | |
195 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
|
196 af_open |
13713 | 197 }; |