[MPlayer-dev-eng] [PATCH] Add sndio input support

Brad Smith brad at comstyle.com
Wed Mar 12 05:35:30 CET 2014


Here is a diff from our ports tree to add the input support to MPlayer
for sndio.


Index: Makefile
===================================================================
--- Makefile	(revision 36993)
+++ Makefile	(working copy)
@@ -35,6 +35,7 @@
 # conditional source declarations
 SRCS_AUDIO_INPUT-$(ALSA)             += stream/ai_alsa.c
 SRCS_AUDIO_INPUT-$(OSS)              += stream/ai_oss.c
+SRCS_AUDIO_INPUT-$(SNDIO)            += stream/ai_sndio.c
 SRCS_COMMON-$(AUDIO_INPUT)           += $(SRCS_AUDIO_INPUT-yes)
 SRCS_COMMON-$(BITMAP_FONT)           += sub/font_load.c
 SRCS_COMMON-$(CDDA)                  += stream/stream_cdda.c            \
Index: stream/ai_sndio.c
===================================================================
--- stream/ai_sndio.c	(revision 0)
+++ stream/ai_sndio.c	(working copy)
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2008 Jacob Meuser <jakemsr at sdf.lonestar.org>
+ *
+ * This file is part of MPlayer.
+ *
+ * MPlayer is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * MPlayer is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with MPlayer; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "config.h"
+
+#include <sndio.h>
+#include "audio_in.h"
+#include "mp_msg.h"
+#include "help_mp.h"
+
+int ai_sndio_setup(audio_in_t *ai)
+{
+    struct sio_par par;
+
+    sio_initpar(&par);
+
+    par.bits = 16;
+    par.sig = 1;
+    par.le = 1;
+    par.rchan = ai->req_channels;
+    par.rate = ai->req_samplerate;
+    par.appbufsz = ai->req_samplerate;	/* 1 sec */
+
+   if (!sio_setpar(ai->sndio.hdl, &par) || !sio_getpar(ai->sndio.hdl, &par)) {
+	mp_msg(MSGT_TV, MSGL_ERR, "could not configure sndio audio");
+	return -1;
+    }
+
+    ai->channels = par.rchan;
+    ai->samplerate = par.rate;
+    ai->samplesize = par.bits;
+    ai->bytes_per_sample = par.bps;
+    ai->blocksize = par.round * par.bps;
+
+    return 0;
+}
+
+int ai_sndio_init(audio_in_t *ai)
+{
+    int err;
+
+    if ((ai->sndio.hdl = sio_open(ai->sndio.device, SIO_REC, 0)) == NULL) {
+	mp_msg(MSGT_TV, MSGL_ERR, "could not open sndio audio");
+	return -1;
+    }
+
+    err = ai_sndio_setup(ai);
+
+    return err;
+}
Index: stream/audio_in.c
===================================================================
--- stream/audio_in.c	(revision 36993)
+++ stream/audio_in.c	(working copy)
@@ -54,6 +54,12 @@
 	ai->oss.device = strdup("/dev/dsp");
 	return 0;
 #endif
+#ifdef CONFIG_SNDIO_AUDIO
+    case AUDIO_IN_SNDIO:
+	ai->sndio.hdl = NULL;
+	ai->sndio.device = strdup("default");
+	return 0;
+#endif
     default:
 	return -1;
     }
@@ -75,6 +81,12 @@
 	ai->setup = 1;
 	return 0;
 #endif
+#ifdef CONFIG_SNDIO_AUDIO
+    case AUDIO_IN_SNDIO:
+	if (ai_sndio_init(ai) < 0) return -1;
+	ai->setup = 1;
+	return 0;
+#endif
     default:
 	return -1;
     }
@@ -97,6 +109,13 @@
 	if (ai_oss_set_samplerate(ai) < 0) return -1;
 	return ai->samplerate;
 #endif
