Title: [212844] trunk/Source/WebCore
Revision
212844
Author
[email protected]
Date
2017-02-22 12:06:57 -0800 (Wed, 22 Feb 2017)

Log Message

[MediaStream iOS] Respond to capture interruptions and notifications
https://bugs.webkit.org/show_bug.cgi?id=168610

Reviewed by Jer Noble.

* platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaStreamAVFObjC.mm:
(WebCore::MediaPlayerPrivateMediaStreamAVFObjC::ensureLayer): Drive-by cleanup: don't create
a sample buffer display layer unless there is an active video track.

* platform/mediastream/mac/AVMediaCaptureSource.h:
* platform/mediastream/mac/AVMediaCaptureSource.mm:
(WebCore::AVMediaCaptureSource::AVMediaCaptureSource): Add static_asserts to ensure that
WebCore::InterruptionReason values map directly to AVCaptureSessionInterruptionReason values.
(WebCore::AVMediaCaptureSource::~AVMediaCaptureSource): Minor cleanup.
(WebCore::AVMediaCaptureSource::startProducingData): Start listening for notifications before
starting the session.
(WebCore::AVMediaCaptureSource::stopProducingData): Remove the notification observers before
stopping the session.
(WebCore::AVMediaCaptureSource::setupSession): Minor style cleanup.
(WebCore::AVMediaCaptureSource::captureSessionRuntimeError): New. When the error is AVErrorMediaServicesWereReset,
sometimes caused by a mediaserverd crash, try to restart the session one time.
(WebCore::AVMediaCaptureSource::captureSessionBeginInterruption): Store the interruption reason.
(WebCore::AVMediaCaptureSource::captureSessionEndInterruption): Try to restart the session if
it was interrupted because the app went into multi-app layout mode.
(WebCore::sessionKVOProperties): Drive-by cleanup.
(-[WebCoreAVMediaCaptureSourceObserver initWithCallback:]):
(-[WebCoreAVMediaCaptureSourceObserver disconnect]):
(-[WebCoreAVMediaCaptureSourceObserver addNotificationObservers]):
(-[WebCoreAVMediaCaptureSourceObserver removeNotificationObservers]):
(-[WebCoreAVMediaCaptureSourceObserver sessionRuntimeError:]):
(-[WebCoreAVMediaCaptureSourceObserver beginSessionInterrupted:]):
(-[WebCoreAVMediaCaptureSourceObserver endSessionInterrupted:]):

* platform/mediastream/mac/AVVideoCaptureSource.mm:
(WebCore::AVVideoCaptureSource::initializeCapabilities): Not all AVCaptureSession preset strings
are available on all platforms so load with SOFT_LINK_POINTER_OPTIONAL and NULL check before use.
(WebCore::sizeForPreset): Ditto.
(WebCore::AVVideoCaptureSource::bestSessionPresetForVideoDimensions): Ditto.

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (212843 => 212844)


