summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNirbheek Chauhan <nirbheek@centricular.com>2018-02-08 03:11:10 +0530
committerNirbheek Chauhan <nirbheek@centricular.com>2018-02-08 14:29:58 +0530
commitcbe2fc40a473d1587efbb770b76b88a720c22f1f (patch)
tree24fa82c217d457fee1e62d4b8cc6f13573e9c6ab
parent7f1d60da5bdb1be80fc1a88904e606ef6897aa14 (diff)
downloadgstreamer-plugins-bad-cbe2fc40a473d1587efbb770b76b88a720c22f1f.tar.gz
wasapisink: Re-align device period if necessary
Sometimes the minimum period advertised by a card results in an unaligned buffer size error during initialization in exclusive mode. In that case, we can fetch the actual buffer size in frames and calculate the period from that. We can't do this pre-emptively because we can't call GetBufferSize till Initialize has been called at least once. https://bugzilla.gnome.org/show_bug.cgi?id=793289
-rw-r--r--sys/wasapi/gstwasapisink.c33
1 files changed, 30 insertions, 3 deletions
diff --git a/sys/wasapi/gstwasapisink.c b/sys/wasapi/gstwasapisink.c
index c8cfd729b..bfb1192c8 100644
--- a/sys/wasapi/gstwasapisink.c
+++ b/sys/wasapi/gstwasapisink.c
@@ -434,6 +434,9 @@ gst_wasapi_sink_prepare (GstAudioSink * asink, GstAudioRingBufferSpec * spec)
GST_INFO_OBJECT (self, "wasapi default period: %" G_GINT64_FORMAT
", min period: %" G_GINT64_FORMAT, default_period, min_period);
+ bpf = GST_AUDIO_INFO_BPF (&spec->info);
+ rate = GST_AUDIO_INFO_RATE (&spec->info);
+
if (self->low_latency) {
if (self->sharemode == AUDCLNT_SHAREMODE_SHARED) {
device_period = default_period;
@@ -458,6 +461,33 @@ gst_wasapi_sink_prepare (GstAudioSink * asink, GstAudioRingBufferSpec * spec)
/* This must always be 0 in shared mode */
self->sharemode == AUDCLNT_SHAREMODE_SHARED ? 0 : device_period,
self->mix_format, NULL);
+
+ if (hr == AUDCLNT_E_BUFFER_SIZE_NOT_ALIGNED &&
+ self->sharemode == AUDCLNT_SHAREMODE_EXCLUSIVE) {
+ guint32 n_frames;
+
+ GST_WARNING_OBJECT (self, "initialize failed due to unaligned period %i",
+ (int) device_period);
+
+ /* Calculate a new aligned period. First get the aligned buffer size. */
+ hr = IAudioClient_GetBufferSize (self->client, &n_frames);
+ if (hr != S_OK) {
+ gchar *msg = gst_wasapi_util_hresult_to_string (hr);
+ GST_ELEMENT_ERROR (self, RESOURCE, OPEN_WRITE, (NULL),
+ ("IAudioClient::GetBufferSize() failed: %s", msg));
+ g_free (msg);
+ goto beach;
+ }
+
+ device_period = (GST_SECOND / 100) * n_frames / rate;
+
+ GST_WARNING_OBJECT (self, "trying to re-initialize with period %i",
+ (int) device_period);
+
+ hr = IAudioClient_Initialize (self->client, self->sharemode,
+ AUDCLNT_STREAMFLAGS_EVENTCALLBACK, device_period,
+ device_period, self->mix_format, NULL);
+ }
if (hr != S_OK) {
gchar *msg = gst_wasapi_util_hresult_to_string (hr);
GST_ELEMENT_ERROR (self, RESOURCE, OPEN_WRITE, (NULL),
@@ -472,9 +502,6 @@ gst_wasapi_sink_prepare (GstAudioSink * asink, GstAudioRingBufferSpec * spec)
GST_ERROR_OBJECT (self, "IAudioClient::GetBufferSize failed");
goto beach;
}
-
- bpf = GST_AUDIO_INFO_BPF (&spec->info);
- rate = GST_AUDIO_INFO_RATE (&spec->info);
GST_INFO_OBJECT (self, "buffer size is %i frames, bpf is %i bytes, "
"rate is %i Hz", self->buffer_frame_count, bpf, rate);