+#ifdef CONFIG_SNDIO_AUDIO
+    case AUDIO_IN_SNDIO:
+	ai->req_samplerate = rate;
+	if (!ai->setup) return 0;
+	if (ai_sndio_setup(ai) < 0) return -1;
+	return ai->samplerate;
+#endif
     default:
 	return -1;
     }
@@ -119,6 +138,13 @@
 	if (ai_oss_set_channels(ai) < 0) return -1;
 	return ai->channels;
 #endif
+#ifdef CONFIG_SNDIO_AUDIO
+    case AUDIO_IN_SNDIO:
+	ai->req_channels = channels;
+	if (!ai->setup) return 0;
+	if (ai_sndio_setup(ai) < 0) return -1;
+	return ai->channels;
+#endif
     default:
 	return -1;
     }
@@ -147,6 +173,12 @@
 	ai->oss.device = strdup(device);
 	return 0;
 #endif
+#ifdef CONFIG_SNDIO_AUDIO
+    case AUDIO_IN_SNDIO:
+	if (ai->sndio.device) free(ai->sndio.device);
+	ai->sndio.device = strdup(device);
+	return 0;
+#endif
     default:
 	return -1;
     }
@@ -172,6 +204,13 @@
 	    ai->setup = 0;
 	    return 0;
 #endif
+#ifdef CONFIG_SNDIO_AUDIO
+	case AUDIO_IN_SNDIO:
+	    if (ai->sndio.hdl)
+	        sio_close(ai->sndio.hdl);
+	    ai->setup = 0;
+	    return 0;
+#endif
 	}
     }
     return -1;
@@ -188,6 +227,12 @@
     case AUDIO_IN_OSS:
 	return 0;
 #endif
+#ifdef CONFIG_SNDIO_AUDIO
+    case AUDIO_IN_SNDIO:
+	if (!sio_start(ai->sndio.hdl))
+	    return -1;
+	return 0;
+#endif
     default:
 	return -1;
     }
@@ -231,6 +276,19 @@
 	}
 	return ret;
 #endif
+#ifdef CONFIG_SNDIO_AUDIO
+    case AUDIO_IN_SNDIO:
+	ret = sio_read(ai->sndio.hdl, buffer, ai->blocksize);
+	if (ret != ai->blocksize) {
+	    if (ret < 0) {
+		mp_msg(MSGT_TV, MSGL_ERR, MSGTR_MPDEMUX_AUDIOIN_ErrReadingAudio, strerror(errno));
+	    } else {
+		mp_msg(MSGT_TV, MSGL_ERR, MSGTR_MPDEMUX_AUDIOIN_NotEnoughSamples);
+	    }
+	    return -1;
+	}
+	return ret;
+#endif
     default:
 	return -1;
     }
Index: stream/audio_in.h
===================================================================
--- stream/audio_in.h	(revision 36993)
+++ stream/audio_in.h	(working copy)
@@ -21,6 +21,7 @@
 
 #define AUDIO_IN_ALSA 1
 #define AUDIO_IN_OSS 2
+#define AUDIO_IN_SNDIO 3
 
 #include "config.h"
 
@@ -45,6 +46,16 @@
 } ai_oss_t;
 #endif
 
+#ifdef CONFIG_SNDIO_AUDIO
+#include <sndio.h>
+
+typedef struct {
+    char *device;
+
+    struct sio_hdl *hdl;
+} ai_sndio_t;
+#endif
+
 typedef struct
 {
     int type;
@@ -67,6 +78,9 @@
 #ifdef CONFIG_OSS_AUDIO
     ai_oss_t oss;
 #endif
+#ifdef CONFIG_SNDIO_AUDIO
+    ai_sndio_t sndio;
+#endif
 } audio_in_t;
 
 int audio_in_init(audio_in_t *ai, int type);
@@ -90,4 +104,9 @@
 int ai_oss_init(audio_in_t *ai);
 #endif
 
