mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-26 11:41:09 +00:00
wasapi2: Respect ringbuffer buffer/latency time
Decide buffer size based on configured buffer/latency time if low-latency is disabled, so that ringbuffer can buffer more than minimum required size. Fixes: https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/2870 Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/6215>
This commit is contained in:
parent
fb8131b7da
commit
7ff7ced388
1 changed files with 29 additions and 8 deletions
|
@ -869,13 +869,15 @@ gst_wasapi2_ring_buffer_initialize_audio_client3 (GstWasapi2RingBuffer * self,
|
||||||
static HRESULT
|
static HRESULT
|
||||||
gst_wasapi2_ring_buffer_initialize_audio_client (GstWasapi2RingBuffer * self,
|
gst_wasapi2_ring_buffer_initialize_audio_client (GstWasapi2RingBuffer * self,
|
||||||
IAudioClient * client_handle, WAVEFORMATEX * mix_format, guint * period,
|
IAudioClient * client_handle, WAVEFORMATEX * mix_format, guint * period,
|
||||||
DWORD extra_flags, GstWasapi2ClientDeviceClass device_class)
|
DWORD extra_flags, GstWasapi2ClientDeviceClass device_class,
|
||||||
|
GstAudioRingBufferSpec * spec, gboolean low_latency)
|
||||||
{
|
{
|
||||||
GstAudioRingBuffer *ringbuffer = GST_AUDIO_RING_BUFFER_CAST (self);
|
GstAudioRingBuffer *ringbuffer = GST_AUDIO_RING_BUFFER_CAST (self);
|
||||||
REFERENCE_TIME default_period, min_period;
|
REFERENCE_TIME default_period, min_period;
|
||||||
DWORD stream_flags =
|
DWORD stream_flags =
|
||||||
AUDCLNT_STREAMFLAGS_EVENTCALLBACK | AUDCLNT_STREAMFLAGS_NOPERSIST;
|
AUDCLNT_STREAMFLAGS_EVENTCALLBACK | AUDCLNT_STREAMFLAGS_NOPERSIST;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
REFERENCE_TIME buf_dur = 0;
|
||||||
|
|
||||||
stream_flags |= extra_flags;
|
stream_flags |= extra_flags;
|
||||||
|
|
||||||
|
@ -889,12 +891,29 @@ gst_wasapi2_ring_buffer_initialize_audio_client (GstWasapi2RingBuffer * self,
|
||||||
GST_INFO_OBJECT (self, "wasapi2 default period: %" G_GINT64_FORMAT
|
GST_INFO_OBJECT (self, "wasapi2 default period: %" G_GINT64_FORMAT
|
||||||
", min period: %" G_GINT64_FORMAT, default_period, min_period);
|
", min period: %" G_GINT64_FORMAT, default_period, min_period);
|
||||||
|
|
||||||
|
/* https://learn.microsoft.com/en-us/windows/win32/api/audioclient/nf-audioclient-iaudioclient-initialize
|
||||||
|
* For a shared-mode stream that uses event-driven buffering,
|
||||||
|
* the caller must set both hnsPeriodicity and hnsBufferDuration to 0
|
||||||
|
*
|
||||||
|
* The above MS documentation does not seem to correct. By setting
|
||||||
|
* zero hnsBufferDuration, we can use audio engine determined buffer size
|
||||||
|
* but it seems to cause glitch depending on device. Calculate buffer size
|
||||||
|
* like wasapi plugin does. Note that MS example code uses non-zero
|
||||||
|
* buffer duration for event-driven shared-mode case as well.
|
||||||
|
*/
|
||||||
|
if (spec && !low_latency) {
|
||||||
|
/* Ensure that the period (latency_time) used is an integral multiple of
|
||||||
|
* either the default period or the minimum period */
|
||||||
|
guint64 factor = (spec->latency_time * 10) / default_period;
|
||||||
|
REFERENCE_TIME period = default_period * MAX (factor, 1);
|
||||||
|
|
||||||
|
buf_dur = spec->buffer_time * 10;
|
||||||
|
if (buf_dur < 2 * period)
|
||||||
|
buf_dur = 2 * period;
|
||||||
|
}
|
||||||
|
|
||||||
hr = client_handle->Initialize (AUDCLNT_SHAREMODE_SHARED, stream_flags,
|
hr = client_handle->Initialize (AUDCLNT_SHAREMODE_SHARED, stream_flags,
|
||||||
/* hnsBufferDuration should be same as hnsPeriodicity
|
buf_dur,
|
||||||
* when AUDCLNT_STREAMFLAGS_EVENTCALLBACK is used.
|
|
||||||
* And in case of shared mode, hnsPeriodicity should be zero, so
|
|
||||||
* this value should be zero as well */
|
|
||||||
0,
|
|
||||||
/* This must always be 0 in shared mode */
|
/* This must always be 0 in shared mode */
|
||||||
0, mix_format, nullptr);
|
0, mix_format, nullptr);
|
||||||
} else {
|
} else {
|
||||||
|
@ -952,7 +971,8 @@ gst_wasapi2_ring_buffer_prepare_loopback_client (GstWasapi2RingBuffer * self)
|
||||||
}
|
}
|
||||||
|
|
||||||
hr = gst_wasapi2_ring_buffer_initialize_audio_client (self, client_handle,
|
hr = gst_wasapi2_ring_buffer_initialize_audio_client (self, client_handle,
|
||||||
mix_format, &period, 0, GST_WASAPI2_CLIENT_DEVICE_CLASS_RENDER);
|
mix_format, &period, 0, GST_WASAPI2_CLIENT_DEVICE_CLASS_RENDER,
|
||||||
|
nullptr, FALSE);
|
||||||
|
|
||||||
if (!gst_wasapi2_result (hr)) {
|
if (!gst_wasapi2_result (hr)) {
|
||||||
GST_ERROR_OBJECT (self, "Failed to initialize audio client");
|
GST_ERROR_OBJECT (self, "Failed to initialize audio client");
|
||||||
|
@ -1077,7 +1097,8 @@ gst_wasapi2_ring_buffer_acquire (GstAudioRingBuffer * buf,
|
||||||
extra_flags = AUDCLNT_STREAMFLAGS_LOOPBACK;
|
extra_flags = AUDCLNT_STREAMFLAGS_LOOPBACK;
|
||||||
|
|
||||||
hr = gst_wasapi2_ring_buffer_initialize_audio_client (self, client_handle,
|
hr = gst_wasapi2_ring_buffer_initialize_audio_client (self, client_handle,
|
||||||
mix_format, &period, extra_flags, self->device_class);
|
mix_format, &period, extra_flags, self->device_class, spec,
|
||||||
|
self->low_latency);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!gst_wasapi2_result (hr)) {
|
if (!gst_wasapi2_result (hr)) {
|
||||||
|
|
Loading…
Reference in a new issue