mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-22 23:28:16 +00:00
directsoundsink: allow specifying audio playback device
https://bugzilla.gnome.org/show_bug.cgi?id=753670
This commit is contained in:
parent
0899529222
commit
5c680333ba
3 changed files with 72 additions and 4 deletions
|
@ -388,7 +388,7 @@ AG_GST_CHECK_FEATURE(DIRECTSOUND, [DirectSound plug-in], directsoundsink, [
|
||||||
save_LIBS="$LIBS"
|
save_LIBS="$LIBS"
|
||||||
CFLAGS="$CFLAGS $DIRECTSOUND_CFLAGS"
|
CFLAGS="$CFLAGS $DIRECTSOUND_CFLAGS"
|
||||||
LDFLAGS="$LDFLAGS $DIRECTSOUND_LDFLAGS"
|
LDFLAGS="$LDFLAGS $DIRECTSOUND_LDFLAGS"
|
||||||
LIBS="$LIBS -ldsound -ldxerr9 -luser32"
|
LIBS="$LIBS -ldsound -ldxerr9 -luser32 -lole32"
|
||||||
AC_MSG_CHECKING(for DirectSound LDFLAGS)
|
AC_MSG_CHECKING(for DirectSound LDFLAGS)
|
||||||
AC_LINK_IFELSE([AC_LANG_PROGRAM([[
|
AC_LINK_IFELSE([AC_LANG_PROGRAM([[
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
@ -397,6 +397,7 @@ AG_GST_CHECK_FEATURE(DIRECTSOUND, [DirectSound plug-in], directsoundsink, [
|
||||||
]], [[
|
]], [[
|
||||||
DXGetErrorString9 (0);
|
DXGetErrorString9 (0);
|
||||||
DirectSoundCreate(NULL, NULL, NULL);
|
DirectSoundCreate(NULL, NULL, NULL);
|
||||||
|
CLSIDFromString(NULL, NULL);
|
||||||
]])
|
]])
|
||||||
],
|
],
|
||||||
[HAVE_DIRECTSOUND="yes"],
|
[HAVE_DIRECTSOUND="yes"],
|
||||||
|
@ -408,7 +409,7 @@ AG_GST_CHECK_FEATURE(DIRECTSOUND, [DirectSound plug-in], directsoundsink, [
|
||||||
|
|
||||||
if test "x$HAVE_DIRECTSOUND" = "xyes"; then
|
if test "x$HAVE_DIRECTSOUND" = "xyes"; then
|
||||||
dnl this is much more than we want
|
dnl this is much more than we want
|
||||||
DIRECTSOUND_LIBS="-ldsound -ldxerr9 -luser32"
|
DIRECTSOUND_LIBS="-ldsound -ldxerr9 -luser32 -lole32"
|
||||||
AC_SUBST(DIRECTSOUND_CFLAGS)
|
AC_SUBST(DIRECTSOUND_CFLAGS)
|
||||||
AC_SUBST(DIRECTSOUND_LDFLAGS)
|
AC_SUBST(DIRECTSOUND_LDFLAGS)
|
||||||
AC_SUBST(DIRECTSOUND_LIBS)
|
AC_SUBST(DIRECTSOUND_LIBS)
|
||||||
|
|
|
@ -101,6 +101,10 @@ static gdouble gst_directsound_sink_get_volume (GstDirectSoundSink * sink);
|
||||||
static void gst_directsound_sink_set_mute (GstDirectSoundSink * sink,
|
static void gst_directsound_sink_set_mute (GstDirectSoundSink * sink,
|
||||||
gboolean mute);
|
gboolean mute);
|
||||||
static gboolean gst_directsound_sink_get_mute (GstDirectSoundSink * sink);
|
static gboolean gst_directsound_sink_get_mute (GstDirectSoundSink * sink);
|
||||||
|
static const gchar *gst_directsound_sink_get_device (GstDirectSoundSink *
|
||||||
|
dsoundsink);
|
||||||
|
static void gst_directsound_sink_set_device (GstDirectSoundSink * dsoundsink,
|
||||||
|
const gchar * device_id);
|
||||||
|
|
||||||
static gboolean gst_directsound_sink_is_spdif_format (GstAudioRingBufferSpec *
|
static gboolean gst_directsound_sink_is_spdif_format (GstAudioRingBufferSpec *
|
||||||
spec);
|
spec);
|
||||||
|
@ -124,7 +128,8 @@ enum
|
||||||
{
|
{
|
||||||
PROP_0,
|
PROP_0,
|
||||||
PROP_VOLUME,
|
PROP_VOLUME,
|
||||||
PROP_MUTE
|
PROP_MUTE,
|
||||||
|
PROP_DEVICE
|
||||||
};
|
};
|
||||||
|
|
||||||
#define gst_directsound_sink_parent_class parent_class
|
#define gst_directsound_sink_parent_class parent_class
|
||||||
|
@ -137,6 +142,9 @@ gst_directsound_sink_finalize (GObject * object)
|
||||||
{
|
{
|
||||||
GstDirectSoundSink *dsoundsink = GST_DIRECTSOUND_SINK (object);
|
GstDirectSoundSink *dsoundsink = GST_DIRECTSOUND_SINK (object);
|
||||||
|
|
||||||
|
g_free (dsoundsink->device_id);
|
||||||
|
dsoundsink->device_id = NULL;
|
||||||
|
|
||||||
g_mutex_clear (&dsoundsink->dsound_lock);
|
g_mutex_clear (&dsoundsink->dsound_lock);
|
||||||
|
|
||||||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
G_OBJECT_CLASS (parent_class)->finalize (object);
|
||||||
|
@ -189,6 +197,12 @@ gst_directsound_sink_class_init (GstDirectSoundSinkClass * klass)
|
||||||
"Mute state of this stream", DEFAULT_MUTE,
|
"Mute state of this stream", DEFAULT_MUTE,
|
||||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||||
|
|
||||||
|
g_object_class_install_property (gobject_class,
|
||||||
|
PROP_DEVICE,
|
||||||
|
g_param_spec_string ("device", "Device",
|
||||||
|
"DirectSound playback device as a GUID string",
|
||||||
|
NULL, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||||
|
|
||||||
gst_element_class_set_static_metadata (element_class,
|
gst_element_class_set_static_metadata (element_class,
|
||||||
"Direct Sound Audio Sink", "Sink/Audio",
|
"Direct Sound Audio Sink", "Sink/Audio",
|
||||||
"Output to a sound card via Direct Sound",
|
"Output to a sound card via Direct Sound",
|
||||||
|
@ -203,6 +217,7 @@ gst_directsound_sink_init (GstDirectSoundSink * dsoundsink)
|
||||||
{
|
{
|
||||||
dsoundsink->volume = 100;
|
dsoundsink->volume = 100;
|
||||||
dsoundsink->mute = FALSE;
|
dsoundsink->mute = FALSE;
|
||||||
|
dsoundsink->device_id = NULL;
|
||||||
dsoundsink->pDS = NULL;
|
dsoundsink->pDS = NULL;
|
||||||
dsoundsink->cached_caps = NULL;
|
dsoundsink->cached_caps = NULL;
|
||||||
dsoundsink->pDSBSecondary = NULL;
|
dsoundsink->pDSBSecondary = NULL;
|
||||||
|
@ -226,6 +241,9 @@ gst_directsound_sink_set_property (GObject * object,
|
||||||
case PROP_MUTE:
|
case PROP_MUTE:
|
||||||
gst_directsound_sink_set_mute (sink, g_value_get_boolean (value));
|
gst_directsound_sink_set_mute (sink, g_value_get_boolean (value));
|
||||||
break;
|
break;
|
||||||
|
case PROP_DEVICE:
|
||||||
|
gst_directsound_sink_set_device (sink, g_value_get_string (value));
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
break;
|
break;
|
||||||
|
@ -245,6 +263,9 @@ gst_directsound_sink_get_property (GObject * object,
|
||||||
case PROP_MUTE:
|
case PROP_MUTE:
|
||||||
g_value_set_boolean (value, gst_directsound_sink_get_mute (sink));
|
g_value_set_boolean (value, gst_directsound_sink_get_mute (sink));
|
||||||
break;
|
break;
|
||||||
|
case PROP_DEVICE:
|
||||||
|
g_value_set_string (value, gst_directsound_sink_get_device (sink));
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
break;
|
break;
|
||||||
|
@ -378,22 +399,51 @@ gst_directsound_sink_query (GstBaseSink * sink, GstQuery * query)
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static LPGUID
|
||||||
|
string_to_guid (const gchar * str)
|
||||||
|
{
|
||||||
|
HRESULT ret;
|
||||||
|
gunichar2 *wstr;
|
||||||
|
LPGUID out;
|
||||||
|
|
||||||
|
wstr = g_utf8_to_utf16 (str, -1, NULL, NULL, NULL);
|
||||||
|
if (!wstr)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
out = g_new (GUID, 1);
|
||||||
|
ret = CLSIDFromString ((LPOLESTR) wstr, out);
|
||||||
|
g_free (wstr);
|
||||||
|
if (ret != NOERROR) {
|
||||||
|
g_free (out);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_directsound_sink_open (GstAudioSink * asink)
|
gst_directsound_sink_open (GstAudioSink * asink)
|
||||||
{
|
{
|
||||||
GstDirectSoundSink *dsoundsink;
|
GstDirectSoundSink *dsoundsink;
|
||||||
HRESULT hRes;
|
HRESULT hRes;
|
||||||
|
LPGUID lpGuid = NULL;
|
||||||
|
|
||||||
dsoundsink = GST_DIRECTSOUND_SINK (asink);
|
dsoundsink = GST_DIRECTSOUND_SINK (asink);
|
||||||
|
|
||||||
|
if (dsoundsink->device_id)
|
||||||
|
lpGuid = string_to_guid (dsoundsink->device_id);
|
||||||
|
|
||||||
/* create and initialize a DirecSound object */
|
/* create and initialize a DirecSound object */
|
||||||
if (FAILED (hRes = DirectSoundCreate (NULL, &dsoundsink->pDS, NULL))) {
|
if (FAILED (hRes = DirectSoundCreate (lpGuid, &dsoundsink->pDS, NULL))) {
|
||||||
GST_ELEMENT_ERROR (dsoundsink, RESOURCE, OPEN_READ,
|
GST_ELEMENT_ERROR (dsoundsink, RESOURCE, OPEN_READ,
|
||||||
("gst_directsound_sink_open: DirectSoundCreate: %s",
|
("gst_directsound_sink_open: DirectSoundCreate: %s",
|
||||||
DXGetErrorString9 (hRes)), (NULL));
|
DXGetErrorString9 (hRes)), (NULL));
|
||||||
|
g_free (lpGuid);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
g_free (lpGuid);
|
||||||
|
|
||||||
if (FAILED (hRes = IDirectSound_SetCooperativeLevel (dsoundsink->pDS,
|
if (FAILED (hRes = IDirectSound_SetCooperativeLevel (dsoundsink->pDS,
|
||||||
GetDesktopWindow (), DSSCL_PRIORITY))) {
|
GetDesktopWindow (), DSSCL_PRIORITY))) {
|
||||||
GST_ELEMENT_ERROR (dsoundsink, RESOURCE, OPEN_READ,
|
GST_ELEMENT_ERROR (dsoundsink, RESOURCE, OPEN_READ,
|
||||||
|
@ -874,3 +924,17 @@ gst_directsound_sink_get_mute (GstDirectSoundSink * dsoundsink)
|
||||||
{
|
{
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const gchar *
|
||||||
|
gst_directsound_sink_get_device (GstDirectSoundSink * dsoundsink)
|
||||||
|
{
|
||||||
|
return dsoundsink->device_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gst_directsound_sink_set_device (GstDirectSoundSink * dsoundsink,
|
||||||
|
const gchar * device_id)
|
||||||
|
{
|
||||||
|
g_free (dsoundsink->device_id);
|
||||||
|
dsoundsink->device_id = g_strdup (device_id);
|
||||||
|
}
|
||||||
|
|
|
@ -74,6 +74,9 @@ struct _GstDirectSoundSink
|
||||||
/* current volume setup by mixer interface */
|
/* current volume setup by mixer interface */
|
||||||
glong volume;
|
glong volume;
|
||||||
gboolean mute;
|
gboolean mute;
|
||||||
|
|
||||||
|
/* current directsound device ID */
|
||||||
|
gchar * device_id;
|
||||||
|
|
||||||
GstCaps *cached_caps;
|
GstCaps *cached_caps;
|
||||||
/* lock used to protect writes and resets */
|
/* lock used to protect writes and resets */
|
||||||
|
|
Loading…
Reference in a new issue