如何使QVideoProbe工作?

时间:2014-08-22 02:48:20

标签: android c++ qt camera qml

我目前正在使用QML制作跨平台应用(Android,iOS),我需要进行QR码扫描功能。 QR码读数正在使用ZXing,没有问题,问题在于相机。 我无法从QCamera中提取视频帧

有一个模块QVideoProbe应该为我做。但是,它不起作用 ,而不是在Win32上,而不是在OSX上。它根本不适用于桌面平台。我没有在这台电脑上使用我的代码,但它就像我在论坛上找到的这个例子一样

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();

论坛上的人跟我有同样的问题。这一行:

videoProbe->setSource((QMediaObject *)camera)

将返回false

论坛上的回复是:

  

使用(传递)Camera元素作为sourceObj,会发生什么?

     

它也可以。

     

那是理论上的。在实践中,它取决于平台。   QVideoProbe并非全部可用(或仅适用于a   媒体播放器或相机)。

     

它应该在文档中,但这里是对QVideoProbe的概述   支持:

     
      
  • Android:仅适用于相机
  •   
  • 黑莓:不支持
  •   
  • iOS:不支持
  •   
  • Linux:仅适用于媒体播放器
  •   
  • Mac:不支持
  •   
  • Windows:仅适用于媒体播放器
  •   
     

如果它不受支持,它并不一定意味着它不可能   在给定的平台上进行,它可能意味着它目前不是   实现。

     

所以,Android只是支持Camera的平台,那么我就是   在Win32上寻找支持,我愿意在win32下添加支持,   这项工作真的很难,我会​​把它合并到Qt中   主线。

     

此外,我将在Android下添加媒体播放器支持。那是两个   功能我正在寻找。

看起来它没有实现,如果这样可行,它只适用于Android,我必须在真实手机上进行测试(模拟器无法正常工作)。

我想从相机中提取帧是任何平台和语言的基本功能。一定有办法。有没有解决方案?

1 个答案:

答案 0 :(得分:0)

我使用hack实现了这一点。它有点像预期的那样工作。我们的想法是使用QAbstractVideoSurface作为QVideoProbe的临时替代方案。它有许多缺点,但至少它是一些东西。

下面的代码编译但我老实说不知道它是否有效(它已经暂停了一段时间)。使用风险自负!

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