After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 748680 - directsoundsink: fix sleep for buffer-time lower than 200000
directsoundsink: fix sleep for buffer-time lower than 200000
Status: RESOLVED FIXED
Product: GStreamer
Classification: Platform
Component: gst-plugins-good
git master
Other Linux
: Normal normal
: 1.7.1
Assigned To: GStreamer Maintainers
GStreamer Maintainers
Depends on:
Blocks:
 
 
Reported: 2015-04-30 06:34 UTC by Thomas Roos
Modified: 2015-12-21 11:47 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
directsoundsink: fix sleep for buffer-time lower than 200000 (924 bytes, patch)
2015-04-30 06:34 UTC, Thomas Roos
none Details | Review
replace the fix 100ms sleep with a sleep calculated as the latency-time minus free buffer (3.75 KB, patch)
2015-12-16 07:22 UTC, Thomas Roos
none Details | Review
replace the fix 100ms sleep with latency-time (3.01 KB, patch)
2015-12-16 15:41 UTC, Thomas Roos
none Details | Review
replace the fix 100ms sleep with (length - dwFreeBufferSize) * 1000) / (bytes_per_sample * rate) (1.84 KB, patch)
2015-12-21 10:41 UTC, Thomas Roos
committed Details | Review

Description Thomas Roos 2015-04-30 06:34:16 UTC
Created attachment 302625 [details] [review]
directsoundsink: fix sleep for buffer-time lower than 200000

There's a fix sleep of 100ms!!! when the ring buffer is already full, but if you have lower buffer-time eg. 60ms this fixed sleep makes it impossible to have a smooth playback. A generic solution or parameter is needed, but I think 100ms fixed sleep is far too much - changed to 10ms sleep. Patch attached
Comment 1 Andoni Morales 2015-04-30 13:52:13 UTC
You should use the configured buffer_time in the ring buffer, instead of another hardcoded value.

spec->buffer_time / 2 seems like a good value for this sleep.
Comment 2 Andoni Morales 2015-04-30 14:06:48 UTC
But never smaller than latency_time
Comment 3 Thomas Roos 2015-12-02 13:40:34 UTC
What about using latency_time? It should be the maximum rate the buffer can be filled with data?
Comment 4 Thomas Roos 2015-12-16 07:22:13 UTC
Created attachment 317474 [details] [review]
replace the fix 100ms sleep with a sleep calculated as the latency-time minus free buffer
Comment 5 Sebastian Dröge (slomo) 2015-12-16 08:28:52 UTC
Review of attachment 317474 [details] [review]:

::: sys/directsound/gstdirectsoundsink.c
@@ +506,3 @@
+    dsoundsink->latency_time = spec->latency_time;
+
+    dsoundsink->sample_rate = spec->info.rate;

You could also just access that at any point after prepare() from the spec field of GstAudioBaseSink's ringbuffer field.

@@ +641,3 @@
+          dsoundsink->sample_rate;
+
+      sleepTime = (dsoundsink->latency_time / 1000) - dwFreeBufferTime;

Why? Wouldn't it be better to wait for ((length - dwFreeBufferSize) * 1000) / (bytes_per_sample * sample_rate) milliseconds instead? That would be the amount of time that is missing from the buffer size before we can fill it with the complete data we currently have.
Comment 6 Thomas Roos 2015-12-16 15:40:35 UTC
"You could also just access that at any point after prepare() from the spec field of GstAudioBaseSink's ringbuffer field." -> I don't understand how to access this in gst_directsound_sink_write. Could you please explain!?

And I also tried your suggestion for the calculation. But decided finally it's best to do it like in directsoundsrc and use the latency-time in ms for the sleep. It's because windows Sleep() function isn't correct enough to gain something out of a correct calculation.
Comment 7 Thomas Roos 2015-12-16 15:41:22 UTC
Created attachment 317505 [details] [review]
replace the fix 100ms sleep with latency-time
Comment 8 Sebastian Dröge (slomo) 2015-12-16 16:24:02 UTC
(In reply to Thomas Roos from comment #6)
> "You could also just access that at any point after prepare() from the spec
> field of GstAudioBaseSink's ringbuffer field." -> I don't understand how to
> access this in gst_directsound_sink_write. Could you please explain!?

GST_AUDIO_BASE_SINK(asink)->ringbuffer->spec.latency_time or similar

> And I also tried your suggestion for the calculation. But decided finally
> it's best to do it like in directsoundsrc and use the latency-time in ms for
> the sleep. It's because windows Sleep() function isn't correct enough to
> gain something out of a correct calculation.

Why calculate anything at all then? ;) It would probably be better to wait for the correct time instead of some random other value, even if Sleep() is not very accurate.

Is there some way to get notified from directsound when the buffer is more free again instead of using Sleep() here?
Comment 9 Thomas Roos 2015-12-21 07:06:22 UTC
> Is there some way to get notified from directsound when the buffer is more 
> free again instead of using Sleep() here?
No, that's one reason more why nowadays you use WASAPI, there you can register a callback.
Comment 10 Sebastian Dröge (slomo) 2015-12-21 09:26:03 UTC
Alright, let's go with sleeping then. But I still think it would be better to sleep for a more accurately calculated time instead of taking some almost random number :)
Comment 11 Thomas Roos 2015-12-21 10:41:08 UTC
Created attachment 317729 [details] [review]
replace the fix 100ms sleep with (length - dwFreeBufferSize) * 1000) / (bytes_per_sample * rate)

ok, lets do it the way you proposed
Comment 12 Sebastian Dröge (slomo) 2015-12-21 11:46:47 UTC
commit 51f94288ce66a0a6a28e45801f4e17eb74044298
Author: Thomas Roos <thomas.roos@industronic.de>
Date:   Mon Dec 21 11:37:26 2015 +0100

    directsoundsink: Fix sleep for buffer-time lower than 200000
    
    https://bugzilla.gnome.org/show_bug.cgi?id=748680