From 9566dd506b97cf03b7c8d08bca6af5d7991c7201 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Mon, 10 Oct 2005 14:16:21 +0000 Subject: [PATCH] sys/oss/: Cleanups, make device configurable in the sink, handle and report errors. Original commit message from CVS: * sys/oss/gstosssink.c: (gst_oss_sink_class_init), (gst_oss_sink_init), (gst_oss_sink_set_property), (gst_oss_sink_get_property), (gst_oss_sink_open), (gst_oss_sink_prepare), (gst_oss_sink_reset): * sys/oss/gstosssink.h: * sys/oss/gstosssrc.c: (gst_oss_src_class_init), (gst_oss_src_set_property), (gst_oss_src_init), (gst_oss_src_open), (gst_oss_src_prepare): Cleanups, make device configurable in the sink, handle and report errors. --- ChangeLog | 13 +++++ sys/oss/gstosssink.c | 118 +++++++++++++++++++++++++++++++++++-------- sys/oss/gstosssink.h | 5 +- sys/oss/gstosssrc.c | 80 ++++++++++++++++++----------- 4 files changed, 163 insertions(+), 53 deletions(-) diff --git a/ChangeLog b/ChangeLog index a6c025a336..5a5c738d02 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +2005-10-10 Wim Taymans + + * sys/oss/gstosssink.c: (gst_oss_sink_class_init), + (gst_oss_sink_init), (gst_oss_sink_set_property), + (gst_oss_sink_get_property), (gst_oss_sink_open), + (gst_oss_sink_prepare), (gst_oss_sink_reset): + * sys/oss/gstosssink.h: + * sys/oss/gstosssrc.c: (gst_oss_src_class_init), + (gst_oss_src_set_property), (gst_oss_src_init), (gst_oss_src_open), + (gst_oss_src_prepare): + Cleanups, make device configurable in the sink, handle and report + errors. + 2005-10-10 Wim Taymans * ext/gconf/gstgconfaudiosink.c: (gst_gconf_audio_sink_reset): diff --git a/sys/oss/gstosssink.c b/sys/oss/gstosssink.c index 92dd0ecd36..4e46c23944 100644 --- a/sys/oss/gstosssink.c +++ b/sys/oss/gstosssink.c @@ -46,6 +46,11 @@ static void gst_oss_sink_class_init (GstOssSinkClass * klass); static void gst_oss_sink_init (GstOssSink * osssink); static void gst_oss_sink_dispose (GObject * object); +static void gst_oss_sink_get_property (GObject * object, guint prop_id, + GValue * value, GParamSpec * pspec); +static void gst_oss_sink_set_property (GObject * object, guint prop_id, + const GValue * value, GParamSpec * pspec); + static GstCaps *gst_oss_sink_getcaps (GstBaseSink * bsink); static gboolean gst_oss_sink_open (GstAudioSink * asink); @@ -64,6 +69,13 @@ enum LAST_SIGNAL }; +#define DEFAULT_DEVICE "/dev/dsp" +enum +{ + PROP_0, + PROP_DEVICE, +}; + static GstStaticPadTemplate osssink_sink_factory = GST_STATIC_PAD_TEMPLATE ("sink", GST_PAD_SINK, @@ -145,6 +157,12 @@ gst_oss_sink_class_init (GstOssSinkClass * klass) parent_class = g_type_class_ref (GST_TYPE_BASE_AUDIO_SINK); gobject_class->dispose = gst_oss_sink_dispose; + gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_oss_sink_get_property); + gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_oss_sink_set_property); + + g_object_class_install_property (gobject_class, PROP_DEVICE, + g_param_spec_string ("device", "Device", + "OSS device (usually /dev/dspN)", DEFAULT_DEVICE, G_PARAM_READWRITE)); gstbasesink_class->get_caps = GST_DEBUG_FUNCPTR (gst_oss_sink_getcaps); @@ -162,9 +180,47 @@ gst_oss_sink_init (GstOssSink * osssink) { GST_DEBUG ("initializing osssink"); + osssink->device = g_strdup (DEFAULT_DEVICE);; osssink->fd = -1; } +static void +gst_oss_sink_set_property (GObject * object, guint prop_id, + const GValue * value, GParamSpec * pspec) +{ + GstOssSink *sink; + + sink = GST_OSSSINK (object); + + switch (prop_id) { + case PROP_DEVICE: + g_free (sink->device); + sink->device = g_value_dup_string (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +gst_oss_sink_get_property (GObject * object, guint prop_id, + GValue * value, GParamSpec * pspec) +{ + GstOssSink *sink; + + sink = GST_OSSSINK (object); + + switch (prop_id) { + case PROP_DEVICE: + g_value_set_string (value, sink->device); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + static GstCaps * gst_oss_sink_getcaps (GstBaseSink * bsink) { @@ -204,16 +260,22 @@ ilog2 (gint x) G_STMT_START { \ int _tmp = _val; \ if (ioctl(_oss->fd, _name, &_tmp) == -1) { \ - perror(G_STRINGIFY (_name)); \ + GST_ELEMENT_ERROR (oss, RESOURCE, OPEN_WRITE, \ + ("Unable to set param "G_STRINGIFY (_name)": %s", \ + g_strerror (errno)), \ + (NULL)); \ return FALSE; \ } \ GST_DEBUG(G_STRINGIFY (name) " %d", _tmp); \ } G_STMT_END -#define GET_PARAM(oss, name, val) \ +#define GET_PARAM(_oss, _name, _val) \ G_STMT_START { \ - if (ioctl(oss->fd, name, val) == -1) { \ - perror(G_STRINGIFY (name)); \ + if (ioctl(oss->fd, _name, _val) == -1) { \ + GST_ELEMENT_ERROR (oss, RESOURCE, OPEN_WRITE, \ + ("Unable to get param "G_STRINGIFY (_name)": %s", \ + g_strerror (errno)), \ + (NULL)); \ return FALSE; \ } \ } G_STMT_END @@ -272,13 +334,19 @@ gst_oss_sink_open (GstAudioSink * asink) mode = O_WRONLY; mode |= O_NONBLOCK; - oss->fd = open ("/dev/dsp", mode, 0); - if (oss->fd == -1) { - perror ("/dev/dsp"); - return FALSE; - } + oss->fd = open (oss->device, mode, 0); + if (oss->fd == -1) + goto open_failed; return TRUE; + +open_failed: + { + GST_ELEMENT_ERROR (oss, RESOURCE, OPEN_WRITE, + ("Unable to open device %s for writing: %s", + oss->device, g_strerror (errno)), (NULL)); + return FALSE; + } } static gboolean @@ -300,15 +368,16 @@ gst_oss_sink_prepare (GstAudioSink * asink, GstRingBufferSpec * spec) mode = fcntl (oss->fd, F_GETFL); mode &= ~O_NONBLOCK; - if (fcntl (oss->fd, F_SETFL, mode) == -1) { - perror ("/dev/dsp"); - return FALSE; - } + if (fcntl (oss->fd, F_SETFL, mode) == -1) + goto non_block; tmp = gst_oss_sink_get_format (spec->format); if (tmp == 0) goto wrong_format; + if (spec->width != 16 && spec->width != 8) + goto dodgy_width; + SET_PARAM (oss, SNDCTL_DSP_SETFMT, tmp); if (spec->channels == 2) SET_PARAM (oss, SNDCTL_DSP_STEREO, 1); @@ -326,9 +395,6 @@ gst_oss_sink_prepare (GstAudioSink * asink, GstRingBufferSpec * spec) spec->segsize = info.fragsize; spec->segtotal = info.fragstotal; - if (spec->width != 16 && spec->width != 8) - goto dodgy_width; - spec->bytes_per_sample = (spec->width / 8) * spec->channels; oss->bytes_per_sample = (spec->width / 8) * spec->channels; memset (spec->silence_sample, 0, spec->bytes_per_sample); @@ -338,14 +404,23 @@ gst_oss_sink_prepare (GstAudioSink * asink, GstRingBufferSpec * spec) return TRUE; +non_block: + { + GST_ELEMENT_ERROR (oss, RESOURCE, OPEN_READ, + ("Unable to set device %s in non blocking mode: %s", + oss->device, g_strerror (errno)), (NULL)); + return FALSE; + } wrong_format: { - GST_DEBUG ("wrong format %d\n", spec->format); + GST_ELEMENT_ERROR (oss, RESOURCE, OPEN_READ, + ("Unable to get format %d", spec->format), (NULL)); return FALSE; } dodgy_width: { - GST_DEBUG ("unexpected width %d\n", spec->width); + GST_ELEMENT_ERROR (oss, RESOURCE, OPEN_READ, + ("unexpected width %d", spec->width), (NULL)); return FALSE; } } @@ -408,12 +483,13 @@ gst_oss_sink_delay (GstAudioSink * asink) static void gst_oss_sink_reset (GstAudioSink * asink) { +#if 0 GstOssSink *oss; - - //gint ret; + gint ret; oss = GST_OSSSINK (asink); /* deadlocks on my machine... */ - //ret = ioctl (oss->fd, SNDCTL_DSP_RESET, 0); + ret = ioctl (oss->fd, SNDCTL_DSP_RESET, 0); +#endif } diff --git a/sys/oss/gstosssink.h b/sys/oss/gstosssink.h index 3cede595d1..c97f003ce9 100644 --- a/sys/oss/gstosssink.h +++ b/sys/oss/gstosssink.h @@ -44,8 +44,9 @@ typedef struct _GstOssSinkClass GstOssSinkClass; struct _GstOssSink { GstAudioSink sink; - gint fd; - gint bytes_per_sample; + gchar *device; + gint fd; + gint bytes_per_sample; }; struct _GstOssSinkClass { diff --git a/sys/oss/gstosssrc.c b/sys/oss/gstosssrc.c index 9d1a7b4dcb..6c2f70082a 100644 --- a/sys/oss/gstosssrc.c +++ b/sys/oss/gstosssrc.c @@ -39,6 +39,8 @@ GST_ELEMENT_DETAILS ("Audio Source (OSS)", "Capture from a sound card via OSS", "Erik Walthinsen , " "Wim Taymans "); +#define DEFAULT_DEVICE "/dev/dsp" +#define DEFAULT_DEVICE_NAME "" enum { @@ -136,11 +138,12 @@ gst_oss_src_class_init (GstOssSrcClass * klass) g_object_class_install_property (gobject_class, PROP_DEVICE, g_param_spec_string ("device", "Device", - "OSS device (usually /dev/dspN)", "/dev/dsp", G_PARAM_READWRITE)); + "OSS device (usually /dev/dspN)", DEFAULT_DEVICE, G_PARAM_READWRITE)); g_object_class_install_property (gobject_class, PROP_DEVICE_NAME, g_param_spec_string ("device-name", "Device name", - "Human-readable name of the sound device", "", G_PARAM_READABLE)); + "Human-readable name of the sound device", DEFAULT_DEVICE_NAME, + G_PARAM_READABLE)); } static void @@ -155,7 +158,7 @@ gst_oss_src_set_property (GObject * object, guint prop_id, case PROP_DEVICE: if (src->device) g_free (src->device); - src->device = g_strdup (g_value_get_string (value)); + src->device = g_value_dup_string (value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); @@ -190,7 +193,8 @@ gst_oss_src_init (GstOssSrc * osssrc, GstOssSrcClass * g_class) GST_DEBUG ("initializing osssrc"); osssrc->fd = -1; - osssrc->device = g_strdup ("/dev/dsp"); + osssrc->device = g_strdup (DEFAULT_DEVICE); + osssrc->device_name = g_strdup (DEFAULT_DEVICE_NAME); } static GstCaps * @@ -228,22 +232,29 @@ ilog2 (gint x) return (x & 0x0000003f) - 1; } -#define SET_PARAM(_oss, _label, _name, _val) \ +#define SET_PARAM(_oss, _name, _val) \ G_STMT_START { \ int _tmp = _val; \ if (ioctl(_oss->fd, _name, &_tmp) == -1) { \ - perror(_label); \ + GST_ELEMENT_ERROR (oss, RESOURCE, OPEN_READ, \ + ("Unable to set param "G_STRINGIFY (_name)": %s", \ + g_strerror (errno)), \ + (NULL)); \ return FALSE; \ } \ - GST_DEBUG_OBJECT (_oss, _label " %d", _tmp); \ + GST_DEBUG_OBJECT (_oss, G_STRINGIFY (_name)" %d", _tmp); \ } G_STMT_END -#define GET_PARAM(oss, label, name, val) \ +#define GET_PARAM(_oss, _name, _val) \ G_STMT_START { \ - if (ioctl(oss->fd, name, val) == -1) { \ - perror(label); \ + if (ioctl(oss->fd, _name, _val) == -1) { \ + GST_ELEMENT_ERROR (oss, RESOURCE, OPEN_READ, \ + ("Unable to get param "G_STRINGIFY (_name)": %s", \ + g_strerror (errno)), \ + (NULL)); \ return FALSE; \ } \ + GST_DEBUG_OBJECT (_oss, G_STRINGIFY (_name)" %d", _val); \ } G_STMT_END static gint @@ -301,23 +312,26 @@ gst_oss_src_open (GstAudioSrc * asrc) mode |= O_NONBLOCK; oss->fd = open (oss->device, mode, 0); - if (oss->fd == -1) { - perror (oss->device); - return FALSE; - } + if (oss->fd == -1) + goto open_failed; if (!oss->mixer) { oss->mixer = gst_ossmixer_new ("/dev/mixer", GST_OSS_MIXER_CAPTURE); if (oss->mixer) { - if (oss->device_name) { - g_free (oss->device_name); - } + g_free (oss->device_name); oss->device_name = g_strdup (oss->mixer->cardname); } } - return TRUE; + +open_failed: + { + GST_ELEMENT_ERROR (oss, RESOURCE, OPEN_READ, + ("Unable to open device %s for recording: %s", + oss->device, g_strerror (errno)), (NULL)); + return FALSE; + } } static gboolean @@ -349,10 +363,8 @@ gst_oss_src_prepare (GstAudioSrc * asrc, GstRingBufferSpec * spec) mode = fcntl (oss->fd, F_GETFL); mode &= ~O_NONBLOCK; - if (fcntl (oss->fd, F_SETFL, mode) == -1) { - perror (oss->device); - return FALSE; - } + if (fcntl (oss->fd, F_SETFL, mode) == -1) + goto non_block; tmp = gst_oss_src_get_format (spec->format); if (tmp == 0) @@ -363,17 +375,17 @@ gst_oss_src_prepare (GstAudioSrc * asrc, GstRingBufferSpec * spec) GST_DEBUG ("set segsize: %d, segtotal: %d, value: %08x", spec->segsize, spec->segtotal, tmp); - SET_PARAM (oss, "SETFRAGMENT", SNDCTL_DSP_SETFRAGMENT, tmp); + SET_PARAM (oss, SNDCTL_DSP_SETFRAGMENT, tmp); - SET_PARAM (oss, "RESET", SNDCTL_DSP_RESET, 0); + SET_PARAM (oss, SNDCTL_DSP_RESET, 0); - SET_PARAM (oss, "SETFMT", SNDCTL_DSP_SETFMT, tmp); + SET_PARAM (oss, SNDCTL_DSP_SETFMT, tmp); if (spec->channels == 2) - SET_PARAM (oss, "STEREO", SNDCTL_DSP_STEREO, 1); - SET_PARAM (oss, "CHANNELS", SNDCTL_DSP_CHANNELS, spec->channels); - SET_PARAM (oss, "SPEED", SNDCTL_DSP_SPEED, spec->rate); + SET_PARAM (oss, SNDCTL_DSP_STEREO, 1); + SET_PARAM (oss, SNDCTL_DSP_CHANNELS, spec->channels); + SET_PARAM (oss, SNDCTL_DSP_SPEED, spec->rate); - GET_PARAM (oss, "GETISPACE", SNDCTL_DSP_GETISPACE, &info); + GET_PARAM (oss, SNDCTL_DSP_GETISPACE, &info); spec->segsize = info.fragsize; spec->segtotal = info.fragstotal; @@ -386,9 +398,17 @@ gst_oss_src_prepare (GstAudioSrc * asrc, GstRingBufferSpec * spec) return TRUE; +non_block: + { + GST_ELEMENT_ERROR (oss, RESOURCE, OPEN_READ, + ("Unable to set device %s in non blocking mode: %s", + oss->device, g_strerror (errno)), (NULL)); + return FALSE; + } wrong_format: { - GST_DEBUG ("wrong format %d\n", spec->format); + GST_ELEMENT_ERROR (oss, RESOURCE, OPEN_READ, + ("Unable to get format %d", spec->format), (NULL)); return FALSE; } }