--- trunk/Source/WebCore/ChangeLog	2017-02-22 19:33:02 UTC (rev 212843)
+++ trunk/Source/WebCore/ChangeLog	2017-02-22 20:06:57 UTC (rev 212844)
@@ -1,3 +1,44 @@
+2017-02-22  Eric Carlson  <[email protected]>
+
+        [MediaStream iOS] Respond to capture interruptions and notifications
+        https://bugs.webkit.org/show_bug.cgi?id=168610
+
+        Reviewed by Jer Noble.
+
+        * platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaStreamAVFObjC.mm:
+        (WebCore::MediaPlayerPrivateMediaStreamAVFObjC::ensureLayer): Drive-by cleanup: don't create
+        a sample buffer display layer unless there is an active video track.
+
+        * platform/mediastream/mac/AVMediaCaptureSource.h:
+        * platform/mediastream/mac/AVMediaCaptureSource.mm:
+        (WebCore::AVMediaCaptureSource::AVMediaCaptureSource): Add static_asserts to ensure that
+        WebCore::InterruptionReason values map directly to AVCaptureSessionInterruptionReason values.
+        (WebCore::AVMediaCaptureSource::~AVMediaCaptureSource): Minor cleanup.
+        (WebCore::AVMediaCaptureSource::startProducingData): Start listening for notifications before
+        starting the session.
+        (WebCore::AVMediaCaptureSource::stopProducingData): Remove the notification observers before
+        stopping the session.
+        (WebCore::AVMediaCaptureSource::setupSession): Minor style cleanup.
+        (WebCore::AVMediaCaptureSource::captureSessionRuntimeError): New. When the error is AVErrorMediaServicesWereReset,
+        sometimes caused by a mediaserverd crash, try to restart the session one time.
+        (WebCore::AVMediaCaptureSource::captureSessionBeginInterruption): Store the interruption reason.
+        (WebCore::AVMediaCaptureSource::captureSessionEndInterruption): Try to restart the session if
+        it was interrupted because the app went into multi-app layout mode.
+        (WebCore::sessionKVOProperties): Drive-by cleanup.
+        (-[WebCoreAVMediaCaptureSourceObserver initWithCallback:]):
+        (-[WebCoreAVMediaCaptureSourceObserver disconnect]):
+        (-[WebCoreAVMediaCaptureSourceObserver addNotificationObservers]):
+        (-[WebCoreAVMediaCaptureSourceObserver removeNotificationObservers]):
+        (-[WebCoreAVMediaCaptureSourceObserver sessionRuntimeError:]):
+        (-[WebCoreAVMediaCaptureSourceObserver beginSessionInterrupted:]):
+        (-[WebCoreAVMediaCaptureSourceObserver endSessionInterrupted:]):
+
+        * platform/mediastream/mac/AVVideoCaptureSource.mm:
+        (WebCore::AVVideoCaptureSource::initializeCapabilities): Not all AVCaptureSession preset strings
+        are available on all platforms so load with SOFT_LINK_POINTER_OPTIONAL and NULL check before use.
+        (WebCore::sizeForPreset): Ditto.
+        (WebCore::AVVideoCaptureSource::bestSessionPresetForVideoDimensions): Ditto.
+
 2017-02-22  Zalan Bujtas  <[email protected]>
 
         Simple line layout: ensureLineBoxes for paginated content.

Modified: trunk/Source/WebCore/platform/mediastream/mac/AVMediaCaptureSource.h (212843 => 212844)


--- trunk/Source/WebCore/platform/mediastream/mac/AVMediaCaptureSource.h	2017-02-22 19:33:02 UTC (rev 212843)
+++ trunk/Source/WebCore/platform/mediastream/mac/AVMediaCaptureSource.h	2017-02-22 20:06:57 UTC (rev 212844)
@@ -39,6 +39,7 @@
 OBJC_CLASS AVCaptureOutput;
 OBJC_CLASS AVCaptureSession;
 OBJC_CLASS AVCaptureVideoDataOutput;
+OBJC_CLASS NSError;
 OBJC_CLASS WebCoreAVMediaCaptureSourceObserver;
 
 typedef struct opaqueCMSampleBuffer *CMSampleBufferRef;
@@ -53,8 +54,13 @@
 
     virtual void captureOutputDidOutputSampleBufferFromConnection(AVCaptureOutput*, CMSampleBufferRef, AVCaptureConnection*) = 0;
 
-    virtual void captureSessionIsRunningDidChange(bool);
+    void captureSessionIsRunningDidChange(bool);
+    void captureSessionRuntimeError(RetainPtr<NSError>);
 
+    enum class InterruptionReason { None, VideoNotAllowedInBackground, AudioInUse, VideoInUse, VideoNotAllowedInSideBySide };
+    void captureSessionBeginInterruption(RetainPtr<NSNotification>);
+    void captureSessionEndInterruption(RetainPtr<NSNotification>);
+
     AVCaptureSession *session() const { return m_session.get(); }
 
     const RealtimeMediaSourceSettings& settings() const final;
@@ -98,7 +104,8 @@
     RefPtr<RealtimeMediaSourceCapabilities> m_capabilities;
     RetainPtr<AVCaptureSession> m_session;
     RetainPtr<AVCaptureDevice> m_device;
-    bool m_isRunning { false};
+    InterruptionReason m_interruption { InterruptionReason::None };
+    bool m_isRunning { false };
 };
 
 } // namespace WebCore

Modified: trunk/Source/WebCore/platform/mediastream/mac/AVMediaCaptureSource.mm (212843 => 212844)


