[MediaStream] Store video preset sizes in a map
authoreric.carlson@apple.com <eric.carlson@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 23 Aug 2018 19:31:28 +0000 (19:31 +0000)
committereric.carlson@apple.com <eric.carlson@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 23 Aug 2018 19:31:28 +0000 (19:31 +0000)
https://bugs.webkit.org/show_bug.cgi?id=188866
<rdar://problem/43622643>

Reviewed by Youenn Fablet.

No new tests, tested manually.

* platform/mediastream/mac/AVVideoCaptureSource.h:
* platform/mediastream/mac/AVVideoCaptureSource.mm:
(WebCore::AVVideoCaptureSource::AVVideoCaptureSource):
(WebCore::AVVideoCaptureSource::initializeCapabilities):
(WebCore::AVVideoCaptureSource::sizeForPreset):
(WebCore::AVVideoCaptureSource::setPreset):
(WebCore::AVVideoCaptureSource::bestSessionPresetForVideoDimensions):
(WebCore::sizeForPreset): Deleted.
(WebCore::AVVideoCaptureSource::bestSessionPresetForVideoDimensions const): Deleted.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@235233 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebCore/ChangeLog
Source/WebCore/platform/mediastream/mac/AVVideoCaptureSource.h
Source/WebCore/platform/mediastream/mac/AVVideoCaptureSource.mm

index e014248..d300016 100644 (file)
@@ -1,3 +1,23 @@
+2018-08-23  Eric Carlson  <eric.carlson@apple.com>
+
+        [MediaStream] Store video preset sizes in a map
+        https://bugs.webkit.org/show_bug.cgi?id=188866
+        <rdar://problem/43622643>
+
+        Reviewed by Youenn Fablet.
+
+        No new tests, tested manually.
+
+        * platform/mediastream/mac/AVVideoCaptureSource.h:
+        * platform/mediastream/mac/AVVideoCaptureSource.mm:
+        (WebCore::AVVideoCaptureSource::AVVideoCaptureSource):
+        (WebCore::AVVideoCaptureSource::initializeCapabilities):
+        (WebCore::AVVideoCaptureSource::sizeForPreset):
+        (WebCore::AVVideoCaptureSource::setPreset):
+        (WebCore::AVVideoCaptureSource::bestSessionPresetForVideoDimensions):
+        (WebCore::sizeForPreset): Deleted.
+        (WebCore::AVVideoCaptureSource::bestSessionPresetForVideoDimensions const): Deleted.
+
 2018-08-23  Ryan Haddad  <ryanhaddad@apple.com>
 
         Unreviewed, attempt to fix the build after r235230.
index cf62427..f8dcd00 100644 (file)
@@ -71,7 +71,7 @@ private:
 
     bool isFrameRateSupported(double frameRate);
 
-    NSString *bestSessionPresetForVideoDimensions(std::optional<int> width, std::optional<int> height) const;
+    NSString *bestSessionPresetForVideoDimensions(std::optional<int> width, std::optional<int> height);
     bool supportsSizeAndFrameRate(std::optional<int> width, std::optional<int> height, std::optional<double>) final;
 
     void initializeCapabilities(RealtimeMediaSourceCapabilities&) final;
@@ -84,16 +84,23 @@ private:
 
     void captureOutputDidOutputSampleBufferFromConnection(AVCaptureOutput*, CMSampleBufferRef, AVCaptureConnection*) final;
     void processNewFrame(RetainPtr<CMSampleBufferRef>, RetainPtr<AVCaptureConnection>);
+    IntSize sizeForPreset(NSString*);
+
+    using VideoPresetMap = HashMap<String, IntSize>;
+    VideoPresetMap& videoPresets() { return m_supportedPresets; }
 
     RetainPtr<NSString> m_pendingPreset;
     RetainPtr<CMSampleBufferRef> m_buffer;
     RetainPtr<AVCaptureVideoDataOutput> m_videoOutput;
 
+    IntSize m_presetSize;
     int32_t m_width { 0 };
     int32_t m_height { 0 };
     int m_sensorOrientation { 0 };
     int m_deviceOrientation { 0 };
     MediaSample::VideoRotation m_sampleRotation { MediaSample::VideoRotation::None };
+
+    VideoPresetMap m_supportedPresets;
 };
 
 } // namespace WebCore
