mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-28 11:10:37 +00:00
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
This commit is contained in:
parent
7f1d60da5b
commit
cbe2fc40a4
1 changed files with 30 additions and 3 deletions
|
@ -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);
|
||||
|
||||
|
|
Loading…
Reference in a new issue