This diff is supposed to make video smoother with the sndio backend. It also adds support for 24-bit encodings, makes use of the sndiod volume knob, removes the need for portaudio and makes sndio the default backend on OpenBSD.
I'm very interested in any regressions, and stuff that used to work, possibly with other backends, but that doesn't work with this one. Comments? OK? -- Alexandre Index: Makefile =================================================================== RCS file: /cvs/ports/x11/vlc/Makefile,v retrieving revision 1.147 diff -u -p -r1.147 Makefile --- Makefile 3 May 2012 06:51:25 -0000 1.147 +++ Makefile 20 May 2012 21:41:50 -0000 @@ -8,7 +8,7 @@ COMMENT-jack= JACK audio output module f V= 2.0.1 DISTNAME= vlc-${V} PKGNAME-main= ${DISTNAME} -REVISION-main= 0 +REVISION-main= 1 PKGNAME-jack= vlc-jack-${V} CATEGORIES= x11 MASTER_SITES= http://download.videolan.org/pub/videolan/vlc/${V}/ @@ -37,10 +37,10 @@ WANTLIB-main= GL ICE lib/qt4/QtGui QtCor gmp gnutls gobject-2.0 gpg-error gsm gthread-2.0 gtk-x11-2.0 \ hogweed jpeg matroska mp3lame nettle notify orc-0.4 ogg \ p11-kit pango-1.0 pangocairo-1.0 pangoft2-1.0 pcre pixman-1 \ - png portaudio postproc proxy pthread-stubs pthread samplerate \ - sndio schroedinger-1.0>=2.0 sndio speex speexdsp swscale tag \ - tar tasn1 tiff theoradec theoraenc usbhid vorbis vorbisenc \ - vpx webp x264 xcb-composite xcb-keysyms xcb-randr xcb-render \ + png postproc proxy pthread-stubs pthread samplerate sndio \ + schroedinger-1.0>=2.0 sndio speex speexdsp swscale tag tar \ + tasn1 tiff theoradec theoraenc usbhid vorbis vorbisenc vpx \ + webp x264 xcb-composite xcb-keysyms xcb-randr xcb-render \ xcb-shape xcb-shm xcb-xfixes xcb-xv xcb xml2 xvidcore z \ ${WANTLIB-common} WANTLIB-jack= jack vlccore ${WANTLIB-common} @@ -60,7 +60,6 @@ LIB_DEPENDS-main= ${LIB_DEPENDS} \ audio/libcddb \ audio/libsamplerate \ audio/libvorbis \ - audio/portaudio-svn \ audio/speex \ audio/taglib \ devel/fribidi \ @@ -130,6 +129,7 @@ CONFIGURE_ARGS+=--disable-a52 \ --disable-mpc \ --disable-mtp \ --disable-neon \ + --disable-portaudio \ --disable-projectm \ --disable-pulse \ --disable-shout \ Index: files/sndio.c =================================================================== RCS file: /cvs/ports/x11/vlc/files/sndio.c,v retrieving revision 1.1 diff -u -p -r1.1 sndio.c --- files/sndio.c 23 Apr 2012 13:47:08 -0000 1.1 +++ files/sndio.c 20 May 2012 21:41:50 -0000 @@ -2,6 +2,7 @@ * sndio.c : sndio plugin for VLC ***************************************************************************** * Copyright (C) 2012 R??mi Denis-Courmont + * Copyright (C) 2012 Alexandre Ratchov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by @@ -27,6 +28,7 @@ #include <vlc_common.h> #include <vlc_plugin.h> #include <vlc_aout.h> +#include <vlc_aout_intf.h> #include <sndio.h> @@ -35,159 +37,208 @@ static void Close (vlc_object_t *); vlc_module_begin () set_shortname ("sndio") - set_description (N_("OpenBSD sndio audio output")) + set_description (N_("sndio audio output")) set_category (CAT_AUDIO) set_subcategory (SUBCAT_AUDIO_AOUT) - set_capability ("audio output", 0) + set_capability ("audio output", 200) set_callbacks (Open, Close ) vlc_module_end () static void Play (audio_output_t *, block_t *); static void Pause (audio_output_t *, bool, mtime_t); +static void Flush (audio_output_t *, bool); +static int VolumeSet(audio_output_t *, float, bool); + +struct aout_sys_t +{ + struct sio_hdl *hdl; + int delay, bpf; +}; + +static void onmove (void *addr, int delta) +{ + audio_output_t *aout = (audio_output_t *)addr; + struct aout_sys_t *sys = (struct aout_sys_t *)aout->sys; + + sys->delay -= delta; +} /** Initializes an sndio playback stream */ static int Open (vlc_object_t *obj) { + char fourcc[4]; + unsigned int chans; audio_output_t *aout = (audio_output_t *)obj; + struct aout_sys_t *sys; + struct sio_hdl *hdl; + struct sio_par par; - struct sio_hdl *sio = sio_open (NULL, SIO_PLAY, 0 /* blocking */); - if (sio == NULL) + hdl = sio_open (NULL, SIO_PLAY, 0); + if (hdl == NULL) { msg_Err (obj, "cannot create audio playback stream"); return VLC_EGENERIC; } - struct sio_par par; sio_initpar (&par); - par.bits = 16; - par.bps = par.bits >> 3; - par.sig = 1; - par.le = SIO_LE_NATIVE; + vlc_fourcc_to_char (aout->format.i_format, fourcc); + do { + if (fourcc[0] == 's') + par.sig = 1; + else if (fourcc[0] == 'u') + par.sig = 0; + else + break; + if (fourcc[1] == '8' && fourcc[2] == ' ' && fourcc[3] == ' ') { + par.bits = 8; + break; + } else if (fourcc[1] == '1' && fourcc[2] == '6') { + par.bits = 16; + } else if (fourcc[1] == '2' && fourcc[2] == '4') { + par.bits = 24; + par.bps = 3; + } else if (fourcc[1] == '3' && fourcc[2] == '2') { + par.bits = 32; + } + if (fourcc[3] == 'l') + par.le = 1; + else if (fourcc[3] == 'b') + par.le = 0; + else + break; + } while (0); par.pchan = aout_FormatNbChannels (&aout->format); par.rate = aout->format.i_rate; - par.xrun = SIO_SYNC; - - if (!sio_setpar (sio, &par) || !sio_getpar (sio, &par)) + par.appbufsz = par.rate / 2; + if (!sio_setpar (hdl, &par) || !sio_getpar (hdl, &par)) { msg_Err (obj, "cannot negotiate audio playback parameters"); goto error; } - if (par.bps != par.bits >> 3) - { - msg_Err (obj, "unsupported audio sample format (%u bits in %u bytes)", - par.bits, par.bps); - goto error; - } - - audio_format_t f; - - switch (par.bits) - { - case 8: - f.i_format = par.sig ? VLC_CODEC_S8 : VLC_CODEC_U8; - break; - case 16: - f.i_format = par.sig ? (par.le ? VLC_CODEC_S16L : VLC_CODEC_S16B) - : (par.le ? VLC_CODEC_U16L : VLC_CODEC_U16B); - break; - case 24: - f.i_format = par.sig ? (par.le ? VLC_CODEC_S24L : VLC_CODEC_S24B) - : (par.le ? VLC_CODEC_U24L : VLC_CODEC_U24B); - break; - case 32: - f.i_format = par.sig ? (par.le ? VLC_CODEC_S32L : VLC_CODEC_S32B) - : (par.le ? VLC_CODEC_U32L : VLC_CODEC_U32B); - break; - default: - msg_Err (obj, "unsupported audio sample format (%u bits)", - par.bits); - goto error; + fourcc[0] = par.sig ? 's' : 'u'; + if (par.bps == 1) { + fourcc[1] = '8'; + fourcc[2] = ' '; + fourcc[3] = ' '; + } else { + fourcc[1] = '0' + (par.bps << 3) / 10; + fourcc[2] = '0' + (par.bps << 3) % 10; + fourcc[3] = par.le ? 'l' : 'b'; + if (par.bits < (par.bps << 3) && !par.msb) { + msg_Err (obj, "unsupported LSB alignement (%u bits in %u bytes)", + par.bits, par.bps); + goto error; + } } - f.i_rate = par.rate; - /* Channel map */ - unsigned chans; switch (par.pchan) { case 1: chans = AOUT_CHAN_CENTER; break; case 2: - chans = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT; + chans = AOUT_CHANS_STEREO; break; case 4: - chans = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT - | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT; + chans = AOUT_CHANS_4_0; break; case 6: - chans = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT - | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT - | AOUT_CHAN_CENTER | AOUT_CHAN_LFE; + chans = AOUT_CHANS_5_1; + break; + case 8: + chans = AOUT_CHANS_7_1; break; default: msg_Err (aout, "unknown %u channels map", par.pchan); goto error; } - f.i_original_channels = f.i_physical_channels = chans; - aout_FormatPrepare (&f); - - aout->format = f; - aout->sys = (void *)sio; + sys = malloc (sizeof(struct aout_sys_t)); + if (sys == NULL) { + msg_Err (aout, "failed to allocate sndio structure"); + goto error; + } + sys->hdl = hdl; + sys->bpf = par.bps * par.pchan; + sys->delay = 0; + aout->sys = sys; + aout->format.i_format = + VLC_FOURCC(fourcc[0], fourcc[1], fourcc[2], fourcc[3]); + aout->format.i_original_channels = chans; + aout->format.i_physical_channels = chans; + aout->format.i_rate = par.rate; aout->pf_play = Play; aout->pf_pause = Pause; - aout->pf_flush = NULL; /* sndio sucks! */ - aout_VolumeSoftInit (aout); /* TODO: sio_onvol() */ - - sio_start (sio); + aout->pf_flush = Flush; + aout_VolumeHardInit (aout, VolumeSet); + VolumeSet(aout, + var_InheritInteger (aout, "volume") / (float)AOUT_VOLUME_DEFAULT, + var_InheritBool (aout, "mute")); + sio_onmove (hdl, onmove, aout); + sio_start (hdl); return VLC_SUCCESS; error: - sio_close (sio); + sio_close (hdl); return VLC_EGENERIC; } static void Close (vlc_object_t *obj) { audio_output_t *aout = (audio_output_t *)obj; - struct sio_hdl *sio = (void *)aout->sys; + struct aout_sys_t *sys = (struct aout_sys_t *)aout->sys; - sio_close (sio); + sio_close (sys->hdl); + free (sys); } static void Play (audio_output_t *aout, block_t *block) { - struct sio_hdl *sio = (void *)aout->sys; - struct sio_par par; + struct aout_sys_t *sys = (struct aout_sys_t *)aout->sys; - if (sio_getpar (sio, &par) == 0) - { - mtime_t delay = par.bufsz * CLOCK_FREQ / aout->format.i_rate; - - delay = block->i_pts - (mdate () - delay); - aout_TimeReport (aout, block->i_pts - delay); - } + aout_TimeReport (aout, block->i_pts - + sys->delay * CLOCK_FREQ / aout->format.i_rate); + sio_write (sys->hdl, block->p_buffer, block->i_nb_samples * sys->bpf); + sys->delay += block->i_nb_samples; + block_Release (block); +} - while (block->i_buffer > 0 && !sio_eof (sio)) - { - size_t bytes = sio_write (sio, block->p_buffer, block->i_buffer); +static void Pause (audio_output_t *aout, bool pause, mtime_t date) +{ + struct aout_sys_t *sys = (struct aout_sys_t *)aout->sys; - block->p_buffer += bytes; - block->i_buffer -= bytes; - /* Note that i_nb_samples and i_pts are corrupted here. */ + if (pause) { + sio_stop (sys->hdl); + sio_start (sys->hdl); + sys->delay = 0; } - block_Release (block); + (void)date; } -static void Pause (audio_output_t *aout, bool pause, mtime_t date) +static void Flush (audio_output_t *aout, bool wait) { - struct sio_hdl *sio = (void *)aout->sys; + struct aout_sys_t *sys = (struct aout_sys_t *)aout->sys; + + sys->delay = 0; + (void)wait; +} + +static int VolumeSet(audio_output_t *aout, float vol, bool mute) +{ + struct aout_sys_t *sys = (struct aout_sys_t *)aout->sys; + int ctl; - if (pause) - sio_stop (sio); - else - sio_start (sio); - (void) date; + if (mute) + ctl = 0; + else { + if (vol < 0) + vol = 0; + if (vol > 1) + vol = 1; + ctl = vol * SIO_MAXVOL; + } + sio_setvol (sys->hdl, ctl); + return VLC_SUCCESS; } Index: patches/patch-modules_audio_output_portaudio_c =================================================================== RCS file: /cvs/ports/x11/vlc/patches/patch-modules_audio_output_portaudio_c,v retrieving revision 1.1 diff -u -p -r1.1 patch-modules_audio_output_portaudio_c --- patches/patch-modules_audio_output_portaudio_c 23 Apr 2012 13:47:08 -0000 1.1 +++ patches/patch-modules_audio_output_portaudio_c 20 May 2012 21:41:50 -0000 @@ -1,12 +0,0 @@ -$OpenBSD: patch-modules_audio_output_portaudio_c,v 1.1 2012/04/23 13:47:08 ajacoutot Exp $ ---- modules/audio_output/portaudio.c.orig Sun Feb 12 22:17:51 2012 -+++ modules/audio_output/portaudio.c Sun Feb 12 22:18:11 2012 -@@ -114,7 +114,7 @@ vlc_module_begin () - set_subcategory( SUBCAT_AUDIO_AOUT ) - add_integer( "portaudio-audio-device", 0, - DEVICE_TEXT, DEVICE_LONGTEXT, false ) -- set_capability( "audio output", 0 ) -+ set_capability( "audio output", 20 ) - set_callbacks( Open, Close ) - vlc_module_end () - Index: pkg/PLIST-main =================================================================== RCS file: /cvs/ports/x11/vlc/pkg/PLIST-main,v retrieving revision 1.22 diff -u -p -r1.22 PLIST-main --- pkg/PLIST-main 3 May 2012 06:51:25 -0000 1.22 +++ pkg/PLIST-main 20 May 2012 21:41:51 -0000 @@ -166,7 +166,6 @@ lib/vlc/plugins/audio_output/ lib/vlc/plugins/audio_output/libadummy_plugin.so lib/vlc/plugins/audio_output/libamem_plugin.so lib/vlc/plugins/audio_output/libaout_file_plugin.so -lib/vlc/plugins/audio_output/libportaudio_plugin.so lib/vlc/plugins/audio_output/libsndio_plugin.so lib/vlc/plugins/codec/ lib/vlc/plugins/codec/liba52_plugin.so