oss4: port to 0.11
authorMark Nauwelaerts <mark.nauwelaerts@collabora.co.uk>
Fri, 20 Apr 2012 16:13:01 +0000 (18:13 +0200)
committerMark Nauwelaerts <mark.nauwelaerts@collabora.co.uk>
Fri, 20 Apr 2012 16:18:54 +0000 (18:18 +0200)
21 files changed:
configure.ac
docs/plugins/Makefile.am
docs/plugins/gst-plugins-good-plugins-docs.sgml
docs/plugins/gst-plugins-good-plugins-sections.txt
sys/oss4/Makefile.am
sys/oss4/oss4-audio.c
sys/oss4/oss4-audio.h
sys/oss4/oss4-mixer-enum.c [deleted file]
sys/oss4/oss4-mixer-enum.h [deleted file]
sys/oss4/oss4-mixer-slider.c [deleted file]
sys/oss4/oss4-mixer-slider.h [deleted file]
sys/oss4/oss4-mixer-switch.c [deleted file]
sys/oss4/oss4-mixer-switch.h [deleted file]
sys/oss4/oss4-mixer.c [deleted file]
sys/oss4/oss4-mixer.h [deleted file]
sys/oss4/oss4-property-probe.c
sys/oss4/oss4-property-probe.h
sys/oss4/oss4-sink.c
sys/oss4/oss4-sink.h
sys/oss4/oss4-source.c
sys/oss4/oss4-source.h

index 1391175..4bb2e27 100644 (file)
@@ -310,7 +310,6 @@ dnl Non ported plugins (non-dependant, then dependant)
 dnl Make sure you have a space before and after all plugins
 GST_PLUGINS_NONPORTED="deinterlace \
  cairo cairo_gobject gdk_pixbuf \
- oss4 \
  osx_video osx_audio "
 AC_SUBST(GST_PLUGINS_NONPORTED)
 
index 7e2b6a5..5c73726 100644 (file)
@@ -191,7 +191,6 @@ EXTRA_HFILES = \
        $(top_srcdir)/gst/wavparse/gstwavparse.h \
        $(top_srcdir)/gst/y4m/gsty4mencode.h \
        $(top_srcdir)/sys/directsound/gstdirectsoundsink.h \
-       $(top_srcdir)/sys/oss4/oss4-mixer.h \
        $(top_srcdir)/sys/oss4/oss4-sink.h \
        $(top_srcdir)/sys/oss4/oss4-source.h \
        $(top_srcdir)/sys/oss/gstosssink.h \
index 7b02a2b..cbedd70 100644 (file)
     <xi:include href="xml/element-multipartmux.xml" />
     <xi:include href="xml/element-multiudpsink.xml" />
     <xi:include href="xml/element-optv.xml" />
-    <xi:include href="xml/element-oss4mixer.xml" />
     <xi:include href="xml/element-oss4sink.xml" />
     <xi:include href="xml/element-oss4src.xml" />
     <xi:include href="xml/element-osssink.xml" />
index a5e7cec..d37038c 100644 (file)
@@ -1397,30 +1397,6 @@ gst_multiudpsink_get_type
 </SECTION>
 
 <SECTION>
-<FILE>element-oss4mixer</FILE>
-<TITLE>oss4mixer</TITLE>
-GstOss4Mixer
-<SUBSECTION Standard>
-GstOss4MixerClass
-GST_OSS4_MIXER
-GST_OSS4_MIXER_CLASS
-GST_IS_OSS4_MIXER
-GST_IS_OSS4_MIXER_CLASS
-GST_TYPE_OSS4_MIXER
-gst_oss4_mixer_get_type
-GST_OSS4_MIXER_CAST
-GST_OSS4_MIXER_IS_OPEN
-MIXEXT_ENUM_IS_AVAILABLE
-MIXEXT_HAS_DESCRIPTION
-MIXEXT_IS_ROOT
-MIXEXT_IS_SLIDER
-gst_oss4_mixer_get_control_val
-gst_oss4_mixer_set_control_val
-gst_oss4_source_input_get_type
-GstOss4MixerControl
-</SECTION>
-
-<SECTION>
 <FILE>element-oss4sink</FILE>
 <TITLE>oss4sink</TITLE>
 GstOss4Sink
index 8f8793c..8e7b466 100644 (file)
@@ -2,10 +2,6 @@ plugin_LTLIBRARIES = libgstoss4audio.la
 
 libgstoss4audio_la_SOURCES = \
        oss4-audio.c          \
-       oss4-mixer.c          \
-       oss4-mixer-enum.c     \
-       oss4-mixer-slider.c   \
-       oss4-mixer-switch.c   \
        oss4-property-probe.c \
        oss4-sink.c           \
        oss4-source.c
@@ -13,7 +9,6 @@ libgstoss4audio_la_SOURCES = \
 libgstoss4audio_la_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_CFLAGS)
 libgstoss4audio_la_LIBADD = \
        $(GST_PLUGINS_BASE_LIBS) \
-        -lgstinterfaces-$(GST_API_VERSION) \
        -lgstaudio-$(GST_API_VERSION) \
        $(GST_LIBS)
 libgstoss4audio_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) 
@@ -21,13 +16,8 @@ libgstoss4audio_la_LIBTOOLFLAGS = --tag=disable-static
 
 noinst_HEADERS = \
        oss4-audio.h          \
-       oss4-mixer.h          \
-       oss4-mixer-enum.h     \
-       oss4-mixer-slider.h   \
-       oss4-mixer-switch.h   \
        oss4-property-probe.h \
        oss4-sink.h           \
        oss4-soundcard.h      \
        oss4-source.h
 
-
index 2661ffe..11f6e5e 100644 (file)
 #include <string.h>
 
 #include "gst/gst-i18n-plugin.h"
-#include <gst/audio/multichannel.h>
+#include <gst/audio/audio.h>
 
 #include "oss4-audio.h"
-#include "oss4-mixer.h"
 #include "oss4-property-probe.h"
 #include "oss4-sink.h"
 #include "oss4-source.h"
@@ -51,33 +50,42 @@ GST_DEBUG_CATEGORY (oss4_debug);
 
 typedef struct
 {
-  const GstBufferFormat gst_fmt;
+  const GstAudioRingBufferFormatType gst_rbfmt;
+  const GstAudioFormat gst_rfmt;
   const gint oss_fmt;
   const gchar name[16];
-  const gint depth;
-  const gint width;
-  const gint endianness;
-  const gboolean signedness;
 } GstOss4AudioFormat;
 
 /* *INDENT-OFF* */
 static const GstOss4AudioFormat fmt_map[] = {
   /* note: keep sorted by preference, prefered formats first */
   {
-  GST_MU_LAW, AFMT_MU_LAW, "audio/x-mulaw", 0, 0, 0, FALSE}, {
-  GST_A_LAW, AFMT_A_LAW, "audio/x-alaw", 0, 0, 0, FALSE}, {
-  GST_S32_LE, AFMT_S32_LE, "audio/x-raw-int", 32, 32, G_LITTLE_ENDIAN, TRUE}, {
-  GST_S32_BE, AFMT_S32_BE, "audio/x-raw-int", 32, 32, G_BIG_ENDIAN, TRUE}, {
-  GST_S24_LE, AFMT_S24_LE, "audio/x-raw-int", 24, 32, G_LITTLE_ENDIAN, TRUE}, {
-  GST_S24_BE, AFMT_S24_BE, "audio/x-raw-int", 24, 32, G_BIG_ENDIAN, TRUE}, {
-  GST_S24_3LE, AFMT_S24_PACKED, "audio/x-raw-int", 24, 24, G_LITTLE_ENDIAN,
-        TRUE}, {
-  GST_S16_LE, AFMT_S16_LE, "audio/x-raw-int", 16, 16, G_LITTLE_ENDIAN, TRUE}, {
-  GST_S16_BE, AFMT_S16_BE, "audio/x-raw-int", 16, 16, G_BIG_ENDIAN, TRUE}, {
-  GST_U16_LE, AFMT_U16_LE, "audio/x-raw-int", 16, 16, G_LITTLE_ENDIAN, FALSE}, {
-  GST_U16_BE, AFMT_U16_BE, "audio/x-raw-int", 16, 16, G_BIG_ENDIAN, FALSE}, {
-  GST_S8, AFMT_S8, "audio/x-raw-int", 8, 8, 0, TRUE}, {
-  GST_U8, AFMT_U8, "audio/x-raw-int", 8, 8, 0, FALSE}
+  GST_AUDIO_RING_BUFFER_FORMAT_TYPE_MU_LAW, 0,
+      AFMT_MU_LAW, "audio/x-mulaw"}, {
+  GST_AUDIO_RING_BUFFER_FORMAT_TYPE_A_LAW, 0,
+      AFMT_A_LAW, "audio/x-alaw"}, {
+  GST_AUDIO_RING_BUFFER_FORMAT_TYPE_RAW, GST_AUDIO_FORMAT_S32LE,
+      AFMT_S32_LE, "audio/x-raw"}, {
+  GST_AUDIO_RING_BUFFER_FORMAT_TYPE_RAW, GST_AUDIO_FORMAT_S32BE,
+      AFMT_S32_BE, "audio/x-raw"}, {
+  GST_AUDIO_RING_BUFFER_FORMAT_TYPE_RAW, GST_AUDIO_FORMAT_S24_32LE,
+      AFMT_S24_LE, "audio/x-raw"}, {
+  GST_AUDIO_RING_BUFFER_FORMAT_TYPE_RAW, GST_AUDIO_FORMAT_S24_32BE,
+      AFMT_S24_BE, "audio/x-raw"}, {
+  GST_AUDIO_RING_BUFFER_FORMAT_TYPE_RAW, GST_AUDIO_FORMAT_S24LE,
+      AFMT_S24_PACKED, "audio/x-raw"}, {
+  GST_AUDIO_RING_BUFFER_FORMAT_TYPE_RAW, GST_AUDIO_FORMAT_S16LE,
+      AFMT_S16_LE, "audio/x-raw"}, {
+  GST_AUDIO_RING_BUFFER_FORMAT_TYPE_RAW, GST_AUDIO_FORMAT_S16BE,
+      AFMT_S16_BE, "audio/x-raw"}, {
+  GST_AUDIO_RING_BUFFER_FORMAT_TYPE_RAW, GST_AUDIO_FORMAT_U16LE,
+      AFMT_U16_LE, "audio/x-raw"}, {
+  GST_AUDIO_RING_BUFFER_FORMAT_TYPE_RAW, GST_AUDIO_FORMAT_U16BE,
+      AFMT_U16_BE, "audio/x-raw"}, {
+  GST_AUDIO_RING_BUFFER_FORMAT_TYPE_RAW, GST_AUDIO_FORMAT_S8,
+      AFMT_S8, "audio/x-raw"}, {
+  GST_AUDIO_RING_BUFFER_FORMAT_TYPE_RAW, GST_AUDIO_FORMAT_U8,
+      AFMT_U8, "audio/x-raw"}
 };
 /* *INDENT-ON* */
 
@@ -96,24 +104,23 @@ gst_oss4_append_format_to_caps (const GstOss4AudioFormat * fmt, GstCaps * caps)
 {
   GstStructure *s;
 
-  s = gst_structure_empty_new (fmt->name);
-  if (fmt->width != 0 && fmt->depth != 0) {
-    gst_structure_set (s, "width", G_TYPE_INT, fmt->width, "depth", G_TYPE_INT,
-        fmt->depth, "signed", G_TYPE_BOOLEAN, fmt->signedness, NULL);
-  }
-  if (fmt->endianness != 0) {
-    gst_structure_set (s, "endianness", G_TYPE_INT, fmt->endianness, NULL);
+  s = gst_structure_new_empty (fmt->name);
+  if (fmt->gst_rbfmt == GST_AUDIO_RING_BUFFER_FORMAT_TYPE_RAW) {
+    gst_structure_set (s, "format", G_TYPE_STRING,
+        gst_audio_format_to_string (fmt->gst_rfmt),
+        "layout", G_TYPE_STRING, "interleaved", NULL);
   }
   gst_caps_append_structure (caps, s);
 }
 
 static gint
-gst_oss4_audio_get_oss_format (GstBufferFormat fmt)
+gst_oss4_audio_get_oss_format (GstAudioRingBufferFormatType fmt,
+    GstAudioFormat rfmt)
 {
   guint i;
 
   for (i = 0; i < G_N_ELEMENTS (fmt_map); ++i) {
-    if (fmt_map[i].gst_fmt == fmt)
+    if (fmt_map[i].gst_rbfmt == fmt && fmt_map[i].gst_rfmt == rfmt)
       return fmt_map[i].oss_fmt;
   }
   return 0;
@@ -200,15 +207,15 @@ gst_oss4_audio_detect_rates (GstObject * obj, oss_audioinfo * ai,
 }
 
 static void
-gst_oss4_audio_add_channel_layout (GstObject * obj, guint64 layout,
-    guint num_channels, GstStructure * s)
+gst_oss4_audio_get_channel_layout (GstObject * obj, guint64 layout,
+    guint num_channels, GstAudioChannelPosition * ch_layout)
 {
   const GstAudioChannelPosition pos_map[16] = {
     GST_AUDIO_CHANNEL_POSITION_NONE,    /* 0 = dunno          */
     GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,      /* 1 = left           */
     GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,     /* 2 = right          */
     GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER,    /* 3 = center         */
-    GST_AUDIO_CHANNEL_POSITION_LFE    /* 4 = lfe            */
+    GST_AUDIO_CHANNEL_POSITION_LFE1,    /* 4 = lfe            */
     GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT,       /* 5 = left surround  */
     GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT,      /* 6 = right surround */
     GST_AUDIO_CHANNEL_POSITION_REAR_LEFT,       /* 7 = left rear      */
@@ -221,12 +228,9 @@ gst_oss4_audio_add_channel_layout (GstObject * obj, guint64 layout,
     GST_AUDIO_CHANNEL_POSITION_NONE,
     GST_AUDIO_CHANNEL_POSITION_NONE
   };
-  GstAudioChannelPosition ch_layout[8] = { 0, };
   guint speaker_pos;            /* speaker position as defined by OSS */
   guint i;
 
-  g_return_if_fail (num_channels <= G_N_ELEMENTS (ch_layout));
-
   for (i = 0; i < num_channels; ++i) {
     /* layout contains up to 16 speaker positions, with each taking up 4 bits */
     speaker_pos = (guint) ((layout >> (i * 4)) & 0x0f);
@@ -238,7 +242,7 @@ gst_oss4_audio_add_channel_layout (GstObject * obj, guint64 layout,
 
     ch_layout[i] = pos_map[speaker_pos];
   }
-  gst_audio_set_channel_positions (s, ch_layout);
+
   return;
 
 no_layout:
@@ -253,11 +257,64 @@ no_layout:
     for (i = 0; i < num_channels; ++i) {
       ch_layout[i] = GST_AUDIO_CHANNEL_POSITION_NONE;
     }
-    gst_audio_set_channel_positions (s, ch_layout);
     return;
   }
 }
 
+static void
+gst_oss4_audio_set_ringbuffer_channel_layout (GstObject * obj, gint fd,
+    GstAudioRingBufferSpec * spec)
+{
+  guint num_channels;
+  guint64 layout = 0;
+  GstAudioRingBuffer *rb;
+  GstAudioChannelPosition ch_layout[8] = { 0, };
+
+  num_channels = GST_AUDIO_INFO_CHANNELS (&spec->info);
+  if (num_channels < 3 || num_channels > 9)
+    return;
+
+  if (spec->type != GST_AUDIO_RING_BUFFER_FORMAT_TYPE_RAW)
+    return;
+
+  if (GST_IS_OSS4_SINK (obj)) {
+    rb = GST_AUDIO_BASE_SINK (obj)->ringbuffer;
+  } else if (GST_IS_OSS4_SOURCE (obj)) {
+    rb = GST_AUDIO_BASE_SRC (obj)->ringbuffer;
+  } else
+    g_assert_not_reached ();
+
+  /* -1 = get info for currently open device (fd). This will fail with
+   * OSS build <= 1013 because of a bug in OSS */
+  if (ioctl (fd, SNDCTL_DSP_GET_CHNORDER, &layout) == -1) {
+    GST_WARNING_OBJECT (obj, "couldn't query channel layout, assuming default");
+    layout = CHNORDER_NORMAL;
+  }
+  GST_DEBUG_OBJECT (obj, "channel layout: %08" G_GINT64_MODIFIER "x", layout);
+
+
+  gst_oss4_audio_get_channel_layout (obj, layout, num_channels, ch_layout);
+  gst_audio_ring_buffer_set_channel_positions (rb, ch_layout);
+
+  return;
+}
+
+static void
+gst_oss4_audio_add_channel_layout (GstObject * obj, guint64 layout,
+    guint num_channels, GstStructure * s)
+{
+  GstAudioChannelPosition ch_layout[8] = { 0, };
+  guint64 mask;
+
+  g_return_if_fail (num_channels <= G_N_ELEMENTS (ch_layout));
+
+  gst_oss4_audio_get_channel_layout (obj, layout, num_channels, ch_layout);
+  if (gst_audio_channel_positions_to_mask (ch_layout, num_channels, &mask))
+    gst_structure_set (s, "channel-mask", GST_TYPE_BITMASK, mask, NULL);
+
+  return;
+}
+
 /* arbitrary max. limit */
 #define GST_OSS4_MIN_CHANNELS 1
 #define GST_OSS4_MAX_CHANNELS 4096
@@ -403,8 +460,8 @@ done:
       chan_s = gst_caps_get_structure (chan_caps, j);
       if ((val = gst_structure_get_value (chan_s, "channels")))
         gst_structure_set_value (s, "channels", val);
-      if ((val = gst_structure_get_value (chan_s, "channel-positions")))
-        gst_structure_set_value (s, "channel-positions", val);
+      if ((val = gst_structure_get_value (chan_s, "channel-mask")))
+        gst_structure_set_value (s, "channel-mask", val);
 
       gst_caps_append_structure (out_caps, s);
       s = NULL;
@@ -458,7 +515,7 @@ gst_oss4_audio_probe_caps (GstObject * obj, int fd)
     }
   }
 
-  caps = gst_caps_do_simplify (caps);
+  caps = gst_caps_simplify (caps);
   GST_LOG_OBJECT (obj, "formats: %" GST_PTR_FORMAT, caps);
 
   if (!gst_oss4_audio_detect_rates (obj, &ai, caps))
@@ -505,7 +562,7 @@ gst_oss4_audio_get_template_caps (void)
     gst_oss4_append_format_to_caps (&fmt_map[i], caps);
   }
 
