diff options
author | Tim-Philipp Müller <tim@centricular.net> | 2005-12-14 17:58:48 +0000 |
---|---|---|
committer | Tim-Philipp Müller <tim@centricular.net> | 2005-12-14 17:58:48 +0000 |
commit | 534e0c268e227f56159161e5309f3a5b98fa1312 (patch) | |
tree | 15d0252e8386007b7022c8b2ce998bb0c864f347 | |
parent | 68232a28919ee281fd6fe61f1e42693feb5965de (diff) |
ext/alsa/: Helper functions to add device probing via the GstPropertyProbe interface to a class.
Original commit message from CVS:
* ext/alsa/Makefile.am:
* ext/alsa/gstalsadeviceprobe.c:
* ext/alsa/gstalsadeviceprobe.h:
Helper functions to add device probing via the GstPropertyProbe
interface to a class.
* ext/alsa/gstalsamixer.h:
Comment out GST_ALSA_MIXER, it returns a struct that's not
used.
* ext/alsa/gstalsamixer.c: (gst_alsa_mixer_open):
Add some debug info.
* ext/alsa/gstalsamixerelement.c:
(gst_alsa_mixer_element_interface_supported),
(gst_implements_interface_init),
(gst_alsa_mixer_element_init_interfaces),
(gst_alsa_mixer_element_class_init),
(gst_alsa_mixer_element_finalize), (gst_alsa_mixer_element_init),
(gst_alsa_mixer_element_set_property),
(gst_alsa_mixer_element_get_property),
(gst_alsa_mixer_element_change_state):
* ext/alsa/gstalsamixerelement.h:
Add 'device' and 'device-name' properties. Add GstPropertyProbe
for device handling (gnome-volume-control will need that).
-rw-r--r-- | ChangeLog | 29 | ||||
-rw-r--r-- | ext/alsa/Makefile.am | 10 | ||||
-rw-r--r-- | ext/alsa/gstalsadeviceprobe.c | 291 | ||||
-rw-r--r-- | ext/alsa/gstalsadeviceprobe.h | 43 | ||||
-rw-r--r-- | ext/alsa/gstalsamixer.c | 7 | ||||
-rw-r--r-- | ext/alsa/gstalsamixer.h | 4 | ||||
-rw-r--r-- | ext/alsa/gstalsamixerelement.c | 165 | ||||
-rw-r--r-- | ext/alsa/gstalsamixerelement.h | 4 |
8 files changed, 532 insertions, 21 deletions
@@ -1,5 +1,32 @@ -2005-12-12 Christian Schaller <set EMAIL_ADDRESS environment variable> +2005-12-14 Tim-Philipp Müller <tim at centricular dot net> + * ext/alsa/Makefile.am: + * ext/alsa/gstalsadeviceprobe.c: + * ext/alsa/gstalsadeviceprobe.h: + Helper functions to add device probing via the GstPropertyProbe + interface to a class. + + * ext/alsa/gstalsamixer.h: + Comment out GST_ALSA_MIXER, it returns a struct that's not + used. + + * ext/alsa/gstalsamixer.c: (gst_alsa_mixer_open): + Add some debug info. + + * ext/alsa/gstalsamixerelement.c: + (gst_alsa_mixer_element_interface_supported), + (gst_implements_interface_init), + (gst_alsa_mixer_element_init_interfaces), + (gst_alsa_mixer_element_class_init), + (gst_alsa_mixer_element_finalize), (gst_alsa_mixer_element_init), + (gst_alsa_mixer_element_set_property), + (gst_alsa_mixer_element_get_property), + (gst_alsa_mixer_element_change_state): + * ext/alsa/gstalsamixerelement.h: + Add 'device' and 'device-name' properties. Add GstPropertyProbe + for device handling (gnome-volume-control will need that). + +2005-12-12 Christian Schaller <uraeus@gnome.org> * ext/Makefile.am: fix cdparanoia entry * gst-plugins-base.spec.in: add cdparanoia diff --git a/ext/alsa/Makefile.am b/ext/alsa/Makefile.am index a8bfdeda2..c34e112f8 100644 --- a/ext/alsa/Makefile.am +++ b/ext/alsa/Makefile.am @@ -1,11 +1,12 @@ plugin_LTLIBRARIES = libgstalsa.la libgstalsa_la_SOURCES = \ - gstalsaplugin.c \ + gstalsadeviceprobe.c \ gstalsamixer.c \ gstalsamixerelement.c \ gstalsamixertrack.c \ gstalsamixeroptions.c \ + gstalsaplugin.c \ gstalsasink.c \ gstalsasrc.c @@ -18,9 +19,10 @@ libgstalsa_la_LIBADD = \ noinst_HEADERS = \ gstalsa.h \ - gstalsasink.h \ - gstalsasrc.h \ + gstalsadeviceprobe.h \ gstalsamixer.h \ gstalsamixerelement.h \ gstalsamixertrack.h \ - gstalsamixeroptions.h + gstalsamixeroptions.h \ + gstalsasrc.h \ + gstalsasink.h diff --git a/ext/alsa/gstalsadeviceprobe.c b/ext/alsa/gstalsadeviceprobe.c new file mode 100644 index 000000000..606918c5b --- /dev/null +++ b/ext/alsa/gstalsadeviceprobe.c @@ -0,0 +1,291 @@ +/* Copyright (C) 2001 CodeFactory AB + * Copyright (C) 2001 Thomas Nyberg <thomas@codefactory.se> + * Copyright (C) 2001-2002 Andy Wingo <apwingo@eos.ncsu.edu> + * Copyright (C) 2003 Benjamin Otte <in7y118@public.uni-hamburg.de> + * Copyright (C) 2005 Tim-Philipp Müller <tim centricular net> + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "gstalsadeviceprobe.h" +#include "gst/interfaces/propertyprobe.h" + +#define DATA_OFFSET_QUARK \ + g_quark_from_static_string ("alsa-device-probe-data-offset-quark") + +#define DEVICE_PROPID_QUARK \ + g_quark_from_static_string ("alsa-device-probe-device-propid-quark") + +static const GList * +gst_alsa_device_property_probe_get_properties (GstPropertyProbe * probe) +{ + GObjectClass *klass = G_OBJECT_GET_CLASS (probe); + static GList *list = NULL; + + /* well, not perfect, but better than no locking at all. + * In the worst case we leak a list node, so who cares? */ + GST_CLASS_LOCK (GST_OBJECT_CLASS (klass)); + + if (!list) { + GParamSpec *pspec; + + pspec = g_object_class_find_property (klass, "device"); + list = g_list_append (NULL, pspec); + } + + GST_CLASS_UNLOCK (GST_OBJECT_CLASS (klass)); + + return list; +} + +/* yes, this is evil, but hey, it works */ + +static gboolean +gst_alsa_device_probe_get_data (GObject * obj, GstAlsaDeviceProbeData ** p_data, + guint * p_device_propid) +{ + gpointer klass; + guint devpropid; + guint offset; + GType type; + + type = G_TYPE_FROM_INSTANCE (obj); + + /* in case this is a derived class ... */ + while (g_type_get_qdata (type, DATA_OFFSET_QUARK) == NULL) { + type = g_type_parent (type); + g_return_val_if_fail (G_TYPE_IS_FUNDAMENTAL (type) == FALSE, FALSE); + } + + offset = GPOINTER_TO_UINT (g_type_get_qdata (type, DATA_OFFSET_QUARK)); + devpropid = GPOINTER_TO_UINT (g_type_get_qdata (type, DEVICE_PROPID_QUARK)); + + g_return_val_if_fail (offset != 0, FALSE); + g_return_val_if_fail (devpropid != 0, FALSE); + + klass = G_OBJECT_GET_CLASS (obj); + + *p_data = (GstAlsaDeviceProbeData *) G_STRUCT_MEMBER_P (klass, offset); + *p_device_propid = devpropid; + + return TRUE; +} + +static void +gst_alsa_add_device_list (GstAlsaDeviceProbeData * probe_data, + snd_pcm_stream_t stream) +{ + snd_ctl_t *handle; + int card, err, dev; + snd_ctl_card_info_t *info; + snd_pcm_info_t *pcminfo; + gboolean mixer = (stream == -1); + + if (stream == -1) + stream = 0; + + snd_ctl_card_info_alloca (&info); + snd_pcm_info_alloca (&pcminfo); + card = -1; + + if (snd_card_next (&card) < 0 || card < 0) { + /* no soundcard found */ + return; + } + while (card >= 0) { + gchar name[32]; + + g_snprintf (name, sizeof (name), "hw:%d", card); + if ((err = snd_ctl_open (&handle, name, 0)) < 0) { + goto next_card; + } + if ((err = snd_ctl_card_info (handle, info)) < 0) { + snd_ctl_close (handle); + goto next_card; + } + + if (mixer) { + probe_data->devices = g_list_append (probe_data->devices, + g_strdup (name)); + } else { + dev = -1; + while (1) { + gchar *gst_device; + + snd_ctl_pcm_next_device (handle, &dev); + + if (dev < 0) + break; + snd_pcm_info_set_device (pcminfo, dev); + snd_pcm_info_set_subdevice (pcminfo, 0); + snd_pcm_info_set_stream (pcminfo, stream); + if ((err = snd_ctl_pcm_info (handle, pcminfo)) < 0) { + continue; + } + + gst_device = g_strdup_printf ("hw:%d,%d", card, dev); + probe_data->devices = g_list_append (probe_data->devices, gst_device); + } + } + snd_ctl_close (handle); + next_card: + if (snd_card_next (&card) < 0) { + break; + } + } +} + +static gboolean +gst_alsa_probe_devices (GstElementClass * klass, + GstAlsaDeviceProbeData * probe_data, gboolean check) +{ + static gboolean init = FALSE; + + /* I'm pretty sure ALSA has a good way to do this. However, their cool + * auto-generated documentation is pretty much useless if you try to + * do function-wise look-ups. */ + + if (!init && !check) { + snd_pcm_stream_t mode = -1; + const GList *templates; + + /* we assume one pad template at max [zero=mixer] */ + templates = gst_element_class_get_pad_template_list (klass); + if (templates) { + if (GST_PAD_TEMPLATE_DIRECTION (templates->data) == GST_PAD_SRC) + mode = SND_PCM_STREAM_CAPTURE; + else + mode = SND_PCM_STREAM_PLAYBACK; + } + + gst_alsa_add_device_list (probe_data, mode); + + init = TRUE; + } + + return init; +} + +static void +gst_alsa_device_property_probe_probe_property (GstPropertyProbe * probe, + guint prop_id, const GParamSpec * pspec) +{ + GstAlsaDeviceProbeData *probe_data; + guint devid; + + if (!gst_alsa_device_probe_get_data (G_OBJECT (probe), &probe_data, &devid)) + g_return_if_reached (); + + if (prop_id == devid) { + gst_alsa_probe_devices (GST_ELEMENT_GET_CLASS (probe), probe_data, FALSE); + } else { + G_OBJECT_WARN_INVALID_PROPERTY_ID (probe, prop_id, pspec); + } +} + +static gboolean +gst_alsa_device_property_probe_needs_probe (GstPropertyProbe * probe, + guint prop_id, const GParamSpec * pspec) +{ + GstAlsaDeviceProbeData *probe_data; + GstElementClass *klass; + guint devid; + + if (!gst_alsa_device_probe_get_data (G_OBJECT (probe), &probe_data, &devid)) + g_return_val_if_reached (FALSE); + + if (prop_id != devid) { + G_OBJECT_WARN_INVALID_PROPERTY_ID (probe, prop_id, pspec); + return FALSE; + } + + klass = GST_ELEMENT_GET_CLASS (probe); + return !gst_alsa_probe_devices (klass, probe_data, TRUE); +} + +static GValueArray * +gst_alsa_device_probe_list_devices (GstAlsaDeviceProbeData * probe_data) +{ + GValueArray *array; + GValue value = { 0 }; + GList *item; + + if (!probe_data->devices) + return NULL; + + array = g_value_array_new (g_list_length (probe_data->devices)); + g_value_init (&value, G_TYPE_STRING); + for (item = probe_data->devices; item != NULL; item = item->next) { + g_value_set_string (&value, (const gchar *) item->data); + g_value_array_append (array, &value); + } + g_value_unset (&value); + + return array; +} + +static GValueArray * +gst_alsa_device_property_probe_get_values (GstPropertyProbe * probe, + guint prop_id, const GParamSpec * pspec) +{ + GstAlsaDeviceProbeData *probe_data; + guint devid; + + if (!gst_alsa_device_probe_get_data (G_OBJECT (probe), &probe_data, &devid)) + g_return_val_if_reached (NULL); + + if (prop_id != devid) { + G_OBJECT_WARN_INVALID_PROPERTY_ID (probe, prop_id, pspec); + return NULL; + } + + return gst_alsa_device_probe_list_devices (probe_data); +} + +static void +gst_alsa_property_probe_interface_init (GstPropertyProbeInterface * iface) +{ + iface->get_properties = gst_alsa_device_property_probe_get_properties; + iface->probe_property = gst_alsa_device_property_probe_probe_property; + iface->needs_probe = gst_alsa_device_property_probe_needs_probe; + iface->get_values = gst_alsa_device_property_probe_get_values; +} + +void +gst_alsa_type_add_device_property_probe_interface (GType type, + guint probe_data_klass_offset, guint device_prop_id) +{ + static const GInterfaceInfo probe_iface_info = { + (GInterfaceInitFunc) gst_alsa_property_probe_interface_init, + NULL, + NULL, + }; + + g_assert (probe_data_klass_offset != 0); + g_assert (device_prop_id != 0); + + g_type_set_qdata (type, DATA_OFFSET_QUARK, + GUINT_TO_POINTER (probe_data_klass_offset)); + + g_type_set_qdata (type, DEVICE_PROPID_QUARK, + GUINT_TO_POINTER (device_prop_id)); + + g_type_add_interface_static (type, GST_TYPE_PROPERTY_PROBE, + &probe_iface_info); +} diff --git a/ext/alsa/gstalsadeviceprobe.h b/ext/alsa/gstalsadeviceprobe.h new file mode 100644 index 000000000..3ad207658 --- /dev/null +++ b/ext/alsa/gstalsadeviceprobe.h @@ -0,0 +1,43 @@ +/* Copyright (C) 2001 CodeFactory AB + * Copyright (C) 2001 Thomas Nyberg <thomas@codefactory.se> + * Copyright (C) 2001-2002 Andy Wingo <apwingo@eos.ncsu.edu> + * Copyright (C) 2003 Benjamin Otte <in7y118@public.uni-hamburg.de> + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef __GST_ALSA_DEVICE_PROBE_H__ +#define __GST_ALSA_DEVICE_PROBE_H__ + +#include "gstalsa.h" + +G_BEGIN_DECLS + +typedef struct _GstAlsaDeviceProbeData GstAlsaDeviceProbeData; + +struct _GstAlsaDeviceProbeData { + /* autodetected devices available */ + GList *devices; +}; + +/* offset is the offset of the device probe data struct in the klass struct */ +void gst_alsa_type_add_device_property_probe_interface (GType type, + guint probe_data_offset, + guint device_prop_id); + +G_END_DECLS + +#endif /* __GST_ALSA_DEVICE_PROBE_H__ */ + diff --git a/ext/alsa/gstalsamixer.c b/ext/alsa/gstalsamixer.c index 15b25f93d..8656924d8 100644 --- a/ext/alsa/gstalsamixer.c +++ b/ext/alsa/gstalsamixer.c @@ -81,8 +81,11 @@ gst_alsa_mixer_open (GstAlsaMixer * mixer) if (sscanf (mixer->device, "hw:%d", &devicenum) == 1) { gchar *name; - if (!snd_card_get_name (devicenum, &name)) - mixer->cardname = name; + if (!snd_card_get_name (devicenum, &name)) { + mixer->cardname = g_strdup (name); + free (name); + GST_DEBUG ("Card name = %s", GST_STR_NULL (mixer->cardname)); + } } GST_INFO ("Successfully opened mixer for device `%s'.", mixer->device); diff --git a/ext/alsa/gstalsamixer.h b/ext/alsa/gstalsamixer.h index 49f71d5eb..971f8053d 100644 --- a/ext/alsa/gstalsamixer.h +++ b/ext/alsa/gstalsamixer.h @@ -30,8 +30,8 @@ G_BEGIN_DECLS - -#define GST_ALSA_MIXER(obj) ((GstAlsaMixer*)(obj)) +/* This does not get you what you think it does, use obj->mixer */ +/* #define GST_ALSA_MIXER(obj) ((GstAlsaMixer*)(obj)) */ typedef enum { diff --git a/ext/alsa/gstalsamixerelement.c b/ext/alsa/gstalsamixerelement.c index 72a16650c..ae19035c8 100644 --- a/ext/alsa/gstalsamixerelement.c +++ b/ext/alsa/gstalsamixerelement.c @@ -23,6 +23,13 @@ #endif #include "gstalsamixerelement.h" +#include "gstalsadeviceprobe.h" + +enum +{ + PROP_DEVICE = 1, + PROP_DEVICE_NAME +}; static GstElementDetails gst_alsa_mixer_element_details = @@ -31,15 +38,62 @@ GST_ELEMENT_DETAILS ("Alsa Mixer", "Control sound input and output levels with ALSA", "Leif Johnson <leif@ambient.2y.net>"); +static void gst_alsa_mixer_element_init_interfaces (GType type); + +GST_BOILERPLATE_FULL (GstAlsaMixerElement, gst_alsa_mixer_element, + GstElement, GST_TYPE_ELEMENT, gst_alsa_mixer_element_init_interfaces) + +/* massive macro that takes care of all the GstMixer stuff */ + GST_IMPLEMENT_ALSA_MIXER_METHODS (GstAlsaMixerElement, gst_alsa_mixer_element); -GST_BOILERPLATE_WITH_INTERFACE (GstAlsaMixerElement, gst_alsa_mixer_element, - GstElement, GST_TYPE_ELEMENT, GstMixer, GST_TYPE_MIXER, - gst_alsa_mixer_element); + static void gst_alsa_mixer_element_get_property (GObject * object, + guint prop_id, GValue * value, GParamSpec * pspec); + static void gst_alsa_mixer_element_set_property (GObject * object, + guint prop_id, const GValue * value, GParamSpec * pspec); + static void gst_alsa_mixer_element_finalize (GObject * object); -GST_IMPLEMENT_ALSA_MIXER_METHODS (GstAlsaMixerElement, gst_alsa_mixer_element); + static GstStateChangeReturn gst_alsa_mixer_element_change_state (GstElement + * element, GstStateChange transition); + + static gboolean + gst_alsa_mixer_element_interface_supported (GstAlsaMixerElement * this, + GType interface_type) +{ + if (interface_type == GST_TYPE_MIXER) { + return gst_alsa_mixer_element_supported (this, interface_type); + } + + g_return_val_if_reached (FALSE); +} + +static void +gst_implements_interface_init (GstImplementsInterfaceClass * klass) +{ + klass->supported = (gpointer) gst_alsa_mixer_element_interface_supported; +} -static GstStateChangeReturn gst_alsa_mixer_element_change_state (GstElement * - element, GstStateChange transition); +static void +gst_alsa_mixer_element_init_interfaces (GType type) +{ + static const GInterfaceInfo implements_iface_info = { + (GInterfaceInitFunc) gst_implements_interface_init, + NULL, + NULL, + }; + static const GInterfaceInfo mixer_iface_info = { + (GInterfaceInitFunc) gst_alsa_mixer_element_interface_init, + NULL, + NULL, + }; + + g_type_add_interface_static (type, GST_TYPE_IMPLEMENTS_INTERFACE, + &implements_iface_info); + g_type_add_interface_static (type, GST_TYPE_MIXER, &mixer_iface_info); + + gst_alsa_type_add_device_property_probe_interface (type, + G_STRUCT_OFFSET (GstAlsaMixerElementClass, device_probe_data), + PROP_DEVICE); +} static void gst_alsa_mixer_element_base_init (gpointer klass) @@ -52,10 +106,36 @@ static void gst_alsa_mixer_element_class_init (GstAlsaMixerElementClass * klass) { GstElementClass *element_class; + GObjectClass *gobject_class; element_class = (GstElementClass *) klass; + gobject_class = (GObjectClass *) klass; + + gobject_class->finalize = gst_alsa_mixer_element_finalize; + gobject_class->get_property = gst_alsa_mixer_element_get_property; + gobject_class->set_property = gst_alsa_mixer_element_set_property; - element_class->change_state = gst_alsa_mixer_element_change_state; + g_object_class_install_property (gobject_class, PROP_DEVICE, + g_param_spec_string ("device", "Device", + "ALSA device, as defined in an asound configuration file", + "default", 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)); + + element_class->change_state = + GST_DEBUG_FUNCPTR (gst_alsa_mixer_element_change_state); +} + +static void +gst_alsa_mixer_element_finalize (GObject * obj) +{ + GstAlsaMixerElement *this = GST_ALSA_MIXER_ELEMENT (obj); + + g_free (this->device); + + G_OBJECT_CLASS (parent_class)->finalize (obj); } static void @@ -63,20 +143,84 @@ gst_alsa_mixer_element_init (GstAlsaMixerElement * this, GstAlsaMixerElementClass * klass) { this->mixer = NULL; + this->device = g_strdup ("default"); +} + +static void +gst_alsa_mixer_element_set_property (GObject * object, guint prop_id, + const GValue * value, GParamSpec * pspec) +{ + GstAlsaMixerElement *this = GST_ALSA_MIXER_ELEMENT (object); + + switch (prop_id) { + case PROP_DEVICE:{ + GST_OBJECT_LOCK (this); + g_free (this->device); + this->device = g_value_dup_string (value); + GST_OBJECT_UNLOCK (this); + break; + } + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +gst_alsa_mixer_element_get_property (GObject * object, guint prop_id, + GValue * value, GParamSpec * pspec) +{ + GstAlsaMixerElement *this = GST_ALSA_MIXER_ELEMENT (object); + + switch (prop_id) { + case PROP_DEVICE:{ + GST_OBJECT_LOCK (this); + g_value_set_string (value, this->device); + GST_OBJECT_UNLOCK (this); + break; + } + case PROP_DEVICE_NAME:{ + GST_OBJECT_LOCK (this); + if (this->mixer) { + g_value_set_string (value, this->mixer->cardname); + } else { + g_value_set_string (value, NULL); + } + GST_OBJECT_UNLOCK (this); + break; + } + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } } static GstStateChangeReturn gst_alsa_mixer_element_change_state (GstElement * element, GstStateChange transition) { + GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS; GstAlsaMixerElement *this = GST_ALSA_MIXER_ELEMENT (element); switch (transition) { case GST_STATE_CHANGE_NULL_TO_READY: if (!this->mixer) { - this->mixer = gst_alsa_mixer_new ("hw:0", GST_ALSA_MIXER_ALL); + if (!this->device) { + this->mixer = gst_alsa_mixer_new ("default", GST_ALSA_MIXER_ALL); + } else { + this->mixer = gst_alsa_mixer_new (this->device, GST_ALSA_MIXER_ALL); + } } break; + default: + break; + } + + ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition); + if (ret == GST_STATE_CHANGE_FAILURE) + return ret; + + switch (transition) { case GST_STATE_CHANGE_READY_TO_NULL: if (this->mixer) { gst_alsa_mixer_free (this->mixer); @@ -87,8 +231,5 @@ gst_alsa_mixer_element_change_state (GstElement * element, break; } - if (GST_ELEMENT_CLASS (parent_class)->change_state) - return GST_ELEMENT_CLASS (parent_class)->change_state (element, transition); - - return GST_STATE_CHANGE_SUCCESS; + return ret; } diff --git a/ext/alsa/gstalsamixerelement.h b/ext/alsa/gstalsamixerelement.h index e53380092..de9471cb7 100644 --- a/ext/alsa/gstalsamixerelement.h +++ b/ext/alsa/gstalsamixerelement.h @@ -23,6 +23,7 @@ #include "gstalsa.h" #include "gstalsamixer.h" +#include "gstalsadeviceprobe.h" G_BEGIN_DECLS @@ -43,10 +44,13 @@ struct _GstAlsaMixerElement { GstElement parent; GstAlsaMixer *mixer; + gchar *device; }; struct _GstAlsaMixerElementClass { GstElementClass parent; + + GstAlsaDeviceProbeData device_probe_data; }; |