--- trunk/Source/WebCore/platform/mediastream/mac/AVMediaCaptureSource.mm	2017-02-22 19:33:02 UTC (rev 212843)
+++ trunk/Source/WebCore/platform/mediastream/mac/AVMediaCaptureSource.mm	2017-02-22 20:06:57 UTC (rev 212844)
@@ -38,6 +38,7 @@
 #import <AVFoundation/AVCaptureInput.h>
 #import <AVFoundation/AVCaptureOutput.h>
 #import <AVFoundation/AVCaptureSession.h>
+#import <AVFoundation/AVError.h>
 #import <objc/runtime.h>
 #import <wtf/MainThread.h>
 
@@ -72,21 +73,25 @@
 SOFT_LINK_POINTER(AVFoundation, AVMediaTypeAudio, NSString *)
 SOFT_LINK_POINTER(AVFoundation, AVMediaTypeMuxed, NSString *)
 SOFT_LINK_POINTER(AVFoundation, AVMediaTypeVideo, NSString *)
-SOFT_LINK_POINTER(AVFoundation, AVCaptureSessionPreset1280x720, NSString *)
-SOFT_LINK_POINTER(AVFoundation, AVCaptureSessionPreset640x480, NSString *)
-SOFT_LINK_POINTER(AVFoundation, AVCaptureSessionPreset352x288, NSString *)
-SOFT_LINK_POINTER(AVFoundation, AVCaptureSessionPresetLow, NSString *)
-SOFT_LINK_POINTER(AVFoundation, AVCaptureSessionDidStopRunningNotification, NSString *)
 
 #define AVMediaTypeAudio getAVMediaTypeAudio()
 #define AVMediaTypeMuxed getAVMediaTypeMuxed()
 #define AVMediaTypeVideo getAVMediaTypeVideo()
-#define AVCaptureSessionPreset1280x720 getAVCaptureSessionPreset1280x720()
-#define AVCaptureSessionPreset640x480 getAVCaptureSessionPreset640x480()
-#define AVCaptureSessionPreset352x288 getAVCaptureSessionPreset352x288()
-#define AVCaptureSessionPresetLow getAVCaptureSessionPresetLow()
-#define AVCaptureSessionDidStopRunningNotification getAVCaptureSessionDidStopRunningNotification()
 
+#if PLATFORM(IOS)
+SOFT_LINK_POINTER_OPTIONAL(AVFoundation, AVCaptureSessionRuntimeErrorNotification, NSString *)
+SOFT_LINK_POINTER_OPTIONAL(AVFoundation, AVCaptureSessionWasInterruptedNotification, NSString *)
+SOFT_LINK_POINTER_OPTIONAL(AVFoundation, AVCaptureSessionInterruptionEndedNotification, NSString *)
+SOFT_LINK_POINTER_OPTIONAL(AVFoundation, AVCaptureSessionInterruptionReasonKey, NSString *)
+SOFT_LINK_POINTER_OPTIONAL(AVFoundation, AVCaptureSessionErrorKey, NSString *)
+
+#define AVCaptureSessionRuntimeErrorNotification getAVCaptureSessionRuntimeErrorNotification()
+#define AVCaptureSessionWasInterruptedNotification getAVCaptureSessionWasInterruptedNotification()
+#define AVCaptureSessionInterruptionEndedNotification getAVCaptureSessionInterruptionEndedNotification()
+#define AVCaptureSessionInterruptionReasonKey getAVCaptureSessionInterruptionReasonKey()
+#define AVCaptureSessionErrorKey getAVCaptureSessionErrorKey()
+#endif
+
 using namespace WebCore;
 
 @interface WebCoreAVMediaCaptureSourceObserver : NSObject<AVCaptureAudioDataOutputSampleBufferDelegate, AVCaptureVideoDataOutputSampleBufferDelegate>
@@ -96,13 +101,20 @@
 
 -(id)initWithCallback:(AVMediaCaptureSource*)callback;
 -(void)disconnect;