-  caps = gst_caps_do_simplify (caps);
+  caps = gst_caps_simplify (caps);
 
   for (i = 0; i < gst_caps_get_size (caps); ++i) {
     GstStructure *s;
@@ -521,17 +578,25 @@ gst_oss4_audio_get_template_caps (void)
 
 /* called by gst_oss4_sink_prepare() and gst_oss4_source_prepare() */
 gboolean
-gst_oss4_audio_set_format (GstObject * obj, int fd, GstRingBufferSpec * spec)
+gst_oss4_audio_set_format (GstObject * obj, int fd,
+    GstAudioRingBufferSpec * spec)
 {
   struct audio_buf_info info = { 0, };
-  int fmt, chans, rate;
+  int ofmt, fmt, chans, rate, width;
+
+  fmt = gst_oss4_audio_get_oss_format (spec->type,
+      GST_AUDIO_INFO_FORMAT (&spec->info));
 
-  fmt = gst_oss4_audio_get_oss_format (spec->format);
   if (fmt == 0)
     goto wrong_format;
 
-  if (spec->type == GST_BUFTYPE_LINEAR && spec->width != 32 &&
-      spec->width != 24 && spec->width != 16 && spec->width != 8) {
+  ofmt = fmt;
+  chans = GST_AUDIO_INFO_CHANNELS (&spec->info);
+  rate = GST_AUDIO_INFO_RATE (&spec->info);
+  width = GST_AUDIO_INFO_WIDTH (&spec->info);
+
+  if (spec->type == GST_AUDIO_RING_BUFFER_FORMAT_TYPE_RAW &&
+      width != 32 && width != 24 && width != 16 && width != 8) {
     goto dodgy_width;
   }
 
@@ -541,14 +606,12 @@ gst_oss4_audio_set_format (GstObject * obj, int fd, GstRingBufferSpec * spec)
     goto set_format_failed;
 
   /* channels */
-  GST_LOG_OBJECT (obj, "setting channels: %d", spec->channels);
-  chans = spec->channels;
+  GST_LOG_OBJECT (obj, "setting channels: %d", chans);
   if (ioctl (fd, SNDCTL_DSP_CHANNELS, &chans) == -1)
     goto set_channels_failed;
 
   /* rate */
-  GST_LOG_OBJECT (obj, "setting rate: %d", spec->rate);
-  rate = spec->rate;
+  GST_LOG_OBJECT (obj, "setting rate: %d", rate);
   if (ioctl (fd, SNDCTL_DSP_SPEED, &rate) == -1)
     goto set_rate_failed;
 
@@ -557,8 +620,8 @@ gst_oss4_audio_set_format (GstObject * obj, int fd, GstRingBufferSpec * spec)
   GST_DEBUG_OBJECT (obj, "effective rate     : %d", rate);
 
   /* make sure format, channels, and rate are the ones we requested */
-  if (fmt != gst_oss4_audio_get_oss_format (spec->format) ||
-      chans != spec->channels || rate != spec->rate) {
+  if (fmt != ofmt || chans != GST_AUDIO_INFO_CHANNELS (&spec->info) ||
+      rate != GST_AUDIO_INFO_RATE (&spec->info)) {
     /* This shouldn't happen, but hey */
     goto format_not_what_was_requested;
   }
@@ -579,24 +642,25 @@ gst_oss4_audio_set_format (GstObject * obj, int fd, GstRingBufferSpec * spec)
    * being too large, and the buffer will wrap.  */
   spec->segtotal = info.fragstotal + 4;
 
-  spec->bytes_per_sample = (spec->width / 8) * spec->channels;
-
   GST_DEBUG_OBJECT (obj, "got segsize: %d, segtotal: %d, value: %08x",
       spec->segsize, spec->segtotal, info.fragsize);
 
+  gst_oss4_audio_set_ringbuffer_channel_layout (obj, fd, spec);
+
   return TRUE;
 
 /* ERRORS */
 wrong_format:
   {
     GST_ELEMENT_ERROR (obj, RESOURCE, SETTINGS, (NULL),
-        ("Unable to get format %d", spec->format));
+        ("Unable to get format (%d, %d)", spec->type,
+            GST_AUDIO_INFO_FORMAT (&spec->info)));
     return FALSE;
   }
 dodgy_width:
   {
     GST_ELEMENT_ERROR (obj, RESOURCE, SETTINGS, (NULL),
-        ("unexpected width %d", spec->width));
+        ("unexpected width %d", width));
     return FALSE;
   }
 set_format_failed:
@@ -664,8 +728,7 @@ gst_oss4_audio_find_device (GstObject * oss)
   GValueArray *arr;
   gchar *ret = NULL;
 
-  arr = gst_property_probe_probe_and_get_values_name (GST_PROPERTY_PROBE (oss),
-      "device");
+  arr = gst_oss4_property_probe_get_values (GST_OBJECT (oss), "device");
 
   if (arr != NULL) {
     if (arr->n_values > 0) {
@@ -703,8 +766,7 @@ plugin_init (GstPlugin * plugin)
   rank = GST_RANK_SECONDARY + 1;
 
   if (!gst_element_register (plugin, "oss4sink", rank, GST_TYPE_OSS4_SINK) ||
-      !gst_element_register (plugin, "oss4src", rank, GST_TYPE_OSS4_SOURCE) ||
-      !gst_element_register (plugin, "oss4mixer", rank, GST_TYPE_OSS4_MIXER)) {
+      !gst_element_register (plugin, "oss4src", rank, GST_TYPE_OSS4_SOURCE)) {
     return FALSE;
   }
 
index d220364..fcfbb8e 100644 (file)
@@ -21,7 +21,7 @@
 #define GST_OSS4_AUDIO_H_
 
 #include <gst/gst.h>
-#include <gst/audio/gstringbuffer.h>
+#include <gst/audio/gstaudioringbuffer.h>
 
 /* This is the minimum version we require */
 #define GST_MIN_OSS4_VERSION  0x040003
@@ -32,7 +32,7 @@ gboolean  gst_oss4_audio_check_version (GstObject * obj, int fd);
 
 GstCaps * gst_oss4_audio_probe_caps  (GstObject * obj, int fd);
 
-gboolean  gst_oss4_audio_set_format  (GstObject * obj, int fd, GstRingBufferSpec * spec);
+gboolean  gst_oss4_audio_set_format  (GstObject * obj, int fd, GstAudioRingBufferSpec * spec);
 
 GstCaps * gst_oss4_audio_get_template_caps (void);
 
diff --git a/sys/oss4/oss4-mixer-enum.c b/sys/oss4/oss4-mixer-enum.c
deleted file mode 100644 (file)
index 4b64bb1..0000000
+++ /dev/null
@@ -1,269 +0,0 @@
-/* GStreamer OSS4 mixer enumeration control
- * Copyright (C) 2007-2008 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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-/* An 'enum' in gnome-volume-control / GstMixer is represented by a
- * GstMixerOptions object
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <gst/gst-i18n-plugin.h>
-
-#define NO_LEGACY_MIXER
-#include "oss4-mixer.h"
-#include "oss4-mixer-enum.h"
-#include "oss4-soundcard.h"
-
-GST_DEBUG_CATEGORY_EXTERN (oss4mixer_debug);
-#define GST_CAT_DEFAULT oss4mixer_debug
-
-static GList *gst_oss4_mixer_enum_get_values (GstMixerOptions * options);
-
-/* GstMixerTrack is a plain GObject, so let's just use the GLib macro here */
-G_DEFINE_TYPE (GstOss4MixerEnum, gst_oss4_mixer_enum, GST_TYPE_MIXER_OPTIONS);
-
-static void
-gst_oss4_mixer_enum_init (GstOss4MixerEnum * e)
-{
-  e->need_update = TRUE;
-}
-
-static void
-gst_oss4_mixer_enum_dispose (GObject * obj)
-{
-  GstMixerOptions *options = GST_MIXER_OPTIONS (obj);
-
-  /* our list is a flat list with constant strings, but the GstMixerOptions
-   * dispose will try to g_free the contained strings, so clean up the list
-   * before chaining up to GstMixerOptions */
-  g_list_free (options->values);
-  options->values = NULL;
-
-  G_OBJECT_CLASS (gst_oss4_mixer_enum_parent_class)->dispose (obj);
-}
-
-static void
-gst_oss4_mixer_enum_class_init (GstOss4MixerEnumClass * klass)
-{
-  GObjectClass *gobject_class = (GObjectClass *) klass;
-  GstMixerOptionsClass *mixeroptions_class = (GstMixerOptionsClass *) klass;
-
-  gobject_class->dispose = gst_oss4_mixer_enum_dispose;
-  mixeroptions_class->get_values = gst_oss4_mixer_enum_get_values;
-}
-
-static GList *
-gst_oss4_mixer_enum_get_values_locked (GstMixerOptions * options)
-{
-  GstOss4MixerEnum *e = GST_OSS4_MIXER_ENUM_CAST (options);
-  GList *oldlist, *list = NULL;
-  int i;
-
-  /* if current list of values is empty, update/re-check in any case */
-  if (!e->need_update && options->values != NULL)
-    return options->values;
-
-  GST_LOG_OBJECT (e, "updating available values for %s", e->mc->mixext.extname);
-
-  for (i = 0; i < e->mc->mixext.maxvalue; ++i) {
-    const gchar *s;
-
-    s = g_quark_to_string (e->mc->enum_vals[i]);
-    if (MIXEXT_ENUM_IS_AVAILABLE (e->mc->mixext, i)) {
-      GST_LOG_OBJECT (e, "option '%s' is available", s);
-      list = g_list_prepend (list, (gpointer) s);
-    } else {
-      GST_LOG_OBJECT (e, "option '%s' is currently not available", s);
-    }
-  }
-
-  list = g_list_reverse (list);
-
-  /* this is not thread-safe, but then the entire GstMixer API isn't really,
-   * since we return foo->list and not a copy and don't take any locks, so
-   * not much we can do here but pray; we're usually either called from _new()
-   * or from within _get_values() though, so it should be okay. We could use
-   * atomic ops here, but I'm not sure how much more that really buys us.*/
-  oldlist = options->values;    /* keep window small */
-  options->values = list;
-  g_list_free (oldlist);
-
-  e->need_update = FALSE;
-
-  return options->values;
-}
-
-static GList *
-gst_oss4_mixer_enum_get_values (GstMixerOptions * options)
-{
-  GstOss4MixerEnum *e = GST_OSS4_MIXER_ENUM (options);
-  GList *list;
-
-  /* we take the lock here mostly to serialise ioctls with the watch thread */
-  GST_OBJECT_LOCK (e->mixer);
-
-  list = gst_oss4_mixer_enum_get_values_locked (options);
-
-  GST_OBJECT_UNLOCK (e->mixer);
-
-  return list;
-}
-
-static const gchar *
-gst_oss4_mixer_enum_get_current_value (GstOss4MixerEnum * e)
-{
-  const gchar *cur_val = NULL;
-
-  if (e->mc->enum_vals != NULL && e->mc->last_val < e->mc->mixext.maxvalue) {
-    cur_val = g_quark_to_string (e->mc->enum_vals[e->mc->last_val]);
-  }
-
-  return cur_val;
-}
-
-static gboolean
-gst_oss4_mixer_enum_update_current (GstOss4MixerEnum * e)
-{
-  int cur = -1;
-
-  if (!gst_oss4_mixer_get_control_val (e->mixer, e->mc, &cur))
-    return FALSE;
-
-  if (cur < 0 || cur >= e->mc->mixext.maxvalue) {
-    GST_WARNING_OBJECT (e, "read value %d out of bounds [0-%d]", cur,
-        e->mc->mixext.maxvalue - 1);
-    e->mc->last_val = 0;
-    return FALSE;
-  }
-
-  return TRUE;
-}
-
-gboolean
-gst_oss4_mixer_enum_set_option (GstOss4MixerEnum * e, const gchar * value)
-{
-  GQuark q;
-  int i;
-
-  q = g_quark_try_string (value);
-  if (q == 0) {
-    GST_WARNING_OBJECT (e, "unknown option '%s'", value);
-    return FALSE;
-  }
-
-  for (i = 0; i < e->mc->mixext.maxvalue; ++i) {
-    if (q == e->mc->enum_vals[i])
-      break;
-  }
-
-  if (i >= e->mc->mixext.maxvalue) {
-    GST_WARNING_OBJECT (e, "option '%s' is not valid for this control", value);
-    return FALSE;
-  }
-
-  GST_LOG_OBJECT (e, "option '%s' = %d", value, i);
-
-  if (!MIXEXT_ENUM_IS_AVAILABLE (e->mc->mixext, i)) {
-    GST_WARNING_OBJECT (e, "option '%s' is not selectable currently", value);
-    return FALSE;
-  }
-
-  if (!gst_oss4_mixer_set_control_val (e->mixer, e->mc, i)) {
-    GST_WARNING_OBJECT (e, "could not set option '%s' (%d)", value, i);
-    return FALSE;
-  }
-
-  /* and re-read current value with sanity checks (or could just assign here) */
-  gst_oss4_mixer_enum_update_current (e);
-
-  return TRUE;
-}
-
-const gchar *
-gst_oss4_mixer_enum_get_option (GstOss4MixerEnum * e)
-{
-  const gchar *cur_str = NULL;
-
-  if (!gst_oss4_mixer_enum_update_current (e)) {
-    GST_WARNING_OBJECT (e, "failed to read current value");
-    return NULL;
-  }
-
-  cur_str = gst_oss4_mixer_enum_get_current_value (e);
-  GST_LOG_OBJECT (e, "%s (%d)", GST_STR_NULL (cur_str), e->mc->last_val);
-  return cur_str;
-}
-
-GstMixerTrack *
-gst_oss4_mixer_enum_new (GstOss4Mixer * mixer, GstOss4MixerControl * mc)
-{
-  GstOss4MixerEnum *e;
-  GstMixerTrack *track;
-
-  e = g_object_new (GST_TYPE_OSS4_MIXER_ENUM, "untranslated-label",
-      mc->mixext.extname, NULL);
-  e->mixer = mixer;
-  e->mc = mc;
-
-  track = GST_MIXER_TRACK (e);
-
-  /* caller will set track->label and track->flags */
-
-  track->num_channels = 0;
-  track->min_volume = 0;
-  track->max_volume = 0;
-
-  (void) gst_oss4_mixer_enum_get_values_locked (GST_MIXER_OPTIONS (track));
-
-  if (!gst_oss4_mixer_enum_update_current (e)) {
-    GST_WARNING_OBJECT (track, "failed to read current value, returning NULL");
-    g_object_unref (track);
-    track = NULL;
-  }
-
-  GST_LOG_OBJECT (e, "current value: %d (%s)", e->mc->last_val,
-      gst_oss4_mixer_enum_get_current_value (e));
-
-  return track;
-}
-
-/* This is called from the watch thread */
-void
-gst_oss4_mixer_enum_process_change_unlocked (GstMixerTrack * track)
-{
-  GstOss4MixerEnum *e = GST_OSS4_MIXER_ENUM_CAST (track);
-
-  gchar *cur;
-
-  if (!e->mc->changed && !e->mc->list_changed)
-    return;
-
-  if (e->mc->list_changed) {
-    gst_mixer_options_list_changed (GST_MIXER (e->mixer),
-        GST_MIXER_OPTIONS (e));
-  }
-
-  GST_OBJECT_LOCK (e->mixer);
-  cur = (gchar *) gst_oss4_mixer_enum_get_current_value (e);
-  GST_OBJECT_UNLOCK (e->mixer);
-
-  gst_mixer_option_changed (GST_MIXER (e->mixer), GST_MIXER_OPTIONS (e), cur);
-}
diff --git a/sys/oss4/oss4-mixer-enum.h b/sys/oss4/oss4-mixer-enum.h
deleted file mode 100644 (file)
index 9fd8166..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-/* GStreamer OSS4 mixer on/off enum control
- * Copyright (C) 2007-2008 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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifndef GST_OSS4_MIXER_ENUM_H
-#define GST_OSS4_MIXER_ENUM_H
-
-#include <gst/gst.h>
-#include <gst/interfaces/mixer.h>
-
-#include "oss4-mixer.h"
-
-G_BEGIN_DECLS
-
-#define GST_TYPE_OSS4_MIXER_ENUM            (gst_oss4_mixer_enum_get_type())
-#define GST_OSS4_MIXER_ENUM(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_OSS4_MIXER_ENUM,GstOss4MixerEnum))
-#define GST_OSS4_MIXER_ENUM_CAST(obj)       ((GstOss4MixerEnum *)(obj))
-#define GST_OSS4_MIXER_ENUM_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_OSS4_MIXER_ENUM,GstOss4MixerEnumClass))
-#define GST_IS_OSS4_MIXER_ENUM(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_OSS4_MIXER_ENUM))
-#define GST_IS_OSS4_MIXER_ENUM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_OSS4_MIXER_ENUM))
-
-typedef struct _GstOss4MixerEnum GstOss4MixerEnum;
-typedef struct _GstOss4MixerEnumClass GstOss4MixerEnumClass;
-
-struct _GstOss4MixerEnum {
-  GstMixerOptions  mixer_option;
-
-  GstOss4MixerControl  * mc;
-  GstOss4Mixer         * mixer;      /* the mixer we belong to (no ref taken) */
-
-  gboolean               need_update;
-};
-
-struct _GstOss4MixerEnumClass {
-  GstMixerOptionsClass mixer_option_class;
-};
-
-GType           gst_oss4_mixer_enum_get_type (void);
-
-gboolean        gst_oss4_mixer_enum_set_option (GstOss4MixerEnum * e, const gchar * value);
-
-const gchar   * gst_oss4_mixer_enum_get_option (GstOss4MixerEnum * e);
-
-GstMixerTrack * gst_oss4_mixer_enum_new (GstOss4Mixer * mixer, GstOss4MixerControl * mc);
-
-void            gst_oss4_mixer_enum_process_change_unlocked (GstMixerTrack * track);
-
-G_END_DECLS
-
-#endif /* GST_OSS4_MIXER_ENUM_H */
-
-
diff --git a/sys/oss4/oss4-mixer-slider.c b/sys/oss4/oss4-mixer-slider.c
deleted file mode 100644 (file)
index e71d134..0000000
+++ /dev/null
@@ -1,311 +0,0 @@
-/* GStreamer OSS4 mixer slider control
- * Copyright (C) 2007-2008 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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-/* A 'slider' in gnome-volume-control / GstMixer is represented by a
- * GstMixerTrack with one or more channels.
- *
- * A slider should be either flagged as INPUT or OUTPUT (mostly because of
- * gnome-volume-control being littered with g_asserts for everything it doesn't
- * expect).
- *
- * From mixertrack.h:
- * "Input tracks can have 'recording' enabled, which means that any input will
- * be hearable into the speakers that are attached to the output. Mute is
- * obvious."
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <string.h>
-#include <errno.h>
-#include <sys/ioctl.h>
-
-#include <gst/gst-i18n-plugin.h>
-
-#define NO_LEGACY_MIXER
-#include "oss4-mixer-slider.h"
-
-GST_DEBUG_CATEGORY_EXTERN (oss4mixer_debug);
-#define GST_CAT_DEFAULT oss4mixer_debug
-
-/* GstMixerTrack is a plain GObject, so let's just use the GLib macro here */
-G_DEFINE_TYPE (GstOss4MixerSlider, gst_oss4_mixer_slider, GST_TYPE_MIXER_TRACK);
-
-static void
-gst_oss4_mixer_slider_class_init (GstOss4MixerSliderClass * klass)
-{
-  /* nothing to do here */
-}
-
-static void
-gst_oss4_mixer_slider_init (GstOss4MixerSlider * s)
-{
-  /* nothing to do here */
-}
-
-static int
-gst_oss4_mixer_slider_pack_volume (GstOss4MixerSlider * s, const gint * volumes)
-{
-  int val = 0;
-
-  switch (s->mc->mixext.type) {
-    case MIXT_MONOSLIDER:
-    case MIXT_MONOSLIDER16:
-    case MIXT_SLIDER:
-      val = volumes[0];
-      break;
-    case MIXT_STEREOSLIDER:
-      val = ((volumes[1] & 0xff) << 8) | (volumes[0] & 0xff);
-      break;
-    case MIXT_STEREOSLIDER16:
-      val = ((volumes[1] & 0xffff) << 16) | (volumes[0] & 0xffff);
-      break;
-    default:
-      g_return_val_if_reached (0);
-  }
-  return val;
-}
-
-static void
-gst_oss4_mixer_slider_unpack_volume (GstOss4MixerSlider * s, int v,
-    gint * volumes)
-{
-  guint32 val;                  /* use uint so bitshifting the highest bit works right */
-
-  val = (guint32) v;
-  switch (s->mc->mixext.type) {
-    case MIXT_SLIDER:
-      volumes[0] = val;
-      break;
-    case MIXT_MONOSLIDER:
-      /* oss repeats the value in the upper bits, as if it was stereo */
-      volumes[0] = val & 0x00ff;
-      break;
-    case MIXT_MONOSLIDER16:
-      /* oss repeats the value in the upper bits, as if it was stereo */
-      volumes[0] = val & 0x0000ffff;
-      break;
-    case MIXT_STEREOSLIDER:
-      volumes[0] = (val & 0x00ff);
-      volumes[1] = (val & 0xff00) >> 8;
-      break;
-    case MIXT_STEREOSLIDER16:
-      volumes[0] = (val & 0x0000ffff);
-      volumes[1] = (val & 0xffff0000) >> 16;
-      break;
-    default:
-      g_return_if_reached ();
-  }
-}
-
-gboolean
-gst_oss4_mixer_slider_get_volume (GstOss4MixerSlider * s, gint * volumes)
-{
-  GstMixerTrack *track = GST_MIXER_TRACK (s);
-  int v = 0;
-
-  /* if we're supposed to be muted, and don't have an actual mute control
-   * (ie. 'simulate' the mute), then just return the volume as saved, not
-   * the actually set volume which is most likely 0 */
-  if (GST_MIXER_TRACK_HAS_FLAG (track, GST_MIXER_TRACK_MUTE) && !s->mc->mute) {
-    volumes[0] = s->volumes[0];
-    if (track->num_channels == 2)
-      volumes[1] = s->volumes[1];
-    return TRUE;
-  }
-
-  if (!gst_oss4_mixer_get_control_val (s->mixer, s->mc, &v))
-    return FALSE;
-
-  gst_oss4_mixer_slider_unpack_volume (s, v, volumes);
-
-  if (track->num_channels > 1) {
-    GST_LOG_OBJECT (s, "volume: left=%d, right=%d", volumes[0], volumes[1]);
-  } else {
-    GST_LOG_OBJECT (s, "volume: mono=%d", volumes[0]);
-  }
-
-  return TRUE;
-}
-
-gboolean
-gst_oss4_mixer_slider_set_volume (GstOss4MixerSlider * s, const gint * volumes)
-{
-  GstMixerTrack *track = GST_MIXER_TRACK (s);
-  int val = 0;
-
-  /* if we're supposed to be muted, and are 'simulating' the mute because
-   * we don't have a mute control, don't actually change the volume, just
-   * save it as the new desired volume for later when we get unmuted again */
-  if (!GST_MIXER_TRACK_HAS_FLAG (track, GST_MIXER_TRACK_NO_MUTE)) {
-    if (GST_MIXER_TRACK_HAS_FLAG (track, GST_MIXER_TRACK_MUTE) && !s->mc->mute)
-      goto done;
-  }
-
-  val = gst_oss4_mixer_slider_pack_volume (s, volumes);
-
-  if (track->num_channels > 1) {
-    GST_LOG_OBJECT (s, "left=%d, right=%d", volumes[0], volumes[1]);
-  } else {
-    GST_LOG_OBJECT (s, "mono=%d", volumes[0]);
-  }
-
-  if (!gst_oss4_mixer_set_control_val (s->mixer, s->mc, val))
-    return FALSE;
-
-done:
-
-  s->volumes[0] = volumes[0];
-  if (track->num_channels == 2)
-    s->volumes[1] = volumes[1];
-
-  return TRUE;
-}
-
-gboolean
-gst_oss4_mixer_slider_set_record (GstOss4MixerSlider * s, gboolean record)
-{
-  /* There doesn't seem to be a way to do this using the OSS4 mixer API, so
-   * just do nothing here for now. */
-  return FALSE;
-}
-
-gboolean
-gst_oss4_mixer_slider_set_mute (GstOss4MixerSlider * s, gboolean mute)
-{
-  GstMixerTrack *track = GST_MIXER_TRACK (s);
-  gboolean ret;
-
-  /* if the control does not support muting, then do not do anything */
-  if (GST_MIXER_TRACK_HAS_FLAG (track, GST_MIXER_TRACK_NO_MUTE)) {
-    return TRUE;
-  }
-
-  /* If we do not have a mute control, simulate mute (which is a bit broken,
-   * since we can not differentiate between capture/playback volume etc., so
-   * we just assume that setting the volume to 0 would be the same as muting
-   * this control) */
-  if (s->mc->mute == NULL) {
-    int volume;
-
-    if (mute) {
-      /* make sure the current volume values get saved. */
-      gst_oss4_mixer_slider_get_volume (s, s->volumes);
-      volume = 0;
-    } else {
-      volume = gst_oss4_mixer_slider_pack_volume (s, s->volumes);
-    }
-    ret = gst_oss4_mixer_set_control_val (s->mixer, s->mc, volume);
-  } else {
-    ret = gst_oss4_mixer_set_control_val (s->mixer, s->mc->mute, !!mute);
-  }
-
-  if (mute) {
-    track->flags |= GST_MIXER_TRACK_MUTE;
-  } else {
-    track->flags &= ~GST_MIXER_TRACK_MUTE;
-  }
-
-  return ret;
-}
-
-GstMixerTrack *
-gst_oss4_mixer_slider_new (GstOss4Mixer * mixer, GstOss4MixerControl * mc)
-{
-  GstOss4MixerSlider *s;
-  GstMixerTrack *track;
-  gint volumes[2] = { 0, };
-
-  s = g_object_new (GST_TYPE_OSS4_MIXER_SLIDER, "untranslated-label",
-      mc->mixext.extname, NULL);
-
-  track = GST_MIXER_TRACK (s);
-
-  /* caller will set track->label and track->flags */
-
-  s->mc = mc;
-  s->mixer = mixer;
-
-  /* we don't do value scaling but just present a scale of 0-maxvalue */
-  track->min_volume = 0;
-  track->max_volume = mc->mixext.maxvalue;
-
-  switch (mc->mixext.type) {
-    case MIXT_MONOSLIDER:
-    case MIXT_MONOSLIDER16:
-    case MIXT_SLIDER:
-      track->num_channels = 1;
-      break;
-    case MIXT_STEREOSLIDER:
-    case MIXT_STEREOSLIDER16:
-      track->num_channels = 2;
-      break;
-    default:
-      g_return_val_if_reached (NULL);
-  }
-
-  GST_LOG_OBJECT (track, "min=%d, max=%d, channels=%d", track->min_volume,
-      track->max_volume, track->num_channels);
-
-  if (!gst_oss4_mixer_slider_get_volume (s, volumes)) {
-    GST_WARNING_OBJECT (track, "failed to read volume, returning NULL");
-    g_object_unref (track);
-    track = NULL;
-  }
-
-  return track;
-}
-
-/* This is called from the watch thread */
-void
-gst_oss4_mixer_slider_process_change_unlocked (GstMixerTrack * track)
-{
-  GstOss4MixerSlider *s = GST_OSS4_MIXER_SLIDER_CAST (track);
-
-  if (s->mc->mute != NULL && s->mc->mute->changed) {
-    gst_mixer_mute_toggled (GST_MIXER (s->mixer), track,
-        !!s->mc->mute->last_val);
-  } else {
-    /* nothing to do here, since we don't/can't easily implement the record
-     * flag */
-  }
-
-  if (s->mc->changed) {
-    gint volumes[2] = { 0, 0 };
-
-    gst_oss4_mixer_slider_unpack_volume (s, s->mc->last_val, volumes);
-
-    /* if we 'simulate' the mute, update flag when the volume changes */
-    if (s->mc->mute == NULL) {
-      if (volumes[0] == 0 && volumes[1] == 0) {
-        track->flags |= GST_MIXER_TRACK_MUTE;
-      } else {
-        track->flags &= ~GST_MIXER_TRACK_MUTE;
-      }
-    }
-
-    gst_mixer_volume_changed (GST_MIXER (s->mixer), track, volumes);
-  }
-}
diff --git a/sys/oss4/oss4-mixer-slider.h b/sys/oss4/oss4-mixer-slider.h
deleted file mode 100644 (file)
index 3bee33f..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-/* GStreamer OSS4 mixer slider control
- * Copyright (C) 2007-2008 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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifndef GST_OSS4_MIXER_SLIDER_H
-#define GST_OSS4_MIXER_SLIDER_H
-
-#include <gst/gst.h>
-#include <gst/interfaces/mixer.h>
-
-#include "oss4-mixer.h"
-
-G_BEGIN_DECLS
-
-#define GST_TYPE_OSS4_MIXER_SLIDER            (gst_oss4_mixer_slider_get_type())
-#define GST_OSS4_MIXER_SLIDER(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_OSS4_MIXER_SLIDER,GstOss4MixerSlider))
-#define GST_OSS4_MIXER_SLIDER_CAST(obj)       ((GstOss4MixerSlider *)(obj))
-#define GST_OSS4_MIXER_SLIDER_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_OSS4_MIXER_SLIDER,GstOss4MixerSliderClass))
-#define GST_IS_OSS4_MIXER_SLIDER(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_OSS4_MIXER_SLIDER))
-#define GST_IS_OSS4_MIXER_SLIDER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_OSS4_MIXER_SLIDER))
-
-typedef struct _GstOss4MixerSlider GstOss4MixerSlider;
-typedef struct _GstOss4MixerSliderClass GstOss4MixerSliderClass;
-
-struct _GstOss4MixerSlider {
-  GstMixerTrack  mixer_track;
-
-  GstOss4MixerControl * mc;
-  GstOss4Mixer        * mixer;      /* the mixer we belong to (no ref taken) */
-  gint                  volumes[2]; /* left/mono, right                      */
-};
-
-struct _GstOss4MixerSliderClass {
-  GstMixerTrackClass mixer_track_class;
-};
-
-GType           gst_oss4_mixer_slider_get_type (void);
-
-GstMixerTrack * gst_oss4_mixer_slider_new (GstOss4Mixer * mixer, GstOss4MixerControl * mc);
-
-gboolean        gst_oss4_mixer_slider_get_volume (GstOss4MixerSlider * s, gint * volumes);
-
-gboolean        gst_oss4_mixer_slider_set_volume (GstOss4MixerSlider * s, const gint * volumes);
-
-gboolean        gst_oss4_mixer_slider_set_record (GstOss4MixerSlider * s, gboolean record);
-
-gboolean        gst_oss4_mixer_slider_set_mute (GstOss4MixerSlider * s, gboolean mute);
-
-void            gst_oss4_mixer_slider_process_change_unlocked (GstMixerTrack * track);
-
-G_END_DECLS
-
-#endif /* GST_OSS4_MIXER_SLIDER_H */
-
-
diff --git a/sys/oss4/oss4-mixer-switch.c b/sys/oss4/oss4-mixer-switch.c
deleted file mode 100644 (file)
index 0a6ce5b..0000000
+++ /dev/null
@@ -1,150 +0,0 @@
-/* GStreamer OSS4 mixer on/off switch control
- * Copyright (C) 2007-2008 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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-/* A simple ON/OFF 'switch' in gnome-volume-control / GstMixer is represented
- * by a GstMixerTrack with no channels.
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <gst/gst-i18n-plugin.h>
-
-#define NO_LEGACY_MIXER
-#include "oss4-mixer-switch.h"
-#include "oss4-soundcard.h"
-
-GST_DEBUG_CATEGORY_EXTERN (oss4mixer_debug);
-#define GST_CAT_DEFAULT oss4mixer_debug
-
-/* GstMixerTrack is a plain GObject, so let's just use the GLib macro here */
-G_DEFINE_TYPE (GstOss4MixerSwitch, gst_oss4_mixer_switch, GST_TYPE_MIXER_TRACK);
-
-static void
-gst_oss4_mixer_switch_class_init (GstOss4MixerSwitchClass * klass)
-{
-  /* nothing to do here */
-}
-
-static void
-gst_oss4_mixer_switch_init (GstOss4MixerSwitch * s)
-{
-  /* nothing to do here */
-}
-
-gboolean
-gst_oss4_mixer_switch_set (GstOss4MixerSwitch * s, gboolean disabled)
-{
-  GstMixerTrack *track;
-  int newval;
-
-  track = GST_MIXER_TRACK (s);
-
-  newval = disabled ? GST_MIXER_TRACK_MUTE : 0;
-
-  if (newval == (track->flags & GST_MIXER_TRACK_MUTE)) {
-    GST_LOG_OBJECT (s, "switch is already %d, doing nothing", newval);
-    return TRUE;
-  }
-
-  if (!gst_oss4_mixer_set_control_val (s->mixer, s->mc, !disabled)) {
-    GST_WARNING_OBJECT (s, "could not set switch to %d", !disabled);
-    return FALSE;
-  }
-
-  if (disabled) {
-    track->flags |= GST_MIXER_TRACK_MUTE;
-  } else {
-    track->flags &= ~GST_MIXER_TRACK_MUTE;
-  }
-
-  GST_LOG_OBJECT (s, "set switch to %d", newval);
-
-  return TRUE;
-}
-
-gboolean
-gst_oss4_mixer_switch_get (GstOss4MixerSwitch * s, gboolean * disabled)
-{
-  GstMixerTrack *track;
-  int enabled = -1;
-
-  track = GST_MIXER_TRACK (s);
-
-  if (!gst_oss4_mixer_get_control_val (s->mixer, s->mc, &enabled)
-      || (enabled < 0)) {
-    GST_WARNING_OBJECT (s, "could not get switch state");
-    return FALSE;
-  }
-
-  if (enabled) {
-    track->flags &= ~GST_MIXER_TRACK_MUTE;
-  } else {
-    track->flags |= GST_MIXER_TRACK_MUTE;
-  }
-  *disabled = (enabled == 0);
-
-  return TRUE;
-}
-
-GstMixerTrack *
-gst_oss4_mixer_switch_new (GstOss4Mixer * mixer, GstOss4MixerControl * mc)
-{
-  GstOss4MixerSwitch *s;
-  GstMixerTrack *track;
-  int cur = -1;
-
-  s = g_object_new (GST_TYPE_OSS4_MIXER_SWITCH, "untranslated-label",
-      mc->mixext.extname, NULL);
-
-  s->mixer = mixer;
-  s->mc = mc;
-
-  track = GST_MIXER_TRACK (s);
-
-  /* caller will set track->label and track->flags */
-
-  track->num_channels = 0;
-  track->min_volume = 0;
-  track->max_volume = 0;
-
-  if (!gst_oss4_mixer_get_control_val (s->mixer, s->mc, &cur) || cur < 0)
-    return NULL;
-
-  if (cur) {
-    track->flags &= ~GST_MIXER_TRACK_MUTE;
-  } else {
-    track->flags |= GST_MIXER_TRACK_MUTE;
-  }
-
-  return track;
-}
-
-/* This is called from the watch thread */
-void
-gst_oss4_mixer_switch_process_change_unlocked (GstMixerTrack * track)
-{
-  GstOss4MixerSwitch *s = GST_OSS4_MIXER_SWITCH_CAST (track);
-
-  if (!s->mc->changed)
-    return;
-
-  gst_mixer_mute_toggled (GST_MIXER (s->mixer), track, !s->mc->last_val);
-}
diff --git a/sys/oss4/oss4-mixer-switch.h b/sys/oss4/oss4-mixer-switch.h
deleted file mode 100644 (file)
index a8ab83f..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-/* GStreamer OSS4 mixer on/off switch control
- * Copyright (C) 2007-2008 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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifndef GST_OSS4_MIXER_SWITCH_H
-#define GST_OSS4_MIXER_SWITCH_H
-
-#include <gst/gst.h>
-#include <gst/interfaces/mixer.h>
-
-#include "oss4-mixer.h"
-
-G_BEGIN_DECLS
-
-#define GST_TYPE_OSS4_MIXER_SWITCH            (gst_oss4_mixer_switch_get_type())
-#define GST_OSS4_MIXER_SWITCH(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_OSS4_MIXER_SWITCH,GstOss4MixerSwitch))
-#define GST_OSS4_MIXER_SWITCH_CAST(obj)       ((GstOss4MixerSwitch *)(obj))
-#define GST_OSS4_MIXER_SWITCH_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_OSS4_MIXER_SWITCH,GstOss4MixerSwitchClass))
-#define GST_IS_OSS4_MIXER_SWITCH(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_OSS4_MIXER_SWITCH))
-#define GST_IS_OSS4_MIXER_SWITCH_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_OSS4_MIXER_SWITCH))
-
-typedef struct _GstOss4MixerSwitch GstOss4MixerSwitch;
-typedef struct _GstOss4MixerSwitchClass GstOss4MixerSwitchClass;
-
-struct _GstOss4MixerSwitch {
-  GstMixerTrack          mixer_track;
-
-  GstOss4MixerControl  * mc;
-  GstOss4Mixer         * mixer;      /* the mixer we belong to (no ref taken) */
-};
-
-struct _GstOss4MixerSwitchClass {
-  GstMixerTrackClass mixer_track_class;
-};
-
-GType            gst_oss4_mixer_switch_get_type (void);
-
-gboolean         gst_oss4_mixer_switch_set (GstOss4MixerSwitch * s, gboolean enabled);
-
-gboolean         gst_oss4_mixer_switch_get (GstOss4MixerSwitch * s, gboolean * enabled);
-
-GstMixerTrack  * gst_oss4_mixer_switch_new (GstOss4Mixer * mixer, GstOss4MixerControl * mc);
-
-void             gst_oss4_mixer_switch_process_change_unlocked (GstMixerTrack * track);
-
-G_END_DECLS
-
-#endif /* GST_OSS4_MIXER_SWITCH_H */
-
-
diff --git a/sys/oss4/oss4-mixer.c b/sys/oss4/oss4-mixer.c
deleted file mode 100644 (file)
index b1e652b..0000000
+++ /dev/null
@@ -1,1857 +0,0 @@
-/* GStreamer OSS4 mixer implementation
- * Copyright (C) 2007-2008 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 mixer library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-/**
- * SECTION:element-oss4mixer
- *
- * This element lets you adjust sound input and output levels with the
- * Open Sound System (OSS) version 4. It supports the GstMixer interface, which
- * can be used to obtain a list of available mixer tracks. Set the mixer
- * element to READY state before using the GstMixer interface on it.
- * 
- * <refsect2>
- * <title>Example pipelines</title>
- * <para>
- * oss4mixer can&apos;t be used in a sensible way in gst-launch.
- * </para>
- * </refsect2>
- *
- * Since: 0.10.7
- */
-
-/* Note: ioctl calls on the same open mixer device are serialised via
- * the object lock to make sure we don't do concurrent ioctls from two
- * different threads (e.g. app thread and mixer watch thread), since that
- * will probably confuse OSS. */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <string.h>
-#include <errno.h>
-#include <sys/ioctl.h>
-
-#include <gst/interfaces/mixer.h>
-#include <gst/gst-i18n-plugin.h>
-#include "gst/glib-compat-private.h"
-
-#include <glib/gprintf.h>
-
-#define NO_LEGACY_MIXER
-
-#include "oss4-audio.h"
-#include "oss4-mixer.h"
-#include "oss4-mixer-enum.h"
-#include "oss4-mixer-slider.h"
-#include "oss4-mixer-switch.h"
-#include "oss4-property-probe.h"
-#include "oss4-soundcard.h"
-
-#define GST_OSS4_MIXER_WATCH_INTERVAL   500     /* in millisecs, ie. 0.5s */
-
-GST_DEBUG_CATEGORY_EXTERN (oss4mixer_debug);
-#define GST_CAT_DEFAULT oss4mixer_debug
-
-#define DEFAULT_DEVICE       NULL
-#define DEFAULT_DEVICE_NAME  NULL
-
-enum
-{
-  PROP_0,
-  PROP_DEVICE,
-  PROP_DEVICE_NAME
-};
-
-static void gst_oss4_mixer_init_interfaces (GType type);
-
-GST_BOILERPLATE_FULL (GstOss4Mixer, gst_oss4_mixer, GstElement,
-    GST_TYPE_ELEMENT, gst_oss4_mixer_init_interfaces);
-
-static GstStateChangeReturn gst_oss4_mixer_change_state (GstElement *
-    element, GstStateChange transition);
-
-static void gst_oss4_mixer_set_property (GObject * object, guint prop_id,
-    const GValue * value, GParamSpec * pspec);
-static void gst_oss4_mixer_get_property (GObject * object, guint prop_id,
-    GValue * value, GParamSpec * pspec);
-static void gst_oss4_mixer_finalize (GObject * object);
-
-static gboolean gst_oss4_mixer_open (GstOss4Mixer * mixer,
-    gboolean silent_errors);
-static void gst_oss4_mixer_close (GstOss4Mixer * mixer);
-
-static gboolean gst_oss4_mixer_enum_control_update_enum_list (GstOss4Mixer * m,
-    GstOss4MixerControl * mc);
-
-#ifndef GST_DISABLE_GST_DEBUG
-static const gchar *mixer_ext_type_get_name (gint type);
-static const gchar *mixer_ext_flags_get_string (gint flags);
-#endif
-
-static void
-gst_oss4_mixer_base_init (gpointer klass)
-{
-  gst_element_class_set_static_metadata (GST_ELEMENT_CLASS (klass),
-      "OSS v4 Audio Mixer", "Generic/Audio",
-      "Control sound input and output levels with OSS4",
-      "Tim-Philipp Müller <tim centricular net>");
-}
-
-static void
-gst_oss4_mixer_class_init (GstOss4MixerClass * klass)
-{
-  GstElementClass *element_class;
-  GObjectClass *gobject_class;
-
-  element_class = (GstElementClass *) klass;
-  gobject_class = (GObjectClass *) klass;
-
-  gobject_class->finalize = gst_oss4_mixer_finalize;
-  gobject_class->set_property = gst_oss4_mixer_set_property;
-  gobject_class->get_property = gst_oss4_mixer_get_property;
-
-  /**
-   * GstOss4Mixer:device
-   *
-   * OSS4 mixer device (e.g. /dev/oss/hdaudio0/mix0 or /dev/mixerN)
-   *
-   **/
-  g_object_class_install_property (gobject_class, PROP_DEVICE,
-      g_param_spec_string ("device", "Device",
-          "OSS mixer device (e.g. /dev/oss/hdaudio0/mix0 or /dev/mixerN) "
-          "(NULL = use first mixer device found)", DEFAULT_DEVICE,
-          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-
-  /**
-   * GstOss4Mixer:device-name
-   *
-   * Human-readable name of the sound device. May be NULL if the device is
-   * not open (ie. when the mixer is in NULL state)
-   *
-   **/
-  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", DEFAULT_DEVICE_NAME,
-          G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
-
-  element_class->change_state = GST_DEBUG_FUNCPTR (gst_oss4_mixer_change_state);
-}
-
-static void
-gst_oss4_mixer_finalize (GObject * obj)
-{
-  GstOss4Mixer *mixer = GST_OSS4_MIXER (obj);
-
-  g_free (mixer->device);
-
-  G_OBJECT_CLASS (parent_class)->finalize (obj);
-}
-
-static void
-gst_oss4_mixer_reset (GstOss4Mixer * mixer)
-{
-  mixer->fd = -1;
-  mixer->need_update = TRUE;
-  memset (&mixer->last_mixext, 0, sizeof (oss_mixext));
-}
-
-static void
-gst_oss4_mixer_init (GstOss4Mixer * mixer, GstOss4MixerClass * g_class)
-{
-  mixer->device = g_strdup (DEFAULT_DEVICE);
-  mixer->device_name = NULL;
-
-  gst_oss4_mixer_reset (mixer);
-}
-
-static void
-gst_oss4_mixer_set_property (GObject * object, guint prop_id,
-    const GValue * value, GParamSpec * pspec)
-{
-  GstOss4Mixer *mixer = GST_OSS4_MIXER (object);
-
-  switch (prop_id) {
-    case PROP_DEVICE:
-      GST_OBJECT_LOCK (mixer);
-      if (!GST_OSS4_MIXER_IS_OPEN (mixer)) {
-        g_free (mixer->device);
-        mixer->device = g_value_dup_string (value);
-        /* unset any cached device-name */
-        g_free (mixer->device_name);
-        mixer->device_name = NULL;
-      } else {
-        g_warning ("%s: can't change \"device\" property while mixer is open",
-            GST_OBJECT_NAME (mixer));
-      }
-      GST_OBJECT_UNLOCK (mixer);
-      break;
-    default:
-      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-      break;
-  }
-}
-
-static void
-gst_oss4_mixer_get_property (GObject * object, guint prop_id,
-    GValue * value, GParamSpec * pspec)
-{
-  GstOss4Mixer *mixer = GST_OSS4_MIXER (object);
-
-  switch (prop_id) {
-    case PROP_DEVICE:
-      GST_OBJECT_LOCK (mixer);
-      g_value_set_string (value, mixer->device);
-      GST_OBJECT_UNLOCK (mixer);
-      break;
-    case PROP_DEVICE_NAME:
-      GST_OBJECT_LOCK (mixer);
-      /* If device is set, try to retrieve the name even if we're not open */
-      if (mixer->fd == -1 && mixer->device != NULL) {
-        if (gst_oss4_mixer_open (mixer, TRUE)) {
-          g_value_set_string (value, mixer->device_name);
-          gst_oss4_mixer_close (mixer);
-        } else {
-          g_value_set_string (value, mixer->device_name);
-        }
-      } else {
-        g_value_set_string (value, mixer->device_name);
-      }
-      GST_OBJECT_UNLOCK (mixer);
-      break;
-    default:
-      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-      break;
-  }
-}
-
-static gboolean
-gst_oss4_mixer_open (GstOss4Mixer * mixer, gboolean silent_errors)
-{
-  struct oss_mixerinfo mi = { 0, };
-  gchar *device;
-
-  g_return_val_if_fail (!GST_OSS4_MIXER_IS_OPEN (mixer), FALSE);
-
-  if (mixer->device)
-    device = g_strdup (mixer->device);
-  else
-    device = gst_oss4_audio_find_device (GST_OBJECT_CAST (mixer));
-
-  /* desperate times, desperate measures */
-  if (device == NULL)
-    device = g_strdup ("/dev/mixer");
-
-  GST_INFO_OBJECT (mixer, "Trying to open OSS4 mixer device '%s'", device);
-
-  mixer->fd = open (device, O_RDWR, 0);
-  if (mixer->fd < 0)
-    goto open_failed;
-
-  /* Make sure it's OSS4. If it's old OSS, let the old ossmixer handle it */
-  if (!gst_oss4_audio_check_version (GST_OBJECT (mixer), mixer->fd))
-    goto legacy_oss;
-
-  GST_INFO_OBJECT (mixer, "Opened mixer device '%s', which is mixer %d",
-      device, mi.dev);
-
-  /* Get device name for currently open fd */
-  mi.dev = -1;
-  if (ioctl (mixer->fd, SNDCTL_MIXERINFO, &mi) == 0) {
-    mixer->modify_counter = mi.modify_counter;
-    if (mi.name[0] != '\0') {
-      mixer->device_name = g_strdup (mi.name);
-    }
-  } else {
-    mixer->modify_counter = 0;
-  }
-
-  if (mixer->device_name == NULL) {
-    mixer->device_name = g_strdup ("Unknown");
-  }
-  GST_INFO_OBJECT (mixer, "device name = '%s'", mixer->device_name);
-
-  mixer->open_device = device;
-
-  return TRUE;
-
-  /* ERRORS */
-open_failed:
-  {
-    if (!silent_errors) {
-      GST_ELEMENT_ERROR (mixer, RESOURCE, OPEN_READ_WRITE,
-          (_("Could not open audio device for mixer control handling.")),
-          GST_ERROR_SYSTEM);
-    } else {
-      GST_DEBUG_OBJECT (mixer, "open failed: %s (ignoring errors)",
-          g_strerror (errno));
-    }
-    g_free (device);
-    return FALSE;
-  }
-legacy_oss:
-  {
-    gst_oss4_mixer_close (mixer);
-    if (!silent_errors) {
-      GST_ELEMENT_ERROR (mixer, RESOURCE, OPEN_READ_WRITE,
-          (_("Could not open audio device for mixer control handling. "
-                  "This version of the Open Sound System is not supported by this "
-                  "element.")), ("Try the 'ossmixer' element instead"));
-    } else {
-      GST_DEBUG_OBJECT (mixer, "open failed: legacy oss (ignoring errors)");
-    }
-    g_free (device);
-    return FALSE;
-  }
-}
-
-static void
-gst_oss4_mixer_control_free (GstOss4MixerControl * mc)
-{
-  g_list_free (mc->children);
-  g_list_free (mc->mute_group);
-  g_free (mc->enum_vals);
-  memset (mc, 0, sizeof (GstOss4MixerControl));
-  g_free (mc);
-}
-
-static void
-gst_oss4_mixer_free_tracks (GstOss4Mixer * mixer)
-{
-  g_list_foreach (mixer->tracks, (GFunc) g_object_unref, NULL);
-  g_list_free (mixer->tracks);
-  mixer->tracks = NULL;
-
-  g_list_foreach (mixer->controls, (GFunc) gst_oss4_mixer_control_free, NULL);
-  g_list_free (mixer->controls);
-  mixer->controls = NULL;
-}
-
-static void
-gst_oss4_mixer_close (GstOss4Mixer * mixer)
-{
-  g_free (mixer->device_name);
-  mixer->device_name = NULL;
-
-  g_free (mixer->open_device);
-  mixer->open_device = NULL;
-
-  gst_oss4_mixer_free_tracks (mixer);
-
-  if (mixer->fd != -1) {
-    close (mixer->fd);
-    mixer->fd = -1;
-  }
-
-  gst_oss4_mixer_reset (mixer);
-}
-
-static void
-gst_oss4_mixer_watch_process_changes (GstOss4Mixer * mixer)
-{
-  GList *c, *t, *tracks = NULL;
-
-  GST_INFO_OBJECT (mixer, "mixer interface or control changed");
-
-  /* this is all with the mixer object lock held */
-
-  /* we go through the list backwards so we can bail out faster when the entire
-   * interface needs to be rebuilt */
-  for (c = g_list_last (mixer->controls); c != NULL; c = c->prev) {
-    GstOss4MixerControl *mc = c->data;
-    oss_mixer_value ossval = { 0, };
-
-    mc->changed = FALSE;
-    mc->list_changed = FALSE;
-
-    /* not interested in controls we don't expose in the mixer interface */
-    if (!mc->used)
-      continue;
-
-    /* don't try to read a value from controls that don't have one */
-    if (mc->mixext.type == MIXT_DEVROOT || mc->mixext.type == MIXT_GROUP)
-      continue;
-
-    /* is this an enum control whose list may change? */
-    if (mc->mixext.type == MIXT_ENUM && mc->enum_version != 0) {
-      if (gst_oss4_mixer_enum_control_update_enum_list (mixer, mc))
-        mc->list_changed = TRUE;
-    }
-
-    ossval.dev = mc->mixext.dev;
-    ossval.ctrl = mc->mixext.ctrl;
-    ossval.timestamp = mc->mixext.timestamp;
-
-    if (ioctl (mixer->fd, SNDCTL_MIX_READ, &ossval) == -1) {
-      if (errno == EIDRM || errno == EFAULT) {
-        GST_DEBUG ("%s has disappeared", mc->mixext.extname);
-        goto mixer_changed;
-      }
-      GST_WARNING_OBJECT (mixer, "MIX_READ failed: %s", g_strerror (errno));
-      /* just ignore, move on to next one */
-      continue;
-    }
-
-    if (ossval.value == mc->last_val) { /* no change */
-      /* GST_LOG_OBJECT (mixer, "%s hasn't changed", mc->mixext.extname); */
-      continue;
-    }
-
-    mc->last_val = ossval.value;
-    GST_LOG_OBJECT (mixer, "%s changed value to %u 0x%08x",
-        mc->mixext.extname, ossval.value, ossval.value);
-    mc->changed = TRUE;
-  }
-
-  /* copy list and take track refs, so we can safely drop the object lock,
-   * which we need to do to be able to post messages on the bus */
-  tracks = g_list_copy (mixer->tracks);
-  g_list_foreach (tracks, (GFunc) g_object_ref, NULL);
-
-  GST_OBJECT_UNLOCK (mixer);
-
-  /* since we don't know (or want to know exactly) which controls belong to
-   * which track, we just go through the tracks one-by-one now and make them
-   * check themselves if any of their controls have changed and which messages
-   * to post on the bus as a result */
-  for (t = tracks; t != NULL; t = t->next) {
-    GstMixerTrack *track = t->data;
-
-    if (GST_IS_OSS4_MIXER_SLIDER (track)) {
-      gst_oss4_mixer_slider_process_change_unlocked (track);
-    } else if (GST_IS_OSS4_MIXER_SWITCH (track)) {
-      gst_oss4_mixer_switch_process_change_unlocked (track);
-    } else if (GST_IS_OSS4_MIXER_ENUM (track)) {
-      gst_oss4_mixer_enum_process_change_unlocked (track);
-    }
-
-    g_object_unref (track);
-  }
-  g_list_free (tracks);
-
-  GST_OBJECT_LOCK (mixer);
-  return;
-
-mixer_changed:
-  {
-    GST_OBJECT_UNLOCK (mixer);
-    gst_mixer_mixer_changed (GST_MIXER (mixer));
-    GST_OBJECT_LOCK (mixer);
-    return;
-  }
-}
-
-/* This thread watches the mixer for changes in a somewhat inefficient way
- * (running an ioctl every half second or so). This is still better and
- * cheaper than apps polling all tracks for changes a few times a second
- * though. Needs more thought. There's probably (hopefully) a way to get
- * notifications via the fd directly somehow. */
-static gpointer
-gst_oss4_mixer_watch_thread (gpointer thread_data)
-{
-  GstOss4Mixer *mixer = GST_OSS4_MIXER_CAST (thread_data);
-
-  GST_DEBUG_OBJECT (mixer, "watch thread running");
-
-  GST_OBJECT_LOCK (mixer);
-  while (!mixer->watch_shutdown) {
-    oss_mixerinfo mi = { 0, };
-    GTimeVal tv;
-
-    mi.dev = -1;
-    if (ioctl (mixer->fd, SNDCTL_MIXERINFO, &mi) == 0) {
-      if (mixer->modify_counter != mi.modify_counter) {
-        /* GST_LOG ("processing changes"); */
-        gst_oss4_mixer_watch_process_changes (mixer);
-        mixer->modify_counter = mi.modify_counter;
-      } else {
-        /* GST_LOG ("no changes"); */
-      }
-    } else {
-      GST_WARNING_OBJECT (mixer, "MIXERINFO failed: %s", g_strerror (errno));
-    }
-
-    /* we could move the _get_current_time out of the loop and just do the
-     * add in ever iteration, which would be less exact, but who cares */
-    g_get_current_time (&tv);
-    g_time_val_add (&tv, GST_OSS4_MIXER_WATCH_INTERVAL * 1000);
-    (void) g_cond_timed_wait (mixer->watch_cond, GST_OBJECT_GET_LOCK (mixer),
-        &tv);
-  }
-  GST_OBJECT_UNLOCK (mixer);
-
-  GST_DEBUG_OBJECT (mixer, "watch thread done");
-  gst_object_unref (mixer);
-  return NULL;
-}
-
-/* call with object lock held */
-static void
-gst_oss4_mixer_wake_up_watch_task (GstOss4Mixer * mixer)
-{
-  GST_LOG_OBJECT (mixer, "signalling watch thread to wake up");
-  g_cond_signal (mixer->watch_cond);
-}
-
-static void
-gst_oss4_mixer_stop_watch_task (GstOss4Mixer * mixer)
-{
-  if (mixer->watch_thread) {
-    GST_OBJECT_LOCK (mixer);
-    mixer->watch_shutdown = TRUE;
-    GST_LOG_OBJECT (mixer, "signalling watch thread to stop");
-    g_cond_signal (mixer->watch_cond);
-    GST_OBJECT_UNLOCK (mixer);
-    GST_LOG_OBJECT (mixer, "waiting for watch thread to join");
-    g_thread_join (mixer->watch_thread);
-    GST_DEBUG_OBJECT (mixer, "watch thread stopped");
-    mixer->watch_thread = NULL;
-  }
-
-  if (mixer->watch_cond) {
-    g_cond_free (mixer->watch_cond);
-    mixer->watch_cond = NULL;
-  }
-}
-
-static void
-gst_oss4_mixer_start_watch_task (GstOss4Mixer * mixer)
-{
-  GError *err = NULL;
-
-  mixer->watch_cond = g_cond_new ();
-  mixer->watch_shutdown = FALSE;
-
-  mixer->watch_thread = g_thread_try_new ("oss4-mixer-thread",
-      gst_oss4_mixer_watch_thread, gst_object_ref (mixer), &err);
-
-  if (mixer->watch_thread == NULL) {
-    GST_ERROR_OBJECT (mixer, "Could not create watch thread: %s", err->message);
-    g_cond_free (mixer->watch_cond);
-    mixer->watch_cond = NULL;
-    g_error_free (err);
-  }
-}
-
-static GstStateChangeReturn
-gst_oss4_mixer_change_state (GstElement * element, GstStateChange transition)
-{
-  GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
-  GstOss4Mixer *mixer = GST_OSS4_MIXER (element);
-
-  switch (transition) {
-    case GST_STATE_CHANGE_NULL_TO_READY:
-      if (!gst_oss4_mixer_open (mixer, FALSE))
-        return GST_STATE_CHANGE_FAILURE;
-      gst_oss4_mixer_start_watch_task (mixer);
-      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:
-      gst_oss4_mixer_stop_watch_task (mixer);
-      gst_oss4_mixer_close (mixer);
-      break;
-    default:
-      break;
-  }
-
-  return ret;
-}
-
-/* === GstMixer interface === */
-
-static inline gboolean
-gst_oss4_mixer_contains_track (GstMixer * mixer, GstMixerTrack * track)
-{
-  return (g_list_find (GST_OSS4_MIXER (mixer)->tracks, track) != NULL);
-}
-
-static inline gboolean
-gst_oss4_mixer_contains_options (GstMixer * mixer, GstMixerOptions * options)
-{
-  return (g_list_find (GST_OSS4_MIXER (mixer)->tracks, options) != NULL);
-}
-
-static void
-gst_oss4_mixer_post_mixer_changed_msg (GstOss4Mixer * mixer)
-{
-  /* only post mixer-changed message once */
-  if (!mixer->need_update) {
-    gst_mixer_mixer_changed (GST_MIXER (mixer));
-    mixer->need_update = TRUE;
-  }
-}
-
-/* call with mixer object lock held to serialise ioctl */
-gboolean
-gst_oss4_mixer_get_control_val (GstOss4Mixer * mixer, GstOss4MixerControl * mc,
-    int *val)
-{
-  oss_mixer_value ossval = { 0, };
-
-  if (GST_OBJECT_TRYLOCK (mixer)) {
-    GST_ERROR ("must be called with mixer lock held");
-    GST_OBJECT_UNLOCK (mixer);
-  }
-
-  ossval.dev = mc->mixext.dev;
-  ossval.ctrl = mc->mixext.ctrl;
-  ossval.timestamp = mc->mixext.timestamp;
-
-  if (ioctl (mixer->fd, SNDCTL_MIX_READ, &ossval) == -1) {
-    if (errno == EIDRM) {
-      GST_DEBUG_OBJECT (mixer, "MIX_READ failed: mixer interface has changed");
-      gst_oss4_mixer_post_mixer_changed_msg (mixer);
-    } else {
-      GST_WARNING_OBJECT (mixer, "MIX_READ failed: %s", g_strerror (errno));
-    }
-    *val = 0;
-    mc->last_val = 0;
-    return FALSE;
-  }
-
-  *val = ossval.value;
-  mc->last_val = ossval.value;
-  GST_LOG_OBJECT (mixer, "got value 0x%08x from %s)", *val, mc->mixext.extname);
-  return TRUE;
-}
-
-/* call with mixer object lock held to serialise ioctl */
-gboolean
-gst_oss4_mixer_set_control_val (GstOss4Mixer * mixer, GstOss4MixerControl * mc,
-    int val)
-{
-  oss_mixer_value ossval = { 0, };
-
-  ossval.dev = mc->mixext.dev;
-  ossval.ctrl = mc->mixext.ctrl;
-  ossval.timestamp = mc->mixext.timestamp;
-  ossval.value = val;
-
-  if (GST_OBJECT_TRYLOCK (mixer)) {
-    GST_ERROR ("must be called with mixer lock held");
-    GST_OBJECT_UNLOCK (mixer);
-  }
-
-  if (ioctl (mixer->fd, SNDCTL_MIX_WRITE, &ossval) == -1) {
-    if (errno == EIDRM) {
-      GST_LOG_OBJECT (mixer, "MIX_WRITE failed: mixer interface has changed");
-      gst_oss4_mixer_post_mixer_changed_msg (mixer);
-    } else {
-      GST_WARNING_OBJECT (mixer, "MIX_WRITE failed: %s", g_strerror (errno));
-    }
-    return FALSE;
-  }
-
-  mc->last_val = val;
-  GST_LOG_OBJECT (mixer, "set value 0x%08x on %s", val, mc->mixext.extname);
-  return TRUE;
-}
-
-#if 0
-static gchar *
-gst_oss4_mixer_control_get_pretty_name (GstOss4MixerControl * mc)
-{
-  gchar *name;
-
-  const gchar *name, *u;
-
-  /* "The id field is the original name given by the driver when it called
-   * mixer_ext_create_control. This name can be used by fully featured GUI
-   * mixers. However this name should be downshifted and cut before the last
-   * underscore ("_") to get the proper name. For example mixer control name
-   * created as "MYDRV_MAINVOL" will become just "mainvol" after this
-   * transformation." */
-  name = mc->mixext.extname;
-  u = MAX (strrchr (name, '_'), strrchr (name, '.'));
-  if (u != NULL)
-    name = u + 1;
-
-  /* maybe capitalize the first letter? */
-  return g_ascii_strdown (name, -1);
-  /* the .id thing doesn't really seem to work right, ie. for some sliders
-   * it's just '-' so you have to use the name of the parent control etc.
-   * let's not use it for now, much too painful. */
-  if (g_str_has_prefix (mc->mixext.extname, "misc."))
-    name = g_strdup (mc->mixext.extname + 5);
-  else
-    name = g_strdup (mc->mixext.extname);
-  /* chop off trailing digit (only one for now) */
-  if (strlen (name) > 0 && g_ascii_isdigit (name[strlen (name) - 1]))
-    name[strlen (name) - 1] = '\0';
-  g_strdelimit (name, ".", ' ');
-  return name;
-}
-#endif
-
-/* these translations are a bit ad-hoc and horribly incomplete; it is not
- * really going to work this way with all the different chipsets and drivers.
- * We also use these for translating option values. */
-static struct
-{
-  const gchar oss_name[32];
-  const gchar *label;
-} labels[] = {
-  {
-  "volume", N_("Volume")}, {
-  "master", N_("Master")}, {
-  "front", N_("Front")}, {
-  "rear", N_("Rear")}, {
-  "headphones", N_("Headphones")}, {
-  "center", N_("Center")}, {
-  "lfe", N_("LFE")}, {
-  "surround", N_("Surround")}, {
-  "side", N_("Side")}, {
-  "speaker", N_("Built-in Speaker")}, {
-  "aux1-out", N_("AUX 1 Out")}, {
-  "aux2-out", N_("AUX 2 Out")}, {
-  "aux-out", N_("AUX Out")}, {
-  "bass", N_("Bass")}, {
-  "treble", N_("Treble")}, {
-  "3d-depth", N_("3D Depth")}, {
-  "3d-center", N_("3D Center")}, {
-  "3d-enhance", N_("3D Enhance")}, {
-  "phone", N_("Telephone")}, {
-  "mic", N_("Microphone")}, {
-  "line-out", N_("Line Out")}, {
-  "line-in", N_("Line In")}, {
-  "linein", N_("Line In")}, {
-  "cd", N_("Internal CD")}, {
-  "video", N_("Video In")}, {
-  "aux1-in", N_("AUX 1 In")}, {
-  "aux2-in", N_("AUX 2 In")}, {
-  "aux-in", N_("AUX In")}, {
-  "pcm", N_("PCM")}, {
-  "record-gain", N_("Record Gain")}, {
-  "igain", N_("Record Gain")}, {
-  "ogain", N_("Output Gain")}, {
-  "micboost", N_("Microphone Boost")}, {
-  "loopback", N_("Loopback")}, {
-  "diag", N_("Diagnostic")}, {
-  "loudness", N_("Bass Boost")}, {
-  "outputs", N_("Playback Ports")}, {
-  "input", N_("Input")}, {
-  "inputs", N_("Record Source")}, {
-  "record-source", N_("Record Source")}, {
-  "monitor-source", N_("Monitor Source")}, {
-  "beep", N_("Keyboard Beep")}, {
-  "monitor-gain", N_("Monitor")}, {
-  "stereo-simulate", N_("Simulate Stereo")}, {
-  "stereo", N_("Stereo")}, {
-  "multich", N_("Surround Sound")}, {
-  "mic-gain", N_("Microphone Gain")}, {
-  "speaker-source", N_("Speaker Source")}, {
-  "mic-source", N_("Microphone Source")}, {
-  "jack", N_("Jack")}, {
-  "center/lfe", N_("Center / LFE")}, {
-  "stereo-mix", N_("Stereo Mix")}, {
-  "mono-mix", N_("Mono Mix")}, {
-  "input-mix", N_("Input Mix")}, {
-  "spdif-in", N_("SPDIF In")}, {
-  "spdif-out", N_("SPDIF Out")}, {
-  "mic1", N_("Microphone 1")}, {
-  "mic2", N_("Microphone 2")}, {
-  "digital-out", N_("Digital Out")}, {
-  "digital-in", N_("Digital In")}, {
-  "hdmi", N_("HDMI")}, {
-  "modem", N_("Modem")}, {
-  "handset", N_("Handset")}, {
-  "other", N_("Other")}, {
-  "stereo", N_("Stereo")}, {
-  "none", N_("None")}, {
-  "on", N_("On")}, {
-  "off", N_("Off")}, {
-  "mute", N_("Mute")}, {
-  "fast", N_("Fast")}, {
-    /* TRANSLATORS: "Very Low" is a quality setting here */
-  "very-low", N_("Very Low")}, {
-    /* TRANSLATORS: "Low" is a quality setting here */
-  "low", N_("Low")}, {
-    /* TRANSLATORS: "Medium" is a quality setting here */
-  "medium", N_("Medium")}, {
-    /* TRANSLATORS: "High" is a quality setting here */
-  "high", N_("High")}, {
-    /* TRANSLATORS: "Very High" is a quality setting here */
-  "very-high", N_("Very High")}, {
-  "high+", N_("Very High")}, {
-    /* TRANSLATORS: "Production" is a quality setting here */
-  "production", N_("Production")}, {
-  "fp-mic", N_("Front Panel Microphone")}, {
-  "fp-linein", N_("Front Panel Line In")}, {
-  "fp-headphones", N_("Front Panel Headphones")}, {
-  "fp-lineout", N_("Front Panel Line Out")}, {
-  "green", N_("Green Connector")}, {
-  "pink", N_("Pink Connector")}, {
-  "blue", N_("Blue Connector")}, {
-  "white", N_("White Connector")}, {
-  "black", N_("Black Connector")}, {
-  "gray", N_("Gray Connector")}, {
-  "orange", N_("Orange Connector")}, {
-  "red", N_("Red Connector")}, {
-  "yellow", N_("Yellow Connector")}, {
-  "fp-green", N_("Green Front Panel Connector")}, {
-  "fp-pink", N_("Pink Front Panel Connector")}, {
-  "fp-blue", N_("Blue Front Panel Connector")}, {
-  "fp-white", N_("White Front Panel Connector")}, {
-  "fp-black", N_("Black Front Panel Connector")}, {
-  "fp-gray", N_("Gray Front Panel Connector")}, {
-  "fp-orange", N_("Orange Front Panel Connector")}, {
-  "fp-red", N_("Red Front Panel Connector")}, {
-  "fp-yellow", N_("Yellow Front Panel Connector")}, {
-  "spread", N_("Spread Output")}, {
-  "downmix", N_("Downmix")},
-      /* FIXME translate Audigy NX USB labels) */
-/*
-  { "rec.src", N_("Record Source") },
-  { "output.mute", N_("Mute output") }
- headph (Controller group)
-   headph.src (Enumeration control)
-   headph.mute (On/Off switch)
- digital2 (Controller group)
-   digital2.src (Enumeration control)
-   digital2.mute (On/Off switch)
- digital (Controller group)
-   digital.mute1 (On/Off switch)
-   digital.vol (Controller group)
-     digital.vol.front (Stereo slider (0-255))
-     digital.vol.surr (Stereo slider (0-255))
-     digital.vol.c/l (Stereo slider (0-255))
-     digital.vol.center (Stereo slider (0-255))
-   digital.mute2 (On/Off switch)
-   digital.vol (Stereo slider (0-255))
- line (Controller group)
-   line.mute (On/Off switch)
-   line.vol (Stereo slider (0-255))
- play-altset (Enumeration control)
- rec-altset (Enumeration control)
-*/
-};
-
-/* Decent i18n is pretty much impossible with OSS's way of providing us with
- * mixer labels (and the fact that they are pretty much random), but that
- * doesn't mean we shouldn't at least try. */
-static gchar *
-gst_oss4_mixer_control_get_translated_name (GstOss4MixerControl * mc)
-{
-  gchar name[128] = { 0, };
-  gchar vmix_str[32] = { '\0', };
-  gchar *ptr;
-  int dummy, i;
-  int num = -1;
-  gboolean function_suffix = FALSE;
-
-  /* main virtual mixer controls (we hide the stream volumes) */
-  if (sscanf (mc->mixext.extname, "vmix%d-%32c", &dummy, vmix_str) == 2) {
-    if (strcmp (vmix_str, "src") == 0)
-      return g_strdup (_("Virtual Mixer Input"));
-    else if (strcmp (vmix_str, "vol") == 0)
-      return g_strdup (_("Virtual Mixer Output"));
-    else if (strcmp (vmix_str, "channels") == 0)
-      return g_strdup (_("Virtual Mixer Channels"));
-  }
-
-  g_strlcpy (name, mc->mixext.extname, sizeof (name));
-
-  /* we deal with either "connector." or "jack." */
-  if ((g_str_has_prefix (name, "connector.")) ||
-      (g_str_has_prefix (name, "jack."))) {
-    ptr = strchr (mc->mixext.extname, '.');
-    ptr++;
-    g_strlcpy (name, ptr, sizeof (name));
-  }
-
-  /* special handling for jack retasking suffixes */
-  if (g_str_has_suffix (name, ".function") || g_str_has_suffix (name, ".mode")) {
-    function_suffix = TRUE;
-    ptr = strrchr (name, '.');
-    *ptr = 0;
-  }
-
-  /* parse off trailing numbers */
-  i = strlen (name);
-  while ((i > 0) && (g_ascii_isdigit (name[i - 1]))) {
-    i--;
-  }
-  /* the check catches the case where the control name is just a number */
-  if ((i > 0) && (name[i] != '\0')) {
-    num = atoi (name + i);
-    name[i] = '\0';
-  }
-
-  /* look for a match, progressively skipping '.' delimited prefixes as we go */
-  ptr = name;
-  do {
-    if (*ptr == '.')
-      ptr++;
-    for (i = 0; i < G_N_ELEMENTS (labels); ++i) {
-      if (g_ascii_strcasecmp (ptr, labels[i].oss_name) == 0) {
-        g_strlcpy (name, _(labels[i].label), sizeof (name));
-        goto append_suffixes;
-      }
-    }
-  } while ((ptr = strchr (ptr, '.')) != NULL);
-
-  /* failing that, just replace periods with spaces */
-  g_strdelimit (name, ".", ' ');
-
-append_suffixes:
-  if (num > -1) {
-    if (function_suffix) {
-      /* TRANSLATORS: name + number of a volume mixer control */
-      return g_strdup_printf (_("%s %d Function"), name, num);
-    } else {
-      return g_strdup_printf ("%s %d", name, num);
-    }
-  } else {
-    if (function_suffix) {
-      /* TRANSLATORS: name of a volume mixer control */
-      return g_strdup_printf (_("%s Function"), name);
-    } else {
-      return g_strdup (name);
-    }
-  }
-}
-
-static const gchar *
-gst_oss4_mixer_control_get_translated_option (const gchar * name)
-{
-  int i;
-  for (i = 0; i < G_N_ELEMENTS (labels); ++i) {
-    if (g_ascii_strcasecmp (name, labels[i].oss_name) == 0) {
-      return _(labels[i].label);
-    }
-  }
-  return (name);
-}
-
-#ifndef GST_DISABLE_GST_DEBUG
-static const gchar *
-mixer_ext_type_get_name (gint type)
-{
-  switch (type) {
-    case MIXT_DEVROOT:
-      return "Device root entry";
-    case MIXT_GROUP:
-      return "Controller group";
-    case MIXT_ONOFF:
-      return "On/Off switch";
-    case MIXT_ENUM:
-      return "Enumeration control";
-    case MIXT_MONOSLIDER:
-      return "Mono slider (0-255)";
-    case MIXT_STEREOSLIDER:
-      return "Stereo slider (0-255)";
-    case MIXT_MESSAGE:
-      return "Textual message"; /* whatever this is */
-    case MIXT_MONOVU:
-      return "Mono VU meter value";
-    case MIXT_STEREOVU:
-      return "Stereo VU meter value";
-    case MIXT_MONOPEAK:
-      return "Mono VU meter peak value";
-    case MIXT_STEREOPEAK:
-      return "Stereo VU meter peak value";
-    case MIXT_RADIOGROUP:
-      return "Radio button group";
-    case MIXT_MARKER:          /* Separator between normal and extension entries */
-      return "Separator";
-    case MIXT_VALUE:
-      return "Decimal value entry";
-    case MIXT_HEXVALUE:
-      return "Hex value entry";
-    case MIXT_SLIDER:
-      return "Mono slider (31-bit value range)";
-    case MIXT_3D:
-      return "3D";              /* what's this? */
-    case MIXT_MONOSLIDER16:
-      return "Mono slider (0-32767)";
-    case MIXT_STEREOSLIDER16:
-      return "Stereo slider (0-32767)";
-    case MIXT_MUTE:
-      return "Mute switch";
-    default:
-      break;
-  }
-  return "unknown";
-}
-#endif /* GST_DISABLE_GST_DEBUG */
-
-#ifndef GST_DISABLE_GST_DEBUG
-static const gchar *
-mixer_ext_flags_get_string (gint flags)
-{
-  struct
-  {
-    gint flag;
-    gchar nick[16];
-  } all_flags[] = {
-    /* first the important ones */
-    {
-    MIXF_MAINVOL, "MAINVOL"}, {
-    MIXF_PCMVOL, "PCMVOL"}, {
-    MIXF_RECVOL, "RECVOL"}, {
-    MIXF_MONVOL, "MONVOL"}, {
-    MIXF_DESCR, "DESCR"},
-        /* now the rest in the right order */
-    {
-    MIXF_READABLE, "READABLE"}, {
-    MIXF_WRITEABLE, "WRITABLE"}, {
-    MIXF_POLL, "POLL"}, {
-    MIXF_HZ, "HZ"}, {
-    MIXF_STRING, "STRING"}, {
-    MIXF_DYNAMIC, "DYNAMIC"}, {
-    MIXF_OKFAIL, "OKFAIL"}, {
-    MIXF_FLAT, "FLAT"}, {
-    MIXF_LEGACY, "LEGACY"}, {
-    MIXF_CENTIBEL, "CENTIBEL"}, {
-    MIXF_DECIBEL, "DECIBEL"}, {
-    MIXF_WIDE, "WIDE"}
-  };
-  GString *s;
-  GQuark q;
-  gint i;
-
-  if (flags == 0)
-    return "None";
-
-  s = g_string_new ("");
-  for (i = 0; i < G_N_ELEMENTS (all_flags); ++i) {
-    if ((flags & all_flags[i].flag)) {
-      if (s->len > 0)
-        g_string_append (s, " | ");
-      g_string_append (s, all_flags[i].nick);
-      flags &= ~all_flags[i].flag;      /* unset */
-    }
-  }
-
-  /* unknown flags? */
-  if (flags != 0) {
-    if (s->len > 0)
-      g_string_append (s, " | ");
-    g_string_append (s, "???");
-  }
-
-  /* we'll just put it into the global quark table (cheeky, eh?) */
-  q = g_quark_from_string (s->str);
-  g_string_free (s, TRUE);
-
-  return g_quark_to_string (q);
-}
-#endif /* GST_DISABLE_GST_DEBUG */
-
-#ifndef GST_DISABLE_GST_DEBUG
-static void
-gst_oss4_mixer_control_dump_tree (GstOss4MixerControl * mc, gint depth)
-{
-  GList *c;
-  gchar spaces[64];
-  gint i;
-
-  depth = MIN (sizeof (spaces) - 1, depth);
-  for (i = 0; i < depth; ++i)
-    spaces[i] = ' ';
-  spaces[i] = '\0';
-
-  GST_LOG ("%s%s (%s)", spaces, mc->mixext.extname,
-      mixer_ext_type_get_name (mc->mixext.type));
-  for (c = mc->children; c != NULL; c = c->next) {
-    GstOss4MixerControl *child_mc = (GstOss4MixerControl *) c->data;
-
-    gst_oss4_mixer_control_dump_tree (child_mc, depth + 2);
-  }
-}
-#endif /* GST_DISABLE_GST_DEBUG */
-
-static GList *
-gst_oss4_mixer_get_controls (GstOss4Mixer * mixer)
-{
-  GstOss4MixerControl *root_mc = NULL;
-  oss_mixerinfo mi = { 0, };
-  GList *controls = NULL;
-  GList *l;
-  guint i;
-
-  /* Get info for currently open fd */
-  mi.dev = -1;
-  if (ioctl (mixer->fd, SNDCTL_MIXERINFO, &mi) == -1)
-    goto no_mixerinfo;
-
-  if (mi.nrext <= 0) {
-    GST_DEBUG ("mixer %s has no controls", mi.id);
-    return NULL;
-  }
-
-  GST_INFO ("Reading controls for mixer %s", mi.id);
-
-  for (i = 0; i < mi.nrext; ++i) {
-    GstOss4MixerControl *mc;
-    oss_mixext mix_ext = { 0, };
-
-    mix_ext.dev = mi.dev;
-    mix_ext.ctrl = i;
-
-    if (ioctl (mixer->fd, SNDCTL_MIX_EXTINFO, &mix_ext) == -1) {
-      GST_DEBUG ("SNDCTL_MIX_EXTINFO failed on mixer %s, control %d: %s",
-          mi.id, i, g_strerror (errno));
-      continue;
-    }
-
-    /* if this is the last one, save it for is-interface-up-to-date checking */
-    if (i == mi.nrext)
-      mixer->last_mixext = mix_ext;
-
-    mc = g_new0 (GstOss4MixerControl, 1);
-    mc->mixext = mix_ext;
-
-    /* both control_no and desc fields are pretty useless, ie. not always set,
-     * if ever, so not listed here */
-    GST_INFO ("Control %d", mix_ext.ctrl);
-    GST_INFO ("  name   : %s", mix_ext.extname);
-    GST_INFO ("  type   : %s (%d)", mixer_ext_type_get_name (mix_ext.type),
-        mix_ext.type);
-    GST_INFO ("  flags  : %s (0x%04x)",
-        mixer_ext_flags_get_string (mix_ext.flags), mix_ext.flags);
-    GST_INFO ("  parent : %d", mix_ext.parent);
-
-    if (!MIXEXT_IS_ROOT (mix_ext)) {
-      /* find parent (we assume it comes in the list before the child) */
-      for (l = controls; l != NULL; l = l->next) {
-        GstOss4MixerControl *parent_mc = (GstOss4MixerControl *) l->data;
-
-        if (parent_mc->mixext.ctrl == mix_ext.parent) {
-          mc->parent = parent_mc;
-          parent_mc->children = g_list_append (parent_mc->children, mc);
-          break;
-        }
-      }
-      if (mc->parent == NULL) {
-        GST_ERROR_OBJECT (mixer, "couldn't find parent for control %d", i);
-        g_free (mc);
-        continue;
-      }
-    } else if (root_mc == NULL) {
-      root_mc = mc;
-    } else {
-      GST_WARNING_OBJECT (mixer, "two root controls?!");
-    }
-
-    controls = g_list_prepend (controls, mc);
-  }
-
-#ifndef GST_DISABLE_GST_DEBUG
-  gst_oss4_mixer_control_dump_tree (root_mc, 0);
-#endif
-
-  return g_list_reverse (controls);
-
-/* ERRORS */
-no_mixerinfo:
-  {
-    GST_WARNING ("SNDCTL_MIXERINFO failed on mixer device %s: %s", mi.id,
-        g_strerror (errno));
-    return NULL;
-  }
-}
-
-static void
-gst_oss4_mixer_controls_guess_master (GstOss4Mixer * mixer,
-    const GList * controls)
-{
-  GstOss4MixerControl *master_mc = NULL;
-  const GList *l;
-
-  for (l = controls; l != NULL; l = l->next) {
-    GstOss4MixerControl *mc = (GstOss4MixerControl *) l->data;
-
-    /* do we need to check if it's a slider type here? */
-    if ((mc->mixext.flags & MIXF_PCMVOL)) {
-      GST_INFO_OBJECT (mixer, "First PCM control: %s", mc->mixext.extname);
-      master_mc = mc;
-      break;
-    }
-
-    if (((mc->mixext.flags & MIXF_MAINVOL)) && master_mc == NULL) {
-      GST_INFO_OBJECT (mixer, "First main volume control: %s",
-          mc->mixext.extname);
-      master_mc = mc;
-    }
-  }
-
-  if (master_mc != NULL)
-    master_mc->is_master = TRUE;
-}
-
-/* type: -1 for all types, otherwise just return siblings with requested type */
-static GList *
-gst_oss4_mixer_control_get_siblings (GstOss4MixerControl * mc, gint type)
-{
-  GList *s, *siblings = NULL;
-
-  if (mc->parent == NULL)
-    return NULL;
-
-  for (s = mc->parent->children; s != NULL; s = s->next) {
-    GstOss4MixerControl *sibling = (GstOss4MixerControl *) s->data;
-
-    if (mc != sibling && (type < 0 || sibling->mixext.type == type))
-      siblings = g_list_append (siblings, sibling);
-  }
-
-  return siblings;
-}
-
-static void
-gst_oss4_mixer_controls_find_sliders (GstOss4Mixer * mixer,
-    const GList * controls)
-{
-  const GList *l;
-
-  for (l = controls; l != NULL; l = l->next) {
-    GstOss4MixerControl *mc = (GstOss4MixerControl *) l->data;
-    GList *s, *siblings;
-
-    if (!MIXEXT_IS_SLIDER (mc->mixext) || mc->parent == NULL || mc->used)
-      continue;
-
-    mc->is_slider = TRUE;
-    mc->used = TRUE;
-
-    siblings = gst_oss4_mixer_control_get_siblings (mc, -1);
-
-    /* Note: the names can be misleading and may not reflect the actual
-     * hierarchy of the controls, e.g. it's possible that a slider is called
-     * connector.green and the mute control then connector.green.mute, but
-     * both controls are in fact siblings and both children of the group
-     * 'green' instead of mute being a child of connector.green as the naming
-     * would seem to suggest */
-    GST_LOG ("Slider: %s, parent=%s, %d siblings", mc->mixext.extname,
-        mc->parent->mixext.extname, g_list_length (siblings));
-
-    for (s = siblings; s != NULL; s = s->next) {
-      GstOss4MixerControl *sibling = (GstOss4MixerControl *) s->data;
-
-      GST_LOG ("    %s (%s)", sibling->mixext.extname,
-          mixer_ext_type_get_name (sibling->mixext.type));
-
-      if (sibling->mixext.type == MIXT_MUTE ||
-          g_str_has_suffix (sibling->mixext.extname, ".mute")) {
-        /* simple case: slider with single mute sibling. We assume the .mute
-         * suffix in the name won't change - can't really do much else anyway */
-        if (sibling->mixext.type == MIXT_ONOFF ||
-            sibling->mixext.type == MIXT_MUTE) {
-          GST_LOG ("    mute control for %s is %s", mc->mixext.extname,
-              sibling->mixext.extname);
-          mc->mute = sibling;
-          sibling->used = TRUE;
-        }
-        /* a group of .mute controls. We assume they are all switches here */
-        if (sibling->mixext.type == MIXT_GROUP) {
-          GList *m;
-
-          for (m = sibling->children; m != NULL; m = m->next) {
-            GstOss4MixerControl *grouped_sibling = m->data;
-
-            if (grouped_sibling->mixext.type == MIXT_ONOFF ||
-                grouped_sibling->mixext.type == MIXT_MUTE) {
-              GST_LOG ("    %s is grouped mute control for %s",
-                  grouped_sibling->mixext.extname, mc->mixext.extname);
-              mc->mute_group = g_list_append (mc->mute_group, grouped_sibling);
-            }
-          }
-
-          GST_LOG ("    %s has a group of %d mute controls",
-              mc->mixext.extname, g_list_length (mc->mute_group));
-
-          /* we don't mark the individual mute controls as used, only the
-           * group control, as we still want individual switches for the
-           * individual controls */
-          sibling->used = TRUE;
-        }
-      }
-    }
-    g_list_free (siblings);
-  }
-}
-
-/* should be called with the mixer object lock held because of the ioctl;
- * returns TRUE if the list was read the first time or modified */
-static gboolean
-gst_oss4_mixer_enum_control_update_enum_list (GstOss4Mixer * mixer,
-    GstOss4MixerControl * mc)
-{
-  oss_mixer_enuminfo ei = { 0, };
-  guint num_existing = 0;
-  int i;
-
-  /* count and existing values */
-  while (mc->enum_vals != NULL && mc->enum_vals[num_existing] != 0)
-    ++num_existing;
-
-  ei.dev = mc->mixext.dev;
-  ei.ctrl = mc->mixext.ctrl;
-
-  /* if we have create a generic list with numeric IDs already and the
-   * number of values hasn't changed, then there's not much to do here */
-  if (mc->no_list && mc->enum_vals != NULL &&
-      num_existing == mc->mixext.maxvalue) {
-    return FALSE;
-  }
-
-  /* if we have a list and it doesn't change, there's nothing to do either */
-  if (mc->enum_vals != NULL && mc->enum_version == 0)
-    return FALSE;
-
-  if (ioctl (mixer->fd, SNDCTL_MIX_ENUMINFO, &ei) == -1) {
-    g_free (mc->enum_vals);
-    mc->enum_vals = g_new0 (GQuark, mc->mixext.maxvalue + 1);
-
-    GST_DEBUG ("no enum info available, creating numeric values from 0-%d",
-        mc->mixext.maxvalue - 1);
-
-    /* "It is possible that some enum controls don't have any name list
-     * available. In this case the application should automatically generate
-     * list of numbers (0 to N-1)" */
-    for (i = 0; i < mc->mixext.maxvalue; ++i) {
-      gchar num_str[8];
-
-      g_snprintf (num_str, sizeof (num_str), "%d", i);
-      mc->enum_vals[i] = g_quark_from_string (num_str);
-    }
-    mc->enum_version = 0;       /* the only way to change is via maxvalue */
-  } else {
-    /* old list same as current list? */
-    if (mc->enum_vals != NULL && mc->enum_version == ei.version)
-      return FALSE;
-
-    /* no list yet, or the list has changed */
-    GST_LOG ("%s", (mc->enum_vals) ? "enum list has changed" : "reading list");
-    if (ei.nvalues != mc->mixext.maxvalue) {
-      GST_WARNING_OBJECT (mixer, "Enum: %s, nvalues %d != maxvalue %d",
-          mc->mixext.extname, ei.nvalues, mc->mixext.maxvalue);
-      mc->mixext.maxvalue = MIN (ei.nvalues, mc->mixext.maxvalue);
-    }
-
-    mc->mixext.maxvalue = MIN (mc->mixext.maxvalue, OSS_ENUM_MAXVALUE);
-
-    g_free (mc->enum_vals);
-    mc->enum_vals = g_new0 (GQuark, mc->mixext.maxvalue + 1);
-    for (i = 0; i < mc->mixext.maxvalue; ++i) {
-      GST_LOG ("  %s", ei.strings + ei.strindex[i]);
-      mc->enum_vals[i] =
-          g_quark_from_string (gst_oss4_mixer_control_get_translated_option
-          (ei.strings + ei.strindex[i]));
-    }
-  }
-
-  return TRUE;
-}
-
-static void
-gst_oss4_mixer_controls_find_enums (GstOss4Mixer * mixer,
-    const GList * controls)
-{
-  const GList *l;
-
-  for (l = controls; l != NULL; l = l->next) {
-    GstOss4MixerControl *mc = (GstOss4MixerControl *) l->data;
-
-    if (mc->mixext.type != MIXT_ENUM || mc->used)
-      continue;
-
-    mc->is_enum = TRUE;
-    mc->used = TRUE;
-
-    /* Note: enums are special: for most controls, the maxvalue is inclusive,
-     * but for enum controls it's actually exclusive (boggle), so that
-     * mixext.maxvalue = num_values */
-
-    GST_LOG ("Enum: %s, parent=%s, num_enums=%d", mc->mixext.extname,
-        mc->parent->mixext.extname, mc->mixext.maxvalue);
-
-    gst_oss4_mixer_enum_control_update_enum_list (mixer, mc);
-  }
-}
-
-static void
-gst_oss4_mixer_controls_find_switches (GstOss4Mixer * mixer,
-    const GList * controls)
-{
-  const GList *l;
-
-  for (l = controls; l != NULL; l = l->next) {
-    GstOss4MixerControl *mc = (GstOss4MixerControl *) l->data;
-
-    if (mc->used)
-      continue;
-
-    if (mc->mixext.type != MIXT_ONOFF && mc->mixext.type != MIXT_MUTE)
-      continue;
-
-    mc->is_switch = TRUE;
-    mc->used = TRUE;
-
-    GST_LOG ("Switch: %s, parent=%s", mc->mixext.extname,
-        mc->parent->mixext.extname);
-  }
-}
-
-static void
-gst_oss4_mixer_controls_find_virtual (GstOss4Mixer * mixer,
-    const GList * controls)
-{
-  const GList *l;
-
-  for (l = controls; l != NULL; l = l->next) {
-    GstOss4MixerControl *mc = (GstOss4MixerControl *) l->data;
-
-    /* or sscanf (mc->mixext.extname, "vmix%d-out.", &n) == 1 ? */
-    /* for now we just flag all virtual controls with managed labels, those
-     * are really more appropriate for a pavucontrol-type control thing than
-     * the (more hardware-oriented) mixer interface */
-    if (mc->mixext.id[0] == '@') {
-      mc->is_virtual = TRUE;
-      GST_LOG ("%s is virtual control with managed label", mc->mixext.extname);
-    }
-  }
-}
-
-static void
-gst_oss4_mixer_controls_dump_unused (GstOss4Mixer * mixer,
-    const GList * controls)
-{
-  const GList *l;
-
-  for (l = controls; l != NULL; l = l->next) {
-    GstOss4MixerControl *mc = (GstOss4MixerControl *) l->data;
-
-    if (mc->used)
-      continue;
-
-    switch (mc->mixext.type) {
-      case MIXT_DEVROOT:
-      case MIXT_GROUP:
-      case MIXT_MESSAGE:
-      case MIXT_MONOVU:
-      case MIXT_STEREOVU:
-      case MIXT_MONOPEAK:
-      case MIXT_STEREOPEAK:
-      case MIXT_MARKER:
-        continue;               /* not interested in these types of controls */
-      case MIXT_MONODB:
-      case MIXT_STEREODB:
-        GST_DEBUG ("obsolete control type %d", mc->mixext.type);
-        continue;
-      case MIXT_MONOSLIDER:
-      case MIXT_STEREOSLIDER:
-      case MIXT_SLIDER:
-      case MIXT_MONOSLIDER16:
-      case MIXT_STEREOSLIDER16:
-        /* this shouldn't happen */
-        GST_ERROR ("unused slider control?!");
-        continue;
-      case MIXT_VALUE:
-      case MIXT_HEXVALUE:
-        /* value entry, not sure what to do with that, skip for now */
-        continue;
-      case MIXT_ONOFF:
-      case MIXT_MUTE:
-      case MIXT_ENUM:
-      case MIXT_3D:
-      case MIXT_RADIOGROUP:
-        GST_DEBUG ("FIXME: handle %s %s",
-            mixer_ext_type_get_name (mc->mixext.type), mc->mixext.extname);
-        break;
-      default:
-        GST_WARNING ("unknown control type %d", mc->mixext.type);
-        continue;
-    }
-  }
-}
-
-static GList *
-gst_oss4_mixer_create_tracks (GstOss4Mixer * mixer, const GList * controls)
-{
-  const GList *c;
-  GList *tracks = NULL;
-
-  for (c = controls; c != NULL; c = c->next) {
-    GstOss4MixerControl *mc = (GstOss4MixerControl *) c->data;
-    GstMixerTrack *track = NULL;
-
-    if (mc->is_virtual)
-      continue;
-
-    if (mc->is_slider) {
-      track = gst_oss4_mixer_slider_new (mixer, mc);
-    } else if (mc->is_enum) {
-      track = gst_oss4_mixer_enum_new (mixer, mc);
-    } else if (mc->is_switch) {
-      track = gst_oss4_mixer_switch_new (mixer, mc);
-    }
-
-    if (track == NULL)
-      continue;
-
-    track->label = gst_oss4_mixer_control_get_translated_name (mc);
-    track->flags = 0;
-
-    GST_LOG ("translated label: %s [%s] = %s", track->label, mc->mixext.id,
-        track->label);
-
-    /* This whole 'a track is either INPUT or OUTPUT' model is just flawed,
-     * esp. if a slider's role can be changed on the fly, like when you change
-     * function of a connector. What should we do in that case? Change the flag
-     * and make the app rebuild the interface? Ignore it? */
-    if (mc->mixext.flags & (MIXF_MAINVOL | MIXF_PCMVOL)) {
-      track->flags = GST_MIXER_TRACK_OUTPUT | GST_MIXER_TRACK_WHITELIST;
-
-    } else if (mc->mixext.flags & MIXF_RECVOL) {
-      /* record gain whitelisted by default */
-      track->flags = GST_MIXER_TRACK_INPUT | GST_MIXER_TRACK_NO_RECORD |
-          GST_MIXER_TRACK_WHITELIST;
-
-    } else if (mc->mixext.flags & MIXF_MONVOL) {
-      /* monitor sources not whitelisted by default */
-      track->flags = GST_MIXER_TRACK_INPUT | GST_MIXER_TRACK_NO_RECORD;
-    }
-
-    /*
-     * The kernel may give us better clues about the scope of a control.
-     * If so, try to honor it.
-     */
-    switch (mc->mixext.desc & MIXEXT_SCOPE_MASK) {
-      case MIXEXT_SCOPE_INPUT:
-      case MIXEXT_SCOPE_RECSWITCH:
-        track->flags |= GST_MIXER_TRACK_INPUT | GST_MIXER_TRACK_NO_RECORD |
-            GST_MIXER_TRACK_WHITELIST;
-        break;
-      case MIXEXT_SCOPE_MONITOR:
-        /* don't whitelist monitor tracks by default */
-        track->flags |= GST_MIXER_TRACK_INPUT | GST_MIXER_TRACK_NO_RECORD;
-        break;
-      case MIXEXT_SCOPE_OUTPUT:
-        track->flags = GST_MIXER_TRACK_OUTPUT | GST_MIXER_TRACK_WHITELIST;
-        break;
-    }
-
-    if (mc->is_master) {
-      track->flags |= GST_MIXER_TRACK_OUTPUT;
-    }
-
-    if (mc->is_master)
-      track->flags |= GST_MIXER_TRACK_MASTER;
-
-    tracks = g_list_append (tracks, track);
-  }
-
-  return tracks;
-}
-
-static void
-gst_oss4_mixer_update_tracks (GstOss4Mixer * mixer)
-{
-  GList *controls, *tracks;
-
-  /* read and process controls */
-  controls = gst_oss4_mixer_get_controls (mixer);
-
-  gst_oss4_mixer_controls_guess_master (mixer, controls);
-
-  gst_oss4_mixer_controls_find_sliders (mixer, controls);
-
-  gst_oss4_mixer_controls_find_enums (mixer, controls);
-
-  gst_oss4_mixer_controls_find_switches (mixer, controls);
-
-  gst_oss4_mixer_controls_find_virtual (mixer, controls);
-
-  gst_oss4_mixer_controls_dump_unused (mixer, controls);
-
-  tracks = gst_oss4_mixer_create_tracks (mixer, controls);
-
-  /* free old tracks and controls */
-  gst_oss4_mixer_free_tracks (mixer);
-
-  /* replace old with new */
-  mixer->tracks = tracks;
-  mixer->controls = controls;
-}
-
-static const GList *
-gst_oss4_mixer_list_tracks (GstMixer * mixer_iface)
-{
-  GstOss4Mixer *mixer = GST_OSS4_MIXER (mixer_iface);
-
-  g_return_val_if_fail (mixer != NULL, NULL);
-  g_return_val_if_fail (GST_OSS4_MIXER_IS_OPEN (mixer), NULL);
-
-  GST_OBJECT_LOCK (mixer);
-
-  /* Do a read on the last control to check if the interface has changed */
-  if (!mixer->need_update && mixer->last_mixext.ctrl > 0) {
-    GstOss4MixerControl mc = { {0,}
-    ,
-    };
-    int val;
-
-    mc.mixext = mixer->last_mixext;
-    gst_oss4_mixer_get_control_val (mixer, &mc, &val);
-  }
-
-  if (mixer->need_update || mixer->tracks == NULL) {
-    gst_oss4_mixer_update_tracks (mixer);
-    mixer->need_update = FALSE;
-  }
-
-  GST_OBJECT_UNLOCK (mixer);
-
-  return (const GList *) mixer->tracks;
-}
-
-static void
-gst_oss4_mixer_set_volume (GstMixer * mixer, GstMixerTrack * track,
-    gint * volumes)
-{
-  GstOss4Mixer *oss;
-
-  g_return_if_fail (mixer != NULL);
-  g_return_if_fail (GST_IS_OSS4_MIXER (mixer));
-  g_return_if_fail (GST_OSS4_MIXER_IS_OPEN (mixer));
-  g_return_if_fail (gst_oss4_mixer_contains_track (mixer, track));
-  g_return_if_fail (volumes != NULL);
-
-  oss = GST_OSS4_MIXER (mixer);
-
-  GST_OBJECT_LOCK (oss);
-
-  if (GST_IS_OSS4_MIXER_SLIDER (track)) {
-    gst_oss4_mixer_slider_set_volume (GST_OSS4_MIXER_SLIDER (track), volumes);
-  }
-
-  GST_OBJECT_UNLOCK (oss);
-}
-
-static void
-gst_oss4_mixer_get_volume (GstMixer * mixer, GstMixerTrack * track,
-    gint * volumes)
-{
-  GstOss4Mixer *oss;
-
-  g_return_if_fail (mixer != NULL);
-  g_return_if_fail (GST_IS_OSS4_MIXER (mixer));
-  g_return_if_fail (GST_OSS4_MIXER_IS_OPEN (mixer));
-  g_return_if_fail (gst_oss4_mixer_contains_track (mixer, track));
-  g_return_if_fail (volumes != NULL);
-
-  oss = GST_OSS4_MIXER (mixer);
-
-  GST_OBJECT_LOCK (oss);
-
-  memset (volumes, 0, track->num_channels * sizeof (gint));
-
-  if (GST_IS_OSS4_MIXER_SWITCH (track)) {
-    gboolean enabled = FALSE;
-    gst_oss4_mixer_switch_get (GST_OSS4_MIXER_SWITCH (track), &enabled);
-  }
-  if (GST_IS_OSS4_MIXER_SLIDER (track)) {
-    gst_oss4_mixer_slider_get_volume (GST_OSS4_MIXER_SLIDER (track), volumes);
-  }
-
-  GST_OBJECT_UNLOCK (oss);
-}
-
-static void
-gst_oss4_mixer_set_record (GstMixer * mixer, GstMixerTrack * track,
-    gboolean record)
-{
-  GstOss4Mixer *oss;
-
-  g_return_if_fail (mixer != NULL);
-  g_return_if_fail (GST_IS_OSS4_MIXER (mixer));
-  g_return_if_fail (GST_OSS4_MIXER_IS_OPEN (mixer));
-  g_return_if_fail (gst_oss4_mixer_contains_track (mixer, track));
-
-  oss = GST_OSS4_MIXER (mixer);
-
-  GST_OBJECT_LOCK (oss);
-
-  if (GST_IS_OSS4_MIXER_SLIDER (track)) {
-    gst_oss4_mixer_slider_set_record (GST_OSS4_MIXER_SLIDER (track), record);
-  } else if (GST_IS_OSS4_MIXER_SWITCH (track)) {
-    if ((track->flags & GST_MIXER_TRACK_INPUT)) {
-      gst_oss4_mixer_switch_set (GST_OSS4_MIXER_SWITCH (track), record);
-    } else {
-      GST_WARNING_OBJECT (track, "set_record called on non-INPUT track");
-    }
-  }
-
-  GST_OBJECT_UNLOCK (oss);
-}
-
-static void
-gst_oss4_mixer_set_mute (GstMixer * mixer, GstMixerTrack * track, gboolean mute)
-{
-  GstOss4Mixer *oss;
-
-  g_return_if_fail (mixer != NULL);
-  g_return_if_fail (GST_IS_OSS4_MIXER (mixer));
-  g_return_if_fail (GST_OSS4_MIXER_IS_OPEN (mixer));
-  g_return_if_fail (gst_oss4_mixer_contains_track (mixer, track));
-
-  oss = GST_OSS4_MIXER (mixer);
-
-  GST_OBJECT_LOCK (oss);
-
-  if (GST_IS_OSS4_MIXER_SLIDER (track)) {
-    gst_oss4_mixer_slider_set_mute (GST_OSS4_MIXER_SLIDER (track), mute);
-  } else if (GST_IS_OSS4_MIXER_SWITCH (track)) {
-    gst_oss4_mixer_switch_set (GST_OSS4_MIXER_SWITCH (track), mute);
-  }
-
-  GST_OBJECT_UNLOCK (oss);
-}
-
-static void
-gst_oss4_mixer_set_option (GstMixer * mixer, GstMixerOptions * options,
-    gchar * value)
-{
-  GstOss4Mixer *oss;
-
-  g_return_if_fail (mixer != NULL);
-  g_return_if_fail (value != NULL);
-  g_return_if_fail (GST_IS_OSS4_MIXER (mixer));
-  g_return_if_fail (GST_OSS4_MIXER_IS_OPEN (mixer));
-  g_return_if_fail (GST_IS_OSS4_MIXER_ENUM (options));
-  g_return_if_fail (gst_oss4_mixer_contains_options (mixer, options));
-
-  oss = GST_OSS4_MIXER (mixer);
-
-  GST_OBJECT_LOCK (oss);
-
-  if (!gst_oss4_mixer_enum_set_option (GST_OSS4_MIXER_ENUM (options), value)) {
-    /* not much we can do here but wake up the watch thread early, so it
-     * can do its thing and post messages if anything has changed */
-    gst_oss4_mixer_wake_up_watch_task (oss);
-  }
-
-  GST_OBJECT_UNLOCK (oss);
-}
-
-static const gchar *
-gst_oss4_mixer_get_option (GstMixer * mixer, GstMixerOptions * options)
-{
-  GstOss4Mixer *oss;
-  const gchar *current_val;
-
-  g_return_val_if_fail (mixer != NULL, NULL);
-  g_return_val_if_fail (GST_IS_OSS4_MIXER (mixer), NULL);
-  g_return_val_if_fail (GST_OSS4_MIXER_IS_OPEN (mixer), NULL);
-  g_return_val_if_fail (GST_IS_OSS4_MIXER_ENUM (options), NULL);
-  g_return_val_if_fail (gst_oss4_mixer_contains_options (mixer, options), NULL);
-
-  oss = GST_OSS4_MIXER (mixer);
-
-  GST_OBJECT_LOCK (oss);
-
-  current_val = gst_oss4_mixer_enum_get_option (GST_OSS4_MIXER_ENUM (options));
-
-  if (current_val == NULL) {
-    /* not much we can do here but wake up the watch thread early, so it
-     * can do its thing and post messages if anything has changed */
-    gst_oss4_mixer_wake_up_watch_task (oss);
-  }
-
-  GST_OBJECT_UNLOCK (oss);
-
-  return current_val;
-}
-
-static GstMixerFlags
-gst_oss4_mixer_get_mixer_flags (GstMixer * mixer)
-{
-  return GST_MIXER_FLAG_AUTO_NOTIFICATIONS | GST_MIXER_FLAG_HAS_WHITELIST |
-      GST_MIXER_FLAG_GROUPING;
-}
-
-static void
-gst_oss4_mixer_interface_init (GstMixerInterface * iface)
-{
-  GST_MIXER_TYPE (iface) = GST_MIXER_HARDWARE;
-
-  iface->list_tracks = gst_oss4_mixer_list_tracks;
-  iface->set_volume = gst_oss4_mixer_set_volume;
-  iface->get_volume = gst_oss4_mixer_get_volume;
-  iface->set_mute = gst_oss4_mixer_set_mute;
-  iface->set_record = gst_oss4_mixer_set_record;
-  iface->set_option = gst_oss4_mixer_set_option;
-  iface->get_option = gst_oss4_mixer_get_option;
-  iface->get_mixer_flags = gst_oss4_mixer_get_mixer_flags;
-}
-
-/* Implement the horror that is GstImplementsInterface */
-
-static gboolean
-gst_oss4_mixer_supported (GstImplementsInterface * iface, GType iface_type)
-{
-  GstOss4Mixer *mixer;
-
-  g_return_val_if_fail (iface_type == GST_TYPE_MIXER, FALSE);
-
-  mixer = GST_OSS4_MIXER (iface);
-
-  return GST_OSS4_MIXER_IS_OPEN (mixer);
-}
-
-static void
-gst_oss4_mixer_implements_interface_init (GstImplementsInterfaceClass * klass)
-{
-  klass->supported = gst_oss4_mixer_supported;
-}
-
-static void
-gst_oss4_mixer_init_interfaces (GType type)
-{
-  static const GInterfaceInfo implements_iface_info = {
-    (GInterfaceInitFunc) gst_oss4_mixer_implements_interface_init,
-    NULL,
-    NULL,
-  };
-  static const GInterfaceInfo mixer_iface_info = {
-    (GInterfaceInitFunc) gst_oss4_mixer_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_oss4_add_property_probe_interface (type);
-}
diff --git a/sys/oss4/oss4-mixer.h b/sys/oss4/oss4-mixer.h
deleted file mode 100644 (file)
index 4eaff50..0000000
+++ /dev/null
@@ -1,128 +0,0 @@
-/* GStreamer OSS4 mixer implementation
- * Copyright (C) 2007-2008 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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifndef OSS4_MIXER_H
-#define OSS4_MIXER_H
-
-#include <gst/gst.h>
-
-#include "oss4-soundcard.h"
-
-#define GST_OSS4_MIXER(obj)              (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_OSS4_MIXER,GstOss4Mixer))
-#define GST_OSS4_MIXER_CAST(obj)         ((GstOss4Mixer *)(obj))
-#define GST_OSS4_MIXER_CLASS(klass)      (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_OSS4_MIXER,GstOss4MixerClass))
-#define GST_IS_OSS4_MIXER(obj)           (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_OSS4_MIXER))
-#define GST_IS_OSS4_MIXER_CLASS(klass)   (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_OSS4_MIXER))
-#define GST_TYPE_OSS4_MIXER              (gst_oss4_mixer_get_type())
-
-#define GST_OSS4_MIXER_IS_OPEN(obj)      (GST_OSS4_MIXER(obj)->fd != -1)
-
-typedef struct _GstOss4Mixer GstOss4Mixer;
-typedef struct _GstOss4MixerClass GstOss4MixerClass;
-
-struct _GstOss4Mixer {
-  GstElement            element;
-
-  /*< private >*/
-
-  /* element bits'n'bops */ 
-  gchar               * device;
-
-  /* mixer details */
-  gint                  fd;             /* file descriptor if open, or -1    */
-  gchar               * device_name;    /* device description, or NULL       */
-  gchar               * open_device;    /* the device we opened              */
-
-  GList               * tracks;         /* list of available tracks          */
-  GList               * controls;       /* list of available controls        */
-  gboolean              need_update;    /* re-read list of available tracks? */
-
-  oss_mixext            last_mixext;    /* we keep this around so we can
-                                         * easily check if the mixer
-                                         * interface has changed             */
-
-  GThread             * watch_thread;   /* thread watching for value changes */
-  GCond               * watch_cond;
-  gint                  watch_shutdown;
-  gint                  modify_counter; /* from MIXERINFO */
-
-  /* for property probe interface */
-  GList               * property_probe_list;
-};
-
-struct _GstOss4MixerClass {
-  GstElementClass       element_class;
-};
-
-/* helper struct holding info about one control */
-typedef struct _GstOss4MixerControl GstOss4MixerControl;
-
-struct _GstOss4MixerControl {
-  oss_mixext           mixext;
-  GstOss4MixerControl *parent;         /* NULL if root                         */
-  GstOss4MixerControl *mute;           /* sibling with mute function, or NULL  */
-  GList               *mute_group;     /* group of mute controls, or NULL      */
-  GList               *children;       /* GstOss4MixerControls (no ownership)  */
-
-  GQuark              *enum_vals;      /* 0-terminated array of values or NULL */
-  int                  enum_version;   /* 0 = list won't change                */
-
-  int                  last_val;       /* last value seen                      */
-
-  gboolean             is_virtual : 1; /* is a vmix control with dynamic label */
-  gboolean             is_master  : 1;
-  gboolean             is_slider  : 1; /* represent as slider                  */
-  gboolean             is_switch  : 1; /* represent as switch                  */
-  gboolean             is_enum    : 1; /* represent as combo/enumeration       */
-  gboolean             no_list    : 1; /* enumeration with no list available   */
-  gboolean             is_input   : 1; /* is an input-related control          */
-  gboolean             is_output  : 1; /* is an output-related control         */
-  gboolean             used       : 1; /* whether we know what to do with this */
-
-  gboolean             changed      : 1; /* transient flag used by watch thread */
-  gboolean             list_changed : 1; /* transient flag used by watch thread */
-};
-
-/* header says parent=-1 means root, but it can also be parent=ctrl */
-#define MIXEXT_IS_ROOT(me) ((me).parent == -1 || (me).parent == (me).ctrl)
-
-#define MIXEXT_IS_SLIDER(me) ((me).type == MIXT_MONOSLIDER ||            \
-    (me).type == MIXT_STEREOSLIDER || (me).type == MIXT_MONOSLIDER16 ||  \
-    (me).type == MIXT_STEREOSLIDER16 || (me).type == MIXT_SLIDER)
-
-#define MIXEXT_HAS_DESCRIPTION(me) (((me).flags & MIXF_DESCR) != 0)
-
-#define MIXEXT_ENUM_IS_AVAILABLE(me,num) \
-    (((me).enum_present[num/8]) & (1 << (num % 8)))
-
-
-GType     gst_oss4_mixer_get_type (void);
-
-gboolean  gst_oss4_mixer_get_control_val (GstOss4Mixer        * mixer,
-                                          GstOss4MixerControl * mc,
-                                          int                 * val);
-
-gboolean  gst_oss4_mixer_set_control_val (GstOss4Mixer        * mixer,
-                                          GstOss4MixerControl * mc,
-                                          int                   val);
-
-G_END_DECLS
-
-#endif /* OSS4_MIXER_H */
-
index 5674da5..c628af8 100644 (file)
@@ -27,9 +27,9 @@
 
 #include <gst/gst.h>
 
+
 #define NO_LEGACY_MIXER
 #include "oss4-audio.h"
-#include "oss4-mixer.h"
 #include "oss4-sink.h"
 #include "oss4-source.h"
 #include "oss4-soundcard.h"
@@ -43,6 +43,8 @@
 #include <errno.h>
 #include <string.h>
 
+#if 0
+
 GST_DEBUG_CATEGORY_EXTERN (oss4_debug);
 #define GST_CAT_DEFAULT oss4_debug
 
@@ -110,6 +112,8 @@ gst_oss4_property_probe_needs_probe (GstPropertyProbe * probe,
   return TRUE;
 }
 
+#endif
+
 static gint
 oss4_mixerinfo_priority_cmp (struct oss_mixerinfo *mi1,
     struct oss_mixerinfo *mi2)
@@ -282,9 +286,8 @@ gst_oss4_property_probe_get_audio_devices (GstObject * obj, int fd,
   return g_list_reverse (devices);
 }
 
-static GValueArray *
-gst_oss4_property_probe_get_values (GstPropertyProbe * probe,
-    guint prop_id, const GParamSpec * pspec)
+GValueArray *
+gst_oss4_property_probe_get_values (GstObject * probe, const gchar * pname)
 {
   struct oss_sysinfo si = { {0,}, };
   GValueArray *array = NULL;
@@ -292,8 +295,8 @@ gst_oss4_property_probe_get_values (GstPropertyProbe * probe,
   GList *devices, *l;
   int cap_mask, fd = -1;
 
-  if (!g_str_equal (pspec->name, "device")) {
-    G_OBJECT_WARN_INVALID_PROPERTY_ID (probe, prop_id, pspec);
+  if (!g_str_equal (pname, "device")) {
+    GST_WARNING_OBJECT (probe, "invalid property");
     return NULL;
   }
 
@@ -310,9 +313,6 @@ gst_oss4_property_probe_get_values (GstPropertyProbe * probe,
     GST_DEBUG_OBJECT (probe, "probing available input devices");
     cap_mask = PCM_CAP_INPUT;
     fd = GST_OSS4_SOURCE (probe)->fd;
-  } else if (GST_IS_OSS4_MIXER (probe)) {
-    fd = GST_OSS4_MIXER (probe)->fd;
-    cap_mask = 0;
   } else {
     GST_OBJECT_UNLOCK (obj);
     g_return_val_if_reached (NULL);
@@ -393,6 +393,7 @@ no_sysinfo:
   }
 }
 
+#if 0
 static void
 gst_oss4_property_probe_interface_init (GstPropertyProbeInterface * iface)
 {
@@ -414,3 +415,4 @@ gst_oss4_add_property_probe_interface (GType type)
   g_type_add_interface_static (type, GST_TYPE_PROPERTY_PROBE,
       &probe_iface_info);
 }
+#endif
index 707af02..8426bb6 100644 (file)
 #ifndef GST_OSS4_PROPERTY_PROBE_H
 #define GST_OSS4_PROPERTY_PROBE_H
 
+#if 0
+
 #include <gst/interfaces/propertyprobe.h>
 
 void      gst_oss4_add_property_probe_interface (GType type);
 
+#endif
+
 gboolean  gst_oss4_property_probe_find_device_name (GstObject   * obj,
                                                     int           fd,
                                                     const gchar * device_handle,
@@ -33,6 +37,9 @@ gboolean  gst_oss4_property_probe_find_device_name_nofd (GstObject   * obj,
                                                          const gchar * device_handle,
                                                          gchar      ** device_name);
 
+GValueArray *gst_oss4_property_probe_get_values (GstObject * obj, const gchar * pname);
+
+
 #endif /* GST_OSS4_PROPERTY_PROBE_H */
 
 
index fe1b2bb..ababa0e 100644 (file)
@@ -55,7 +55,7 @@
 #include <string.h>
 
 #include <gst/gst-i18n-plugin.h>
-#include <gst/interfaces/streamvolume.h>
+#include <gst/audio/streamvolume.h>
 
 #define NO_LEGACY_MIXER
 #include "oss4-audio.h"
@@ -66,7 +66,6 @@
 GST_DEBUG_CATEGORY_EXTERN (oss4sink_debug);
 #define GST_CAT_DEFAULT oss4sink_debug
 
-static void gst_oss4_sink_init_interfaces (GType type);
 static void gst_oss4_sink_dispose (GObject * object);
 static void gst_oss4_sink_finalize (GObject * object);
 
@@ -75,15 +74,15 @@ static void gst_oss4_sink_get_property (GObject * object, guint prop_id,
 static void gst_oss4_sink_set_property (GObject * object, guint prop_id,
     const GValue * value, GParamSpec * pspec);
 
-static GstCaps *gst_oss4_sink_getcaps (GstBaseSink * bsink);
+static GstCaps *gst_oss4_sink_getcaps (GstBaseSink * bsink, GstCaps * filter);
 static gboolean gst_oss4_sink_open (GstAudioSink * asink,
     gboolean silent_errors);
 static gboolean gst_oss4_sink_open_func (GstAudioSink * asink);
 static gboolean gst_oss4_sink_close (GstAudioSink * asink);
 static gboolean gst_oss4_sink_prepare (GstAudioSink * asink,
-    GstRingBufferSpec * spec);
+    GstAudioRingBufferSpec * spec);
 static gboolean gst_oss4_sink_unprepare (GstAudioSink * asink);
-static guint gst_oss4_sink_write (GstAudioSink * asink, gpointer data,
+static gint gst_oss4_sink_write (GstAudioSink * asink, gpointer data,
     guint length);
 static guint gst_oss4_sink_delay (GstAudioSink * asink);
 static void gst_oss4_sink_reset (GstAudioSink * asink);
@@ -104,8 +103,9 @@ enum
   PROP_LAST
 };
 
-GST_BOILERPLATE_FULL (GstOss4Sink, gst_oss4_sink, GstAudioSink,
-    GST_TYPE_AUDIO_SINK, gst_oss4_sink_init_interfaces);
+#define gst_oss4_sink_parent_class parent_class
+G_DEFINE_TYPE_WITH_CODE (GstOss4Sink, gst_oss4_sink,
+    GST_TYPE_AUDIO_SINK, G_IMPLEMENT_INTERFACE (GST_TYPE_STREAM_VOLUME, NULL));
 
 static void
 gst_oss4_sink_dispose (GObject * object)
@@ -121,27 +121,13 @@ gst_oss4_sink_dispose (GObject * object)
 }
 
 static void
-gst_oss4_sink_base_init (gpointer g_class)
-{
-  GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
-  GstPadTemplate *templ;
-
-  gst_element_class_set_static_metadata (element_class,
-      "OSS v4 Audio Sink", "Sink/Audio",
-      "Output to a sound card via OSS version 4",
-      "Tim-Philipp Müller <tim centricular net>");
-
-  templ = gst_pad_template_new ("sink", GST_PAD_SINK, GST_PAD_ALWAYS,
-      gst_oss4_audio_get_template_caps ());
-  gst_element_class_add_pad_template (element_class, templ);
-}
-
-static void
 gst_oss4_sink_class_init (GstOss4SinkClass * klass)
 {
   GstAudioSinkClass *audiosink_class = (GstAudioSinkClass *) klass;
   GstBaseSinkClass *basesink_class = (GstBaseSinkClass *) klass;
+  GstElementClass *gstelement_class = (GstElementClass *) klass;
   GObjectClass *gobject_class = (GObjectClass *) klass;
+  GstPadTemplate *templ;
 
   gobject_class->dispose = gst_oss4_sink_dispose;
   gobject_class->finalize = gst_oss4_sink_finalize;
@@ -180,10 +166,19 @@ gst_oss4_sink_class_init (GstOss4SinkClass * klass)
   audiosink_class->write = GST_DEBUG_FUNCPTR (gst_oss4_sink_write);
   audiosink_class->delay = GST_DEBUG_FUNCPTR (gst_oss4_sink_delay);
   audiosink_class->reset = GST_DEBUG_FUNCPTR (gst_oss4_sink_reset);
+
+  gst_element_class_set_static_metadata (gstelement_class,
+      "OSS v4 Audio Sink", "Sink/Audio",
+      "Output to a sound card via OSS version 4",
+      "Tim-Philipp Müller <tim centricular net>");
+
+  templ = gst_pad_template_new ("sink", GST_PAD_SINK, GST_PAD_ALWAYS,
+      gst_oss4_audio_get_template_caps ());
+  gst_element_class_add_pad_template (gstelement_class, templ);
 }
 
 static void
-gst_oss4_sink_init (GstOss4Sink * osssink, GstOss4SinkClass * klass)
+gst_oss4_sink_init (GstOss4Sink * osssink)
 {
   const gchar *device;
 
@@ -206,9 +201,6 @@ gst_oss4_sink_finalize (GObject * object)
   g_free (osssink->device);
   osssink->device = NULL;
 
-  g_list_free (osssink->property_probe_list);
-  osssink->property_probe_list = NULL;
-
   G_OBJECT_CLASS (parent_class)->finalize (object);
 }
 
@@ -383,7 +375,7 @@ gst_oss4_sink_get_property (GObject * object, guint prop_id,
 }
 
 static GstCaps *
-gst_oss4_sink_getcaps (GstBaseSink * bsink)
+gst_oss4_sink_getcaps (GstBaseSink * bsink, GstCaps * filter)
 {
   GstOss4Sink *oss;
   GstCaps *caps;
@@ -401,7 +393,16 @@ gst_oss4_sink_getcaps (GstBaseSink * bsink)
     }
   }
 
-  return caps;
+  if (filter && caps) {
+    GstCaps *intersection;
+
+    intersection =
+        gst_caps_intersect_full (filter, caps, GST_CAPS_INTERSECT_FIRST);
+    gst_caps_unref (caps);
+    return intersection;
+  } else {
+    return caps;
+  }
 }
 
 /* note: we must not take the object lock here unless we fix up get_property */
@@ -576,7 +577,7 @@ gst_oss4_sink_close (GstAudioSink * asink)
 }
 
 static gboolean
-gst_oss4_sink_prepare (GstAudioSink * asink, GstRingBufferSpec * spec)
+gst_oss4_sink_prepare (GstAudioSink * asink, GstAudioRingBufferSpec * spec)
 {
   GstOss4Sink *oss;
 
@@ -588,7 +589,8 @@ gst_oss4_sink_prepare (GstAudioSink * asink, GstRingBufferSpec * spec)
     return FALSE;
   }
 
-  oss->bytes_per_sample = spec->bytes_per_sample;
+  oss->bytes_per_sample = GST_AUDIO_INFO_BPF (&spec->info);
+
   return TRUE;
 }
 
