iOS: Add ifdef'd support for video file input
This commit is contained in:
parent
862b85cd3f
commit
3fa7eb2a5a
@ -56,6 +56,7 @@ Pod::Spec.new do |s|
|
||||
'CARGO_BUILD_TARGET[sdk=iphonesimulator*][arch=arm64]' => 'aarch64-apple-ios-sim',
|
||||
'CARGO_BUILD_TARGET[sdk=iphonesimulator*][arch=*]' => 'x86_64-apple-ios',
|
||||
'CARGO_BUILD_TARGET[sdk=iphoneos*]' => 'aarch64-apple-ios',
|
||||
'SWIFT_ACTIVE_COMPILATION_CONDITIONS' => ENV.include?('RINGRTC_USE_FILE_BASED_CAMERA') ? 'USE_FILE_BASED_CAMERA' : '',
|
||||
}
|
||||
|
||||
s.script_phases = [
|
||||
|
||||
@ -12,18 +12,41 @@ public class VideoCaptureController {
|
||||
static let maxCaptureHeight: Int32 = 720
|
||||
static let maxCaptureFrameRate: Int32 = 30
|
||||
|
||||
// Keep around for captureSession even if USE_FILE_BASED_CAMERA
|
||||
private let capturer = RTCCameraVideoCapturer()
|
||||
var capturerDelegate: RTCVideoCapturerDelegate? {
|
||||
set { capturer.delegate = newValue }
|
||||
get { capturer.delegate }
|
||||
}
|
||||
private let serialQueue = DispatchQueue(label: "org.signal.videoCaptureController")
|
||||
|
||||
#if USE_FILE_BASED_CAMERA
|
||||
private var fileCapturer = RTCFileVideoCapturer()
|
||||
private var delegate: RTCVideoCapturerDelegate?
|
||||
var capturerDelegate: RTCVideoCapturerDelegate? {
|
||||
set {
|
||||
self.delegate = newValue
|
||||
let wasCapturing = self.isCapturing
|
||||
if wasCapturing {
|
||||
self.stopCapture()
|
||||
}
|
||||
self.fileCapturer = RTCFileVideoCapturer.init(
|
||||
delegate: newValue!
|
||||
)
|
||||
if wasCapturing {
|
||||
self.startCapture()
|
||||
}
|
||||
}
|
||||
get { self.delegate }
|
||||
}
|
||||
#else
|
||||
var capturerDelegate: RTCVideoCapturerDelegate? {
|
||||
set { capturer.delegate = newValue }
|
||||
get { capturer.delegate }
|
||||
}
|
||||
#endif
|
||||
private let serialQueue = DispatchQueue(
|
||||
label: "org.signal.videoCaptureController"
|
||||
)
|
||||
private var _isUsingFrontCamera: Bool = true
|
||||
public var isUsingFrontCamera: Bool? {
|
||||
get {
|
||||
serialQueue.sync { [weak self] in
|
||||
return self?._isUsingFrontCamera
|
||||
}
|
||||
serialQueue.sync { [weak self] in
|
||||
return self?._isUsingFrontCamera
|
||||
}
|
||||
}
|
||||
private var isCapturing: Bool = false
|
||||
@ -62,7 +85,11 @@ public class VideoCaptureController {
|
||||
// a crash on iOS 13 when built with the iOS 13 SDK.
|
||||
guard strongSelf.isCapturing else { return }
|
||||
|
||||
strongSelf.capturer.stopCapture()
|
||||
#if USE_FILE_BASED_CAMERA
|
||||
strongSelf.fileCapturer.stopCapture()
|
||||
#else
|
||||
strongSelf.capturer.stopCapture()
|
||||
#endif
|
||||
strongSelf.isCapturing = false
|
||||
}
|
||||
}
|
||||
@ -78,7 +105,9 @@ public class VideoCaptureController {
|
||||
// Only restart capturing again if the camera changes.
|
||||
if strongSelf._isUsingFrontCamera != isUsingFrontCamera {
|
||||
strongSelf._isUsingFrontCamera = isUsingFrontCamera
|
||||
strongSelf.startCaptureSync()
|
||||
#if !USE_FILE_BASED_CAMERA
|
||||
strongSelf.startCaptureSync()
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -93,24 +122,44 @@ public class VideoCaptureController {
|
||||
Logger.info("startCaptureSync():")
|
||||
assertIsOnSerialQueue()
|
||||
|
||||
let position: AVCaptureDevice.Position = _isUsingFrontCamera ? .front : .back
|
||||
guard let device: AVCaptureDevice = self.device(position: position) else {
|
||||
failDebug("unable to find captureDevice")
|
||||
return
|
||||
}
|
||||
#if USE_FILE_BASED_CAMERA
|
||||
fileCapturer.startCapturing(
|
||||
fromFileNamed: "input_video.mp4",
|
||||
onError: { (error: Error) -> Void in
|
||||
Logger.error("Failed to start capturing: \(error)")
|
||||
}
|
||||
)
|
||||
#else
|
||||
|
||||
guard let format: AVCaptureDevice.Format = self.format(device: device) else {
|
||||
failDebug("unable to find captureDevice")
|
||||
return
|
||||
}
|
||||
let position: AVCaptureDevice.Position =
|
||||
_isUsingFrontCamera ? .front : .back
|
||||
guard let device: AVCaptureDevice = self.device(position: position)
|
||||
else {
|
||||
failDebug("unable to find captureDevice")
|
||||
return
|
||||
}
|
||||
|
||||
guard
|
||||
let format: AVCaptureDevice.Format = self.format(device: device)
|
||||
else {
|
||||
failDebug("unable to find captureDevice")
|
||||
return
|
||||
}
|
||||
capturer.startCapture(
|
||||
with: device,
|
||||
format: format,
|
||||
fps: Int(VideoCaptureController.maxCaptureFrameRate)
|
||||
)
|
||||
#endif
|
||||
|
||||
capturer.startCapture(with: device, format: format, fps: Int(VideoCaptureController.maxCaptureFrameRate))
|
||||
isCapturing = true
|
||||
}
|
||||
|
||||
private func device(position: AVCaptureDevice.Position) -> AVCaptureDevice? {
|
||||
private func device(position: AVCaptureDevice.Position) -> AVCaptureDevice?
|
||||
{
|
||||
let captureDevices = RTCCameraVideoCapturer.captureDevices()
|
||||
guard let device = (captureDevices.first { $0.position == position }) else {
|
||||
guard let device = (captureDevices.first { $0.position == position })
|
||||
else {
|
||||
Logger.debug("unable to find desired position: \(position)")
|
||||
return captureDevices.first
|
||||
}
|
||||
@ -124,7 +173,7 @@ public class VideoCaptureController {
|
||||
CChar(pixelFormat >> 16 & 0xFF),
|
||||
CChar(pixelFormat >> 8 & 0xFF),
|
||||
CChar(pixelFormat & 0xFF),
|
||||
0
|
||||
0,
|
||||
]
|
||||
|
||||
var subTypeString = ""
|
||||
@ -145,37 +194,62 @@ public class VideoCaptureController {
|
||||
// on all devices the client supports.
|
||||
let screenSize = UIScreen.main.nativeBounds.size
|
||||
// screenSize is given in portrait-up orientation, but capture dimensions are in landscape.
|
||||
let targetWidth = max(Int32(screenSize.height), VideoCaptureController.maxCaptureWidth)
|
||||
let targetHeight = max(Int32(screenSize.width), VideoCaptureController.maxCaptureHeight)
|
||||
let targetWidth = max(
|
||||
Int32(screenSize.height),
|
||||
VideoCaptureController.maxCaptureWidth
|
||||
)
|
||||
let targetHeight = max(
|
||||
Int32(screenSize.width),
|
||||
VideoCaptureController.maxCaptureHeight
|
||||
)
|
||||
let targetFrameRate = VideoCaptureController.maxCaptureFrameRate
|
||||
|
||||
Logger.info("Capture Formats")
|
||||
Logger.info(" screenSize: \(screenSize)")
|
||||
Logger.info(" maxCaptureWidth: \(VideoCaptureController.maxCaptureWidth)")
|
||||
Logger.info(" maxCaptureHeight: \(VideoCaptureController.maxCaptureHeight)")
|
||||
Logger.info(
|
||||
" maxCaptureWidth: \(VideoCaptureController.maxCaptureWidth)"
|
||||
)
|
||||
Logger.info(
|
||||
" maxCaptureHeight: \(VideoCaptureController.maxCaptureHeight)"
|
||||
)
|
||||
Logger.info(" targetWidth: \(targetWidth)")
|
||||
Logger.info(" targetHeight: \(targetHeight)")
|
||||
Logger.info(" targetFrameRate: \(targetFrameRate)")
|
||||
Logger.info(" preferredPixelFormat: \(getSubTypeString(pixelFormat: capturer.preferredOutputPixelFormat()))")
|
||||
#if !USE_FILE_BASED_CAMERA
|
||||
// Not there on RTCFileVideoCapture
|
||||
Logger.info(
|
||||
" preferredPixelFormat: \(getSubTypeString(pixelFormat: capturer.preferredOutputPixelFormat()))"
|
||||
)
|
||||
#endif
|
||||
Logger.debug(" formats:")
|
||||
|
||||
var selectedFormat: AVCaptureDevice.Format?
|
||||
var currentDiff: Int32 = Int32.max
|
||||
|
||||
for format in formats {
|
||||
let dimension = CMVideoFormatDescriptionGetDimensions(format.formatDescription)
|
||||
let pixelFormat = CMFormatDescriptionGetMediaSubType(format.formatDescription);
|
||||
let dimension = CMVideoFormatDescriptionGetDimensions(
|
||||
format.formatDescription
|
||||
)
|
||||
let pixelFormat = CMFormatDescriptionGetMediaSubType(
|
||||
format.formatDescription
|
||||
)
|
||||
|
||||
for range in format.videoSupportedFrameRateRanges {
|
||||
Logger.debug(" width: \(dimension.width) height: \(dimension.height) pixelFormat: \(getSubTypeString(pixelFormat: pixelFormat)) fps range: \(range.minFrameRate) - \(range.maxFrameRate)")
|
||||
Logger.debug(
|
||||
" width: \(dimension.width) height: \(dimension.height) pixelFormat: \(getSubTypeString(pixelFormat: pixelFormat)) fps range: \(range.minFrameRate) - \(range.maxFrameRate)"
|
||||
)
|
||||
}
|
||||
|
||||
let diff = abs(targetWidth - dimension.width) + abs(targetHeight - dimension.height)
|
||||
let diff =
|
||||
abs(targetWidth - dimension.width)
|
||||
+ abs(targetHeight - dimension.height)
|
||||
if diff < currentDiff {
|
||||
// Look through all framerate ranges for this capture format and find
|
||||
// the first that supports the desired framerate.
|
||||
for range in format.videoSupportedFrameRateRanges {
|
||||
if Double(targetFrameRate) >= range.minFrameRate && Double(targetFrameRate) <= range.maxFrameRate {
|
||||
if Double(targetFrameRate) >= range.minFrameRate
|
||||
&& Double(targetFrameRate) <= range.maxFrameRate
|
||||
{
|
||||
selectedFormat = format
|
||||
currentDiff = diff
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user