Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Task/fix video constraints #549

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion dist/cordova-plugin-iosrtc.js
Original file line number Diff line number Diff line change
Expand Up @@ -2776,7 +2776,6 @@ function isPositiveFloat(number) {
return typeof number === 'number' && number >= 0;
}


function getUserMedia(constraints) {

// Detect callback usage to assist 5.0.1 to 5.0.2 migration
Expand Down Expand Up @@ -3082,6 +3081,7 @@ function getUserMedia(constraints) {
// TODO ConstrainDouble min, max
if (typeof constraints.video.aspectRatio === 'object') {
newConstraints.video.aspectRatio = {};

if (isPositiveFloat(constraints.video.aspectRatio.min)) {
newConstraints.video.aspectRatio.min = parseFloat(constraints.video.aspectRatio.min, 10);
}
Expand Down
2 changes: 1 addition & 1 deletion js/getUserMedia.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ function isPositiveFloat(number) {
return typeof number === 'number' && number >= 0;
}


function getUserMedia(constraints) {

// Detect callback usage to assist 5.0.1 to 5.0.2 migration
Expand Down Expand Up @@ -328,6 +327,7 @@ function getUserMedia(constraints) {
// TODO ConstrainDouble min, max
if (typeof constraints.video.aspectRatio === 'object') {
newConstraints.video.aspectRatio = {};

if (isPositiveFloat(constraints.video.aspectRatio.min)) {
newConstraints.video.aspectRatio.min = parseFloat(constraints.video.aspectRatio.min, 10);
}
Expand Down
97 changes: 54 additions & 43 deletions src/PluginRTCVideoCaptureController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -49,13 +49,18 @@ class PluginRTCVideoCaptureController : NSObject {
private let DEFAULT_WIDTH : Int32 = 640
private let DEFAULT_FPS : Int = 15
private let DEFAULT_ASPECT_RATIO : Float32 = 4/3
private let DEFAULT_WIDTHS_RATIO : NSDictionary = [
"1.333333" : 640,
"1.222222": 352,
"1.777778" : 960
]
private let FACING_MODE_USER : String = "user";
private let FACING_MODE_ENV : String = "environment";

var capturer: RTCCameraVideoCapturer
var isCapturing: Bool = false;

// Default to the front camera.
// Note: Default will be front camera.
var device: AVCaptureDevice?
var deviceFormat: AVCaptureDevice.Format?
var deviceFrameRate: Int?
Expand Down Expand Up @@ -180,6 +185,7 @@ class PluginRTCVideoCaptureController : NSObject {
// facingMode ConstrainDOMString NSDictionary
// Check the video contraints: examine facingMode and deviceId
// and pick a default if neither are specified.

var position : AVCaptureDevice.Position = AVCaptureDevice.Position.unspecified;

let facingMode = self.getConstrainDOMStringValue(constraint: "facingMode"),
Expand Down Expand Up @@ -229,9 +235,8 @@ class PluginRTCVideoCaptureController : NSObject {
facingMode == "environment" && device?.position != AVCaptureDevice.Position.back ||
facingMode == "user" && device?.position != AVCaptureDevice.Position.front
)) {

NSLog("PluginRTCVideoCaptureController#findDevice facingMode fail exact requirement");
return nil;
NSLog("PluginRTCVideoCaptureController#findDevice facingMode fail exact requirement");
return nil;
}

deviceFormat = findFormatForDevice(device:device!);
Expand All @@ -258,7 +263,11 @@ class PluginRTCVideoCaptureController : NSObject {
return nil;
}

deviceFrameRate = Int(maxFrameRate > 0 ? maxFrameRate : minFrameRate)
// Compute deviceFrameRate knowing minFrameRate and maxFrameRate can be 0
deviceFrameRate = max(
max(Int(formatFrameRateRange.minFrameRate), minFrameRate),
(maxFrameRate > 0 ? min(Int(formatFrameRateRange.maxFrameRate), maxFrameRate) : self.DEFAULT_FPS)
)

NSLog("PluginRTCVideoCaptureController#findDevice deviceFrameRate:%i", deviceFrameRate!);

Expand Down Expand Up @@ -338,47 +347,44 @@ class PluginRTCVideoCaptureController : NSObject {

var selectedFormat: AVCaptureDevice.Format? = nil
let formats: NSArray = RTCCameraVideoCapturer.supportedFormats(for: device) as NSArray
let selectedFormats : NSArray = [];

var widthRange: NSDictionary = getConstraintDoubleValues(constraint: "width", defaultValue: 0),
minWidth = widthRange.object(forKey: "min") as! Int32,
maxWidth = widthRange.object(forKey: "max") as! Int32

var heightRange: NSDictionary = getConstraintDoubleValues(constraint: "height", defaultValue: 0),
minHeight = heightRange.object(forKey: "min") as! Int32,
maxHeight = heightRange.object(forKey: "max") as! Int32

var widthRange: NSDictionary = getConstraintDoubleValues(constraint: "width", defaultValue: 0),
minWidth = widthRange.object(forKey: "min") as! Int32,
maxWidth = widthRange.object(forKey: "max") as! Int32

let aspectRatioRange: NSDictionary = getConstraintLongValues(constraint: "aspectRatio", defaultValue: 0.0),
minAspectRatio = aspectRatioRange.object(forKey: "min") as! Float32,
maxAspectRatio = aspectRatioRange.object(forKey: "max") as! Float32

let frameRateRange: NSDictionary = getConstraintDoubleValues(constraint: "frameRate", defaultValue: self.DEFAULT_FPS),
minFrameRate = frameRateRange.object(forKey: "min") as! Float64,
maxFrameRate = frameRateRange.object(forKey: "max") as! Float64

// If aspectRatioRange > 0
if (minAspectRatio > 0 || maxAspectRatio > 0) {
// Compute heightRange depending widthRange and aspectRatioRange
// We dont want to compute defaultHeight and defaultWidth if only height is provided
if (minWidth != 0 && maxWidth != 0 && minHeight == 0 && maxHeight == 0) {

// and only one dimension is provided compute missing dimension
if (((minWidth > 0 || maxWidth > 0) && minHeight == 0 && maxHeight == 0)) {
minHeight = Int32(Float32(minWidth) / (minAspectRatio > 0 ? minAspectRatio : maxAspectRatio));
maxHeight = Int32(Float32(maxWidth) / (minAspectRatio > 0 ? minAspectRatio : maxAspectRatio));
} else if (((minHeight > 0 || maxHeight > 0) && minWidth == 0 && maxWidth == 0)) {
minWidth = Int32(Float32(maxHeight) * (minAspectRatio > 0 ? minAspectRatio : maxAspectRatio));
maxWidth = Int32(Float32(maxHeight) * (minAspectRatio > 0 ? minAspectRatio : maxAspectRatio));
}

NSLog("PluginRTCVideoCaptureController#findFormatForDevice contraints using aspectRatioRange - width:%i/%i, height:%i/%i, aspectRatio: %f/%f", minWidth, maxWidth, minHeight, maxHeight, minAspectRatio, maxAspectRatio);
let defaultAspectRatio = String(format: "%.6f", minAspectRatio > 0 ? minAspectRatio : DEFAULT_ASPECT_RATIO);

// If no aspectRatioRange and no dimension is provided use default dimension
} else if (minHeight == 0 && maxHeight == 0 && minWidth == 0 && maxWidth == 0) {
minHeight = self.DEFAULT_HEIGHT;
maxHeight = self.DEFAULT_HEIGHT;
maxWidth = self.DEFAULT_WIDTH;
maxWidth = self.DEFAULT_WIDTH;
let defaultWidth = DEFAULT_WIDTHS_RATIO.object(forKey: defaultAspectRatio) != nil ?
DEFAULT_WIDTHS_RATIO.object(forKey: defaultAspectRatio) as! Int : DEFAULT_WIDTH;
widthRange = getConstraintDoubleValues(constraint: "width", defaultValue: defaultWidth)
minWidth = widthRange.object(forKey: "min") as! Int32
maxWidth = widthRange.object(forKey: "max") as! Int32

NSLog("PluginRTCVideoCaptureController#findFormatForDevice contraints using default - width:%i/%i, height:%i/%i, aspectRatio: %f/%f", minWidth, maxWidth, minHeight, maxHeight, minAspectRatio, maxAspectRatio);
let defaultHeight = Int(Float32(minWidth) / (minAspectRatio > 0 ? minAspectRatio : DEFAULT_ASPECT_RATIO));
heightRange = getConstraintDoubleValues(constraint: "height", defaultValue: defaultHeight)
minHeight = heightRange.object(forKey: "min") as! Int32
maxHeight = heightRange.object(forKey: "max") as! Int32
}

let frameRateRange: NSDictionary = getConstraintDoubleValues(constraint: "frameRate", defaultValue: DEFAULT_FPS),
minFrameRate = frameRateRange.object(forKey: "min") as! Float64,
maxFrameRate = frameRateRange.object(forKey: "max") as! Float64

NSLog("PluginRTCVideoCaptureController#findFormatForDevice contraints width:%i/%i, height:%i/%i, aspectRatio: %f/%f, frameRateRanges:%f/%f", minWidth, maxWidth, minHeight, maxHeight, minAspectRatio, maxAspectRatio, minFrameRate, maxFrameRate);

for format: Any in formats {

let devFormat: AVCaptureDevice.Format = format as! AVCaptureDevice.Format
Expand All @@ -391,9 +397,9 @@ class PluginRTCVideoCaptureController : NSObject {
let frameRateRanges: [AVFrameRateRange] = devFormat.videoSupportedFrameRateRanges
let frameRates = frameRateRanges[0];

// dimension.height and dimension.width Matches
NSLog("PluginRTCVideoCaptureController#findFormatForDevice device format - width:%i, height:%i, aspectRatio: %f, frameRateRanges:%f/%f", dimension.width, dimension.height, aspectRatio, frameRates.minFrameRate, frameRates.maxFrameRate);



if (
(minAspectRatio == 0 && maxAspectRatio == 0) || (
(minAspectRatio == 0 || checkDoubleIsEqual(fromFloat: aspectRatio, toFloat: minAspectRatio)) ||
Expand All @@ -410,8 +416,10 @@ class PluginRTCVideoCaptureController : NSObject {

// dimension.height and dimension.width Matches
if (
((maxHeight == 0 || dimension.height <= maxHeight) && (minHeight == 0 || dimension.height >= minHeight)) &&
((maxWidth == 0 || dimension.width <= maxWidth) && (minWidth == 0 || dimension.width >= minWidth))
(minAspectRatio == 0 && maxAspectRatio == 0) || (
(minAspectRatio == 0 || checkDoubleIsEqual(fromFloat: aspectRatio, toFloat: minAspectRatio)) ||
(maxAspectRatio == 0 || checkDoubleIsEqual(fromFloat: aspectRatio, toFloat: maxAspectRatio))
)
) {
//NSLog("dimensions %i/%i, aspectRatio: %f", dimension.width, dimension.height, aspectRatio);
} else {
Expand Down Expand Up @@ -442,10 +450,13 @@ class PluginRTCVideoCaptureController : NSObject {
continue
}

selectedFormat = devFormat;
NSLog("PluginRTCVideoCaptureController#findFormatForDevice format width:%i, height:%i, aspectRatio: %f, frameRateRanges:%f/%f", dimension.width, dimension.height, aspectRatio, frameRates.minFrameRate, frameRates.maxFrameRate);

// TODO Handle isConstrainExact for required constraint
// Add to selectedFormats
selectedFormats.adding(selectedFormat!)
}

// TODO filter selectedFormats to get ideal match using getConstrainDoubleIdeal and getConstraintLongIdealValue

if (selectedFormat != nil) {

Expand All @@ -454,8 +465,9 @@ class PluginRTCVideoCaptureController : NSObject {
let frameRateRanges: [AVFrameRateRange] = selectedFormat!.videoSupportedFrameRateRanges
let frameRates = frameRateRanges[0];

// TODO Apply frameRates via minFrameRate/maxFrameRate

// TODO check aspectRatio, width and height, using getConstrainDoubleIdealValue
NSLog("PluginRTCVideoCaptureController#findFormatForDevice format selected width:%i, height:%i, aspectRatio: %f, frameRateRanges:%f/%f", dimension.width, dimension.height, aspectRatio, frameRates.minFrameRate, frameRates.maxFrameRate);
} else {
NSLog("PluginRTCVideoCaptureController#findFormatForDevice selected format - width:%i, height:%i, aspectRatio: %f, frameRateRanges:%f/%f", dimension.width, dimension.height, aspectRatio, frameRates.minFrameRate, frameRates.maxFrameRate);
}

Expand Down Expand Up @@ -495,7 +507,7 @@ class PluginRTCVideoCaptureController : NSObject {
fileprivate func isConstrainDOMStringExact(constraint: String) -> Bool {
return isConstrainExact(constraint: constraint);
}

fileprivate func isConstrainExact(constraint: String) -> Bool {
var isRequired: Bool = false;
let constraints = self.constraints;
Expand All @@ -517,7 +529,6 @@ class PluginRTCVideoCaptureController : NSObject {
return isRequired;
}


fileprivate func getConstrainDoubleIdealValue(constraint: String) -> Int {
return getConstrainIdealValue(constraint: constraint) as! Int;
}
Expand Down Expand Up @@ -559,7 +570,7 @@ class PluginRTCVideoCaptureController : NSObject {
} else {
return true
}
}
}

fileprivate func getConstraintDoubleValues(constraint: String, defaultValue: Int) -> NSDictionary {
return getConstrainRangeValues(constraint: constraint, defaultValue: NSNumber(value: defaultValue));
Expand Down