summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNirbheek Chauhan <nirbheek@centricular.com>2018-02-26 15:55:19 +0530
committerNirbheek Chauhan <nirbheek@centricular.com>2018-02-26 16:23:11 +0530
commit995059dc87eca5c42b960b475979613ba6d9b4a2 (patch)
tree79baf199ac1c67e860a489a8975b1f6b3b36ab01
parentf7d0ce2477f58896551fe52c826da0184febf3ff (diff)
wasapi: Add a property for trying the AudioClient3 API
The AudioClient3 API is only available on Windows 10, and we will automatically detect when it is available and use it. However, using it for capturing audio with low latency and without glitches seems to require setting the realtime priority of the entire pipeline to "critical", which we cannot do from inside the element. Hence, we can only enable that by default for wasapisink since apps should be able to safely set the low-latency property to TRUE if they need low-latency capture or playback.
-rw-r--r--sys/wasapi/gstwasapisink.c35
-rw-r--r--sys/wasapi/gstwasapisink.h1
-rw-r--r--sys/wasapi/gstwasapisrc.c35
-rw-r--r--sys/wasapi/gstwasapisrc.h1
4 files changed, 64 insertions, 8 deletions
diff --git a/sys/wasapi/gstwasapisink.c b/sys/wasapi/gstwasapisink.c
index 7ef0516f8..e6a0e826a 100644
--- a/sys/wasapi/gstwasapisink.c
+++ b/sys/wasapi/gstwasapisink.c
@@ -54,6 +54,7 @@ static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink",
#define DEFAULT_MUTE FALSE
#define DEFAULT_EXCLUSIVE FALSE
#define DEFAULT_LOW_LATENCY FALSE
+#define DEFAULT_AUDIOCLIENT3 TRUE
enum
{
@@ -62,7 +63,8 @@ enum
PROP_MUTE,
PROP_DEVICE,
PROP_EXCLUSIVE,
- PROP_LOW_LATENCY
+ PROP_LOW_LATENCY,
+ PROP_AUDIOCLIENT3
};
static void gst_wasapi_sink_dispose (GObject * object);
@@ -132,6 +134,12 @@ gst_wasapi_sink_class_init (GstWasapiSinkClass * klass)
"Optimize all settings for lowest latency",
DEFAULT_LOW_LATENCY, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+ g_object_class_install_property (gobject_class,
+ PROP_AUDIOCLIENT3,
+ g_param_spec_boolean ("use-audioclient3", "Use the AudioClient3 API",
+ "Use the Windows 10 AudioClient3 API when available",
+ DEFAULT_AUDIOCLIENT3, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
gst_element_class_add_static_pad_template (gstelement_class, &sink_template);
gst_element_class_set_static_metadata (gstelement_class, "WasapiSrc",
"Sink/Audio",
@@ -155,6 +163,11 @@ gst_wasapi_sink_class_init (GstWasapiSinkClass * klass)
static void
gst_wasapi_sink_init (GstWasapiSink * self)
{
+ self->role = DEFAULT_ROLE;
+ self->mute = DEFAULT_MUTE;
+ self->sharemode = AUDCLNT_SHAREMODE_SHARED;
+ self->low_latency = DEFAULT_LOW_LATENCY;
+ self->try_audioclient3 = DEFAULT_AUDIOCLIENT3;
self->event_handle = CreateEvent (NULL, FALSE, FALSE, NULL);
CoInitialize (NULL);
@@ -232,6 +245,9 @@ gst_wasapi_sink_set_property (GObject * object, guint prop_id,
case PROP_LOW_LATENCY:
self->low_latency = g_value_get_boolean (value);
break;
+ case PROP_AUDIOCLIENT3:
+ self->try_audioclient3 = g_value_get_boolean (value);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -262,12 +278,24 @@ gst_wasapi_sink_get_property (GObject * object, guint prop_id,
case PROP_LOW_LATENCY:
g_value_set_boolean (value, self->low_latency);
break;
+ case PROP_AUDIOCLIENT3:
+ g_value_set_boolean (value, self->try_audioclient3);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
+static gboolean
+gst_wasapi_sink_can_audioclient3 (GstWasapiSink * self)
+{
+ if (self->sharemode == AUDCLNT_SHAREMODE_SHARED &&
+ self->try_audioclient3 && gst_wasapi_util_have_audioclient3 ())
+ return TRUE;
+ return FALSE;
+}
+
static GstCaps *
gst_wasapi_sink_get_caps (GstBaseSink * bsink, GstCaps * filter)
{
@@ -416,8 +444,7 @@ gst_wasapi_sink_prepare (GstAudioSink * asink, GstAudioRingBufferSpec * spec)
guint bpf, rate, devicep_frames;
HRESULT hr;
- if (self->sharemode == AUDCLNT_SHAREMODE_SHARED &&
- gst_wasapi_util_have_audioclient3 ()) {
+ if (gst_wasapi_sink_can_audioclient3 (self)) {
if (!gst_wasapi_util_initialize_audioclient3 (GST_ELEMENT (self), spec,
(IAudioClient3 *) self->client, self->mix_format, self->low_latency,
&devicep_frames))
@@ -521,7 +548,7 @@ gst_wasapi_sink_unprepare (GstAudioSink * asink)
GstWasapiSink *self = GST_WASAPI_SINK (asink);
if (self->sharemode == AUDCLNT_SHAREMODE_EXCLUSIVE &&
- !gst_wasapi_util_have_audioclient3 ())
+ !gst_wasapi_sink_can_audioclient3 (self))
CoUninitialize ();
if (self->thread_priority_handle != NULL) {
diff --git a/sys/wasapi/gstwasapisink.h b/sys/wasapi/gstwasapisink.h
index e445ce290..c17866991 100644
--- a/sys/wasapi/gstwasapisink.h
+++ b/sys/wasapi/gstwasapisink.h
@@ -62,6 +62,7 @@ struct _GstWasapiSink
gint sharemode;
gboolean mute;
gboolean low_latency;
+ gboolean try_audioclient3;
wchar_t *device_strid;
};
diff --git a/sys/wasapi/gstwasapisrc.c b/sys/wasapi/gstwasapisrc.c
index 93b166e4d..f1fd6415d 100644
--- a/sys/wasapi/gstwasapisrc.c
+++ b/sys/wasapi/gstwasapisrc.c
@@ -51,6 +51,7 @@ static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src",
#define DEFAULT_ROLE GST_WASAPI_DEVICE_ROLE_CONSOLE
#define DEFAULT_EXCLUSIVE FALSE
#define DEFAULT_LOW_LATENCY FALSE
+#define DEFAULT_AUDIOCLIENT3 FALSE
enum
{
@@ -58,7 +59,8 @@ enum
PROP_ROLE,
PROP_DEVICE,
PROP_EXCLUSIVE,
- PROP_LOW_LATENCY
+ PROP_LOW_LATENCY,
+ PROP_AUDIOCLIENT3
};
static void gst_wasapi_src_dispose (GObject * object);
@@ -124,6 +126,12 @@ gst_wasapi_src_class_init (GstWasapiSrcClass * klass)
"Optimize all settings for lowest latency",
DEFAULT_LOW_LATENCY, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+ g_object_class_install_property (gobject_class,
+ PROP_AUDIOCLIENT3,
+ g_param_spec_boolean ("use-audioclient3", "Use the AudioClient3 API",
+ "Whether to use the Windows 10 AudioClient3 API when available",
+ DEFAULT_AUDIOCLIENT3, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
gst_element_class_add_static_pad_template (gstelement_class, &src_template);
gst_element_class_set_static_metadata (gstelement_class, "WasapiSrc",
"Source/Audio",
@@ -155,6 +163,10 @@ gst_wasapi_src_init (GstWasapiSrc * self)
gst_wasapi_src_get_time, gst_object_ref (self),
(GDestroyNotify) gst_object_unref);
+ self->role = DEFAULT_ROLE;
+ self->sharemode = AUDCLNT_SHAREMODE_SHARED;
+ self->low_latency = DEFAULT_LOW_LATENCY;
+ self->try_audioclient3 = DEFAULT_AUDIOCLIENT3;
self->event_handle = CreateEvent (NULL, FALSE, FALSE, NULL);
CoInitialize (NULL);
@@ -229,6 +241,9 @@ gst_wasapi_src_set_property (GObject * object, guint prop_id,
case PROP_LOW_LATENCY:
self->low_latency = g_value_get_boolean (value);
break;
+ case PROP_AUDIOCLIENT3:
+ self->try_audioclient3 = g_value_get_boolean (value);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -256,12 +271,24 @@ gst_wasapi_src_get_property (GObject * object, guint prop_id,
case PROP_LOW_LATENCY:
g_value_set_boolean (value, self->low_latency);
break;
+ case PROP_AUDIOCLIENT3:
+ g_value_set_boolean (value, self->try_audioclient3);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
+static gboolean
+gst_wasapi_src_can_audioclient3 (GstWasapiSrc * self)
+{
+ if (self->sharemode == AUDCLNT_SHAREMODE_SHARED &&
+ self->try_audioclient3 && gst_wasapi_util_have_audioclient3 ())
+ return TRUE;
+ return FALSE;
+}
+
static GstCaps *
gst_wasapi_src_get_caps (GstBaseSrc * bsrc, GstCaps * filter)
{
@@ -384,8 +411,7 @@ gst_wasapi_src_prepare (GstAudioSrc * asrc, GstAudioRingBufferSpec * spec)
guint bpf, rate, devicep_frames, buffer_frames;
HRESULT hr;
- if (self->sharemode == AUDCLNT_SHAREMODE_SHARED &&
- gst_wasapi_util_have_audioclient3 ()) {
+ if (gst_wasapi_src_can_audioclient3 (self)) {
if (!gst_wasapi_util_initialize_audioclient3 (GST_ELEMENT (self), spec,
(IAudioClient3 *) self->client, self->mix_format, self->low_latency,
&devicep_frames))
@@ -466,7 +492,8 @@ gst_wasapi_src_unprepare (GstAudioSrc * asrc)
{
GstWasapiSrc *self = GST_WASAPI_SRC (asrc);
- if (self->sharemode == AUDCLNT_SHAREMODE_EXCLUSIVE)
+ if (self->sharemode == AUDCLNT_SHAREMODE_EXCLUSIVE &&
+ !gst_wasapi_src_can_audioclient3 (self))
CoUninitialize ();
if (self->thread_priority_handle != NULL) {
diff --git a/sys/wasapi/gstwasapisrc.h b/sys/wasapi/gstwasapisrc.h
index ca3f64146..21e4647e8 100644
--- a/sys/wasapi/gstwasapisrc.h
+++ b/sys/wasapi/gstwasapisrc.h
@@ -63,6 +63,7 @@ struct _GstWasapiSrc
gint role;
gint sharemode;
gboolean low_latency;
+ gboolean try_audioclient3;
wchar_t *device_strid;
};