--(void)captureOutput:(AVCaptureOutputType *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnectionType *)connection;
--(void)observeValueForKeyPath:keyPath ofObject:(id)object change:(NSDictionary *)change context:(void*)context;
+-(void)addNotificationObservers;
+-(void)removeNotificationObservers;
+-(void)captureOutput:(AVCaptureOutputType*)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnectionType*)connection;
+-(void)observeValueForKeyPath:keyPath ofObject:(id)object change:(NSDictionary*)change context:(void*)context;
+#if PLATFORM(IOS)
+-(void)sessionRuntimeError:(NSNotification*)notification;
+-(void)beginSessionInterrupted:(NSNotification*)notification;
+-(void)endSessionInterrupted:(NSNotification*)notification;
+#endif
 @end
 
 namespace WebCore {
 
-static NSArray* sessionKVOProperties();
+static NSArray<NSString*>* sessionKVOProperties();
 
 static dispatch_queue_t globaAudioCaptureSerialQueue()
 {
@@ -130,6 +142,13 @@
     , m_objcObserver(adoptNS([[WebCoreAVMediaCaptureSourceObserver alloc] initWithCallback:this]))
     , m_device(device)
 {
+#if PLATFORM(IOS)
+    static_assert(static_cast<int>(InterruptionReason::VideoNotAllowedInBackground) == static_cast<int>(AVCaptureSessionInterruptionReasonVideoDeviceNotAvailableInBackground), "InterruptionReason::VideoNotAllowedInBackground is not AVCaptureSessionInterruptionReasonVideoDeviceNotAvailableInBackground as expected");
+    static_assert(static_cast<int>(InterruptionReason::VideoNotAllowedInSideBySide) == AVCaptureSessionInterruptionReasonVideoDeviceNotAvailableWithMultipleForegroundApps, "InterruptionReason::VideoNotAllowedInSideBySide is not AVCaptureSessionInterruptionReasonVideoDeviceNotAvailableWithMultipleForegroundApps as expected");
+    static_assert(static_cast<int>(InterruptionReason::VideoInUse) == AVCaptureSessionInterruptionReasonVideoDeviceInUseByAnotherClient, "InterruptionReason::VideoInUse is not AVCaptureSessionInterruptionReasonVideoDeviceInUseByAnotherClient as expected");
+    static_assert(static_cast<int>(InterruptionReason::AudioInUse) == AVCaptureSessionInterruptionReasonAudioDeviceInUseByAnotherClient, "InterruptionReason::AudioInUse is not AVCaptureSessionInterruptionReasonAudioDeviceInUseByAnotherClient as expected");
+#endif
+    
     setPersistentID(device.uniqueID);
     setMuted(true);
 }
@@ -138,11 +157,15 @@
 {
     [m_objcObserver disconnect];
 
-    if (m_session) {
-        for (NSString *keyName in sessionKVOProperties())
-            [m_session removeObserver:m_objcObserver.get() forKeyPath:keyName];
+    if (!m_session)
+        return;
+
+    for (NSString *keyName in sessionKVOProperties())
+        [m_session removeObserver:m_objcObserver.get() forKeyPath:keyName];
+
+    if ([m_session isRunning])
         [m_session stopRunning];
-    }
+
 }
 
 void AVMediaCaptureSource::startProducingData()
@@ -152,7 +175,8 @@
     
     if ([m_session isRunning])
         return;
-    
+
+    [m_objcObserver addNotificationObservers];
     [m_session startRunning];
 }
 
@@ -161,6 +185,7 @@
     if (!m_session || ![m_session isRunning])
         return;
 
+    [m_objcObserver removeNotificationObservers];
     [m_session stopRunning];
 }
 
@@ -223,7 +248,7 @@
         return;
 
     m_session = adoptNS([allocAVCaptureSessionInstance() init]);
-    for (NSString *keyName in sessionKVOProperties())
+    for (NSString* keyName in sessionKVOProperties())
         [m_session addObserver:m_objcObserver.get() forKeyPath:keyName options:NSKeyValueObservingOptionNew context:(void *)nil];
 
     [m_session beginConfiguration];
@@ -253,6 +278,35 @@
     });
 }
 
