From f5743b63de97d7d5bba29dc769387b42a092cb82 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Sat, 7 Dec 2002 14:25:18 +0000 Subject: [PATCH] Some cleanups and refactoring make ossrc do good negotiation Original commit message from CVS: Some cleanups and refactoring make ossrc do good negotiation --- sys/oss/Makefile.am | 10 +- sys/oss/gstosscommon.c | 91 +++++++++++++++ sys/oss/gstosscommon.h | 31 +++++ sys/oss/gstosssink.c | 81 ++----------- sys/oss/gstosssrc.c | 307 ++++++++++++++++++++++++------------------------- sys/oss/gstosssrc.h | 20 ++-- 6 files changed, 299 insertions(+), 241 deletions(-) create mode 100644 sys/oss/gstosscommon.c create mode 100644 sys/oss/gstosscommon.h diff --git a/sys/oss/Makefile.am b/sys/oss/Makefile.am index 10d07a2..5275c39 100644 --- a/sys/oss/Makefile.am +++ b/sys/oss/Makefile.am @@ -4,7 +4,13 @@ plugin_LTLIBRARIES = libgstossaudio.la EXTRA_LTLIBRARIES = libgstosshelper.la -libgstossaudio_la_SOURCES = gstosssink.c gstosssrc.c gstossaudio.c gstossgst.c gstossclock.c +libgstossaudio_la_SOURCES = gstosssink.c \ + gstosssrc.c \ + gstossaudio.c \ + gstossgst.c \ + gstossclock.c \ + gstosscommon.c + libgstossaudio_la_CFLAGS = $(GST_CFLAGS) libgstossaudio_la_LIBADD = libgstossaudio_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) @@ -12,4 +18,4 @@ libgstossaudio_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) libgstosshelper_la_SOURCES = gstosshelper.c libgstosshelper_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) -noinst_HEADERS = gstosssink.h gstosssrc.h gstossgst.h gstossclock.h gstosshelper.h +noinst_HEADERS = gstosssink.h gstosssrc.h gstossgst.h gstossclock.h gstosshelper.h gstosscommon.h diff --git a/sys/oss/gstosscommon.c b/sys/oss/gstosscommon.c new file mode 100644 index 0000000..cadf5a2 --- /dev/null +++ b/sys/oss/gstosscommon.c @@ -0,0 +1,91 @@ +/* GStreamer + * Copyright (C) 1999,2000 Erik Walthinsen + * 2000 Wim Taymans + * + * gstosssink.c: + * + * 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. + */ + + +#include "gstosscommon.h" +#include + +gboolean +gst_ossformat_get (gint law, gint endianness, gboolean sign, gint width, gint depth, + gint *format, gint *bps) +{ + if (width != depth) + return FALSE; + + *bps = 1; + + if (law == 0) { + if (width == 16) { + if (sign == TRUE) { + if (endianness == G_LITTLE_ENDIAN) { + *format = AFMT_S16_LE; + GST_DEBUG (GST_CAT_PLUGIN_INFO, + "16 bit signed LE, no law (%d)", *format); + } + else if (endianness == G_BIG_ENDIAN) { + *format = AFMT_S16_BE; + GST_DEBUG (GST_CAT_PLUGIN_INFO, + "16 bit signed BE, no law (%d)", *format); + } + } + else { + if (endianness == G_LITTLE_ENDIAN) { + *format = AFMT_U16_LE; + GST_DEBUG (GST_CAT_PLUGIN_INFO, + "16 bit unsigned LE, no law (%d)", *format); + } + else if (endianness == G_BIG_ENDIAN) { + *format = AFMT_U16_BE; + GST_DEBUG (GST_CAT_PLUGIN_INFO, + "16 bit unsigned BE, no law (%d)", *format); + } + } + *bps = 2; + } + else if (width == 8) { + if (sign == TRUE) { + *format = AFMT_S8; + GST_DEBUG (GST_CAT_PLUGIN_INFO, + "8 bit signed, no law (%d)", *format); + } + else { + *format = AFMT_U8; + GST_DEBUG (GST_CAT_PLUGIN_INFO, + "8 bit unsigned, no law (%d)", *format); + } + *bps = 1; + } + } else if (law == 1) { + *format = AFMT_MU_LAW; + GST_DEBUG (GST_CAT_PLUGIN_INFO, + "mu law (%d)", *format); + } else if (law == 2) { + *format = AFMT_A_LAW; + GST_DEBUG (GST_CAT_PLUGIN_INFO, + "a law (%d)", *format); + } else { + g_critical ("unknown law"); + return FALSE; + } + + return TRUE; +} diff --git a/sys/oss/gstosscommon.h b/sys/oss/gstosscommon.h new file mode 100644 index 0000000..18bdd90 --- /dev/null +++ b/sys/oss/gstosscommon.h @@ -0,0 +1,31 @@ +/* GStreamer + * Copyright (C) 1999,2000 Erik Walthinsen + * 2000 Wim Taymans + * + * gstosssink.c: + * + * 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_OSSFORMAT_H__ +#define __GST_OSSFORMAT_H__ + +#include + +gboolean gst_ossformat_get (gint law, gint endianness, gboolean sign, + gint width, gint depth, gint *format, gint *bps); + +#endif /* __GST_OSSFORMAT_H__ */ diff --git a/sys/oss/gstosssink.c b/sys/oss/gstosssink.c index f8abd1c..049a3a0 100644 --- a/sys/oss/gstosssink.c +++ b/sys/oss/gstosssink.c @@ -31,6 +31,7 @@ #include #include +#include /* elementfactory information */ static GstElementDetails gst_osssink_details = { @@ -253,7 +254,7 @@ gst_osssink_init (GstOssSink *osssink) static GstPadConnectReturn gst_osssink_sinkconnect (GstPad *pad, GstCaps *caps) { - gint law, endianness, depth; + gint law, endianness, width, depth, bps; gboolean sign; gint format = -1; GstOssSink *osssink = GST_OSSSINK (gst_pad_get_parent (pad)); @@ -261,12 +262,14 @@ gst_osssink_sinkconnect (GstPad *pad, GstCaps *caps) if (!GST_CAPS_IS_FIXED (caps)) return GST_PAD_CONNECT_DELAYED; - gst_caps_get_int (caps, "width", &osssink->width); + gst_caps_get_int (caps, "width", &width); gst_caps_get_int (caps, "depth", &depth); - if (osssink->width != depth) + if (width != depth) return GST_PAD_CONNECT_REFUSED; + osssink->width = width; + /* laws 1 and 2 are 1 bps anyway */ osssink->bps = 1; @@ -274,76 +277,16 @@ gst_osssink_sinkconnect (GstPad *pad, GstCaps *caps) gst_caps_get_int (caps, "endianness", &endianness); gst_caps_get_boolean (caps, "signed", &sign); - if (law == 0) { - if (osssink->width == 16) { - if (sign == TRUE) { - if (endianness == G_LITTLE_ENDIAN) - { - format = AFMT_S16_LE; - GST_DEBUG (GST_CAT_PLUGIN_INFO, - "gst_osssink_sinkconnect: 16 bit signed LE, no law (%d)", - format); - } - else if (endianness == G_BIG_ENDIAN) - { - format = AFMT_S16_BE; - GST_DEBUG (GST_CAT_PLUGIN_INFO, - "gst_osssink_sinkconnect: 16 bit signed BE, no law (%d)", - format); - } - } - else { - if (endianness == G_LITTLE_ENDIAN) - { - format = AFMT_U16_LE; - GST_DEBUG (GST_CAT_PLUGIN_INFO, - "gst_osssink_sinkconnect: 16 bit unsigned LE, no law (%d)", - format); - } - else if (endianness == G_BIG_ENDIAN) - { - format = AFMT_U16_BE; - GST_DEBUG (GST_CAT_PLUGIN_INFO, - "gst_osssink_sinkconnect: 16 bit unsigned BE, no law (%d)", - format); - } - } - osssink->bps = 2; - } - else if (osssink->width == 8) { - if (sign == TRUE) { - format = AFMT_S8; - GST_DEBUG (GST_CAT_PLUGIN_INFO, - "gst_osssink_sinkconnect: 8 bit signed, no law (%d)", - format); - } - else { - format = AFMT_U8; - GST_DEBUG (GST_CAT_PLUGIN_INFO, - "gst_osssink_sinkconnect: 8 bit unsigned, no law (%d)", - format); - } - osssink->bps = 1; - } - } else if (law == 1) { - format = AFMT_MU_LAW; - GST_DEBUG (GST_CAT_PLUGIN_INFO, - "gst_osssink_sinkconnect: mu law (%d)", - format); - } else if (law == 2) { - format = AFMT_A_LAW; - GST_DEBUG (GST_CAT_PLUGIN_INFO, - "gst_osssink_sinkconnect: a law (%d)", - format); - } else { - g_critical ("unknown law"); + if (!gst_ossformat_get (law, endianness, sign, + width, depth, &format, &bps)) + { + GST_DEBUG (GST_CAT_PLUGIN_INFO, "could not get format"); return GST_PAD_CONNECT_REFUSED; } - if (format == -1) - return GST_PAD_CONNECT_REFUSED; - + osssink->bps = bps; osssink->format = format; + gst_caps_get_int (caps, "channels", &osssink->channels); gst_caps_get_int (caps, "rate", &osssink->frequency); diff --git a/sys/oss/gstosssrc.c b/sys/oss/gstosssrc.c index 8a9445d..93c048b 100644 --- a/sys/oss/gstosssrc.c +++ b/sys/oss/gstosssrc.c @@ -28,6 +28,7 @@ #include #include +#include /* elementfactory information */ static GstElementDetails gst_osssrc_details = { @@ -51,10 +52,6 @@ enum { ARG_0, ARG_DEVICE, ARG_BYTESPERREAD, - ARG_CUROFFSET, - ARG_FORMAT, - ARG_CHANNELS, - ARG_FREQUENCY }; GST_PAD_TEMPLATE_FACTORY (osssrc_src_factory, @@ -87,15 +84,17 @@ GST_PAD_TEMPLATE_FACTORY (osssrc_src_factory, static void gst_osssrc_class_init (GstOssSrcClass *klass); static void gst_osssrc_init (GstOssSrc *osssrc); -static void gst_osssrc_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec); -static void gst_osssrc_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec); +static GstPadConnectReturn gst_osssrc_srcconnect (GstPad *pad, GstCaps *caps); +static void gst_osssrc_set_property (GObject *object, guint prop_id, + const GValue *value, GParamSpec *pspec); +static void gst_osssrc_get_property (GObject *object, guint prop_id, + GValue *value, GParamSpec *pspec); static GstElementStateReturn gst_osssrc_change_state (GstElement *element); -static GstPadConnectReturn gst_osssrc_connect (GstPad *pad, GstCaps *caps); static gboolean gst_osssrc_send_event (GstElement *element, GstEvent *event); static void gst_osssrc_close_audio (GstOssSrc *src); static gboolean gst_osssrc_open_audio (GstOssSrc *src); -static void gst_osssrc_sync_parms (GstOssSrc *osssrc); +static gboolean gst_osssrc_sync_parms (GstOssSrc *osssrc); static GstBuffer * gst_osssrc_get (GstPad *pad); @@ -138,18 +137,6 @@ gst_osssrc_class_init (GstOssSrcClass *klass) g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_BYTESPERREAD, g_param_spec_ulong("bytes_per_read","bytes_per_read","bytes_per_read", 0,G_MAXULONG,0,G_PARAM_READWRITE)); /* CHECKME */ - g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_CUROFFSET, - g_param_spec_ulong("curoffset","curoffset","curoffset", - 0,G_MAXULONG,0,G_PARAM_READABLE)); /* CHECKME */ - g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_FORMAT, - g_param_spec_int("format","format","format", - G_MININT,G_MAXINT,0,G_PARAM_READWRITE)); /* CHECKME */ - g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_CHANNELS, - g_param_spec_int("channels","channels","channels", - G_MININT,G_MAXINT,0,G_PARAM_READWRITE)); /* CHECKME */ - g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_FREQUENCY, - g_param_spec_int("frequency","frequency","frequency", - G_MININT,G_MAXINT,0,G_PARAM_READWRITE)); /* CHECKME */ g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_DEVICE, g_param_spec_string("device","device","oss device (/dev/dspN usually)", "default",G_PARAM_READWRITE)); @@ -166,20 +153,22 @@ gst_osssrc_init (GstOssSrc *osssrc) { osssrc->srcpad = gst_pad_new_from_template ( GST_PAD_TEMPLATE_GET (osssrc_src_factory), "src"); - gst_pad_set_get_function(osssrc->srcpad,gst_osssrc_get); - gst_pad_set_connect_function (osssrc->srcpad, gst_osssrc_connect); + gst_pad_set_get_function (osssrc->srcpad, gst_osssrc_get); + gst_pad_set_connect_function (osssrc->srcpad, gst_osssrc_srcconnect); gst_element_add_pad (GST_ELEMENT (osssrc), osssrc->srcpad); osssrc->device = g_strdup ("/dev/dsp"); osssrc->fd = -1; /* adding some default values */ - osssrc->format = AFMT_S16_LE; + osssrc->law = 0; + osssrc->endianness = G_BYTE_ORDER; + osssrc->sign = TRUE; + osssrc->depth = 16; + osssrc->width = 16; osssrc->channels = 2; - osssrc->frequency = 44100; - + osssrc->rate = 44100; osssrc->need_eos = FALSE; - osssrc->need_sync = FALSE; osssrc->bytes_per_read = 4096; osssrc->curoffset = 0; @@ -187,6 +176,82 @@ gst_osssrc_init (GstOssSrc *osssrc) osssrc->samples_since_basetime = 0; } +static GstPadConnectReturn +gst_osssrc_srcconnect (GstPad *pad, GstCaps *caps) +{ + GstOssSrc *src; + + src = GST_OSSSRC(gst_pad_get_parent (pad)); + + if (!GST_CAPS_IS_FIXED (caps)) + return GST_PAD_CONNECT_DELAYED; + + gst_caps_get_int (caps, "law", &src->law); + gst_caps_get_int (caps, "endianness", &src->endianness); + gst_caps_get_boolean (caps, "signed", &src->sign); + gst_caps_get_int (caps, "width", &src->width); + gst_caps_get_int (caps, "depth", &src->depth); + gst_caps_get_int (caps, "rate", &src->rate); + gst_caps_get_int (caps, "channels", &src->channels); + + if (!gst_osssrc_sync_parms (src)) + return GST_PAD_CONNECT_REFUSED; + + return GST_PAD_CONNECT_OK; +} +#define GET_FIXED_INT(caps, name, dest) \ +G_STMT_START { \ + if (gst_caps_has_fixed_property (caps, name)) \ + gst_caps_get_int (caps, name, dest); \ +} G_STMT_END +#define GET_FIXED_BOOLEAN(caps, name, dest) \ +G_STMT_START { \ + if (gst_caps_has_fixed_property (caps, name)) \ + gst_caps_get_boolean (caps, name, dest); \ +} G_STMT_END + +static gboolean +gst_osssrc_negotiate (GstPad *pad) +{ + GstOssSrc *src; + GstCaps *allowed; + + src = GST_OSSSRC(gst_pad_get_parent (pad)); + + allowed = gst_pad_get_allowed_caps (pad); + + /* peel off fixed stuff from the allowed caps */ + GET_FIXED_INT (allowed, "law", &src->law); + GET_FIXED_INT (allowed, "endianness", &src->endianness); + GET_FIXED_BOOLEAN (allowed, "signed", &src->sign); + GET_FIXED_INT (allowed, "width", &src->width); + GET_FIXED_INT (allowed, "depth", &src->depth); + GET_FIXED_INT (allowed, "rate", &src->rate); + GET_FIXED_INT (allowed, "channels", &src->channels); + + if (!gst_osssrc_sync_parms (src)) + return FALSE; + + /* set caps on src pad */ + if (gst_pad_try_set_caps (src->srcpad, + GST_CAPS_NEW ( + "oss_src", + "audio/raw", + "format", GST_PROPS_STRING ("int"), + "law", GST_PROPS_INT (src->law), + "endianness", GST_PROPS_INT (src->endianness), + "signed", GST_PROPS_BOOLEAN (src->sign), + "width", GST_PROPS_INT (src->width), + "depth", GST_PROPS_INT (src->depth), + "rate", GST_PROPS_INT (src->rate), + "channels", GST_PROPS_INT (src->channels) + )) <= 0) + { + return FALSE; + } + return TRUE; +} + static GstBuffer * gst_osssrc_get (GstPad *pad) { @@ -195,22 +260,17 @@ gst_osssrc_get (GstPad *pad) glong readbytes; glong readsamples; - g_return_val_if_fail (pad != NULL, NULL); src = GST_OSSSRC(gst_pad_get_parent (pad)); GST_DEBUG (GST_CAT_PLUGIN_INFO, "attempting to read something from the soundcard"); if (src->need_eos) { -/* gst_element_set_eos (GST_ELEMENT (src)); */ src->need_eos = FALSE; return GST_BUFFER (gst_event_new (GST_EVENT_EOS)); } - buf = gst_buffer_new (); - g_return_val_if_fail (buf, NULL); + buf = gst_buffer_new_and_alloc (src->bytes_per_read); - GST_BUFFER_DATA (buf) = (gpointer)g_malloc (src->bytes_per_read); - readbytes = read (src->fd,GST_BUFFER_DATA (buf), src->bytes_per_read); @@ -218,43 +278,28 @@ gst_osssrc_get (GstPad *pad) gst_element_set_eos (GST_ELEMENT (src)); return NULL; } + if (!GST_PAD_CAPS (pad)) { - /* set caps on src pad */ - if (gst_pad_try_set_caps (src->srcpad, - GST_CAPS_NEW ( - "oss_src", - "audio/raw", - "format", GST_PROPS_STRING ("int"), - "law", GST_PROPS_INT (0), /*FIXME */ - "endianness", GST_PROPS_INT (G_BYTE_ORDER), /*FIXME */ - "signed", GST_PROPS_BOOLEAN (TRUE), /*FIXME */ - "width", GST_PROPS_INT (src->format), - "depth", GST_PROPS_INT (src->format), - "rate", GST_PROPS_INT (src->frequency), - "channels", GST_PROPS_INT (src->channels) - )) <= 0) - { - gst_element_error (GST_ELEMENT (src), "could not set caps"); + /* nothing was negotiated, we can decide on a format */ + if (!gst_osssrc_negotiate (pad)) { + gst_element_error (GST_ELEMENT (src), "could not negotiate format"); return NULL; } } - else - { - /* where did they come from ? */ - gst_caps_debug (gst_pad_get_caps (src->srcpad), "caps were already set on oss"); - } GST_BUFFER_SIZE (buf) = readbytes; GST_BUFFER_OFFSET (buf) = src->curoffset; GST_BUFFER_TIMESTAMP (buf) = src->basetime + - src->samples_since_basetime * GST_SECOND / src->frequency; + src->samples_since_basetime * GST_SECOND / src->rate; src->curoffset += readbytes; readsamples = readbytes / src->channels; - if (src->format == 16) readsamples /= 2; + if (src->width == 16) readsamples /= 2; src->samples_since_basetime += readsamples; - GST_DEBUG (GST_CAT_PLUGIN_INFO, "pushed buffer from soundcard of %ld bytes, timestamp %lld", readbytes, GST_BUFFER_TIMESTAMP (buf)); + GST_DEBUG (GST_CAT_PLUGIN_INFO, "pushed buffer from soundcard of %ld bytes, timestamp %lld", + readbytes, GST_BUFFER_TIMESTAMP (buf)); + return buf; } @@ -272,22 +317,6 @@ gst_osssrc_set_property (GObject *object, guint prop_id, const GValue *value, GP case ARG_BYTESPERREAD: src->bytes_per_read = g_value_get_ulong (value); break; - case ARG_FORMAT: - src->format = g_value_get_int (value); - break; - case ARG_CHANNELS: - src->channels = g_value_get_int (value); - break; - case ARG_FREQUENCY: - /* Preserve the timestamps */ - src->basetime = src->samples_since_basetime * GST_SECOND / src->frequency; - src->samples_since_basetime = 0; - - src->frequency = g_value_get_int (value); - break; - case ARG_CUROFFSET: - src->curoffset = g_value_get_ulong (value); - break; case ARG_DEVICE: g_free(src->device); src->device = g_strdup (g_value_get_string (value)); @@ -311,18 +340,6 @@ gst_osssrc_get_property (GObject *object, guint prop_id, GValue *value, GParamSp case ARG_BYTESPERREAD: g_value_set_ulong (value, src->bytes_per_read); break; - case ARG_FORMAT: - g_value_set_int (value, src->format); - break; - case ARG_CHANNELS: - g_value_set_int (value, src->channels); - break; - case ARG_FREQUENCY: - g_value_set_int (value, src->frequency); - break; - case ARG_CUROFFSET: - g_value_set_ulong (value, src->curoffset); - break; case ARG_DEVICE: g_value_set_string (value, src->device); break; @@ -337,42 +354,27 @@ gst_osssrc_change_state (GstElement *element) { GstOssSrc *osssrc = GST_OSSSRC (element); - g_return_val_if_fail (GST_IS_OSSSRC (element), FALSE); GST_DEBUG (GST_CAT_PLUGIN_INFO, "osssrc: state change"); switch (GST_STATE_TRANSITION (element)) { - case GST_STATE_READY_TO_NULL: - break; - - case GST_STATE_NULL_TO_READY: - break; - - case GST_STATE_READY_TO_PAUSED: - /* Paused state: open device */ - if (!GST_FLAG_IS_SET (element, GST_OSSSRC_OPEN)) { - if (!gst_osssrc_open_audio (GST_OSSSRC (element))) - return GST_STATE_FAILURE; - } - - break; - - case GST_STATE_PAUSED_TO_READY: - /* Going down to ready: close device */ - if (GST_FLAG_IS_SET (element, GST_OSSSRC_OPEN)) - gst_osssrc_close_audio (GST_OSSSRC (element)); - - break; - - case GST_STATE_PAUSED_TO_PLAYING: - if (osssrc->need_sync) { - gst_osssrc_sync_parms (GST_OSSSRC (element)); - osssrc->need_sync = FALSE; - } - - break; - - case GST_STATE_PLAYING_TO_PAUSED: - break; + case GST_STATE_NULL_TO_READY: + break; + case GST_STATE_READY_TO_PAUSED: + if (!GST_FLAG_IS_SET (element, GST_OSSSRC_OPEN)) { + if (!gst_osssrc_open_audio (osssrc)) + return GST_STATE_FAILURE; + } + break; + case GST_STATE_PAUSED_TO_PLAYING: + break; + case GST_STATE_PLAYING_TO_PAUSED: + break; + case GST_STATE_PAUSED_TO_READY: + if (GST_FLAG_IS_SET (element, GST_OSSSRC_OPEN)) + gst_osssrc_close_audio (osssrc); + break; + case GST_STATE_READY_TO_NULL: + break; } if (GST_ELEMENT_CLASS (parent_class)->change_state) @@ -381,25 +383,6 @@ gst_osssrc_change_state (GstElement *element) return GST_STATE_SUCCESS; } -static GstPadConnectReturn -gst_osssrc_connect (GstPad *pad, - GstCaps *caps) -{ - GstOssSrc *osssrc; - - osssrc = GST_OSSSRC (GST_PAD_PARENT (pad)); - - if (!GST_CAPS_IS_FIXED (caps)) { - return GST_PAD_CONNECT_DELAYED; - } - - gst_caps_get_int (caps, "rate", &osssrc->frequency); - gst_caps_get_int (caps, "channels", &osssrc->channels); - - osssrc->need_sync = TRUE; - return GST_PAD_CONNECT_OK; -} - static gboolean gst_osssrc_send_event (GstElement *element, GstEvent *event) @@ -410,13 +393,12 @@ gst_osssrc_send_event (GstElement *element, osssrc = GST_OSSSRC (element); switch (GST_EVENT_TYPE (event)) { - case GST_EVENT_EOS: - osssrc->need_eos = TRUE; - retval = TRUE; - break; - - default: - break; + case GST_EVENT_EOS: + osssrc->need_eos = TRUE; + retval = TRUE; + break; + default: + break; } gst_event_unref (event); @@ -435,7 +417,6 @@ gst_osssrc_open_audio (GstOssSrc *src) if (src->fd > 0) { /* set card state */ - gst_osssrc_sync_parms (src); GST_DEBUG (GST_CAT_PLUGIN_INFO,"opened audio: %s",src->device); GST_FLAG_SET (src, GST_OSSSRC_OPEN); @@ -456,7 +437,7 @@ gst_osssrc_close_audio (GstOssSrc *src) GST_FLAG_UNSET (src, GST_OSSSRC_OPEN); } -static void +static gboolean gst_osssrc_sync_parms (GstOssSrc *osssrc) { audio_buf_info ispace; @@ -465,32 +446,39 @@ gst_osssrc_sync_parms (GstOssSrc *osssrc) * is actually set to ! Setting it to 44101 Hz could cause it to * be set to 44101, for example */ + guint rate; + gint format; + gint bps; - guint frequency; - - g_return_if_fail (osssrc != NULL); - g_return_if_fail (GST_IS_OSSSRC (osssrc)); - g_return_if_fail (osssrc->fd > 0); + g_return_val_if_fail (osssrc->fd > 0, FALSE); - frequency = osssrc->frequency; + /* get rate, we don't modify the original rate as the audio device + * might not exactly give us the requested value */ + rate = osssrc->rate; + /* transform format parameters to oss format */ + if (!gst_ossformat_get (osssrc->law, osssrc->endianness, osssrc->sign, + osssrc->width, osssrc->depth, &format, &bps)) + { + return FALSE; + } + frag = 0x7fff0006; ioctl(osssrc->fd, SNDCTL_DSP_SETFRAGMENT, &frag); ioctl(osssrc->fd, SNDCTL_DSP_RESET, 0); - ioctl(osssrc->fd, SNDCTL_DSP_SETFMT, &osssrc->format); + ioctl(osssrc->fd, SNDCTL_DSP_SETFMT, &format); ioctl(osssrc->fd, SNDCTL_DSP_CHANNELS, &osssrc->channels); - ioctl(osssrc->fd, SNDCTL_DSP_SPEED, &osssrc->frequency); - osssrc->frequency = frequency; - ioctl(osssrc->fd, SNDCTL_DSP_SPEED, &frequency); + ioctl(osssrc->fd, SNDCTL_DSP_SPEED, &rate); ioctl(osssrc->fd, SNDCTL_DSP_GETISPACE, &ispace); ioctl(osssrc->fd, SNDCTL_DSP_GETBLKSIZE, &frag); g_print("setting sound card to %dHz %d bit %s (%d bytes buffer, %d fragment)\n", - osssrc->frequency, osssrc->format, + rate, osssrc->width, (osssrc->channels == 2) ? "stereo" : "mono", ispace.bytes, frag); + return TRUE; } gboolean @@ -498,10 +486,13 @@ gst_osssrc_factory_init (GstPlugin *plugin) { GstElementFactory *factory; - factory = gst_element_factory_new ("osssrc", GST_TYPE_OSSSRC, &gst_osssrc_details); + factory = gst_element_factory_new ("osssrc", + GST_TYPE_OSSSRC, + &gst_osssrc_details); g_return_val_if_fail (factory != NULL, FALSE); - gst_element_factory_add_pad_template (factory, GST_PAD_TEMPLATE_GET (osssrc_src_factory)); + gst_element_factory_add_pad_template (factory, + GST_PAD_TEMPLATE_GET (osssrc_src_factory)); gst_plugin_add_feature (plugin, GST_PLUGIN_FEATURE (factory)); diff --git a/sys/oss/gstosssrc.h b/sys/oss/gstosssrc.h index 5109c3c..0c082a1 100644 --- a/sys/oss/gstosssrc.h +++ b/sys/oss/gstosssrc.h @@ -28,11 +28,7 @@ #include #include - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - +G_BEGIN_DECLS #define GST_TYPE_OSSSRC \ (gst_osssrc_get_type()) @@ -67,11 +63,14 @@ struct _GstOssSrc { gint fd; /* audio parameters */ - gint format; + gint law; + gint endianness; + gint sign; + gint width; + gint depth; + gint rate; gint channels; - gint frequency; - gboolean need_sync; /* Do the parameters need resynced? */ gboolean need_eos; /* Do we need to emit an EOS? */ /* blocking */ @@ -90,9 +89,6 @@ GType gst_osssrc_get_type(void); gboolean gst_osssrc_factory_init (GstPlugin *plugin); -#ifdef __cplusplus -} -#endif /* __cplusplus */ - +G_END_DECLS #endif /* __GST_OSSSRC_H__ */ -- 2.7.4