docs/plugins/gst-plugins-bad-plugins.args: Remove directsoundsink property doc as...
authorSébastien Moutte <sebastien@moutte.net>
Wed, 23 May 2007 22:44:12 +0000 (22:44 +0000)
committerSébastien Moutte <sebastien@moutte.net>
Wed, 23 May 2007 22:44:12 +0000 (22:44 +0000)
Original commit message from CVS:
* docs/plugins/gst-plugins-bad-plugins.args:
Remove directsoundsink property doc as this sink use the mixer
interface now.
* docs/plugins/gst-plugins-bad-plugins.interfaces:
Add interfaces implemented by Windows sinks.
* sys/directsound/gstdirectsoundsink.c:
* sys/directsound/gstdirectsoundsink.h:
Remove directsoundsink property  and implement the mixer interface.
* win32/vs6/gst_plugins_bad.dsw:
* win32/vs6/libgstdirectsound.dsp:
Update project files.
* gst-libs/gst/dshow/gstdshow.cpp:
* gst-libs/gst/dshow/gstdshow.h:
* gst-libs/gst/dshow/gstdshowfakesink.cpp:
* gst-libs/gst/dshow/gstdshowfakesink.h:
* gst-libs/gst/dshow/gstdshowfakesrc.cpp:
* gst-libs/gst/dshow/gstdshowfakesrc.h:
* gst-libs/gst/dshow/gstdshowinterface.cpp:
* gst-libs/gst/dshow/gstdshowinterface.h:
* win32/common/libgstdshow.def:
* win32/vs6/libgstdshow.dsp:
Add a new gst library which allow to create internal Direct Show
graph (pipelines) to wrap Windows sources, decoders or encoders.
It includes a DirectShow fake source and sink and utility functions.
* sys/dshowsrcwrapper/gstdshowaudiosrc.c:
* sys/dshowsrcwrapper/gstdshowaudiosrc.h:
* sys/dshowsrcwrapper/gstdshowsrcwrapper.c:
* sys/dshowsrcwrapper/gstdshowsrcwrapper.h:
* sys/dshowsrcwrapper/gstdshowvideosrc.c:
* sys/dshowsrcwrapper/gstdshowvideosrc.h:
* win32/vs6/libdshowsrcwrapper.dsp:
Add a new plugin to wrap DirectShow sources on Windows.
It gets data from any webcam, dv cam, micro. We could add
tv tunner card later.

sys/directsound/gstdirectsoundsink.c
sys/directsound/gstdirectsoundsink.h
win32/vs6/libgstdirectsound.dsp

index e0b262e..97127bd 100644 (file)
@@ -76,13 +76,8 @@ static void gst_directsound_sink_class_init (GstDirectSoundSinkClass * klass);
 static void gst_directsound_sink_init (GstDirectSoundSink * dsoundsink,
     GstDirectSoundSinkClass * g_class);
 static void gst_directsound_sink_finalise (GObject * object);
-static void gst_directsound_sink_set_property (GObject * object,
-    guint prop_id, const GValue * value, GParamSpec * pspec);
-static void gst_directsound_sink_get_property (GObject * object,
-    guint prop_id, GValue * value, GParamSpec * pspec);
 
 static GstCaps *gst_directsound_sink_getcaps (GstBaseSink * bsink);
-
 static gboolean gst_directsound_sink_prepare (GstAudioSink * asink,
     GstRingBufferSpec * spec);
 static gboolean gst_directsound_sink_unprepare (GstAudioSink * asink);
@@ -94,6 +89,12 @@ static guint gst_directsound_sink_write (GstAudioSink * asink, gpointer data,
 static guint gst_directsound_sink_delay (GstAudioSink * asink);
 static void gst_directsound_sink_reset (GstAudioSink * asink);
 
+/* interfaces */
+static void gst_directsound_sink_interfaces_init (GType type);
+static void
+gst_directsound_sink_implements_interface_init (GstImplementsInterfaceClass *
+    iface);
+static void gst_directsound_sink_mixer_interface_init (GstMixerClass * iface);
 
 static GstStaticPadTemplate directsoundsink_sink_factory =
     GST_STATIC_PAD_TEMPLATE ("sink",
@@ -110,22 +111,108 @@ static GstStaticPadTemplate directsoundsink_sink_factory =
         "depth = (int) 8, "
         "rate = (int) [ 1, MAX ], " "channels = (int) [ 1, 2 ]"));
 
