Mercurial > mplayer.hg
annotate libao2/ao_plugin.c @ 4655:364cf7cc77be
Unroll -ni usage for deint. Anyway it doesn't help :(
author | nick |
---|---|
date | Mon, 11 Feb 2002 07:30:05 +0000 |
parents | 118ae69769be |
children | c72b386debb4 |
rev | line source |
---|---|
3096 | 1 #include <stdio.h> |
2 #include <stdlib.h> | |
3 | |
4 #include "../config.h" | |
5 | |
3194
1648d11fc36c
commandline configuration of audio plugins now through struct, format conversion plugin added
anders
parents:
3107
diff
changeset
|
6 #include "afmt.h" |
3096 | 7 #include "audio_out.h" |
8 #include "audio_out_internal.h" | |
9 | |
10 #include "audio_plugin.h" | |
11 | |
12 static ao_info_t info = | |
13 { | |
14 "Plugin audio output", | |
15 "plugin", | |
16 "Anders", | |
17 "" | |
18 }; | |
19 | |
20 LIBAO_EXTERN(plugin) | |
21 | |
3107 | 22 #define plugin(i) (ao_plugin_local_data.plugins[i]) |
23 #define driver() (ao_plugin_local_data.driver) | |
3096 | 24 |
3107 | 25 // local data |
3096 | 26 typedef struct ao_plugin_local_data_s |
27 { | |
4313 | 28 void* buf; // Output data buffer |
29 int len; // Amount of data in buffer | |
30 float bps; // Bytes per second out | |
31 ao_functions_t* driver; // Output driver | |
3107 | 32 ao_plugin_functions_t** plugins; // List of used plugins |
3194
1648d11fc36c
commandline configuration of audio plugins now through struct, format conversion plugin added
anders
parents:
3107
diff
changeset
|
33 ao_plugin_functions_t* available_plugins[NPL]; // List of available plugins |
3096 | 34 } ao_plugin_local_data_t; |
35 | |
4313 | 36 static ao_plugin_local_data_t ao_plugin_local_data={NULL,0,0.0,NULL,NULL,AO_PLUGINS}; |
3096 | 37 |
4313 | 38 // global data |
39 volatile ao_plugin_data_t ao_plugin_data; // Data used by the plugins | |
40 volatile ao_plugin_cfg_t ao_plugin_cfg=CFG_DEFAULTS; // Set in cfg-mplayer.h | |
3096 | 41 |
42 // to set/get/query special features/parameters | |
43 static int control(int cmd,int arg){ | |
3107 | 44 switch(cmd){ |
45 case AOCONTROL_SET_PLUGIN_DRIVER: | |
46 ao_plugin_local_data.driver=(ao_functions_t*)arg; | |
47 return CONTROL_OK; | |
48 default: | |
49 return driver()->control(cmd,arg); | |
50 } | |
51 return CONTROL_UNKNOWN; | |
52 } | |
53 | |
54 // Recursive function for adding plugins | |
55 // return 1 for success and 0 for error | |
56 int add_plugin(int i,char* cfg){ | |
57 int cnt=0; | |
58 // Find end of plugin name | |
59 while((cfg[cnt]!=',')&&(cfg[cnt]!='\0')&&(cnt<100)) cnt++; | |
60 if(cnt >= 100) | |
61 return 0; | |
62 | |
3680 | 63 // Is this the last iteration or just another plugin |
3107 | 64 if(cfg[cnt]=='\0'){ |
65 ao_plugin_local_data.plugins=malloc((i+1)*sizeof(ao_plugin_functions_t*)); | |
66 if(ao_plugin_local_data.plugins){ | |
67 ao_plugin_local_data.plugins[i+1]=NULL; | |
68 // Find the plugin matching the cfg string name | |
69 cnt=0; | |
70 while(ao_plugin_local_data.available_plugins[cnt] && cnt<20){ | |
71 if(0==strcmp(ao_plugin_local_data.available_plugins[cnt]->info->short_name,cfg)){ | |
72 ao_plugin_local_data.plugins[i]=ao_plugin_local_data.available_plugins[cnt]; | |
73 return 1; | |
74 } | |
75 cnt++; | |
76 } | |
77 printf("[plugin]: Invalid plugin: %s \n",cfg); | |
78 return 0; | |
79 } | |
80 else | |
81 return 0; | |
82 } else { | |
83 cfg[cnt]='\0'; | |
84 if(add_plugin(i+1,&cfg[cnt+1])){ | |
85 cnt=0; | |
86 // Find the plugin matching the cfg string name | |
87 while(ao_plugin_local_data.available_plugins[cnt] && cnt < 20){ | |
88 if(0==strcmp(ao_plugin_local_data.available_plugins[cnt]->info->short_name,cfg)){ | |
89 ao_plugin_local_data.plugins[i]=ao_plugin_local_data.available_plugins[cnt]; | |
90 return 1; | |
91 } | |
92 cnt++; | |
93 } | |
94 printf("[plugin]: Invalid plugin: %s \n",cfg); | |
95 return 0; | |
96 } | |
97 else | |
98 return 0; | |
99 } | |
100 return 0; // Will never happen... | |
3096 | 101 } |
102 | |
103 // open & setup audio device and plugins | |
104 // return: 1=success 0=fail | |
105 static int init(int rate,int channels,int format,int flags){ | |
106 int ok=1; | |
107 | |
4313 | 108 // Create list of plugins from cfg option |
3096 | 109 int i=0; |
3194
1648d11fc36c
commandline configuration of audio plugins now through struct, format conversion plugin added
anders
parents:
3107
diff
changeset
|
110 if(ao_plugin_cfg.plugin_list){ |
1648d11fc36c
commandline configuration of audio plugins now through struct, format conversion plugin added
anders
parents:
3107
diff
changeset
|
111 if(!add_plugin(i,ao_plugin_cfg.plugin_list)) |
3107 | 112 return 0; |
113 } | |
3096 | 114 |
115 /* Set input parameters and itterate through plugins each plugin | |
116 changes the parameters according to its output */ | |
117 ao_plugin_data.rate=rate; | |
118 ao_plugin_data.channels=channels; | |
119 ao_plugin_data.format=format; | |
120 ao_plugin_data.sz_mult=1; | |
121 ao_plugin_data.sz_fix=0; | |
122 ao_plugin_data.delay_mult=1; | |
123 ao_plugin_data.delay_fix=0; | |
124 i=0; | |
125 while(plugin(i)&&ok) | |
126 ok=plugin(i++)->init(); | |
127 | |
128 if(!ok) return 0; | |
129 | |
4313 | 130 // Calculate bps |
131 ao_plugin_local_data.bps=(float)(ao_plugin_data.rate * | |
132 ao_plugin_data.channels); | |
133 | |
134 if(ao_plugin_data.format == AFMT_S16_LE || | |
135 ao_plugin_data.format == AFMT_S16_BE || | |
136 ao_plugin_data.format == AFMT_U16_LE || | |
137 ao_plugin_data.format == AFMT_U16_BE) | |
138 ao_plugin_local_data.bps *= 2; | |
139 | |
140 if(ao_plugin_data.format == AFMT_S32_LE || | |
141 ao_plugin_data.format == AFMT_S32_BE) | |
142 ao_plugin_local_data.bps *= 4; | |
143 | |
3107 | 144 // This should never happen but check anyway |
145 if(NULL==ao_plugin_local_data.driver) | |
146 return 0; | |
147 | |
3096 | 148 ok = driver()->init(ao_plugin_data.rate, |
3107 | 149 ao_plugin_data.channels, |
150 ao_plugin_data.format, | |
151 flags); | |
3096 | 152 if(!ok) return 0; |
153 | |
154 /* Now that the driver is initialized we can calculate and set the | |
155 input and output buffers for each plugin */ | |
156 ao_plugin_data.len=driver()->get_space(); | |
3107 | 157 while((i>0) && ok) |
3194
1648d11fc36c
commandline configuration of audio plugins now through struct, format conversion plugin added
anders
parents:
3107
diff
changeset
|
158 ok=plugin(--i)->control(AOCONTROL_PLUGIN_SET_LEN,0); |
3107 | 159 |
160 if(!ok) return 0; | |
3096 | 161 |
4374
0a95c5074c50
Fixed sig 11 caused by resampling plugin, some cosmetic changes and speed improvements
anders
parents:
4313
diff
changeset
|
162 // Allocate output buffer |
4313 | 163 if(ao_plugin_local_data.buf) |
164 free(ao_plugin_local_data.buf); | |
165 ao_plugin_local_data.buf=malloc(MAX_OUTBURST); | |
166 | |
167 if(!ao_plugin_local_data.buf) return 0; | |
168 | |
3096 | 169 return 1; |
170 } | |
171 | |
172 // close audio device | |
173 static void uninit(){ | |
174 int i=0; | |
175 driver()->uninit(); | |
176 while(plugin(i)) | |
177 plugin(i++)->uninit(); | |
3107 | 178 if(ao_plugin_local_data.plugins) |
179 free(ao_plugin_local_data.plugins); | |
4313 | 180 if(ao_plugin_local_data.buf) |
181 free(ao_plugin_local_data.buf); | |
3096 | 182 } |
183 | |
184 // stop playing and empty buffers (for seeking/pause) | |
185 static void reset(){ | |
186 int i=0; | |
187 driver()->reset(); | |
188 while(plugin(i)) | |
189 plugin(i++)->reset(); | |
4313 | 190 ao_plugin_local_data.len=0; |
3096 | 191 } |
192 | |
193 // stop playing, keep buffers (for pause) | |
194 static void audio_pause(){ | |
195 driver()->pause(); | |
196 } | |
197 | |
198 // resume playing, after audio_pause() | |
199 static void audio_resume(){ | |
200 driver()->resume(); | |
201 } | |
202 | |
203 // return: how many bytes can be played without blocking | |
204 static int get_space(){ | |
205 double sz=(double)(driver()->get_space()); | |
4313 | 206 if(sz+(double)ao_plugin_local_data.len > (double)MAX_OUTBURST) |
207 sz=(double)MAX_OUTBURST-(double)ao_plugin_local_data.len; | |
3096 | 208 sz*=ao_plugin_data.sz_mult; |
209 sz+=ao_plugin_data.sz_fix; | |
210 return (int)(sz); | |
211 } | |
212 | |
213 // plays 'len' bytes of 'data' | |
214 // return: number of bytes played | |
215 static int play(void* data,int len,int flags){ | |
4313 | 216 int l,i=0; |
217 // Limit length to avoid over flow in plugins | |
218 int tmp = driver()->get_space(); | |
3096 | 219 int ret_len =(tmp<len)?tmp:len; |
4375 | 220 if(ret_len){ |
221 // Filter data | |
222 ao_plugin_data.len=ret_len; | |
223 ao_plugin_data.data=data; | |
4376 | 224 while(plugin(i)) |
4375 | 225 plugin(i++)->play(); |
226 // Copy data to output buffer | |
227 memcpy(ao_plugin_local_data.buf+ao_plugin_local_data.len, | |
228 ao_plugin_data.data,ao_plugin_data.len); | |
229 // Send data to output | |
230 l=driver()->play(ao_plugin_local_data.buf, | |
231 ao_plugin_data.len+ao_plugin_local_data.len,flags); | |
232 // Save away unsent data | |
233 ao_plugin_local_data.len=ao_plugin_data.len+ao_plugin_local_data.len-l; | |
234 memcpy(ao_plugin_local_data.buf,ao_plugin_local_data.buf+l, | |
235 ao_plugin_local_data.len); | |
236 } | |
3096 | 237 return ret_len; |
238 } | |
239 | |
240 // return: delay in seconds between first and last sample in buffer | |
241 static float get_delay(){ | |
242 float delay=driver()->get_delay(); | |
4313 | 243 delay+=(float)ao_plugin_local_data.len/ao_plugin_local_data.bps; |
3096 | 244 delay*=ao_plugin_data.delay_mult; |
245 delay+=ao_plugin_data.delay_fix; | |
246 return delay; | |
247 } | |
248 | |
249 | |
3279
d6ea11bed983
Commandline interface to ao_plugin updated according to mplayers complex parameter format and plugin pl_format finished (alpha code needs testing)
anders
parents:
3194
diff
changeset
|
250 |
d6ea11bed983
Commandline interface to ao_plugin updated according to mplayers complex parameter format and plugin pl_format finished (alpha code needs testing)
anders
parents:
3194
diff
changeset
|
251 |