如何使用Qt中的RGBA32数据将带有YUV数据的'QVideoFrame'转换为'QVideoframe'?

时间:2017-03-29 23:42:37

标签: c++ qt format qt5 qvideoframe

我从网络摄像头收到QVideoFrames,它们包含 YUV 格式(QVideoFrame::Format_YUV420P)的图像数据。如何将一个此类框架转换为QVideoFrame::Format_ARGB32QVideoFrame::Format_RGBA32

只使用 Qt5 中的现有功能,我可以不降低水平吗?

示例:

QVideoFrame convertFormat(const QVideoFrame &inputframe, QVideoFrame::PixelFormat outputFormat)
{
    // What comes here?
}

//Usage
QVideoFrame converted = convertFormat(mySourceFrame, QVideoFrame::Format_RGB32);

3 个答案:

答案 0 :(得分:3)

我找到了一个内置于Qt5 的解决方案,但不支持Qt

以下是如何进行:

  1. QT += multimedia-private放入qmake .pro文件
  2. #include "private/qvideoframe_p.h"放入您的代码中以使该功能可用。
  3. 您现在可以访问具有以下签名的函数:QImage qt_imageFromVideoFrame(const QVideoFrame &frame);
  4. 使用此功能将QVideoFrame转换为临时QImage,然后从该图片中创建输出QVideoFrame
  5. 以下是我的示例用法:

    QVideoFrame convertFormat(const QVideoFrame &inputframe, QVideoFrame::PixelFormat outputFormat)
        {
            inputframe->map(QAbstractVideoBuffer::ReadOnly);
            QImage tempImage=qt_imageFromVideoFrame(inputframe);
            inputframe->unmap();
            QVideoFrame outputFrame=QVideoFrame(tempImage);
            return outputFrame;
        }
    

    同样,从标题中复制的警告内容如下:

    //
    //  W A R N I N G
    //  -------------
    //
    // This file is not part of the Qt API.  It exists purely as an
    // implementation detail.  This header file may change from version to
    // version without notice, or even be removed.
    //
    // We mean it.
    //
    

    这在我的项目中无关紧要,因为它是个人玩具产品。如果它变得严重,我将只追踪该功能的实现并将其复制到我的项目中。

答案 1 :(得分:1)

我找到了一个YUV - > the linked comment中的RGB转换解决方案,

因此,像以下示例一样实现 supportedPixelFormats 功能可以实现转换甚至基于YUV的格式的魔力(在我的情况下,它转换了 Format_YUV420P 格式化)为 Format_RGB24 格式:

QList<QVideoFrame::PixelFormat>MyVideoSurface::
supportedPixelFormats(QAbstractVideoBuffer::HandleType handleType) const
{
    Q_UNUSED(handleType);
    return QList<QVideoFrame::PixelFormat>()
        << QVideoFrame::Format_RGB24
    ;
}

告诉我它是否适合你。

答案 2 :(得分:-2)

https://doc.qt.io/qt-5/qvideoframe.html#map

if (inputframe.map(QAbstractVideoBuffer::ReadOnly))
{
    int height = inputframe.height();
    int width = inputframe.width();
    uchar* bits = inputframe.bits();
    // figure out the inputFormat and outputFormat, they should be QImage::Format
    QImage image(bits, width, height, inputFormat);
    // do your conversion
    QImage outImage = image.convertToForma(outFormat); // blah convert
    return QVideoFrame(outImage);
}