Mercurial > mplayer.hg
comparison libao2/ao_plugin.c @ 4313:1dbffed555a6
Added buffering of output data
author | anders |
---|---|
date | Wed, 23 Jan 2002 12:28:36 +0000 |
parents | 2cc5737ec923 |
children | 0a95c5074c50 |
comparison
equal
deleted
inserted
replaced
4312:971836f677a9 | 4313:1dbffed555a6 |
---|---|
23 #define driver() (ao_plugin_local_data.driver) | 23 #define driver() (ao_plugin_local_data.driver) |
24 | 24 |
25 // local data | 25 // local data |
26 typedef struct ao_plugin_local_data_s | 26 typedef struct ao_plugin_local_data_s |
27 { | 27 { |
28 ao_functions_t* driver; // Output driver set in mplayer.c | 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 | |
29 ao_plugin_functions_t** plugins; // List of used plugins | 32 ao_plugin_functions_t** plugins; // List of used plugins |
30 ao_plugin_functions_t* available_plugins[NPL]; // List of available plugins | 33 ao_plugin_functions_t* available_plugins[NPL]; // List of available plugins |
31 } ao_plugin_local_data_t; | 34 } ao_plugin_local_data_t; |
32 | 35 |
33 static ao_plugin_local_data_t ao_plugin_local_data={NULL,NULL,AO_PLUGINS}; | 36 static ao_plugin_local_data_t ao_plugin_local_data={NULL,0,0.0,NULL,NULL,AO_PLUGINS}; |
34 | 37 |
35 // gloabal data | 38 // global data |
36 volatile ao_plugin_data_t ao_plugin_data; // data used by the plugins | 39 volatile ao_plugin_data_t ao_plugin_data; // Data used by the plugins |
37 volatile ao_plugin_cfg_t ao_plugin_cfg=CFG_DEFAULTS; // cfg data set in cfg-mplayer.h | 40 volatile ao_plugin_cfg_t ao_plugin_cfg=CFG_DEFAULTS; // Set in cfg-mplayer.h |
38 | 41 |
39 // to set/get/query special features/parameters | 42 // to set/get/query special features/parameters |
40 static int control(int cmd,int arg){ | 43 static int control(int cmd,int arg){ |
41 switch(cmd){ | 44 switch(cmd){ |
42 case AOCONTROL_SET_PLUGIN_DRIVER: | 45 case AOCONTROL_SET_PLUGIN_DRIVER: |
100 // open & setup audio device and plugins | 103 // open & setup audio device and plugins |
101 // return: 1=success 0=fail | 104 // return: 1=success 0=fail |
102 static int init(int rate,int channels,int format,int flags){ | 105 static int init(int rate,int channels,int format,int flags){ |
103 int ok=1; | 106 int ok=1; |
104 | 107 |
105 /* Create list of plugins from cfg option */ | 108 // Create list of plugins from cfg option |
106 int i=0; | 109 int i=0; |
107 if(ao_plugin_cfg.plugin_list){ | 110 if(ao_plugin_cfg.plugin_list){ |
108 if(!add_plugin(i,ao_plugin_cfg.plugin_list)) | 111 if(!add_plugin(i,ao_plugin_cfg.plugin_list)) |
109 return 0; | 112 return 0; |
110 } | 113 } |
122 while(plugin(i)&&ok) | 125 while(plugin(i)&&ok) |
123 ok=plugin(i++)->init(); | 126 ok=plugin(i++)->init(); |
124 | 127 |
125 if(!ok) return 0; | 128 if(!ok) return 0; |
126 | 129 |
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 | |
127 // This should never happen but check anyway | 144 // This should never happen but check anyway |
128 if(NULL==ao_plugin_local_data.driver) | 145 if(NULL==ao_plugin_local_data.driver) |
129 return 0; | 146 return 0; |
130 | 147 |
131 ok = driver()->init(ao_plugin_data.rate, | 148 ok = driver()->init(ao_plugin_data.rate, |
140 while((i>0) && ok) | 157 while((i>0) && ok) |
141 ok=plugin(--i)->control(AOCONTROL_PLUGIN_SET_LEN,0); | 158 ok=plugin(--i)->control(AOCONTROL_PLUGIN_SET_LEN,0); |
142 | 159 |
143 if(!ok) return 0; | 160 if(!ok) return 0; |
144 | 161 |
162 // Allocate output buffer */ | |
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 | |
145 return 1; | 169 return 1; |
146 } | 170 } |
147 | 171 |
148 // close audio device | 172 // close audio device |
149 static void uninit(){ | 173 static void uninit(){ |
151 driver()->uninit(); | 175 driver()->uninit(); |
152 while(plugin(i)) | 176 while(plugin(i)) |
153 plugin(i++)->uninit(); | 177 plugin(i++)->uninit(); |
154 if(ao_plugin_local_data.plugins) | 178 if(ao_plugin_local_data.plugins) |
155 free(ao_plugin_local_data.plugins); | 179 free(ao_plugin_local_data.plugins); |
180 if(ao_plugin_local_data.buf) | |
181 free(ao_plugin_local_data.buf); | |
156 } | 182 } |
157 | 183 |
158 // stop playing and empty buffers (for seeking/pause) | 184 // stop playing and empty buffers (for seeking/pause) |
159 static void reset(){ | 185 static void reset(){ |
160 int i=0; | 186 int i=0; |
161 driver()->reset(); | 187 driver()->reset(); |
162 while(plugin(i)) | 188 while(plugin(i)) |
163 plugin(i++)->reset(); | 189 plugin(i++)->reset(); |
190 ao_plugin_local_data.len=0; | |
164 } | 191 } |
165 | 192 |
166 // stop playing, keep buffers (for pause) | 193 // stop playing, keep buffers (for pause) |
167 static void audio_pause(){ | 194 static void audio_pause(){ |
168 driver()->pause(); | 195 driver()->pause(); |
174 } | 201 } |
175 | 202 |
176 // return: how many bytes can be played without blocking | 203 // return: how many bytes can be played without blocking |
177 static int get_space(){ | 204 static int get_space(){ |
178 double sz=(double)(driver()->get_space()); | 205 double sz=(double)(driver()->get_space()); |
206 if(sz+(double)ao_plugin_local_data.len > (double)MAX_OUTBURST) | |
207 sz=(double)MAX_OUTBURST-(double)ao_plugin_local_data.len; | |
179 sz*=ao_plugin_data.sz_mult; | 208 sz*=ao_plugin_data.sz_mult; |
180 sz+=ao_plugin_data.sz_fix; | 209 sz+=ao_plugin_data.sz_fix; |
181 return (int)(sz); | 210 return (int)(sz); |
182 } | 211 } |
183 | 212 |
184 // plays 'len' bytes of 'data' | 213 // plays 'len' bytes of 'data' |
185 // return: number of bytes played | 214 // return: number of bytes played |
186 static int play(void* data,int len,int flags){ | 215 static int play(void* data,int len,int flags){ |
187 int i=0; | 216 int l,i=0; |
188 /* Due to constant buffer sizes in plugins limit length */ | 217 // Limit length to avoid over flow in plugins |
189 int tmp = get_space(); | 218 int tmp = driver()->get_space(); |
190 int ret_len =(tmp<len)?tmp:len; | 219 int ret_len =(tmp<len)?tmp:len; |
191 /* Filter data */ | 220 // Filter data |
192 ao_plugin_data.len=ret_len; | 221 ao_plugin_data.len=ret_len; |
193 ao_plugin_data.data=data; | 222 ao_plugin_data.data=data; |
194 while(plugin(i)) | 223 while(plugin(i)) |
195 plugin(i++)->play(); | 224 plugin(i++)->play(); |
196 /* Send data to output */ | 225 // Copy data to output buffer |
197 //fprintf(stderr, "ao_plugin: ret_len=%d, len=%d\n", ret_len, len); | 226 memcpy(ao_plugin_local_data.buf+ao_plugin_local_data.len, |
198 len=driver()->play(ao_plugin_data.data,ao_plugin_data.len,flags); | 227 ao_plugin_data.data,ao_plugin_data.len); |
199 //fprintf(stderr, "ao_plugin: returned len=%d\n", len); | 228 // Send data to output |
200 | 229 l=driver()->play(ao_plugin_local_data.buf, |
201 if(len!=ao_plugin_data.len) | 230 ao_plugin_data.len+ao_plugin_local_data.len,flags); |
202 fprintf(stderr,"[ao_plugin] Warning under or over flow in sound plugin\n"); | 231 // Save away unsent data |
232 ao_plugin_local_data.len=ao_plugin_data.len+ao_plugin_local_data.len-l; | |
233 memcpy(ao_plugin_local_data.buf,ao_plugin_local_data.buf+l, | |
234 ao_plugin_local_data.len); | |
203 | 235 |
204 return ret_len; | 236 return ret_len; |
205 } | 237 } |
206 | 238 |
207 // return: delay in seconds between first and last sample in buffer | 239 // return: delay in seconds between first and last sample in buffer |
208 static float get_delay(){ | 240 static float get_delay(){ |
209 float delay=driver()->get_delay(); | 241 float delay=driver()->get_delay(); |
242 delay+=(float)ao_plugin_local_data.len/ao_plugin_local_data.bps; | |
210 delay*=ao_plugin_data.delay_mult; | 243 delay*=ao_plugin_data.delay_mult; |
211 delay+=ao_plugin_data.delay_fix; | 244 delay+=ao_plugin_data.delay_fix; |
212 return delay; | 245 return delay; |
213 } | 246 } |
214 | 247 |