Skip to content

Commit

Permalink
[Cocoa] Use AVCaptureDeviceDiscoverySession for camera discovery
Browse files Browse the repository at this point in the history
https://bugs.webkit.org/show_bug.cgi?id=248054
rdar://101919809

Reviewed by Youenn Fablet.

* Source/WebCore/PAL/pal/cocoa/AVFoundationSoftLink.h:
* Source/WebCore/PAL/pal/cocoa/AVFoundationSoftLink.mm:

* Source/WebCore/platform/mediastream/mac/AVCaptureDeviceManager.mm:
(WebCore::currentCameras): Use AVCaptureDeviceDiscoverySession.
(WebCore::AVCaptureDeviceManager::updateCachedAVCaptureDevices): Call currentCameras.
(WebCore::AVCaptureDeviceManager::retrieveCaptureDevices): Ditto.
(WebCore::AVCaptureDeviceManager::registerForDeviceNotifications): Key-value observe
AVCaptureDeviceDiscoverySession.devices.
(WebCore::AVCaptureDeviceManager::~AVCaptureDeviceManager): Stop listening.

Canonical link: https://commits.webkit.org/256849@main
  • Loading branch information
eric-carlson committed Nov 18, 2022
1 parent 4b51a0d commit 460662e
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 5 deletions.
27 changes: 27 additions & 0 deletions Source/WebCore/PAL/pal/cocoa/AVFoundationSoftLink.h
Expand Up @@ -104,6 +104,7 @@ SOFT_LINK_CLASS_FOR_HEADER(PAL, AVCaptureOutput)
SOFT_LINK_CLASS_FOR_HEADER(PAL, AVCaptureSession)
SOFT_LINK_CLASS_FOR_HEADER(PAL, AVCaptureVideoDataOutput)
SOFT_LINK_CLASS_FOR_HEADER(PAL, AVFrameRateRange)
SOFT_LINK_CLASS_FOR_HEADER(PAL, AVCaptureDeviceDiscoverySession)
#endif