@@ -619,7 +621,7 @@ couldnt_reopen:
   }
 }
 
-static guint
+static gint
 gst_oss4_sink_write (GstAudioSink * asink, gpointer data, guint length)
 {
   GstOss4Sink *oss;
@@ -681,15 +683,3 @@ gst_oss4_sink_reset (GstAudioSink * asink)
    * same device/fd from multiple threads and might deadlock or blow up in
    * other ways if we try an ioctl SNDCTL_DSP_HALT or similar */
 }
-
-static void
-gst_oss4_sink_init_interfaces (GType type)
-{
-  static const GInterfaceInfo svol_iface_info = {
-    NULL, NULL, NULL
-  };
-
-  g_type_add_interface_static (type, GST_TYPE_STREAM_VOLUME, &svol_iface_info);
-
-  gst_oss4_add_property_probe_interface (type);
-}
index b1489a7..4722195 100644 (file)
@@ -47,8 +47,6 @@ struct _GstOss4Sink {
   gint          mute_volume;
 
   GstCaps     * probed_caps;
-
-  GList       * property_probe_list;
 };
 
 struct _GstOss4SinkClass {
index 5e4d447..4b39ce4 100644 (file)
@@ -50,7 +50,6 @@
 #include <unistd.h>
 #include <string.h>
 
-#include <gst/interfaces/mixer.h>
 #include <gst/gst-i18n-plugin.h>
 
 #define NO_LEGACY_MIXER
@@ -74,10 +73,8 @@ enum
   PROP_DEVICE_NAME
 };
 