+#ifdef CONFIG_SNDIO_AUDIO
+int ai_sndio_setup(audio_in_t *ai);
+int ai_sndio_init(audio_in_t *ai);
+#endif
+
 #endif /* MPLAYER_AUDIO_IN_H */
Index: stream/tvi_bsdbt848.c
===================================================================
--- stream/tvi_bsdbt848.c	(revision 36993)
+++ stream/tvi_bsdbt848.c	(working copy)
@@ -51,9 +51,10 @@
 #include <signal.h>
 #include <string.h>
 #include <errno.h>
+#include <sys/ioctl.h>
 
 #include <sys/param.h>
-#ifdef CONFIG_SUN_AUDIO
+#if defined(CONFIG_SUN_AUDIO) && !defined(CONFIG_SNDIO_AUDIO)
 #include <sys/audioio.h>
 #endif
 
@@ -65,6 +66,9 @@
 #include IOCTL_BT848_H_NAME
 #endif
 
+#if defined(CONFIG_SNDIO_AUDIO)
+#include <sndio.h>
+#else
 #ifdef HAVE_SYS_SOUNDCARD_H
 #include <sys/soundcard.h>
 #else
@@ -74,6 +78,7 @@
 #include <machine/soundcard.h>
 #endif
 #endif
+#endif
 
 #include "libaf/af_format.h"
 #include "libmpcodecs/img_format.h"
@@ -103,7 +108,13 @@
 /* Audio */
     char *dspdev;
     int dspready;
+#if defined(CONFIG_SNDIO_AUDIO)
+    struct sio_hdl *hdl;
+    struct sio_par par;
+    int round, appbufsz; /* sizes in bytes */
+#else
     int dspfd;
+#endif
     int dspsamplesize;
     int dspstereo;
     int dspspeed;
@@ -111,6 +122,9 @@
     int dspframesize;
     int dsprate;
     long long dspbytesread;
+#if defined(CONFIG_SNDIO_AUDIO)
+    long long realpos;
+#endif
 
 /* Video */
     char *btdev;
@@ -160,6 +174,15 @@
 
 static int getinput(int innumber);
 
