How to convert 'QVideoFrame' with YUV data to 'QVideoframe' with RGBA32 data in Qt?

隐身守侯 提交于 2019-12-01 11:08:01

I found a solution that is built into Qt5, but UNSUPPORTED BY Qt.

Here is how to go about:

  1. Put QT += multimedia-private into your qmake .pro file
  2. Put #include "private/qvideoframe_p.h" into your code to make the function available.
  3. You now have access to a function with the following signature: QImage qt_imageFromVideoFrame(const QVideoFrame &frame);
  4. Use the function to convert the QVideoFrame to a temporay QImage and then create the output QVideoFrame from that image.

Here is my example usage:

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;
    }

Again, the warning copied from the header reads as follows:

//
//  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.
//

This does not matter in my project since it is a personal toy product. If it ever gets serious I will just track down the implementation of that function and copy it into my project or something.

I've found a YUV --> RGB conversion solution in the linked comment,

So Implementing the supportedPixelFormats function like the following example does the magic of converting even YUV based formats (in my case, it converted a Format_YUV420P format) into the Format_RGB24 format:

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

Tell me if it worked for you.

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);
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!