How to make QVideoProbe work?

I am currently using a cross-platform application (Android, iOS) using QML, and I need to perform the function of scanning a QR code. QR code readings use ZXing, and there are no problems, the problem is with the camera. I cannot extract video frames from QCamera .

There is a QVideoProbe module that should do this for me. However, it does not work, not on Win32, not on OSX. It just doesn't work on a desktop platform. I do not have my code on this computer, but it is exactly the same as in this example, I found on the forum

 QCamera *camera = new QCamera; camera->setCaptureMode(QCamera::CaptureVideo); QCameraViewfinder *viewfinder = new QCameraViewfinder(); camera->setViewfinder(viewfinder); qDebug() << " start set source"; QVideoProbe *videoProbe = new QVideoProbe(this); if (videoProbe->setSource((QMediaObject *)camera)) { qDebug() << " set source succeed"; //Probing succeeded, videoProbe->isValid() should be true. connect(videoProbe, SIGNAL(videoFrameProbed(const QVideoFrame &)),this,SLOT(detectAVA(const QVideoFrame &))); } camera->start(); 

The forum guy has the same problem with me. Line:

 videoProbe->setSource((QMediaObject *)camera) 

will return false .

Reply on the forum:

Using (passing) the Camera element as sourceObj, what will happen?

It will also work.

That was in theory. In practice, it depends on the platform. QVideoProbe not available for all of them (or only for a media player or camera).

It should be in the document, but here is an overview of QVideoProbe support:

  • Android: camera only
  • Blackberry: no support
  • iOS: no support
  • Linux: media player only
  • Mac: no support
  • Windows: media player only

If you do not support it, this does not necessarily mean that it is impossible to do it on this platform, it may mean that it is not currently implemented.

So, Android is only a platform that supports Camera, then I am looking for support for Win32, I am ready to add support for win32, that the work will be very difficult, and I will integrate it into Qt Trunk.

In addition, I will add media player support for Android. These are the two features that I am looking for.

It seems that it is not implemented, and if it works, it will only work on Android, and I have to test it on a real phone (the simulator does not work).

I think that extracting the frame from the camera is a very simple function on any platform and language. There must be a way. Is there any solution?

+5
source share
1 answer

I implemented this with a hack. It works as expected. The idea is to use QAbstractVideoSurface as a temporary alternative to QVideoProbe . It has many disadvantages, but at least it is something.

The code below compiles, but I honestly don't know if it works (it has been sitting idle for a while). Use at your own risk!

PoorMansProbe.hpp

 #ifndef POORMANSPROBE_HPP #define POORMANSPROBE_HPP #include <QAbstractVideoSurface> #include <QList> class QCamera; class QCameraViewfinder; class PoorMansProbe : public QAbstractVideoSurface { Q_OBJECT private: QCamera *source; public: explicit PoorMansProbe(QObject *parent = nullptr); QList<QVideoFrame::PixelFormat> supportedPixelFormats(QAbstractVideoBuffer::HandleType handleType) const; // Called from QAbstractVideoSurface whenever a new frame is present bool present(const QVideoFrame &frame) Q_DECL_OVERRIDE; bool setSource(QCamera *source); bool isActive() const; signals: // Users of this class will get frames via this signal void videoFrameProbed(const QVideoFrame &videoFrame); void flush(); }; #endif // POORMANSPROBE_HPP 

PoorMansProbe.cpp

 #include "PoorMansProbe.hpp" #include <QVideoFrame> #include <QCamera> #include <QCameraViewfinder> PoorMansProbe::PoorMansProbe(QObject *parent) : QAbstractVideoSurface(parent) , source(0) { } QList<QVideoFrame::PixelFormat> PoorMansProbe::supportedPixelFormats(QAbstractVideoBuffer::HandleType handleType) const { Q_UNUSED(handleType); return QList<QVideoFrame::PixelFormat>() << QVideoFrame::Format_ARGB32 << QVideoFrame::Format_ARGB32_Premultiplied << QVideoFrame::Format_RGB32 << QVideoFrame::Format_RGB24 << QVideoFrame::Format_RGB565 << QVideoFrame::Format_RGB555 << QVideoFrame::Format_ARGB8565_Premultiplied << QVideoFrame::Format_BGRA32 << QVideoFrame::Format_BGRA32_Premultiplied << QVideoFrame::Format_BGR32 << QVideoFrame::Format_BGR24 << QVideoFrame::Format_BGR565 << QVideoFrame::Format_BGR555 << QVideoFrame::Format_BGRA5658_Premultiplied << QVideoFrame::Format_AYUV444 << QVideoFrame::Format_AYUV444_Premultiplied << QVideoFrame::Format_YUV444 << QVideoFrame::Format_YUV420P << QVideoFrame::Format_YV12 << QVideoFrame::Format_UYVY << QVideoFrame::Format_YUYV << QVideoFrame::Format_NV12 << QVideoFrame::Format_NV21 << QVideoFrame::Format_IMC1 << QVideoFrame::Format_IMC2 << QVideoFrame::Format_IMC3 << QVideoFrame::Format_IMC4 << QVideoFrame::Format_Y8 << QVideoFrame::Format_Y16 << QVideoFrame::Format_Jpeg << QVideoFrame::Format_CameraRaw << QVideoFrame::Format_AdobeDng; } bool PoorMansProbe::present(const QVideoFrame &frame) { if (frame.isValid()) { emit videoFrameProbed(frame); return true; } return false; } bool PoorMansProbe::setSource(QCamera *source) { this->source=source; source->setViewfinder(this); QCameraViewfinderSettings viewfinderSettings; // I have a broken camera that only support these settings, but you should put whatever settings you need here viewfinderSettings.setResolution(640, 480); viewfinderSettings.setMinimumFrameRate(0.0); viewfinderSettings.setMaximumFrameRate(30.0); source->setViewfinderSettings(viewfinderSettings); return true; } bool PoorMansProbe::isActive() const { return (0!=source); } 
0
source

Source: https://habr.com/ru/post/1200897/


All Articles