-enum
+GST_BOILERPLATE_FULL (GstDirectSoundSink, gst_directsound_sink, GstAudioSink,
+    GST_TYPE_AUDIO_SINK, gst_directsound_sink_interfaces_init);
+
+/* interfaces stuff */
+static void
+gst_directsound_sink_interfaces_init (GType type)
+{
+  static const GInterfaceInfo implements_interface_info = {
+    (GInterfaceInitFunc) gst_directsound_sink_implements_interface_init,
+    NULL,
+    NULL,
+  };
+
+  static const GInterfaceInfo mixer_interface_info = {
+    (GInterfaceInitFunc) gst_directsound_sink_mixer_interface_init,
+    NULL,
+    NULL,
+  };
+
+  g_type_add_interface_static (type,
+      GST_TYPE_IMPLEMENTS_INTERFACE, &implements_interface_info);
+  g_type_add_interface_static (type, GST_TYPE_MIXER, &mixer_interface_info);
+}
+
+static gboolean
+gst_directsound_sink_interface_supported (GstImplementsInterface * iface,
+    GType iface_type)
 {
-  PROP_0,
-  PROP_ATTENUATION
-};
+  g_return_val_if_fail (iface_type == GST_TYPE_MIXER, FALSE);
+
+  /* for the sake of this example, we'll always support it. However, normally,
+   * you would check whether the device you've opened supports mixers. */
+  return TRUE;
+}
 
 static void
-_do_init (GType directsoundsink_type)
+gst_directsound_sink_implements_interface_init (GstImplementsInterfaceClass *
+    iface)
 {
-  GST_DEBUG_CATEGORY_INIT (directsoundsink_debug, "directsoundsink", 0,
-      "DirectSound sink");
+  iface->supported = gst_directsound_sink_interface_supported;
 }
 
-GST_BOILERPLATE_FULL (GstDirectSoundSink, gst_directsound_sink, GstAudioSink,
-    GST_TYPE_AUDIO_SINK, _do_init);
+/*
+ * This function returns the list of support tracks (inputs, outputs)
+ * on this element instance. Elements usually build this list during
+ * _init () or when going from NULL to READY.
+ */
+
+static const GList *
+gst_directsound_sink_mixer_list_tracks (GstMixer * mixer)
+{
+  GstDirectSoundSink *dsoundsink = GST_DIRECTSOUND_SINK (mixer);
 
+  return dsoundsink->tracks;
+}
+
+/*
+ * Set volume. volumes is an array of size track->num_channels, and
+ * each value in the array gives the wanted volume for one channel
+ * on the track.
+ */
+
+static void
+gst_directsound_sink_mixer_set_volume (GstMixer * mixer,
+    GstMixerTrack * track, gint * volumes)
+{
+  GstDirectSoundSink *dsoundsink = GST_DIRECTSOUND_SINK (mixer);
+
+  if (volumes[0] != dsoundsink->volume) {
+    dsoundsink->volume = volumes[0];
+
+    if (dsoundsink->pDSBSecondary) {
+      /* DirectSound is using attenuation in the following range 
+       * (DSBVOLUME_MIN=-10000, DSBVOLUME_MAX=0) */
+      glong ds_attenuation = DSBVOLUME_MIN + (dsoundsink->volume * 100);
+
+      IDirectSoundBuffer_SetVolume (dsoundsink->pDSBSecondary, ds_attenuation);
+    }
+  }
+}
+
+static void
+gst_directsound_sink_mixer_get_volume (GstMixer * mixer,
+    GstMixerTrack * track, gint * volumes)
+{
+  GstDirectSoundSink *dsoundsink = GST_DIRECTSOUND_SINK (mixer);
+
+  volumes[0] = dsoundsink->volume;
+}
+
+static void
+gst_directsound_sink_mixer_interface_init (GstMixerClass * iface)
+{
+  /* the mixer interface requires a definition of the mixer type:
+   * hardware or software? */
+  GST_MIXER_TYPE (iface) = GST_MIXER_SOFTWARE;
+
+  /* virtual function pointers */
+  iface->list_tracks = gst_directsound_sink_mixer_list_tracks;
+  iface->set_volume = gst_directsound_sink_mixer_set_volume;
+  iface->get_volume = gst_directsound_sink_mixer_get_volume;
+}
 
 static void
 gst_directsound_sink_finalise (GObject * object)
