summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
Diffstat (limited to 'sys')
-rw-r--r--sys/directdraw/gstdirectdrawsink.c10
-rwxr-xr-x[-rw-r--r--]sys/directsound/gstdirectsoundsrc.c1179
-rw-r--r--[-rwxr-xr-x]sys/dshowsrcwrapper/Makefile.am0
-rw-r--r--[-rwxr-xr-x]sys/dshowsrcwrapper/gstdshow.cpp15
-rw-r--r--[-rwxr-xr-x]sys/dshowsrcwrapper/gstdshow.h3
-rw-r--r--[-rwxr-xr-x]sys/dshowsrcwrapper/gstdshowaudiosrc.cpp23
-rw-r--r--[-rwxr-xr-x]sys/dshowsrcwrapper/gstdshowaudiosrc.h0
-rw-r--r--[-rwxr-xr-x]sys/dshowsrcwrapper/gstdshowfakesink.cpp0
-rw-r--r--[-rwxr-xr-x]sys/dshowsrcwrapper/gstdshowfakesink.h0
-rw-r--r--[-rwxr-xr-x]sys/dshowsrcwrapper/gstdshowsrcwrapper.cpp0
-rw-r--r--[-rwxr-xr-x]sys/dshowsrcwrapper/gstdshowvideosrc.cpp229
-rw-r--r--[-rwxr-xr-x]sys/dshowsrcwrapper/gstdshowvideosrc.h15
12 files changed, 857 insertions, 617 deletions
diff --git a/sys/directdraw/gstdirectdrawsink.c b/sys/directdraw/gstdirectdrawsink.c
index 538227de..bb0332f8 100644
--- a/sys/directdraw/gstdirectdrawsink.c
+++ b/sys/directdraw/gstdirectdrawsink.c
@@ -961,10 +961,12 @@ gst_directdraw_sink_show_frame (GstBaseSink * bsink, GstBuffer * buf)
/* Write each line respecting the destination surface pitch */
data = surf_desc.lpSurface;
- src_pitch = GST_BUFFER_SIZE (buf) / ddrawsink->video_height;
- for (line = 0; line < surf_desc.dwHeight; line++) {
- memcpy (data, GST_BUFFER_DATA (buf) + (line * src_pitch), src_pitch);
- data += surf_desc.lPitch;
+ if (ddrawsink->video_height) {
+ src_pitch = GST_BUFFER_SIZE (buf) / ddrawsink->video_height;
+ for (line = 0; line < surf_desc.dwHeight; line++) {
+ memcpy (data, GST_BUFFER_DATA (buf) + (line * src_pitch), src_pitch);
+ data += surf_desc.lPitch;
+ }
}
/* Unlock the surface */
diff --git a/sys/directsound/gstdirectsoundsrc.c b/sys/directsound/gstdirectsoundsrc.c
index 429d6b85..fce9d5c8 100644..100755
--- a/sys/directsound/gstdirectsoundsrc.c
+++ b/sys/directsound/gstdirectsoundsrc.c
@@ -1,587 +1,678 @@
-/*
- * GStreamer
- * Copyright 2005 Thomas Vander Stichele <thomas@apestaart.org>
- * Copyright 2005 Ronald S. Bultje <rbultje@ronald.bitfreak.net>
- * Copyright 2005 Sébastien Moutte <sebastien@moutte.net>
- * Copyright 2006 Joni Valtanen <joni.valtanen@movial.fi>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Alternatively, the contents of this file may be used under the
- * GNU Lesser General Public License Version 2.1 (the "LGPL"), in
- * which case the following provisions apply instead of the ones
- * mentioned above:
- *
- * 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.
- */
-
-/*
- TODO: add device selection and check rate etc.
-*/
-
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif /* */
-
-#include <gst/gst.h>
-#include <gst/audio/gstbaseaudiosrc.h>
-
-#include "gstdirectsoundsrc.h"
-
-#include <windows.h>
-#include <dsound.h>
- GST_DEBUG_CATEGORY_STATIC (directsoundsrc_debug);
-
-#define GST_CAT_DEFAULT directsoundsrc_debug
- static GstElementDetails gst_directsound_src_details =
- GST_ELEMENT_DETAILS ("Audio Source (DIRECTCSOUND)", "Source/Audio",
- "Capture from a soundcard via DIRECTSOUND",
- "Joni Valtanen <joni.valtanen@movial.fi>");
-
-/* defaults here */
-#define DEFAULT_DEVICE 0
-
-/* properties */
- enum
-{ PROP_0, PROP_DEVICE
+/*
+ * GStreamer
+ * Copyright 2005 Thomas Vander Stichele <thomas@apestaart.org>
+ * Copyright 2005 Ronald S. Bultje <rbultje@ronald.bitfreak.net>
+ * Copyright 2005 Sébastien Moutte <sebastien@moutte.net>
+ * Copyright 2006 Joni Valtanen <joni.valtanen@movial.fi>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Alternatively, the contents of this file may be used under the
+ * GNU Lesser General Public License Version 2.1 (the "LGPL"), in
+ * which case the following provisions apply instead of the ones
+ * mentioned above:
+ *
+ * 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.
+ */
+
+/*
+ TODO: add device selection and check rate etc.
+*/
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <gst/gst.h>
+#include <gst/audio/gstbaseaudiosrc.h>
+
+#include "gstdirectsoundsrc.h"
+
+#include <windows.h>
+#include <dsound.h>
+
+GST_DEBUG_CATEGORY_STATIC (directsoundsrc_debug);
+#define GST_CAT_DEFAULT directsoundsrc_debug
+
+static GstElementDetails gst_directsound_src_details =
+GST_ELEMENT_DETAILS ("Direct Sound Audio Src",
+ "Source/Audio",
+ "Capture from a soundcard via DIRECTSOUND",
+ "Joni Valtanen <joni.valtanen@movial.fi>");
+
+/* defaults here */
+#define DEFAULT_DEVICE 0
+
+/* properties */
+enum
+{
+ PROP_0,
+ PROP_DEVICE
};
- static HRESULT (WINAPI * pDSoundCaptureCreate) (LPGUID,
- LPDIRECTSOUNDCAPTURE *, LPUNKNOWN);
- static void gst_directsound_src_finalise (GObject * object);
- static void gst_directsound_src_set_property (GObject * object,
- guint prop_id, const GValue * value, GParamSpec * pspec);
- static void gst_directsound_src_get_property (GObject * object,
- guint prop_id, GValue * value, GParamSpec * pspec);
- static gboolean gst_directsound_src_open (GstAudioSrc * asrc);
- static gboolean gst_directsound_src_close (GstAudioSrc * asrc);
- static gboolean gst_directsound_src_prepare (GstAudioSrc * asrc,
- GstRingBufferSpec * spec);
- static gboolean gst_directsound_src_unprepare (GstAudioSrc * asrc);
- static void gst_directsound_src_reset (GstAudioSrc * asrc);
- static GstCaps *gst_directsound_src_getcaps (GstBaseSrc * bsrc);
- static guint gst_directsound_src_read (GstAudioSrc * asrc, gpointer data,
- guint length);
- static void gst_directsound_src_dispose (GObject * object);
- static void gst_directsound_src_do_init (GType type);
- static guint gst_directsound_src_delay (GstAudioSrc * asrc);
- static GstStaticPadTemplate directsound_src_src_factory =
- GST_STATIC_PAD_TEMPLATE ( "src", GST_PAD_SRC, GST_PAD_ALWAYS,
- GST_STATIC_CAPS ("audio/x-raw-int, "
- "endianness = (int) { LITTLE_ENDIAN, BIG_ENDIAN }, "
- "signed = (boolean) { TRUE, FALSE }, " "width = (int) 16, "
- "depth = (int) 16, " "rate = (int) [ 1, MAX ], "
- "channels = (int) [ 1, 2 ]; " "audio/x-raw-int, "
- "signed = (boolean) { TRUE, FALSE }, " "width = (int) 8, "
- "depth = (int) 8, " "rate = (int) [ 1, MAX ], "
- "channels = (int) [ 1, 2 ]"));
- static void
-gst_directsound_src_do_init (GType type)
+
+
+static HRESULT (WINAPI * pDSoundCaptureCreate) (LPGUID,
+ LPDIRECTSOUNDCAPTURE *, LPUNKNOWN);
+
+static void gst_directsound_src_finalise (GObject * object);
+
+static void gst_directsound_src_set_property (GObject * object,
+ guint prop_id, const GValue * value, GParamSpec * pspec);
+
+static void gst_directsound_src_get_property (GObject * object,
+ guint prop_id, GValue * value, GParamSpec * pspec);
+
+static gboolean gst_directsound_src_open (GstAudioSrc * asrc);
+static gboolean gst_directsound_src_close (GstAudioSrc * asrc);
+static gboolean gst_directsound_src_prepare (GstAudioSrc * asrc,
+ GstRingBufferSpec * spec);
+static gboolean gst_directsound_src_unprepare (GstAudioSrc * asrc);
+static void gst_directsound_src_reset (GstAudioSrc * asrc);
+static GstCaps *gst_directsound_src_getcaps (GstBaseSrc * bsrc);
+
+static guint gst_directsound_src_read (GstAudioSrc * asrc,
+ gpointer data, guint length);
+
+static void gst_directsound_src_dispose (GObject * object);
+
+static void gst_directsound_src_do_init (GType type);
+
+static guint gst_directsound_src_delay (GstAudioSrc * asrc);
+
+static GstStaticPadTemplate directsound_src_src_factory =
+ GST_STATIC_PAD_TEMPLATE ("src",
+ GST_PAD_SRC,
+ GST_PAD_ALWAYS,
+ GST_STATIC_CAPS ("audio/x-raw-int, "
+ "endianness = (int) { LITTLE_ENDIAN, BIG_ENDIAN }, "
+ "signed = (boolean) { TRUE, FALSE }, "
+ "width = (int) 16, "
+ "depth = (int) 16, "
+ "rate = (int) [ 1, MAX ], " "channels = (int) [ 1, 2 ]; "
+ "audio/x-raw-int, "
+ "signed = (boolean) { TRUE, FALSE }, "
+ "width = (int) 8, "
+ "depth = (int) 8, "
+ "rate = (int) [ 1, MAX ], " "channels = (int) [ 1, 2 ]"));
+
+static void
+gst_directsound_src_do_init (GType type)
{
- GST_DEBUG_CATEGORY_INIT (directsoundsrc_debug, "directsoundsrc", 0,
- "DirectSound Src");
- } GST_BOILERPLATE_FULL (GstDirectSoundSrc, gst_directsound_src,
- GstAudioSrc, GST_TYPE_AUDIO_SRC, gst_directsound_src_do_init);
- static void
-gst_directsound_src_dispose (GObject * object)
+ GST_DEBUG_CATEGORY_INIT (directsoundsrc_debug, "directsoundsrc", 0,
+ "DirectSound Src");
+
+
+}
+
+GST_BOILERPLATE_FULL (GstDirectSoundSrc, gst_directsound_src, GstAudioSrc,
+ GST_TYPE_AUDIO_SRC, gst_directsound_src_do_init);
+
+static void
+gst_directsound_src_dispose (GObject * object)
{
- G_OBJECT_CLASS (parent_class)->dispose (object);
- } static void
+ G_OBJECT_CLASS (parent_class)->dispose (object);
+}
-gst_directsound_src_finalise (GObject * object)
+static void
+gst_directsound_src_finalise (GObject * object)
{
- GstDirectSoundSrc * dsoundsrc = GST_DIRECTSOUND_SRC (object);
- g_mutex_free (dsoundsrc->dsound_lock);
- } static void
+ GstDirectSoundSrc *dsoundsrc = GST_DIRECTSOUND_SRC (object);
+
+ g_mutex_free (dsoundsrc->dsound_lock);
+}
-gst_directsound_src_base_init (gpointer g_class)
+static void
+gst_directsound_src_base_init (gpointer g_class)
{
- GstElementClass * element_class = GST_ELEMENT_CLASS (g_class);
- GST_DEBUG ("initializing directsoundsrc base\n");
- gst_element_class_set_details (element_class, &gst_directsound_src_details);
- gst_element_class_add_pad_template (element_class,
- gst_static_pad_template_get (&directsound_src_src_factory));
- }
-
-/* initialize the plugin's class */
-static void
-gst_directsound_src_class_init (GstDirectSoundSrcClass * klass)
+ GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
+
+ GST_DEBUG ("initializing directsoundsrc base\n");
+
+ gst_element_class_set_details (element_class, &gst_directsound_src_details);
+
+ gst_element_class_add_pad_template (element_class,
+ gst_static_pad_template_get (&directsound_src_src_factory));
+}
+
+
+/* initialize the plugin's class */
+static void
+gst_directsound_src_class_init (GstDirectSoundSrcClass * klass)
{
- GObjectClass * gobject_class;
- GstElementClass * gstelement_class;
- GstBaseSrcClass * gstbasesrc_class;
- GstBaseAudioSrcClass * gstbaseaudiosrc_class;
- GstAudioSrcClass * gstaudiosrc_class;
- gobject_class = (GObjectClass *) klass;
- gstelement_class = (GstElementClass *) klass;
- gstbasesrc_class = (GstBaseSrcClass *) klass;
- gstbaseaudiosrc_class = (GstBaseAudioSrcClass *) klass;
- gstaudiosrc_class = (GstAudioSrcClass *) klass;
- GST_DEBUG ("initializing directsoundsrc class\n");
- gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_directsound_src_finalise);
- gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_directsound_src_dispose);
- gobject_class->get_property =
+ GObjectClass *gobject_class;
+ GstElementClass *gstelement_class;
+ GstBaseSrcClass *gstbasesrc_class;
+ GstBaseAudioSrcClass *gstbaseaudiosrc_class;
+ GstAudioSrcClass *gstaudiosrc_class;
+
+ gobject_class = (GObjectClass *) klass;
+ gstelement_class = (GstElementClass *) klass;
+ gstbasesrc_class = (GstBaseSrcClass *) klass;
+ gstbaseaudiosrc_class = (GstBaseAudioSrcClass *) klass;
+ gstaudiosrc_class = (GstAudioSrcClass *) klass;
+
+ GST_DEBUG ("initializing directsoundsrc class\n");
+
+ gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_directsound_src_finalise);
+ gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_directsound_src_dispose);
+ gobject_class->get_property =
GST_DEBUG_FUNCPTR (gst_directsound_src_get_property);
- gobject_class->set_property =
+ gobject_class->set_property =
GST_DEBUG_FUNCPTR (gst_directsound_src_set_property);
- gstbasesrc_class->get_caps =
- GST_DEBUG_FUNCPTR (gst_directsound_src_getcaps);
- gstaudiosrc_class->open = GST_DEBUG_FUNCPTR (gst_directsound_src_open);
- gstaudiosrc_class->close = GST_DEBUG_FUNCPTR (gst_directsound_src_close);
- gstaudiosrc_class->read = GST_DEBUG_FUNCPTR (gst_directsound_src_read);
- gstaudiosrc_class->prepare = GST_DEBUG_FUNCPTR (gst_directsound_src_prepare);
- gstaudiosrc_class->unprepare =
+
+ gstbasesrc_class->get_caps = GST_DEBUG_FUNCPTR (gst_directsound_src_getcaps);
+
+ gstaudiosrc_class->open = GST_DEBUG_FUNCPTR (gst_directsound_src_open);
+ gstaudiosrc_class->close = GST_DEBUG_FUNCPTR (gst_directsound_src_close);
+ gstaudiosrc_class->read = GST_DEBUG_FUNCPTR (gst_directsound_src_read);
+ gstaudiosrc_class->prepare = GST_DEBUG_FUNCPTR (gst_directsound_src_prepare);
+ gstaudiosrc_class->unprepare =
GST_DEBUG_FUNCPTR (gst_directsound_src_unprepare);
- gstaudiosrc_class->delay = GST_DEBUG_FUNCPTR (gst_directsound_src_delay);
- gstaudiosrc_class->reset = GST_DEBUG_FUNCPTR (gst_directsound_src_reset);
- } static GstCaps *
+ gstaudiosrc_class->delay = GST_DEBUG_FUNCPTR (gst_directsound_src_delay);
+ gstaudiosrc_class->reset = GST_DEBUG_FUNCPTR (gst_directsound_src_reset);
+
+
+}
-gst_directsound_src_getcaps (GstBaseSrc * bsrc)
+static GstCaps *
+gst_directsound_src_getcaps (GstBaseSrc * bsrc)
{
- GstDirectSoundSrc * dsoundsrc;
- GstCaps * caps = NULL;
- GST_DEBUG ("get caps\n");
- dsoundsrc = GST_DIRECTSOUND_SRC (bsrc);
- caps = gst_caps_copy (gst_pad_get_pad_template_caps (GST_BASE_SRC_PAD
+ GstDirectSoundSrc *dsoundsrc;
+ GstCaps *caps = NULL;
+ GST_DEBUG ("get caps\n");
+
+ dsoundsrc = GST_DIRECTSOUND_SRC (bsrc);
+
+
+ caps = gst_caps_copy (gst_pad_get_pad_template_caps (GST_BASE_SRC_PAD
(bsrc)));
- return caps;
- }
+ return caps;
+
+}
- static void
+static void
gst_directsound_src_set_property (GObject * object, guint prop_id,
- const GValue * value, GParamSpec * pspec)
+ const GValue * value, GParamSpec * pspec)
{
-
- // GstDirectSoundSrc *src = GST_DIRECTSOUND_SRC (object);
- GST_DEBUG ("set property\n");
- switch (prop_id)
- {
-
-#if 0
- /* FIXME */
+ // GstDirectSoundSrc *src = GST_DIRECTSOUND_SRC (object);
+ GST_DEBUG ("set property\n");
+
+ switch (prop_id) {
+#if 0
+ /* FIXME */
case PROP_DEVICE:
- src->device = g_value_get_uint (value);
- break;
-
-#endif /* */
+ src->device = g_value_get_uint (value);
+ break;
+#endif
default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
- }
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
- static void
+static void
gst_directsound_src_get_property (GObject * object, guint prop_id,
- GValue * value, GParamSpec * pspec)
+ GValue * value, GParamSpec * pspec)
{
-
-#if 0
- GstDirectSoundSrc * src = GST_DIRECTSOUND_SRC (object);
-
-#endif /* */
- GST_DEBUG ("get property\n");
- switch (prop_id) {
-
-#if 0
- /* FIXME */
+#if 0
+ GstDirectSoundSrc *src = GST_DIRECTSOUND_SRC (object);
+#endif
+
+ GST_DEBUG ("get property\n");
+
+ switch (prop_id) {
+#if 0
+ /* FIXME */
case PROP_DEVICE:
- g_value_set_uint (value, src->device);
- break;
-
-#endif /* */
+ g_value_set_uint (value, src->device);
+ break;
+#endif
default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
- }
-
-
-/* initialize the new element
- * instantiate pads and add them to element
- * set functions
- * initialize structure
- */
-static void
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+
+/* initialize the new element
+ * instantiate pads and add them to element
+ * set functions
+ * initialize structure
+ */
+static void
gst_directsound_src_init (GstDirectSoundSrc * src,
- GstDirectSoundSrcClass * gclass)
+ GstDirectSoundSrcClass * gclass)
{
- GST_DEBUG ("initializing directsoundsrc\n");
- src->dsound_lock = g_mutex_new ();
- } static gboolean
+ GST_DEBUG ("initializing directsoundsrc\n");
+ src->dsound_lock = g_mutex_new ();
+}
+
+
-gst_directsound_src_open (GstAudioSrc * asrc)
+static gboolean
+gst_directsound_src_open (GstAudioSrc * asrc)
{
- GstDirectSoundSrc * dsoundsrc;
- HRESULT hRes; /* Result for windows functions */
- GST_DEBUG ("initializing directsoundsrc\n");
- dsoundsrc = GST_DIRECTSOUND_SRC (asrc);
-
- /* Open dsound.dll */
- dsoundsrc->DSoundDLL = LoadLibrary ("dsound.dll");
- if (!dsoundsrc->DSoundDLL) {
- goto dsound_open;
- }
-
- /* Building the DLL Calls */
- pDSoundCaptureCreate =
+ GstDirectSoundSrc *dsoundsrc;
+ HRESULT hRes; /* Result for windows functions */
+
+ GST_DEBUG ("initializing directsoundsrc\n");
+
+ dsoundsrc = GST_DIRECTSOUND_SRC (asrc);
+
+ /* Open dsound.dll */
+ dsoundsrc->DSoundDLL = LoadLibrary ("dsound.dll");
+ if (!dsoundsrc->DSoundDLL) {
+ goto dsound_open;
+ }
+
+ /* Building the DLL Calls */
+ pDSoundCaptureCreate =
(void *) GetProcAddress (dsoundsrc->DSoundDLL,
- TEXT ("DirectSoundCaptureCreate"));
-
- /* If everything is not ok */
- if (!pDSoundCaptureCreate) {
- goto capture_function;
- }
-
- /* FIXME: add here device selection */
- /* Create capture object */
- hRes = pDSoundCaptureCreate (NULL, &dsoundsrc->pDSC, NULL);
- if (FAILED (hRes)) {
- goto capture_object;
- }
- return TRUE;
- capture_function: {
- FreeLibrary (dsoundsrc->DSoundDLL);
- GST_ELEMENT_ERROR (dsoundsrc, RESOURCE, OPEN_READ,
+ TEXT ("DirectSoundCaptureCreate"));
+
+ /* If everything is not ok */
+ if (!pDSoundCaptureCreate) {
+ goto capture_function;
+ }
+
+ /* FIXME: add here device selection */
+ /* Create capture object */
+ hRes = pDSoundCaptureCreate (NULL, &dsoundsrc->pDSC, NULL);
+ if (FAILED (hRes)) {
+ goto capture_object;
+ }
+
+ return TRUE;
+
+capture_function:
+ {
+ FreeLibrary (dsoundsrc->DSoundDLL);
+ GST_ELEMENT_ERROR (dsoundsrc, RESOURCE, OPEN_READ,
("Unable to get capturecreate function"), (NULL));
- return FALSE;
- }
- capture_object: {
- FreeLibrary (dsoundsrc->DSoundDLL);
- GST_ELEMENT_ERROR (dsoundsrc, RESOURCE, OPEN_READ,
+ return FALSE;
+ }
+capture_object:
+ {
+ FreeLibrary (dsoundsrc->DSoundDLL);
+ GST_ELEMENT_ERROR (dsoundsrc, RESOURCE, OPEN_READ,
("Unable to create capture object"), (NULL));
- return FALSE;
- }
- dsound_open: {
- GST_ELEMENT_ERROR (dsoundsrc, RESOURCE, OPEN_READ,
+ return FALSE;
+ }
+dsound_open:
+ {
+ DWORD err = GetLastError ();
+ GST_ELEMENT_ERROR (dsoundsrc, RESOURCE, OPEN_READ,
("Unable to open dsound.dll"), (NULL));
- return FALSE;
- }
- }
+ g_print ("0x%x\n", HRESULT_FROM_WIN32 (err));
+ return FALSE;
+ }
+}
- static gboolean
-gst_directsound_src_close (GstAudioSrc * asrc)
+static gboolean
+gst_directsound_src_close (GstAudioSrc * asrc)
{
- GstDirectSoundSrc * dsoundsrc;
- HRESULT hRes; /* Result for windows functions */
- GST_DEBUG ("initializing directsoundsrc\n");
- dsoundsrc = GST_DIRECTSOUND_SRC (asrc);
-
- /* Release capture handler */
- hRes = IDirectSoundCapture_Release (dsoundsrc->pDSC);
-
- /* Close library */
- FreeLibrary (dsoundsrc->DSoundDLL);
- return TRUE;
- }
-
- static gboolean
-gst_directsound_src_prepare (GstAudioSrc * asrc, GstRingBufferSpec * spec)
+ GstDirectSoundSrc *dsoundsrc;
+ HRESULT hRes; /* Result for windows functions */
+
+ GST_DEBUG ("initializing directsoundsrc\n");
+
+ dsoundsrc = GST_DIRECTSOUND_SRC (asrc);
+
+ /* Release capture handler */
+ hRes = IDirectSoundCapture_Release (dsoundsrc->pDSC);
+
+ /* Close library */
+ FreeLibrary (dsoundsrc->DSoundDLL);
+
+ return TRUE;
+}
+
+static gboolean
+gst_directsound_src_prepare (GstAudioSrc * asrc, GstRingBufferSpec * spec)
{
- GstDirectSoundSrc * dsoundsrc;
- WAVEFORMATEX wfx; /* Wave format structure */
- HRESULT hRes; /* Result for windows functions */
- DSCBUFFERDESC descSecondary; /* Capturebuffer decsiption */
- int fmt = 0; /* audio format */
- dsoundsrc = GST_DIRECTSOUND_SRC (asrc);
- GST_DEBUG ("initializing directsoundsrc\n");
-
- /* Define buffer */
- memset (&wfx, 0, sizeof (WAVEFORMATEX));
- wfx.wFormatTag = WAVE_FORMAT_PCM; /* should be WAVE_FORMAT_PCM */
- wfx.nChannels = spec->channels;
- wfx.nSamplesPerSec = spec->rate; /* 8000|11025|22050|44100 */
- wfx.wBitsPerSample = spec->width; // 8|16;
- wfx.nBlockAlign = wfx.nChannels * (wfx.wBitsPerSample / 8);
- wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign;
- wfx.cbSize = 0; /* This size is allways for PCM-format */
-
- /* 1 or 2 Channels etc...
- FIXME: Never really tested. Is this ok?
- */
- if (spec->width == 16 && spec->channels == 1) {
- spec->format = GST_S16_LE;
- } else if (spec->width == 16 && spec->channels == 2) {
- spec->format = GST_U16_LE;
- } else if (spec->width == 8 && spec->channels == 1) {
- spec->format = GST_S8;
- } else if (spec->width == 8 && spec->channels == 2) {
- spec->format = GST_U8;
- }
-
- /* Set the buffer size to two seconds.
- This should never reached.
- */
- dsoundsrc->buffer_size = wfx.nAvgBytesPerSec * 2;
-
- //notifysize * 16; //spec->width; /*original 16*/
- GST_DEBUG ("Buffer size: %d", dsoundsrc->buffer_size);
-
- /* Init secondary buffer desciption */
- memset (&descSecondary, 0, sizeof (DSCBUFFERDESC));
- descSecondary.dwSize = sizeof (DSCBUFFERDESC);
- descSecondary.dwFlags = 0;
- descSecondary.dwReserved = 0;
-
- /* This is not primary buffer so have to set size */
- descSecondary.dwBufferBytes = dsoundsrc->buffer_size;
- descSecondary.lpwfxFormat = &wfx;
-
- /* Create buffer */
- hRes =
- IDirectSoundCapture_CreateCaptureBuffer (dsoundsrc->pDSC, &descSecondary,
- &dsoundsrc->pDSBSecondary, NULL);
- if (hRes != DS_OK) {
- goto capture_buffer;
- }
- spec->channels = wfx.nChannels;
- spec->rate = wfx.nSamplesPerSec;
- spec->bytes_per_sample = (spec->width / 8) * spec->channels;
- dsoundsrc->bytes_per_sample = spec->bytes_per_sample;
- GST_DEBUG ("latency time: %llu - buffer time: %llu", spec->latency_time,
- spec->buffer_time);
-
- /* Buffer-time should be allways more than 2*latency */
- if (spec->buffer_time < spec->latency_time * 2) {
- spec->buffer_time = spec->latency_time * 2;
- GST_WARNING ("buffer-time was less than latency");
- }
-
- /* Save the times */
- dsoundsrc->buffer_time = spec->buffer_time;
- dsoundsrc->latency_time = spec->latency_time;
- dsoundsrc->latency_size =
- (gint) wfx.nAvgBytesPerSec * dsoundsrc->latency_time / 1000000.0;
- spec->segsize =
- (guint) (((double) spec->buffer_time / 1000000.0) * wfx.nAvgBytesPerSec);
-
- /* just in case */
- if (spec->segsize < 1)
- spec->segsize = 1;
- spec->segtotal = spec->width * (wfx.nAvgBytesPerSec / spec->segsize);
- GST_DEBUG ("bytes/sec: %d, buffer size: %d, segsize: %d, segtotal: %d",
- wfx.nAvgBytesPerSec, dsoundsrc->buffer_size, spec->segsize,
- spec->segtotal);
- spec->silence_sample[0] = 0;
- spec->silence_sample[1] = 0;
- spec->silence_sample[2] = 0;
- spec->silence_sample[3] = 0;
- if (spec->width != 16 && spec->width != 8)
- goto dodgy_width;
-
- /* Not readed anything yet */
- dsoundsrc->current_circular_offset = 0;
- GST_DEBUG ("GstRingBufferSpec->channels: %d, GstRingBufferSpec->rate: %d, \
-GstRingBufferSpec->bytes_per_sample: %d\n\
-WAVEFORMATEX.nSamplesPerSec: %ld, WAVEFORMATEX.wBitsPerSample: %d, \
-WAVEFORMATEX.nBlockAlign: %d, WAVEFORMATEX.nAvgBytesPerSec: %ld\n", spec->channels, spec->rate, spec->bytes_per_sample, wfx.nSamplesPerSec, wfx.wBitsPerSample, wfx.nBlockAlign, wfx.nAvgBytesPerSec);
- return TRUE;
- wrong_format: {
- GST_ELEMENT_ERROR (dsoundsrc, RESOURCE, OPEN_READ,
+
+ GstDirectSoundSrc *dsoundsrc;
+ WAVEFORMATEX wfx; /* Wave format structure */
+ HRESULT hRes; /* Result for windows functions */
+ DSCBUFFERDESC descSecondary; /* Capturebuffer decsiption */
+
+ int fmt = 0; /* audio format */
+
+ dsoundsrc = GST_DIRECTSOUND_SRC (asrc);
+
+ GST_DEBUG ("initializing directsoundsrc\n");
+
+ /* Define buffer */
+ memset (&wfx, 0, sizeof (WAVEFORMATEX));
+ wfx.wFormatTag = WAVE_FORMAT_PCM; /* should be WAVE_FORMAT_PCM */
+ wfx.nChannels = spec->channels;
+ wfx.nSamplesPerSec = spec->rate; /* 8000|11025|22050|44100 */
+ wfx.wBitsPerSample = spec->width; // 8|16;
+
+ wfx.nBlockAlign = wfx.nChannels * (wfx.wBitsPerSample / 8);
+ wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign;
+ wfx.cbSize = 0; /* This size is allways for PCM-format */
+
+ /* 1 or 2 Channels etc...
+ FIXME: Never really tested. Is this ok?
+ */
+ if (spec->width == 16 && spec->channels == 1) {
+ spec->format = GST_S16_LE;
+ } else if (spec->width == 16 && spec->channels == 2) {
+ spec->format = GST_U16_LE;
+ } else if (spec->width == 8 && spec->channels == 1) {
+ spec->format = GST_S8;
+ } else if (spec->width == 8 && spec->channels == 2) {
+ spec->format = GST_U8;
+ }
+
+ /* Set the buffer size to two seconds.
+ This should never reached.
+ */
+ dsoundsrc->buffer_size = wfx.nAvgBytesPerSec * 2;
+
+ //notifysize * 16; //spec->width; /*original 16*/
+ GST_DEBUG ("Buffer size: %d", dsoundsrc->buffer_size);
+
+ /* Init secondary buffer desciption */
+ memset (&descSecondary, 0, sizeof (DSCBUFFERDESC));
+ descSecondary.dwSize = sizeof (DSCBUFFERDESC);
+ descSecondary.dwFlags = 0;
+ descSecondary.dwReserved = 0;
+
+ /* This is not primary buffer so have to set size */
+ descSecondary.dwBufferBytes = dsoundsrc->buffer_size;
+ descSecondary.lpwfxFormat = &wfx;
+
+ /* Create buffer */
+ hRes = IDirectSoundCapture_CreateCaptureBuffer (dsoundsrc->pDSC,
+ &descSecondary, &dsoundsrc->pDSBSecondary, NULL);
+ if (hRes != DS_OK) {
+ goto capture_buffer;
+ }
+
+ spec->channels = wfx.nChannels;
+ spec->rate = wfx.nSamplesPerSec;
+ spec->bytes_per_sample = (spec->width / 8) * spec->channels;
+ dsoundsrc->bytes_per_sample = spec->bytes_per_sample;
+
+ GST_DEBUG ("latency time: %llu - buffer time: %llu",
+ spec->latency_time, spec->buffer_time);
+
+ /* Buffer-time should be allways more than 2*latency */
+ if (spec->buffer_time < spec->latency_time * 2) {
+ spec->buffer_time = spec->latency_time * 2;
+ GST_WARNING ("buffer-time was less than latency");
+ }
+
+ /* Save the times */
+ dsoundsrc->buffer_time = spec->buffer_time;
+ dsoundsrc->latency_time = spec->latency_time;
+
+ dsoundsrc->latency_size = (gint) wfx.nAvgBytesPerSec *
+ dsoundsrc->latency_time / 1000000.0;
+
+
+ spec->segsize = (guint) (((double) spec->buffer_time / 1000000.0) *
+ wfx.nAvgBytesPerSec);
+
+ /* just in case */
+ if (spec->segsize < 1)
+ spec->segsize = 1;
+
+ spec->segtotal = spec->width * (wfx.nAvgBytesPerSec / spec->segsize);
+
+ GST_DEBUG ("bytes/sec: %d, buffer size: %d, segsize: %d, segtotal: %d",
+ wfx.nAvgBytesPerSec,
+ dsoundsrc->buffer_size, spec->segsize, spec->segtotal);
+
+ spec->silence_sample[0] = 0;
+ spec->silence_sample[1] = 0;
+ spec->silence_sample[2] = 0;
+ spec->silence_sample[3] = 0;
+
+ if (spec->width != 16 && spec->width != 8)
+ goto dodgy_width;
+
+ /* Not readed anything yet */
+ dsoundsrc->current_circular_offset = 0;
+
+ GST_DEBUG ("GstRingBufferSpec->channels: %d, GstRingBufferSpec->rate: %d, \
+GstRingBufferSpec->bytes_per_sample: %d\n\
+WAVEFORMATEX.nSamplesPerSec: %ld, WAVEFORMATEX.wBitsPerSample: %d, \
+WAVEFORMATEX.nBlockAlign: %d, WAVEFORMATEX.nAvgBytesPerSec: %ld\n", spec->channels, spec->rate, spec->bytes_per_sample, wfx.nSamplesPerSec, wfx.wBitsPerSample, wfx.nBlockAlign, wfx.nAvgBytesPerSec);
+
+ return TRUE;
+
+wrong_format:
+ {
+ GST_ELEMENT_ERROR (dsoundsrc, RESOURCE, OPEN_READ,
("Unable to get format %d", spec->format), (NULL));
- return FALSE;
- }
- capture_buffer: {
- GST_ELEMENT_ERROR (dsoundsrc, RESOURCE, OPEN_READ,
+ return FALSE;
+ }
+capture_buffer:
+ {
+ GST_ELEMENT_ERROR (dsoundsrc, RESOURCE, OPEN_READ,
("Unable to create capturebuffer"), (NULL));
- return FALSE;
- }
- dodgy_width: {
- GST_ELEMENT_ERROR (dsoundsrc, RESOURCE, OPEN_READ,
+ return FALSE;
+ }
+dodgy_width:
+ {
+ GST_ELEMENT_ERROR (dsoundsrc, RESOURCE, OPEN_READ,
("Unexpected width %d", spec->width), (NULL));
- return FALSE;
- }
- }
+ return FALSE;
+ }
- static gboolean
-gst_directsound_src_unprepare (GstAudioSrc * asrc)
+}
+
+static gboolean
+gst_directsound_src_unprepare (GstAudioSrc * asrc)
{
- GstDirectSoundSrc * dsoundsrc;
- HRESULT hRes; /* Result for windows functions */
-
- /* Resets */
- GST_DEBUG ("unpreparing directsoundsrc");
- dsoundsrc = GST_DIRECTSOUND_SRC (asrc);
-
- /* Stop capturing */
- hRes = IDirectSoundCaptureBuffer_Stop (dsoundsrc->pDSBSecondary);
-
- /* Release buffer */
- hRes = IDirectSoundCaptureBuffer_Release (dsoundsrc->pDSBSecondary);
- return TRUE;
- }
-
-
-/*
-return number of readed bytes */
-static guint
-gst_directsound_src_read (GstAudioSrc * asrc, gpointer data, guint length)
+ GstDirectSoundSrc *dsoundsrc;
+
+ HRESULT hRes; /* Result for windows functions */
+
+ /* Resets */
+ GST_DEBUG ("unpreparing directsoundsrc");
+
+ dsoundsrc = GST_DIRECTSOUND_SRC (asrc);
+
+ /* Stop capturing */
+ hRes = IDirectSoundCaptureBuffer_Stop (dsoundsrc->pDSBSecondary);
+
+ /* Release buffer */
+ hRes = IDirectSoundCaptureBuffer_Release (dsoundsrc->pDSBSecondary);
+
+ return TRUE;
+
+}
+
+/*
+return number of readed bytes */
+static guint
+gst_directsound_src_read (GstAudioSrc * asrc, gpointer data, guint length)
{
- GstDirectSoundSrc * dsoundsrc;
- HRESULT hRes; /* Result for windows functions */
- DWORD dwCurrentCaptureCursor = 0;
- DWORD dwBufferSize = 0;
- LPVOID pLockedBuffer1 = NULL;
- LPVOID pLockedBuffer2 = NULL;
- DWORD dwSizeBuffer1 = 0;
- DWORD dwSizeBuffer2 = 0;
- DWORD dwStatus = 0;
- GST_DEBUG ("reading directsoundsrc\n");
- dsoundsrc = GST_DIRECTSOUND_SRC (asrc);
- GST_DSOUND_LOCK (dsoundsrc);
-
- /* Get current buffer status */
- hRes =
- IDirectSoundCaptureBuffer_GetStatus (dsoundsrc->pDSBSecondary,
- &dwStatus);
-
- /* Starting capturing if not allready */
- if (!(dwStatus & DSCBSTATUS_CAPTURING)) {
- hRes =
- IDirectSoundCaptureBuffer_Start (dsoundsrc->pDSBSecondary,
- DSCBSTART_LOOPING);
-
- // Sleep (dsoundsrc->latency_time/1000);
- GST_DEBUG ("capture started");
- }
-
- // calculate_buffersize:
- while (length > dwBufferSize) {
- Sleep (dsoundsrc->latency_time / 1000);
- hRes =
- IDirectSoundCaptureBuffer_GetCurrentPosition (dsoundsrc->pDSBSecondary,
- &dwCurrentCaptureCursor, NULL);
-
- /* calculate the buffer */
- if (dwCurrentCaptureCursor < dsoundsrc->current_circular_offset) {
- dwBufferSize = dsoundsrc->buffer_size -
- (dsoundsrc->current_circular_offset - dwCurrentCaptureCursor);
- } else {
- dwBufferSize =
- dwCurrentCaptureCursor - dsoundsrc->current_circular_offset;
- }
- } // while (...
-
- /* Lock the buffer */
- hRes =
- IDirectSoundCaptureBuffer_Lock (dsoundsrc->pDSBSecondary,
- dsoundsrc->current_circular_offset, length, &pLockedBuffer1,
- &dwSizeBuffer1, &pLockedBuffer2, &dwSizeBuffer2, 0L);
-
- /* Copy buffer data to another buffer */
- if (hRes == DS_OK) {
- memcpy (data, pLockedBuffer1, dwSizeBuffer1);
- }
-
- /* ...and if something is in another buffer */
- if (pLockedBuffer2 != NULL) {
- memcpy ((data + dwSizeBuffer1), pLockedBuffer2, dwSizeBuffer2);
- }
- dsoundsrc->current_circular_offset += dwSizeBuffer1 + dwSizeBuffer2;
- dsoundsrc->current_circular_offset %= dsoundsrc->buffer_size;
- IDirectSoundCaptureBuffer_Unlock (dsoundsrc->pDSBSecondary, pLockedBuffer1,
- dwSizeBuffer1, pLockedBuffer2, dwSizeBuffer2);
- GST_DSOUND_UNLOCK (dsoundsrc);
-
- /* return length (readed data size in bytes) */
- return length;
- }
-
- static guint
-gst_directsound_src_delay (GstAudioSrc * asrc)
+ GstDirectSoundSrc *dsoundsrc;
+
+ HRESULT hRes; /* Result for windows functions */
+ DWORD dwCurrentCaptureCursor = 0;
+ DWORD dwBufferSize = 0;
+
+ LPVOID pLockedBuffer1 = NULL;
+ LPVOID pLockedBuffer2 = NULL;
+ DWORD dwSizeBuffer1 = 0;
+ DWORD dwSizeBuffer2 = 0;
+
+ DWORD dwStatus = 0;
+
+ GST_DEBUG ("reading directsoundsrc\n");
+
+ dsoundsrc = GST_DIRECTSOUND_SRC (asrc);
+
+ GST_DSOUND_LOCK (dsoundsrc);
+
+ /* Get current buffer status */
+ hRes = IDirectSoundCaptureBuffer_GetStatus (dsoundsrc->pDSBSecondary,
+ &dwStatus);
+
+ /* Starting capturing if not allready */
+ if (!(dwStatus & DSCBSTATUS_CAPTURING)) {
+ hRes = IDirectSoundCaptureBuffer_Start (dsoundsrc->pDSBSecondary,
+ DSCBSTART_LOOPING);
+ // Sleep (dsoundsrc->latency_time/1000);
+ GST_DEBUG ("capture started");
+ }
+ // calculate_buffersize:
+ while (length > dwBufferSize) {
+ Sleep (dsoundsrc->latency_time / 1000);
+
+ hRes =
+ IDirectSoundCaptureBuffer_GetCurrentPosition (dsoundsrc->pDSBSecondary,
+ &dwCurrentCaptureCursor, NULL);
+
+ /* calculate the buffer */
+ if (dwCurrentCaptureCursor < dsoundsrc->current_circular_offset) {
+ dwBufferSize = dsoundsrc->buffer_size -
+ (dsoundsrc->current_circular_offset - dwCurrentCaptureCursor);
+ } else {
+ dwBufferSize =
+ dwCurrentCaptureCursor - dsoundsrc->current_circular_offset;
+ }
+
+
+ } // while (...
+
+ /* Lock the buffer */
+ hRes = IDirectSoundCaptureBuffer_Lock (dsoundsrc->pDSBSecondary,
+ dsoundsrc->current_circular_offset,
+ length,
+ &pLockedBuffer1, &dwSizeBuffer1, &pLockedBuffer2, &dwSizeBuffer2, 0L);
+
+ /* Copy buffer data to another buffer */
+ if (hRes == DS_OK) {
+ memcpy (data, pLockedBuffer1, dwSizeBuffer1);
+ }
+
+ /* ...and if something is in another buffer */
+ if (pLockedBuffer2 != NULL) {
+ memcpy (((guchar *) data + dwSizeBuffer1), pLockedBuffer2, dwSizeBuffer2);
+ }
+
+ dsoundsrc->current_circular_offset += dwSizeBuffer1 + dwSizeBuffer2;
+ dsoundsrc->current_circular_offset %= dsoundsrc->buffer_size;
+
+ IDirectSoundCaptureBuffer_Unlock (dsoundsrc->pDSBSecondary,
+ pLockedBuffer1, dwSizeBuffer1, pLockedBuffer2, dwSizeBuffer2);
+
+ GST_DSOUND_UNLOCK (dsoundsrc);
+
+ /* return length (readed data size in bytes) */
+ return length;
+
+}
+
+static guint
+gst_directsound_src_delay (GstAudioSrc * asrc)
{
- GstDirectSoundSrc * dsoundsrc;
- HRESULT hRes;
- DWORD dwCurrentCaptureCursor;
- DWORD dwBytesInQueue = 0;
- gint nNbSamplesInQueue = 0;
- GST_DEBUG ("Delay\n");
- dsoundsrc = GST_DIRECTSOUND_SRC (asrc);
-
- /* evaluate the number of samples in queue in the circular buffer */
- hRes =
- IDirectSoundCaptureBuffer_GetCurrentPosition (dsoundsrc->pDSBSecondary,
- &dwCurrentCaptureCursor, NULL);
-
- /* FIXME: Check is this calculated right */
- if (hRes == S_OK) {
- if (dwCurrentCaptureCursor < dsoundsrc->current_circular_offset) {
- dwBytesInQueue =
- dsoundsrc->buffer_size - (dsoundsrc->current_circular_offset -
- dwCurrentCaptureCursor);
- } else {
- dwBytesInQueue =
- dwCurrentCaptureCursor - dsoundsrc->current_circular_offset;
- }
- nNbSamplesInQueue = dwBytesInQueue / dsoundsrc->bytes_per_sample;
- }
- return nNbSamplesInQueue;
- }
-
- static void
-gst_directsound_src_reset (GstAudioSrc * asrc)
+ GstDirectSoundSrc *dsoundsrc;
+ HRESULT hRes;
+ DWORD dwCurrentCaptureCursor;
+ DWORD dwBytesInQueue = 0;
+ gint nNbSamplesInQueue = 0;
+
+ GST_DEBUG ("Delay\n");
+
+ dsoundsrc = GST_DIRECTSOUND_SRC (asrc);
+
+ /* evaluate the number of samples in queue in the circular buffer */
+ hRes =
+ IDirectSoundCaptureBuffer_GetCurrentPosition (dsoundsrc->pDSBSecondary,
+ &dwCurrentCaptureCursor, NULL);
+ /* FIXME: Check is this calculated right */
+ if (hRes == S_OK) {
+ if (dwCurrentCaptureCursor < dsoundsrc->current_circular_offset) {
+ dwBytesInQueue =
+ dsoundsrc->buffer_size - (dsoundsrc->current_circular_offset -
+ dwCurrentCaptureCursor);
+ } else {
+ dwBytesInQueue =
+ dwCurrentCaptureCursor - dsoundsrc->current_circular_offset;
+ }
+
+ nNbSamplesInQueue = dwBytesInQueue / dsoundsrc->bytes_per_sample;
+ }
+
+ return nNbSamplesInQueue;
+}
+
+static void
+gst_directsound_src_reset (GstAudioSrc * asrc)
{
- GstDirectSoundSrc * dsoundsrc;
- LPVOID pLockedBuffer = NULL;
- DWORD dwSizeBuffer = 0;
- GST_DEBUG ("reset directsoundsrc\n");
- dsoundsrc = GST_DIRECTSOUND_SRC (asrc);
-
-#if 0
- IDirectSoundCaptureBuffer_Stop (dsoundsrc->pDSBSecondary);
-
-#endif /* */
- GST_DSOUND_LOCK (dsoundsrc);
- if (dsoundsrc->pDSBSecondary) {
-
- /*stop capturing */
- HRESULT hRes =
- IDirectSoundCaptureBuffer_Stop (dsoundsrc->pDSBSecondary);
-
- /*reset position */
- /* hRes = IDirectSoundCaptureBuffer_SetCurrentPosition (dsoundsrc->pDSBSecondary, 0); */
-
- /*reset the buffer */
- hRes =
- IDirectSoundCaptureBuffer_Lock (dsoundsrc->pDSBSecondary,
- dsoundsrc->current_circular_offset, dsoundsrc->buffer_size,
- pLockedBuffer, &dwSizeBuffer, NULL, NULL, 0L);
- if (SUCCEEDED (hRes)) {
- memset (pLockedBuffer, 0, dwSizeBuffer);
- hRes =
- IDirectSoundCaptureBuffer_Unlock (dsoundsrc->pDSBSecondary,
- pLockedBuffer, dwSizeBuffer, NULL, 0);
- }
- dsoundsrc->current_circular_offset = 0;
- }
- GST_DSOUND_UNLOCK (dsoundsrc);
- }
-
-
+ GstDirectSoundSrc *dsoundsrc;
+ LPVOID pLockedBuffer = NULL;
+ DWORD dwSizeBuffer = 0;
+
+ GST_DEBUG ("reset directsoundsrc\n");
+
+ dsoundsrc = GST_DIRECTSOUND_SRC (asrc);
+
+#if 0
+ IDirectSoundCaptureBuffer_Stop (dsoundsrc->pDSBSecondary);
+#endif
+
+ GST_DSOUND_LOCK (dsoundsrc);
+
+ if (dsoundsrc->pDSBSecondary) {
+ /*stop capturing */
+ HRESULT hRes = IDirectSoundCaptureBuffer_Stop (dsoundsrc->pDSBSecondary);
+
+ /*reset position */
+ /* hRes = IDirectSoundCaptureBuffer_SetCurrentPosition (dsoundsrc->pDSBSecondary, 0); */
+
+ /*reset the buffer */
+ hRes = IDirectSoundCaptureBuffer_Lock (dsoundsrc->pDSBSecondary,
+ dsoundsrc->current_circular_offset, dsoundsrc->buffer_size,
+ pLockedBuffer, &dwSizeBuffer, NULL, NULL, 0L);
+
+ if (SUCCEEDED (hRes)) {
+ memset (pLockedBuffer, 0, dwSizeBuffer);
+
+ hRes =
+ IDirectSoundCaptureBuffer_Unlock (dsoundsrc->pDSBSecondary,
+ pLockedBuffer, dwSizeBuffer, NULL, 0);
+ }
+ dsoundsrc->current_circular_offset = 0;
+
+ }
+
+ GST_DSOUND_UNLOCK (dsoundsrc);
+}
diff --git a/sys/dshowsrcwrapper/Makefile.am b/sys/dshowsrcwrapper/Makefile.am
index de78c531..de78c531 100755..100644
--- a/sys/dshowsrcwrapper/Makefile.am
+++ b/sys/dshowsrcwrapper/Makefile.am
diff --git a/sys/dshowsrcwrapper/gstdshow.cpp b/sys/dshowsrcwrapper/gstdshow.cpp
index 4b090346..8b77b585 100755..100644
--- a/sys/dshowsrcwrapper/gstdshow.cpp
+++ b/sys/dshowsrcwrapper/gstdshow.cpp
@@ -70,6 +70,21 @@ gst_dshow_free_pins_mediatypes (GList *pins_mediatypes)
g_list_free (pins_mediatypes);
}
+gboolean
+gst_dshow_check_mediatype (AM_MEDIA_TYPE *media_type, const GUID sub_type,
+ const GUID format_type)
+{
+ RPC_STATUS rpcstatus;
+
+ g_return_val_if_fail (media_type != NULL, FALSE);
+
+ return
+ UuidCompare (&media_type->subtype, (UUID *) &sub_type,
+ &rpcstatus) == 0 && rpcstatus == RPC_S_OK &&
+ UuidCompare (&media_type->formattype, (UUID *) &format_type,
+ &rpcstatus) == 0 && rpcstatus == RPC_S_OK;
+}
+
gboolean
gst_dshow_get_pin_from_filter (IBaseFilter *filter, PIN_DIRECTION pindir, IPin **pin)
{
diff --git a/sys/dshowsrcwrapper/gstdshow.h b/sys/dshowsrcwrapper/gstdshow.h
index e71ca789..4491e50d 100755..100644
--- a/sys/dshowsrcwrapper/gstdshow.h
+++ b/sys/dshowsrcwrapper/gstdshow.h
@@ -54,6 +54,9 @@ void gst_dshow_free_mediatype (AM_MEDIA_TYPE *pmt);
/* free the memory of all mediatypes of the input list if pin mediatype */
void gst_dshow_free_pins_mediatypes (GList *mediatypes);
+/* allow to know what kind of media type we have */
+gboolean gst_dshow_check_mediatype (AM_MEDIA_TYPE *media_type, const GUID sub_type, const GUID format_type);
+
/* get a pin from directshow filter */
gboolean gst_dshow_get_pin_from_filter (IBaseFilter *filter, PIN_DIRECTION pindir, IPin **pin);
diff --git a/sys/dshowsrcwrapper/gstdshowaudiosrc.cpp b/sys/dshowsrcwrapper/gstdshowaudiosrc.cpp
index a0e2d78c..03dab12d 100755..100644
--- a/sys/dshowsrcwrapper/gstdshowaudiosrc.cpp
+++ b/sys/dshowsrcwrapper/gstdshowaudiosrc.cpp
@@ -264,15 +264,12 @@ static GValueArray *
gst_dshowaudiosrc_get_device_name_values (GstDshowAudioSrc * src)
{
GValueArray *array = g_value_array_new (0);
- GValue value = { 0 };
ICreateDevEnum *devices_enum = NULL;
IEnumMoniker *moniker_enum = NULL;
IMoniker *moniker = NULL;
HRESULT hres = S_FALSE;
ULONG fetched;
- g_value_init (&value, G_TYPE_STRING);
-
hres = CoCreateInstance (CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER,
IID_ICreateDevEnum, (LPVOID *) &devices_enum);
if (hres != S_OK) {
@@ -310,6 +307,8 @@ gst_dshowaudiosrc_get_device_name_values (GstDshowAudioSrc * src)
g_utf16_to_utf8 ((const gunichar2 *) varFriendlyName.bstrVal,
wcslen (varFriendlyName.bstrVal), NULL, NULL, NULL);
+ GValue value = { 0 };
+ g_value_init (&value, G_TYPE_STRING);
g_value_set_string (&value, friendly_name);
g_value_array_append (array, &value);
g_value_unset (&value);
@@ -368,6 +367,17 @@ gst_dshowaudiosrc_set_property (GObject * object, guint prop_id,
}
break;
}
+ case PROP_DEVICE_NAME:
+ {
+ if (src->device_name) {
+ g_free (src->device_name);
+ src->device_name = NULL;
+ }
+ if (g_value_get_string (value)) {
+ src->device_name = g_strdup (g_value_get_string (value));
+ }
+ break;
+ }
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -757,7 +767,6 @@ gst_dshowaudiosrc_getcaps_from_streamcaps (GstDshowAudioSrc * src, IPin * pin,
{
GstCaps *caps = NULL;
HRESULT hres = S_OK;
- RPC_STATUS rpcstatus;
int icount = 0;
int isize = 0;
AUDIO_STREAM_CONFIG_CAPS ascc;
@@ -785,11 +794,7 @@ gst_dshowaudiosrc_getcaps_from_streamcaps (GstDshowAudioSrc * src, IPin * pin,
if (!caps)
caps = gst_caps_new_empty ();
- if ((UuidCompare (&pin_mediatype->mediatype->subtype, (UUID *) &MEDIASUBTYPE_PCM,
- &rpcstatus) == 0 && rpcstatus == RPC_S_OK)
- && (UuidCompare (&pin_mediatype->mediatype->formattype,
- (UUID *) &FORMAT_WaveFormatEx, &rpcstatus) == 0
- && rpcstatus == RPC_S_OK)) {
+ if (gst_dshow_check_mediatype (pin_mediatype->mediatype, MEDIASUBTYPE_PCM, FORMAT_WaveFormatEx)) {
WAVEFORMATEX *wavformat =
(WAVEFORMATEX *) pin_mediatype->mediatype->pbFormat;
mediacaps =
diff --git a/sys/dshowsrcwrapper/gstdshowaudiosrc.h b/sys/dshowsrcwrapper/gstdshowaudiosrc.h
index d5cfe6e0..d5cfe6e0 100755..100644
--- a/sys/dshowsrcwrapper/gstdshowaudiosrc.h
+++ b/sys/dshowsrcwrapper/gstdshowaudiosrc.h
diff --git a/sys/dshowsrcwrapper/gstdshowfakesink.cpp b/sys/dshowsrcwrapper/gstdshowfakesink.cpp
index 6c0c74dc..6c0c74dc 100755..100644
--- a/sys/dshowsrcwrapper/gstdshowfakesink.cpp
+++ b/sys/dshowsrcwrapper/gstdshowfakesink.cpp
diff --git a/sys/dshowsrcwrapper/gstdshowfakesink.h b/sys/dshowsrcwrapper/gstdshowfakesink.h
index 51291c69..51291c69 100755..100644
--- a/sys/dshowsrcwrapper/gstdshowfakesink.h
+++ b/sys/dshowsrcwrapper/gstdshowfakesink.h
diff --git a/sys/dshowsrcwrapper/gstdshowsrcwrapper.cpp b/sys/dshowsrcwrapper/gstdshowsrcwrapper.cpp
index 9acfc344..9acfc344 100755..100644
--- a/sys/dshowsrcwrapper/gstdshowsrcwrapper.cpp
+++ b/sys/dshowsrcwrapper/gstdshowsrcwrapper.cpp
diff --git a/sys/dshowsrcwrapper/gstdshowvideosrc.cpp b/sys/dshowsrcwrapper/gstdshowvideosrc.cpp
index 14654f60..86cb5eb7 100755..100644
--- a/sys/dshowsrcwrapper/gstdshowvideosrc.cpp
+++ b/sys/dshowsrcwrapper/gstdshowvideosrc.cpp
@@ -1,5 +1,6 @@
/* GStreamer
* Copyright (C) 2007 Sebastien Moutte <sebastien@moutte.net>
+ * Copyright (C) 2009 Julien Isorce <julien.isorce@gmail.com>
*
* gstdshowvideosrc.c:
*
@@ -25,6 +26,8 @@
#include "gstdshowvideosrc.h"
+#include <gst/video/video.h>
+
static const GstElementDetails gst_dshowvideosrc_details =
GST_ELEMENT_DETAILS ("DirectShow video capture source",
"Source/Video",
@@ -42,12 +45,9 @@ const GUID MEDIASUBTYPE_I420
static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src",
GST_PAD_SRC,
GST_PAD_ALWAYS,
- GST_STATIC_CAPS ("video/x-raw-rgb,"
- "bpp = (int) 24,"
- "depth = (int) 24,"
- "width = (int) [ 1, MAX ],"
- "height = (int) [ 1, MAX ],"
- "framerate = (fraction) [ 0, MAX ];"
+ GST_STATIC_CAPS (
+ GST_VIDEO_CAPS_BGR ";"
+ GST_VIDEO_CAPS_YUV ("{ I420 }") ";"
"video/x-dv,"
"systemstream = (boolean) FALSE,"
"width = (int) [ 1, MAX ],"
@@ -55,11 +55,7 @@ static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src",
"framerate = (fraction) [ 0, MAX ],"
"format = (fourcc) dvsd;"
"video/x-dv,"
- "systemstream = (boolean) TRUE;"
- "video/x-raw-yuv,"
- "width = (int) [ 1, MAX ],"
- "height = (int) [ 1, MAX ],"
- "framerate = (fraction) [ 0, MAX ]," "format = (fourcc) I420")
+ "systemstream = (boolean) TRUE")
);
static void gst_dshowvideosrc_init_interfaces (GType type);
@@ -104,6 +100,7 @@ static gboolean gst_dshowvideosrc_unlock (GstBaseSrc * bsrc);
static gboolean gst_dshowvideosrc_unlock_stop (GstBaseSrc * bsrc);
static gboolean gst_dshowvideosrc_set_caps (GstBaseSrc * bsrc, GstCaps * caps);
static GstCaps *gst_dshowvideosrc_get_caps (GstBaseSrc * bsrc);
+static void gst_dshowvideosrc_src_fixate (GstBaseSrc * bsrc, GstCaps * caps);
static GstFlowReturn gst_dshowvideosrc_create (GstPushSrc * psrc,
GstBuffer ** buf);
@@ -170,6 +167,7 @@ gst_dshowvideosrc_class_init (GstDshowVideoSrcClass * klass)
gstbasesrc_class->get_caps = GST_DEBUG_FUNCPTR (gst_dshowvideosrc_get_caps);
gstbasesrc_class->set_caps = GST_DEBUG_FUNCPTR (gst_dshowvideosrc_set_caps);
+ gstbasesrc_class->fixate = GST_DEBUG_FUNCPTR (gst_dshowvideosrc_src_fixate);
gstbasesrc_class->start = GST_DEBUG_FUNCPTR (gst_dshowvideosrc_start);
gstbasesrc_class->stop = GST_DEBUG_FUNCPTR (gst_dshowvideosrc_stop);
gstbasesrc_class->unlock = GST_DEBUG_FUNCPTR (gst_dshowvideosrc_unlock);
@@ -205,6 +203,7 @@ gst_dshowvideosrc_init (GstDshowVideoSrc * src, GstDshowVideoSrcClass * klass)
src->media_filter = NULL;
src->filter_graph = NULL;
src->caps = NULL;
+ src->video_defaults = NULL;
src->pins_mediatypes = NULL;
src->is_rgb = FALSE;
@@ -219,6 +218,36 @@ gst_dshowvideosrc_init (GstDshowVideoSrc * src, GstDshowVideoSrcClass * klass)
}
static void
+gst_dshowvideosrc_src_fixate (GstBaseSrc * bsrc, GstCaps * caps)
+{
+ /* If there is no desired video size, set default video size to device preffered video size */
+
+ GstDshowVideoSrc *src = GST_DSHOWVIDEOSRC (bsrc);
+ GstStructure *structure = gst_caps_get_structure (caps, 0);
+ guint i = 0;
+ gint res = -1;
+
+ for (; i < gst_caps_get_size (src->caps) && res == -1; i++) {
+ GstCaps *capstmp = gst_caps_copy_nth (src->caps, i);
+
+ if (gst_caps_is_subset (caps, capstmp)) {
+ res = i;
+ }
+ gst_caps_unref (capstmp);
+ }
+
+ if (res != -1) {
+ GList *type_video_default = g_list_nth (src->video_defaults, res);
+ if (type_video_default) {
+ GstCaptureVideoDefault *video_default = (GstCaptureVideoDefault *) type_video_default->data;
+ gst_structure_fixate_field_nearest_int (structure, "width", video_default->defaultWidth);
+ gst_structure_fixate_field_nearest_int (structure, "height", video_default->defaultHeight);
+ gst_structure_fixate_field_nearest_fraction (structure, "framerate", video_default->defaultFPS, 1);
+ }
+ }
+}
+
+static void
gst_dshowvideosrc_dispose (GObject * gobject)
{
GstDshowVideoSrc *src = GST_DSHOWVIDEOSRC (gobject);
@@ -238,6 +267,11 @@ gst_dshowvideosrc_dispose (GObject * gobject)
src->caps = NULL;
}
+ if (src->video_defaults) {
+ g_list_free (src->video_defaults);
+ src->video_defaults = NULL;
+ }
+
if (src->pins_mediatypes) {
gst_dshow_free_pins_mediatypes (src->pins_mediatypes);
src->pins_mediatypes = NULL;
@@ -292,7 +326,6 @@ gst_dshowvideosrc_probe_probe_property (GstPropertyProbe * probe,
switch (prop_id) {
case PROP_DEVICE_NAME:
- //gst_v4l_class_probe_devices (klass, FALSE);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (probe, prop_id, pspec);
@@ -320,15 +353,12 @@ static GValueArray *
gst_dshowvideosrc_get_device_name_values (GstDshowVideoSrc * src)
{
GValueArray *array = g_value_array_new (0);
- GValue value = { 0 };
ICreateDevEnum *devices_enum = NULL;
IEnumMoniker *moniker_enum = NULL;
IMoniker *moniker = NULL;
HRESULT hres = S_FALSE;
ULONG fetched;
- g_value_init (&value, G_TYPE_STRING);
-
hres = CoCreateInstance (CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER,
IID_ICreateDevEnum, (LPVOID *) &devices_enum);
if (hres != S_OK) {
@@ -367,6 +397,8 @@ gst_dshowvideosrc_get_device_name_values (GstDshowVideoSrc * src)
g_utf16_to_utf8 ((const gunichar2 *) varFriendlyName.bstrVal,
wcslen (varFriendlyName.bstrVal), NULL, NULL, NULL);
+ GValue value = { 0 };
+ g_value_init (&value, G_TYPE_STRING);
g_value_set_string (&value, friendly_name);
g_value_array_append (array, &value);
g_value_unset (&value);
@@ -556,7 +588,6 @@ static GstStateChangeReturn
gst_dshowvideosrc_change_state (GstElement * element, GstStateChange transition)
{
HRESULT hres = S_FALSE;
- IAMVfwCaptureDialogs *dialog = NULL;
GstDshowVideoSrc *src = GST_DSHOWVIDEOSRC (element);
switch (transition) {
@@ -675,13 +706,51 @@ gst_dshowvideosrc_set_caps (GstBaseSrc * bsrc, GstCaps * caps)
if (res != -1 && src->pins_mediatypes) {
/* get the corresponding media type and build the dshow graph */
- GstCapturePinMediaType *pin_mediatype = NULL;
- gchar *caps_string = NULL;
GList *type = g_list_nth (src->pins_mediatypes, res);
- if (type) {
+ //will be removed when GST_TYPE_INT_RANGE_STEP exits
+ GList *type_video_default = g_list_nth (src->video_defaults, res);
+
+ if (type && type_video_default) {
+ //will be removed when GST_TYPE_INT_RANGE_STEP exits
+ GstCaptureVideoDefault *video_default = (GstCaptureVideoDefault *) type_video_default->data;
+ GstCapturePinMediaType *pin_mediatype = NULL;
+ gchar *caps_string = NULL;
+ gchar *src_caps_string = NULL;
+
+ /* retrieve the desired video size */
+ VIDEOINFOHEADER *video_info = NULL;
+ gint width = 0;
+ gint height = 0;
+ gint numerator = 0;
+ gint denominator = 0;
+ gst_structure_get_int (s, "width", &width);
+ gst_structure_get_int (s, "height", &height);
+ gst_structure_get_fraction (s, "framerate", &numerator, &denominator);
+
+ /* check if the desired video size is valid about granularity */
+ /* This check will be removed when GST_TYPE_INT_RANGE_STEP exits */
+ /* See remarks in gst_dshowvideosrc_getcaps_from_streamcaps function */
+ if (video_default->granularityWidth != 0 && width % video_default->granularityWidth != 0)
+ g_warning ("your desired video size is not valid : %d mod %d !=0\n", width, video_default->granularityWidth) ;
+ if (video_default->granularityHeight !=0 && height % video_default->granularityHeight != 0)
+ g_warning ("your desired video size is not valid : %d mod %d !=0\n", height, video_default->granularityHeight) ;
+
+ /* display all capabilities when using --gst-debug-level=3 */
+ src_caps_string = gst_caps_to_string (src->caps);
+ GST_CAT_LEVEL_LOG (dshowvideosrc_debug, GST_LEVEL_INFO, src, src_caps_string);
+ g_free (src_caps_string);
+
pin_mediatype = (GstCapturePinMediaType *) type->data;
+ /* update mediatype */
+ video_info = (VIDEOINFOHEADER *) pin_mediatype->mediatype->pbFormat;
+ video_info->bmiHeader.biWidth = width;
+ video_info->bmiHeader.biHeight = height;
+ video_info->AvgTimePerFrame = (LONGLONG) (10000000 * denominator / (double)numerator);
+ video_info->bmiHeader.biSizeImage = DIBSIZE(video_info->bmiHeader);
+ pin_mediatype->mediatype->lSampleSize = DIBSIZE(video_info->bmiHeader);
+
src->dshow_fakesink->gst_set_media_type (pin_mediatype->mediatype);
src->dshow_fakesink->gst_set_buffer_callback(
(push_buffer_func) gst_dshowvideosrc_push_buffer, src);
@@ -695,7 +764,7 @@ gst_dshowvideosrc_set_caps (GstBaseSrc * bsrc, GstCaps * caps)
}
hres = src->filter_graph->ConnectDirect(pin_mediatype->capture_pin,
- input_pin, NULL);
+ input_pin, pin_mediatype->mediatype);
input_pin->Release();
if (hres != S_OK) {
@@ -829,7 +898,6 @@ gst_dshowvideosrc_getcaps_from_streamcaps (GstDshowVideoSrc * src, IPin * pin,
{
GstCaps *caps = NULL;
HRESULT hres = S_OK;
- RPC_STATUS rpcstatus;
int icount = 0;
int isize = 0;
VIDEO_STREAM_CONFIG_CAPS vscc;
@@ -845,6 +913,7 @@ gst_dshowvideosrc_getcaps_from_streamcaps (GstDshowVideoSrc * src, IPin * pin,
for (; i < icount; i++) {
GstCapturePinMediaType *pin_mediatype = g_new0 (GstCapturePinMediaType, 1);
+ GstCaptureVideoDefault *video_default = g_new0 (GstCaptureVideoDefault, 1);
pin->AddRef();
pin_mediatype->capture_pin = pin;
@@ -857,91 +926,127 @@ gst_dshowvideosrc_getcaps_from_streamcaps (GstDshowVideoSrc * src, IPin * pin,
if (!caps)
caps = gst_caps_new_empty ();
+ /* some remarks: */
+ /* Hope GST_TYPE_INT_RANGE_STEP will exits in future gstreamer releases */
+ /* because we could use : */
+ /* "width", GST_TYPE_INT_RANGE_STEP, video_default->minWidth, video_default->maxWidth, video_default->granularityWidth */
+ /* instead of : */
+ /* "width", GST_TYPE_INT_RANGE, video_default->minWidth, video_default->maxWidth */
+
+ /* For framerate we do not need a step (granularity) because */
+ /* "The IAMStreamConfig::SetFormat method will set the frame rate to the closest */
+ /* value that the filter supports" as it said in the VIDEO_STREAM_CONFIG_CAPS dshwo doc */
+
/* I420 */
- if ((UuidCompare (&pin_mediatype->mediatype->subtype, (UUID *) &MEDIASUBTYPE_I420,
- &rpcstatus) == 0 && rpcstatus == RPC_S_OK)
- && (UuidCompare (&pin_mediatype->mediatype->formattype,
- (UUID *) &FORMAT_VideoInfo, &rpcstatus) == 0
- && rpcstatus == RPC_S_OK)) {
+ if (gst_dshow_check_mediatype (pin_mediatype->mediatype, MEDIASUBTYPE_I420, FORMAT_VideoInfo)) {
video_info = (VIDEOINFOHEADER *) pin_mediatype->mediatype->pbFormat;
+ video_default->defaultWidth = video_info->bmiHeader.biWidth;
+ video_default->defaultHeight = video_info->bmiHeader.biHeight;
+ video_default->defaultFPS = (int) (10000000 / video_info->AvgTimePerFrame);
+ video_default->granularityWidth = vscc.OutputGranularityX;
+ video_default->granularityHeight = vscc.OutputGranularityY;
+
mediacaps = gst_caps_new_simple ("video/x-raw-yuv",
- "width", G_TYPE_INT, video_info->bmiHeader.biWidth,
- "height", G_TYPE_INT, video_info->bmiHeader.biHeight,
- "framerate", GST_TYPE_FRACTION,
- (int) (10000000 / video_info->AvgTimePerFrame), 1, "format",
- GST_TYPE_FOURCC, MAKEFOURCC ('I', '4', '2', '0'), NULL);
+ "width", GST_TYPE_INT_RANGE, vscc.MinOutputSize.cx, vscc.MaxOutputSize.cx,
+ "height", GST_TYPE_INT_RANGE, vscc.MinOutputSize.cy, vscc.MaxOutputSize.cy,
+ "framerate", GST_TYPE_FRACTION_RANGE,
+ (int) (10000000 / vscc.MaxFrameInterval), 1,
+ (int) (10000000 / vscc.MinFrameInterval), 1,
+ "format", GST_TYPE_FOURCC, MAKEFOURCC ('I', '4', '2', '0'), NULL);
if (mediacaps) {
src->pins_mediatypes =
g_list_append (src->pins_mediatypes, pin_mediatype);
+ src->video_defaults =
+ g_list_append (src->video_defaults, video_default);
gst_caps_append (caps, mediacaps);
} else {
gst_dshow_free_pin_mediatype (pin_mediatype);
+ g_free (video_default);
}
continue;
}
- /* RGB24 */
- if ((UuidCompare (&pin_mediatype->mediatype->subtype, (UUID *) &MEDIASUBTYPE_RGB24,
- &rpcstatus) == 0 && rpcstatus == RPC_S_OK)
- && (UuidCompare (&pin_mediatype->mediatype->formattype,
- (UUID *) &FORMAT_VideoInfo, &rpcstatus) == 0
- && rpcstatus == RPC_S_OK)) {
+ /* BGR */
+ if (gst_dshow_check_mediatype (pin_mediatype->mediatype, MEDIASUBTYPE_RGB24, FORMAT_VideoInfo)) {
video_info = (VIDEOINFOHEADER *) pin_mediatype->mediatype->pbFormat;
+ video_default->defaultWidth = video_info->bmiHeader.biWidth;
+ video_default->defaultHeight = video_info->bmiHeader.biHeight;
+ video_default->defaultFPS = (int) (10000000 / video_info->AvgTimePerFrame);
+ video_default->granularityWidth = vscc.OutputGranularityX;
+ video_default->granularityHeight = vscc.OutputGranularityY;
+
/* ffmpegcolorspace handles RGB24 in BIG_ENDIAN */
mediacaps = gst_caps_new_simple ("video/x-raw-rgb",
- "bpp", G_TYPE_INT, 24,
- "depth", G_TYPE_INT, 24,
- "width", G_TYPE_INT, video_info->bmiHeader.biWidth,
- "height", G_TYPE_INT, video_info->bmiHeader.biHeight,
- "framerate", GST_TYPE_FRACTION,
- (int) (10000000 / video_info->AvgTimePerFrame), 1, "endianness",
- G_TYPE_INT, G_BIG_ENDIAN, "red_mask", G_TYPE_INT, 255, "green_mask",
- G_TYPE_INT, 65280, "blue_mask", G_TYPE_INT, 16711680, NULL);
+ "bpp", G_TYPE_INT, 24,
+ "depth", G_TYPE_INT, 24,
+ "width", GST_TYPE_INT_RANGE, vscc.MinOutputSize.cx, vscc.MaxOutputSize.cx,
+ "height", GST_TYPE_INT_RANGE, vscc.MinOutputSize.cy, vscc.MaxOutputSize.cy,
+ "framerate", GST_TYPE_FRACTION_RANGE,
+ (int) (10000000 / vscc.MaxFrameInterval), 1,
+ (int) (10000000 / vscc.MinFrameInterval), 1,
+ "endianness", G_TYPE_INT, G_BIG_ENDIAN,
+ "red_mask", G_TYPE_INT, 255,
+ "green_mask", G_TYPE_INT, 65280,
+ "blue_mask", G_TYPE_INT, 16711680, NULL);
if (mediacaps) {
src->pins_mediatypes =
g_list_append (src->pins_mediatypes, pin_mediatype);
+ src->video_defaults =
+ g_list_append (src->video_defaults, video_default);
gst_caps_append (caps, mediacaps);
} else {
gst_dshow_free_pin_mediatype (pin_mediatype);
+ g_free (video_default);
}
continue;
}
/* DVSD */
- if ((UuidCompare (&pin_mediatype->mediatype->subtype, (UUID *) &MEDIASUBTYPE_dvsd,
- &rpcstatus) == 0 && rpcstatus == RPC_S_OK)
- && (UuidCompare (&pin_mediatype->mediatype->formattype,
- (UUID *) &FORMAT_VideoInfo, &rpcstatus) == 0
- && rpcstatus == RPC_S_OK)) {
+ if (gst_dshow_check_mediatype (pin_mediatype->mediatype, MEDIASUBTYPE_dvsd, FORMAT_VideoInfo)) {
video_info = (VIDEOINFOHEADER *) pin_mediatype->mediatype->pbFormat;
+ video_default->defaultWidth = video_info->bmiHeader.biWidth;
+ video_default->defaultHeight = video_info->bmiHeader.biHeight;
+ video_default->defaultFPS = (int) (10000000 / video_info->AvgTimePerFrame);
+ video_default->granularityWidth = vscc.OutputGranularityX;
+ video_default->granularityHeight = vscc.OutputGranularityY;
+
mediacaps = gst_caps_new_simple ("video/x-dv",
- "systemstream", G_TYPE_BOOLEAN, FALSE,
- "format", GST_TYPE_FOURCC, GST_MAKE_FOURCC ('d', 'v', 's', 'd'),
- "framerate", GST_TYPE_FRACTION,
- (int) (10000000 / video_info->AvgTimePerFrame), 1, "width",
- G_TYPE_INT, video_info->bmiHeader.biWidth, "height", G_TYPE_INT,
- video_info->bmiHeader.biHeight, NULL);
+ "systemstream", G_TYPE_BOOLEAN, FALSE,
+ "format", GST_TYPE_FOURCC, GST_MAKE_FOURCC ('d', 'v', 's', 'd'),
+ "framerate", GST_TYPE_FRACTION_RANGE,
+ (int) (10000000 / vscc.MaxFrameInterval), 1,
+ (int) (10000000 / vscc.MinFrameInterval), 1,
+ "width", GST_TYPE_INT_RANGE, vscc.MinOutputSize.cx, vscc.MaxOutputSize.cx,
+ "height", GST_TYPE_INT_RANGE, vscc.MinOutputSize.cy, vscc.MaxOutputSize.cy, NULL);
if (mediacaps) {
src->pins_mediatypes =
g_list_append (src->pins_mediatypes, pin_mediatype);
+ src->video_defaults =
+ g_list_append (src->video_defaults, video_default);
gst_caps_append (caps, mediacaps);
} else {
gst_dshow_free_pin_mediatype (pin_mediatype);
+ g_free (video_default);
}
continue;
}
/* DV stream */
- if ((UuidCompare (&pin_mediatype->mediatype->subtype, (UUID *) &MEDIASUBTYPE_dvsd,
- &rpcstatus) == 0 && rpcstatus == RPC_S_OK)
- && (UuidCompare (&pin_mediatype->mediatype->formattype,
- (UUID *) &FORMAT_DvInfo, &rpcstatus) == 0 && rpcstatus == RPC_S_OK)) {
+ if (gst_dshow_check_mediatype (pin_mediatype->mediatype, MEDIASUBTYPE_dvsd, FORMAT_DvInfo)) {
+ video_info = (VIDEOINFOHEADER *) pin_mediatype->mediatype->pbFormat;
+
+ //No video size in caps when stream ? I do know if the following fields exist
+ video_default->defaultWidth = video_info->bmiHeader.biWidth;
+ video_default->defaultHeight = video_info->bmiHeader.biHeight;
+ video_default->defaultFPS = (int) (10000000 / video_info->AvgTimePerFrame);
+ video_default->granularityWidth = vscc.OutputGranularityX;
+ video_default->granularityHeight = vscc.OutputGranularityY;
mediacaps = gst_caps_new_simple ("video/x-dv",
"systemstream", G_TYPE_BOOLEAN, TRUE, NULL);
@@ -949,14 +1054,18 @@ gst_dshowvideosrc_getcaps_from_streamcaps (GstDshowVideoSrc * src, IPin * pin,
if (mediacaps) {
src->pins_mediatypes =
g_list_append (src->pins_mediatypes, pin_mediatype);
+ src->video_defaults =
+ g_list_append (src->video_defaults, video_default);
gst_caps_append (caps, mediacaps);
} else {
gst_dshow_free_pin_mediatype (pin_mediatype);
+ g_free (video_default);
}
continue;
}
} else {
gst_dshow_free_pin_mediatype (pin_mediatype);
+ g_free (video_default);
}
}
diff --git a/sys/dshowsrcwrapper/gstdshowvideosrc.h b/sys/dshowsrcwrapper/gstdshowvideosrc.h
index bf94e61f..41583071 100755..100644
--- a/sys/dshowsrcwrapper/gstdshowvideosrc.h
+++ b/sys/dshowsrcwrapper/gstdshowvideosrc.h
@@ -42,6 +42,18 @@ G_BEGIN_DECLS
typedef struct _GstDshowVideoSrc GstDshowVideoSrc;
typedef struct _GstDshowVideoSrcClass GstDshowVideoSrcClass;
+/* video default properties associated to a video format (YUY2, I420, RGB24 ...) */
+typedef struct _GstCaptureVideoDefault
+{
+ gint defaultWidth;
+ gint defaultHeight;
+ gint defaultFPS;
+
+ gint granularityWidth; //will be removed when GST_TYPE_INT_RANGE_STEP exits
+ gint granularityHeight; //will be removed when GST_TYPE_INT_RANGE_STEP exits
+
+} GstCaptureVideoDefault;
+
struct _GstDshowVideoSrc
{
GstPushSrc src;
@@ -55,6 +67,9 @@ struct _GstDshowVideoSrc
/* list of caps created from the list of supported media types of the dshow capture filter */
GstCaps *caps;
+ /* list of dshow default video properties from filter's capture pins */
+ GList *video_defaults;
+
/* list of dshow media types from the filter's capture pins */
GList *pins_mediatypes;