diff options
author | Dave Robillard <dave@drobilla.net> | 2009-08-12 01:09:13 -0400 |
---|---|---|
committer | Dave Robillard <dave@drobilla.net> | 2009-08-12 01:09:13 -0400 |
commit | 41f47a3d610a99ac7e3ed85f6ef3f5c130487c36 (patch) | |
tree | 32e5a05cae35f825d43e8439ff6040e3d0c2e90d /sys | |
parent | 882524e727a1c378be79f0425298243c24aa3adf (diff) | |
parent | e46ff7bda0f7996b456476dccb4a822688a690fb (diff) | |
download | gst-plugins-bad-41f47a3d610a99ac7e3ed85f6ef3f5c130487c36.tar.gz gst-plugins-bad-41f47a3d610a99ac7e3ed85f6ef3f5c130487c36.tar.bz2 gst-plugins-bad-41f47a3d610a99ac7e3ed85f6ef3f5c130487c36.zip |
Merge branch 'fdo' into lv2
Diffstat (limited to 'sys')
-rw-r--r-- | sys/directdraw/gstdirectdrawsink.c | 10 | ||||
-rwxr-xr-x[-rw-r--r--] | sys/directsound/gstdirectsoundsrc.c | 1179 | ||||
-rw-r--r--[-rwxr-xr-x] | sys/dshowsrcwrapper/Makefile.am | 0 | ||||
-rw-r--r--[-rwxr-xr-x] | sys/dshowsrcwrapper/gstdshow.cpp | 15 | ||||
-rw-r--r--[-rwxr-xr-x] | sys/dshowsrcwrapper/gstdshow.h | 3 | ||||
-rw-r--r--[-rwxr-xr-x] | sys/dshowsrcwrapper/gstdshowaudiosrc.cpp | 23 | ||||
-rw-r--r--[-rwxr-xr-x] | sys/dshowsrcwrapper/gstdshowaudiosrc.h | 0 | ||||
-rw-r--r--[-rwxr-xr-x] | sys/dshowsrcwrapper/gstdshowfakesink.cpp | 0 | ||||
-rw-r--r--[-rwxr-xr-x] | sys/dshowsrcwrapper/gstdshowfakesink.h | 0 | ||||
-rw-r--r--[-rwxr-xr-x] | sys/dshowsrcwrapper/gstdshowsrcwrapper.cpp | 0 | ||||
-rw-r--r--[-rwxr-xr-x] | sys/dshowsrcwrapper/gstdshowvideosrc.cpp | 229 | ||||
-rw-r--r--[-rwxr-xr-x] | sys/dshowsrcwrapper/gstdshowvideosrc.h | 15 |
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; |