From 38ee3653f78f5f63ea8fd7cd20eed11406b2f3b7 Mon Sep 17 00:00:00 2001 From: Michael Kirk Date: Mon, 25 Jun 2018 16:44:29 -0600 Subject: [PATCH] synchronize access to CaptureController state // FREEBIE --- Signal/src/call/PeerConnectionClient.swift | 42 ++++++++++++++++++---- 1 file changed, 36 insertions(+), 6 deletions(-) diff --git a/Signal/src/call/PeerConnectionClient.swift b/Signal/src/call/PeerConnectionClient.swift index 0400b2816..5f6e16225 100644 --- a/Signal/src/call/PeerConnectionClient.swift +++ b/Signal/src/call/PeerConnectionClient.swift @@ -367,7 +367,6 @@ class PeerConnectionClient: NSObject, RTCPeerConnectionDelegate, RTCDataChannelD } captureController.switchCamera(isUsingFrontCamera: isUsingFrontCamera) - captureController.startCapture() } } @@ -426,7 +425,6 @@ class PeerConnectionClient: NSObject, RTCPeerConnectionDelegate, RTCDataChannelD // MARK: VideoCaptureSettingsDelegate - // MJK: fixme var videoWidth: Int32 { return 400 } @@ -764,6 +762,7 @@ class PeerConnectionClient: NSObject, RTCPeerConnectionDelegate, RTCDataChannelD videoSender = nil localVideoTrack = nil remoteVideoTrack = nil + videoCaptureController = nil if let peerConnection = peerConnection { peerConnection.delegate = nil @@ -1117,16 +1116,35 @@ protocol VideoCaptureSettingsDelegate: class { class VideoCaptureController { + let serialQueue = DispatchQueue(label: "org.signal.videoCaptureController") let capturer: RTCCameraVideoCapturer weak var settingsDelegate: VideoCaptureSettingsDelegate? var isUsingFrontCamera: Bool = true + func assertIsOnSerialQueue() { + if _isDebugAssertConfiguration(), #available(iOS 10.0, *) { + assertOnQueue(serialQueue) + } + } + public init(capturer: RTCCameraVideoCapturer, settingsDelegate: VideoCaptureSettingsDelegate) { self.capturer = capturer self.settingsDelegate = settingsDelegate } public func startCapture() { + serialQueue.sync { [weak self] in + guard let strongSelf = self else { + return + } + + strongSelf.startCaptureSync() + } + } + + private func startCaptureSync() { + assertIsOnSerialQueue() + let position: AVCaptureDevice.Position = isUsingFrontCamera ? .front : .back guard let device: AVCaptureDevice = self.device(position: position) else { owsFail("unable to find captureDevice") @@ -1139,17 +1157,24 @@ class VideoCaptureController { } let fps = self.framesPerSecond(format: format) - capturer.startCapture(with: device, format: format, fps: fps) } public func stopCapture() { - self.capturer.stopCapture() + serialQueue.sync { [weak self] in + guard let strongSelf = self else { + return + } + + strongSelf.capturer.stopCapture() + } } public func switchCamera(isUsingFrontCamera: Bool) { - self.isUsingFrontCamera = isUsingFrontCamera - self.startCapture() + serialQueue.sync { + self.isUsingFrontCamera = isUsingFrontCamera + self.startCaptureSync() + } } private func device(position: AVCaptureDevice.Position) -> AVCaptureDevice? { @@ -1179,6 +1204,11 @@ class VideoCaptureController { } } + if _isDebugAssertConfiguration(), let selectedFormat = selectedFormat { + let dimension = CMVideoFormatDescriptionGetDimensions(selectedFormat.formatDescription) + Logger.debug("in \(#function) selected format width: \(dimension.width) height: \(dimension.height)") + } + assert(selectedFormat != nil) return selectedFormat