Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Cannot write to QVideoFrame from QVideoFilterRunnable [ubuntu 18]



  • I am trying the change QVideoFrame from QVideoFilterRunnable but it doesn't allow me (see below):

    I am running the code on Ubuntu 18.

    16:38:27: Starting /home/mike/Downloads/OpticalMeasure/build-CuteDetector-Desktop_Qt_5_12_0_GCC_64bit-Debug/CuteDetector...
    QML debugging is enabled. Only use this in a safe environment.
    
    (CuteDetector:17368): GStreamer-CRITICAL **: 16:38:29.127: write map requested on non-writable buffer
    16:38:29: The program has unexpectedly finished.
    

    qcvdetectfilter.h

    #ifndef QCVDETECTFILTER_H
    #define QCVDETECTFILTER_H
    
    #include <QAbstractVideoFilter>
    #include <QDebug>
    #include <QTemporaryFile>
    #include <QMutex>
    #include "opencv2/opencv.hpp"
    
    class QCvDetectFilter : public QAbstractVideoFilter
    {
        Q_OBJECT
    public:
        QVideoFilterRunnable *createFilterRunnable();
    
    signals:
        void objectDetected(float x, float y, float w, float h);
    
    public slots:
    
    };
    
    class QCvDetectFilterRunnable : public QVideoFilterRunnable
    {
    public:
        QCvDetectFilterRunnable(QCvDetectFilter *creator) {filter = creator;}
        QVideoFrame run(QVideoFrame *input, const QVideoSurfaceFormat &surfaceFormat, RunFlags flags);
    
    private:
        void dft(cv::InputArray input, cv::OutputArray output);
        QCvDetectFilter *filter;
    };
    
    #endif // QCVDETECTFILTER_H
    

    qcvdetectfilter.cpp

    #include "qcvdetectfilter.h"
    #include "cvmatandqimage.h"
    
    cv::CascadeClassifier classifier;
    
    QVideoFilterRunnable* QCvDetectFilter::createFilterRunnable()
    {
        return new QCvDetectFilterRunnable(this);
    }
    
    QVideoFrame QCvDetectFilterRunnable::run(QVideoFrame *input, const QVideoSurfaceFormat &surfaceFormat, RunFlags flags)
    {
        Q_UNUSED(flags);
        input->map(QAbstractVideoBuffer::WriteOnly);
    
    //    if( input->isValid() && input->map(QAbstractVideoBuffer::ReadWrite))
    //       {
            cv::Mat mat(input->height(),input->width(), CV_8U, input->bits());
            cv::Scalar color(255, 0, 0);
            cv::circle(mat, cv::Point(50,50), 20, color);
    
     input->unmap();
        return *input;
    }
    

  • Lifetime Qt Champion

    Hi,

    Why did you remove the check of the return value of map ?



  • hi,

    Cuz even if I keep it like below, I still get the same error message:

    if( input->isValid() && input->map(QAbstractVideoBuffer::ReadWrite))
           {
            input->bits()[0] = 1;
            cv::Mat mat(input->height(),input->width(), CV_8U, input->bits());
            cv::Scalar color(255, 0, 0);
            cv::circle(mat, cv::Point(50,50), 20, color);
        } else {
            std::cout << "is not writable";
        }
    
    

    here is the error

    
    (CuteDetector:5644): GStreamer-CRITICAL **: 04:06:49.253: write map requested on non-writable buffer
    QVideoFrame::unmap() was called more times then QVideoFrame::map()
    
    

    I found a working example which does the job pretty perfectly but I have hard time figuring out what is actually done differently.

    At least let me know how things done differently here :)

    https://github.com/stephenquan/MyVideoFilterApp


  • Lifetime Qt Champion

    He never maps the QVideoFrame directly.

    He either us the private qt_imageFromVideoFrame method (which will to the map/unmap cycle) to get a QImage and work on that, or in the case of an OpenGL Texture, use OpenGL directly to access the data.


Log in to reply