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
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.