b666a5d2b5
* newer ffmpeg * use sndio in lqtplay
196 lines
4.8 KiB
Plaintext
196 lines
4.8 KiB
Plaintext
$OpenBSD: patch-utils_lqtplay_c,v 1.6 2010/05/26 22:31:23 jakemsr Exp $
|
|
--- utils/lqtplay.c.orig Thu Jan 14 10:41:17 2010
|
|
+++ utils/lqtplay.c Wed May 26 15:23:48 2010
|
|
@@ -41,6 +41,8 @@
|
|
|
|
#include "common.h"
|
|
|
|
+#define HAVE_SNDIO
|
|
+
|
|
#include <X11/Xlib.h>
|
|
#include <X11/Intrinsic.h>
|
|
#include <X11/StringDefs.h>
|
|
@@ -70,6 +72,10 @@
|
|
#ifdef HAVE_ALSA
|
|
#include <alsa/asoundlib.h>
|
|
#endif
|
|
+#ifdef HAVE_SNDIO
|
|
+#include <poll.h>
|
|
+#include <sndio.h>
|
|
+#endif
|
|
|
|
#include <unistd.h>
|
|
#include <stdlib.h>
|
|
@@ -789,6 +795,88 @@ return 0;
|
|
|
|
|
|
/* ------------------------------------------------------------------------ */
|
|
+/* sndio code */
|
|
+
|
|
+#ifdef HAVE_SNDIO
|
|
+
|
|
+static struct sio_hdl *hdl;
|
|
+static struct sio_par par;
|
|
+
|
|
+static int use_sndio = 1;
|
|
+
|
|
+static int oss_sr,oss_hr;
|
|
+
|
|
+#else
|
|
+
|
|
+/* Disable sndio */
|
|
+static int use_sndio = 0;
|
|
+
|
|
+#endif /* HAVE_SNDIO */
|
|
+
|
|
+static int
|
|
+sndio_setformat(int chan, int rate)
|
|
+{
|
|
+#ifdef HAVE_SNDIO
|
|
+ sio_initpar(&par);
|
|
+ par.bits = 16;
|
|
+ par.sig = 1;
|
|
+ par.rate = rate;
|
|
+ par.pchan = chan;
|
|
+ /* yes, lqtplay wants really small blocks */
|
|
+ par.round = rate / 100;
|
|
+ par.appbufsz = par.round * 25;
|
|
+
|
|
+ if (!sio_setpar(hdl, &par) || !sio_getpar(hdl, &par)) {
|
|
+ fprintf(stderr,_("ERROR: can't set sound format\n"));
|
|
+ exit(1);
|
|
+ }
|
|
+
|
|
+ if (par.pchan != chan || par.bits != 16 || par.sig != 1 ||
|
|
+ par.le != SIO_LE_NATIVE) {
|
|
+ fprintf(stderr,_("ERROR: can't set requested sound format\n"));
|
|
+ exit(1);
|
|
+ }
|
|
+
|
|
+ if (par.rate != rate) {
|
|
+ oss_sr = rate;
|
|
+ oss_hr = par.rate;
|
|
+ fprintf(stderr,_("WARNING: sample rate mismatch (need %d, got %d)\n"),
|
|
+ rate, par.rate);
|
|
+ }
|
|
+
|
|
+ return 0;
|
|
+#else
|
|
+ return 1;
|
|
+#endif
|
|
+}
|
|
+
|
|
+static int sndio_init(char *dev, int channels, int rate)
|
|
+{
|
|
+#ifdef HAVE_SNDIO
|
|
+
|
|
+ /* this code is absolutely horrible. lqtplay expects to be able
|
|
+ to write at least every 2 ms. do not follow this example. */
|
|
+
|
|
+ hdl = sio_open(NULL, SIO_PLAY, 1);
|
|
+ if (NULL == hdl) {
|
|
+ fprintf(stderr,_("ERROR: can't open sndio\n"));
|
|
+ return -1;
|
|
+ }
|
|
+ sndio_setformat(channels,rate);
|
|
+
|
|
+ if (!sio_start(hdl)) {
|
|
+ fprintf(stderr,_("ERROR: can't start sndio\n"));
|
|
+ return -1;
|
|
+ }
|
|
+ return 0;
|
|
+#else
|
|
+ return 1;
|
|
+#endif
|
|
+}
|
|
+
|
|
+
|
|
+
|
|
+/* ------------------------------------------------------------------------ */
|
|
/* oss code */
|
|
|
|
#ifndef AFMT_S16_NE
|
|
@@ -972,7 +1060,11 @@ static void qt_init(FILE *fp, char *filename)
|
|
qt_hasaudio = 1;
|
|
qt_channels = quicktime_track_channels(qt,0);
|
|
qt_sample_rate = quicktime_sample_rate(qt,0);
|
|
- if (use_alsa == 1) {
|
|
+ if (use_sndio == 1) {
|
|
+ if (-1 == sndio_init(adev_name, qt_channels,
|
|
+ qt_sample_rate)) {
|
|
+ qt_hasaudio = 0;}
|
|
+ } else if (use_alsa == 1) {
|
|
if (-1 == alsa_init(adev_name, qt_channels,
|
|
qt_sample_rate)) {
|
|
qt_hasaudio = 0;}
|
|
@@ -1422,6 +1514,48 @@ static int qt_alsa_audio_write()
|
|
return 0;
|
|
}
|
|
|
|
+static int qt_sndio_audio_write(void)
|
|
+{
|
|
+#ifdef HAVE_SNDIO
|
|
+ struct pollfd pfd;
|
|
+ int rc, n, revents;
|
|
+
|
|
+ if(!qt_audio_samples_in_buffer)
|
|
+ decode_audio(AUDIO_BLOCK_SIZE);
|
|
+
|
|
+ /* this code is absolutely horrible. do not follow this example. */
|
|
+
|
|
+ n = sio_pollfd(hdl, &pfd, POLLOUT);
|
|
+ rc = poll(&pfd, n, 10000);
|
|
+ if (rc <= 0)
|
|
+ goto fail;
|
|
+ revents = sio_revents(hdl, &pfd);
|
|
+ if (!(revents & POLLOUT))
|
|
+ goto fail;
|
|
+ rc = sio_write(hdl,qt_audio_ptr,qt_audio_samples_in_buffer * qt_channels * sizeof(*qt_audio));
|
|
+ switch (rc) {
|
|
+ case 0:
|
|
+ goto fail;
|
|
+ break;
|
|
+ default:
|
|
+ qt_audio_samples_in_buffer -= rc / (qt_channels * sizeof(*qt_audio));
|
|
+ qt_audio_ptr += rc / sizeof(*qt_audio);
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ if (qt_audio_eof && 0 == qt_audio_samples_in_buffer) {
|
|
+ return -1;
|
|
+ }
|
|
+#endif
|
|
+ return 0;
|
|
+fail:
|
|
+ fprintf(stderr,_("write sndio: Huh? no data to write/no data written?\n"));
|
|
+ sio_close(hdl);
|
|
+ hdl = NULL;
|
|
+ qt_hasaudio = 0;
|
|
+ return 0;
|
|
+}
|
|
+
|
|
static int qt_oss_audio_write(void)
|
|
{
|
|
int rc;
|
|
@@ -1803,7 +1937,7 @@ int main(int argc, char *argv[])
|
|
FD_SET(ConnectionNumber(dpy),&rd);
|
|
max = ConnectionNumber(dpy);
|
|
if (qt_hasaudio) {
|
|
- if (use_alsa == 0) {
|
|
+ if (use_alsa == 0 && use_sndio == 0) {
|
|
FD_SET(oss_fd,&wr);
|
|
if (oss_fd > max)
|
|
max = oss_fd;
|
|
@@ -1841,7 +1975,10 @@ int main(int argc, char *argv[])
|
|
}
|
|
rc = select(max+1,&rd,&wr,NULL,&wait);
|
|
if (qt_hasaudio) {
|
|
- if (use_alsa == 1) {
|
|
+ if (use_sndio == 1) {
|
|
+ if (0 != qt_sndio_audio_write()) qt_hasaudio = 0;
|
|
+ }
|
|
+ else if (use_alsa == 1) {
|
|
if (0 != qt_alsa_audio_write()) qt_hasaudio = 0;
|
|
}
|
|
else if (FD_ISSET(oss_fd,&wr)) {
|