index ab04f03..facc38f 100644 (file)
@@ -94,6 +94,14 @@ SOFT_LINK_CONSTANT_MAY_FAIL(AVFoundation, AVCaptureSessionPreset320x240, NSStrin
 #define AVCaptureSessionPreset352x288 getAVCaptureSessionPreset352x288()
 #define AVCaptureSessionPreset320x240 getAVCaptureSessionPreset320x240()
 
+#if PLATFORM(IOS)
+SOFT_LINK_CONSTANT_MAY_FAIL(AVFoundation, AVCaptureSessionPreset3840x2160, NSString *)
+SOFT_LINK_CONSTANT_MAY_FAIL(AVFoundation, AVCaptureSessionPreset1920x1080, NSString *)
+
+#define AVCaptureSessionPreset3840x2160 getAVCaptureSessionPreset3840x2160()
+#define AVCaptureSessionPreset1920x1080 getAVCaptureSessionPreset1920x1080()
+#endif
+
 using namespace WebCore;
 
 namespace WebCore {
@@ -123,6 +131,32 @@ CaptureSourceOrError AVVideoCaptureSource::create(const AtomicString& id, const
 AVVideoCaptureSource::AVVideoCaptureSource(AVCaptureDeviceTypedef* device, const AtomicString& id)
     : AVMediaCaptureSource(device, id, Type::Video)
 {
+    struct VideoPreset {
+        bool symbolAvailable;
+        NSString* name;
+        int width;
+        int height;
+    };
+
+    static const VideoPreset presets[] = {
+#if PLATFORM(IOS)
+        { canLoadAVCaptureSessionPreset3840x2160(), AVCaptureSessionPreset3840x2160, 3840, 2160  },
+        { canLoadAVCaptureSessionPreset1920x1080(), AVCaptureSessionPreset1920x1080, 1920, 1080 },
+#endif
+        { canLoadAVCaptureSessionPreset1280x720(), AVCaptureSessionPreset1280x720, 1280, 720 },
+        { canLoadAVCaptureSessionPreset960x540(), AVCaptureSessionPreset960x540, 960, 540 },
+        { canLoadAVCaptureSessionPreset640x480(), AVCaptureSessionPreset640x480, 640, 480 },
+        { canLoadAVCaptureSessionPreset352x288(), AVCaptureSessionPreset352x288, 352, 288 },
+        { canLoadAVCaptureSessionPreset320x240(), AVCaptureSessionPreset320x240, 320, 240 },
+    };
+
+    auto* presetsMap = &videoPresets();
+    for (auto& preset : presets) {
+        if (!preset.symbolAvailable || !preset.name || ![device supportsAVCaptureSessionPreset:preset.name])
+            continue;
+
+        presetsMap->add(String(preset.name), IntSize(preset.width, preset.height));
+    }
 }
 
 AVVideoCaptureSource::~AVVideoCaptureSource()
@@ -168,32 +202,13 @@ void AVVideoCaptureSource::initializeCapabilities(RealtimeMediaSourceCapabilitie
             lowestFrameRateRange = std::min<Float64>(lowestFrameRateRange, range.minFrameRate);
             highestFrameRateRange = std::max<Float64>(highestFrameRateRange, range.maxFrameRate);
         }
+    }
 
-        if (canLoadAVCaptureSessionPreset1280x720() && [videoDevice supportsAVCaptureSessionPreset:AVCaptureSessionPreset1280x720]) {
-            updateSizeMinMax(minimumWidth, maximumWidth, 1280);
-            updateSizeMinMax(minimumHeight, maximumHeight, 720);
-            updateAspectRatioMinMax(minimumAspectRatio, maximumAspectRatio, 1280.0 / 720);
-        }
-        if (canLoadAVCaptureSessionPreset960x540() && [videoDevice supportsAVCaptureSessionPreset:AVCaptureSessionPreset960x540]) {
-            updateSizeMinMax(minimumWidth, maximumWidth, 960);
-            updateSizeMinMax(minimumHeight, maximumHeight, 540);
-            updateAspectRatioMinMax(minimumAspectRatio, maximumAspectRatio, 960 / 540);
-        }
-        if (canLoadAVCaptureSessionPreset640x480() && [videoDevice supportsAVCaptureSessionPreset:AVCaptureSessionPreset640x480]) {
-            updateSizeMinMax(minimumWidth, maximumWidth, 640);
-            updateSizeMinMax(minimumHeight, maximumHeight, 480);
-            updateAspectRatioMinMax(minimumAspectRatio, maximumAspectRatio, 640 / 480);
-        }
-        if (canLoadAVCaptureSessionPreset352x288() && [videoDevice supportsAVCaptureSessionPreset:AVCaptureSessionPreset352x288]) {
-            updateSizeMinMax(minimumWidth, maximumWidth, 352);
-            updateSizeMinMax(minimumHeight, maximumHeight, 288);
-            updateAspectRatioMinMax(minimumAspectRatio, maximumAspectRatio, 352 / 288);
-        }
-        if (canLoadAVCaptureSessionPreset320x240() && [videoDevice supportsAVCaptureSessionPreset:AVCaptureSessionPreset320x240]) {
-            updateSizeMinMax(minimumWidth, maximumWidth, 320);
-            updateSizeMinMax(minimumHeight, maximumHeight, 240);
-            updateAspectRatioMinMax(minimumAspectRatio, maximumAspectRatio, 320 / 240);
-        }
+    for (auto& preset : videoPresets()) {
+        auto values = preset.value;
+        updateSizeMinMax(minimumWidth, maximumWidth, values.width());
+        updateSizeMinMax(minimumHeight, maximumHeight, values.height());
+        updateAspectRatioMinMax(minimumAspectRatio, maximumAspectRatio, static_cast<double>(values.width()) / values.height());
     }
 
     capabilities.setFrameRate(CapabilityValueOrRange(lowestFrameRateRange, highestFrameRateRange));
@@ -241,28 +256,17 @@ bool AVVideoCaptureSource::applySize(const IntSize& size)
     return setPreset(preset);
 }
 
-static IntSize sizeForPreset(NSString* preset)
+IntSize AVVideoCaptureSource::sizeForPreset(NSString* preset)
 {
     if (!preset)
         return { };
 
-    if (canLoadAVCaptureSessionPreset1280x720() && [preset isEqualToString:AVCaptureSessionPreset1280x720])
-        return { 1280, 720 };
-
-    if (canLoadAVCaptureSessionPreset960x540() && [preset isEqualToString:AVCaptureSessionPreset960x540])
-        return { 960, 540 };
-
-    if (canLoadAVCaptureSessionPreset640x480() && [preset isEqualToString:AVCaptureSessionPreset640x480])
-        return { 640, 480 };
-
-    if (canLoadAVCaptureSessionPreset352x288() && [preset isEqualToString:AVCaptureSessionPreset352x288])
-        return { 352, 288 };
+    auto& presets = videoPresets();
+    auto it = presets.find(String(preset));
+    if (it != presets.end())
+        return { it->value.width(), it->value.height() };
 
-    if (canLoadAVCaptureSessionPreset320x240() && [preset isEqualToString:AVCaptureSessionPreset320x240])
-        return { 320, 240 };
-    
     return { };
-    
 }
 
 bool AVVideoCaptureSource::setPreset(NSString *preset)
@@ -273,9 +277,11 @@ bool AVVideoCaptureSource::setPreset(NSString *preset)
     }
 
     auto size = sizeForPreset(preset);