+#if PLATFORM(IOS)
+void AVMediaCaptureSource::captureSessionRuntimeError(RetainPtr<NSError> error)
+{
+    if (!m_isRunning || error.get().code != AVErrorMediaServicesWereReset)
+        return;
+
+    // Try to restart the session, but reset m_isRunning immediately so if it fails we won't try again.
+    [m_session startRunning];
+    m_isRunning = [m_session isRunning];
+}
+
+void AVMediaCaptureSource::captureSessionBeginInterruption(RetainPtr<NSNotification> notification)
+{
+    m_interruption = static_cast<AVMediaCaptureSource::InterruptionReason>([notification.get().userInfo[AVCaptureSessionInterruptionReasonKey] integerValue]);
+}
+
+void AVMediaCaptureSource::captureSessionEndInterruption(RetainPtr<NSNotification>)
+{
+    InterruptionReason reason = m_interruption;
+
+    m_interruption = InterruptionReason::None;
+    if (reason != InterruptionReason::VideoNotAllowedInSideBySide || m_isRunning)
+        return;
+
+    [m_session startRunning];
+    m_isRunning = [m_session isRunning];
+}
+#endif
+
 void AVMediaCaptureSource::setVideoSampleBufferDelegate(AVCaptureVideoDataOutputType* videoOutput)
 {
     [videoOutput setSampleBufferDelegate:m_objcObserver.get() queue:globaVideoCaptureSerialQueue()];
@@ -269,7 +323,7 @@
     return nullptr;
 }
 
-NSArray* sessionKVOProperties()
+NSArray<NSString*>* sessionKVOProperties()
 {
     static NSArray* keys = [@[@"running"] retain];
     return keys;
@@ -286,6 +340,7 @@
         return nil;
 
     m_callback = callback;
+
     return self;
 }
 
@@ -293,10 +348,33 @@
 {
     [NSObject cancelPreviousPerformRequestsWithTarget:self];
     m_callback = 0;
+    [self removeNotificationObservers];
 }
 
-- (void)captureOutput:(AVCaptureOutputType *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnectionType *)connection
+- (void)addNotificationObservers
 {
+#if PLATFORM(IOS)
+    ASSERT(m_callback);
+
+    NSNotificationCenter* center = [NSNotificationCenter defaultCenter];
+    AVCaptureSessionType* session = m_callback->session();
+
+    [center addObserver:self selector:@selector(sessionRuntimeError:) name:AVCaptureSessionRuntimeErrorNotification object:session];
+    [center addObserver:self selector:@selector(beginSessionInterrupted:) name:AVCaptureSessionWasInterruptedNotification object:session];
+    [center addObserver:self selector:@selector(endSessionInterrupted:) name:AVCaptureSessionInterruptionEndedNotification object:session];
+#endif
+}
+
+- (void)removeNotificationObservers
+{
+#if PLATFORM(IOS)
+    ASSERT(m_callback);
+    [[NSNotificationCenter defaultCenter] removeObserver:m_callback->session()];
+#endif
+}
+
+- (void)captureOutput:(AVCaptureOutputType*)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnectionType*)connection
+{
     if (!m_callback)
         return;
 
@@ -303,7 +381,7 @@
     m_callback->captureOutputDidOutputSampleBufferFromConnection(captureOutput, sampleBuffer, connection);
 }
 
--(void)observeValueForKeyPath:keyPath ofObject:(id)object change:(NSDictionary *)change context:(void*)context
+- (void)observeValueForKeyPath:keyPath ofObject:(id)object change:(NSDictionary*)change context:(void*)context
 {
     UNUSED_PARAM(object);
     UNUSED_PARAM(context);
@@ -328,6 +406,33 @@
         m_callback->captureSessionIsRunningDidChange([newValue boolValue]);
 }
 
+#if PLATFORM(IOS)
+- (void)sessionRuntimeError:(NSNotification*)notification
+{
+    NSError *error = notification.userInfo[AVCaptureSessionErrorKey];
+    LOG(Media, "WebCoreAVMediaCaptureSourceObserver::sessionRuntimeError(%p) - error = %s", self, [[error localizedDescription] UTF8String]);
+
+    if (m_callback)
+        m_callback->captureSessionRuntimeError(error);
+}
+
+-(void)beginSessionInterrupted:(NSNotification*)notification
+{
+    LOG(Media, "WebCoreAVMediaCaptureSourceObserver::beginSessionInterrupted(%p) - reason = %d", self, [notification.userInfo[AVCaptureSessionInterruptionReasonKey] integerValue]);
+
+    if (m_callback)
+        m_callback->captureSessionBeginInterruption(notification);
+}
+
+- (void)endSessionInterrupted:(NSNotification*)notification
+{
+    LOG(Media, "WebCoreAVMediaCaptureSourceObserver::endSessionInterrupted(%p) ", self);
+
+    if (m_callback)
+        m_callback->captureSessionEndInterruption(notification);
+}
+#endif
+
 @end
 
 #endif // ENABLE(MEDIA_STREAM)

