Own audio thread with real time priority

1,275 views
Skip to first unread message

Oleg Beletski

unread,
Jan 12, 2015, 7:23:59 AM1/12/15
to andro...@googlegroups.com
Is there any way to start own low latency audio thread with real time scheduling (SCHED_FIFO)  that original OpenSL ES simple buffer queue callback is enjoying? In my case audio content generation is happening on different thread than the callback and I observed timing issues.
Call to sched_setscheduler has been failing for that purpose with the errno 1, operation not permitted.

Thanks,
Oleg

Glenn Kasten

unread,
Jan 13, 2015, 11:06:19 AM1/13/15
to andro...@googlegroups.com
Currently the only recommended way to handle this is do the time-critical work within the callback running in SCHED_FIFO thread,
and to defer non-time-critical work to another CFS (SCHED_OTHER) thread.
Communication between the SCHED_FIFO and SCHED_OTHER threads can be via a mechanism that is not subject to priority inversion,
for example I have found that a non-blocking FIFO works well in many cases. See

The reason we don't support arbitrary use of SCHED_FIFO is that we need to enforce
correct assignment of priorities based on periods per RMS; see this article for details:

You may discover hacks that appear to bypass this restriction of no arbitrary use of SCHED_FIFO.
I don't recommend using such hacks as they will not work in the future.
For future compatibility, follow the guidelines in first paragraph above.

Davy Wentzler

unread,
Jan 15, 2015, 8:32:08 AM1/15/15
to andro...@googlegroups.com
Hi Glenn,

I don't think SCHED_FIFO is always used. On our Samsung S4 running Android 4.4.2, sched_getscheduler(0) always returns 0 (SCHED_OTHER).
On our Nexus 5, running Android 4.4.4, sched_getscheduler(0) only returns 1 (SCHED_FIFO) when the native sample rate is used (and probably the native buffer size). So I assume this only holds for Nexus devices using the native sample rate and buffer size?

Glenn Kasten

unread,
Jan 16, 2015, 10:40:09 AM1/16/15
to andro...@googlegroups.com
The relevant audio server threads run with SCHED_FIFO
when the device driver buffer sizes are small enough that
CFS (SCHED_OTHER) would be unreliable. 

The audio client threads run with SCHED_FIFO only when
they meet the criteria for lower latency "fast tracks".
As of 5.0 the rules are approximately:
 - OpenSL ES buffer queue API
 - native sample rate
 - native buffer size
 - no OpenSL ES interfaces that are incompatible with fast tracks
 - adequate bandwidth to support fast tracks
The concept of "native" breaks down for USB and other
off-device I/O.  This "native" concept needs to be re-visited.

Oleg Beletski

unread,
Jan 19, 2015, 7:57:18 AM1/19/15
to andro...@googlegroups.com
Hi guys,
 
I was not able to see OpenSL ES callbacks coming with SCHED_FIFO at all on Samsaung Galaxy Note3 running Android 4.4.2, event though I was playing around with different buffer sizes. Moreover, with buffer size set to 960 frames callbacks arrive in pairs (native/optimal size reported by AudioManager), with 240 there are 8 callback coming in one cluster.
For that device FEATURE_AUDIO_LOW_LATENCY is set to false.
Could that be that for some 4.4 devices SCHED_FIFO is disabled by manufacturer?

Cyanogen image on the same hardware do run callbacks with SCHED_FIFO and reports native buffer size as 240 frame. Android version is different though. It is 4.4.4. Any explanation for that?

Glenn Kasten

unread,
Jan 20, 2015, 10:24:17 AM1/20/15
to andro...@googlegroups.com
Oleg,
What is the value reported by 
and PROPERTY_OUTPUT_FRAMES_PER_BUFFER
? And can you also please check the logcat right at the time you
create and start the AudioTrack ... are there any audio-related log messages?
Glenn

Oleg Beletski

unread,
Jan 29, 2015, 10:22:36 AM1/29/15
to andro...@googlegroups.com
Glenn,
I finally was able to spend some time to explore things better. I made some checks with Samsung Tab S, Android 4.4.2.