-static void gst_oss4_source_init_interfaces (GType type);
-
-GST_BOILERPLATE_FULL (GstOss4Source, gst_oss4_source, GstAudioSrc,
-    GST_TYPE_AUDIO_SRC, gst_oss4_source_init_interfaces);
+#define gst_oss4_source_parent_class parent_class
+G_DEFINE_TYPE (GstOss4Source, gst_oss4_source, GST_TYPE_AUDIO_SRC);
 
 static void gst_oss4_source_get_property (GObject * object, guint prop_id,
     GValue * value, GParamSpec * pspec);
@@ -87,14 +84,14 @@ static void gst_oss4_source_set_property (GObject * object, guint prop_id,
 static void gst_oss4_source_dispose (GObject * object);
 static void gst_oss4_source_finalize (GstOss4Source * osssrc);
 
-static GstCaps *gst_oss4_source_getcaps (GstBaseSrc * bsrc);
+static GstCaps *gst_oss4_source_getcaps (GstBaseSrc * bsrc, GstCaps * filter);
 
 static gboolean gst_oss4_source_open (GstAudioSrc * asrc,
     gboolean silent_errors);
 static gboolean gst_oss4_source_open_func (GstAudioSrc * asrc);
 static gboolean gst_oss4_source_close (GstAudioSrc * asrc);
 static gboolean gst_oss4_source_prepare (GstAudioSrc * asrc,
-    GstRingBufferSpec * spec);
+    GstAudioRingBufferSpec * spec);
 static gboolean gst_oss4_source_unprepare (GstAudioSrc * asrc);
 static guint gst_oss4_source_read (GstAudioSrc * asrc, gpointer data,
     guint length);
