From a36d5da13534db0a96463b27a89fd3c586fbb7c8 Mon Sep 17 00:00:00 2001 From: Sofian Audry Date: Wed, 27 Dec 2017 15:57:50 -0500 Subject: [PATCH] Fix format problems by copying frame into QImage. --- src/core/VideoSurface.cpp | 61 +++++++++++++++++++++++---------------- src/core/VideoSurface.h | 7 ++--- 2 files changed, 38 insertions(+), 30 deletions(-) diff --git a/src/core/VideoSurface.cpp b/src/core/VideoSurface.cpp index dd11f16..7906f0b 100644 --- a/src/core/VideoSurface.cpp +++ b/src/core/VideoSurface.cpp @@ -41,6 +41,7 @@ #include "VideoSurface.h" #include +#include namespace mmp { @@ -61,10 +62,16 @@ QList VideoSurface::supportedPixelFormats( if (handleType == QAbstractVideoBuffer::NoHandle) { return QList() << QVideoFrame::Format_RGB32 + << QVideoFrame::Format_RGB24 + << QVideoFrame::Format_RGB565 + << QVideoFrame::Format_RGB555 << QVideoFrame::Format_ARGB32 << QVideoFrame::Format_ARGB32_Premultiplied - << QVideoFrame::Format_RGB565 - << QVideoFrame::Format_RGB555; + << QVideoFrame::Format_BGR32 + << QVideoFrame::Format_BGR24 + << QVideoFrame::Format_BGR565 + << QVideoFrame::Format_BGR555 + ; } else { return QList(); } @@ -72,34 +79,38 @@ QList VideoSurface::supportedPixelFormats( bool VideoSurface::present(const QVideoFrame &frame) { - // if (!framePainted) { - // if (!QAbstractVideoSurface::isActive()) - // setError(StoppedError); - // - // return false; - // } else { - currentFrame = frame; - // - // int width = frame.width(); - // int height = frame.height(); - // const uchar* bits = frame.bits(); - // framePainted = false; - // - // update(); + // Copy current frame. + QVideoFrame currentFrame(frame); - return true; -// } + // Convert frame into QImage with appropriate format. + // Source: https://stackoverflow.com/questions/27829830/convert-qvideoframe-to-qimage + if (currentFrame.map(QAbstractVideoBuffer::ReadOnly)) + { + QImage::Format imageFormat = QVideoFrame::imageFormatFromPixelFormat(currentFrame.pixelFormat()); + if (imageFormat != QImage::Format_Invalid) { + _img = QImage(currentFrame.bits(), currentFrame.width(), currentFrame.height(), imageFormat); + } else { + // e.g. JPEG + int nbytes = currentFrame.mappedBytes(); + _img = QImage::fromData(currentFrame.bits(), nbytes); + } + + currentFrame.unmap(); + + // Convert to OpenGLformat and apply transforms to straighten. + _img = QGLWidget::convertToGLFormat(_img) + .mirrored(true, false) + .transformed(QTransform().rotate(180)); + + return true; + } + else + return false; } const uchar* VideoSurface::bits() { - if (currentFrame.map(QAbstractVideoBuffer::ReadOnly)) { - const uchar* bits = currentFrame.bits(); - currentFrame.unmap(); - return bits; - } - else - return 0; + return _img.bits(); } } diff --git a/src/core/VideoSurface.h b/src/core/VideoSurface.h index db4cc0c..d547100 100644 --- a/src/core/VideoSurface.h +++ b/src/core/VideoSurface.h @@ -66,11 +66,8 @@ public: const uchar* bits(); private: - // QImage::Format imageFormat; - // QSize imageSize; - - QVideoFrame currentFrame; - // bool framePainted; + // Each frame is saved internally in a QImage. + QImage _img; }; }