add linsbdio backend and use it by default
This commit is contained in:
parent
99577ec26d
commit
41cc379d59
@ -1,4 +1,4 @@
|
||||
# $OpenBSD: Makefile,v 1.24 2008/09/24 23:01:32 jakemsr Exp $
|
||||
# $OpenBSD: Makefile,v 1.25 2008/11/03 23:24:08 jakemsr Exp $
|
||||
|
||||
COMMENT-main = multimedia framework - good plugins
|
||||
COMMENT-aalib = multimedia framework - aalib plugin
|
||||
@ -18,7 +18,7 @@ COMMENT-soup = multimedia framework - libsoup plugin
|
||||
|
||||
V = 0.10.8
|
||||
DISTNAME = gst-plugins-good-$V
|
||||
PKGNAME-main = gstreamer-plugins-good-$Vp4
|
||||
PKGNAME-main = gstreamer-plugins-good-$Vp5
|
||||
PKGNAME-aalib = gstreamer-aalib-$Vp0
|
||||
PKGNAME-cairo = gstreamer-cairo-$Vp1
|
||||
PKGNAME-gconf = gstreamer-confelements-$Vp0
|
||||
@ -50,7 +50,7 @@ WANTLIB = glib-2.0 gmodule-2.0 gobject-2.0 gthread-2.0 \
|
||||
LIB_DEPENDS = gstreamer-0.10:gstreamer->=0.10:$P/core
|
||||
|
||||
WANTLIB-main = ${WANTLIB} \
|
||||
ICE SM X11 Xdamage Xext Xfixes ossaudio \
|
||||
ICE SM X11 Xdamage Xext Xfixes ossaudio sndio \
|
||||
gstcontroller-0.10 gstbase-0.10 Xau Xdmcp
|
||||
LIB_DEPENDS-main = ${LIB_DEPENDS} \
|
||||
oil-0.3::devel/liboil \
|
||||
@ -148,6 +148,10 @@ WANTLIB-soup = ${WANTLIB} \
|
||||
LIB_DEPENDS-soup = ${LIB_DEPENDS} \
|
||||
soup-2.4::devel/libsoup
|
||||
|
||||
BUILD_DEPENDS += ${MODGNU_AUTOCONF_DEPENDS} \
|
||||
${MODGNU_AUTOMAKE_DEPENDS}
|
||||
AUTOMAKE_VERSION = 1.9
|
||||
CONFIGURE_STYLE = gnu
|
||||
CONFIGURE_ARGS += --with-aalib-prefix=${LOCALBASE} \
|
||||
--disable-cdio \
|
||||
--disable-dv1394 \
|
||||
@ -156,9 +160,16 @@ CONFIGURE_ARGS += --with-aalib-prefix=${LOCALBASE} \
|
||||
--disable-schemas-install \
|
||||
--enable-experimental \
|
||||
--enable-gst_v4l2 \
|
||||
--with-default-audiosink=osssink \
|
||||
--with-default-audiosrc=osssrc \
|
||||
--with-default-audiosink=libsndiosink \
|
||||
--with-default-audiosrc=libsndiosrc \
|
||||
--with-default-videosink=xvimagesink \
|
||||
--with-default-videosrc=v4l2src
|
||||
|
||||
post-extract:
|
||||
cp -R ${FILESDIR} ${WRKSRC}/ext/libsndio
|
||||
|
||||
pre-configure:
|
||||
cd ${WRKSRC} && AUTOCONF_VERSION=${AUTOCONF_VERSION} \
|
||||
AUTOMAKE_VERSION=${AUTOMAKE_VERSION} NOCONFIGURE="true" ./autogen.sh
|
||||
|
||||
.include <bsd.port.mk>
|
||||
|
11
multimedia/gstreamer-0.10/plugins-good/files/Makefile.am
Normal file
11
multimedia/gstreamer-0.10/plugins-good/files/Makefile.am
Normal file
@ -0,0 +1,11 @@
|
||||
plugin_LTLIBRARIES = libgstlibsndio.la
|
||||
|
||||
libgstlibsndio_la_SOURCES = gstlibsndio.c libsndiosink.c libsndiosrc.c
|
||||
libgstlibsndio_la_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_CFLAGS)
|
||||
libgstlibsndio_la_LIBADD = \
|
||||
$(GST_PLUGINS_BASE_LIBS) -lgstaudio-$(GST_MAJORMINOR) \
|
||||
$(LIBSNDIO_LIBS)
|
||||
libgstlibsndio_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
|
||||
|
||||
noinst_HEADERS = libsndiosink.h libsndiosrc.h
|
||||
EXTRA_DIST =
|
54
multimedia/gstreamer-0.10/plugins-good/files/gstlibsndio.c
Normal file
54
multimedia/gstreamer-0.10/plugins-good/files/gstlibsndio.c
Normal file
@ -0,0 +1,54 @@
|
||||
/* GStreamer
|
||||
* Copyright (C) <2008> Jacob Meuser <jakemsr@sdf.lonestar.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
#include "libsndiosink.h"
|
||||
#include "libsndiosrc.h"
|
||||
|
||||
#include "gst/gst-i18n-plugin.h"
|
||||
|
||||
GST_DEBUG_CATEGORY (libsndio_debug);
|
||||
|
||||
static gboolean
|
||||
plugin_init (GstPlugin * plugin)
|
||||
{
|
||||
if (!gst_element_register (plugin, "libsndiosrc", GST_RANK_PRIMARY,
|
||||
GST_TYPE_LIBSNDIOSRC) ||
|
||||
!gst_element_register (plugin, "libsndiosink", GST_RANK_PRIMARY,
|
||||
GST_TYPE_LIBSNDIOSINK)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
GST_DEBUG_CATEGORY_INIT (libsndio_debug, "libsndio", 0, "libsndio elements");
|
||||
|
||||
#ifdef ENABLE_NLS
|
||||
setlocale (LC_ALL, "");
|
||||
bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
|
||||
#endif /* ENABLE_NLS */
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
|
||||
GST_VERSION_MINOR,
|
||||
"libsndio",
|
||||
"libsndio support for GStreamer",
|
||||
plugin_init, VERSION, GST_LICENSE, GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN)
|
536
multimedia/gstreamer-0.10/plugins-good/files/libsndiosink.c
Normal file
536
multimedia/gstreamer-0.10/plugins-good/files/libsndiosink.c
Normal file
@ -0,0 +1,536 @@
|
||||
/* GStreamer
|
||||
* Copyright (C) <2008> Jacob Meuser <jakemsr@sdf.lonestar.org>
|
||||
*
|
||||
* libsndiosink.c: libsndio audio sink
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/**
|
||||
* SECTION:element-libsndiosink
|
||||
* @see_also: #GstAutoAudioSink
|
||||
*
|
||||
* <refsect2>
|
||||
* <para>
|
||||
* This element outputs sound to a sound card using libsndio.
|
||||
* </para>
|
||||
* <para>
|
||||
* Simple example pipeline that plays an Ogg/Vorbis file via libsndio:
|
||||
* <programlisting>
|
||||
* gst-launch -v filesrc location=foo.ogg ! decodebin ! audioconvert ! audioresample ! libsndiosink
|
||||
* </programlisting>
|
||||
* </para>
|
||||
* </refsect2>
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "libsndiosink.h"
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <gst/gst-i18n-plugin.h>
|
||||
|
||||
GST_DEBUG_CATEGORY_EXTERN (libsndio_debug);
|
||||
#define GST_CAT_DEFAULT libsndio_debug
|
||||
|
||||
/* elementfactory information */
|
||||
static const GstElementDetails libsndiosink_details =
|
||||
GST_ELEMENT_DETAILS ("Libsndio audio sink",
|
||||
"Sink/Audio",
|
||||
"Plays audio through libsndio",
|
||||
"Jacob Meuser <jakemsr@sdf.lonestar.org>");
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
PROP_HOST
|
||||
};
|
||||
|
||||
static GstStaticPadTemplate libsndio_sink_factory =
|
||||
GST_STATIC_PAD_TEMPLATE ("sink",
|
||||
GST_PAD_SINK,
|
||||
GST_PAD_ALWAYS,
|
||||
GST_STATIC_CAPS ("audio/x-raw-int, "
|
||||
"endianness = (int) { 1234, 4321 }, "
|
||||
"signed = (boolean) { TRUE, FALSE }, "
|
||||
"width = (int) { 8, 16, 24, 32 }, "
|
||||
"depth = (int) { 8, 16, 24, 32 }, "
|
||||
"rate = (int) [ 8000, 192000 ], "
|
||||
"channels = (int) [ 1, 16 ] ")
|
||||
);
|
||||
|
||||
static void gst_libsndiosink_finalize (GObject * object);
|
||||
|
||||
static GstCaps *gst_libsndiosink_getcaps (GstBaseSink * bsink);
|
||||
|
||||
static gboolean gst_libsndiosink_open (GstAudioSink * asink);
|
||||
static gboolean gst_libsndiosink_close (GstAudioSink * asink);
|
||||
static gboolean gst_libsndiosink_prepare (GstAudioSink * asink,
|
||||
GstRingBufferSpec * spec);
|
||||
static gboolean gst_libsndiosink_unprepare (GstAudioSink * asink);
|
||||
static guint gst_libsndiosink_write (GstAudioSink * asink, gpointer data,
|
||||
guint length);
|
||||
static guint gst_libsndiosink_delay (GstAudioSink * asink);
|
||||
static void gst_libsndiosink_reset (GstAudioSink * asink);
|
||||
|
||||
static void gst_libsndiosink_set_property (GObject * object, guint prop_id,
|
||||
const GValue * value, GParamSpec * pspec);
|
||||
static void gst_libsndiosink_get_property (GObject * object, guint prop_id,
|
||||
GValue * value, GParamSpec * pspec);
|
||||
static void gst_libsndiosink_cb(void * addr, int delta);
|
||||
|
||||
GST_BOILERPLATE (GstLibsndioSink, gst_libsndiosink, GstAudioSink, GST_TYPE_AUDIO_SINK);
|
||||
|
||||
static void
|
||||
gst_libsndiosink_base_init (gpointer g_class)
|
||||
{
|
||||
GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
|
||||
|
||||
gst_element_class_set_details (element_class, &libsndiosink_details);
|
||||
|
||||
gst_element_class_add_pad_template (element_class,
|
||||
gst_static_pad_template_get (&libsndio_sink_factory));
|
||||
}
|
||||
|
||||
static void
|
||||
gst_libsndiosink_class_init (GstLibsndioSinkClass * klass)
|
||||
{
|
||||
GObjectClass *gobject_class;
|
||||
GstBaseSinkClass *gstbasesink_class;
|
||||
GstBaseAudioSinkClass *gstbaseaudiosink_class;
|
||||
GstAudioSinkClass *gstaudiosink_class;
|
||||
|
||||
gobject_class = (GObjectClass *) klass;
|
||||
gstbasesink_class = (GstBaseSinkClass *) klass;
|
||||
gstbaseaudiosink_class = (GstBaseAudioSinkClass *) klass;
|
||||
gstaudiosink_class = (GstAudioSinkClass *) klass;
|
||||
|
||||
parent_class = g_type_class_peek_parent (klass);
|
||||
|
||||
gobject_class->finalize = gst_libsndiosink_finalize;
|
||||
|
||||
gstbasesink_class->get_caps = GST_DEBUG_FUNCPTR (gst_libsndiosink_getcaps);
|
||||
|
||||
gstaudiosink_class->open = GST_DEBUG_FUNCPTR (gst_libsndiosink_open);
|
||||
gstaudiosink_class->close = GST_DEBUG_FUNCPTR (gst_libsndiosink_close);
|
||||
gstaudiosink_class->prepare = GST_DEBUG_FUNCPTR (gst_libsndiosink_prepare);
|
||||
gstaudiosink_class->unprepare = GST_DEBUG_FUNCPTR (gst_libsndiosink_unprepare);
|
||||
gstaudiosink_class->write = GST_DEBUG_FUNCPTR (gst_libsndiosink_write);
|
||||
gstaudiosink_class->delay = GST_DEBUG_FUNCPTR (gst_libsndiosink_delay);
|
||||
gstaudiosink_class->reset = GST_DEBUG_FUNCPTR (gst_libsndiosink_reset);
|
||||
|
||||
gobject_class->set_property = gst_libsndiosink_set_property;
|
||||
gobject_class->get_property = gst_libsndiosink_get_property;
|
||||
|
||||
/* default value is filled in the _init method */
|
||||
g_object_class_install_property (gobject_class, PROP_HOST,
|
||||
g_param_spec_string ("host", "Host",
|
||||
"Device or socket libsndio will access", NULL, G_PARAM_READWRITE));
|
||||
}
|
||||
|
||||
static void
|
||||
gst_libsndiosink_init (GstLibsndioSink * libsndiosink, GstLibsndioSinkClass * klass)
|
||||
{
|
||||
libsndiosink->hdl = NULL;
|
||||
libsndiosink->host = g_strdup (g_getenv ("AUDIODEVICE"));
|
||||
}
|
||||
|
||||
static void
|
||||
gst_libsndiosink_finalize (GObject * object)
|
||||
{
|
||||
GstLibsndioSink *libsndiosink = GST_LIBSNDIOSINK (object);
|
||||
|
||||
gst_caps_replace (&libsndiosink->cur_caps, NULL);
|
||||
g_free (libsndiosink->host);
|
||||
|
||||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static GstCaps *
|
||||
gst_libsndiosink_getcaps (GstBaseSink * bsink)
|
||||
{
|
||||
GstLibsndioSink *libsndiosink;
|
||||
|
||||
libsndiosink = GST_LIBSNDIOSINK (bsink);
|
||||
|
||||
/* no hdl, we're done with the template caps */
|
||||
if (libsndiosink->cur_caps == NULL) {
|
||||
GST_LOG_OBJECT (libsndiosink, "getcaps called, returning template caps");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
GST_LOG_OBJECT (libsndiosink, "returning %" GST_PTR_FORMAT, libsndiosink->cur_caps);
|
||||
|
||||
return gst_caps_ref (libsndiosink->cur_caps);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_libsndiosink_open (GstAudioSink * asink)
|
||||
{
|
||||
GstPadTemplate *pad_template;
|
||||
GstLibsndioSink *libsndiosink;
|
||||
struct sio_par par;
|
||||
struct sio_cap cap;
|
||||
GArray *rates, *chans;
|
||||
GValue rates_v = { 0 };
|
||||
GValue chans_v = { 0 };
|
||||
GValue value = { 0 };
|
||||
struct sio_enc enc;
|
||||
struct sio_conf conf;
|
||||
int confs[SIO_NCONF];
|
||||
int rate, chan;
|
||||
int i, j, k;
|
||||
int nconfs;
|
||||
|
||||
|
||||
libsndiosink = GST_LIBSNDIOSINK (asink);
|
||||
|
||||
GST_DEBUG_OBJECT (libsndiosink, "open");
|
||||
|
||||
/* conect */
|
||||
libsndiosink->hdl = sio_open (libsndiosink->host, SIO_PLAY, 0);
|
||||
|
||||
if (libsndiosink->hdl == NULL)
|
||||
goto couldnt_connect;
|
||||
|
||||
/* Use libsndio defaults as the only encodings, but get the supported
|
||||
* sample rates and number of channels.
|
||||
*/
|
||||
|
||||
if (!sio_getpar(libsndiosink->hdl, &par))
|
||||
goto no_server_info;
|
||||
|
||||
if (!sio_getcap(libsndiosink->hdl, &cap))
|
||||
goto no_server_info;
|
||||
|
||||
rates = g_array_new(FALSE, FALSE, sizeof(int));
|
||||
chans = g_array_new(FALSE, FALSE, sizeof(int));
|
||||
|
||||
/* find confs that have the default encoding */
|
||||
nconfs = 0;
|
||||
for (i = 0; i < cap.nconf; i++) {
|
||||
for (j = 0; j < SIO_NENC; j++) {
|
||||
if (cap.confs[i].enc & (1 << j)) {
|
||||
enc = cap.enc[j];
|
||||
if (enc.bits == par.bits && enc.sig == par.sig && enc.le == par.le) {
|
||||
confs[nconfs] = i;
|
||||
nconfs++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* find the rates and channels of the confs that have the default encoding */
|
||||
for (i = 0; i < nconfs; i++) {
|
||||
conf = cap.confs[confs[i]];
|
||||
/* rates */
|
||||
for (j = 0; j < SIO_NRATE; j++) {
|
||||
if (conf.rate & (1 << j)) {
|
||||
rate = cap.rate[j];
|
||||
for (k = 0; k < rates->len && rate; k++) {
|
||||
if (rate == g_array_index(rates, int, k))
|
||||
rate = 0;
|
||||
}
|
||||
/* add in ascending order */
|
||||
if (rate) {
|
||||
for (k = 0; k < rates->len; k++) {
|
||||
if (rate < g_array_index(rates, int, k)) {
|
||||
g_array_insert_val(rates, k, rate);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (k == rates->len)
|
||||
g_array_append_val(rates, rate);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* channels */
|
||||
for (j = 0; j < SIO_NCHAN; j++) {
|
||||
if (conf.pchan & (1 << j)) {
|
||||
chan = cap.pchan[j];
|
||||
for (k = 0; k < chans->len && chan; k++) {
|
||||
if (chan == g_array_index(chans, int, k))
|
||||
chan = 0;
|
||||
}
|
||||
/* add in ascending order */
|
||||
if (chan) {
|
||||
for (k = 0; k < chans->len; k++) {
|
||||
if (chan < g_array_index(chans, int, k)) {
|
||||
g_array_insert_val(chans, k, chan);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (k == chans->len)
|
||||
g_array_append_val(chans, chan);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/* not sure how this can happen, but it might */
|
||||
if (cap.nconf == 0) {
|
||||
g_array_append_val(rates, par.rate);
|
||||
g_array_append_val(chans, par.pchan);
|
||||
}
|
||||
|
||||
g_value_init(&rates_v, GST_TYPE_LIST);
|
||||
g_value_init(&chans_v, GST_TYPE_LIST);
|
||||
g_value_init(&value, G_TYPE_INT);
|
||||
|
||||
for (i = 0; i < rates->len; i++) {
|
||||
g_value_set_int(&value, g_array_index(rates, int, i));
|
||||
gst_value_list_append_value(&rates_v, &value);
|
||||
}
|
||||
for (i = 0; i < chans->len; i++) {
|
||||
g_value_set_int(&value, g_array_index(chans, int, i));
|
||||
gst_value_list_append_value(&chans_v, &value);
|
||||
}
|
||||
|
||||
g_array_free(rates, TRUE);
|
||||
g_array_free(chans, TRUE);
|
||||
|
||||
pad_template = gst_static_pad_template_get (&libsndio_sink_factory);
|
||||
libsndiosink->cur_caps = gst_caps_copy (gst_pad_template_get_caps (pad_template));
|
||||
gst_object_unref (pad_template);
|
||||
|
||||
for (i = 0; i < libsndiosink->cur_caps->structs->len; i++) {
|
||||
GstStructure *s;
|
||||
|
||||
s = gst_caps_get_structure (libsndiosink->cur_caps, i);
|
||||
gst_structure_set (s, "endianness", G_TYPE_INT, par.le ? 1234 : 4321, NULL);
|
||||
gst_structure_set (s, "signed", G_TYPE_BOOLEAN, par.sig ? TRUE : FALSE, NULL);
|
||||
gst_structure_set (s, "width", G_TYPE_INT, par.bits, NULL);
|
||||
// gst_structure_set (s, "depth", G_TYPE_INT, par.bps * 8, NULL); /* XXX */
|
||||
gst_structure_set_value (s, "rate", &rates_v);
|
||||
gst_structure_set_value (s, "channels", &chans_v);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
||||
/* ERRORS */
|
||||
couldnt_connect:
|
||||
{
|
||||
GST_ELEMENT_ERROR (libsndiosink, RESOURCE, OPEN_WRITE,
|
||||
(_("Could not establish connection to libsndio")),
|
||||
("can't open connection to libsndio"));
|
||||
return FALSE;
|
||||
}
|
||||
no_server_info:
|
||||
{
|
||||
GST_ELEMENT_ERROR (libsndiosink, RESOURCE, OPEN_WRITE,
|
||||
(_("Failed to query libsndio capabilities")),
|
||||
("couldn't get libsndio info!"));
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_libsndiosink_close (GstAudioSink * asink)
|
||||
{
|
||||
GstLibsndioSink *libsndiosink = GST_LIBSNDIOSINK (asink);
|
||||
|
||||
GST_DEBUG_OBJECT (libsndiosink, "close");
|
||||
|
||||
gst_caps_replace (&libsndiosink->cur_caps, NULL);
|
||||
sio_close (libsndiosink->hdl);
|
||||
libsndiosink->hdl = NULL;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_libsndiosink_cb(void *addr, int delta)
|
||||
{
|
||||
GstLibsndioSink *libsndiosink = GST_LIBSNDIOSINK ((GstAudioSink *)addr);
|
||||
|
||||
libsndiosink->realpos += delta;
|
||||
|
||||
if (libsndiosink->realpos >= libsndiosink->playpos)
|
||||
libsndiosink->latency = 0;
|
||||
else
|
||||
libsndiosink->latency = libsndiosink->playpos - libsndiosink->realpos;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_libsndiosink_prepare (GstAudioSink * asink, GstRingBufferSpec * spec)
|
||||
{
|
||||
GstLibsndioSink *libsndiosink = GST_LIBSNDIOSINK (asink);
|
||||
struct sio_par par;
|
||||
int spec_bpf;
|
||||
|
||||
GST_DEBUG_OBJECT (libsndiosink, "prepare");
|
||||
|
||||
libsndiosink->playpos = libsndiosink->realpos = libsndiosink->latency = 0;
|
||||
|
||||
sio_initpar(&par);
|
||||
par.sig = spec->sign;
|
||||
par.le = !spec->bigend;
|
||||
par.bits = spec->width;
|
||||
// par.bps = spec->depth / 8; /* XXX */
|
||||
par.rate = spec->rate;
|
||||
par.pchan = spec->channels;
|
||||
|
||||
spec_bpf = ((spec->width / 8) * spec->channels);
|
||||
|
||||
par.bufsz = (spec->segsize * spec->segtotal) / spec_bpf;
|
||||
|
||||
if (!sio_setpar(libsndiosink->hdl, &par))
|
||||
goto cannot_configure;
|
||||
|
||||
sio_getpar(libsndiosink->hdl, &par);
|
||||
|
||||
spec->sign = par.sig;
|
||||
spec->bigend = !par.le;
|
||||
spec->width = par.bits;
|
||||
// spec->depth = par.bps * 8; /* XXX */
|
||||
spec->rate = par.rate;
|
||||
spec->channels = par.pchan;
|
||||
|
||||
libsndiosink->bpf = par.bps * par.pchan;
|
||||
|
||||
spec->segsize = par.round * par.pchan * par.bps;
|
||||
spec->segtotal = par.bufsz / par.round;
|
||||
|
||||
/* FIXME: this is wrong for signed ints (and the
|
||||
* audioringbuffers should do it for us anyway) */
|
||||
spec->silence_sample[0] = 0;
|
||||
spec->silence_sample[1] = 0;
|
||||
spec->silence_sample[2] = 0;
|
||||
spec->silence_sample[3] = 0;
|
||||
|
||||
sio_onmove(libsndiosink->hdl, gst_libsndiosink_cb, libsndiosink);
|
||||
|
||||
if (!sio_start(libsndiosink->hdl))
|
||||
goto cannot_start;
|
||||
|
||||
GST_INFO_OBJECT (libsndiosink, "successfully opened connection to libsndio");
|
||||
|
||||
return TRUE;
|
||||
|
||||
/* ERRORS */
|
||||
cannot_configure:
|
||||
{
|
||||
GST_ELEMENT_ERROR (libsndiosink, RESOURCE, OPEN_WRITE,
|
||||
(_("Could not configure libsndio")),
|
||||
("can't configure libsndio"));
|
||||
return FALSE;
|
||||
}
|
||||
cannot_start:
|
||||
{
|
||||
GST_ELEMENT_ERROR (libsndiosink, RESOURCE, OPEN_WRITE,
|
||||
(_("Could not start libsndio")),
|
||||
("can't start libsndio"));
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_libsndiosink_unprepare (GstAudioSink * asink)
|
||||
{
|
||||
GstLibsndioSink *libsndiosink = GST_LIBSNDIOSINK (asink);
|
||||
|
||||
if (libsndiosink->hdl == NULL)
|
||||
return TRUE;
|
||||
|
||||
sio_stop(libsndiosink->hdl);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
static guint
|
||||
gst_libsndiosink_write (GstAudioSink * asink, gpointer data, guint length)
|
||||
{
|
||||
GstLibsndioSink *libsndiosink = GST_LIBSNDIOSINK (asink);
|
||||
guint done;
|
||||
|
||||
done = sio_write (libsndiosink->hdl, data, length);
|
||||
|
||||
if (done == 0)
|
||||
goto write_error;
|
||||
|
||||
libsndiosink->playpos += (done / libsndiosink->bpf);
|
||||
|
||||
data = (char *) data + done;
|
||||
|
||||
return done;
|
||||
|
||||
/* ERRORS */
|
||||
write_error:
|
||||
{
|
||||
GST_ELEMENT_ERROR (libsndiosink, RESOURCE, WRITE,
|
||||
("Failed to write data to libsndio"), GST_ERROR_SYSTEM);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static guint
|
||||
gst_libsndiosink_delay (GstAudioSink * asink)
|
||||
{
|
||||
GstLibsndioSink *libsndiosink = GST_LIBSNDIOSINK (asink);
|
||||
|
||||
if (libsndiosink->latency == (guint) - 1) {
|
||||
GST_WARNING_OBJECT (asink, "couldn't get latency");
|
||||
return 0;
|
||||
}
|
||||
|
||||
GST_DEBUG_OBJECT (asink, "got latency: %u", libsndiosink->latency);
|
||||
|
||||
return libsndiosink->latency;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_libsndiosink_reset (GstAudioSink * asink)
|
||||
{
|
||||
/* no way to flush the buffers with libsndio ? */
|
||||
|
||||
GST_DEBUG_OBJECT (asink, "reset called");
|
||||
}
|
||||
|
||||
static void
|
||||
gst_libsndiosink_set_property (GObject * object, guint prop_id, const GValue * value,
|
||||
GParamSpec * pspec)
|
||||
{
|
||||
GstLibsndioSink *libsndiosink = GST_LIBSNDIOSINK (object);
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_HOST:
|
||||
g_free (libsndiosink->host);
|
||||
libsndiosink->host = g_value_dup_string (value);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gst_libsndiosink_get_property (GObject * object, guint prop_id, GValue * value,
|
||||
GParamSpec * pspec)
|
||||
{
|
||||
GstLibsndioSink *libsndiosink = GST_LIBSNDIOSINK (object);
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_HOST:
|
||||
g_value_set_string (value, libsndiosink->host);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
72
multimedia/gstreamer-0.10/plugins-good/files/libsndiosink.h
Normal file
72
multimedia/gstreamer-0.10/plugins-good/files/libsndiosink.h
Normal file
@ -0,0 +1,72 @@
|
||||
/* GStreamer
|
||||
* Copyright (C) <2008> Jacob Meuser <jakemsr@sdf.lonestar.org>
|
||||
*
|
||||
* libsndiosink.h: libsndio audio sink
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __GST_LIBSNDIOSINK_H__
|
||||
#define __GST_LIBSNDIOSINK_H__
|
||||
|
||||
#include <sndio.h>
|
||||
|
||||
#include <gst/gst.h>
|
||||
#include <gst/audio/gstaudiosink.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_TYPE_LIBSNDIOSINK \
|
||||
(gst_libsndiosink_get_type())
|
||||
#define GST_LIBSNDIOSINK(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_LIBSNDIOSINK,GstLibsndioSink))
|
||||
#define GST_LIBSNDIOSINK_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_LIBSNDIOSINK,GstLibsndioSinkClass))
|
||||
#define GST_IS_LIBSNDIOSINK(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_LIBSNDIOSINK))
|
||||
#define GST_IS_LIBSNDIOSINK_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_LIBSNDIOSINK))
|
||||
|
||||
typedef struct _GstLibsndioSink GstLibsndioSink;
|
||||
typedef struct _GstLibsndioSinkClass GstLibsndioSinkClass;
|
||||
|
||||
struct _GstLibsndioSink {
|
||||
GstAudioSink sink;
|
||||
|
||||
struct sio_hdl *hdl;
|
||||
gchar *host;
|
||||
|
||||
/* bytes per frame */
|
||||
int bpf;
|
||||
|
||||
/* frames counts */
|
||||
volatile long long realpos;
|
||||
volatile long long playpos;
|
||||
volatile guint latency;
|
||||
|
||||
GstCaps *cur_caps;
|
||||
};
|
||||
|
||||
struct _GstLibsndioSinkClass {
|
||||
GstAudioSinkClass parent_class;
|
||||
};
|
||||
|
||||
GType gst_libsndiosink_get_type (void);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_LIBSNDIOSINK_H__ */
|
536
multimedia/gstreamer-0.10/plugins-good/files/libsndiosrc.c
Normal file
536
multimedia/gstreamer-0.10/plugins-good/files/libsndiosrc.c
Normal file
@ -0,0 +1,536 @@
|
||||
/* GStreamer
|
||||
* Copyright (C) <2008> Jacob Meuser <jakemsr@sdf.lonestar.org>
|
||||
*
|
||||
* libsndiosrc.c: libsndio audio source
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/**
|
||||
* SECTION:element-libsndiosrc
|
||||
* @see_also: #GstAutoAudioSrc
|
||||
*
|
||||
* <refsect2>
|
||||
* <para>
|
||||
* This element retrieves samples from a sound card using libsndio.
|
||||
* </para>
|
||||
* <para>
|
||||
* Simple example pipeline that plays an Ogg/Vorbis file via libsndio:
|
||||
* <programlisting>
|
||||
* gst-launch -v libsndiosrc ! audioconvert ! vorbisenc ! oggmux ! filesink location=foo.ogg
|
||||
* </programlisting>
|
||||
* </para>
|
||||
* </refsect2>
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "libsndiosrc.h"
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <gst/gst-i18n-plugin.h>
|
||||
|
||||
GST_DEBUG_CATEGORY_EXTERN (libsndio_debug);
|
||||
#define GST_CAT_DEFAULT libsndio_debug
|
||||
|
||||
/* elementfactory information */
|
||||
static const GstElementDetails libsndiosrc_details =
|
||||
GST_ELEMENT_DETAILS ("Libsndio audio source",
|
||||
"Source/Audio",
|
||||
"Records audio through libsndio",
|
||||
"Jacob Meuser <jakemsr@sdf.lonestar.org>");
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
PROP_HOST
|
||||
};
|
||||
|
||||
static GstStaticPadTemplate libsndio_src_factory =
|
||||
GST_STATIC_PAD_TEMPLATE ("src",
|
||||
GST_PAD_SRC,
|
||||
GST_PAD_ALWAYS,
|
||||
GST_STATIC_CAPS ("audio/x-raw-int, "
|
||||
"endianness = (int) { 1234, 4321 }, "
|
||||
"signed = (boolean) { TRUE, FALSE }, "
|
||||
"width = (int) { 8, 16, 24, 32 }, "
|
||||
"depth = (int) { 8, 16, 24, 32 }, "
|
||||
"rate = (int) [ 8000, 192000 ], "
|
||||
"channels = (int) [ 1, 16 ] ")
|
||||
);
|
||||
|
||||
static void gst_libsndiosrc_finalize (GObject * object);
|
||||
|
||||
static GstCaps *gst_libsndiosrc_getcaps (GstBaseSrc * bsrc);
|
||||
|
||||
static gboolean gst_libsndiosrc_open (GstAudioSrc * asrc);
|
||||
static gboolean gst_libsndiosrc_close (GstAudioSrc * asrc);
|
||||
static gboolean gst_libsndiosrc_prepare (GstAudioSrc * asrc,
|
||||
GstRingBufferSpec * spec);
|
||||
static gboolean gst_libsndiosrc_unprepare (GstAudioSrc * asrc);
|
||||
static guint gst_libsndiosrc_read (GstAudioSrc * asrc, gpointer data,
|
||||
guint length);
|
||||
static guint gst_libsndiosrc_delay (GstAudioSrc * asrc);
|
||||
static void gst_libsndiosrc_reset (GstAudioSrc * asrc);
|
||||
|
||||
static void gst_libsndiosrc_set_property (GObject * object, guint prop_id,
|
||||
const GValue * value, GParamSpec * pspec);
|
||||
static void gst_libsndiosrc_get_property (GObject * object, guint prop_id,
|
||||
GValue * value, GParamSpec * pspec);
|
||||
static void gst_libsndiosrc_cb(void * addr, int delta);
|
||||
|
||||
GST_BOILERPLATE (GstLibsndioSrc, gst_libsndiosrc, GstAudioSrc, GST_TYPE_AUDIO_SRC);
|
||||
|
||||
static void
|
||||
gst_libsndiosrc_base_init (gpointer g_class)
|
||||
{
|
||||
GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
|
||||
|
||||
gst_element_class_set_details (element_class, &libsndiosrc_details);
|
||||
|
||||
gst_element_class_add_pad_template (element_class,
|
||||
gst_static_pad_template_get (&libsndio_src_factory));
|
||||
}
|
||||
|
||||
static void
|
||||
gst_libsndiosrc_class_init (GstLibsndioSrcClass * klass)
|
||||
{
|
||||
GObjectClass *gobject_class;
|
||||
GstBaseSrcClass *gstbasesrc_class;
|
||||
GstBaseAudioSrcClass *gstbaseaudiosrc_class;
|
||||
GstAudioSrcClass *gstaudiosrc_class;
|
||||
|
||||
gobject_class = (GObjectClass *) klass;
|
||||
gstbasesrc_class = (GstBaseSrcClass *) klass;
|
||||
gstbaseaudiosrc_class = (GstBaseAudioSrcClass *) klass;
|
||||
gstaudiosrc_class = (GstAudioSrcClass *) klass;
|
||||
|
||||
parent_class = g_type_class_peek_parent (klass);
|
||||
|
||||
gobject_class->finalize = gst_libsndiosrc_finalize;
|
||||
|
||||
gstbasesrc_class->get_caps = GST_DEBUG_FUNCPTR (gst_libsndiosrc_getcaps);
|
||||
|
||||
gstaudiosrc_class->open = GST_DEBUG_FUNCPTR (gst_libsndiosrc_open);
|
||||
gstaudiosrc_class->close = GST_DEBUG_FUNCPTR (gst_libsndiosrc_close);
|
||||
gstaudiosrc_class->prepare = GST_DEBUG_FUNCPTR (gst_libsndiosrc_prepare);
|
||||
gstaudiosrc_class->unprepare = GST_DEBUG_FUNCPTR (gst_libsndiosrc_unprepare);
|
||||
gstaudiosrc_class->read = GST_DEBUG_FUNCPTR (gst_libsndiosrc_read);
|
||||
gstaudiosrc_class->delay = GST_DEBUG_FUNCPTR (gst_libsndiosrc_delay);
|
||||
gstaudiosrc_class->reset = GST_DEBUG_FUNCPTR (gst_libsndiosrc_reset);
|
||||
|
||||
gobject_class->set_property = gst_libsndiosrc_set_property;
|
||||
gobject_class->get_property = gst_libsndiosrc_get_property;
|
||||
|
||||
/* default value is filled in the _init method */
|
||||
g_object_class_install_property (gobject_class, PROP_HOST,
|
||||
g_param_spec_string ("host", "Host",
|
||||
"Device or socket libsndio will access", NULL, G_PARAM_READWRITE));
|
||||
}
|
||||
|
||||
static void
|
||||
gst_libsndiosrc_init (GstLibsndioSrc * libsndiosrc, GstLibsndioSrcClass * klass)
|
||||
{
|
||||
libsndiosrc->hdl = NULL;
|
||||
libsndiosrc->host = g_strdup (g_getenv ("AUDIODEVICE"));
|
||||
}
|
||||
|
||||
static void
|
||||
gst_libsndiosrc_finalize (GObject * object)
|
||||
{
|
||||
GstLibsndioSrc *libsndiosrc = GST_LIBSNDIOSRC (object);
|
||||
|
||||
gst_caps_replace (&libsndiosrc->cur_caps, NULL);
|
||||
g_free (libsndiosrc->host);
|
||||
|
||||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static GstCaps *
|
||||
gst_libsndiosrc_getcaps (GstBaseSrc * bsrc)
|
||||
{
|
||||
GstLibsndioSrc *libsndiosrc;
|
||||
|
||||
libsndiosrc = GST_LIBSNDIOSRC (bsrc);
|
||||
|
||||
/* no hdl, we're done with the template caps */
|
||||
if (libsndiosrc->cur_caps == NULL) {
|
||||
GST_LOG_OBJECT (libsndiosrc, "getcaps called, returning template caps");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
GST_LOG_OBJECT (libsndiosrc, "returning %" GST_PTR_FORMAT, libsndiosrc->cur_caps);
|
||||
|
||||
return gst_caps_ref (libsndiosrc->cur_caps);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_libsndiosrc_open (GstAudioSrc * asrc)
|
||||
{
|
||||
GstPadTemplate *pad_template;
|
||||
GstLibsndioSrc *libsndiosrc;
|
||||
struct sio_par par;
|
||||
struct sio_cap cap;
|
||||
GArray *rates, *chans;
|
||||
GValue rates_v = { 0 };
|
||||
GValue chans_v = { 0 };
|
||||
GValue value = { 0 };
|
||||
struct sio_enc enc;
|
||||
struct sio_conf conf;
|
||||
int confs[SIO_NCONF];
|
||||
int rate, chan;
|
||||
int i, j, k;
|
||||
int nconfs;
|
||||
|
||||
libsndiosrc = GST_LIBSNDIOSRC (asrc);
|
||||
|
||||
GST_DEBUG_OBJECT (libsndiosrc, "open");
|
||||
|
||||
/* connect */
|
||||
libsndiosrc->hdl = sio_open (libsndiosrc->host, SIO_REC, 0);
|
||||
|
||||
if (libsndiosrc->hdl == NULL)
|
||||
goto couldnt_connect;
|
||||
|
||||
/* Use libsndio defaults as the only encodings, but get the supported
|
||||
* sample rates and number of channels.
|
||||
*/
|
||||
|
||||
if (!sio_getpar(libsndiosrc->hdl, &par))
|
||||
goto no_server_info;
|
||||
|
||||
if (!sio_getcap(libsndiosrc->hdl, &cap))
|
||||
goto no_server_info;
|
||||
|
||||
rates = g_array_new(FALSE, FALSE, sizeof(int));
|
||||
chans = g_array_new(FALSE, FALSE, sizeof(int));
|
||||
|
||||
/* find confs that have the default encoding */
|
||||
nconfs = 0;
|
||||
for (i = 0; i < cap.nconf; i++) {
|
||||
for (j = 0; j < SIO_NENC; j++) {
|
||||
if (cap.confs[i].enc & (1 << j)) {
|
||||
enc = cap.enc[j];
|
||||
if (enc.bits == par.bits && enc.sig == par.sig && enc.le == par.le) {
|
||||
confs[nconfs] = i;
|
||||
nconfs++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* find the rates and channels of the confs that have the default encoding */
|
||||
for (i = 0; i < nconfs; i++) {
|
||||
conf = cap.confs[confs[i]];
|
||||
/* rates */
|
||||
for (j = 0; j < SIO_NRATE; j++) {
|
||||
if (conf.rate & (1 << j)) {
|
||||
rate = cap.rate[j];
|
||||
for (k = 0; k < rates->len && rate; k++) {
|
||||
if (rate == g_array_index(rates, int, k))
|
||||
rate = 0;
|
||||
}
|
||||
/* add in ascending order */
|
||||
if (rate) {
|
||||
for (k = 0; k < rates->len; k++) {
|
||||
if (rate < g_array_index(rates, int, k)) {
|
||||
g_array_insert_val(rates, k, rate);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (k == rates->len)
|
||||
g_array_append_val(rates, rate);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* channels */
|
||||
for (j = 0; j < SIO_NCHAN; j++) {
|
||||
if (conf.rchan & (1 << j)) {
|
||||
chan = cap.rchan[j];
|
||||
for (k = 0; k < chans->len && chan; k++) {
|
||||
if (chan == g_array_index(chans, int, k))
|
||||
chan = 0;
|
||||
}
|
||||
/* add in ascending order */
|
||||
if (chan) {
|
||||
for (k = 0; k < chans->len; k++) {
|
||||
if (chan < g_array_index(chans, int, k)) {
|
||||
g_array_insert_val(chans, k, chan);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (k == chans->len)
|
||||
g_array_append_val(chans, chan);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/* not sure how this can happen, but it might */
|
||||
if (cap.nconf == 0) {
|
||||
g_array_append_val(rates, par.rate);
|
||||
g_array_append_val(chans, par.rchan);
|
||||
}
|
||||
|
||||
g_value_init(&rates_v, GST_TYPE_LIST);
|
||||
g_value_init(&chans_v, GST_TYPE_LIST);
|
||||
g_value_init(&value, G_TYPE_INT);
|
||||
|
||||
for (i = 0; i < rates->len; i++) {
|
||||
g_value_set_int(&value, g_array_index(rates, int, i));
|
||||
gst_value_list_append_value(&rates_v, &value);
|
||||
}
|
||||
for (i = 0; i < chans->len; i++) {
|
||||
g_value_set_int(&value, g_array_index(chans, int, i));
|
||||
gst_value_list_append_value(&chans_v, &value);
|
||||
}
|
||||
|
||||
g_array_free(rates, TRUE);
|
||||
g_array_free(chans, TRUE);
|
||||
|
||||
pad_template = gst_static_pad_template_get (&libsndio_src_factory);
|
||||
libsndiosrc->cur_caps = gst_caps_copy (gst_pad_template_get_caps (pad_template));
|
||||
gst_object_unref (pad_template);
|
||||
|
||||
for (i = 0; i < libsndiosrc->cur_caps->structs->len; i++) {
|
||||
GstStructure *s;
|
||||
|
||||
s = gst_caps_get_structure (libsndiosrc->cur_caps, i);
|
||||
gst_structure_set (s, "endianness", G_TYPE_INT, par.le ? 1234 : 4321, NULL);
|
||||
gst_structure_set (s, "signed", G_TYPE_BOOLEAN, par.sig ? TRUE : FALSE, NULL);
|
||||
gst_structure_set (s, "width", G_TYPE_INT, par.bits, NULL);
|
||||
// gst_structure_set (s, "depth", G_TYPE_INT, par.bps * 8, NULL); /* XXX */
|
||||
gst_structure_set_value (s, "rate", &rates_v);
|
||||
gst_structure_set_value (s, "channels", &chans_v);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
||||
/* ERRORS */
|
||||
couldnt_connect:
|
||||
{
|
||||
GST_ELEMENT_ERROR (libsndiosrc, RESOURCE, OPEN_READ,
|
||||
(_("Could not establish connection to libsndio")),
|
||||
("can't open connection to libsndio"));
|
||||
return FALSE;
|
||||
}
|
||||
no_server_info:
|
||||
{
|
||||
GST_ELEMENT_ERROR (libsndiosrc, RESOURCE, OPEN_READ,
|
||||
(_("Failed to query libsndio capabilities")),
|
||||
("couldn't get libsndio info!"));
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_libsndiosrc_close (GstAudioSrc * asrc)
|
||||
{
|
||||
GstLibsndioSrc *libsndiosrc = GST_LIBSNDIOSRC (asrc);
|
||||
|
||||
GST_DEBUG_OBJECT (libsndiosrc, "close");
|
||||
|
||||
gst_caps_replace (&libsndiosrc->cur_caps, NULL);
|
||||
sio_close (libsndiosrc->hdl);
|
||||
libsndiosrc->hdl = NULL;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_libsndiosrc_cb(void *addr, int delta)
|
||||
{
|
||||
GstLibsndioSrc *libsndiosrc = GST_LIBSNDIOSRC ((GstAudioSrc *)addr);
|
||||
|
||||
libsndiosrc->realpos += delta;
|
||||
|
||||
if (libsndiosrc->readpos >= libsndiosrc->realpos)
|
||||
libsndiosrc->latency = 0;
|
||||
else
|
||||
libsndiosrc->latency = libsndiosrc->realpos - libsndiosrc->readpos;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_libsndiosrc_prepare (GstAudioSrc * asrc, GstRingBufferSpec * spec)
|
||||
{
|
||||
GstLibsndioSrc *libsndiosrc = GST_LIBSNDIOSRC (asrc);
|
||||
struct sio_par par;
|
||||
int spec_bpf;
|
||||
|
||||
GST_DEBUG_OBJECT (libsndiosrc, "prepare");
|
||||
|
||||
libsndiosrc->readpos = libsndiosrc->realpos = libsndiosrc->latency = 0;
|
||||
|
||||
sio_initpar(&par);
|
||||
par.sig = spec->sign;
|
||||
par.le = !spec->bigend;
|
||||
par.bits = spec->width;
|
||||
// par.bps = spec->depth / 8; /* XXX */
|
||||
par.rate = spec->rate;
|
||||
par.rchan = spec->channels;
|
||||
|
||||
spec_bpf = ((spec->width / 8) * spec->channels);
|
||||
|
||||
par.round = spec->segsize / spec_bpf;
|
||||
par.bufsz = (spec->segsize * spec->segtotal) / spec_bpf;
|
||||
|
||||
if (!sio_setpar(libsndiosrc->hdl, &par))
|
||||
goto cannot_configure;
|
||||
|
||||
sio_getpar(libsndiosrc->hdl, &par);
|
||||
|
||||
spec->sign = par.sig;
|
||||
spec->bigend = !par.le;
|
||||
spec->width = par.bits;
|
||||
// spec->depth = par.bps * 8; /* XXX */
|
||||
spec->rate = par.rate;
|
||||
spec->channels = par.rchan;
|
||||
|
||||
libsndiosrc->bpf = par.bps * par.rchan;
|
||||
|
||||
spec->segsize = par.round * par.rchan * par.bps;
|
||||
spec->segtotal = par.bufsz / par.round;
|
||||
|
||||
/* FIXME: this is wrong for signed ints (and the
|
||||
* audioringbuffers should do it for us anyway) */
|
||||
spec->silence_sample[0] = 0;
|
||||
spec->silence_sample[1] = 0;
|
||||
spec->silence_sample[2] = 0;
|
||||
spec->silence_sample[3] = 0;
|
||||
|
||||
sio_onmove(libsndiosrc->hdl, gst_libsndiosrc_cb, libsndiosrc);
|
||||
|
||||
if (!sio_start(libsndiosrc->hdl))
|
||||
goto cannot_start;
|
||||
|
||||
GST_INFO_OBJECT (libsndiosrc, "successfully opened connection to libsndio");
|
||||
|
||||
return TRUE;
|
||||
|
||||
/* ERRORS */
|
||||
cannot_configure:
|
||||
{
|
||||
GST_ELEMENT_ERROR (libsndiosrc, RESOURCE, OPEN_READ,
|
||||
(_("Could not configure libsndio")),
|
||||
("can't configure libsndio"));
|
||||
return FALSE;
|
||||
}
|
||||
cannot_start:
|
||||
{
|
||||
GST_ELEMENT_ERROR (libsndiosrc, RESOURCE, OPEN_READ,
|
||||
(_("Could not start libsndio")),
|
||||
("can't start libsndio"));
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_libsndiosrc_unprepare (GstAudioSrc * asrc)
|
||||
{
|
||||
GstLibsndioSrc *libsndiosrc = GST_LIBSNDIOSRC (asrc);
|
||||
|
||||
if (libsndiosrc->hdl == NULL)
|
||||
return TRUE;
|
||||
|
||||
sio_stop(libsndiosrc->hdl);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
static guint
|
||||
gst_libsndiosrc_read (GstAudioSrc * asrc, gpointer data, guint length)
|
||||
{
|
||||
GstLibsndioSrc *libsndiosrc = GST_LIBSNDIOSRC (asrc);
|
||||
guint done;
|
||||
|
||||
done = sio_read (libsndiosrc->hdl, data, length);
|
||||
|
||||
if (done == 0)
|
||||
goto read_error;
|
||||
|
||||
libsndiosrc->readpos += (done / libsndiosrc->bpf);
|
||||
|
||||
data = (char *) data + done;
|
||||
|
||||
return done;
|
||||
|
||||
/* ERRORS */
|
||||
read_error:
|
||||
{
|
||||
GST_ELEMENT_ERROR (libsndiosrc, RESOURCE, READ,
|
||||
("Failed to read data from libsndio"), GST_ERROR_SYSTEM);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static guint
|
||||
gst_libsndiosrc_delay (GstAudioSrc * asrc)
|
||||
{
|
||||
GstLibsndioSrc *libsndiosrc = GST_LIBSNDIOSRC (asrc);
|
||||
|
||||
if (libsndiosrc->latency == (guint) - 1) {
|
||||
GST_WARNING_OBJECT (asrc, "couldn't get latency");
|
||||
return 0;
|
||||
}
|
||||
|
||||
GST_DEBUG_OBJECT (asrc, "got latency: %u", libsndiosrc->latency);
|
||||
|
||||
return libsndiosrc->latency;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_libsndiosrc_reset (GstAudioSrc * asrc)
|
||||
{
|
||||
/* no way to flush the buffers with libsndio ? */
|
||||
|
||||
GST_DEBUG_OBJECT (asrc, "reset called");
|
||||
}
|
||||
|
||||
static void
|
||||
gst_libsndiosrc_set_property (GObject * object, guint prop_id, const GValue * value,
|
||||
GParamSpec * pspec)
|
||||
{
|
||||
GstLibsndioSrc *libsndiosrc = GST_LIBSNDIOSRC (object);
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_HOST:
|
||||
g_free (libsndiosrc->host);
|
||||
libsndiosrc->host = g_value_dup_string (value);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gst_libsndiosrc_get_property (GObject * object, guint prop_id, GValue * value,
|
||||
GParamSpec * pspec)
|
||||
{
|
||||
GstLibsndioSrc *libsndiosrc = GST_LIBSNDIOSRC (object);
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_HOST:
|
||||
g_value_set_string (value, libsndiosrc->host);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
72
multimedia/gstreamer-0.10/plugins-good/files/libsndiosrc.h
Normal file
72
multimedia/gstreamer-0.10/plugins-good/files/libsndiosrc.h
Normal file
@ -0,0 +1,72 @@
|
||||
/* GStreamer
|
||||
* Copyright (C) <2008> Jacob Meuser <jakemsr@sdf.lonestar.org>
|
||||
*
|
||||
* libsndiosrc.h: libsndio audio source
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __GST_LIBSNDIOSRC_H__
|
||||
#define __GST_LIBSNDIOSRC_H__
|
||||
|
||||
#include <sndio.h>
|
||||
|
||||
#include <gst/gst.h>
|
||||
#include <gst/audio/gstaudiosrc.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_TYPE_LIBSNDIOSRC \
|
||||
(gst_libsndiosrc_get_type())
|
||||
#define GST_LIBSNDIOSRC(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_LIBSNDIOSRC,GstLibsndioSrc))
|
||||
#define GST_LIBSNDIOSRC_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_LIBSNDIOSRC,GstLibsndioSrcClass))
|
||||
#define GST_IS_LIBSNDIOSRC(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_LIBSNDIOSRC))
|
||||
#define GST_IS_LIBSNDIOSRC_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_LIBSNDIOSRC))
|
||||
|
||||
typedef struct _GstLibsndioSrc GstLibsndioSrc;
|
||||
typedef struct _GstLibsndioSrcClass GstLibsndioSrcClass;
|
||||
|
||||
struct _GstLibsndioSrc {
|
||||
GstAudioSrc src;
|
||||
|
||||
struct sio_hdl *hdl;
|
||||
gchar *host;
|
||||
|
||||
/* bytes per frame */
|
||||
int bpf;
|
||||
|
||||
/* frames counts */
|
||||
volatile long long realpos;
|
||||
volatile long long readpos;
|
||||
volatile guint latency;
|
||||
|
||||
GstCaps *cur_caps;
|
||||
};
|
||||
|
||||
struct _GstLibsndioSrcClass {
|
||||
GstAudioSrcClass parent_class;
|
||||
};
|
||||
|
||||
GType gst_libsndiosrc_get_type (void);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_LIBSNDIOSRC_H__ */
|
@ -1,6 +1,6 @@
|
||||
$OpenBSD: patch-configure_ac,v 1.5 2008/05/16 14:24:01 ajacoutot Exp $
|
||||
--- configure.ac.orig Wed Apr 23 03:55:55 2008
|
||||
+++ configure.ac Wed May 14 12:28:02 2008
|
||||
$OpenBSD: patch-configure_ac,v 1.6 2008/11/03 23:24:09 jakemsr Exp $
|
||||
--- configure.ac.orig Tue Apr 22 18:55:55 2008
|
||||
+++ configure.ac Mon Oct 27 01:45:57 2008
|
||||
@@ -488,6 +488,8 @@ AG_GST_CHECK_FEATURE(GST_V4L2, [Video 4 Linux 2], v4l2
|
||||
#ifdef __sun /* Solaris */
|
||||
#include <sys/types.h>
|
||||
@ -19,7 +19,29 @@ $OpenBSD: patch-configure_ac,v 1.5 2008/05/16 14:24:01 ajacoutot Exp $
|
||||
#else /* Linux */
|
||||
#include <linux/types.h>
|
||||
#define _LINUX_TIME_H
|
||||
@@ -699,7 +703,7 @@ AG_GST_CHECK_FEATURE(FLAC, [FLAC lossless audio], flac
|
||||
@@ -676,6 +680,21 @@ AG_GST_CHECK_FEATURE(ESD, [ESounD sound daemon], esdsi
|
||||
fi
|
||||
])
|
||||
|
||||
+dnl *** libsndio ***
|
||||
+translit(dnm, m, l) AM_CONDITIONAL(USE_LIBSNDIO, true)
|
||||
+AG_GST_CHECK_FEATURE(LIBSNDIO, [libsndio audio], libsndioaudio, [
|
||||
+ AC_CHECK_HEADER(sndio.h, HAVE_LIBSNDIO="yes", HAVE_LIBSNDIO="no")
|
||||
+ if test $HAVE_LIBSNDIO = yes
|
||||
+ then
|
||||
+ AC_CHECK_LIB(sndio, sio_open, HAVE_LIBSNDIO="yes", HAVE_LIBSNDIO="no", [])
|
||||
+ if test $HAVE_LIBSNDIO = yes
|
||||
+ then
|
||||
+ LIBSNDIO_LIBS=-lsndio
|
||||
+ AC_SUBST(LIBSNDIO_LIBS)
|
||||
+ fi
|
||||
+ fi
|
||||
+])
|
||||
+
|
||||
dnl *** FLAC ***
|
||||
translit(dnm, m, l) AM_CONDITIONAL(USE_FLAC, true)
|
||||
AC_TRY_COMPILE([#include <FLAC/export.h>], [
|
||||
@@ -699,7 +718,7 @@ AG_GST_CHECK_FEATURE(FLAC, [FLAC lossless audio], flac
|
||||
])
|
||||
else
|
||||
AG_GST_CHECK_FEATURE(FLAC, [FLAC lossless audio], flac, [
|
||||
@ -28,7 +50,7 @@ $OpenBSD: patch-configure_ac,v 1.5 2008/05/16 14:24:01 ajacoutot Exp $
|
||||
dnl API change in FLAC 1.1.3, so require that...
|
||||
if test x$HAVE_FLAC = xyes; then
|
||||
AC_CHECK_DECL(FLAC__STREAM_ENCODER_TELL_STATUS_ERROR,
|
||||
@@ -773,7 +777,7 @@ AG_GST_CHECK_FEATURE(LIBDV, [libdv DV demuxer/decoder]
|
||||
@@ -773,7 +792,7 @@ AG_GST_CHECK_FEATURE(LIBDV, [libdv DV demuxer/decoder]
|
||||
dnl *** libpng ***
|
||||
translit(dnm, m, l) AM_CONDITIONAL(USE_LIBPNG, true)
|
||||
AG_GST_CHECK_FEATURE(LIBPNG, [Portable Network Graphics library], png, [
|
||||
@ -37,3 +59,19 @@ $OpenBSD: patch-configure_ac,v 1.5 2008/05/16 14:24:01 ajacoutot Exp $
|
||||
])
|
||||
|
||||
dnl *** dv1394 ***
|
||||
@@ -947,6 +966,7 @@ AM_CONDITIONAL(USE_ANNODEX, false)
|
||||
AM_CONDITIONAL(USE_CAIRO, false)
|
||||
AM_CONDITIONAL(USE_CDIO, false)
|
||||
AM_CONDITIONAL(USE_ESD, false)
|
||||
+AM_CONDITIONAL(USE_LIBSNDIO, false)
|
||||
AM_CONDITIONAL(USE_FLAC, false)
|
||||
AM_CONDITIONAL(USE_GCONF, false)
|
||||
AM_CONDITIONAL(USE_GDK_PIXBUF, false)
|
||||
@@ -1066,6 +1086,7 @@ ext/cairo/Makefile
|
||||
ext/cdio/Makefile
|
||||
ext/dv/Makefile
|
||||
ext/esd/Makefile
|
||||
+ext/libsndio/Makefile
|
||||
ext/flac/Makefile
|
||||
ext/gconf/Makefile
|
||||
ext/gdk_pixbuf/Makefile
|
||||
|
@ -0,0 +1,32 @@
|
||||
$OpenBSD: patch-ext_Makefile_am,v 1.1 2008/11/03 23:24:09 jakemsr Exp $
|
||||
--- ext/Makefile.am.orig Fri Sep 26 02:05:28 2008
|
||||
+++ ext/Makefile.am Fri Sep 26 02:07:07 2008
|
||||
@@ -82,6 +82,12 @@ else
|
||||
LIBPNG_DIR =
|
||||
endif
|
||||
|
||||
+if USE_LIBSNDIO
|
||||
+LIBSNDIO_DIR = libsndio
|
||||
+else
|
||||
+LIBSNDIO_DIR =
|
||||
+endif
|
||||
+
|
||||
# if USE_MIKMOD
|
||||
# MIKMOD_DIR = mikmod
|
||||
# else
|
||||
@@ -140,6 +146,7 @@ SUBDIRS = \
|
||||
$(LIBDV_DIR) \
|
||||
$(LIBMNG_DIR) \
|
||||
$(LIBPNG_DIR) \
|
||||
+ $(LIBSNDIO_DIR) \
|
||||
$(MIKMOD_DIR) \
|
||||
$(SHOUT2_DIR) \
|
||||
$(SOUP_DIR) \
|
||||
@@ -162,6 +169,7 @@ DIST_SUBDIRS = \
|
||||
ladspa \
|
||||
libcaca \
|
||||
libpng \
|
||||
+ libsndio \
|
||||
raw1394 \
|
||||
shout2 \
|
||||
soup \
|
@ -0,0 +1,13 @@
|
||||
$OpenBSD: patch-sys_oss_Makefile_am,v 1.1 2008/11/03 23:24:09 jakemsr Exp $
|
||||
--- sys/oss/Makefile.am.orig Fri Sep 26 02:07:41 2008
|
||||
+++ sys/oss/Makefile.am Fri Sep 26 02:08:01 2008
|
||||
@@ -13,7 +13,8 @@ libgstossaudio_la_LIBADD = \
|
||||
$(GST_PLUGINS_BASE_LIBS) \
|
||||
-lgstinterfaces-$(GST_MAJORMINOR) \
|
||||
-lgstaudio-$(GST_MAJORMINOR) \
|
||||
- $(GST_LIBS)
|
||||
+ $(GST_LIBS) \
|
||||
+ -lossaudio
|
||||
libgstossaudio_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
|
||||
|
||||
noinst_HEADERS = common.h \
|
@ -1,13 +0,0 @@
|
||||
$OpenBSD: patch-sys_oss_Makefile_in,v 1.2 2008/05/13 15:11:51 espie Exp $
|
||||
--- sys/oss/Makefile.in.orig Thu Apr 24 00:39:31 2008
|
||||
+++ sys/oss/Makefile.in Mon May 12 14:28:03 2008
|
||||
@@ -521,7 +521,8 @@ libgstossaudio_la_LIBADD = \
|
||||
$(GST_PLUGINS_BASE_LIBS) \
|
||||
-lgstinterfaces-$(GST_MAJORMINOR) \
|
||||
-lgstaudio-$(GST_MAJORMINOR) \
|
||||
- $(GST_LIBS)
|
||||
+ $(GST_LIBS) \
|
||||
+ -lossaudio
|
||||
|
||||
libgstossaudio_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
|
||||
|
@ -1,4 +1,4 @@
|
||||
@comment $OpenBSD: PLIST-main,v 1.8 2008/05/18 13:37:22 ajacoutot Exp $
|
||||
@comment $OpenBSD: PLIST-main,v 1.9 2008/11/03 23:24:09 jakemsr Exp $
|
||||
@conflict gstreamer-plugins-bad-<0.10.7
|
||||
lib/gstreamer-${VERSION}/libgstalaw.la
|
||||
lib/gstreamer-${VERSION}/libgstalaw.so
|
||||
@ -36,6 +36,8 @@ lib/gstreamer-${VERSION}/libgstid3demux.la
|
||||
lib/gstreamer-${VERSION}/libgstid3demux.so
|
||||
lib/gstreamer-${VERSION}/libgstlevel.la
|
||||
lib/gstreamer-${VERSION}/libgstlevel.so
|
||||
lib/gstreamer-${VERSION}/libgstlibsndio.la
|
||||
lib/gstreamer-${VERSION}/libgstlibsndio.so
|
||||
lib/gstreamer-${VERSION}/libgstmatroska.la
|
||||
lib/gstreamer-${VERSION}/libgstmatroska.so
|
||||
lib/gstreamer-${VERSION}/libgstmonoscope.la
|
||||
|
Loading…
Reference in New Issue
Block a user