Modified: trunk/Source/WebCore/platform/mediastream/mac/AVVideoCaptureSource.mm (212843 => 212844)


--- trunk/Source/WebCore/platform/mediastream/mac/AVVideoCaptureSource.mm	2017-02-22 19:33:02 UTC (rev 212843)
+++ trunk/Source/WebCore/platform/mediastream/mac/AVVideoCaptureSource.mm	2017-02-22 20:06:57 UTC (rev 212844)
@@ -84,12 +84,12 @@
 #define AVCaptureVideoPreviewLayer getAVCaptureVideoPreviewLayerClass()
 #define AVFrameRateRange getAVFrameRateRangeClass()
 
-SOFT_LINK_POINTER(AVFoundation, AVCaptureSessionPreset1280x720, NSString *)
-SOFT_LINK_POINTER(AVFoundation, AVCaptureSessionPreset960x540, NSString *)
-SOFT_LINK_POINTER(AVFoundation, AVCaptureSessionPreset640x480, NSString *)
-SOFT_LINK_POINTER(AVFoundation, AVCaptureSessionPreset352x288, NSString *)
-SOFT_LINK_POINTER(AVFoundation, AVCaptureSessionPreset320x240, NSString *)
-SOFT_LINK_POINTER(AVFoundation, AVCaptureSessionPresetLow, NSString *)
+SOFT_LINK_POINTER_OPTIONAL(AVFoundation, AVCaptureSessionPreset1280x720, NSString *)
+SOFT_LINK_POINTER_OPTIONAL(AVFoundation, AVCaptureSessionPreset960x540, NSString *)
+SOFT_LINK_POINTER_OPTIONAL(AVFoundation, AVCaptureSessionPreset640x480, NSString *)
+SOFT_LINK_POINTER_OPTIONAL(AVFoundation, AVCaptureSessionPreset352x288, NSString *)
+SOFT_LINK_POINTER_OPTIONAL(AVFoundation, AVCaptureSessionPreset320x240, NSString *)
+SOFT_LINK_POINTER_OPTIONAL(AVFoundation, AVCaptureSessionPresetLow, NSString *)
 
 #define AVCaptureSessionPreset1280x720 getAVCaptureSessionPreset1280x720()
 #define AVCaptureSessionPreset960x540 getAVCaptureSessionPreset960x540()
@@ -164,27 +164,27 @@
             highestFrameRateRange = std::max<Float64>(highestFrameRateRange, range.maxFrameRate);
         }
 
