Mercurial > mplayer.hg
annotate libaf/af_channels.c @ 36494:60d86116a5bc
Simplify: use memcpy_pic.
author | reimar |
---|---|
date | Sat, 18 Jan 2014 11:41:27 +0000 |
parents | 2b9bc3c2933d |
children |
rev | line source |
---|---|
28229
72d0b1444141
Replace informal license notices by standard license header
diego
parents:
24888
diff
changeset
|
1 /* |
72d0b1444141
Replace informal license notices by standard license header
diego
parents:
24888
diff
changeset
|
2 * Audio filter that adds and removes channels, according to the |
72d0b1444141
Replace informal license notices by standard license header
diego
parents:
24888
diff
changeset
|
3 * command line parameter channels. It is stupid and can only add |
72d0b1444141
Replace informal license notices by standard license header
diego
parents:
24888
diff
changeset
|
4 * silence or copy channels, not mix or filter. |
72d0b1444141
Replace informal license notices by standard license header
diego
parents:
24888
diff
changeset
|
5 * |
72d0b1444141
Replace informal license notices by standard license header
diego
parents:
24888
diff
changeset
|
6 * This file is part of MPlayer. |
72d0b1444141
Replace informal license notices by standard license header
diego
parents:
24888
diff
changeset
|
7 * |
72d0b1444141
Replace informal license notices by standard license header
diego
parents:
24888
diff
changeset
|
8 * MPlayer is free software; you can redistribute it and/or modify |
72d0b1444141
Replace informal license notices by standard license header
diego
parents:
24888
diff
changeset
|
9 * it under the terms of the GNU General Public License as published by |
72d0b1444141
Replace informal license notices by standard license header
diego
parents:
24888
diff
changeset
|
10 * the Free Software Foundation; either version 2 of the License, or |
72d0b1444141
Replace informal license notices by standard license header
diego
parents:
24888
diff
changeset
|
11 * (at your option) any later version. |
72d0b1444141
Replace informal license notices by standard license header
diego
parents:
24888
diff
changeset
|
12 * |
72d0b1444141
Replace informal license notices by standard license header
diego
parents:
24888
diff
changeset
|
13 * MPlayer is distributed in the hope that it will be useful, |
72d0b1444141
Replace informal license notices by standard license header
diego
parents:
24888
diff
changeset
|
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
72d0b1444141
Replace informal license notices by standard license header
diego
parents:
24888
diff
changeset
|
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
72d0b1444141
Replace informal license notices by standard license header
diego
parents:
24888
diff
changeset
|
16 * GNU General Public License for more details. |
72d0b1444141
Replace informal license notices by standard license header
diego
parents:
24888
diff
changeset
|
17 * |
72d0b1444141
Replace informal license notices by standard license header
diego
parents:
24888
diff
changeset
|
18 * You should have received a copy of the GNU General Public License along |
72d0b1444141
Replace informal license notices by standard license header
diego
parents:
24888
diff
changeset
|
19 * with MPlayer; if not, write to the Free Software Foundation, Inc., |
72d0b1444141
Replace informal license notices by standard license header
diego
parents:
24888
diff
changeset
|
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
72d0b1444141
Replace informal license notices by standard license header
diego
parents:
24888
diff
changeset
|
21 */ |
72d0b1444141
Replace informal license notices by standard license header
diego
parents:
24888
diff
changeset
|
22 |
7568 | 23 #include <stdio.h> |
24 #include <stdlib.h> | |
25 #include <string.h> | |
7975 | 26 #include <inttypes.h> |
7568 | 27 |
36395
2b9bc3c2933d
Remove some macros and switch to libavutil equivalents.
reimar
parents:
34174
diff
changeset
|
28 #include "libavutil/common.h" |
34174
a93891202051
Add missing mp_msg.h #includes, remove some unnecessary ones.
diego
parents:
29263
diff
changeset
|
29 #include "mp_msg.h" |
7568 | 30 #include "af.h" |
31 | |
8607 | 32 #define FR 0 |
33 #define TO 1 | |
34 | |
35 typedef struct af_channels_s{ | |
36 int route[AF_NCH][2]; | |
37 int nr; | |
38 int router; | |
39 }af_channels_t; | |
40 | |
7568 | 41 // Local function for copying data |
8711
906f7a2dc085
sig 11 fix in reinit and resample + spelling error fixes
anders
parents:
8607
diff
changeset
|
42 static void copy(void* in, void* out, int ins, int inos,int outs, int outos, int len, int bps) |
7568 | 43 { |
44 switch(bps){ | |
45 case 1:{ | |
46 int8_t* tin = (int8_t*)in; | |
47 int8_t* tout = (int8_t*)out; | |
48 tin += inos; | |
49 tout += outos; | |
50 len = len/ins; | |
51 while(len--){ | |
52 *tout=*tin; | |
53 tin +=ins; | |
54 tout+=outs; | |
55 } | |
56 break; | |
57 } | |
58 case 2:{ | |
59 int16_t* tin = (int16_t*)in; | |
60 int16_t* tout = (int16_t*)out; | |
61 tin += inos; | |
62 tout += outos; | |
63 len = len/(2*ins); | |
64 while(len--){ | |
65 *tout=*tin; | |
66 tin +=ins; | |
67 tout+=outs; | |
68 } | |
69 break; | |
70 } | |
12913 | 71 case 3:{ |
72 int8_t* tin = (int8_t*)in; | |
73 int8_t* tout = (int8_t*)out; | |
74 tin += 3 * inos; | |
75 tout += 3 * outos; | |
76 len = len / ( 3 * ins); | |
77 while (len--) { | |
78 tout[0] = tin[0]; | |
79 tout[1] = tin[1]; | |
80 tout[2] = tin[2]; | |
81 tin += 3 * ins; | |
82 tout += 3 * outs; | |
83 } | |
84 break; | |
85 } | |
7568 | 86 case 4:{ |
87 int32_t* tin = (int32_t*)in; | |
88 int32_t* tout = (int32_t*)out; | |
89 tin += inos; | |
90 tout += outos; | |
91 len = len/(4*ins); | |
92 while(len--){ | |
93 *tout=*tin; | |
94 tin +=ins; | |
95 tout+=outs; | |
96 } | |
97 break; | |
98 } | |
99 case 8:{ | |
100 int64_t* tin = (int64_t*)in; | |
101 int64_t* tout = (int64_t*)out; | |
102 tin += inos; | |
103 tout += outos; | |
104 len = len/(8*ins); | |
105 while(len--){ | |
106 *tout=*tin; | |
107 tin +=ins; | |
108 tout+=outs; | |
109 } | |
110 break; | |
111 } | |
112 default: | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29049
diff
changeset
|
113 mp_msg(MSGT_AFILTER, MSGL_ERR, "[channels] Unsupported number of bytes/sample: %i" |
8607 | 114 " please report this error on the MPlayer mailing list. \n",bps); |
7568 | 115 } |
116 } | |
117 | |
8607 | 118 // Make sure the routes are sane |
119 static int check_routes(af_channels_t* s, int nin, int nout) | |
120 { | |
121 int i; | |
122 if((s->nr < 1) || (s->nr > AF_NCH)){ | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29049
diff
changeset
|
123 mp_msg(MSGT_AFILTER, MSGL_ERR, "[channels] The number of routing pairs must be" |
8607 | 124 " between 1 and %i. Current value is %i\n",AF_NCH,s->nr); |
125 return AF_ERROR; | |
126 } | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29049
diff
changeset
|
127 |
8607 | 128 for(i=0;i<s->nr;i++){ |
129 if((s->route[i][FR] >= nin) || (s->route[i][TO] >= nout)){ | |
29049 | 130 mp_msg(MSGT_AFILTER, MSGL_ERR, "[channels] Invalid routing in pair nr. %i.\n", i); |
8607 | 131 return AF_ERROR; |
132 } | |
133 } | |
134 return AF_OK; | |
135 } | |
136 | |
7568 | 137 // Initialization and runtime control |
138 static int control(struct af_instance_s* af, int cmd, void* arg) | |
139 { | |
8607 | 140 af_channels_t* s = af->setup; |
7568 | 141 switch(cmd){ |
142 case AF_CONTROL_REINIT: | |
8607 | 143 |
144 // Set default channel assignment | |
145 if(!s->router){ | |
146 int i; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29049
diff
changeset
|
147 // Make sure this filter isn't redundant |
8607 | 148 if(af->data->nch == ((af_data_t*)arg)->nch) |
149 return AF_DETACH; | |
150 | |
151 // If mono: fake stereo | |
152 if(((af_data_t*)arg)->nch == 1){ | |
36395
2b9bc3c2933d
Remove some macros and switch to libavutil equivalents.
reimar
parents:
34174
diff
changeset
|
153 s->nr = FFMIN(af->data->nch,2); |
8607 | 154 for(i=0;i<s->nr;i++){ |
155 s->route[i][FR] = 0; | |
156 s->route[i][TO] = i; | |
157 } | |
158 } | |
159 else{ | |
36395
2b9bc3c2933d
Remove some macros and switch to libavutil equivalents.
reimar
parents:
34174
diff
changeset
|
160 s->nr = FFMIN(af->data->nch, ((af_data_t*)arg)->nch); |
8607 | 161 for(i=0;i<s->nr;i++){ |
162 s->route[i][FR] = i; | |
163 s->route[i][TO] = i; | |
164 } | |
165 } | |
166 } | |
7568 | 167 |
168 af->data->rate = ((af_data_t*)arg)->rate; | |
169 af->data->format = ((af_data_t*)arg)->format; | |
170 af->data->bps = ((af_data_t*)arg)->bps; | |
24888 | 171 af->mul = (double)af->data->nch / ((af_data_t*)arg)->nch; |
8607 | 172 return check_routes(s,((af_data_t*)arg)->nch,af->data->nch); |
7998
d48a06d07afb
Adding commandline options for filters and fixing stupid bug in cfg
anders
parents:
7975
diff
changeset
|
173 case AF_CONTROL_COMMAND_LINE:{ |
d48a06d07afb
Adding commandline options for filters and fixing stupid bug in cfg
anders
parents:
7975
diff
changeset
|
174 int nch = 0; |
8607 | 175 int n = 0; |
176 // Check number of channels and number of routing pairs | |
177 sscanf(arg, "%i:%i%n", &nch, &s->nr, &n); | |
178 | |
179 // If router scan commandline for routing pairs | |
180 if(s->nr){ | |
181 char* cp = &((char*)arg)[n]; | |
182 int ch = 0; | |
183 // Sanity check | |
184 if((s->nr < 1) || (s->nr > AF_NCH)){ | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29049
diff
changeset
|
185 mp_msg(MSGT_AFILTER, MSGL_ERR, "[channels] The number of routing pairs must be" |
8607 | 186 " between 1 and %i. Current value is %i\n",AF_NCH,s->nr); |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29049
diff
changeset
|
187 } |
8607 | 188 s->router = 1; |
189 // Scan for pairs on commandline | |
190 while((*cp == ':') && (ch < s->nr)){ | |
191 sscanf(cp, ":%i:%i%n" ,&s->route[ch][FR], &s->route[ch][TO], &n); | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29049
diff
changeset
|
192 mp_msg(MSGT_AFILTER, MSGL_V, "[channels] Routing from channel %i to" |
8607 | 193 " channel %i\n",s->route[ch][FR],s->route[ch][TO]); |
194 cp = &cp[n]; | |
195 ch++; | |
196 } | |
197 } | |
198 | |
199 if(AF_OK != af->control(af,AF_CONTROL_CHANNELS | AF_CONTROL_SET ,&nch)) | |
200 return AF_ERROR; | |
201 return AF_OK; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29049
diff
changeset
|
202 } |
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29049
diff
changeset
|
203 case AF_CONTROL_CHANNELS | AF_CONTROL_SET: |
7568 | 204 // Reinit must be called after this function has been called |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29049
diff
changeset
|
205 |
7568 | 206 // Sanity check |
12008 | 207 if(((int*)arg)[0] <= 0 || ((int*)arg)[0] > AF_NCH){ |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29049
diff
changeset
|
208 mp_msg(MSGT_AFILTER, MSGL_ERR, "[channels] The number of output channels must be" |
8607 | 209 " between 1 and %i. Current value is %i\n",AF_NCH,((int*)arg)[0]); |
7568 | 210 return AF_ERROR; |
211 } | |
212 | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29049
diff
changeset
|
213 af->data->nch=((int*)arg)[0]; |
8607 | 214 if(!s->router) |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29049
diff
changeset
|
215 mp_msg(MSGT_AFILTER, MSGL_V, "[channels] Changing number of channels" |
8607 | 216 " to %i\n",af->data->nch); |
217 return AF_OK; | |
218 case AF_CONTROL_CHANNELS | AF_CONTROL_GET: | |
219 *(int*)arg = af->data->nch; | |
220 return AF_OK; | |
221 case AF_CONTROL_CHANNELS_ROUTING | AF_CONTROL_SET:{ | |
222 int ch = ((af_control_ext_t*)arg)->ch; | |
223 int* route = ((af_control_ext_t*)arg)->arg; | |
224 s->route[ch][FR] = route[FR]; | |
225 s->route[ch][TO] = route[TO]; | |
226 return AF_OK; | |
227 } | |
228 case AF_CONTROL_CHANNELS_ROUTING | AF_CONTROL_GET:{ | |
229 int ch = ((af_control_ext_t*)arg)->ch; | |
230 int* route = ((af_control_ext_t*)arg)->arg; | |
231 route[FR] = s->route[ch][FR]; | |
232 route[TO] = s->route[ch][TO]; | |
233 return AF_OK; | |
234 } | |
235 case AF_CONTROL_CHANNELS_NR | AF_CONTROL_SET: | |
236 s->nr = *(int*)arg; | |
237 return AF_OK; | |
238 case AF_CONTROL_CHANNELS_NR | AF_CONTROL_GET: | |
239 *(int*)arg = s->nr; | |
240 return AF_OK; | |
241 case AF_CONTROL_CHANNELS_ROUTER | AF_CONTROL_SET: | |
242 s->router = *(int*)arg; | |
243 return AF_OK; | |
244 case AF_CONTROL_CHANNELS_ROUTER | AF_CONTROL_GET: | |
245 *(int*)arg = s->router; | |
7568 | 246 return AF_OK; |
247 } | |
248 return AF_UNKNOWN; | |
249 } | |
250 | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29049
diff
changeset
|
251 // Deallocate memory |
7568 | 252 static void uninit(struct af_instance_s* af) |
253 { | |
22179 | 254 free(af->setup); |
255 if (af->data) | |
256 free(af->data->audio); | |
257 free(af->data); | |
7568 | 258 } |
259 | |
260 // Filter data through filter | |
261 static af_data_t* play(struct af_instance_s* af, af_data_t* data) | |
262 { | |
8607 | 263 af_data_t* c = data; // Current working data |
264 af_data_t* l = af->data; // Local data | |
265 af_channels_t* s = af->setup; | |
266 int i; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29049
diff
changeset
|
267 |
7568 | 268 if(AF_OK != RESIZE_LOCAL_BUFFER(af,data)) |
269 return NULL; | |
270 | |
8607 | 271 // Reset unused channels |
24888 | 272 memset(l->audio,0,c->len / c->nch * l->nch); |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29049
diff
changeset
|
273 |
8607 | 274 if(AF_OK == check_routes(s,c->nch,l->nch)) |
275 for(i=0;i<s->nr;i++) | |
276 copy(c->audio,l->audio,c->nch,s->route[i][FR], | |
277 l->nch,s->route[i][TO],c->len,c->bps); | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29049
diff
changeset
|
278 |
7568 | 279 // Set output data |
280 c->audio = l->audio; | |
24888 | 281 c->len = c->len / c->nch * l->nch; |
7568 | 282 c->nch = l->nch; |
283 | |
284 return c; | |
285 } | |
286 | |
287 // Allocate memory and set function pointers | |
22746
fd6f824ef894
Rename open to af_open so as not to conflict with a previous header definition.
diego
parents:
22179
diff
changeset
|
288 static int af_open(af_instance_t* af){ |
7568 | 289 af->control=control; |
290 af->uninit=uninit; | |
291 af->play=play; | |
24888 | 292 af->mul=1; |
7568 | 293 af->data=calloc(1,sizeof(af_data_t)); |
8607 | 294 af->setup=calloc(1,sizeof(af_channels_t)); |
295 if((af->data == NULL) || (af->setup == NULL)) | |
7568 | 296 return AF_ERROR; |
297 return AF_OK; | |
298 } | |
299 | |
300 // Description of this filter | |
301 af_info_t af_info_channels = { | |
302 "Insert or remove channels", | |
303 "channels", | |
304 "Anders", | |
305 "", | |
7615 | 306 AF_FLAGS_REENTRANT, |
22746
fd6f824ef894
Rename open to af_open so as not to conflict with a previous header definition.
diego
parents:
22179
diff
changeset
|
307 af_open |
7568 | 308 }; |