I receive QVideoFrames
from webcam, and they contain image data in YUV format (QVideoFrame::Format_YUV420P
). How can I convert one such frame to one with QVideoFrame::Format_ARGB32
or QVideoFrame::Format_RGBA32
?
Can I do it without going low level, using just existing functionality in Qt5?
Example:
QVideoFrame convertFormat(const QVideoFrame &inputframe, QVideoFrame::PixelFormat outputFormat)
{
// What comes here?
}
//Usage
QVideoFrame converted = convertFormat(mySourceFrame, QVideoFrame::Format_RGB32);
I found a solution that is built into Qt5, but UNSUPPORTED BY Qt.
Here is how to go about:
- Put
QT += multimedia-private
into your qmake .pro file - Put
#include "private/qvideoframe_p.h"
into your code to make the function available. - You now have access to a function with the following signature:
QImage qt_imageFromVideoFrame(const QVideoFrame &frame);
- Use the function to convert the
QVideoFrame
to a temporayQImage
and then create the outputQVideoFrame
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);
}
来源:https://stackoverflow.com/questions/43106069/how-to-convert-qvideoframe-with-yuv-data-to-qvideoframe-with-rgba32-data-in