Index: gstautoaudiosink.c
===================================================================
RCS file: /cvs/gstreamer/gst-plugins-good/gst/autodetect/gstautoaudiosink.c,v
retrieving revision 1.17
diff -u -p -r1.17 gstautoaudiosink.c
--- gstautoaudiosink.c	25 Apr 2006 21:39:42 -0000	1.17
+++ gstautoaudiosink.c	12 May 2006 14:40:00 -0000
@@ -31,7 +31,7 @@
  * <title>Example launch line</title>
  * <para>
  * <programlisting>
- * gst-launch -v -m audiotestsrc ! autoaudiosink
+ * gst-launch -v -m audiotestsrc ! audioconvert ! autoaudiosink
  * </programlisting>
  * </para>
  * </refsect2>
@@ -46,9 +46,21 @@
 #include "gstautoaudiosink.h"
 #include "gstautodetect.h"
 
+enum
+{
+  ARG_0,
+  ARG_FAIL_SILENTLY
+};
+
+#define DEFAULT_FAIL_SILENTLY FALSE
+
 static GstStateChangeReturn
 gst_auto_audio_sink_change_state (GstElement * element,
     GstStateChange transition);
+static void gst_auto_audio_sink_set_property (GObject * object, guint prop_id,
+    const GValue * value, GParamSpec * pspec);
+static void gst_auto_audio_sink_get_property (GObject * object, guint prop_id,
+    GValue * value, GParamSpec * pspec);
 
 GST_BOILERPLATE (GstAutoAudioSink, gst_auto_audio_sink, GstBin, GST_TYPE_BIN);
 
@@ -75,6 +87,15 @@ static void
 gst_auto_audio_sink_class_init (GstAutoAudioSinkClass * klass)
 {
   GstElementClass *eklass = GST_ELEMENT_CLASS (klass);
+  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+
+  gobject_class->set_property = gst_auto_audio_sink_set_property;
+  gobject_class->get_property = gst_auto_audio_sink_get_property;
+
+  g_object_class_install_property (gobject_class, ARG_FAIL_SILENTLY,
+      g_param_spec_boolean ("fail-silently", "Fail silently",
+          "Do not throw an error and use a fake sink instead if no working "
+          "audio sink can be found", DEFAULT_FAIL_SILENTLY, G_PARAM_READWRITE));
 
   eklass->change_state = GST_DEBUG_FUNCPTR (gst_auto_audio_sink_change_state);
 }
@@ -113,6 +134,8 @@ gst_auto_audio_sink_init (GstAutoAudioSi
   gst_auto_audio_sink_reset (sink);
 
   GST_OBJECT_FLAG_SET (sink, GST_ELEMENT_IS_SINK);
+
+  sink->fail_silently = DEFAULT_FAIL_SILENTLY;
 }
 
 static gboolean
@@ -169,7 +192,6 @@ gst_auto_audio_sink_find_best (GstAutoAu
    * - soundserversinks should only be chosen if already running, or if
    *    the user explicitly wants this to run... That is not easy.
    */
-
   while (1) {
     GST_DEBUG_OBJECT (sink, "Trying to find %s",
         ss ? "soundservers" : "audio devices");
@@ -235,6 +257,14 @@ gst_auto_audio_sink_find_best (GstAutoAu
 done:
   GST_DEBUG_OBJECT (sink, "done trying");
   if (!choice) {
+    if (sink->fail_silently) {
+      GST_DEBUG_OBJECT (sink, "no audio sink found, using fakesink!");
+      choice = gst_element_factory_make ("fakesink", "actual-sink");
+      g_object_set (choice, "sync", TRUE, NULL);
+      gst_element_set_state (choice, GST_STATE_READY);
+      return choice;
+    }
+
     if (errors) {
       /* FIXME: we forward the first error for now; but later on it might make
        * sense to actually analyse them */
@@ -287,6 +317,42 @@ gst_auto_audio_sink_detect (GstAutoAudio
   return TRUE;
 }
 
+static void
+gst_auto_audio_sink_set_property (GObject * object, guint prop_id,
+    const GValue * value, GParamSpec * pspec)
+{
+  GstAutoAudioSink *sink = GST_AUTO_AUDIO_SINK (object);
+
+  GST_OBJECT_LOCK (sink);
+  switch (prop_id) {
+    case ARG_FAIL_SILENTLY:
+      sink->fail_silently = g_value_get_boolean (value);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+  }
+  GST_OBJECT_UNLOCK (sink);
+}
+
+static void
+gst_auto_audio_sink_get_property (GObject * object, guint prop_id,
+    GValue * value, GParamSpec * pspec)
+{
+  GstAutoAudioSink *sink = GST_AUTO_AUDIO_SINK (object);
+
+  GST_OBJECT_LOCK (sink);
+  switch (prop_id) {
+    case ARG_FAIL_SILENTLY:
+      g_value_set_boolean (value, sink->fail_silently);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+  }
+  GST_OBJECT_UNLOCK (sink);
+}
+
 static GstStateChangeReturn
 gst_auto_audio_sink_change_state (GstElement * element,
     GstStateChange transition)
Index: gstautoaudiosink.h
===================================================================
RCS file: /cvs/gstreamer/gst-plugins-good/gst/autodetect/gstautoaudiosink.h,v
retrieving revision 1.4
diff -u -p -r1.4 gstautoaudiosink.h
--- gstautoaudiosink.h	6 Dec 2005 19:44:51 -0000	1.4
+++ gstautoaudiosink.h	12 May 2006 14:40:00 -0000
@@ -31,18 +31,18 @@ G_BEGIN_DECLS
                                GstAutoAudioSink))
 #define GST_AUTO_AUDIO_SINK_CLASS(klass) \
   (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_AUTO_AUDIO_SINK, \
-                            GstAutoAudioSink))
+                            GstAutoAudioSinkClass))
 #define GST_IS_AUTO_AUDIO_SINK(obj) \
   (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_AUTO_AUDIO_SINK))
-#define GST_IS_AUTO_AUDIO_SINK_CLASS(obj) \
+#define GST_IS_AUTO_AUDIO_SINK_CLASS(klass) \
   (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_AUTO_AUDIO_SINK))
 
 typedef struct _GstAutoAudioSink {
   GstBin parent;
 
-  /* explicit pointers to stuff used */
-  GstPad *pad;
-  GstElement *kid;
+  GstPad      *pad;
+  GstElement  *kid;
+  gboolean     fail_silently;
 } GstAutoAudioSink;
 
 typedef struct _GstAutoAudioSinkClass {