+#if defined(CONFIG_SNDIO_AUDIO)
+void movecb(void *addr, int delta)
+{
+    priv_t *priv = addr;
+
+    priv->realpos += delta * priv->dspsamplesize/8 * (priv->dspstereo+1);
+}
+#endif
+
 static void processframe(int signal)
 {
 struct timeval curtime;
@@ -220,7 +243,9 @@
 
     /* set audio device name */
     if (!tv_param->adevice)
-#ifdef CONFIG_SUN_AUDIO
+#if defined(CONFIG_SNDIO_AUDIO)
+        priv->dspdev = NULL;
+#elif defined(CONFIG_SUN_AUDIO)
         priv->dspdev = strdup("/dev/sound");
 #else
         priv->dspdev = strdup("/dev/dsp");
@@ -329,12 +354,39 @@
         {
         int dspspeed = *(int *)arg;
 
+#if defined(CONFIG_SNDIO_AUDIO)
+        if (!sio_stop(priv->hdl))
+            {
+            mp_msg(MSGT_TV, MSGL_ERR, MSGTR_TV_Bt848InvalidAudioRate, "sio_stop failed");
+            return TVI_CONTROL_FALSE;
+            }
+        sio_initpar(&priv->par);
+        priv->par.rate = dspspeed;
+        priv->par.round = 4096 / (priv->dspsamplesize/8 * (priv->dspstereo + 1));
+        if(!sio_setpar(priv->hdl, &priv->par) || !sio_getpar(priv->hdl, &priv->par))
+            {
+            mp_msg(MSGT_TV, MSGL_ERR, MSGTR_TV_Bt848InvalidAudioRate, "sio_[s|g]etpar failed");
+            return TVI_CONTROL_FALSE;
+            }
+        priv->round = priv->par.round * priv->par.bps * priv->par.rchan;
+        priv->appbufsz = priv->par.appbufsz * priv->par.bps * priv->par.rchan;
+        if(priv->par.rate != dspspeed)
+            {
+            mp_msg(MSGT_TV, MSGL_ERR, MSGTR_TV_Bt848InvalidAudioRate, "returned rate != requested rate");
+            return TVI_CONTROL_FALSE;
+            }
+        if (!sio_start(priv->hdl))
+            {
+            mp_msg(MSGT_TV, MSGL_ERR, MSGTR_TV_Bt848InvalidAudioRate, "sio_start failed");
+            return TVI_CONTROL_FALSE;
+            }
+#else
            if(ioctl(priv->dspfd, SNDCTL_DSP_SPEED, &dspspeed) == -1)
             {
             mp_msg(MSGT_TV, MSGL_ERR, MSGTR_TV_Bt848InvalidAudioRate, strerror(errno));
             return TVI_CONTROL_FALSE;
             }
-
+#endif
         priv->dspspeed = dspspeed;
 
         priv->dspframesize = priv->dspspeed*priv->dspsamplesize/8/
@@ -643,12 +695,76 @@
 priv->dspsamplesize = 16;
 priv->dspstereo = 1;
 priv->dspspeed = 44100;
+#if !defined(CONFIG_SNDIO_AUDIO)
 priv->dspfmt = AFMT_S16_LE;
+#endif
 priv->dspbytesread = 0;
 priv->dsprate = priv->dspspeed * priv->dspsamplesize/8*(priv->dspstereo+1);
 priv->dspframesize = priv->dspspeed*priv->dspsamplesize/8/priv->fps *
                      (priv->dspstereo+1);
 
+#if defined(CONFIG_SNDIO_AUDIO)
+
+if((priv->hdl = sio_open(priv->dspdev, SIO_REC, 0)) == NULL)
+    {
+    mp_msg(MSGT_TV, MSGL_ERR, MSGTR_TV_Bt848ErrorOpeningDspDev, "sio_open failed");
+    priv->dspready = FALSE;
+    }
+
+sio_initpar(&priv->par);
+priv->par.rchan = priv->dspstereo + 1;
+priv->par.rate = priv->dspspeed;
+priv->par.bits = priv->dspsamplesize;
+priv->par.sig = 1;
+//priv->par.round = FRAGSIZE / (priv->dspsamplesize/8 * (priv->dspstereo + 1));
+priv->par.round = priv->dspspeed / 100; /* 10 ms */
+priv->par.appbufsz = priv->dspspeed / 4; /* 250 ms */
+
+if(priv->dspready && (!sio_setpar(priv->hdl, &priv->par) || !sio_getpar(priv->hdl, &priv->par)))
+    {
+    mp_msg(MSGT_TV, MSGL_ERR, MSGTR_TV_Bt848ErrorConfiguringDsp, "sio_[s|g]etpar failed");
+    priv->dspready = FALSE;
+    }
+
+priv->round = priv->par.round * priv->par.bps * priv->par.rchan;
+priv->appbufsz = priv->par.appbufsz * priv->par.bps * priv->par.rchan;
+
+if(priv->par.rchan != priv->dspstereo + 1)
+    {
+    mp_msg(MSGT_TV, MSGL_ERR, MSGTR_TV_Bt848ErrorConfiguringDsp, "returned channels != requested channels");
+    priv->dspready = FALSE;
+    }
+if (priv->par.bits != priv->dspsamplesize || priv->par.sig != 1 || priv->par.le != SIO_LE_NATIVE)
+    {
+    mp_msg(MSGT_TV, MSGL_ERR, MSGTR_TV_Bt848ErrorConfiguringDsp, "returned format != requested format");
+    priv->dspready = FALSE;
+    }
+if(priv->par.rate != priv->dspspeed)
+    {
+    mp_msg(MSGT_TV, MSGL_ERR, MSGTR_TV_Bt848ErrorConfiguringDsp, "returned rate != requested rate");
+    // this may be overridden later with command line options, so it's not necessarily a problem
+    //priv->dspready = FALSE;
+    }
+
+priv->realpos = 0;
+
+if(priv->dspready == TRUE)
+    {
+    sio_onmove(priv->hdl, movecb, priv);
+    if(!sio_start(priv->hdl))
+        {
+        mp_msg(MSGT_TV, MSGL_ERR, MSGTR_TV_Bt848ErrorConfiguringDsp, "sio_start failed");
+        priv->dspready = FALSE;
+        }
+    }
+
+if(priv->dspready == FALSE)
+    {
+    sio_close(priv->hdl);
+    }
+
+#else
+
 if((priv->dspfd = open (priv->dspdev, O_RDONLY, 0)) < 0)
     {
     mp_msg(MSGT_TV, MSGL_ERR, MSGTR_TV_Bt848ErrorOpeningDspDev, strerror(errno));
@@ -674,6 +790,8 @@
     priv->dspready = 0;
     }
 
+#endif
+
 return 1;
 }
 
@@ -697,7 +815,9 @@
     return 0;
     }
 