SOFT_LINK_CONSTANT_FOR_HEADER(PAL, AVFoundation, AVAudioTimePitchAlgorithmSpectral, NSString *)
Expand Down Expand Up @@ -334,6 +335,32 @@ SOFT_LINK_CONSTANT_FOR_HEADER(PAL, AVFoundation, AVAudioSessionRouteChangeReason
#define AVAudioSessionRouteChangeReasonKey PAL::get_AVFoundation_AVAudioSessionRouteChangeReasonKey()
#endif // PLATFORM(IOS_FAMILY)

#if !PLATFORM(WATCHOS) && !PLATFORM(APPLETV)
SOFT_LINK_CONSTANT_FOR_HEADER(PAL, AVFoundation, AVCaptureDeviceTypeBuiltInWideAngleCamera, NSString *)
#define AVCaptureDeviceTypeBuiltInWideAngleCamera PAL::get_AVFoundation_AVCaptureDeviceTypeBuiltInWideAngleCamera()
SOFT_LINK_CONSTANT_FOR_HEADER(PAL, AVFoundation, AVCaptureDeviceTypeBuiltInTelephotoCamera, NSString *)
#define AVCaptureDeviceTypeBuiltInTelephotoCamera PAL::get_AVFoundation_AVCaptureDeviceTypeBuiltInTelephotoCamera()
SOFT_LINK_CONSTANT_FOR_HEADER(PAL, AVFoundation, AVCaptureDeviceTypeBuiltInUltraWideCamera, NSString *)
#define AVCaptureDeviceTypeBuiltInUltraWideCamera PAL::get_AVFoundation_AVCaptureDeviceTypeBuiltInUltraWideCamera()
SOFT_LINK_CONSTANT_FOR_HEADER(PAL, AVFoundation, AVCaptureDeviceTypeBuiltInDualCamera, NSString *)
#define AVCaptureDeviceTypeBuiltInDualCamera PAL::get_AVFoundation_AVCaptureDeviceTypeBuiltInDualCamera()
SOFT_LINK_CONSTANT_FOR_HEADER(PAL, AVFoundation, AVCaptureDeviceTypeBuiltInDualWideCamera, NSString *)
#define AVCaptureDeviceTypeBuiltInDualWideCamera PAL::get_AVFoundation_AVCaptureDeviceTypeBuiltInDualWideCamera()
SOFT_LINK_CONSTANT_FOR_HEADER(PAL, AVFoundation, AVCaptureDeviceTypeBuiltInTripleCamera, NSString *)
#define AVCaptureDeviceTypeBuiltInTripleCamera PAL::get_AVFoundation_AVCaptureDeviceTypeBuiltInTripleCamera()
SOFT_LINK_CONSTANT_FOR_HEADER(PAL, AVFoundation, AVCaptureDeviceTypeBuiltInTrueDepthCamera, NSString *)
#define AVCaptureDeviceTypeBuiltInTrueDepthCamera PAL::get_AVFoundation_AVCaptureDeviceTypeBuiltInTrueDepthCamera()
SOFT_LINK_CONSTANT_FOR_HEADER(PAL, AVFoundation, AVCaptureDeviceTypeBuiltInLiDARDepthCamera, NSString *)
#define AVCaptureDeviceTypeBuiltInLiDARDepthCamera PAL::get_AVFoundation_AVCaptureDeviceTypeBuiltInLiDARDepthCamera()
SOFT_LINK_CONSTANT_FOR_HEADER(PAL, AVFoundation, AVCaptureDeviceTypeDeskViewCamera, NSString *)
#define AVCaptureDeviceTypeDeskViewCamera PAL::get_AVFoundation_AVCaptureDeviceTypeDeskViewCamera()
#endif

#if PLATFORM(MAC)
SOFT_LINK_CONSTANT_FOR_HEADER(PAL, AVFoundation, AVCaptureDeviceTypeExternalUnknown, NSString *)
#define AVCaptureDeviceTypeExternalUnknown PAL::get_AVFoundation_AVCaptureDeviceTypeExternalUnknown()
#endif

#if PLATFORM(IOS_FAMILY) && !PLATFORM(WATCHOS) && !PLATFORM(APPLETV)
SOFT_LINK_FUNCTION_FOR_HEADER(PAL, AVFoundation, AVCaptureSessionSetAuthorizedToUseCameraInMultipleForegroundAppLayout, void, (AVCaptureSession *session), (session))
#define AVCaptureSessionSetAuthorizedToUseCameraInMultipleForegroundAppLayout softLink_AVFoundation_AVCaptureSessionSetAuthorizedToUseCameraInMultipleForegroundAppLayout
Expand Down
17 changes: 17 additions & 0 deletions Source/WebCore/PAL/pal/cocoa/AVFoundationSoftLink.mm
Expand Up @@ -127,6 +127,7 @@ static BOOL justReturnsNO()
SOFT_LINK_CLASS_FOR_SOURCE_WITH_EXPORT(PAL, AVFoundation, AVCaptureSession, PAL_EXPORT)
SOFT_LINK_CLASS_FOR_SOURCE_WITH_EXPORT(PAL, AVFoundation, AVCaptureVideoDataOutput, PAL_EXPORT)
SOFT_LINK_CLASS_FOR_SOURCE_WITH_EXPORT(PAL, AVFoundation, AVFrameRateRange, PAL_EXPORT)
SOFT_LINK_CLASS_FOR_SOURCE_WITH_EXPORT(PAL, AVFoundation, AVCaptureDeviceDiscoverySession, PAL_EXPORT)
#endif

SOFT_LINK_CONSTANT_FOR_SOURCE_WITH_EXPORT(PAL, AVFoundation, AVAssetImageGeneratorApertureModeCleanAperture, NSString *, PAL_EXPORT)
Expand Down Expand Up @@ -244,6 +245,22 @@ static BOOL justReturnsNO()
SOFT_LINK_CONSTANT_MAY_FAIL_FOR_SOURCE_WITH_EXPORT(PAL, AVFoundation, AVURLAssetRequiresCustomURLLoadingKey, NSString *, PAL_EXPORT)
#endif // PLATFORM(IOS_FAMILY)

#if !PLATFORM(WATCHOS) && !PLATFORM(APPLETV)
SOFT_LINK_CONSTANT_FOR_SOURCE_WITH_EXPORT(PAL, AVFoundation, AVCaptureDeviceTypeBuiltInWideAngleCamera, NSString *, PAL_EXPORT)
SOFT_LINK_CONSTANT_FOR_SOURCE_WITH_EXPORT(PAL, AVFoundation, AVCaptureDeviceTypeBuiltInTelephotoCamera, NSString *, PAL_EXPORT)
SOFT_LINK_CONSTANT_FOR_SOURCE_WITH_EXPORT(PAL, AVFoundation, AVCaptureDeviceTypeBuiltInUltraWideCamera, NSString *, PAL_EXPORT)
SOFT_LINK_CONSTANT_FOR_SOURCE_WITH_EXPORT(PAL, AVFoundation, AVCaptureDeviceTypeBuiltInDualCamera, NSString *, PAL_EXPORT)
SOFT_LINK_CONSTANT_FOR_SOURCE_WITH_EXPORT(PAL, AVFoundation, AVCaptureDeviceTypeBuiltInDualWideCamera, NSString *, PAL_EXPORT)
SOFT_LINK_CONSTANT_FOR_SOURCE_WITH_EXPORT(PAL, AVFoundation, AVCaptureDeviceTypeBuiltInTripleCamera, NSString *, PAL_EXPORT)
SOFT_LINK_CONSTANT_FOR_SOURCE_WITH_EXPORT(PAL, AVFoundation, AVCaptureDeviceTypeBuiltInTrueDepthCamera, NSString *, PAL_EXPORT)
SOFT_LINK_CONSTANT_FOR_SOURCE_WITH_EXPORT(PAL, AVFoundation, AVCaptureDeviceTypeBuiltInLiDARDepthCamera, NSString *, PAL_EXPORT)
SOFT_LINK_CONSTANT_FOR_SOURCE_WITH_EXPORT(PAL, AVFoundation, AVCaptureDeviceTypeDeskViewCamera, NSString *, PAL_EXPORT)
#endif

#if PLATFORM(MAC)
SOFT_LINK_CONSTANT_FOR_SOURCE_WITH_EXPORT(PAL, AVFoundation, AVCaptureDeviceTypeExternalUnknown, NSString *, PAL_EXPORT)
#endif

#if PLATFORM(IOS_FAMILY) && !PLATFORM(WATCHOS) && !PLATFORM(APPLETV)
SOFT_LINK_FUNCTION_FOR_SOURCE(PAL, AVFoundation, AVCaptureSessionSetAuthorizedToUseCameraInMultipleForegroundAppLayout, void, (AVCaptureSession *session), (session))
#endif // PLATFORM(IOS_FAMILY) && !PLATFORM(WATCHOS) && !PLATFORM(APPLETV)
Expand Down
30 changes: 25 additions & 5 deletions Source/WebCore/platform/mediastream/mac/AVCaptureDeviceManager.mm
Expand Up @@ -91,10 +91,28 @@ inline static bool deviceIsAvailable(AVCaptureDevice *device)
return true;
}