-        if ([videoDevice supportsAVCaptureSessionPreset:AVCaptureSessionPreset1280x720]) {
+        if (AVCaptureSessionPreset1280x720 && [videoDevice supportsAVCaptureSessionPreset:AVCaptureSessionPreset1280x720]) {
             updateSizeMinMax(minimumWidth, maximumWidth, 1280);
             updateSizeMinMax(minimumHeight, maximumHeight, 720);
             updateAspectRatioMinMax(minimumAspectRatio, maximumAspectRatio, 1280.0 / 720);
         }
-        if ([videoDevice supportsAVCaptureSessionPreset:AVCaptureSessionPreset960x540]) {
+        if (AVCaptureSessionPreset960x540 && [videoDevice supportsAVCaptureSessionPreset:AVCaptureSessionPreset960x540]) {
             updateSizeMinMax(minimumWidth, maximumWidth, 960);
             updateSizeMinMax(minimumHeight, maximumHeight, 540);
             updateAspectRatioMinMax(minimumAspectRatio, maximumAspectRatio, 960 / 540);
         }
-        if ([videoDevice supportsAVCaptureSessionPreset:AVCaptureSessionPreset640x480]) {
+        if (AVCaptureSessionPreset640x480 && [videoDevice supportsAVCaptureSessionPreset:AVCaptureSessionPreset640x480]) {
             updateSizeMinMax(minimumWidth, maximumWidth, 640);
             updateSizeMinMax(minimumHeight, maximumHeight, 480);
             updateAspectRatioMinMax(minimumAspectRatio, maximumAspectRatio, 640 / 480);
         }
-        if ([videoDevice supportsAVCaptureSessionPreset:AVCaptureSessionPreset352x288]) {
+        if (AVCaptureSessionPreset352x288 && [videoDevice supportsAVCaptureSessionPreset:AVCaptureSessionPreset352x288]) {
             updateSizeMinMax(minimumWidth, maximumWidth, 352);
             updateSizeMinMax(minimumHeight, maximumHeight, 288);
             updateAspectRatioMinMax(minimumAspectRatio, maximumAspectRatio, 352 / 288);
         }
-        if ([videoDevice supportsAVCaptureSessionPreset:AVCaptureSessionPreset320x240]) {
+        if (AVCaptureSessionPreset320x240 && [videoDevice supportsAVCaptureSessionPreset:AVCaptureSessionPreset320x240]) {
             updateSizeMinMax(minimumWidth, maximumWidth, 320);
             updateSizeMinMax(minimumHeight, maximumHeight, 240);
             updateAspectRatioMinMax(minimumAspectRatio, maximumAspectRatio, 320 / 240);
@@ -239,19 +239,19 @@
     if (!preset)
         return { };
 
-    if ([preset isEqualToString:AVCaptureSessionPreset1280x720])
+    if (AVCaptureSessionPreset1280x720 && [preset isEqualToString:AVCaptureSessionPreset1280x720])
         return { 1280, 720 };
 
-    if ([preset isEqualToString:AVCaptureSessionPreset960x540])
+    if (AVCaptureSessionPreset960x540 && [preset isEqualToString:AVCaptureSessionPreset960x540])
         return { 960, 540 };
 
-    if ([preset isEqualToString:AVCaptureSessionPreset640x480])
+    if (AVCaptureSessionPreset640x480 && [preset isEqualToString:AVCaptureSessionPreset640x480])
         return { 640, 480 };
 
-    if ([preset isEqualToString:AVCaptureSessionPreset352x288])
+    if (AVCaptureSessionPreset352x288 && [preset isEqualToString:AVCaptureSessionPreset352x288])
         return { 352, 288 };
 
-    if ([preset isEqualToString:AVCaptureSessionPreset320x240])
+    if (AVCaptureSessionPreset320x240 && [preset isEqualToString:AVCaptureSessionPreset320x240])
         return { 320, 240 };
     
     return { };
@@ -495,19 +495,19 @@
         return nil;
 
     AVCaptureDeviceTypedef *videoDevice = device();
-    if ((!width || width.value() == 1280) && (!height || height.value() == 720))
+    if ((!width || width.value() == 1280) && (!height || height.value() == 720) && AVCaptureSessionPreset1280x720)
         return [videoDevice supportsAVCaptureSessionPreset:AVCaptureSessionPreset1280x720] ? AVCaptureSessionPreset1280x720 : nil;
 
-    if ((!width || width.value() == 960) && (!height || height.value() == 540 ))
+    if ((!width || width.value() == 960) && (!height || height.value() == 540) && AVCaptureSessionPreset960x540)
         return [videoDevice supportsAVCaptureSessionPreset:AVCaptureSessionPreset960x540] ? AVCaptureSessionPreset960x540 : nil;
 
-    if ((!width || width.value() == 640) && (!height || height.value() == 480 ))
+    if ((!width || width.value() == 640) && (!height || height.value() == 480 ) && AVCaptureSessionPreset640x480)
         return [videoDevice supportsAVCaptureSessionPreset:AVCaptureSessionPreset640x480] ? AVCaptureSessionPreset640x480 : nil;
 
-    if ((!width || width.value() == 352) && (!height || height.value() == 288 ))
+    if ((!width || width.value() == 352) && (!height || height.value() == 288 ) && AVCaptureSessionPreset352x288)
         return [videoDevice supportsAVCaptureSessionPreset:AVCaptureSessionPreset352x288] ? AVCaptureSessionPreset352x288 : nil;
 
-    if ((!width || width.value() == 320) && (!height || height.value() == 240 ))
+    if ((!width || width.value() == 320) && (!height || height.value() == 240 ) && AVCaptureSessionPreset320x240)
         return [videoDevice supportsAVCaptureSessionPreset:AVCaptureSessionPreset320x240] ? AVCaptureSessionPreset320x240 : nil;
 
     return nil;
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to