+#if !defined(CONFIG_SNDIO_AUDIO)
 read(priv->dspfd, &tmp, 2);
+#endif
 
 gettimeofday(&curtime, NULL);
 
@@ -736,10 +856,15 @@
     return 0;
     }
 
-close(priv->btfd);
+#if defined(CONFIG_SNDIO_AUDIO)
+sio_close(priv->hdl);
+priv->hdl = NULL;
+#else
 close(priv->dspfd);
+priv->dspfd = -1;
+#endif
 
-priv->dspfd = -1;
+close(priv->btfd);
 priv->btfd = -1;
 
 priv->dspready = priv->videoready = 0;
@@ -819,13 +944,21 @@
 
 /* Get exactly one frame of audio, which forces video sync to audio.. */
 
+#if defined(CONFIG_SNDIO_AUDIO)
+bytesread=sio_read(priv->hdl, buffer, len);
+#else
 bytesread=read(priv->dspfd, buffer, len);
+#endif
 
 while(bytesread < len)
     {
+#if defined(CONFIG_SNDIO_AUDIO)
+    ret=sio_read(priv->hdl, &buffer[bytesread], len-bytesread);
+    if(ret == 0)
+#else
     ret=read(priv->dspfd, &buffer[bytesread], len-bytesread);
-
     if(ret == -1)
+#endif
         {
         mp_msg(MSGT_TV, MSGL_ERR, MSGTR_TV_Bt848ErrorReadingAudio, strerror(errno));
         return 0;
@@ -858,13 +991,19 @@
 static int get_audio_framesize(priv_t *priv)
 {
 int bytesavail;
-#ifdef CONFIG_SUN_AUDIO
+#if defined(CONFIG_SUN_AUDIO) && !defined(CONFIG_SNDIO_AUDIO)
 struct audio_info auinf;
 #endif
 
 if(!priv->dspready) return 0;
 
-#ifdef CONFIG_SUN_AUDIO
+#if defined(CONFIG_SNDIO_AUDIO)
+bytesavail = priv->realpos - priv->dspbytesread;
+if(bytesavail > priv->appbufsz)
+    bytesavail = priv->appbufsz;
+if(bytesavail < priv->round)
+    bytesavail = priv->round;
+#elif defined(CONFIG_SUN_AUDIO)
 if(ioctl(priv->dspfd, AUDIO_GETINFO, &auinf) < 0)
     {
     mp_msg(MSGT_TV, MSGL_ERR, MSGTR_TV_Bt848IoctlFailed, "AUDIO_GETINFO", strerror(errno));

-- 
This message has been scanned for viruses and
dangerous content by MailScanner, and is
believed to be clean.



More information about the MPlayer-dev-eng mailing list