You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 04:00:42