-    if (size.width() == m_width && size.height() == m_height)
+    if (m_presetSize == size)
         return true;
 
+    m_presetSize = size;
+
     @try {
         session().sessionPreset = preset;
 #if PLATFORM(MAC)
@@ -506,26 +512,21 @@ void AVVideoCaptureSource::captureOutputDidOutputSampleBufferFromConnection(AVCa
     });
 }
 
-NSString* AVVideoCaptureSource::bestSessionPresetForVideoDimensions(std::optional<int> width, std::optional<int> height) const
+NSString* AVVideoCaptureSource::bestSessionPresetForVideoDimensions(std::optional<int> width, std::optional<int> height)
 {
     if (!width && !height)
         return nil;
 
-    AVCaptureDeviceTypedef *videoDevice = device();
-    if ((!width || width.value() == 1280) && (!height || height.value() == 720) && canLoadAVCaptureSessionPreset1280x720())
-        return [videoDevice supportsAVCaptureSessionPreset:AVCaptureSessionPreset1280x720] ? AVCaptureSessionPreset1280x720 : nil;
-
-    if ((!width || width.value() == 960) && (!height || height.value() == 540) && canLoadAVCaptureSessionPreset960x540())
-        return [videoDevice supportsAVCaptureSessionPreset:AVCaptureSessionPreset960x540] ? AVCaptureSessionPreset960x540 : nil;
+    int widthValue = width ? width.value() : 0;
+    int heightValue = height ? height.value() : 0;
 
-    if ((!width || width.value() == 640) && (!height || height.value() == 480 ) && canLoadAVCaptureSessionPreset640x480())
-        return [videoDevice supportsAVCaptureSessionPreset:AVCaptureSessionPreset640x480] ? AVCaptureSessionPreset640x480 : nil;
+    for (auto& preset : videoPresets()) {
+        auto size = preset.value;
+        NSString* name = preset.key;
 
-    if ((!width || width.value() == 352) && (!height || height.value() == 288 ) && canLoadAVCaptureSessionPreset352x288())
-        return [videoDevice supportsAVCaptureSessionPreset:AVCaptureSessionPreset352x288] ? AVCaptureSessionPreset352x288 : nil;
-
-    if ((!width || width.value() == 320) && (!height || height.value() == 240 ) && canLoadAVCaptureSessionPreset320x240())
-        return [videoDevice supportsAVCaptureSessionPreset:AVCaptureSessionPreset320x240] ? AVCaptureSessionPreset320x240 : nil;
+        if ((!widthValue || widthValue == size.width()) && (!heightValue || heightValue == size.height()))
+            return name;
+    }
 
     return nil;
 }