@@ -102,29 +99,16 @@ static guint gst_oss4_source_delay (GstAudioSrc * asrc);
 static void gst_oss4_source_reset (GstAudioSrc * asrc);
 
 static void
-gst_oss4_source_base_init (gpointer g_class)
-{
-  GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
-  GstPadTemplate *templ;
-
-  gst_element_class_set_static_metadata (element_class,
-      "OSS v4 Audio Source", "Source/Audio",
-      "Capture from a sound card via OSS version 4",
-      "Tim-Philipp Müller <tim centricular net>");
-
-  templ = gst_pad_template_new ("src", GST_PAD_SRC, GST_PAD_ALWAYS,
-      gst_oss4_audio_get_template_caps ());
-  gst_element_class_add_pad_template (element_class, templ);
-}
-
-static void
 gst_oss4_source_class_init (GstOss4SourceClass * klass)
 {
   GObjectClass *gobject_class;
+  GstElementClass *gstelement_class;
   GstBaseSrcClass *gstbasesrc_class;
   GstAudioSrcClass *gstaudiosrc_class;
+  GstPadTemplate *templ;
 
   gobject_class = (GObjectClass *) klass;
+  gstelement_class = (GstElementClass *) klass;
   gstbasesrc_class = (GstBaseSrcClass *) klass;
   gstaudiosrc_class = (GstAudioSrcClass *) klass;
 
@@ -153,10 +137,19 @@ gst_oss4_source_class_init (GstOss4SourceClass * klass)
       g_param_spec_string ("device-name", "Device name",
           "Human-readable name of the sound device", DEFAULT_DEVICE_NAME,
           G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
+
+  gst_element_class_set_static_metadata (gstelement_class,
+      "OSS v4 Audio Source", "Source/Audio",
+      "Capture from a sound card via OSS version 4",
+      "Tim-Philipp Müller <tim centricular net>");
+
+  templ = gst_pad_template_new ("src", GST_PAD_SRC, GST_PAD_ALWAYS,
+      gst_oss4_audio_get_template_caps ());
+  gst_element_class_add_pad_template (gstelement_class, templ);
 }
 
 static void
-gst_oss4_source_init (GstOss4Source * osssrc, GstOss4SourceClass * g_class)
+gst_oss4_source_init (GstOss4Source * osssrc)
 {
   const gchar *device;
 
@@ -176,9 +169,6 @@ gst_oss4_source_finalize (GstOss4Source * oss)
   g_free (oss->device);
   oss->device = NULL;
 
-  g_list_free (oss->property_probe_list);
-  oss->property_probe_list = NULL;
-
   G_OBJECT_CLASS (parent_class)->finalize ((GObject *) (oss));
 }
 
@@ -265,7 +255,7 @@ gst_oss4_source_get_property (GObject * object, guint prop_id,
 }
 
 static GstCaps *
-gst_oss4_source_getcaps (GstBaseSrc * bsrc)
+gst_oss4_source_getcaps (GstBaseSrc * bsrc, GstCaps * filter)
 {
   GstOss4Source *oss;
   GstCaps *caps;
@@ -283,7 +273,16 @@ gst_oss4_source_getcaps (GstBaseSrc * bsrc)
     }
   }
 
