diff options
author | Artem Dyomin <artem.dyomin@qt.io> | 2023-08-14 17:18:49 +0200 |
---|---|---|
committer | Qt Cherry-pick Bot <cherrypick_bot@qt-project.org> | 2023-08-22 09:16:16 +0000 |
commit | 6332cdc7c1f73551c92b8d5b27168e9f12f5788a (patch) | |
tree | f92d25be49b933fbfb72858c337108f60a426497 | |
parent | b548dcebcb17bedbeeb114f95282dc084595c717 (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.h | 14 | ||||
-rw-r--r-- | src/multimedia/platform/qplatformcamera.cpp | 7 | ||||
-rw-r--r-- | src/multimedia/platform/qplatformcamera_p.h | 6 | ||||
-rw-r--r-- | src/plugins/multimedia/darwin/camera/avfcamerarenderer.mm | 29 | ||||
-rw-r--r-- | src/plugins/multimedia/darwin/camera/avfcamerarenderer_p.h | 3 | ||||
-rw-r--r-- | src/plugins/multimedia/darwin/camera/avfcamerautility.mm | 25 | ||||
-rw-r--r-- | src/plugins/multimedia/darwin/camera/qavfcamerabase.mm | 17 | ||||
-rw-r--r-- | src/plugins/multimedia/darwin/qavfhelpers.mm | 134 | ||||
-rw-r--r-- | src/plugins/multimedia/darwin/qavfhelpers_p.h | 16 | ||||
-rw-r--r-- | src/plugins/multimedia/ffmpeg/qavfcamera.mm | 9 | ||||
-rw-r--r-- | src/plugins/multimedia/ffmpeg/qavfcamera_p.h | 3 |
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 5709e6cb3..f2da5c6ed 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 0a22e81bd..9b87a5423 100644 --- a/src/plugins/multimedia/ffmpeg/qavfcamera.mm +++ b/src/plugins/multimedia/ffmpeg/qavfcamera.mm @@ -314,12 +314,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 0d3f91361..83dcd20e8 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: bool checkCameraPermission(); |