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

Help with QThread



  • Hi There,

    I have a VideoPlayer and I want to put it into a separate thread, but I'm not sure how to do this. Here's my (shortened) code`

    VideoPlayer :: VideoPlayer(QWidget *parent)
        :QGraphicsScene(parent)
        ,mediaPlayer(0,QMediaPlayer::VideoSurface)
        ,videoItem(0)
    {
        videoItem=new VideoItem;
        mediaPlayer.setVideoOutput(videoItem);
        addItem(videoItem);
    }
    

    And here's the code for the VideoItem:

    VideoItem::VideoItem(QGraphicsItem *parent)
        : QGraphicsItem(parent)
        , imageFormat(QImage::Format_Invalid)
        , framePainted(false)
    {
    
    }
    
    VideoItem::~VideoItem()
    {
    }
    
    QRectF VideoItem::boundingRect() const
    {    
        return QRectF(QPointF(0,0), surfaceFormat().sizeHint());
    }
    
    void VideoItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
    {
        Q_UNUSED(option);
        Q_UNUSED(widget);
    
        if (currentFrame.map(QAbstractVideoBuffer::ReadOnly)) {
            const QTransform oldTransform = painter->transform();
    
            if (surfaceFormat().scanLineDirection() == QVideoSurfaceFormat::BottomToTop) {
               painter->scale(1, -1);
               painter->translate(0, -boundingRect().height());
            }
    
            painter->drawImage(boundingRect(), QImage(
                    currentFrame.bits(),
                    imageSize.width(),
                    imageSize.height(),
                    imageFormat));
    
            painter->setTransform(oldTransform);
    
            framePainted = true;
    
            currentFrame.unmap();
        }
    }
    
    QList<QVideoFrame::PixelFormat> VideoItem::supportedPixelFormats(
            QAbstractVideoBuffer::HandleType handleType) const
    {
        if (handleType == QAbstractVideoBuffer::NoHandle) {
            return QList<QVideoFrame::PixelFormat>()
                    << QVideoFrame::Format_RGB32
                    << QVideoFrame::Format_ARGB32
                    << QVideoFrame::Format_ARGB32_Premultiplied
                    << QVideoFrame::Format_RGB565
                    << QVideoFrame::Format_RGB555;
        } else {
            return QList<QVideoFrame::PixelFormat>();
        }
    }
    
    bool VideoItem::start(const QVideoSurfaceFormat &format)
    {
        if (isFormatSupported(format)) {
            imageFormat = QVideoFrame::imageFormatFromPixelFormat(format.pixelFormat());
            imageSize = format.frameSize();
            framePainted = true;
    
            QAbstractVideoSurface::start(format);
    
            prepareGeometryChange();
            emit sizeChanged(boundingRect());
            return true;
        } else {
            return false;
        }
    }
    
    void VideoItem::stop()
    {
        currentFrame = QVideoFrame();
        framePainted = false;
    
        QAbstractVideoSurface::stop();
    }
    
    bool VideoItem::present(const QVideoFrame &frame)
    {
        if (!framePainted) {
            if (!QAbstractVideoSurface::isActive())
                setError(StoppedError);
    
            return false;
        } else {
            currentFrame = frame;
            framePainted = false;
            update();
            emit frameChanged();
            return true;
        }
    }
    
    

    I think I need to put the VideoItem's present function into a QThread but I am not sure how to do it. So my question is: is it the right place to use QThread and if so how do I go about it? Any help or suggestions would be gratefully received.

    Thanks in advance
    Best wishes
    Ziggx


  • Lifetime Qt Champion

    Hi
    You cannot have any widgets (GUI) in another thread. That is not allowed at all.
    All GUI must stay in main thread.
    But why you want to run player in a thread ?



  • The app is a bit sluggish when running video - I use videoitem to emit a signal whenever there is a new frame (I need this to update timecode). I had hoped that using Thread would let it run faster. But from what you say, I simply can't do that.

    Hmm... I'll have to think again.

    Thanks for your reply

    Best wishes
    Ziggx


  • Lifetime Qt Champion

    @ziggx said in Help with QThread:

    I need this to update timecode

    How heavy is this updating?



  • It needs to run on every new frame. :(


  • Lifetime Qt Champion

    @ziggx It's not what I asked. The question is: how long does each calculation for this update take?



  • Hmm... checked the elapsed time for that function and it is 1ms or less. The problem is obviously somewhere else. I'm on OSX and the activity monitor shows I have lots of idle wakeups - could the OS be slowing things down?

    Best wishes
    Ziggx


Log in to reply