demux_lavf: try harder to make up a frame rate
[mplayer.git] / libao2 / ao_esd.c
blobe7c6701aa0de6ac9678f7d12faf2a802ef3cadd2
1 /*
2 * EsounD audio output driver for MPlayer
4 * copyright (c) 2002 Juergen Keil <jk@tools.de>
6 * This file is part of MPlayer.
8 * MPlayer is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * MPlayer is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License along
19 * with MPlayer; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 * TODO / known problems:
25 * - does not work well when the esd daemon has autostandby disabled
26 * (workaround: run esd with option "-as 2" - fortunatelly this is
27 * the default)
28 * - plays noise on a linux 2.4.4 kernel with a SB16PCI card, when using
29 * a local tcp connection to the esd daemon; there is no noise when using
30 * a unix domain socket connection.
31 * (there are EIO errors reported by the sound card driver, so this is
32 * most likely a linux sound card driver problem)
35 #include <sys/types.h>
36 #include <sys/time.h>
37 #include <sys/socket.h>
38 #include <stdio.h>
39 #include <string.h>
40 #include <unistd.h>
41 #include <errno.h>
42 #include <fcntl.h>
43 #include <time.h>
44 #ifdef __svr4__
45 #include <stropts.h>
46 #endif
47 #include <esd.h>
49 #include "config.h"
50 #include "audio_out.h"
51 #include "audio_out_internal.h"
52 #include "libaf/af_format.h"
53 #include "mp_msg.h"
56 #define ESD_RESAMPLES 0
57 #define ESD_DEBUG 0
59 #if ESD_DEBUG
60 #define dprintf(...) printf(__VA_ARGS__)
61 #else
62 #define dprintf(...) /**/
63 #endif
66 #define ESD_CLIENT_NAME "MPlayer"
67 #define ESD_MAX_DELAY (1.0f) /* max amount of data buffered in esd (#sec) */
69 static const ao_info_t info =
71 "EsounD audio output",
72 "esd",
73 "Juergen Keil <jk@tools.de>",
77 LIBAO_EXTERN(esd)
79 static int esd_fd = -1;
80 static int esd_play_fd = -1;
81 static esd_server_info_t *esd_svinfo;
82 static int esd_latency;
83 static int esd_bytes_per_sample;
84 static unsigned long esd_samples_written;
85 static struct timeval esd_play_start;
86 extern float audio_delay;
89 * to set/get/query special features/parameters
91 static int control(int cmd, void *arg)
93 esd_player_info_t *esd_pi;
94 esd_info_t *esd_i;
95 time_t now;
96 static time_t vol_cache_time;
97 static ao_control_vol_t vol_cache;
99 switch (cmd) {
100 case AOCONTROL_GET_VOLUME:
101 time(&now);
102 if (now == vol_cache_time) {
103 *(ao_control_vol_t *)arg = vol_cache;
104 return CONTROL_OK;
107 dprintf("esd: get vol\n");
108 if ((esd_i = esd_get_all_info(esd_fd)) == NULL)
109 return CONTROL_ERROR;
111 for (esd_pi = esd_i->player_list; esd_pi != NULL; esd_pi = esd_pi->next)
112 if (strcmp(esd_pi->name, ESD_CLIENT_NAME) == 0)
113 break;
115 if (esd_pi != NULL) {
116 ao_control_vol_t *vol = (ao_control_vol_t *)arg;
117 vol->left = esd_pi->left_vol_scale * 100 / ESD_VOLUME_BASE;
118 vol->right = esd_pi->right_vol_scale * 100 / ESD_VOLUME_BASE;
120 vol_cache = *vol;
121 vol_cache_time = now;
123 esd_free_all_info(esd_i);
125 return CONTROL_OK;
127 case AOCONTROL_SET_VOLUME:
128 dprintf("esd: set vol\n");
129 if ((esd_i = esd_get_all_info(esd_fd)) == NULL)
130 return CONTROL_ERROR;
132 for (esd_pi = esd_i->player_list; esd_pi != NULL; esd_pi = esd_pi->next)
133 if (strcmp(esd_pi->name, ESD_CLIENT_NAME) == 0)
134 break;
136 if (esd_pi != NULL) {
137 ao_control_vol_t *vol = (ao_control_vol_t *)arg;
138 esd_set_stream_pan(esd_fd, esd_pi->source_id,
139 vol->left * ESD_VOLUME_BASE / 100,
140 vol->right * ESD_VOLUME_BASE / 100);
142 vol_cache = *vol;
143 time(&vol_cache_time);
145 esd_free_all_info(esd_i);
146 return CONTROL_OK;
148 default:
149 return CONTROL_UNKNOWN;
155 * open & setup audio device
156 * return: 1=success 0=fail
158 static int init(int rate_hz, int channels, int format, int flags)
160 esd_format_t esd_fmt;
161 int bytes_per_sample;
162 int fl;
163 char *server = ao_subdevice; /* NULL for localhost */
164 float lag_seconds, lag_net = 0., lag_serv;
165 struct timeval proto_start, proto_end;
167 global_ao->no_persistent_volume = true;
169 if (esd_fd < 0) {
170 esd_fd = esd_open_sound(server);
171 if (esd_fd < 0) {
172 mp_tmsg(MSGT_AO, MSGL_ERR, "[AO ESD] esd_open_sound failed: %s\n",
173 strerror(errno));
174 return 0;
177 /* get server info, and measure network latency */
178 gettimeofday(&proto_start, NULL);
179 esd_svinfo = esd_get_server_info(esd_fd);
180 if(server) {
181 gettimeofday(&proto_end, NULL);
182 lag_net = (proto_end.tv_sec - proto_start.tv_sec) +
183 (proto_end.tv_usec - proto_start.tv_usec) / 1000000.0;
184 lag_net /= 2.0; /* round trip -> one way */
185 } else
186 lag_net = 0.0; /* no network lag */
189 if (esd_svinfo) {
190 mp_msg(MSGT_AO, MSGL_INFO, "AO: [esd] server info:\n");
191 esd_print_server_info(esd_svinfo);
196 esd_fmt = ESD_STREAM | ESD_PLAY;
198 #if ESD_RESAMPLES
199 /* let the esd daemon convert sample rate */
200 #else
201 /* let mplayer's audio filter convert the sample rate */
202 if (esd_svinfo != NULL)
203 rate_hz = esd_svinfo->rate;
204 #endif
205 ao_data.samplerate = rate_hz;
207 /* EsounD can play mono or stereo */
208 switch (channels) {
209 case 1:
210 esd_fmt |= ESD_MONO;
211 ao_data.channels = bytes_per_sample = 1;
212 break;
213 default:
214 esd_fmt |= ESD_STEREO;
215 ao_data.channels = bytes_per_sample = 2;
216 break;
219 /* EsounD can play 8bit unsigned and 16bit signed native */
220 switch (format) {
221 case AF_FORMAT_S8:
222 case AF_FORMAT_U8:
223 esd_fmt |= ESD_BITS8;
224 ao_data.format = AF_FORMAT_U8;
225 break;
226 default:
227 esd_fmt |= ESD_BITS16;
228 ao_data.format = AF_FORMAT_S16_NE;
229 bytes_per_sample *= 2;
230 break;
233 /* modify audio_delay depending on esd_latency
234 * latency is number of samples @ 44.1khz stereo 16 bit
235 * adjust according to rate_hz & bytes_per_sample
237 #ifdef CONFIG_ESD_LATENCY
238 esd_latency = esd_get_latency(esd_fd);
239 #else
240 esd_latency = ((channels == 1 ? 2 : 1) * ESD_DEFAULT_RATE *
241 (ESD_BUF_SIZE + 64 * (4.0f / bytes_per_sample))
242 ) / rate_hz;
243 esd_latency += ESD_BUF_SIZE * 2;
244 #endif
245 if(esd_latency > 0) {
246 lag_serv = (esd_latency * 4.0f) / (bytes_per_sample * rate_hz);
247 lag_seconds = lag_net + lag_serv;
248 audio_delay += lag_seconds;
249 mp_tmsg(MSGT_AO, MSGL_INFO,"[AO ESD] latency: [server: %0.2fs, net: %0.2fs] (adjust %0.2fs)\n",
250 lag_serv, lag_net, lag_seconds);
253 esd_play_fd = esd_play_stream_fallback(esd_fmt, rate_hz,
254 server, ESD_CLIENT_NAME);
255 if (esd_play_fd < 0) {
256 mp_tmsg(MSGT_AO, MSGL_ERR, "[AO ESD] failed to open ESD playback stream: %s\n", strerror(errno));
257 return 0;
260 /* enable non-blocking i/o on the socket connection to the esd server */
261 if ((fl = fcntl(esd_play_fd, F_GETFL)) >= 0)
262 fcntl(esd_play_fd, F_SETFL, O_NDELAY|fl);
264 #if ESD_DEBUG
266 int sbuf, rbuf, len;
267 len = sizeof(sbuf);
268 getsockopt(esd_play_fd, SOL_SOCKET, SO_SNDBUF, &sbuf, &len);
269 len = sizeof(rbuf);
270 getsockopt(esd_play_fd, SOL_SOCKET, SO_RCVBUF, &rbuf, &len);
271 dprintf("esd: send/receive socket buffer space %d/%d bytes\n",
272 sbuf, rbuf);
274 #endif
276 ao_data.bps = bytes_per_sample * rate_hz;
277 ao_data.outburst = ao_data.bps > 100000 ? 4*ESD_BUF_SIZE : 2*ESD_BUF_SIZE;
279 esd_play_start.tv_sec = 0;
280 esd_samples_written = 0;
281 esd_bytes_per_sample = bytes_per_sample;
283 return 1;
288 * close audio device
290 static void uninit(int immed)
292 if (esd_play_fd >= 0) {
293 esd_close(esd_play_fd);
294 esd_play_fd = -1;
297 if (esd_svinfo) {
298 esd_free_server_info(esd_svinfo);
299 esd_svinfo = NULL;
302 if (esd_fd >= 0) {
303 esd_close(esd_fd);
304 esd_fd = -1;
310 * plays 'len' bytes of 'data'
311 * it should round it down to outburst*n
312 * return: number of bytes played
314 static int play(void* data, int len, int flags)
316 int offs;
317 int nwritten;
318 int nsamples;
319 int n;
321 /* round down buffersize to a multiple of ESD_BUF_SIZE bytes */
322 len = len / ESD_BUF_SIZE * ESD_BUF_SIZE;
323 if (len <= 0)
324 return 0;
326 #define SINGLE_WRITE 0
327 #if SINGLE_WRITE
328 nwritten = write(esd_play_fd, data, len);
329 #else
330 for (offs = 0, nwritten=0; offs + ESD_BUF_SIZE <= len; offs += ESD_BUF_SIZE) {
332 * note: we're writing to a non-blocking socket here.
333 * A partial write means, that the socket buffer is full.
335 n = write(esd_play_fd, (char*)data + offs, ESD_BUF_SIZE);
336 if ( n < 0 ) {
337 if ( errno != EAGAIN )
338 dprintf("esd play: write failed: %s\n", strerror(errno));
339 break;
340 } else if ( n != ESD_BUF_SIZE ) {
341 nwritten += n;
342 break;
343 } else
344 nwritten += n;
346 #endif
348 if (nwritten > 0) {
349 if (!esd_play_start.tv_sec)
350 gettimeofday(&esd_play_start, NULL);
351 nsamples = nwritten / esd_bytes_per_sample;
352 esd_samples_written += nsamples;
354 dprintf("esd play: %d %lu\n", nsamples, esd_samples_written);
355 } else {
356 dprintf("esd play: blocked / %lu\n", esd_samples_written);
359 return nwritten;
364 * stop playing, keep buffers (for pause)
366 static void audio_pause(void)
369 * not possible with esd. the esd daemom will continue playing
370 * buffered data (not more than ESD_MAX_DELAY seconds of samples)
376 * resume playing, after audio_pause()
378 static void audio_resume(void)
381 * not possible with esd.
383 * Let's hope the pause was long enough that the esd ran out of
384 * buffered data; we restart our time based delay computation
385 * for an audio resume.
387 esd_play_start.tv_sec = 0;
388 esd_samples_written = 0;
393 * stop playing and empty buffers (for seeking/pause)
395 static void reset(void)
397 #ifdef __svr4__
398 /* throw away data buffered in the esd connection */
399 if (ioctl(esd_play_fd, I_FLUSH, FLUSHW))
400 perror("I_FLUSH");
401 #endif
406 * return: how many bytes can be played without blocking
408 static int get_space(void)
410 struct timeval tmout;
411 fd_set wfds;
412 float current_delay;
413 int space;
416 * Don't buffer too much data in the esd daemon.
418 * If we send too much, esd will block in write()s to the sound
419 * device, and the consequence is a huge slow down for things like
420 * esd_get_all_info().
422 if ((current_delay = get_delay()) >= ESD_MAX_DELAY) {
423 dprintf("esd get_space: too much data buffered\n");
424 return 0;
427 FD_ZERO(&wfds);
428 FD_SET(esd_play_fd, &wfds);
429 tmout.tv_sec = 0;
430 tmout.tv_usec = 0;
432 if (select(esd_play_fd + 1, NULL, &wfds, NULL, &tmout) != 1)
433 return 0;
435 if (!FD_ISSET(esd_play_fd, &wfds))
436 return 0;
438 /* try to fill 50% of the remaining "free" buffer space */
439 space = (ESD_MAX_DELAY - current_delay) * ao_data.bps * 0.5f;
441 /* round up to next multiple of ESD_BUF_SIZE */
442 space = (space + ESD_BUF_SIZE-1) / ESD_BUF_SIZE * ESD_BUF_SIZE;
444 dprintf("esd get_space: %d\n", space);
445 return space;
450 * return: delay in seconds between first and last sample in buffer
452 static float get_delay(void)
454 struct timeval now;
455 double buffered_samples_time;
456 double play_time;
458 if (!esd_play_start.tv_sec)
459 return 0;
461 buffered_samples_time = (float)esd_samples_written / ao_data.samplerate;
462 gettimeofday(&now, NULL);
463 play_time = now.tv_sec - esd_play_start.tv_sec;
464 play_time += (now.tv_usec - esd_play_start.tv_usec) / 1000000.;
466 /* dprintf("esd delay: %f %f\n", play_time, buffered_samples_time); */
468 if (play_time > buffered_samples_time) {
469 dprintf("esd: underflow\n");
470 esd_play_start.tv_sec = 0;
471 esd_samples_written = 0;
472 return 0;
475 dprintf("esd: get_delay %f\n", buffered_samples_time - play_time);
476 return buffered_samples_time - play_time;