Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adjust OpenSL ES buffer queue length based on capacity #744

Closed
philburk opened this issue Dec 29, 2019 · 7 comments · Fixed by #1601
Closed

Adjust OpenSL ES buffer queue length based on capacity #744

philburk opened this issue Dec 29, 2019 · 7 comments · Fixed by #1601
Assignees
Labels
enhancement P1 high priority
Milestone

Comments

@philburk
Copy link
Collaborator

philburk commented Dec 29, 2019

Change kBufferQueueLength constant to mBufferQueueLength variable.
Set mBufferQueueLength based on capacity and callbacksize.

See experiment on the effect of kBufferQueueLength on latency in:
Why Oboe only enqueue one buffer? #464

Understanding FramesPerCallback / kBufferQueueLength / Buffer Size #736

According to this internal bug:

b/27819623 | Allow OpenSL ES to specify a total buffer size for a fast track

starting in N, adding more buffers would improve glitch protection. So this change would help devices running 7.0, 7.1 and 8.0. That would be about 1/3 of Android devices. For 8.1 and later, AAudio is available.

[Update: as of August 2022, 17.5% of devices are running < 8.1]

@klw111
Copy link

klw111 commented Mar 24, 2020

Allow OpenSL ES to specify a total buffer size for a fast track
Has this feature implemented in branch 1.3-stable?

@philburk
Copy link
Collaborator Author

No. This issue is still open.

@philburk
Copy link
Collaborator Author

philburk commented Aug 6, 2022

Measure the effect of changing kBufferQueueLength on Sargo running SP2A with OpenSL ES with Low Latency.
Burst = 192.

kBufferQueueLength RT latency Capacity
2 22.2
3 24.1 576
4 25.9 768

Latency increases by 2 msec (96 frames) per buffer. Not 192!

Used main Oboetester screen to set frames per callback to 96.

kBufferQueueLength RT latency Capacity
2 17.8 192
3 19.9 288
4 22.2 384

The latency still increases by 2 msec/buffer but the latency is lower!

I then set kBufferQueueLength and added some code to the beginning of processBufferCallback(). Burst = 192.
if (getBufferDepth(bq) >= 3) {
return false;
}

maxDepth RT latency Capacity
3 34.2 1536
4 34.0 1536
5 34.27 1536

This does not seem to affect latency! I expected it to limit the amount of data in the buffer.
I added some logs and the depth was always zero.

@philburk
Copy link
Collaborator Author

philburk commented Aug 6, 2022

I then added a loop in processBufferCallback:

while (depth < 4 && countdown-- > 0 && !shouldStopStream) {

In the first callback I could see the depth grow to four then stabilize.

maxDepth RT latency Capacity
1 34.4 1536
2 37.8 1536
3 42.2 1536
4 45.8 1536
5 50.6 1536
6 54.3 1536
7 58.0 1536
8 62.3 1536

At 9 it failed to start because there were only 8 buffers allocated.

@philburk
Copy link
Collaborator Author

philburk commented Aug 6, 2022

Hypothesis: in Android S the kBufferQueueLength affects the size of the internal buffer, which increases latency and should afford some glitch protection. Enqueuing multiple buffers increases the queue depth, adds latency. But I suspect these buffers are stored on the client side and will not help with glitch protection.

philburk added a commit that referenced this issue Aug 6, 2022
The OpenSL ES buffer queue length controls the allocated size of
the internal buffer. So we can use that to make sure there is enough
capacity to protect against glitches when setting a callback size
or a high capacity.

Fixes #744
It might help with #952
@philburk
Copy link
Collaborator Author

philburk commented Aug 8, 2022

Testing on a Nexus 6 running SDK 6.0.1, burst = 192.
Use format = PCM_I16 for input and output, analog headset jack.

kBufferQueueLength RT latency Capacity
2 50.0 384
3 49.5 576
4 49.7 768

Latency, and glitch protection, does not increase with the number of buffers. That was added in 7.0. ag/941250
SDK 6.0 has problems that we cannot fix in Oboe.

@philburk
Copy link
Collaborator Author

philburk commented Aug 8, 2022

Testing on a Nexus 6 running SDK 7 MR2, burst = 192.
Use format = PCM_I16 for input and output, analog headset jack.

kBufferQueueLength RT latency Capacity
2 53.3 384
3 57.5 576
4 61.5 768

Latency, and glitch protection, increases with the number of buffers.

philburk added a commit that referenced this issue Aug 30, 2022
The OpenSL ES buffer queue length controls the allocated size of
the internal buffer. So we can use that to make sure there is enough
capacity to protect against glitches when setting a callback size
or a high capacity.

Fixes #744
Fixes #1599

It might help with #952

Bump Oboe to version 1.6.4
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement P1 high priority
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants