Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Qt6 thread error
Forum Updated to NodeBB v4.3 + New Features

Qt6 thread error

Scheduled Pinned Locked Moved Unsolved General and Desktop
5 Posts 2 Posters 609 Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • S Offline
    S Offline
    Soviet-Ball
    wrote on last edited by
    #1

    In my media player project, it contains no QThread and it works well in Qt 6.3.2 on Windows and Android.However, in Qt 6..5.3, it never works.When I try playing a media in debug mode, it shows a critical messagebox.

    what it outputs:
    failed to get textures for frame; format: 172 textureConverter null
    ASSERT failure in QCoreApplication::sendEvent: "Cannot send events to objects owned by a different thread. Current thread 0x0x2aec62898c0. Receiver '' (of type 'QLabel') was created in thread 0x0x2aeba8ec7b0", file C:\Users\qt\work\qt\qtbase\src\corelib\kernel\qcoreapplication.cpp, line 541(In fact, the file doesn't exist)

    Through using QDebug line by line, I found it errors when I use QMediaPlayer::play().Why and how can I solve it?

    bool PlayerWidget::play()
    {
    player->play();
    QObject::connect(this,QOverloadQMediaPlayer::Error,QString::of(&PlayerWidget::error_private),[=](QMediaPlayer::Error error,QString string){
    if(error != QMediaPlayer::Error::NoError)
    {
    this->disconnect(this,SIGNAL(error_private(QMediaPlayer::Error,QString)),0,0);
    filepath = "";
    loop->quit();
    }
    });
    QObject::connect(this,QOverloadQMediaPlayer::MediaStatus::of(&PlayerWidget::statusChanged_private),[=](QMediaPlayer::MediaStatus status){
    if(status == QMediaPlayer::BufferedMedia)
    {
    this->disconnect(this,SIGNAL(statusChanged_private(QMediaPlayer::MediaStatus)),0,0);
    loop->quit();
    }
    });
    loop->exec();
    if(player->mediaStatus() == QMediaPlayer::BufferedMedia)
    return true;
    else
    return false;
    }

    Christian EhrlicherC 1 Reply Last reply
    0
    • S Soviet-Ball

      In my media player project, it contains no QThread and it works well in Qt 6.3.2 on Windows and Android.However, in Qt 6..5.3, it never works.When I try playing a media in debug mode, it shows a critical messagebox.

      what it outputs:
      failed to get textures for frame; format: 172 textureConverter null
      ASSERT failure in QCoreApplication::sendEvent: "Cannot send events to objects owned by a different thread. Current thread 0x0x2aec62898c0. Receiver '' (of type 'QLabel') was created in thread 0x0x2aeba8ec7b0", file C:\Users\qt\work\qt\qtbase\src\corelib\kernel\qcoreapplication.cpp, line 541(In fact, the file doesn't exist)

      Through using QDebug line by line, I found it errors when I use QMediaPlayer::play().Why and how can I solve it?

      bool PlayerWidget::play()
      {
      player->play();
      QObject::connect(this,QOverloadQMediaPlayer::Error,QString::of(&PlayerWidget::error_private),[=](QMediaPlayer::Error error,QString string){
      if(error != QMediaPlayer::Error::NoError)
      {
      this->disconnect(this,SIGNAL(error_private(QMediaPlayer::Error,QString)),0,0);
      filepath = "";
      loop->quit();
      }
      });
      QObject::connect(this,QOverloadQMediaPlayer::MediaStatus::of(&PlayerWidget::statusChanged_private),[=](QMediaPlayer::MediaStatus status){
      if(status == QMediaPlayer::BufferedMedia)
      {
      this->disconnect(this,SIGNAL(statusChanged_private(QMediaPlayer::MediaStatus)),0,0);
      loop->quit();
      }
      });
      loop->exec();
      if(player->mediaStatus() == QMediaPlayer::BufferedMedia)
      return true;
      else
      return false;
      }

      Christian EhrlicherC Offline
      Christian EhrlicherC Offline
      Christian Ehrlicher
      Lifetime Qt Champion
      wrote on last edited by
      #2

      Please format your code with code tags so others can read it and also provide a minimal, compilable exmaple. The error mentions a QLabel but I can't see any label in your code.

      Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
      Visit the Qt Academy at https://academy.qt.io/catalog

      S 1 Reply Last reply
      1
      • Christian EhrlicherC Christian Ehrlicher

        Please format your code with code tags so others can read it and also provide a minimal, compilable exmaple. The error mentions a QLabel but I can't see any label in your code.

        S Offline
        S Offline
        Soviet-Ball
        wrote on last edited by
        #3

        @Christian-Ehrlicher Actually, the error is mainly about QVideoFrame, not the label or the thread.It seems that the function QVideoFrame::toImage() has some bugs. And I found a similar question in Qt Forum:
        https://forum.qt.io/topic/145400/always-get-failed-to-get-textures-for-frame-true-error-for-media?_=1695988710176

        But I still don't know how to solve it.I have tried QImage(frame.bits(0),frame.width(),frame.height(),QVideoFrameFormat::imageFormatFromPixelFormat(frame.pixelFormat())) but it didn't work.(When I replace the frame image with one from local file, it worked)

        Christian EhrlicherC 1 Reply Last reply
        0
        • S Soviet-Ball

          @Christian-Ehrlicher Actually, the error is mainly about QVideoFrame, not the label or the thread.It seems that the function QVideoFrame::toImage() has some bugs. And I found a similar question in Qt Forum:
          https://forum.qt.io/topic/145400/always-get-failed-to-get-textures-for-frame-true-error-for-media?_=1695988710176

          But I still don't know how to solve it.I have tried QImage(frame.bits(0),frame.width(),frame.height(),QVideoFrameFormat::imageFormatFromPixelFormat(frame.pixelFormat())) but it didn't work.(When I replace the frame image with one from local file, it worked)

          Christian EhrlicherC Offline
          Christian EhrlicherC Offline
          Christian Ehrlicher
          Lifetime Qt Champion
          wrote on last edited by
          #4

          @Soviet-Ball said in Qt6 thread error:

          Actually, the error is mainly about QVideoFrame, not the label

          And why is the assertion about QLabel then?

          ASSERT failure in QCoreApplication::sendEvent: "Cannot send events to objects owned by a different thread. Current thread 0x0x2aec62898c0. Receiver '' (of type 'QLabel') was created in thread 0x0x2aeba8ec7b0",

          And again - please properly format your code and provide a minimal, compilable example of your program.

          QImage(frame.bits(0),frame.width(),frame.height(),QVideoFrameFormat::imageFormatFromPixelFormat(frame.pixelFormat())) b

          Where does this now suddenly comes from? Your code does not has this anywhere...

          Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
          Visit the Qt Academy at https://academy.qt.io/catalog

          S 1 Reply Last reply
          0
          • Christian EhrlicherC Christian Ehrlicher

            @Soviet-Ball said in Qt6 thread error:

            Actually, the error is mainly about QVideoFrame, not the label

            And why is the assertion about QLabel then?

            ASSERT failure in QCoreApplication::sendEvent: "Cannot send events to objects owned by a different thread. Current thread 0x0x2aec62898c0. Receiver '' (of type 'QLabel') was created in thread 0x0x2aeba8ec7b0",

            And again - please properly format your code and provide a minimal, compilable example of your program.

            QImage(frame.bits(0),frame.width(),frame.height(),QVideoFrameFormat::imageFormatFromPixelFormat(frame.pixelFormat())) b

            Where does this now suddenly comes from? Your code does not has this anywhere...

            S Offline
            S Offline
            Soviet-Ball
            wrote on last edited by
            #5

            @Christian-Ehrlicher I'm sorry that I may misunderstand your meaning.
            Here's the PlayerWidget class, still works well in Qt 6.3.2 and 5.14.2, but can't work in Qt 6.5.3.

            playerwidget.h:

            #ifndef PLAYERWIDGET_H
            #define PLAYERWIDGET_H
            #define Multimedia_And_Widgets_Enabled
            #define Multimedia_Private_Enabled
            #include <QWidget>
            #include <QLabel>
            #include <QFileInfo>
            #include <QKeyEvent>
            #ifdef Multimedia_And_Widgets_Enabled
            #include <QImageWriter>
            #include <QCamera>
            #include <QMediaPlayer>
            #include <QVideoWidget>
            #include <QMediaMetaData>
            #include <QVideoFrame>
            #include <QGraphicsVideoItem>
            #include <QGraphicsScene>
            #include <QGraphicsView>
            #include <QAudioOutput>
            #include <QMediaRecorder>
            #include <QAudioDecoder>
            #if(QT_VERSION>=QT_VERSION_CHECK(6,0,0))
            #include <QVideoSink>
            #include <QVideoFrameFormat>
            #else
            #ifdef Multimedia_Private_Enabled
            #include <private/qvideoframe_p.h>
            #endif
            #include <QVideoProbe>
            #include <QAbstractVideoSurface>
            #include <QAudioRecorder>
            #include <QAudioEncoderSettings>
            #include <QVideoEncoderSettings>
            #endif
            #endif
            
            class PlayerWidget : public QWidget
            {
                Q_OBJECT
            
            public:
                explicit PlayerWidget(QWidget *parent = nullptr);
                ~PlayerWidget();
                enum State
                {
                    StoppedState,
                    PlayingState,
                    PausedState
                };
                bool eventFilter(QObject *watched, QEvent *event);
                bool setFilePath(QString p);
                QString filePath();
                QMediaPlayer* mediaPlayer();
                bool play();
                void pause();
                void stop();
                void setPosition(int position);
                int duration();
                int volume();
                void setVolume(int v);
                bool hasVideo();
                bool hasAudio();
                QVideoFrame videoFrame();
                QMediaPlayer::MediaStatus mediaStatus();
                PlayerWidget::State state();
                void lock();
                void unlock();
                bool isLocked();
            signals:
                void keyRelease(QKeyEvent* event);
                void error(QMediaPlayer::Error e,QString errorString);
                void statusChanged(QMediaPlayer::MediaStatus status);
                void positionChanged(int position);
                void durationChanged(int duration);
                void videoFrameChanged(QVideoFrame frame);
                void hasVideoChanged(bool available);
                void hasAudioChanged(bool available);
                void stateChanged(PlayerWidget::State state);
            
                void statusChanged_private(QMediaPlayer::MediaStatus status);
                void error_private(QMediaPlayer::Error e,QString errorString);
            private:
                QEventLoop* loop;
                QMediaPlayer* player;
                QVideoWidget* videowidget;
                QLabel* label;
                QAudioOutput* audiooutput;
                QVideoFrame frame;
                QString filepath = "";
                bool videoAvailable = false;
                bool audioAvailable = false;
                bool enable = true;
                bool ret;
                bool widgetmode = false;
                QPoint startpoint = QPoint(-1,-1);
            #if (QT_VERSION >= QT_VERSION_CHECK(6,0,0))
                QVideoSink* sink;
            #else
                QVideoProbe* probe;
            #endif
            };
            #endif // PLAYERWIDGET_H
            

            playerwidget.cpp:

            #include "playerwidget.h"
            static bool hasFilePermission(QString filepath,QIODevice::OpenModeFlag device = QIODevice::ReadWrite)
            {
                bool check = true;
                if(filepath != "")
                {
                    QFile* file = new QFile(filepath);
                    if(!file->exists())
                        check = false;
                    if(file->open(device))
                    {
                        file->close();
                        delete file;
                        if(!check)
                            QFile::remove(filepath);
                        return true;
                    }
                    else
                    {
                        delete file;
                        return false;
                    }
                }
                else
                {
                    return false;
                }
            }
            PlayerWidget::PlayerWidget(QWidget *parent) :
                QWidget(parent)
            {
                qDebug() << "thread of playerwidget.cpp : " << this->thread();
                this->setStyleSheet("background-color: black;");
                this->setAttribute(Qt::WA_AcceptTouchEvents, true);
            
                player = new QMediaPlayer;
                videowidget = new QVideoWidget(this);
                audiooutput = new QAudioOutput;
                label = new QLabel(this);
                loop = new QEventLoop(this);
            #if (QT_VERSION >= QT_VERSION_CHECK(6,0,0))
                sink = new QVideoSink;
            #else
                probe = new QVideoProbe;
            #endif
            
                label->setStyleSheet("background-color: black;");
                label->resize(this->size());
                label->setAlignment(Qt::AlignCenter);
                if(widgetmode)
                {
                    videowidget->show();
                    label->hide();
                }
                else
                {
                   videowidget->hide();
                   label->show();
                }
                player->setVideoOutput(videowidget);
            
            #if (QT_VERSION >= QT_VERSION_CHECK(6,0,0))
                player->setAudioOutput(audiooutput);
                player->setVideoSink(sink);
            #else
                probe->setSource(player);
            #endif
            
                this->installEventFilter(this);
            
            #if (QT_VERSION >= QT_VERSION_CHECK(6,0,0))
                connect(player,&QMediaPlayer::errorChanged,[this](){
                    emit error_private(player->error(),player->errorString());
                    emit error(player->error(),player->errorString());
                });
                connect(player,&QMediaPlayer::hasVideoChanged,[this](){
                    videoAvailable = player->hasVideo();
                    emit hasVideoChanged(videoAvailable);
                    if(this->hasVideo())
                    {
                        label->show();
                    }
                    else
                    {
                        label->clear();
                        label->hide();
                    }
                });
                connect(player,&QMediaPlayer::hasAudioChanged,[this](){
                    audioAvailable = player->hasAudio();
                    emit hasAudioChanged(audioAvailable);
                    if(this->hasVideo())
                    {
                        label->show();
                    }
                    else
                    {
                        label->clear();
                        label->hide();
                    }
                });
                connect(player,&QMediaPlayer::playbackStateChanged,[this](){
                    emit stateChanged(this->state());
                });
                connect(sink,&QVideoSink::videoFrameChanged,[this](const QVideoFrame &f){
                    frame = f;
                    emit videoFrameChanged(frame);
                    if(f.isValid() && widgetmode == false && !this->isLocked())
                    {
                        label->setPixmap(QPixmap::fromImage(f.toImage().scaled(label->size(),Qt::KeepAspectRatio)));
                    }
                });
            #else
                QObject::connect(player,QOverload<QMediaPlayer::Error>::of(&QMediaPlayer::error),[=](){
                    emit error_private(player->error(),player->errorString());
                    emit error(player->error(),player->errorString());
                });
                QObject::connect(player,QOverload<bool>::of(&QMediaPlayer::videoAvailableChanged),[=](bool available){
                    videoAvailable = available;
                    emit hasVideoChanged(videoAvailable);
                    if(this->hasVideo())
                    {
                        label->show();
                    }
                    else
                    {
                        label->clear();
                        label->hide();
                    }
                });
                QObject::connect(player,QOverload<bool>::of(&QMediaPlayer::audioAvailableChanged),[=](bool available){
                    audioAvailable = available;
                    emit hasAudioChanged(audioAvailable);
                    if(this->hasVideo())
                    {
                        label->show();
                    }
                    else
                    {
                        label->clear();
                        label->hide();
                    }
                });
                QObject::connect(probe,QOverload<const QVideoFrame &>::of(&QVideoProbe::videoFrameProbed),[=](const QVideoFrame &f){
                    frame = f;
                    emit videoFrameChanged(frame);
                    if(f.isValid() && enable == true && widgetmode == false)
                    {
                        QImage image = qt_imageFromVideoFrame(f);
            #ifdef Q_OS_WIN
                        image = image.mirrored();
            #endif
                        if(!image.isNull())
                        {
                            image = image.scaled(label->size(),Qt::KeepAspectRatio);
                            label->setPixmap(QPixmap::fromImage(image));
                        }
                    }
                });
                QObject::connect(player,QOverload<QMediaPlayer::State>::of(&QMediaPlayer::stateChanged),[=](){
                    emit stateChanged(this->state());
                });
            #endif
                connect(player,&QMediaPlayer::mediaStatusChanged,[this](){
                    emit statusChanged_private(player->mediaStatus());
                    emit statusChanged(player->mediaStatus());
                });
                connect(player,&QMediaPlayer::positionChanged,[this](){
                    emit positionChanged(player->position());
                });
                connect(player,&QMediaPlayer::durationChanged,[this](){
                    emit durationChanged(player->duration());
                });
            }
            bool PlayerWidget::eventFilter(QObject *watched, QEvent *event)
            {
                if(watched == this)
                {
                    if(event->type() == QEvent::KeyRelease)
                    {
                        QKeyEvent* keyEvent = static_cast<QKeyEvent*>(event);
                        emit keyRelease(keyEvent);
                    }
                    else if(event->type() == QEvent::Resize)
                    {
                        if(widgetmode)
                            videowidget->resize(this->size());
                        else
                            label->resize(this->size());
                    }
                    else if(event->type() == QEvent::Close)
                    {
                        player->stop();
                    }
                    else if(event->type() == QEvent::Hide)
                    {
                        if(widgetmode)
                            videowidget->hide();
                        else
                            label->hide();
                    }
                    else if(event->type() == QEvent::Show)
                    {
                        if(widgetmode)
                            videowidget->show();
                        else
                            label->show();
                    }
                }
                return QObject::eventFilter(watched,event);
            }
            PlayerWidget::~PlayerWidget()
            {
            }
            bool PlayerWidget::setFilePath(QString p)
            {
                if(QFileInfo(p).isFile() && hasFilePermission(p,QIODevice::ReadOnly))
                {
                    filepath = p;
            #if (QT_VERSION >= QT_VERSION_CHECK(6,0,0))
                    player->setSource(QUrl::fromLocalFile(filepath));
            #else
                    player->setMedia(QUrl::fromLocalFile(filepath));
            #endif
                    return true;
                }
                else
                {
                    filepath = "";
                    return false;
                }
            }
            QString PlayerWidget::filePath()
            {
                return filepath;
            }
            QMediaPlayer* PlayerWidget::mediaPlayer()
            {
                return player;
            }
            bool PlayerWidget::play()
            {
                //QEventLoop* loop = new QEventLoop;
                player->play();
                QObject::connect(this,QOverload<QMediaPlayer::Error,QString>::of(&PlayerWidget::error_private),[=](QMediaPlayer::Error error,QString string){
                    if(error != QMediaPlayer::Error::NoError)
                    {
                        this->disconnect(this,SIGNAL(error_private(QMediaPlayer::Error,QString)),0,0);
                        filepath = "";
                        loop->quit();
                        //loop->exit(0);
                    }
                });
                QObject::connect(this,QOverload<QMediaPlayer::MediaStatus>::of(&PlayerWidget::statusChanged_private),[=](QMediaPlayer::MediaStatus status){
                    if(status == QMediaPlayer::BufferedMedia)
                    {
                        this->disconnect(this,SIGNAL(statusChanged_private(QMediaPlayer::MediaStatus)),0,0);
                        loop->quit();
                        //loop->exit(0);
                    }
                });
                this->lock();
                loop->exec();
                this->unlock();
                return bool(player->error()==QMediaPlayer::Error::NoError);
            }
            void PlayerWidget::pause()
            {
                player->pause();
            }
            void PlayerWidget::stop()
            {
                player->stop();
            }
            void PlayerWidget::setPosition(int position)
            {
                if(position >= 0)
                    player->setPosition(position);
            }
            int PlayerWidget::duration()
            {
                return player->duration();
            }
            int PlayerWidget::volume()
            {
            #if (QT_VERSION >= QT_VERSION_CHECK(6,0,0))
                    return int(player->audioOutput()->volume()*100.0);
            #else
                    return player->volume();
            #endif
            }
            void PlayerWidget::setVolume(int v)
            {
            #if (QT_VERSION >= QT_VERSION_CHECK(6,0,0))
                    player->audioOutput()->setVolume(float(v)/100.0);
            #else
                    player->setVolume(v);
            #endif
            }
            bool PlayerWidget::hasVideo()
            {
                //return player->hasVideo();
                return videoAvailable;
            }
            bool PlayerWidget::hasAudio()
            {
                //return player->hasAudio();
                return audioAvailable;
            }
            QVideoFrame PlayerWidget::videoFrame()
            {
                return frame;
            }
            QMediaPlayer::MediaStatus PlayerWidget::mediaStatus()
            {
                return player->mediaStatus();
            }
            PlayerWidget::State PlayerWidget::state()
            {
            #if (QT_VERSION >= QT_VERSION_CHECK(6,0,0))
                if(player->playbackState() == QMediaPlayer::PlaybackState::PlayingState)
                {
                    return PlayerWidget::State::PlayingState;
                }
                else if(player->playbackState() == QMediaPlayer::PlaybackState::PausedState)
                {
                    return PlayerWidget::State::PausedState;
                }
                else
                {
                    return PlayerWidget::State::StoppedState;
                }
            #else
                if(player->state() == QMediaPlayer::State::PlayingState)
                {
                    return PlayerWidget::State::PlayingState;
                }
                else if(player->state() == QMediaPlayer::State::PausedState)
                {
                    return PlayerWidget::State::PausedState;
                }
                else
                {
                    return PlayerWidget::State::StoppedState;
                }
            #endif
            }
            void PlayerWidget::lock()
            {
                enable = false;
            }
            void PlayerWidget::unlock()
            {
                enable = true;
            }
            bool PlayerWidget::isLocked()
            {
                if(enable == true)
                    return false;
                else
                    return true;
            }
            

            how to use:

            PlayerWidget* widget = new PlayerWidget(this);
            if(widget->setFilePath(QFileDialog::getOpenFileName()) && widget->play())
                        {
                            return true;
                        }
                        else
                        {
                            return false;
                        }
            
            1 Reply Last reply
            0

            • Login

            • Login or register to search.
            • First post
              Last post
            0
            • Categories
            • Recent
            • Tags
            • Popular
            • Users
            • Groups
            • Search
            • Get Qt Extensions
            • Unsolved