summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArtem Dyomin <artem.dyomin@qt.io>2023-08-14 17:18:49 +0200
committerQt Cherry-pick Bot <cherrypick_bot@qt-project.org>2023-08-22 09:16:16 +0000
commit278c3cf992f2bd1614a8d3d3c1264f836474a766 (patch)
tree2d83cd42c015d52ae8ca1d85385607a3327875eb
parentd1841e202ce39413a96e4cb0fc5bb8b8066a6f36 (diff)
Fix recognizing ambiguous formats by macOS camera implementation
The problem is that we have ambiguous conversions videotoolbox pixel formats to QVideoFrameFormat::PixelFormat, e.g. we interpret both kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange and kCVPixelFormatType_420YpCbCr8BiPlanarFullRange as QVideoFrameFormat::Format_NV12. Let's store color range in QCameraFormatPrivate to avoid the ambiguous conversion. Task-number: QTBUG-115575 Change-Id: I86dc3b85ca111855435acf63fba55ea0f87200bd Reviewed-by: Jøger Hansegård <joger.hansegard@qt.io> Reviewed-by: Artem Dyomin <artem.dyomin@qt.io> (cherry picked from commit 35f59535360e9822150f6daf4d0c95e2efe17176) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
-rw-r--r--src/multimedia/camera/qcameradevice_p.h14
-rw-r--r--src/multimedia/platform/qplatformcamera.cpp7
-rw-r--r--src/multimedia/platform/qplatformcamera_p.h6
-rw-r--r--src/plugins/multimedia/darwin/camera/avfcamerarenderer.mm29
-rw-r--r--src/plugins/multimedia/darwin/camera/avfcamerarenderer_p.h3
-rw-r--r--src/plugins/multimedia/darwin/camera/avfcamerautility.mm25
-rw-r--r--src/plugins/multimedia/darwin/camera/qavfcamerabase.mm17
-rw-r--r--src/plugins/multimedia/darwin/qavfhelpers.mm134
-rw-r--r--src/plugins/multimedia/darwin/qavfhelpers_p.h16
-rw-r--r--src/plugins/multimedia/ffmpeg/qavfcamera.mm9
-rw-r--r--src/plugins/multimedia/ffmpeg/qavfcamera_p.h3
11 files changed, 134 insertions, 129 deletions
diff --git a/src/multimedia/camera/qcameradevice_p.h b/src/multimedia/camera/qcameradevice_p.h
index d2ea8d6b1..638cc0cae 100644
--- a/src/multimedia/camera/qcameradevice_p.h
+++ b/src/multimedia/camera/qcameradevice_p.h
@@ -24,10 +24,22 @@ QT_BEGIN_NAMESPACE
class QCameraFormatPrivate : public QSharedData
{
public:
- QVideoFrameFormat::PixelFormat pixelFormat;
+ QVideoFrameFormat::PixelFormat pixelFormat = QVideoFrameFormat::Format_Invalid;
QSize resolution;
float minFrameRate = 0;
float maxFrameRate = 0;
+ QVideoFrameFormat::ColorRange colorRange = QVideoFrameFormat::ColorRange_Unknown;
+
+ static QVideoFrameFormat::ColorRange getColorRange(const QCameraFormat &format)
+ {
+ auto d = handle(format);
+ return d ? d->colorRange : QVideoFrameFormat::ColorRange_Unknown;
+ }
+
+ static const QCameraFormatPrivate *handle(const QCameraFormat &format)
+ {
+ return format.d.get();
+ }
QCameraFormat create() { return QCameraFormat(this); }
};
diff --git a/src/multimedia/platform/qplatformcamera.cpp b/src/multimedia/platform/qplatformcamera.cpp
index 77f1a327a..0d3975550 100644
--- a/src/multimedia/platform/qplatformcamera.cpp
+++ b/src/multimedia/platform/qplatformcamera.cpp
@@ -2,6 +2,7 @@
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qplatformcamera_p.h"
+#include "private/qcameradevice_p.h"
QT_BEGIN_NAMESPACE
@@ -22,13 +23,15 @@ QCameraFormat QPlatformCamera::findBestCameraFormat(const QCameraDevice &camera)
const auto isValid = fmt.pixelFormat() != QVideoFrameFormat::Format_Invalid;
const auto resolution = fmt.resolution();
const auto sufficientFrameRate = std::min(fmt.maxFrameRate(), MinSufficientFrameRate);
+ const auto pixelFormatScore =
+ cameraPixelFormatScore(fmt.pixelFormat(), QCameraFormatPrivate::getColorRange(fmt));
return std::make_tuple(
isValid, // 1st: ensure valid formats
sufficientFrameRate, // 2nd: ensure the highest frame rate in the range [0; 29]*/
resolution.width() * resolution.height(), // 3rd: ensure the highest resolution
- cameraPixelFormatScore(fmt.pixelFormat()),
- fmt.maxFrameRate()); // 4th: ensure the highest framerate in the whole range
+ pixelFormatScore, // 4th: eshure the best pixel format
+ fmt.maxFrameRate()); // 5th: ensure the highest framerate in the whole range
};
const auto formats = camera.videoFormats();
diff --git a/src/multimedia/platform/qplatformcamera_p.h b/src/multimedia/platform/qplatformcamera_p.h
index 794e4372e..85624c0ce 100644
--- a/src/multimedia/platform/qplatformcamera_p.h
+++ b/src/multimedia/platform/qplatformcamera_p.h
@@ -116,7 +116,11 @@ Q_SIGNALS:
protected:
explicit QPlatformCamera(QCamera *parent);
- virtual int cameraPixelFormatScore(QVideoFrameFormat::PixelFormat /*format*/) const { return 0; }
+ virtual int cameraPixelFormatScore(QVideoFrameFormat::PixelFormat /*format*/,
+ QVideoFrameFormat::ColorRange /*colorRange*/) const
+ {
+ return 0;
+ }
QCameraFormat findBestCameraFormat(const QCameraDevice &camera) const;
QCameraFormat m_cameraFormat;
diff --git a/src/plugins/multimedia/darwin/camera/avfcamerarenderer.mm b/src/plugins/multimedia/darwin/camera/avfcamerarenderer.mm
index 5ea320d81..1b461da7a 100644
--- a/src/plugins/multimedia/darwin/camera/avfcamerarenderer.mm
+++ b/src/plugins/multimedia/darwin/camera/avfcamerarenderer.mm
@@ -2,6 +2,7 @@
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "private/qabstractvideobuffer_p.h"
+#include "private/qcameradevice_p.h"
#include "avfcamerarenderer_p.h"
#include "avfcamerasession_p.h"
#include "avfcameraservice_p.h"
@@ -113,10 +114,11 @@ void AVFCameraRenderer::setOutputSettings()
if (!m_videoDataOutput)
return;
- const auto cameraPixelFormat = m_cameraSession ? m_cameraSession->cameraFormat().pixelFormat()
- : QVideoFrameFormat::Format_Invalid;
- if (cameraPixelFormat != QVideoFrameFormat::Format_Invalid)
- setPixelFormat(cameraPixelFormat);
+ if (m_cameraSession) {
+ const auto format = m_cameraSession->cameraFormat();
+ if (format.pixelFormat() != QVideoFrameFormat::Format_Invalid)
+ setPixelFormat(format.pixelFormat(), QCameraFormatPrivate::getColorRange(format));
+ }
// If no output settings set from above,
// it's most likely because the rhi is OpenGL
@@ -247,7 +249,8 @@ void AVFCameraRenderer::handleViewfinderFrame()
}
}
-void AVFCameraRenderer::setPixelFormat(const QVideoFrameFormat::PixelFormat pixelFormat)
+void AVFCameraRenderer::setPixelFormat(QVideoFrameFormat::PixelFormat pixelFormat,
+ QVideoFrameFormat::ColorRange colorRange)
{
if (rhi() && rhi()->backend() == QRhi::OpenGLES2) {
if (pixelFormat != QVideoFrameFormat::Format_BGRA8888)
@@ -258,25 +261,29 @@ void AVFCameraRenderer::setPixelFormat(const QVideoFrameFormat::PixelFormat pixe
// Default to 32BGRA pixel formats on the viewfinder, in case the requested
// format can't be used (shouldn't happen unless the developers sets a wrong camera
// format on the camera).
- unsigned avPixelFormat = kCVPixelFormatType_32BGRA;
- if (!QAVFHelpers::toCVPixelFormat(pixelFormat, avPixelFormat))
+ auto cvPixelFormat = QAVFHelpers::toCVPixelFormat(pixelFormat, colorRange);
+ if (cvPixelFormat == CvPixelFormatInvalid) {
+ cvPixelFormat = kCVPixelFormatType_32BGRA;
qWarning() << "QCamera::setCameraFormat: couldn't convert requested pixel format, using ARGB32";
+ }
bool isSupported = false;
NSArray *supportedPixelFormats = m_videoDataOutput.availableVideoCVPixelFormatTypes;
for (NSNumber *currentPixelFormat in supportedPixelFormats)
{
- if ([currentPixelFormat unsignedIntValue] == avPixelFormat) {
+ if ([currentPixelFormat unsignedIntValue] == cvPixelFormat) {
isSupported = true;
break;
}
}
if (isSupported) {
- NSDictionary* outputSettings = @{
- (NSString *)kCVPixelBufferPixelFormatTypeKey: [NSNumber numberWithUnsignedInt:avPixelFormat]
+ NSDictionary *outputSettings = @{
+ (NSString *)
+ kCVPixelBufferPixelFormatTypeKey : [NSNumber numberWithUnsignedInt:cvPixelFormat]
#ifndef Q_OS_IOS // On iOS this key generates a warning about 'unsupported key'.
- , (NSString *)kCVPixelBufferMetalCompatibilityKey: @true
+ ,
+ (NSString *)kCVPixelBufferMetalCompatibilityKey : @true
#endif // Q_OS_IOS
};
if (m_outputSettings)
diff --git a/src/plugins/multimedia/darwin/camera/avfcamerarenderer_p.h b/src/plugins/multimedia/darwin/camera/avfcamerarenderer_p.h
index 6e42f52ec..57f665cd6 100644
--- a/src/plugins/multimedia/darwin/camera/avfcamerarenderer_p.h
+++ b/src/plugins/multimedia/darwin/camera/avfcamerarenderer_p.h
@@ -59,7 +59,8 @@ public:
AVFCaptureFramesDelegate *captureDelegate() const;
void resetCaptureDelegate() const;
- void setPixelFormat(const QVideoFrameFormat::PixelFormat format);
+ void setPixelFormat(QVideoFrameFormat::PixelFormat pixelFormat,
+ QVideoFrameFormat::ColorRange colorRange);
Q_SIGNALS:
void newViewfinderFrame(const QVideoFrame &frame);
diff --git a/src/plugins/multimedia/darwin/camera/avfcamerautility.mm b/src/plugins/multimedia/darwin/camera/avfcamerautility.mm
index fb73ba3f6..704fbdc11 100644
--- a/src/plugins/multimedia/darwin/camera/avfcamerautility.mm
+++ b/src/plugins/multimedia/darwin/camera/avfcamerautility.mm
@@ -7,6 +7,7 @@
#include <QtCore/qvector.h>
#include <QtCore/qpair.h>
#include <private/qmultimediautils_p.h>
+#include <private/qcameradevice_p.h>
#include "avfvideobuffer_p.h"
#include "qavfhelpers_p.h"
@@ -100,19 +101,29 @@ qt_convert_to_capture_device_format(AVCaptureDevice *captureDevice,
const QCameraFormat &cameraFormat,
const std::function<bool(uint32_t)> &cvFormatValidator)
{
+ const auto cameraFormatPrivate = QCameraFormatPrivate::handle(cameraFormat);
+ if (!cameraFormatPrivate)
+ return nil;
+
+ const auto requiredCvPixFormat = QAVFHelpers::toCVPixelFormat(cameraFormatPrivate->pixelFormat,
+ cameraFormatPrivate->colorRange);
+
+ if (requiredCvPixFormat == CvPixelFormatInvalid)
+ return nil;
+
AVCaptureDeviceFormat *newFormat = nil;
NSArray<AVCaptureDeviceFormat *> *formats = captureDevice.formats;
for (AVCaptureDeviceFormat *format in formats) {
CMFormatDescriptionRef formatDesc = format.formatDescription;
CMVideoDimensions dim = CMVideoFormatDescriptionGetDimensions(formatDesc);
- FourCharCode formatCodec = CMVideoFormatDescriptionGetCodecType(formatDesc);
- if (QAVFHelpers::fromCVPixelFormat(formatCodec) == cameraFormat.pixelFormat()
- && cameraFormat.resolution().width() == dim.width
- && cameraFormat.resolution().height() == dim.height
- && (!cvFormatValidator || cvFormatValidator(formatCodec))) {
+ FourCharCode cvPixFormat = CMVideoFormatDescriptionGetCodecType(formatDesc);
+
+ if (requiredCvPixFormat == cvPixFormat
+ && cameraFormatPrivate->resolution == QSize(dim.width, dim.height)
+ && (!cvFormatValidator || cvFormatValidator(cvPixFormat))) {
for (AVFrameRateRange *frameRateRange in format.videoSupportedFrameRateRanges) {
- if (frameRateRange.minFrameRate >= cameraFormat.minFrameRate()
- && frameRateRange.maxFrameRate <= cameraFormat.maxFrameRate()) {
+ if (frameRateRange.minFrameRate >= cameraFormatPrivate->minFrameRate
+ && frameRateRange.maxFrameRate <= cameraFormatPrivate->maxFrameRate) {
newFormat = format;
break;
}
diff --git a/src/plugins/multimedia/darwin/camera/qavfcamerabase.mm b/src/plugins/multimedia/darwin/camera/qavfcamerabase.mm
index 1cf7bb58c..15c79d544 100644
--- a/src/plugins/multimedia/darwin/camera/qavfcamerabase.mm
+++ b/src/plugins/multimedia/darwin/camera/qavfcamerabase.mm
@@ -166,6 +166,7 @@ void QAVFVideoDevices::updateCameraDevices()
auto encoding = CMVideoFormatDescriptionGetCodecType(format.formatDescription);
auto pixelFormat = QAVFHelpers::fromCVPixelFormat(encoding);
+ auto colorRange = QAVFHelpers::colorRangeForCVPixelFormat(encoding);
// Ignore pixel formats we can't handle
if (pixelFormat == QVideoFrameFormat::Format_Invalid) {
qCDebug(qLcCamera) << "ignore camera CV format" << encoding
@@ -192,16 +193,12 @@ void QAVFVideoDevices::updateCameraDevices()
#endif
qCDebug(qLcCamera) << "Add camera format. pixelFormat:" << pixelFormat
- << "cvPixelFormat" << encoding << "resolution:" << resolution
- << "frameRate: [" << minFrameRate << maxFrameRate << "]";
-
- auto *f = new QCameraFormatPrivate{
- QSharedData(),
- pixelFormat,
- resolution,
- minFrameRate,
- maxFrameRate
- };
+ << "colorRange:" << colorRange << "cvPixelFormat" << encoding
+ << "resolution:" << resolution << "frameRate: [" << minFrameRate
+ << maxFrameRate << "]";
+
+ auto *f = new QCameraFormatPrivate{ QSharedData(), pixelFormat, resolution,
+ minFrameRate, maxFrameRate, colorRange };
videoFormats << f->create();
}
if (videoFormats.isEmpty()) {
diff --git a/src/plugins/multimedia/darwin/qavfhelpers.mm b/src/plugins/multimedia/darwin/qavfhelpers.mm
index 74d0c9b9c..51ae9eedc 100644
--- a/src/plugins/multimedia/darwin/qavfhelpers.mm
+++ b/src/plugins/multimedia/darwin/qavfhelpers.mm
@@ -7,102 +7,72 @@
#import <CoreVideo/CoreVideo.h>
-static QVideoFrameFormat::ColorRange colorRangeForPixelFormat(unsigned avPixelFormat)
+namespace {
+
+using PixelFormat = QVideoFrameFormat::PixelFormat;
+using ColorRange = QVideoFrameFormat::ColorRange;
+
+// clang-format off
+constexpr std::tuple<CvPixelFormat, PixelFormat, ColorRange> PixelFormatMap[] = {
+ { kCVPixelFormatType_32ARGB, PixelFormat::Format_ARGB8888, ColorRange::ColorRange_Unknown },
+ { kCVPixelFormatType_32BGRA, PixelFormat::Format_BGRA8888, ColorRange::ColorRange_Unknown },
+ { kCVPixelFormatType_420YpCbCr8Planar, PixelFormat::Format_YUV420P, ColorRange::ColorRange_Unknown },
+ { kCVPixelFormatType_420YpCbCr8PlanarFullRange, PixelFormat::Format_YUV420P, ColorRange::ColorRange_Full },
+ { kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange, PixelFormat::Format_NV12, ColorRange::ColorRange_Video },
+ { kCVPixelFormatType_420YpCbCr8BiPlanarFullRange, PixelFormat::Format_NV12, ColorRange::ColorRange_Full },
+ { kCVPixelFormatType_420YpCbCr10BiPlanarVideoRange, PixelFormat::Format_P010, ColorRange::ColorRange_Video },
+ { kCVPixelFormatType_420YpCbCr10BiPlanarFullRange, PixelFormat::Format_P010, ColorRange::ColorRange_Full },
+ { kCVPixelFormatType_422YpCbCr8, PixelFormat::Format_UYVY, ColorRange::ColorRange_Video },
+ { kCVPixelFormatType_422YpCbCr8_yuvs, PixelFormat::Format_YUYV, ColorRange::ColorRange_Video },
+ { kCVPixelFormatType_OneComponent8, PixelFormat::Format_Y8, ColorRange::ColorRange_Unknown },
+ { kCVPixelFormatType_OneComponent16, PixelFormat::Format_Y16, ColorRange::ColorRange_Unknown },
+
+ // The cases with kCMVideoCodecType_JPEG/kCMVideoCodecType_JPEG_OpenDML as cv pixel format should be investigated.
+ // Matching kCMVideoCodecType_JPEG_OpenDML to ColorRange_Full is a little hack to distinguish between
+ // kCMVideoCodecType_JPEG and kCMVideoCodecType_JPEG_OpenDML.
+ { kCMVideoCodecType_JPEG, PixelFormat::Format_Jpeg, ColorRange::ColorRange_Unknown },
+ { kCMVideoCodecType_JPEG_OpenDML, PixelFormat::Format_Jpeg, ColorRange::ColorRange_Full }
+};
+// clang-format on
+
+template<typename Type, typename... Args>
+Type findInPixelFormatMap(Type defaultValue, Args... args)
{
- switch (avPixelFormat) {
- case kCVPixelFormatType_420YpCbCr8PlanarFullRange:
- case kCVPixelFormatType_420YpCbCr8BiPlanarFullRange:
- case kCVPixelFormatType_420YpCbCr10BiPlanarFullRange:
- return QVideoFrameFormat::ColorRange_Full;
- case kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange:
- case kCVPixelFormatType_420YpCbCr10BiPlanarVideoRange:
- case kCVPixelFormatType_422YpCbCr8:
- case kCVPixelFormatType_422YpCbCr8_yuvs:
- return QVideoFrameFormat::ColorRange_Video;
- default:
- return QVideoFrameFormat::ColorRange_Unknown;
- }
+ auto checkElement = [&](const auto &element) {
+ return ((args == std::get<Args>(element)) && ...);
+ };
+
+ auto found = std::find_if(std::begin(PixelFormatMap), std::end(PixelFormatMap), checkElement);
+ return found == std::end(PixelFormatMap) ? defaultValue : std::get<Type>(*found);
}
-QVideoFrameFormat::PixelFormat QAVFHelpers::fromCVPixelFormat(unsigned avPixelFormat)
+}
+
+ColorRange QAVFHelpers::colorRangeForCVPixelFormat(CvPixelFormat cvPixelFormat)
{
- switch (avPixelFormat) {
- case kCVPixelFormatType_32ARGB:
- return QVideoFrameFormat::Format_ARGB8888;
- case kCVPixelFormatType_32BGRA:
- return QVideoFrameFormat::Format_BGRA8888;
- case kCVPixelFormatType_420YpCbCr8Planar:
- case kCVPixelFormatType_420YpCbCr8PlanarFullRange:
- return QVideoFrameFormat::Format_YUV420P;
- case kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange:
- case kCVPixelFormatType_420YpCbCr8BiPlanarFullRange:
- return QVideoFrameFormat::Format_NV12;
- case kCVPixelFormatType_420YpCbCr10BiPlanarVideoRange:
- case kCVPixelFormatType_420YpCbCr10BiPlanarFullRange:
- return QVideoFrameFormat::Format_P010;
- case kCVPixelFormatType_422YpCbCr8:
- return QVideoFrameFormat::Format_UYVY;
- case kCVPixelFormatType_422YpCbCr8_yuvs:
- return QVideoFrameFormat::Format_YUYV;
- case kCVPixelFormatType_OneComponent8:
- return QVideoFrameFormat::Format_Y8;
- case q_kCVPixelFormatType_OneComponent16:
- return QVideoFrameFormat::Format_Y16;
-
- case kCMVideoCodecType_JPEG:
- case kCMVideoCodecType_JPEG_OpenDML:
- return QVideoFrameFormat::Format_Jpeg;
- default:
- return QVideoFrameFormat::Format_Invalid;
- }
+ return findInPixelFormatMap(ColorRange::ColorRange_Unknown, cvPixelFormat);
}
-bool QAVFHelpers::toCVPixelFormat(QVideoFrameFormat::PixelFormat qtFormat, unsigned &conv)
+PixelFormat QAVFHelpers::fromCVPixelFormat(CvPixelFormat cvPixelFormat)
{
- switch (qtFormat) {
- case QVideoFrameFormat::Format_ARGB8888:
- conv = kCVPixelFormatType_32ARGB;
- break;
- case QVideoFrameFormat::Format_BGRA8888:
- conv = kCVPixelFormatType_32BGRA;
- break;
- case QVideoFrameFormat::Format_YUV420P:
- conv = kCVPixelFormatType_420YpCbCr8PlanarFullRange;
- break;
- case QVideoFrameFormat::Format_NV12:
- conv = kCVPixelFormatType_420YpCbCr8BiPlanarFullRange;
- break;
- case QVideoFrameFormat::Format_P010:
- conv = kCVPixelFormatType_420YpCbCr10BiPlanarFullRange;
- break;
- case QVideoFrameFormat::Format_UYVY:
- conv = kCVPixelFormatType_422YpCbCr8;
- break;
- case QVideoFrameFormat::Format_YUYV:
- conv = kCVPixelFormatType_422YpCbCr8_yuvs;
- break;
- case QVideoFrameFormat::Format_Y8:
- conv = kCVPixelFormatType_OneComponent8;
- break;
- case QVideoFrameFormat::Format_Y16:
- conv = q_kCVPixelFormatType_OneComponent16;
- break;
- default:
- return false;
- }
+ return findInPixelFormatMap(PixelFormat::Format_Invalid, cvPixelFormat);
+}
- return true;
+CvPixelFormat QAVFHelpers::toCVPixelFormat(PixelFormat pixelFmt, ColorRange colorRange)
+{
+ return findInPixelFormatMap(CvPixelFormatInvalid, pixelFmt, colorRange);
}
QVideoFrameFormat QAVFHelpers::videoFormatForImageBuffer(CVImageBufferRef buffer, bool openGL)
{
- auto avPixelFormat = CVPixelBufferGetPixelFormatType(buffer);
- auto pixelFormat = fromCVPixelFormat(avPixelFormat);
+ auto cvPixelFormat = CVPixelBufferGetPixelFormatType(buffer);
+ auto pixelFormat = fromCVPixelFormat(cvPixelFormat);
if (openGL) {
- if (avPixelFormat == kCVPixelFormatType_32BGRA)
+ if (cvPixelFormat == kCVPixelFormatType_32BGRA)
pixelFormat = QVideoFrameFormat::Format_SamplerRect;
else
- qWarning() << "Accelerated macOS OpenGL video supports BGRA only, got CV pixel format" << avPixelFormat;
+ qWarning() << "Accelerated macOS OpenGL video supports BGRA only, got CV pixel format"
+ << cvPixelFormat;
}
size_t width = CVPixelBufferGetWidth(buffer);
@@ -166,7 +136,7 @@ QVideoFrameFormat QAVFHelpers::videoFormatForImageBuffer(CVImageBufferRef buffer
}
}
- format.setColorRange(colorRangeForPixelFormat(avPixelFormat));
+ format.setColorRange(colorRangeForCVPixelFormat(cvPixelFormat));
format.setColorSpace(colorSpace);
format.setColorTransfer(colorTransfer);
return format;
diff --git a/src/plugins/multimedia/darwin/qavfhelpers_p.h b/src/plugins/multimedia/darwin/qavfhelpers_p.h
index 2d2a531cf..8133d5500 100644
--- a/src/plugins/multimedia/darwin/qavfhelpers_p.h
+++ b/src/plugins/multimedia/darwin/qavfhelpers_p.h
@@ -21,19 +21,19 @@
#include <CoreVideo/CVPixelBuffer.h>
#include <CoreVideo/CVImageBuffer.h>
-enum {
- // macOS 10.14 doesn't define this pixel format yet
- q_kCVPixelFormatType_OneComponent16 = 'L016'
-};
-
QT_BEGIN_NAMESPACE
+using CvPixelFormat = unsigned;
+constexpr CvPixelFormat CvPixelFormatInvalid = 0;
+
namespace QAVFHelpers
{
- QVideoFrameFormat::PixelFormat fromCVPixelFormat(unsigned avPixelFormat);
- bool toCVPixelFormat(QVideoFrameFormat::PixelFormat qtFormat, unsigned &conv);
+QVideoFrameFormat::ColorRange colorRangeForCVPixelFormat(CvPixelFormat cvPixelFormat);
+QVideoFrameFormat::PixelFormat fromCVPixelFormat(CvPixelFormat cvPixelFormat);
+CvPixelFormat toCVPixelFormat(QVideoFrameFormat::PixelFormat pixFmt,
+ QVideoFrameFormat::ColorRange colorRange);
- QVideoFrameFormat videoFormatForImageBuffer(CVImageBufferRef buffer, bool openGL = false);
+QVideoFrameFormat videoFormatForImageBuffer(CVImageBufferRef buffer, bool openGL = false);
};
QT_END_NAMESPACE
diff --git a/src/plugins/multimedia/ffmpeg/qavfcamera.mm b/src/plugins/multimedia/ffmpeg/qavfcamera.mm
index 4e336674e..800825bd9 100644
--- a/src/plugins/multimedia/ffmpeg/qavfcamera.mm
+++ b/src/plugins/multimedia/ffmpeg/qavfcamera.mm
@@ -350,12 +350,11 @@ std::optional<int> QAVFCamera::ffmpegHWPixelFormat() const
return m_hwPixelFormat == AV_PIX_FMT_NONE ? std::optional<int>{} : m_hwPixelFormat;
}
-int QAVFCamera::cameraPixelFormatScore(QVideoFrameFormat::PixelFormat pixFmt) const
+int QAVFCamera::cameraPixelFormatScore(QVideoFrameFormat::PixelFormat pixelFormat,
+ QVideoFrameFormat::ColorRange colorRange) const
{
- unsigned cvFormat = 0;
- const auto isSupported =
- QAVFHelpers::toCVPixelFormat(pixFmt, cvFormat) && isCVFormatSupported(cvFormat);
- return static_cast<int>(isSupported);
+ auto cvFormat = QAVFHelpers::toCVPixelFormat(pixelFormat, colorRange);
+ return static_cast<int>(isCVFormatSupported(cvFormat));
}
QT_END_NAMESPACE
diff --git a/src/plugins/multimedia/ffmpeg/qavfcamera_p.h b/src/plugins/multimedia/ffmpeg/qavfcamera_p.h
index 3d462df8c..3f3fc97cd 100644
--- a/src/plugins/multimedia/ffmpeg/qavfcamera_p.h
+++ b/src/plugins/multimedia/ffmpeg/qavfcamera_p.h
@@ -60,7 +60,8 @@ public:
std::optional<int> ffmpegHWPixelFormat() const override;
- int cameraPixelFormatScore(QVideoFrameFormat::PixelFormat pixFmt) const override;
+ int cameraPixelFormatScore(QVideoFrameFormat::PixelFormat pixelFmt,
+ QVideoFrameFormat::ColorRange colorRange) const override;
private:
void requestCameraPermissionIfNeeded();