summaryrefslogtreecommitdiff
path: root/java/openjfx8-devel/files/sndiosink.c
diff options
context:
space:
mode:
Diffstat (limited to 'java/openjfx8-devel/files/sndiosink.c')
-rw-r--r--java/openjfx8-devel/files/sndiosink.c502
1 files changed, 102 insertions, 400 deletions
diff --git a/java/openjfx8-devel/files/sndiosink.c b/java/openjfx8-devel/files/sndiosink.c
index eda86ee726f2..cc68bd29d807 100644
--- a/java/openjfx8-devel/files/sndiosink.c
+++ b/java/openjfx8-devel/files/sndiosink.c
@@ -1,5 +1,6 @@
/*
- * Copyright (C) <2008> Jacob Meuser <jakemsr@sdf.lonestar.org>
+ * Copyright (C) 2008 Jacob Meuser <jakemsr@sdf.lonestar.org>
+ * Copyright (C) 2012 Alexandre Ratchov <alex@caoua.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -34,491 +35,192 @@
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
-
#include "sndiosink.h"
-#include <unistd.h>
-#include <errno.h>
-
-#define _(x) x
GST_DEBUG_CATEGORY_EXTERN (gst_sndio_debug);
#define GST_CAT_DEFAULT gst_sndio_debug
-enum
-{
- PROP_0,
- PROP_HOST
-};
+#define gst_sndiosink_parent_class parent_class
-static GstStaticPadTemplate sndio_sink_factory =
+static GstStaticPadTemplate sndiosink_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 ] ")
+ GST_PAD_SINK,
+ GST_PAD_ALWAYS,
+ GST_STATIC_CAPS (GST_SNDIO_CAPS_STRING)
);
-static void gst_sndiosink_finalize (GObject * object);
-
-static GstCaps *gst_sndiosink_getcaps (GstBaseSink * bsink);
+G_DEFINE_TYPE_WITH_CODE (GstSndioSink, gst_sndiosink, GST_TYPE_AUDIO_SINK,
+ G_IMPLEMENT_INTERFACE (GST_TYPE_STREAM_VOLUME, NULL));
+static void gst_sndiosink_finalize (GObject * object);
+static GstCaps *gst_sndiosink_getcaps (GstBaseSink * bsink,
+ GstCaps * filter);
static gboolean gst_sndiosink_open (GstAudioSink * asink);
static gboolean gst_sndiosink_close (GstAudioSink * asink);
static gboolean gst_sndiosink_prepare (GstAudioSink * asink,
- GstRingBufferSpec * spec);
+ GstAudioRingBufferSpec * spec);
static gboolean gst_sndiosink_unprepare (GstAudioSink * asink);
-static guint gst_sndiosink_write (GstAudioSink * asink, gpointer data,
+static gint gst_sndiosink_write (GstAudioSink * asink, gpointer data,
guint length);
static guint gst_sndiosink_delay (GstAudioSink * asink);
static void gst_sndiosink_reset (GstAudioSink * asink);
-
static void gst_sndiosink_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec);
static void gst_sndiosink_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec);
-static void gst_sndiosink_cb(void * addr, int delta);
-
-GST_BOILERPLATE (GstSndioSink, gst_sndiosink, GstAudioSink, GST_TYPE_AUDIO_SINK);
-
-static void
-gst_sndiosink_base_init (gpointer g_class)
-{
- GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
-
- gst_element_class_set_details_simple (element_class,
- "Sndio audio sink", "Sink/Audio", "Plays audio through sndio",
- "Jacob Meuser <jakemsr@sdf.lonestar.org>");
-
- gst_element_class_add_pad_template (element_class,
- gst_static_pad_template_get (&sndio_sink_factory));
-}
-
-static void
-gst_sndiosink_class_init (GstSndioSinkClass * 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_sndiosink_finalize;
-
- gstbasesink_class->get_caps = GST_DEBUG_FUNCPTR (gst_sndiosink_getcaps);
-
- gstaudiosink_class->open = GST_DEBUG_FUNCPTR (gst_sndiosink_open);
- gstaudiosink_class->close = GST_DEBUG_FUNCPTR (gst_sndiosink_close);
- gstaudiosink_class->prepare = GST_DEBUG_FUNCPTR (gst_sndiosink_prepare);
- gstaudiosink_class->unprepare = GST_DEBUG_FUNCPTR (gst_sndiosink_unprepare);
- gstaudiosink_class->write = GST_DEBUG_FUNCPTR (gst_sndiosink_write);
- gstaudiosink_class->delay = GST_DEBUG_FUNCPTR (gst_sndiosink_delay);
- gstaudiosink_class->reset = GST_DEBUG_FUNCPTR (gst_sndiosink_reset);
-
- gobject_class->set_property = gst_sndiosink_set_property;
- gobject_class->get_property = gst_sndiosink_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 sndio will access", NULL, G_PARAM_READWRITE));
-}
static void
-gst_sndiosink_init (GstSndioSink * sndiosink, GstSndioSinkClass * klass)
+gst_sndiosink_init (GstSndioSink * sink)
{
- sndiosink->hdl = NULL;
- sndiosink->host = g_strdup (g_getenv ("AUDIODEVICE"));
+ gst_sndio_init (&sink->sndio, G_OBJECT(sink));
}
static void
gst_sndiosink_finalize (GObject * object)
{
- GstSndioSink *sndiosink = GST_SNDIOSINK (object);
-
- gst_caps_replace (&sndiosink->cur_caps, NULL);
- g_free (sndiosink->host);
+ GstSndioSink *sink = GST_SNDIOSINK (object);
+ gst_sndio_finalize (&sink->sndio);
G_OBJECT_CLASS (parent_class)->finalize (object);
}
static GstCaps *
-gst_sndiosink_getcaps (GstBaseSink * bsink)
+gst_sndiosink_getcaps (GstBaseSink * bsink, GstCaps * filter)
{
- GstSndioSink *sndiosink;
-
- sndiosink = GST_SNDIOSINK (bsink);
-
- /* no hdl, we're done with the template caps */
- if (sndiosink->cur_caps == NULL) {
- GST_LOG_OBJECT (sndiosink, "getcaps called, returning template caps");
- return NULL;
- }
-
- GST_LOG_OBJECT (sndiosink, "returning %" GST_PTR_FORMAT, sndiosink->cur_caps);
+ GstSndioSink *sink = GST_SNDIOSINK (bsink);
- return gst_caps_ref (sndiosink->cur_caps);
+ return gst_sndio_getcaps (&sink->sndio, filter);
}
static gboolean
gst_sndiosink_open (GstAudioSink * asink)
{
- GstPadTemplate *pad_template;
- GstSndioSink *sndiosink;
- 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;
-
- sndiosink = GST_SNDIOSINK (asink);
-
- GST_DEBUG_OBJECT (sndiosink, "open");
-
- /* conect */
- sndiosink->hdl = sio_open (sndiosink->host, SIO_PLAY, 0);
-
- if (sndiosink->hdl == NULL)
- goto couldnt_connect;
-
- /* Use sndio defaults as the only encodings, but get the supported
- * sample rates and number of channels.
- */
-
- if (!sio_getpar(sndiosink->hdl, &par))
- goto no_server_info;
-
- if (!sio_getcap(sndiosink->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);
- }
+ GstSndioSink *sink = GST_SNDIOSINK (asink);
- 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 (&sndio_sink_factory);
- sndiosink->cur_caps = gst_caps_copy (gst_pad_template_get_caps (pad_template));
- gst_object_unref (pad_template);
-
- for (i = 0; i < sndiosink->cur_caps->structs->len; i++) {
- GstStructure *s;
-
- s = gst_caps_get_structure (sndiosink->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 (sndiosink, RESOURCE, OPEN_WRITE,
- (_("Could not establish connection to sndio")),
- ("can't open connection to sndio"));
- return FALSE;
- }
-no_server_info:
- {
- GST_ELEMENT_ERROR (sndiosink, RESOURCE, OPEN_WRITE,
- (_("Failed to query sndio capabilities")),
- ("couldn't get sndio info!"));
- return FALSE;
- }
+ return gst_sndio_open (&sink->sndio, SIO_PLAY);
}
static gboolean
gst_sndiosink_close (GstAudioSink * asink)
{
- GstSndioSink *sndiosink = GST_SNDIOSINK (asink);
-
- GST_DEBUG_OBJECT (sndiosink, "close");
-
- gst_caps_replace (&sndiosink->cur_caps, NULL);
- sio_close (sndiosink->hdl);
- sndiosink->hdl = NULL;
-
- return TRUE;
-}
-
-static void
-gst_sndiosink_cb(void *addr, int delta)
-{
- GstSndioSink *sndiosink = GST_SNDIOSINK ((GstAudioSink *)addr);
-
- sndiosink->realpos += delta;
+ GstSndioSink *sink = GST_SNDIOSINK (asink);
- if (sndiosink->realpos >= sndiosink->playpos)
- sndiosink->latency = 0;
- else
- sndiosink->latency = sndiosink->playpos - sndiosink->realpos;
+ return gst_sndio_close (&sink->sndio);
}
static gboolean
-gst_sndiosink_prepare (GstAudioSink * asink, GstRingBufferSpec * spec)
+gst_sndiosink_prepare (GstAudioSink * asink, GstAudioRingBufferSpec * spec)
{
- GstSndioSink *sndiosink = GST_SNDIOSINK (asink);
- struct sio_par par;
- int spec_bpf;
-
- GST_DEBUG_OBJECT (sndiosink, "prepare");
-
- sndiosink->playpos = sndiosink->realpos = sndiosink->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.appbufsz = (spec->segsize * spec->segtotal) / spec_bpf;
-
- if (!sio_setpar(sndiosink->hdl, &par))
- goto cannot_configure;
-
- sio_getpar(sndiosink->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;
-
- sndiosink->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(sndiosink->hdl, gst_sndiosink_cb, sndiosink);
-
- if (!sio_start(sndiosink->hdl))
- goto cannot_start;
-
- GST_INFO_OBJECT (sndiosink, "successfully opened connection to sndio");
-
- return TRUE;
+ GstSndioSink *sink = GST_SNDIOSINK (asink);
- /* ERRORS */
-cannot_configure:
- {
- GST_ELEMENT_ERROR (sndiosink, RESOURCE, OPEN_WRITE,
- (_("Could not configure sndio")),
- ("can't configure sndio"));
- return FALSE;
- }
-cannot_start:
- {
- GST_ELEMENT_ERROR (sndiosink, RESOURCE, OPEN_WRITE,
- (_("Could not start sndio")),
- ("can't start sndio"));
- return FALSE;
- }
+ return gst_sndio_prepare (&sink->sndio, spec);
}
static gboolean
gst_sndiosink_unprepare (GstAudioSink * asink)
{
- GstSndioSink *sndiosink = GST_SNDIOSINK (asink);
-
- if (sndiosink->hdl == NULL)
- return TRUE;
+ GstSndioSink *sink = GST_SNDIOSINK (asink);
- sio_stop(sndiosink->hdl);
-
- return TRUE;
+ return gst_sndio_unprepare (&sink->sndio);
}
-static guint
+static gint
gst_sndiosink_write (GstAudioSink * asink, gpointer data, guint length)
{
- GstSndioSink *sndiosink = GST_SNDIOSINK (asink);
+ GstSndioSink *sink = GST_SNDIOSINK (asink);
guint done;
- done = sio_write (sndiosink->hdl, data, length);
-
- if (done == 0)
- goto write_error;
-
- sndiosink->playpos += (done / sndiosink->bpf);
-
- data = (char *) data + done;
-
- return done;
-
- /* ERRORS */
-write_error:
- {
- GST_ELEMENT_ERROR (sndiosink, RESOURCE, WRITE,
- ("Failed to write data to sndio"), GST_ERROR_SYSTEM);
+ if (length == 0)
return 0;
+ done = sio_write (sink->sndio.hdl, data, length);
+ if (done == 0) {
+ GST_ELEMENT_ERROR (sink, RESOURCE, WRITE,
+ ("Failed to write data to sndio"), (NULL));
+ return 0;
}
+ sink->sndio.delay += done;
+ return done;
}
static guint
gst_sndiosink_delay (GstAudioSink * asink)
{
- GstSndioSink *sndiosink = GST_SNDIOSINK (asink);
-
- if (sndiosink->latency == (guint) - 1) {
- GST_WARNING_OBJECT (asink, "couldn't get latency");
- return 0;
- }
+ GstSndioSink *sink = GST_SNDIOSINK (asink);
- GST_DEBUG_OBJECT (asink, "got latency: %u", sndiosink->latency);
-
- return sndiosink->latency;
+ return GST_SNDIO_DELAY(&sink->sndio);
}
static void
gst_sndiosink_reset (GstAudioSink * asink)
{
- /* no way to flush the buffers with sndio ? */
-
- GST_DEBUG_OBJECT (asink, "reset called");
}
static void
-gst_sndiosink_set_property (GObject * object, guint prop_id, const GValue * value,
- GParamSpec * pspec)
+gst_sndiosink_set_property (GObject * object, guint prop_id,
+ const GValue * value, GParamSpec * pspec)
{
- GstSndioSink *sndiosink = GST_SNDIOSINK (object);
-
- switch (prop_id) {
- case PROP_HOST:
- g_free (sndiosink->host);
- sndiosink->host = g_value_dup_string (value);
- break;
- default:
- break;
- }
+ GstSndioSink *sink = GST_SNDIOSINK (object);
+
+ gst_sndio_set_property (&sink->sndio, prop_id, value, pspec);
}
static void
gst_sndiosink_get_property (GObject * object, guint prop_id, GValue * value,
GParamSpec * pspec)
{
- GstSndioSink *sndiosink = GST_SNDIOSINK (object);
-
- switch (prop_id) {
- case PROP_HOST:
- g_value_set_string (value, sndiosink->host);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
+ GstSndioSink *sink = GST_SNDIOSINK (object);
+
+ gst_sndio_get_property (&sink->sndio, prop_id, value, pspec);
+}
+
+static void
+gst_sndiosink_class_init (GstSndioSinkClass * klass)
+{
+ GObjectClass *gobject_class;
+ GstElementClass *gstelement_class;
+ GstBaseSinkClass *gstbasesink_class;
+ GstAudioBaseSinkClass *gstbaseaudiosink_class;
+ GstAudioSinkClass *gstaudiosink_class;
+
+ gobject_class = (GObjectClass *) klass;
+ gstelement_class = (GstElementClass *) klass;
+ gstbasesink_class = (GstBaseSinkClass *) klass;
+ gstbaseaudiosink_class = (GstAudioBaseSinkClass *) klass;
+ gstaudiosink_class = (GstAudioSinkClass *) klass;
+
+ parent_class = g_type_class_peek_parent (klass);
+
+ gobject_class->finalize = gst_sndiosink_finalize;
+ gobject_class->get_property = gst_sndiosink_get_property;
+ gobject_class->set_property = gst_sndiosink_set_property;
+
+ gst_element_class_set_static_metadata (gstelement_class,
+ "Audio sink (sndio)", "Sink/Audio",
+ "Output to a sound card via sndio",
+ "Jacob Meuser <jakemsr@sdf.lonestar.org>");
+
+ gst_element_class_add_pad_template (gstelement_class,
+ gst_static_pad_template_get (&sndiosink_factory));
+
+ gstbasesink_class->get_caps = GST_DEBUG_FUNCPTR (gst_sndiosink_getcaps);
+ gstaudiosink_class->open = GST_DEBUG_FUNCPTR (gst_sndiosink_open);
+ gstaudiosink_class->prepare = GST_DEBUG_FUNCPTR (gst_sndiosink_prepare);
+ gstaudiosink_class->unprepare = GST_DEBUG_FUNCPTR (gst_sndiosink_unprepare);
+ gstaudiosink_class->close = GST_DEBUG_FUNCPTR (gst_sndiosink_close);
+ gstaudiosink_class->write = GST_DEBUG_FUNCPTR (gst_sndiosink_write);
+ gstaudiosink_class->delay = GST_DEBUG_FUNCPTR (gst_sndiosink_delay);
+ gstaudiosink_class->reset = GST_DEBUG_FUNCPTR (gst_sndiosink_reset);
+
+ g_object_class_install_property (gobject_class, PROP_DEVICE,
+ g_param_spec_string ("device", "Device",
+ "sndio device as defined in sndio(7)",
+ SIO_DEVANY, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+ g_object_class_install_property (gobject_class, PROP_VOLUME,
+ g_param_spec_double ("volume", "Volume",
+ "Linear volume of this stream, 1.0=100%", 0.0, 1.0,
+ 1.0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+ g_object_class_install_property (gobject_class, PROP_MUTE,
+ g_param_spec_boolean ("mute", "Mute",
+ "Mute state of this stream", FALSE,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
}