Here is the outcome:
PROPERTY_OUTPUT_SAMPLE_RATE: 48000
PROPERTY_OUTPUT_FRAMES_PER_BUFFER: 960
FEATURE_LOW_LATENCY: false
 

I was also using native-audio application from NDK for OpenSL ES testing. I changed sampling rate to match my device (48000) and then disabled usage of send effects interface that could affect selection of fast audio path.

I was not able to see anything in the log that could shed any light on why thread is not running with FIFO priority.

Here are related log entries. Can you spot anything unusual? Could the reason for that be disabled low latency feature?

Thanks,
Oleg
 

D/OPENSLSAMPLEAUDIO( 8816): createEngine
I/AudioFlinger( 2214): sleepTime is reduced to minimum forcely
V/AudioPolicyManagerBase( 2214): getOutputsForDevice device 0002 -> 0002
V/AudioPolicyManagerBase( 2214): selectOutputForEffects outputs[0] flags 2
V/AudioPolicyManagerBase( 2214): selectOutputForEffects outputOffloaded 0 outputDeepBuffer 0
V/AudioPolicyManagerBase( 2214): getOutputForEffect() got output 2 for fx Auxiliary Environmental Reverb flags 1
I/AudioFlinger( 2214): createEffect_l() set channelCount = 2
V/AudioPolicyManagerBase( 2214): registerEffect() effect Auxiliary Environmental Reverb, io 2, strategy 0 session 0 id 24
V/AudioPolicyManagerBase( 2214): registerEffect() memory 91, total memory 91
I/AudioFlinger( 2214): sleepTime is reduced to minimum forcely
V/AudioPolicyManagerBase( 2214): setEffectEnabled(true) total CPU 470

D/OPENSLSAMPLEAUDIO( 8816): createBufferQueueAudioPlayer
V/AudioPolicyManagerBase( 2214): getOutput() device 2, stream 3, samplingRate 48000, format 1, channelMask 3, flags 4
V/AudioPolicyManagerBase( 2214): getOutputsForDevice device 0002 -> 0002
V/AudioPolicyManagerBase( 2214): getOutput() returns output 2
D/AudioFlinger( 2214): Creating track with bufferSize 16384 bytes, frameCount 3840, mFrameSize 4
V/LvOutput( 2214): initCheck: 0
V/LvOutput( 2214): attachEffects: attach processing to output 2, stream 3, session 25, mode 0
V/LvOutput( 2214): attachEffects: no output processing needs to be attached to this stream
V/LvOutput( 2214): LvOutput::setAllProcessorEnabled(false) mOutputs.size(0)
V/AudioPolicyManagerBase( 2214): startOutput() output 2, stream 3, session 25
V/AudioPolicyManagerBase( 2214): changeRefCount() stream 3, count 1
V/AudioPolicyManagerBase( 2214): getNewDevice() selected device 2
I/AudioFlinger( 2214): sleepTime is reduced to minimum forcely
V/AudioPolicyManagerBase( 2214): setOutputDevice() output 2 device 0002 force 0 delayMs 0
V/AudioPolicyManagerBase( 2214): setOutputDevice() prevDevice (0002)
V/AudioPolicyManagerBase( 2214): setOutputDevice() setting same device 0002 or null device for output 2
V/AudioPolicyManagerBase( 2214): getOutputsForDevice device 0002 -> 0002
V/AudioPolicyManagerBase( 2214): getOutputsForDevice device 0002 -> 0002
I/AudioFlinger( 2214): sleepTime is reduced to minimum forcely
V/LvOutput( 2214): initCheck: 0
V/LvOutput( 2214): detachEffects: detach processing for output 2, stream 3, session 25
V/LvOutput( 2214): detachEffects: no output processing was attached to this stream
I/AudioFlinger( 2214): sleepTime is reduced to minimum forcely
Reply all
Reply to author
Forward
0 new messages