2021-02-19 08:28:05 -07:00
|
|
|
//
|
|
|
|
// AVCaptureDevice.Format+toDictionary.swift
|
2021-06-21 14:42:46 -06:00
|
|
|
// mrousavy
|
2021-02-19 08:28:05 -07:00
|
|
|
//
|
|
|
|
// Created by Marc Rousavy on 15.01.21.
|
2021-06-01 05:07:57 -06:00
|
|
|
// Copyright © 2021 mrousavy. All rights reserved.
|
2021-02-19 08:28:05 -07:00
|
|
|
//
|
|
|
|
|
|
|
|
import AVFoundation
|
|
|
|
|
|
|
|
private func getAllVideoStabilizationModes() -> [AVCaptureVideoStabilizationMode] {
|
|
|
|
var modes: [AVCaptureVideoStabilizationMode] = [.auto, .cinematic, .off, .standard]
|
|
|
|
if #available(iOS 13, *) {
|
|
|
|
modes.append(.cinematicExtended)
|
|
|
|
}
|
|
|
|
return modes
|
|
|
|
}
|
|
|
|
|
|
|
|
extension AVCaptureDevice.Format {
|
|
|
|
var videoStabilizationModes: [AVCaptureVideoStabilizationMode] {
|
|
|
|
return getAllVideoStabilizationModes().filter { self.isVideoStabilizationModeSupported($0) }
|
|
|
|
}
|
|
|
|
|
2023-08-21 04:50:14 -06:00
|
|
|
var minFrameRate: Float64 {
|
|
|
|
let maxRange = videoSupportedFrameRateRanges.max { l, r in
|
|
|
|
return l.maxFrameRate < r.maxFrameRate
|
|
|
|
}
|
|
|
|
return maxRange?.maxFrameRate ?? 0
|
|
|
|
}
|
|
|
|
|
|
|
|
var maxFrameRate: Float64 {
|
|
|
|
let maxRange = videoSupportedFrameRateRanges.max { l, r in
|
|
|
|
return l.maxFrameRate < r.maxFrameRate
|
|
|
|
}
|
|
|
|
return maxRange?.maxFrameRate ?? 0
|
|
|
|
}
|
|
|
|
|
2023-10-06 08:11:09 -06:00
|
|
|
var supportsVideoHDR: Bool {
|
|
|
|
let pixelFormat = CMFormatDescriptionGetMediaSubType(formatDescription)
|
|
|
|
let hdrFormats = [
|
|
|
|
kCVPixelFormatType_420YpCbCr10BiPlanarFullRange,
|
|
|
|
kCVPixelFormatType_420YpCbCr10BiPlanarVideoRange,
|
|
|
|
kCVPixelFormatType_Lossless_420YpCbCr10PackedBiPlanarVideoRange,
|
|
|
|
]
|
|
|
|
return hdrFormats.contains(pixelFormat)
|
|
|
|
}
|
|
|
|
|
|
|
|
func toDictionary() -> [String: AnyHashable] {
|
2023-09-01 07:07:16 -06:00
|
|
|
let availablePixelFormats = AVCaptureVideoDataOutput().availableVideoPixelFormatTypes
|
|
|
|
let pixelFormats = availablePixelFormats.map { format in PixelFormat(mediaSubType: format) }
|
2023-08-21 04:50:14 -06:00
|
|
|
|
2023-09-01 07:07:16 -06:00
|
|
|
return [
|
2021-03-09 02:53:29 -07:00
|
|
|
"videoStabilizationModes": videoStabilizationModes.map(\.descriptor),
|
2021-02-19 08:28:05 -07:00
|
|
|
"autoFocusSystem": autoFocusSystem.descriptor,
|
2023-10-06 08:11:09 -06:00
|
|
|
"photoHeight": photoDimensions.height,
|
|
|
|
"photoWidth": photoDimensions.width,
|
2021-07-08 02:59:27 -06:00
|
|
|
"videoHeight": videoDimensions.height,
|
|
|
|
"videoWidth": videoDimensions.width,
|
2021-02-19 08:28:05 -07:00
|
|
|
"maxISO": maxISO,
|
|
|
|
"minISO": minISO,
|
|
|
|
"fieldOfView": videoFieldOfView,
|
|
|
|
"maxZoom": videoMaxZoomFactor,
|
2023-10-06 08:11:09 -06:00
|
|
|
"supportsVideoHDR": supportsVideoHDR,
|
2021-02-19 08:28:05 -07:00
|
|
|
"supportsPhotoHDR": false,
|
2023-08-21 04:50:14 -06:00
|
|
|
"minFps": minFrameRate,
|
|
|
|
"maxFps": maxFrameRate,
|
2023-09-01 07:07:16 -06:00
|
|
|
"pixelFormats": pixelFormats.map(\.unionValue),
|
2023-09-21 08:29:46 -06:00
|
|
|
"supportsDepthCapture": !supportedDepthDataFormats.isEmpty,
|
2021-02-19 08:28:05 -07:00
|
|
|
]
|
|
|
|
}
|
2023-10-06 08:11:09 -06:00
|
|
|
|
|
|
|
/**
|
|
|
|
Compares this format to the given JS `CameraDeviceFormat`.
|
|
|
|
Only the most important properties (such as dimensions and FPS) are taken into consideration,
|
|
|
|
so this is not an exact equals, but more like a "matches filter" comparison.
|
|
|
|
*/
|
|
|
|
func isEqualTo(jsFormat dict: NSDictionary) -> Bool {
|
|
|
|
guard dict["photoWidth"] as? Int32 == photoDimensions.width && dict["photoHeight"] as? Int32 == photoDimensions.height else {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
guard dict["videoWidth"] as? Int32 == videoDimensions.width && dict["videoHeight"] as? Int32 == videoDimensions.height else {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
guard dict["minFps"] as? Float64 == minFrameRate && dict["maxFps"] as? Float64 == maxFrameRate else {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
guard dict["supportsVideoHDR"] as? Bool == supportsVideoHDR else {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
return true
|
|
|
|
}
|
2021-02-19 08:28:05 -07:00
|
|
|
}
|