avfvideosrc: Explicitly request device video permissions for macOS 10.14+

Since macOS Mojave (10.14), video permissions have to be explicitly
granted by a user in order to open a video device such as a camera.
This commit adds a check for the current permission status, and tries
to request for permission if applicable.
This commit is contained in:
o0Ignition0o 2019-11-30 14:08:06 +01:00
parent 24d096597b
commit d29012a760

View file

@ -427,6 +427,45 @@ static AVCaptureVideoOrientation GstAVFVideoSourceOrientation2AVCaptureVideoOrie
GST_DEBUG_OBJECT (element, "Opening device");
// Since Mojave, permissions are now supposed to be explicitly granted
// before performing anything on a device
if (@available(macOS 10.14, *)) {
// Check if permission has already been granted (or denied)
AVAuthorizationStatus authStatus = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];
switch (authStatus) {
case AVAuthorizationStatusDenied:
// The user has explicitly denied permission for media capture.
GST_ELEMENT_ERROR (element, RESOURCE, NOT_AUTHORIZED,
("Device video access permission has been explicitly denied before"), ("Authorization status: %d", (int)authStatus));
return success;
case AVAuthorizationStatusRestricted:
// The user is not allowed to access media capture devices.
GST_ELEMENT_ERROR (element, RESOURCE, NOT_AUTHORIZED,
("Device video access permission cannot be granted by the user"), ("Authorization status: %d", (int)authStatus));
return success;
case AVAuthorizationStatusAuthorized:
// The user has explicitly granted permission for media capture,
// or explicit user permission is not necessary for the media type in question.
GST_DEBUG_OBJECT (element, "Device video access permission has already been granted");
break;
case AVAuthorizationStatusNotDetermined:
// Explicit user permission is required for media capture,
// but the user has not yet granted or denied such permission.
dispatch_sync (mainQueue, ^{
[AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo completionHandler:^(BOOL granted) {
GST_DEBUG_OBJECT (element, "Device video access permission %s", granted ? "granted" : "not granted");
}];
});
// Check if permission has been granted
AVAuthorizationStatus videoAuthorizationStatus = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];
if (videoAuthorizationStatus != AVAuthorizationStatusAuthorized) {
GST_ELEMENT_ERROR (element, RESOURCE, NOT_AUTHORIZED,
("Device video access permission has just been denied"), ("Authorization status: %d", (int)videoAuthorizationStatus));
return success;
}
}
}
dispatch_sync (mainQueue, ^{
BOOL ret;