[Audio Threads] Change workgroup code for safety
The changes include no longer leaving the workgroup for seeking or for converter format changes, and also still leaving the workgroup on thread termination if there was an error with intervals starting or finishing. Signed-off-by: Christopher Snowhill <kode54@gmail.com>swiftingly
parent
02d2ab01a7
commit
e9230a080c
|
@ -446,22 +446,19 @@ static void convert_be_to_le(uint8_t *buffer, size_t bitsPerSample, size_t bytes
|
|||
// when the end of stream is reached. Convert function instead processes what it can,
|
||||
// and returns 0 samples when it has nothing more to process at the end of stream.
|
||||
while([self shouldContinue] == YES) {
|
||||
[self followWorkgroup];
|
||||
|
||||
int amountConverted;
|
||||
while(paused) {
|
||||
usleep(500);
|
||||
}
|
||||
[self startWorkslice];
|
||||
@autoreleasepool {
|
||||
[self startWorkslice];
|
||||
amountConverted = [self convert:writeBuf amount:CHUNK_SIZE];
|
||||
[self endWorkslice];
|
||||
}
|
||||
[self endWorkslice];
|
||||
if(!amountConverted) {
|
||||
if(paused) {
|
||||
continue;
|
||||
} else if(streamFormatChanged) {
|
||||
[self leaveWorkgroup];
|
||||
[self cleanUp];
|
||||
[self setupWithInputFormat:newInputFormat withInputConfig:newInputChannelConfig outputFormat:outputFormat outputConfig:outputChannelConfig isLossless:rememberedLossless];
|
||||
continue;
|
||||
|
|
|
@ -157,7 +157,6 @@ static void *kInputNodeContext = &kInputNodeContext;
|
|||
|
||||
while([self shouldContinue] == YES && [self endOfStream] == NO) {
|
||||
if(shouldSeek == YES) {
|
||||
[self leaveWorkgroup];
|
||||
BufferChain *bufferChain = [[controller controller] bufferChain];
|
||||
ConverterNode *converter = [bufferChain converter];
|
||||
DLog(@"SEEKING! Resetting Buffer");
|
||||
|
@ -183,15 +182,13 @@ static void *kInputNodeContext = &kInputNodeContext;
|
|||
}
|
||||
|
||||
if(amountInBuffer < CHUNK_SIZE) {
|
||||
[self followWorkgroup];
|
||||
|
||||
int framesToRead = CHUNK_SIZE - amountInBuffer;
|
||||
int framesRead;
|
||||
[self startWorkslice];
|
||||
@autoreleasepool {
|
||||
[self startWorkslice];
|
||||
framesRead = [decoder readAudio:((char *)inputBuffer) + bytesInBuffer frames:framesToRead];
|
||||
[self endWorkslice];
|
||||
}
|
||||
[self endWorkslice];
|
||||
|
||||
if(framesRead > 0 && !seekError) {
|
||||
amountInBuffer += framesRead;
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
BOOL shouldContinue;
|
||||
BOOL endOfStream; // All data is now in buffer
|
||||
BOOL initialBufferFilled;
|
||||
BOOL isRealtime, isRealtimeError; // If was successfully set realtime, or if error
|
||||
BOOL isRealtime, isRealtimeError, isDeadlineError; // If was successfully set realtime, or if error
|
||||
|
||||
AudioStreamBasicDescription nodeFormat;
|
||||
uint32_t nodeChannelConfig;
|
||||
|
|
|
@ -222,6 +222,7 @@ BOOL SetPriorityRealtimeAudio(mach_port_t mach_thread_id) {
|
|||
wg = workgroup;
|
||||
if(wg && !isRealtimeError) {
|
||||
int result = os_workgroup_join(wg, &wgToken);
|
||||
isDeadlineError = NO;
|
||||
if(result == 0) return;
|
||||
if(result == EALREADY) {
|
||||
DLog(@"Thread already in workgroup");
|
||||
|
@ -251,13 +252,13 @@ BOOL SetPriorityRealtimeAudio(mach_port_t mach_thread_id) {
|
|||
|
||||
- (void)startWorkslice {
|
||||
if(@available(macOS 11, *)) {
|
||||
if(wg && !isRealtimeError) {
|
||||
if(wg && !isRealtimeError && !isDeadlineError) {
|
||||
const uint64_t currentTime = mach_absolute_time();
|
||||
const uint64_t deadline = currentTime + intervalMachLength;
|
||||
int result = os_workgroup_interval_start(wg, currentTime, deadline, nil);
|
||||
if(result != 0) {
|
||||
DLog(@"Deadline error = %d", result);
|
||||
isRealtimeError = YES;
|
||||
isDeadlineError = YES;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -265,11 +266,11 @@ BOOL SetPriorityRealtimeAudio(mach_port_t mach_thread_id) {
|
|||
|
||||
- (void)endWorkslice {
|
||||
if(@available(macOS 11, *)) {
|
||||
if(wg && !isRealtimeError) {
|
||||
if(wg && !isRealtimeError && !isDeadlineError) {
|
||||
int result = os_workgroup_interval_finish(wg, nil);
|
||||
if(result != 0) {
|
||||
DLog(@"Deadline end error = %d", result);
|
||||
isRealtimeError = YES;
|
||||
isDeadlineError = YES;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue