summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/plugins/avfoundation/camera/avfcamerautility.h3
-rw-r--r--src/plugins/avfoundation/camera/avfcamerautility.mm50
-rw-r--r--src/plugins/avfoundation/camera/avfcameraviewfindersettingscontrol.mm10
-rw-r--r--src/plugins/avfoundation/camera/avfimageencodercontrol.mm10
-rw-r--r--src/plugins/avfoundation/camera/avfvideoencodersettingscontrol.mm44
5 files changed, 74 insertions, 43 deletions
diff --git a/src/plugins/avfoundation/camera/avfcamerautility.h b/src/plugins/avfoundation/camera/avfcamerautility.h
index 7a0de4a66..79e9359ec 100644
--- a/src/plugins/avfoundation/camera/avfcamerautility.h
+++ b/src/plugins/avfoundation/camera/avfcamerautility.h
@@ -176,6 +176,9 @@ AVCaptureDeviceFormat *qt_find_best_framerate_match(AVCaptureDevice *captureDevi
Float64 fps);
AVFrameRateRange *qt_find_supported_framerate_range(AVCaptureDeviceFormat *format, Float64 fps);
+bool qt_formats_are_equal(AVCaptureDeviceFormat *f1, AVCaptureDeviceFormat *f2);
+bool qt_set_active_format(AVCaptureDevice *captureDevice, AVCaptureDeviceFormat *format, bool preserveFps);
+
#endif
AVFPSRange qt_current_framerates(AVCaptureDevice *captureDevice, AVCaptureConnection *videoConnection);
diff --git a/src/plugins/avfoundation/camera/avfcamerautility.mm b/src/plugins/avfoundation/camera/avfcamerautility.mm
index 712868d22..4bec1dbe9 100644
--- a/src/plugins/avfoundation/camera/avfcamerautility.mm
+++ b/src/plugins/avfoundation/camera/avfcamerautility.mm
@@ -380,6 +380,56 @@ AVFrameRateRange *qt_find_supported_framerate_range(AVCaptureDeviceFormat *forma
return match;
}
+bool qt_formats_are_equal(AVCaptureDeviceFormat *f1, AVCaptureDeviceFormat *f2)
+{
+ if (f1 == f2)
+ return true;
+
+ if (![f1.mediaType isEqualToString:f2.mediaType])
+ return false;
+
+ return CMFormatDescriptionEqual(f1.formatDescription, f2.formatDescription);
+}
+
+bool qt_set_active_format(AVCaptureDevice *captureDevice, AVCaptureDeviceFormat *format, bool preserveFps)
+{
+ static bool firstSet = true;
+
+ if (!captureDevice || !format)
+ return false;
+
+ if (qt_formats_are_equal(captureDevice.activeFormat, format)) {
+ if (firstSet) {
+ // The capture device format is persistent. The first time we set a format, report that
+ // it changed even if the formats are the same.
+ // This prevents the session from resetting the format to the default value.
+ firstSet = false;
+ return true;
+ }
+ return false;
+ }
+
+ firstSet = false;
+
+ const AVFConfigurationLock lock(captureDevice);
+ if (!lock) {
+ qWarning("Failed to set active format (lock failed)");
+ return false;
+ }
+
+ // Changing the activeFormat resets the frame rate.
+ AVFPSRange fps;
+ if (preserveFps)
+ fps = qt_current_framerates(captureDevice, nil);
+
+ captureDevice.activeFormat = format;
+
+ if (preserveFps)
+ qt_set_framerate_limits(captureDevice, nil, fps.first, fps.second);
+
+ return true;
+}
+
#endif // SDK
void qt_set_framerate_limits(AVCaptureConnection *videoConnection, qreal minFPS, qreal maxFPS)
diff --git a/src/plugins/avfoundation/camera/avfcameraviewfindersettingscontrol.mm b/src/plugins/avfoundation/camera/avfcameraviewfindersettingscontrol.mm
index 1d2539893..14f146d25 100644
--- a/src/plugins/avfoundation/camera/avfcameraviewfindersettingscontrol.mm
+++ b/src/plugins/avfoundation/camera/avfcameraviewfindersettingscontrol.mm
@@ -382,15 +382,7 @@ bool AVFCameraViewfinderSettingsControl2::applySettings(const QCameraViewfinderS
#if QT_MAC_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_10_7, __IPHONE_7_0)
AVCaptureDeviceFormat *match = findBestFormatMatch(settings);
if (match) {
- if (match != captureDevice.activeFormat) {
- const AVFConfigurationLock lock(captureDevice);
- if (lock) {
- captureDevice.activeFormat = match;
- activeFormatChanged = true;
- } else {
- qDebugCamera() << Q_FUNC_INFO << "failed to lock for configuration";
- }
- }
+ activeFormatChanged = qt_set_active_format(captureDevice, match, false);
} else {
qDebugCamera() << Q_FUNC_INFO << "matching device format not found";
// We still can update the pixel format at least.
diff --git a/src/plugins/avfoundation/camera/avfimageencodercontrol.mm b/src/plugins/avfoundation/camera/avfimageencodercontrol.mm
index b35008030..20de4b5e8 100644
--- a/src/plugins/avfoundation/camera/avfimageencodercontrol.mm
+++ b/src/plugins/avfoundation/camera/avfimageencodercontrol.mm
@@ -227,15 +227,7 @@ bool AVFImageEncoderControl::applySettings()
return false;
}
- if (match != captureDevice.activeFormat) {
- const AVFConfigurationLock lock(captureDevice);
- if (!lock) {
- qDebugCamera() << Q_FUNC_INFO << "failed to lock for configuration";
- return false;
- }
- captureDevice.activeFormat = match;
- activeFormatChanged = true;
- }
+ activeFormatChanged = qt_set_active_format(captureDevice, match, true);
#if defined(Q_OS_IOS) && QT_IOS_PLATFORM_SDK_EQUAL_OR_ABOVE(__IPHONE_8_0)
if (QSysInfo::MacintoshVersion >= QSysInfo::MV_IOS_8_0) {
diff --git a/src/plugins/avfoundation/camera/avfvideoencodersettingscontrol.mm b/src/plugins/avfoundation/camera/avfvideoencodersettingscontrol.mm
index 87bc91129..248997d57 100644
--- a/src/plugins/avfoundation/camera/avfvideoencodersettingscontrol.mm
+++ b/src/plugins/avfoundation/camera/avfvideoencodersettingscontrol.mm
@@ -215,6 +215,10 @@ NSDictionary *AVFVideoEncoderSettingsControl::applySettings(AVCaptureConnection
if (!device)
return nil;
+ AVFPSRange currentFps = qt_current_framerates(device, connection);
+ const bool needFpsChange = m_requestedSettings.frameRate() > 0
+ && m_requestedSettings.frameRate() != currentFps.second;
+
NSMutableDictionary *videoSettings = [NSMutableDictionary dictionary];
// -- Codec
@@ -234,8 +238,8 @@ NSDictionary *AVFVideoEncoderSettingsControl::applySettings(AVCaptureConnection
int h = m_requestedSettings.resolution().height();
#if QT_MAC_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_10_7, __IPHONE_7_0)
- if (device.activeFormat) {
- CMFormatDescriptionRef formatDesc = device.activeFormat.formatDescription;
+ if (AVCaptureDeviceFormat *currentFormat = device.activeFormat) {
+ CMFormatDescriptionRef formatDesc = currentFormat.formatDescription;
CMVideoDimensions dim = CMVideoFormatDescriptionGetDimensions(formatDesc);
// We have to change the device's activeFormat in 3 cases:
@@ -245,7 +249,7 @@ NSDictionary *AVFVideoEncoderSettingsControl::applySettings(AVCaptureConnection
AVCaptureDeviceFormat *newFormat = nil;
if ((w <= 0 || h <= 0)
&& m_requestedSettings.frameRate() > 0
- && !format_supports_framerate(device.activeFormat, m_requestedSettings.frameRate())) {
+ && !format_supports_framerate(currentFormat, m_requestedSettings.frameRate())) {
newFormat = qt_find_best_framerate_match(device,
m_service->session()->defaultCodec(),
@@ -267,17 +271,10 @@ NSDictionary *AVFVideoEncoderSettingsControl::applySettings(AVCaptureConnection
}
}
- if (newFormat && newFormat != device.activeFormat) {
- const AVFConfigurationLock lock(device);
- if (lock) {
- m_restoreFormat = [device.activeFormat retain];
- m_restoreFps = qt_current_framerates(device, connection);
-
- device.activeFormat = newFormat;
-
- formatDesc = newFormat.formatDescription;
- dim = CMVideoFormatDescriptionGetDimensions(formatDesc);
- }
+ if (qt_set_active_format(device, newFormat, !needFpsChange)) {
+ m_restoreFormat = [currentFormat retain];
+ formatDesc = newFormat.formatDescription;
+ dim = CMVideoFormatDescriptionGetDimensions(formatDesc);
}
if (w > 0 && h > 0) {
@@ -313,14 +310,12 @@ NSDictionary *AVFVideoEncoderSettingsControl::applySettings(AVCaptureConnection
// -- FPS
- const qreal fps = m_requestedSettings.frameRate();
- if (fps > qreal(0)) {
- if (!m_restoreFps.first && !m_restoreFps.second)
- m_restoreFps = qt_current_framerates(device, connection);
+ if (needFpsChange) {
+ m_restoreFps = currentFps;
+ const qreal fps = m_requestedSettings.frameRate();
qt_set_framerate_limits(device, connection, fps, fps);
}
- AVFPSRange currentFps = qt_current_framerates(device, connection);
- m_actualSettings.setFrameRate(currentFps.second);
+ m_actualSettings.setFrameRate(qt_current_framerates(device, connection).second);
// -- Codec Settings
@@ -379,18 +374,17 @@ void AVFVideoEncoderSettingsControl::unapplySettings(AVCaptureConnection *connec
if (!device)
return;
+ const bool needFpsChanged = m_restoreFps.first || m_restoreFps.second;
+
#if QT_MAC_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_10_7, __IPHONE_7_0)
if (m_restoreFormat) {
- const AVFConfigurationLock lock(device);
- if (lock)
- device.activeFormat = m_restoreFormat;
-
+ qt_set_active_format(device, m_restoreFormat, !needFpsChanged);
[m_restoreFormat release];
m_restoreFormat = nil;
}
#endif
- if (m_restoreFps.first || m_restoreFps.second) {
+ if (needFpsChanged) {
qt_set_framerate_limits(device, connection, m_restoreFps.first, m_restoreFps.second);
m_restoreFps = AVFPSRange();
}