@@ -134,6 +221,12 @@ gst_directsound_sink_finalise (GObject * object)
 
   g_mutex_free (dsoundsink->dsound_lock);
 
+  if (dsoundsink->tracks) {
+    g_list_foreach (dsoundsink->tracks, (GFunc) g_object_unref, NULL);
+    g_list_free (dsoundsink->tracks);
+    dsoundsink->tracks = NULL;
+  }
+
   G_OBJECT_CLASS (parent_class)->finalize (object);
 }
 
@@ -162,13 +255,12 @@ gst_directsound_sink_class_init (GstDirectSoundSinkClass * klass)
   gstbaseaudiosink_class = (GstBaseAudioSinkClass *) klass;
   gstaudiosink_class = (GstAudioSinkClass *) klass;
 
+  GST_DEBUG_CATEGORY_INIT (directsoundsink_debug, "directsoundsink", 0,
+      "DirectSound sink");
+
   parent_class = g_type_class_peek_parent (klass);
 
   gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_directsound_sink_finalise);
-  gobject_class->get_property =
-      GST_DEBUG_FUNCPTR (gst_directsound_sink_get_property);
-  gobject_class->set_property =
-      GST_DEBUG_FUNCPTR (gst_directsound_sink_set_property);
 
   gstbasesink_class->get_caps =
       GST_DEBUG_FUNCPTR (gst_directsound_sink_getcaps);
@@ -182,69 +274,28 @@ gst_directsound_sink_class_init (GstDirectSoundSinkClass * klass)
   gstaudiosink_class->write = GST_DEBUG_FUNCPTR (gst_directsound_sink_write);
   gstaudiosink_class->delay = GST_DEBUG_FUNCPTR (gst_directsound_sink_delay);
   gstaudiosink_class->reset = GST_DEBUG_FUNCPTR (gst_directsound_sink_reset);
-
-  g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_ATTENUATION,
-      g_param_spec_long ("attenuation", "Attenuation of the sound",
-          "The attenuation for the directsound buffer (default is 0 so the directsound buffer will not be attenuated)",
-          -10000, 0, 0, G_PARAM_READWRITE));
-}
-
-static void
-gst_directsound_sink_set_property (GObject * object, guint prop_id,
-    const GValue * value, GParamSpec * pspec)
-{
-  GstDirectSoundSink *dsoundsink;
-
-  dsoundsink = GST_DIRECTSOUND_SINK (object);
-
-  switch (prop_id) {
-    case PROP_ATTENUATION:
-    {
-      glong attenuation = g_value_get_long (value);
-
-      if (attenuation != dsoundsink->attenuation) {
-        dsoundsink->attenuation = attenuation;
-
-        if (dsoundsink->pDSBSecondary)
-          IDirectSoundBuffer_SetVolume (dsoundsink->pDSBSecondary,
-              dsoundsink->attenuation);
-      }
-
-      break;
-    }
-    default:
-      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-      break;
-  }
-}
-
-static void
-gst_directsound_sink_get_property (GObject * object, guint prop_id,
-    GValue * value, GParamSpec * pspec)
-{
-  GstDirectSoundSink *dsoundsink;
-
-  dsoundsink = GST_DIRECTSOUND_SINK (object);
-
-  switch (prop_id) {
-    case PROP_ATTENUATION:
-      g_value_set_long (value, dsoundsink->attenuation);
-      break;
-    default:
-      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-      break;
-  }
 }
 
 static void
 gst_directsound_sink_init (GstDirectSoundSink * dsoundsink,
     GstDirectSoundSinkClass * g_class)
 {
+  GstMixerTrack *track = NULL;
+
+  dsoundsink->tracks = NULL;
+  track = g_object_new (GST_TYPE_MIXER_TRACK, NULL);
+  track->label = g_strdup ("DSoundTrack");
+  track->num_channels = 2;
+  track->min_volume = 0;
+  track->max_volume = 100;
+  track->flags = GST_MIXER_TRACK_OUTPUT;
+  dsoundsink->tracks = g_list_append (dsoundsink->tracks, track);
+
   dsoundsink->pDS = NULL;
   dsoundsink->pDSBSecondary = NULL;
   dsoundsink->current_circular_offset = 0;
   dsoundsink->buffer_size = DSBSIZE_MIN;
-  dsoundsink->attenuation = 0;
+  dsoundsink->volume = 100;
   dsoundsink->dsound_lock = g_mutex_new ();
   dsoundsink->first_buffer_after_reset = FALSE;
 }