static RetainPtr<NSArray<AVCaptureDevice *>> currentCameras()
{
AVCaptureDeviceDiscoverySession *discoverySession = [PAL::getAVCaptureDeviceDiscoverySessionClass()
discoverySessionWithDeviceTypes:
@[AVCaptureDeviceTypeBuiltInWideAngleCamera,
AVCaptureDeviceTypeBuiltInTelephotoCamera,
AVCaptureDeviceTypeBuiltInUltraWideCamera,
AVCaptureDeviceTypeDeskViewCamera,
#if PLATFORM(MAC)
AVCaptureDeviceTypeExternalUnknown,
#endif
]
mediaType:AVMediaTypeVideo
position:AVCaptureDevicePositionUnspecified
];
return discoverySession.devices;
}

void AVCaptureDeviceManager::updateCachedAVCaptureDevices()
{
ASSERT(!isMainThread());
auto* currentDevices = [PAL::getAVCaptureDeviceClass() devices];
auto currentDevices = currentCameras();
auto removedDevices = adoptNS([[NSMutableArray alloc] init]);
for (AVCaptureDevice *cachedDevice in m_avCaptureDevices.get()) {
if (![currentDevices containsObject:cachedDevice])
Expand All @@ -107,7 +125,7 @@ inline static bool deviceIsAvailable(AVCaptureDevice *device)
[m_avCaptureDevices removeObjectsInArray:removedDevices.get()];
}

for (AVCaptureDevice *device in currentDevices) {
for (AVCaptureDevice *device in currentDevices.get()) {

if (![device hasMediaType:AVMediaTypeVideo] && ![device hasMediaType:AVMediaTypeMuxed])
continue;
Expand Down Expand Up @@ -153,14 +171,14 @@ static inline bool isVideoDevice(AVCaptureDevice *device)

updateCachedAVCaptureDevices();

auto* currentDevices = [PAL::getAVCaptureDeviceClass() devices];
auto currentDevices = currentCameras();
Vector<CaptureDevice> deviceList;

auto* defaultVideoDevice = [PAL::getAVCaptureDeviceClass() defaultDeviceWithMediaType: AVMediaTypeVideo];
#if PLATFORM(IOS)
if ([defaultVideoDevice position] != AVCaptureDevicePositionFront) {
defaultVideoDevice = nullptr;
for (AVCaptureDevice *platformDevice in currentDevices) {
for (AVCaptureDevice *platformDevice in currentDevices.get()) {
if (!isVideoDevice(platformDevice))
continue;

Expand All @@ -175,7 +193,7 @@ static inline bool isVideoDevice(AVCaptureDevice *device)
if (defaultVideoDevice)
deviceList.append(toCaptureDevice(defaultVideoDevice, true));

for (AVCaptureDevice *platformDevice in currentDevices) {
for (AVCaptureDevice *platformDevice in currentDevices.get()) {
if (isVideoDevice(platformDevice) && platformDevice.uniqueID != defaultVideoDevice.uniqueID)
deviceList.append(toCaptureDevice(platformDevice));
}
Expand Down Expand Up @@ -230,13 +248,15 @@ static inline bool isVideoDevice(AVCaptureDevice *device)
for (AVCaptureDevice *device in m_avCaptureDevices.get())
[device removeObserver:m_objcObserver.get() forKeyPath:@"suspended"];
[PAL::getAVCaptureDeviceClass() removeObserver:m_objcObserver.get() forKeyPath:@"systemPreferredCamera"];
[PAL::getAVCaptureDeviceDiscoverySessionClass() removeObserver:m_objcObserver.get() forKeyPath:@"devices"];
}

void AVCaptureDeviceManager::registerForDeviceNotifications()
{
[[NSNotificationCenter defaultCenter] addObserver:m_objcObserver.get() selector:@selector(deviceConnectedDidChange:) name:AVCaptureDeviceWasConnectedNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:m_objcObserver.get() selector:@selector(deviceConnectedDidChange:) name:AVCaptureDeviceWasDisconnectedNotification object:nil];
[PAL::getAVCaptureDeviceClass() addObserver:m_objcObserver.get() forKeyPath:@"systemPreferredCamera" options:(NSKeyValueObservingOptionOld | NSKeyValueObservingOptionNew) context:nil];
[PAL::getAVCaptureDeviceDiscoverySessionClass() addObserver:m_objcObserver.get() forKeyPath:@"devices" options:(NSKeyValueObservingOptionOld | NSKeyValueObservingOptionNew) context:nil];
}

} // namespace WebCore
Expand Down

0 comments on commit 460662e

Please sign in to comment.