QVideoSink: process each frame of QCamera and Paint to QVideoWidget
-
Overview
I have followed and tried to implement similar code to what is in https://forum.qt.io/topic/133893/painting-a-qvideoframe-on-a-qvideowidget-with-qt6 but continue to get errors of
QWidget::paintEngine: Should no longer be called
,QPainter::worldTransform: Painter not active
, andQPainter::setWorldTransform: Painter not active
. After using solutions from https://forum.qt.io/topic/64693/unable-to-paint-on-qt-widget-shows-error-paintengine-should-no-longer-be-called I still get the same errors and my QVideoWidget is black with no output.Details
I'm using Qt 6.4.0 and testing both on android emulator as well as on a Google Pixel 6.
The main differences in my application vs the post's example are:
- I've created ui/h/cpp files, and the class inherits from QWidget and not the QMainWindow
- My custom class is put inside a scroll area widget.
- Again, trying on android (I think the post was on desktop?)
I use the same code from that discussion:
#scannerpage.h QVideoSink m_videoSink; QMediaCaptureSession m_captureSession; QScopedPointer<QCamera> m_camer;
# scannerpage.cpp m_camera.reset(new QCamera(QMediaDevices::defaultVideoInput())); m_captureSession.setCamera(m_camera.data()); connect(&m_videoSink, &QVideoSink::videoFrameChanged, this, &ScannerPage::processVideoFrame); m_captureSession.setVideoSink(&m_videoSink); m_captureSession.setVideoOutput(m_videoWidget); m_camera->start(); m_videoWidget = new QVideoWidget(this); ui->gridLayout->addWidget(m_videoWidget);
I can see via debug that my code is reaching
processVideoFrame()
, but the errors that I hit are:QWidget::paintEngine: Should no longer be called QPainter::begin: Paint device returned engine == 0, type: 1 QPainter::worldTransform: Painter not active QPainter::setWorldTransform: Painter not active QPainter::setWorldTransform: Painter not active
So, after seeing those errors I found https://forum.qt.io/topic/64693/unable-to-paint-on-qt-widget-shows-error-paintengine-should-no-longer-be-called and https://stackoverflow.com/questions/25781353/qt-qwidgetpaintengine-should-no-longer-be-called. Note in the stackoverflow one, I'm not using QML/Quick, I'm trying to just put my
QVideoWidget
into the scroll area, process each frame, and still have a preview in the QVideoWidget.So I changed the
processVideoFrame()
function to the following:void ScannerPage::processVideoFrame() { m_tmpVideoFrame = m_videoSink.videoFrame(); if (m_tmpVideoFrame.map(QVideoFrame::ReadOnly)) { #videoframe.paint(new QPainter(m_videoWidget), QRectF(0.0f,0.0f,100.0f,100.0f), QVideoFrame::PaintOptions()); #videoframe.unmap(); m_videoWidget->update(); } }
And added the following to my
.h
file and.cpp
file:#scannerpage.h private slots: void paintEvent(QPaintEvent *event) override; private: QVideoFrame m_tmpVideoFrame;
#scannerpage.cpp void ScannerPage::paintEvent(QPaintEvent *event) { m_tmpVideoFrame.paint(new QPainter(m_videoWidget), QRectF(0.0f,0.0f,100.0f,100.0f), QVideoFrame::PaintOptions()); m_tmpVideoFrame.unmap(); }
But I still get those errors I mentioned earlier of
paintEngine should no longer be called
and the QVideoWidget is still black.What am I missing here?