Below is an update of mplayer sndio backend:
- use sndiod volume knob if available, rather than
chaining two soft volume knobs (consumes less CPU)
- stop audio during pause, consumes less CPU
- remove unnecessary checks
- honour AOPLAY_FINAL_CHUNK flag, fixes playback of
very short files
comments? ok?
-- Alexandre
Index: Makefile
===
RCS file: /cvs/ports/x11/mplayer/Makefile,v
retrieving revision 1.197
diff -u -p -r1.197 Makefile
--- Makefile30 Dec 2011 17:40:40 - 1.197
+++ Makefile24 Jan 2012 22:21:08 -
@@ -13,7 +13,7 @@ SUBST_VARS += PREFIX CONFDIR
# Distfiles must be hand-rolled, see README
N =mplayer
DISTNAME = mplayer-${V}
-REVISION = 11
+REVISION = 12
CATEGORIES = x11 multimedia
Index: files/ao_sndio.c
===
RCS file: /cvs/ports/x11/mplayer/files/ao_sndio.c,v
retrieving revision 1.6
diff -u -p -r1.6 ao_sndio.c
--- files/ao_sndio.c8 Nov 2010 21:25:44 - 1.6
+++ files/ao_sndio.c24 Jan 2012 22:21:08 -
@@ -40,7 +40,7 @@ LIBAO_EXTERN(sndio)
static struct sio_hdl *hdl = NULL;
static struct sio_par par;
-static long long realpos = 0, playpos = 0;
+static int delay, vol, havevol;
#define SILENCE_NMAX 0x1000
static char silence[SILENCE_NMAX];
@@ -49,7 +49,21 @@ static char silence[SILENCE_NMAX];
*/
static int control(int cmd, void *arg)
{
- return CONTROL_FALSE;
+ ao_control_vol_t *ctl = arg;
+
+ if (!havevol)
+ return CONTROL_FALSE;
+ switch (cmd) {
+ case AOCONTROL_GET_VOLUME:
+ ctl->left = ctl->right = vol * 100 / SIO_MAXVOL;
+ break;
+ case AOCONTROL_SET_VOLUME:
+ sio_setvol(hdl, ctl->left * SIO_MAXVOL / 100);
+ break;
+ default:
+ return CONTROL_UNKNOWN;
+ }
+ return CONTROL_OK;
}
/*
@@ -57,7 +71,15 @@ static int control(int cmd, void *arg)
*/
static void movecb(void *addr, int delta)
{
- realpos += delta * (int)(par.bps * par.pchan);
+ delay -= delta * (int)(par.bps * par.pchan);
+}
+
+/*
+ * call-back invoked to notify about volume changes
+ */
+static void volcb(void *addr, unsigned newvol)
+{
+ vol = newvol;
}
/*
@@ -74,7 +96,6 @@ static int init(int rate, int channels,
mp_msg(MSGT_AO, MSGL_ERR, "ao2: can't open sndio\n");
return 0;
}
-
sio_initpar(&par);
switch (format) {
case AF_FORMAT_U8:
@@ -194,24 +215,22 @@ static int init(int rate, int channels,
}
bpf = par.bps * par.pchan;
- ao_data.samplerate = par.rate;
ao_data.channels = par.pchan;
ao_data.format = ac3 ? AF_FORMAT_AC3_NE : format;
ao_data.bps = bpf * par.rate;
ao_data.buffersize = par.appbufsz * bpf;
ao_data.outburst = par.round * bpf;
+ /* avoid resampling for close rates */
+ if ((par.rate >= rate * 0.97) && (par.rate <= rate * 1.03))
+ ao_data.samplerate = rate;
+ else
+ ao_data.samplerate = par.rate;
+ havevol = sio_onvol(hdl, volcb, NULL);
sio_onmove(hdl, movecb, NULL);
- realpos = playpos = 0;
+ delay = 0;
if (!sio_start(hdl)) {
mp_msg(MSGT_AO, MSGL_ERR, "ao2: init: couldn't start\n");
}
-
- /* avoid resampling for close rates */
- if ((ao_data.samplerate >= rate * 0.97) &&
- (ao_data.samplerate <= rate * 1.03)) {
- ao_data.samplerate = rate;
- }
-
if (ao_data.samplerate != rate) {
/* apparently mplayer rounds a little when resampling.
* anyway, it doesn't write quite a full buffer on the first
@@ -220,8 +239,8 @@ static int init(int rate, int channels,
* enough for everything I have come across.
*/
sio_write(hdl, silence, 8 * bpf);
+ delay += 8 * bpf;
}
-
return 1;
}
@@ -237,11 +256,12 @@ static void uninit(int immed)
/*
* stop playing and empty buffers (for seeking/pause)
*/
-static void reset(void) {
+static void reset(void)
+{
if (!sio_stop(hdl)) {
mp_msg(MSGT_AO, MSGL_ERR, "ao2: reset: couldn't stop\n");
}
- realpos = playpos = 0;
+ delay = 0;
if (!sio_start(hdl)) {
mp_msg(MSGT_AO, MSGL_ERR, "ao2: reset: couldn't start\n");
}
@@ -253,19 +273,17 @@ static void reset(void) {
static int get_space(void)
{
struct pollfd pfd;
- int bufused, space, revents, n;
+ int bufused, revents, n;
/*
* call poll() and sio_revents(), so the
-* playpos and realpos counters are updated
+* delay counter is updated
*/
n = sio_pollfd(hdl, &pfd, POLLOUT);