Qt6.5 M1苹果机设置QCamera为NV12却输出UYVY问题咨询
Qt6.5 M1设备QCamera设置Format_NV12格式但QVideoSink输出Format_UYVY的问题解决
问题场景
在Qt6.5环境下,通过setCameraFormat将QCamera的像素格式设置为Format_NV12时,Apple M1设备上QVideoSink最终输出的格式却是Format_UYVY,但Intel架构Mac设备表现完全正常。相关代码如下:
QCameraDevice cameraDevice; const QList<QCameraDevice> availableCameras = QMediaDevices::videoInputs(); for (const QCameraDevice &availableCamera : availableCameras) { if (availableCamera == QMediaDevices::defaultVideoInput()) cameraDevice = availableCamera; } camera_.reset(new QCamera(cameraDevice)); if (camera_->cameraFormat().isNull()) { auto formats = cameraDevice.videoFormats(); if (!formats.isEmpty()) { QCameraFormat bestFormat; for (const auto &fmt : formats) { if (fmt.pixelFormat() == QVideoFrameFormat::Format_NV12 && fmt.resolution().width() > fmt.resolution().height() && bestFormat.resolution().width() < fmt.resolution().width() && bestFormat.resolution().height() < fmt.resolution().height()) { bestFormat = fmt; } } camera_->setCameraFormat(bestFormat); } } captureSession_.setCamera(camera_.data()); captureSession_.setVideoSink(&videoSink_); connect(&videoSink_, &QVideoSink::videoFrameChanged, this, &VideoCaputer::OnFrameChanged); ... void VideoCaputer::OnFrameChanged(const QVideoFrame &frame) { // why? just on apple m1 if (frame.pixelFormat() == QVideoFrameFormat::Format_UYVY) { qDebug()<< "pixelFormat error"; return; } }
原因分析
- M1设备的AVFoundation框架(Qt在macOS上的多媒体底层实现)对Format_NV12格式的支持存在架构差异,摄像头硬件默认输出格式或Qt的格式适配逻辑在arm架构下未正确匹配设置。
- 代码中选中的Format_NV12格式对应的分辨率、帧率等参数可能未被M1摄像头硬件支持,导致Qt自动回退到兼容格式Format_UYVY。
解决方案
1. 验证格式设置是否生效
在调用setCameraFormat后,打印实际生效的摄像头格式,确认设置是否成功:
camera_->setCameraFormat(bestFormat); // 打印目标格式与实际生效格式 qDebug() << "Target format:" << bestFormat.pixelFormat() << bestFormat.resolution() << bestFormat.maxFrameRate(); qDebug() << "Actual applied format:" << camera_->cameraFormat().pixelFormat() << camera_->cameraFormat().resolution() << camera_->cameraFormat().maxFrameRate();
如果实际格式与目标不符,说明选中的Format_NV12格式参数(如分辨率、帧率)不被M1设备支持,需要调整格式筛选逻辑。
2. 优化格式筛选逻辑
扩展格式筛选条件,确保选中的Format_NV12格式是M1摄像头真正支持的完整配置:
for (const auto &fmt : formats) { if (fmt.pixelFormat() == QVideoFrameFormat::Format_NV12 && fmt.resolution().width() > fmt.resolution().height() // 增加帧率有效性检查 && fmt.minFrameRate() > 0 && fmt.maxFrameRate() >= 30) { // 根据业务需求调整帧率阈值 // 优先选择高分辨率+高帧率的格式 if (bestFormat.isNull() || fmt.resolution().width() > bestFormat.resolution().width() || (fmt.resolution().width() == bestFormat.resolution().width() && fmt.maxFrameRate() > bestFormat.maxFrameRate())) { bestFormat = fmt; } } }
3. 手动格式转换
如果M1设备确实无法输出Format_NV12,可在OnFrameChanged中手动将Format_UYVY转换为目标格式:
void VideoCaputer::OnFrameChanged(const QVideoFrame &frame) { QVideoFrame processedFrame = frame; if (frame.pixelFormat() == QVideoFrameFormat::Format_UYVY) { // 转换格式为NV12 processedFrame = frame.convertTo(QVideoFrameFormat::Format_NV12); if (!processedFrame.isValid()) { qDebug() << "Failed to convert UYVY to NV12"; return; } } // 使用processedFrame进行后续业务处理 // ... }
4. 升级Qt版本
Qt6.5可能存在M1架构下AVFoundation适配的bug,尝试升级到Qt6.6及以上版本,查看是否已修复相关格式匹配问题。
内容的提问来源于stack exchange,提问作者Ruibin.Chow
相关产品推荐
相关产品推荐