-  return caps;
+  if (filter && caps) {
+    GstCaps *intersection;
+
+    intersection =
+        gst_caps_intersect_full (filter, caps, GST_CAPS_INTERSECT_FIRST);
+    gst_caps_unref (caps);
+    return intersection;
+  } else {
+    return caps;
+  }
 }
 
 /* note: we must not take the object lock here unless we fix up get_property */
@@ -414,14 +413,6 @@ gst_oss4_source_open_func (GstAudioSrc * asrc)
   return gst_oss4_source_open (asrc, FALSE);
 }
 
-static void
-gst_oss4_source_free_mixer_tracks (GstOss4Source * oss)
-{
-  g_list_foreach (oss->tracks, (GFunc) g_object_unref, NULL);
-  g_list_free (oss->tracks);
-  oss->tracks = NULL;
-}
-
 static gboolean
 gst_oss4_source_close (GstAudioSrc * asrc)
 {
@@ -445,13 +436,11 @@ gst_oss4_source_close (GstAudioSrc * asrc)
   g_free (oss->device_name);
   oss->device_name = NULL;
 
-  gst_oss4_source_free_mixer_tracks (oss);
-
   return TRUE;
 }
 
 static gboolean
-gst_oss4_source_prepare (GstAudioSrc * asrc, GstRingBufferSpec * spec)
+gst_oss4_source_prepare (GstAudioSrc * asrc, GstAudioRingBufferSpec * spec)
 {
   GstOss4Source *oss;
 
@@ -463,7 +452,8 @@ gst_oss4_source_prepare (GstAudioSrc * asrc, GstRingBufferSpec * spec)
     return FALSE;
   }
 
