Skip to content

Commit

Permalink
Apply patch. rdar://problem/106142457
Browse files Browse the repository at this point in the history
    REGRESSION iOS 16.4 beta selects ultra-wide for facingMode: environment
    https://bugs.webkit.org/show_bug.cgi?id=253186
    rdar://problem/106142457

    Reviewed by Jer Noble.

    For ultra wide back cameras, add a zoomn factor of 2 so that a zoom of 1 corresponds to a standard FOV.
    We compute this factor once and we then divide by this factor for capabilities and multiply by this factor for settings.
    Manually tested on device.

    * Source/WebCore/platform/mediastream/mac/AVVideoCaptureSource.h:
    * Source/WebCore/platform/mediastream/mac/AVVideoCaptureSource.mm:
    (WebCore::AVVideoCaptureSource::computeMinZoom const):
    (WebCore::AVVideoCaptureSource::computeMaxZoom const):
    (WebCore::cameraZoomScaleFactor):
    (WebCore::AVVideoCaptureSource::AVVideoCaptureSource):
    (WebCore::AVVideoCaptureSource::setFrameRateAndZoomWithPreset):
    (WebCore::AVVideoCaptureSource::generatePresets):
    (WebCore::computeMaxZoom): Deleted.

    Canonical link: https://commits.webkit.org/261877@main

Identifier: 259548.393@safari-7615.1.26.11-branch
  • Loading branch information
youennf authored and MyahCobbs committed Mar 31, 2023
1 parent 1a04bf9 commit 7a49b97
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,9 @@ class AVVideoCaptureSource : public RealtimeVideoCaptureSource, private Orientat
void updateVerifyCapturingTimer();
void verifyIsCapturing();

std::optional<double> computeMinZoom() const;
std::optional<double> computeMaxZoom(AVCaptureDeviceFormat*) const;

RefPtr<VideoFrame> m_buffer;
RetainPtr<AVCaptureVideoDataOutput> m_videoOutput;
std::unique_ptr<ImageTransferSessionVT> m_imageTransferSession;
Expand All @@ -138,6 +141,8 @@ class AVVideoCaptureSource : public RealtimeVideoCaptureSource, private Orientat
RetainPtr<AVFrameRateRange> m_appliedFrameRateRange;

double m_currentFrameRate;
double m_currentZoom { 1 };
double m_zoomScaleFactor { 1 };
bool m_interrupted { false };
bool m_isRunning { false };

Expand Down
44 changes: 40 additions & 4 deletions Source/WebCore/platform/mediastream/mac/AVVideoCaptureSource.mm
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,6 @@ static dispatch_queue_t globaVideoCaptureSerialQueue()
});
return globalQueue;
}

class AVVideoPreset : public VideoPreset {
public:
static Ref<AVVideoPreset> create(IntSize size, Vector<FrameRateRange>&& frameRateRanges, AVCaptureDeviceFormat* format)
Expand All @@ -101,14 +100,36 @@ static dispatch_queue_t globaVideoCaptureSerialQueue()
}

AVVideoPreset(IntSize size, Vector<FrameRateRange>&& frameRateRanges, AVCaptureDeviceFormat* format)
: VideoPreset(size, WTFMove(frameRateRanges), AVCapture)
, format(format)
: VideoPreset(size, WTFMove(frameRateRanges), AVCapture)
, format(format)
{
}

RetainPtr<AVCaptureDeviceFormat> format;
};

std::optional<double> AVVideoCaptureSource::computeMinZoom() const
{
#if PLATFORM(IOS_FAMILY)
if (m_zoomScaleFactor == 1.0)
return { };
return 1.0 / m_zoomScaleFactor;
#else
return { };
#endif
}

std::optional<double> AVVideoCaptureSource::computeMaxZoom(AVCaptureDeviceFormat* format) const
{
#if PLATFORM(IOS_FAMILY)
// We restrict zoom for now as it might require elevated permissions.
return std::min([format videoMaxZoomFactor], 4.0) / m_zoomScaleFactor;
#else
UNUSED_PARAM(format);
return { };
#endif
}

CaptureSourceOrError AVVideoCaptureSource::create(const CaptureDevice& device, MediaDeviceHashSalts&& hashSalts, const MediaConstraints* constraints, PageIdentifier pageIdentifier)
{
auto *avDevice = [PAL::getAVCaptureDeviceClass() deviceWithUniqueID:device.persistentId()];
Expand All @@ -125,10 +146,22 @@ static dispatch_queue_t globaVideoCaptureSerialQueue()
return CaptureSourceOrError(RealtimeVideoSource::create(WTFMove(source)));
}

static double cameraZoomScaleFactor(AVCaptureDeviceType deviceType)
{
#if PLATFORM(IOS_FAMILY)
return (PAL::canLoad_AVFoundation_AVCaptureDeviceTypeBuiltInTripleCamera() && deviceType == AVCaptureDeviceTypeBuiltInTripleCamera)
|| (PAL::canLoad_AVFoundation_AVCaptureDeviceTypeBuiltInDualWideCamera() && deviceType == AVCaptureDeviceTypeBuiltInDualWideCamera) ? 2.0 : 1.0;
#else
UNUSED_PARAM(deviceType);
return 1.0;
#endif
}

AVVideoCaptureSource::AVVideoCaptureSource(AVCaptureDevice* avDevice, const CaptureDevice& device, MediaDeviceHashSalts&& hashSalts, PageIdentifier pageIdentifier)
: RealtimeVideoCaptureSource(device, WTFMove(hashSalts), pageIdentifier)
, m_objcObserver(adoptNS([[WebCoreAVVideoCaptureSourceObserver alloc] initWithCallback:this]))
, m_device(avDevice)
, m_zoomScaleFactor(cameraZoomScaleFactor([avDevice deviceType]))
, m_verifyCapturingTimer(*this, &AVVideoCaptureSource::verifyIsCapturing)
{
[m_device addObserver:m_objcObserver.get() forKeyPath:@"suspended" options:NSKeyValueObservingOptionNew context:(void *)nil];
Expand Down Expand Up @@ -343,6 +376,7 @@ static dispatch_queue_t globaVideoCaptureSerialQueue()
auto* avPreset = preset ? downcast<AVVideoPreset>(preset.get()) : nullptr;
m_currentPreset = avPreset;
m_currentFrameRate = requestedFrameRate;
m_currentZoom = m_zoomScaleFactor * requestedZoom;

setSessionSizeAndFrameRate();
}
Expand Down Expand Up @@ -664,7 +698,9 @@ static inline int sensorOrientationFromVideoOutput(AVCaptureVideoDataOutput* vid
for (AVFrameRateRange* range in [format videoSupportedFrameRateRanges])
frameRates.append({ range.minFrameRate, range.maxFrameRate});

presets.append(AVVideoPreset::create(size, WTFMove(frameRates), format));
VideoPreset preset { size, WTFMove(frameRates), computeMinZoom(), computeMaxZoom(format) };
preset.setFormat(format);
presets.append(WTFMove(preset));
}

setSupportedPresets(WTFMove(presets));
Expand Down

0 comments on commit 7a49b97

Please sign in to comment.