-
Audio mixer invalidates the output format after updating the settings from the main thread. At the same time, it still performs conversion that is called from append method and uses This is similar to #1496 where Thanks in advance. |
Beta Was this translation helpful? Give feedback.
Replies: 3 comments 4 replies
-
I couldn’t determine the specific issue, so I’m not sure whether or not to use a queue. Does a data race mean that the program crashes? Or does it mean that, due to the order of execution, the values might not be applied to the subsequent processing? Regarding issue #1496, lockQueue is used for making changes to the AVCaptureSession system. Changing AVCaptureSession values is a time-consuming process. The videoIO.lockQueue is used for capturing CMSampleBuffer from the device and eliminating data conflicts. Therefore, as they serve different purposes, I don't think removing the lockQueue is appropriate. |
Beta Was this translation helpful? Give feedback.
-
Yes the program crashes when user tries to change sample rate or number of channels before or after going live. Let's say user changes the settings from some UI menu. Here's a code that would be called when selecting new settings: final class IngestViewController: UIViewController {
func updateSampleRateFromUI(_ sampleRate: Float64) {
stream.audioMixerSettings = stream.audioMixerSettings.copy(sampleRate: sampleRate)
}
func updateSampleRateFromUI_simulateCrash() {
for _ in 0..<10000 {
let sampleRate: Float64 = Int(stream.audioMixerSettings.sampleRate) == 44100 ? 48000 : 44100
stream.audioMixerSettings = stream.audioMixerSettings.copy(sampleRate: sampleRate)
}
}
}
private extension IOAudioMixerSettings {
/// Helper function to build new settings based on the current values
func copy(sampleRate: Float64? = nil, channels: UInt32? = nil) -> IOAudioMixerSettings {
var settings = IOAudioMixerSettings(sampleRate: sampleRate ?? self.sampleRate,
channels: channels ?? self.channels)
settings.mainTrack = mainTrack
settings.tracks = tracks
settings.isMuted = isMuted
settings.maximumNumberOfChannels = maximumNumberOfChannels
return settings
}
} This leads to all kind of random crashes for the properties that are getting accessed from the both threads:
Proposed solution would be to make all audio mixer properties be modified inside of public var audioMixerSettings: IOAudioMixerSettings {
get {
mixer.audioIO.lockQueue.sync { self.mixer.audioIO.mixerSettings }
}
set {
mixer.audioIO.lockQueue.async {
self.mixer.audioIO.mixerSettings = newValue
}
}
} |
Beta Was this translation helpful? Give feedback.
-
Similar to the audio properties, here is the code that simulates video orientation change crash: func configureCaptureDevice_simulateCrash() {
for _ in 0..<10000 {
let positions: [AVCaptureDevice.Position] = [.back, .front]
stream.attachCamera(AVCaptureDevice.default(.builtInWideAngleCamera, for: .video, position: positions.randomElement()!))
let orientations: [AVCaptureVideoOrientation] = [.portrait, .landscapeLeft]
stream.videoOrientation = orientations.randomElement()!
}
}
public var videoOrientation: AVCaptureVideoOrientation {
get {
return lockQueue.sync { self.mixer.videoIO.videoOrientation }
}
set {
lockQueue.async {
self.mixer.videoIO.videoOrientation = newValue
}
}
} |
Beta Was this translation helpful? Give feedback.
[FYI] #1510