Mercurial > mplayer.hg
comparison libao2/ao_jack.c @ 16104:fc2459a18bf3
improved audio delay estimation, supposed to help make the video smoother
author | reimar |
---|---|
date | Tue, 26 Jul 2005 10:47:29 +0000 |
parents | 8bb0701496ec |
children | 0671f92d2cb4 |
comparison
equal
deleted
inserted
replaced
16103:1b10f858d873 | 16104:fc2459a18bf3 |
---|---|
41 #define MAX_CHANS 6 | 41 #define MAX_CHANS 6 |
42 static jack_port_t *ports[MAX_CHANS]; | 42 static jack_port_t *ports[MAX_CHANS]; |
43 static int num_ports; ///< Number of used ports == number of channels | 43 static int num_ports; ///< Number of used ports == number of channels |
44 static jack_client_t *client; | 44 static jack_client_t *client; |
45 static float jack_latency; | 45 static float jack_latency; |
46 static int estimate; | |
46 static volatile int paused = 0; ///< set if paused | 47 static volatile int paused = 0; ///< set if paused |
47 static volatile int underrun = 0; ///< signals if an underrun occured | 48 static volatile int underrun = 0; ///< signals if an underrun occured |
48 | 49 |
49 //! If this is defined try to make a more precise delay estimation. Will be slower. | 50 static volatile float callback_interval = 0; |
50 #undef JACK_ESTIMATE_DELAY | 51 static volatile float callback_time = 0; |
51 #ifdef JACK_ESTIMATE_DELAY | |
52 static volatile int callback_samples = 0; | |
53 static volatile unsigned int callback_time = 0; | |
54 #endif | |
55 | 52 |
56 //! size of one chunk, if this is too small MPlayer will start to "stutter" | 53 //! size of one chunk, if this is too small MPlayer will start to "stutter" |
57 //! after a short time of playback | 54 //! after a short time of playback |
58 #define CHUNK_SIZE (16 * 1024) | 55 #define CHUNK_SIZE (16 * 1024) |
59 //! number of "virtual" chunks the buffer consists of | 56 //! number of "virtual" chunks the buffer consists of |
184 if (!paused && !underrun) | 181 if (!paused && !underrun) |
185 if (read_buffer(bufs, nframes, num_ports) < nframes) | 182 if (read_buffer(bufs, nframes, num_ports) < nframes) |
186 underrun = 1; | 183 underrun = 1; |
187 if (paused || underrun) | 184 if (paused || underrun) |
188 silence(bufs, nframes, num_ports); | 185 silence(bufs, nframes, num_ports); |
189 #ifdef JACK_ESTIMATE_DELAY | 186 if (estimate) { |
190 callback_samples = nframes; | 187 float now = (float)GetTimer() / 1000000.0; |
191 callback_time = GetTimer(); | 188 float diff = callback_time + callback_interval - now; |
192 #endif | 189 if (diff < 0.002) |
190 callback_time += callback_interval; | |
191 else | |
192 callback_time = now; | |
193 callback_interval = (float)nframes / (float)ao_data.samplerate; | |
194 } | |
193 return 0; | 195 return 0; |
194 } | 196 } |
195 | 197 |
196 /** | 198 /** |
197 * \brief print suboption usage help | 199 * \brief print suboption usage help |
202 "\n-ao jack commandline help:\n" | 204 "\n-ao jack commandline help:\n" |
203 "Example: mplayer -ao jack:port=myout\n" | 205 "Example: mplayer -ao jack:port=myout\n" |
204 " connects MPlayer to the jack ports named myout\n" | 206 " connects MPlayer to the jack ports named myout\n" |
205 "\nOptions:\n" | 207 "\nOptions:\n" |
206 " port=<port name>\n" | 208 " port=<port name>\n" |
207 " Connects to the given ports instead of the default physical ones\n"); | 209 " Connects to the given ports instead of the default physical ones\n" |
210 " estimate\n" | |
211 " Estimates the amount of data in buffers (experimental)\n"); | |
208 } | 212 } |
209 | 213 |
210 static int init(int rate, int channels, int format, int flags) { | 214 static int init(int rate, int channels, int format, int flags) { |
211 const char **matching_ports = NULL; | 215 const char **matching_ports = NULL; |
212 char *port_name = NULL; | 216 char *port_name = NULL; |
213 char client_name[40]; | 217 char client_name[40]; |
214 opt_t subopts[] = { | 218 opt_t subopts[] = { |
215 {"port", OPT_ARG_MSTRZ, &port_name, NULL}, | 219 {"port", OPT_ARG_MSTRZ, &port_name, NULL}, |
220 {"estimate", OPT_ARG_BOOL, &estimate, NULL}, | |
216 {NULL} | 221 {NULL} |
217 }; | 222 }; |
218 int port_flags = JackPortIsInput; | 223 int port_flags = JackPortIsInput; |
219 int i; | 224 int i; |
225 estimate = 1; | |
220 if (subopt_parse(ao_subdevice, subopts) != 0) { | 226 if (subopt_parse(ao_subdevice, subopts) != 0) { |
221 print_help(); | 227 print_help(); |
222 return 0; | 228 return 0; |
223 } | 229 } |
224 if (channels > MAX_CHANS) { | 230 if (channels > MAX_CHANS) { |
267 } | 273 } |
268 } | 274 } |
269 rate = jack_get_sample_rate(client); | 275 rate = jack_get_sample_rate(client); |
270 jack_latency = (float)(jack_port_get_total_latency(client, ports[0]) + | 276 jack_latency = (float)(jack_port_get_total_latency(client, ports[0]) + |
271 jack_get_buffer_size(client)) / (float)rate; | 277 jack_get_buffer_size(client)) / (float)rate; |
278 callback_interval = 0; | |
272 buffer = (unsigned char *) malloc(BUFFSIZE); | 279 buffer = (unsigned char *) malloc(BUFFSIZE); |
273 | 280 |
274 ao_data.channels = channels; | 281 ao_data.channels = channels; |
275 ao_data.samplerate = rate; | 282 ao_data.samplerate = rate; |
276 ao_data.format = AF_FORMAT_FLOAT_NE; | 283 ao_data.format = AF_FORMAT_FLOAT_NE; |
341 } | 348 } |
342 | 349 |
343 static float get_delay() { | 350 static float get_delay() { |
344 int buffered = BUFFSIZE - CHUNK_SIZE - buf_free(); // could be less | 351 int buffered = BUFFSIZE - CHUNK_SIZE - buf_free(); // could be less |
345 float in_jack = jack_latency; | 352 float in_jack = jack_latency; |
346 #ifdef JACK_ESTIMATE_DELAY | 353 if (estimate && callback_interval > 0) { |
347 unsigned int elapsed = GetTimer() - callback_time; | 354 float elapsed = (float)GetTimer() / 1000000.0 - callback_time; |
348 in_jack += (float)callback_samples / (float)ao_data.samplerate - (float)elapsed / 1000.0 / 1000.0; | 355 in_jack += callback_interval - elapsed; |
349 if (in_jack < 0) in_jack = 0; | 356 if (in_jack < 0) in_jack = 0; |
350 #endif | 357 } |
351 return (float)buffered / (float)ao_data.bps + in_jack; | 358 return (float)buffered / (float)ao_data.bps + in_jack; |
352 } | 359 } |
353 | 360 |