Add an option for real-time priority mixing
Default to disable for now, as a safety precaution
This commit is contained in:
parent
0e1e8503e0
commit
6cfc31777b
38
Alc/ALc.c
38
Alc/ALc.c
@ -208,6 +208,9 @@ static tls_type LocalContext;
|
||||
// Context Error
|
||||
static ALCenum g_eLastContextError = ALC_NO_ERROR;
|
||||
|
||||
// Mixing Priority Level
|
||||
ALint RTPrioLevel;
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
|
||||
|
||||
@ -253,6 +256,8 @@ static void alc_init(void)
|
||||
|
||||
tls_create(&LocalContext);
|
||||
|
||||
RTPrioLevel = GetConfigValueInt(NULL, "rt-prio", 0);
|
||||
|
||||
devs = GetConfigValue(NULL, "drivers", "");
|
||||
if(devs[0])
|
||||
{
|
||||
@ -424,6 +429,39 @@ DECL_APPEND_LIST_FUNC(AllDevice)
|
||||
DECL_APPEND_LIST_FUNC(CaptureDevice)
|
||||
|
||||
|
||||
void EnableRTPrio(ALint level)
|
||||
{
|
||||
ALboolean failed;
|
||||
|
||||
#ifdef _WIN32
|
||||
if(level > 0)
|
||||
failed = !SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL);
|
||||
else
|
||||
failed = !SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_NORMAL);
|
||||
#elif defined(HAVE_PTHREAD_SETSCHEDPARAM)
|
||||
struct sched_param param;
|
||||
|
||||
if(level > 0)
|
||||
{
|
||||
/* Use the minimum real-time priority possible for now (on Linux this
|
||||
* should be 1 for SCHED_RR) */
|
||||
param.sched_priority = sched_get_priority_min(SCHED_RR);
|
||||
failed = !!pthread_setschedparam(pthread_self(), SCHED_RR, ¶m);
|
||||
}
|
||||
else
|
||||
{
|
||||
param.sched_priority = 0;
|
||||
failed = !!pthread_setschedparam(pthread_self(), SCHED_OTHER, ¶m);
|
||||
}
|
||||
#else
|
||||
/* Real-time priority not available */
|
||||
failed = !!level;
|
||||
#endif
|
||||
if(failed)
|
||||
AL_PRINT("Failed to set priority level for thread\n");
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
IsDevice
|
||||
|
||||
|
@ -271,7 +271,7 @@ static ALuint ALSAProc(ALvoid *ptr)
|
||||
char *WritePtr;
|
||||
int err;
|
||||
|
||||
EnableRTPrio();
|
||||
EnableRTPrio(RTPrioLevel);
|
||||
|
||||
while(!data->killNow)
|
||||
{
|
||||
@ -345,7 +345,7 @@ static ALuint ALSANoMMapProc(ALvoid *ptr)
|
||||
snd_pcm_sframes_t avail;
|
||||
char *WritePtr;
|
||||
|
||||
EnableRTPrio();
|
||||
EnableRTPrio(RTPrioLevel);
|
||||
|
||||
while(!data->killNow)
|
||||
{
|
||||
@ -400,7 +400,7 @@ static ALuint ALSANoMMapCaptureProc(ALvoid *ptr)
|
||||
alsa_data *data = (alsa_data*)pDevice->ExtraData;
|
||||
snd_pcm_sframes_t avail;
|
||||
|
||||
EnableRTPrio();
|
||||
EnableRTPrio(RTPrioLevel);
|
||||
|
||||
while(!data->killNow)
|
||||
{
|
||||
|
@ -134,7 +134,7 @@ static ALuint DSoundProc(ALvoid *ptr)
|
||||
DWORD avail;
|
||||
HRESULT err;
|
||||
|
||||
EnableRTPrio();
|
||||
EnableRTPrio(RTPrioLevel);
|
||||
|
||||
memset(&DSBCaps, 0, sizeof(DSBCaps));
|
||||
DSBCaps.dwSize = sizeof(DSBCaps);
|
||||
|
@ -82,7 +82,7 @@ static ALuint OSSProc(ALvoid *ptr)
|
||||
ALint frameSize;
|
||||
ssize_t wrote;
|
||||
|
||||
EnableRTPrio();
|
||||
EnableRTPrio(RTPrioLevel);
|
||||
|
||||
frameSize = aluChannelsFromFormat(pDevice->Format) *
|
||||
aluBytesFromFormat(pDevice->Format);
|
||||
@ -124,7 +124,7 @@ static ALuint OSSCaptureProc(ALvoid *ptr)
|
||||
int frameSize;
|
||||
int amt;
|
||||
|
||||
EnableRTPrio();
|
||||
EnableRTPrio(RTPrioLevel);
|
||||
|
||||
frameSize = aluBytesFromFormat(pDevice->Format);
|
||||
frameSize *= aluChannelsFromFormat(pDevice->Format);
|
||||
|
@ -57,6 +57,8 @@ static ALuint SolarisProc(ALvoid *ptr)
|
||||
ALint frameSize;
|
||||
int wrote;
|
||||
|
||||
EnableRTPrio(RTPrioLevel);
|
||||
|
||||
frameSize = aluChannelsFromFormat(pDevice->Format) *
|
||||
aluBytesFromFormat(pDevice->Format);
|
||||
|
||||
|
@ -181,22 +181,6 @@ static __inline ALuint NextPowerOf2(ALuint value)
|
||||
return powerOf2;
|
||||
}
|
||||
|
||||
static __inline void EnableRTPrio()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL);
|
||||
#elif defined(HAVE_PTHREAD_SETSCHEDPARAM)
|
||||
struct sched_param param;
|
||||
|
||||
/* Use the minimum real-time priority possible for now (on Linux this
|
||||
* should be 1 for SCHED_RR) */
|
||||
param.sched_priority = sched_get_priority_min(SCHED_RR);
|
||||
pthread_setschedparam(pthread_self(), SCHED_RR, ¶m);
|
||||
#else
|
||||
/* Real-time priority not available */
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
typedef struct {
|
||||
ALCboolean (*OpenPlayback)(ALCdevice*, const ALCchar*);
|
||||
@ -343,6 +327,8 @@ struct ALCcontext_struct
|
||||
ALCcontext *next;
|
||||
};
|
||||
|
||||
extern ALint RTPrioLevel;
|
||||
|
||||
ALCvoid ReleaseALC(ALCvoid);
|
||||
|
||||
void AppendDeviceList(const ALCchar *name);
|
||||
@ -373,6 +359,8 @@ int GetConfigValueInt(const char *blockName, const char *keyName, int def);
|
||||
float GetConfigValueFloat(const char *blockName, const char *keyName, float def);
|
||||
int GetConfigValueBool(const char *blockName, const char *keyName, float def);
|
||||
|
||||
void EnableRTPrio(ALint level);
|
||||
|
||||
ALCboolean ALCAPIENTRY alcMakeCurrent(ALCcontext *context);
|
||||
ALCcontext* ALCAPIENTRY alcGetThreadContext(void);
|
||||
|
||||
|
@ -52,6 +52,15 @@
|
||||
# Sets the output frequency.
|
||||
#frequency = 44100
|
||||
|
||||
## rt-prio:
|
||||
# Sets real-time priority for the mixing thread. Not all drivers may use this
|
||||
# (eg. PulseAudio) as they already control the priority of the mixing thread.
|
||||
# 0 and negative values will disable it. Note that this may constitute a
|
||||
# security risk since a real-time priority thread can indefinitely block
|
||||
# normal-priority threads if it fails to wait. As such, the default is
|
||||
# disabled.
|
||||
#rt-prio = 0
|
||||
|
||||
## period_size:
|
||||
# Sets the update period size, in frames. This is the number of frames needed
|
||||
# for each mixing update. If the deprecated 'refresh' option is specified and
|
||||
|
Loading…
x
Reference in New Issue
Block a user