@@ -335,10 +386,6 @@ gst_directsound_sink_prepare (GstAudioSink * asink, GstRingBufferSpec * spec)
     return FALSE;
   }
 
-  if (dsoundsink->attenuation != 0)
-    IDirectSoundBuffer_SetVolume (dsoundsink->pDSBSecondary,
-        dsoundsink->attenuation);
-
   return TRUE;
 }
 
index ea7ccbd..6acf92b 100644 (file)
@@ -30,6 +30,7 @@
 
 #include <gst/gst.h>
 #include <gst/audio/gstaudiosink.h>
+#include <gst/interfaces/mixer.h>
 
 #include <windows.h>
 #include <dxerr9.h>
@@ -51,20 +52,27 @@ struct _GstDirectSoundSink
 {
   GstAudioSink sink;
 
+  /* directsound object interface pointer */
   LPDIRECTSOUND pDS;
 
+  /* directsound sound object interface pointer */
   LPDIRECTSOUNDBUFFER pDSBSecondary;
 
-  /*DirectSound buffer size */
+  /* directSound buffer size */
   guint buffer_size;
 
-  /*Offset of the circular buffer where we must write next */
+  /* offset of the circular buffer where we must write next */
   guint current_circular_offset;
 
   guint bytes_per_sample;
 
-  glong attenuation;
+  /* current volume setup by mixer interface */
+  glong volume;
 
+  /* tracks list of our mixer interface implementation */
+  GList *tracks;
+
+  /* lock used to protect writes and resets */
   GMutex *dsound_lock;
 
   gboolean first_buffer_after_reset;
index e763d48..e6c3737 100644 (file)
@@ -53,7 +53,7 @@ BSC32=bscmake.exe
 # ADD BSC32 /nologo
 LINK32=link.exe
 # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
-# ADD LINK32 glib-2.0.lib gobject-2.0.lib libgstaudio-0.10.lib libgstreamer-0.10.lib libgstbase-0.10.lib dsound.lib dxerr9.lib user32.lib /nologo /dll /machine:I386 /libpath:"../../../gstreamer/win32/vs6/release" /libpath:"../../../gst-plugins-base/win32/vs6/release" /libpath:"./release"
+# ADD LINK32 glib-2.0.lib gobject-2.0.lib libgstaudio-0.10.lib libgstreamer-0.10.lib libgstbase-0.10.lib libgstinterfaces-0.10.lib dsound.lib dxerr9.lib user32.lib /nologo /dll /machine:I386 /libpath:"../../../gstreamer/win32/vs6/release" /libpath:"../../../gst-plugins-base/win32/vs6/release" /libpath:"./release"
 # Begin Special Build Tool
 TargetPath=.\Release\libgstdirectsound.dll
 SOURCE="$(InputPath)"
@@ -84,7 +84,7 @@ BSC32=bscmake.exe
 # ADD BSC32 /nologo
 LINK32=link.exe
 # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 glib-2.0D.lib gobject-2.0D.lib libgstaudio-0.10.lib libgstreamer-0.10.lib libgstbase-0.10.lib dsound.lib dxerr9.lib user32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept /libpath:"../../../gstreamer/win32/vs6/debug" /libpath:"../../../gst-plugins-base/win32/vs6/debug" /libpath:"./debug"
+# ADD LINK32 glib-2.0D.lib gobject-2.0D.lib libgstaudio-0.10.lib libgstreamer-0.10.lib libgstbase-0.10.lib libgstinterfaces-0.10.lib dsound.lib dxerr9.lib user32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept /libpath:"../../../gstreamer/win32/vs6/debug" /libpath:"../../../gst-plugins-base/win32/vs6/debug" /libpath:"./debug"
 # SUBTRACT LINK32 /incremental:no
 # Begin Special Build Tool
 TargetPath=.\Debug\libgstdirectsound.dll