-  oss->bytes_per_sample = spec->bytes_per_sample;
+  oss->bytes_per_sample = GST_AUDIO_INFO_BPF (&spec->info);
+
   return TRUE;
 }
 
@@ -555,442 +545,3 @@ gst_oss4_source_reset (GstAudioSrc * asrc)
    * same device/fd from multiple threads and might deadlock or blow up in
    * other ways if we try an ioctl SNDCTL_DSP_HALT or similar */
 }
-
-/* GstMixer interface, which we abuse here for input selection, because we
- * don't have a proper interface for that and because that's what
- * gnome-sound-recorder does. */
-
-/* GstMixerTrack is a plain GObject, so let's just use the GLib macro here */
-G_DEFINE_TYPE (GstOss4SourceInput, gst_oss4_source_input, GST_TYPE_MIXER_TRACK);
-
-static void
-gst_oss4_source_input_class_init (GstOss4SourceInputClass * klass)
-{
-  /* nothing to do here */
-}
-
-static void
-gst_oss4_source_input_init (GstOss4SourceInput * i)
-{
-  /* nothing to do here */
-}
-
-#if 0
-
-static void
-gst_ossmixer_ensure_track_list (GstOssMixer * mixer)
-{
-  gint i, master = -1;
-
-  g_return_if_fail (mixer->fd != -1);
-
-  if (mixer->tracklist)
-    return;
-
-  /* find master volume */
-  if (mixer->devmask & SOUND_MASK_VOLUME)
-    master = SOUND_MIXER_VOLUME;
-  else if (mixer->devmask & SOUND_MASK_PCM)
-    master = SOUND_MIXER_PCM;
-  else if (mixer->devmask & SOUND_MASK_SPEAKER)
-    master = SOUND_MIXER_SPEAKER;       /* doubtful... */
-  /* else: no master, so we won't set any */
-
-  /* build track list */
-  for (i = 0; i < SOUND_MIXER_NRDEVICES; i++) {
-    if (mixer->devmask & (1 << i)) {
-      GstMixerTrack *track;
-      gboolean input = FALSE, stereo = FALSE, record = FALSE;
-
-      /* track exists, make up capabilities */
-      if (MASK_BIT_IS_SET (mixer->stereomask, i))
-        stereo = TRUE;
-      if (MASK_BIT_IS_SET (mixer->recmask, i))
-        input = TRUE;
-      if (MASK_BIT_IS_SET (mixer->recdevs, i))
-        record = TRUE;
-
-      /* do we want mixer in our list? */
-      if (!((mixer->dir & GST_OSS_MIXER_CAPTURE && input == TRUE) ||
-              (mixer->dir & GST_OSS_MIXER_PLAYBACK && i != SOUND_MIXER_PCM)))
-        /* the PLAYBACK case seems hacky, but that's how 0.8 had it */
-        continue;
-
-      /* add track to list */
-      track = gst_ossmixer_track_new (mixer->fd, i, stereo ? 2 : 1,
-          (record ? GST_MIXER_TRACK_RECORD : 0) |
-          (input ? GST_MIXER_TRACK_INPUT :
-              GST_MIXER_TRACK_OUTPUT) |
-          ((master != i) ? 0 : GST_MIXER_TRACK_MASTER));
-      mixer->tracklist = g_list_append (mixer->tracklist, track);
-    }
-  }
-}
-
-/* unused with G_DISABLE_* */
-static G_GNUC_UNUSED gboolean
-gst_ossmixer_contains_track (GstOssMixer * mixer, GstOssMixerTrack * osstrack)
-{
-  const GList *item;
-
-  for (item = mixer->tracklist; item != NULL; item = item->next)
-    if (item->data == osstrack)
-      return TRUE;
-
-  return FALSE;
-}
-
-const GList *
-gst_ossmixer_list_tracks (GstOssMixer * mixer)
-{
-  gst_ossmixer_ensure_track_list (mixer);
-
-  return (const GList *) mixer->tracklist;
-}
-
-void
-gst_ossmixer_get_volume (GstOssMixer * mixer,
-    GstMixerTrack * track, gint * volumes)
-{
-  gint volume;
-  GstOssMixerTrack *osstrack = GST_OSSMIXER_TRACK (track);
-
-  g_return_if_fail (mixer->fd != -1);
-  g_return_if_fail (gst_ossmixer_contains_track (mixer, osstrack));
-
-  if (track->flags & GST_MIXER_TRACK_MUTE) {
-    volumes[0] = osstrack->lvol;
-    if (track->num_channels == 2) {
-      volumes[1] = osstrack->rvol;
-    }
-  } else {
-    /* get */
-    if (ioctl (mixer->fd, MIXER_READ (osstrack->track_num), &volume) < 0) {
-      g_warning ("Error getting recording device (%d) volume: %s",
-          osstrack->track_num, g_strerror (errno));
-      volume = 0;
-    }
-
-    osstrack->lvol = volumes[0] = (volume & 0xff);
-    if (track->num_channels == 2) {
-      osstrack->rvol = volumes[1] = ((volume >> 8) & 0xff);
-    }
-  }
-}
-
-void
-gst_ossmixer_set_mute (GstOssMixer * mixer, GstMixerTrack * track,
-    gboolean mute)
-{
-  int volume;
-  GstOssMixerTrack *osstrack = GST_OSSMIXER_TRACK (track);
-
-  g_return_if_fail (mixer->fd != -1);
-  g_return_if_fail (gst_ossmixer_contains_track (mixer, osstrack));
-
-  if (mute) {
-    volume = 0;
-  } else {
-    volume = (osstrack->lvol & 0xff);
-    if (MASK_BIT_IS_SET (mixer->stereomask, osstrack->track_num)) {
-      volume |= ((osstrack->rvol & 0xff) << 8);
-    }
-  }
-
-  if (ioctl (mixer->fd, MIXER_WRITE (osstrack->track_num), &volume) < 0) {
-    g_warning ("Error setting mixer recording device volume (0x%x): %s",
-        volume, g_strerror (errno));
-    return;
-  }
-
-  if (mute) {
-    track->flags |= GST_MIXER_TRACK_MUTE;
-  } else {
-    track->flags &= ~GST_MIXER_TRACK_MUTE;
-  }
-}
-#endif
-
-static gint
-gst_oss4_source_mixer_get_current_input (GstOss4Source * oss)
-{
-  int cur = -1;
-
-  if (ioctl (oss->fd, SNDCTL_DSP_GET_RECSRC, &cur) == -1 || cur < 0)
-    return -1;
-
-  return cur;
-}
-
-static const gchar *
-gst_oss4_source_mixer_update_record_flags (GstOss4Source * oss, gint cur_route)
-{
-  const gchar *cur_name = "";
-  GList *t;
-
-  for (t = oss->tracks; t != NULL; t = t->next) {
-    GstMixerTrack *track = t->data;
-
-    if (GST_OSS4_SOURCE_INPUT (track)->route == cur_route) {
-      if (!GST_MIXER_TRACK_HAS_FLAG (track, GST_MIXER_TRACK_RECORD)) {
-        track->flags |= GST_MIXER_TRACK_RECORD;
-        /* no point in sending a mixer-record-changes message here */
-      }
-      cur_name = track->label;
-    } else {
-      if (GST_MIXER_TRACK_HAS_FLAG (track, GST_MIXER_TRACK_RECORD)) {
-        track->flags &= ~GST_MIXER_TRACK_RECORD;
-        /* no point in sending a mixer-record-changes message here */
-      }
-    }
-  }
-
-  return cur_name;
-}
-
-static const GList *
-gst_oss4_source_mixer_list_tracks (GstMixer * mixer)
-{
-  oss_mixer_enuminfo names = { 0, };
-  GstOss4Source *oss;
-  const gchar *cur_name;
-  GList *tracks = NULL;
-  gint i, cur;
-
-  g_return_val_if_fail (mixer != NULL, NULL);
-  g_return_val_if_fail (GST_IS_OSS4_SOURCE (mixer), NULL);
-  g_return_val_if_fail (GST_OSS4_SOURCE_IS_OPEN (mixer), NULL);
-
-  oss = GST_OSS4_SOURCE (mixer);
-
-  if (oss->tracks != NULL && oss->tracks_static)
-    goto done;
-
-  if (ioctl (oss->fd, SNDCTL_DSP_GET_RECSRC_NAMES, &names) == -1)
-    goto get_recsrc_names_error;
-
-  oss->tracks_static = (names.version == 0);
-
-  GST_INFO_OBJECT (oss, "%d inputs (list is static: %s):", names.nvalues,
-      (oss->tracks_static) ? "yes" : "no");
-
-  for (i = 0; i < MIN (names.nvalues, OSS_ENUM_MAXVALUE + 1); ++i) {
-    GstMixerTrack *track;
-
-    track = g_object_new (GST_TYPE_OSS4_SOURCE_INPUT, NULL);
-    track->label = g_strdup (&names.strings[names.strindex[i]]);
-    track->flags = GST_MIXER_TRACK_INPUT;
-    track->num_channels = 2;
-    track->min_volume = 0;
-    track->max_volume = 100;
-    GST_OSS4_SOURCE_INPUT (track)->route = i;
-
-    GST_INFO_OBJECT (oss, " [%d] %s", i, track->label);
-    tracks = g_list_append (tracks, track);
-  }
-
-  gst_oss4_source_free_mixer_tracks (oss);
-  oss->tracks = tracks;
-
-done:
-
-  /* update RECORD flags */
-  cur = gst_oss4_source_mixer_get_current_input (oss);
-  cur_name = gst_oss4_source_mixer_update_record_flags (oss, cur);
-  GST_DEBUG_OBJECT (oss, "current input route: %d (%s)", cur, cur_name);
-
-  return (const GList *) oss->tracks;
-
-/* ERRORS */
-get_recsrc_names_error:
-  {
-    GST_WARNING_OBJECT (oss, "GET_RECSRC_NAMES failed: %s", g_strerror (errno));
-    return NULL;
-  }
-}
-
-static void
-gst_oss4_source_mixer_set_volume (GstMixer * mixer, GstMixerTrack * track,
-    gint * volumes)
-{
-  GstOss4Source *oss;
-  int new_vol, cur;
-
-  g_return_if_fail (mixer != NULL);
-  g_return_if_fail (track != NULL);
-  g_return_if_fail (GST_IS_MIXER_TRACK (track));
-  g_return_if_fail (GST_IS_OSS4_SOURCE (mixer));
-  g_return_if_fail (GST_OSS4_SOURCE_IS_OPEN (mixer));
-
-  oss = GST_OSS4_SOURCE (mixer);
-
-  cur = gst_oss4_source_mixer_get_current_input (oss);
-  if (cur != GST_OSS4_SOURCE_INPUT (track)->route) {
-    GST_DEBUG_OBJECT (oss, "track not selected input route, ignoring request");
-    return;
-  }
-
-  new_vol = (volumes[1] << 8) | volumes[0];
-  if (ioctl (oss->fd, SNDCTL_DSP_SETRECVOL, &new_vol) == -1) {
-    GST_WARNING_OBJECT (oss, "SETRECVOL failed: %s", g_strerror (errno));
-  }
-}
-
-static void
-gst_oss4_source_mixer_get_volume (GstMixer * mixer, GstMixerTrack * track,
-    gint * volumes)
-{
-  GstOss4Source *oss;
-  int cur;
-
-  g_return_if_fail (mixer != NULL);
-  g_return_if_fail (GST_IS_OSS4_SOURCE (mixer));
-  g_return_if_fail (GST_OSS4_SOURCE_IS_OPEN (mixer));
-
-  oss = GST_OSS4_SOURCE (mixer);
-
-  cur = gst_oss4_source_mixer_get_current_input (oss);
-  if (cur != GST_OSS4_SOURCE_INPUT (track)->route) {
-    volumes[0] = 0;
-    volumes[1] = 0;
-  } else {
-    int vol = -1;
-
-    if (ioctl (oss->fd, SNDCTL_DSP_GETRECVOL, &vol) == -1 || vol < 0) {
-      GST_WARNING_OBJECT (oss, "GETRECVOL failed: %s", g_strerror (errno));
-      volumes[0] = 100;
-      volumes[1] = 100;
-    } else {
-      volumes[0] = MIN (100, vol & 0xff);
-      volumes[1] = MIN (100, (vol >> 8) & 0xff);
-    }
-  }
-}
-
-static void
-gst_oss4_source_mixer_set_record (GstMixer * mixer, GstMixerTrack * track,
-    gboolean record)
-{
-  GstOss4Source *oss;
-  const gchar *cur_name;
-  gint cur;
-
-  g_return_if_fail (mixer != NULL);
-  g_return_if_fail (track != NULL);
-  g_return_if_fail (GST_IS_MIXER_TRACK (track));
-  g_return_if_fail (GST_IS_OSS4_SOURCE (mixer));
-  g_return_if_fail (GST_OSS4_SOURCE_IS_OPEN (mixer));
-
-  oss = GST_OSS4_SOURCE (mixer);
-
-  cur = gst_oss4_source_mixer_get_current_input (oss);
-
-  /* stop recording for an input that's not selected anyway => nothing to do */
-  if (!record && cur != GST_OSS4_SOURCE_INPUT (track)->route)
-    goto done;
-
-  /* select recording for an input that's already selected => nothing to do
-   * (or should we mess with the recording volume in this case maybe?) */
-  if (record && cur == GST_OSS4_SOURCE_INPUT (track)->route)
-    goto done;
-
-  /* make current input stop recording: we can't really make an input stop
-   * recording, we can only select an input FOR recording, so we'll just ignore
-   * all requests to stop for now */
-  if (!record) {
-    GST_WARNING_OBJECT (oss, "Can't un-select an input as such, only switch "
-        "to a different input source");
-    /* FIXME: set recording volume to 0 maybe? */
-  } else {
-    int new_route = GST_OSS4_SOURCE_INPUT (track)->route;
-
-    /* select this input for recording */
-
-    if (ioctl (oss->fd, SNDCTL_DSP_SET_RECSRC, &new_route) == -1) {
-      GST_WARNING_OBJECT (oss, "Could not select input %d for recording: %s",
-          new_route, g_strerror (errno));
-    } else {
-      cur = new_route;
-    }
-  }
-
-done:
-
-  cur_name = gst_oss4_source_mixer_update_record_flags (oss, cur);
-  GST_DEBUG_OBJECT (oss, "active input route: %d (%s)", cur, cur_name);
-}
-
-static void
-gst_oss4_source_mixer_set_mute (GstMixer * mixer, GstMixerTrack * track,
-    gboolean mute)
-{
-  g_return_if_fail (mixer != NULL);
-  g_return_if_fail (track != NULL);
-  g_return_if_fail (GST_IS_MIXER_TRACK (track));
-  g_return_if_fail (GST_IS_OSS4_SOURCE (mixer));
-  g_return_if_fail (GST_OSS4_SOURCE_IS_OPEN (mixer));
-
-  /* FIXME: implement gst_oss4_source_mixer_set_mute() - what to do here? */
-  /* oss4_mixer_set_mute (mixer->mixer, track, mute); */
-}
-
-static void
-gst_oss4_source_mixer_interface_init (GstMixerInterface * iface)
-{
-  GST_MIXER_TYPE (iface) = GST_MIXER_HARDWARE;
-
-  iface->list_tracks = gst_oss4_source_mixer_list_tracks;
-  iface->set_volume = gst_oss4_source_mixer_set_volume;
-  iface->get_volume = gst_oss4_source_mixer_get_volume;
-  iface->set_mute = gst_oss4_source_mixer_set_mute;
-  iface->set_record = gst_oss4_source_mixer_set_record;
-}
-
-/* Implement the horror that is GstImplementsInterface */
-
-static gboolean
-gst_oss4_source_mixer_supported (GstImplementsInterface * iface,
-    GType iface_type)
-{
-  GstOss4Source *oss;
-  gboolean is_open;
-
-  g_return_val_if_fail (GST_IS_OSS4_SOURCE (iface), FALSE);
-  g_return_val_if_fail (iface_type == GST_TYPE_MIXER, FALSE);
-
-  oss = GST_OSS4_SOURCE (iface);
-
-  GST_OBJECT_LOCK (oss);
-  is_open = GST_OSS4_SOURCE_IS_OPEN (iface);
-  GST_OBJECT_UNLOCK (oss);
-
-  return is_open;
-}
-
-static void
-gst_oss4_source_mixer_implements_interface_init (GstImplementsInterfaceClass *
-    klass)
-{
-  klass->supported = gst_oss4_source_mixer_supported;
-}
-
-static void
-gst_oss4_source_init_interfaces (GType type)
-{
-  static const GInterfaceInfo implements_iface_info = {
-    (GInterfaceInitFunc) gst_oss4_source_mixer_implements_interface_init,
-    NULL,
-    NULL,
-  };
-  static const GInterfaceInfo mixer_iface_info = {
-    (GInterfaceInitFunc) gst_oss4_source_mixer_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_oss4_add_property_probe_interface (type);
-}
index 3a86b43..f30021e 100644 (file)
@@ -22,7 +22,6 @@
 
 #include <gst/gst.h>
 #include <gst/audio/gstaudiosrc.h>
-#include <gst/interfaces/mixertrack.h>
 
 G_BEGIN_DECLS
 
@@ -46,13 +45,6 @@ struct _GstOss4Source {
   gint            bytes_per_sample;
 
   GstCaps       * probed_caps;
-
-  /* property probe interface */
-  GList         * property_probe_list;
-
-  /* mixer interface */
-  GList         * tracks;
-  gboolean        tracks_static;  /* FALSE if the list of inputs may change */
 };
 
 struct _GstOss4SourceClass {
@@ -61,28 +53,6 @@ struct _GstOss4SourceClass {
 
 GType  gst_oss4_source_get_type (void);
 
-/* our mixer track for input selection */
-#define GST_TYPE_OSS4_SOURCE_INPUT            (gst_oss4_source_input_get_type())
-#define GST_OSS4_SOURCE_INPUT(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_OSS4_SOURCE_INPUT,GstOss4SourceInput))
-#define GST_OSS4_SOURCE_INPUT_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_OSS4_SOURCE_INPUT,GstOss4SourceInputClass))
-#define GST_IS_OSS4_SOURCE_INPUT(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_OSS4_SOURCE_INPUT))
-#define GST_IS_OSS4_SOURCE_INPUT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_OSS4_SOURCE_INPUT))
-
-typedef struct _GstOss4SourceInput GstOss4SourceInput;
-typedef struct _GstOss4SourceInputClass GstOss4SourceInputClass;
-
-struct _GstOss4SourceInput {
-  GstMixerTrack mixer_track;
-
-  int           route; /* number for SNDCTL_DSP_SET_RECSRC etc. */
-};
-
-struct _GstOss4SourceInputClass {
-  GstMixerTrackClass mixer_track_class;
-};
-
-GType  gst_oss4_source_input_get_type (void);
-
 G_END_DECLS
 
 #endif /* GST_OSS4_SOURCE_H */