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. QThread cannot be stop after QCamera->start()
Forum Updated to NodeBB v4.3 + New Features

QThread cannot be stop after QCamera->start()

Scheduled Pinned Locked Moved Unsolved General and Desktop
11 Posts 5 Posters 283 Views 2 Watching
  • 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.
  • Q Offline
    Q Offline
    QtTester
    wrote last edited by
    #1

    hey guys.
    6.9.3+vs2022.
    I wanna capture a usb cam video. it works find but the thread for capturing cannot be stop.
    when I exit the app, thread.wait() cannot return after runing run() function ,even i already run stop().
    If I donot do anything , wait() works fine and can return.
    why wait() cannot return?

    mainwindow.cpp, two button, one for start , another for stop:

    #include "mainwindow.h"
    #include "ui_mainwindow.h"
    
    #include <QCamera>
    #include <QDebug>
    #include <QCameraDevice>
    #include <QMediaDevices>
    
    MainWindow::MainWindow(QWidget *parent)
        : QMainWindow(parent)
        , ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
        connect(this,&MainWindow::sigStart,&m_cam,&CamOperator::run);
        connect(this,&MainWindow::sigStop,&m_cam,&CamOperator::stop);
    
        //
        qDebug() <<"ui:"<<QThread::currentThread();
    }
    
    MainWindow::~MainWindow()
    {
        delete ui;
    }
    
    void MainWindow::on_pushButton_clicked()
    {
        emit sigStart();
    }
    
    void MainWindow::on_pushButton_2_clicked()
    {
        emit sigStop();
    }
    
    

    wrapper for qcamera:

    #include "camoperator.h"
    #include <QDebug>
    #include <QImage>
    #include <QDateTime>
    #include <QTimer>
    
    #define T_DBG qDebug()
    #define T_ERR qDebug()
    
    CamOperator::CamOperator(QObject *parent)
        : QObject{parent}
    {
        moveToThread(&m_bgThread);
        m_bgThread.start();
    }
    
    CamOperator::~CamOperator()
    {
        stop();
    
        if(m_bgThread.isRunning()){
            T_DBG<<"stop cam...";
            m_bgThread.requestInterruption();
            m_bgThread.quit();
            if(1){
                T_DBG<<"wait thread end...";
    
                // 3000 right here, after run(), it cannot return anymore.
                m_bgThread.wait();
            }
            T_DBG<<"thred end";
        }
    
    }
    
    void CamOperator::run()
    {
        auto cam = QMediaDevices::defaultVideoInput();
    
        T_DBG <<QThread::currentThread();
        if(cam.isNull()){
            T_ERR <<"no usb cam";
            goto fail;
        }
        m_camera = new QCamera(cam);
        m_captureSession.setCamera(m_camera);
        m_imageCapture = new QImageCapture;
        m_captureSession.setImageCapture(m_imageCapture);
        connect(m_imageCapture,&QImageCapture::imageCaptured,this,[=](int id,const QImage &i){
            emit sigImageReady(i);
        });
        connect(m_imageCapture,&QImageCapture::readyForCaptureChanged,this,[=](bool ready){
            if(ready){
                m_imageCapture->capture();
                //qDebug()<<"ready";
            }
        });
        emit sigErrorReport("openCamOk");
        T_DBG <<"start capture";
        m_camera->start();
        goto end;
    
    fail:
        emit sigErrorReport("openCamFail");
    end:
        T_DBG <<"start cap end";
    }
    
    void CamOperator::stop()
    {
        if(m_camera){
            m_camera->stop();
            disconnect(m_imageCapture);
            delete m_imageCapture;
            delete m_camera;
            m_camera = nullptr;
        }
        emit sigErrorReport("camClosed");
        T_DBG <<"stop end";
    }
    
    
    #ifndef CAMOPERATOR_H
    #define CAMOPERATOR_H
    
    #include <QThread>
    #include <QCamera>
    #include <QImageCapture>
    #include <QCameraDevice>
    #include <QMediaDevices>
    #include <QMediaCaptureSession>
    
    class ICameraWrapper;
    class CamOperator : public QObject
    {
        Q_OBJECT
    public:
        explicit CamOperator(QObject *parent = nullptr);
        ~CamOperator();
    
    signals:
        void sigErrorReport(const QString &);
        void sigImageReady(const QImage &);
    
    public slots:
        void run();
        void stop();
    
    private:
        QString m_camType;
        QCamera *m_camera{};
        QImageCapture *m_imageCapture;
        QMediaCaptureSession m_captureSession;
        QThread m_bgThread;
    };
    
    #endif // CAMOPERATOR_H
    
    
    Christian EhrlicherC 1 Reply Last reply
    0
    • Q QtTester

      hey guys.
      6.9.3+vs2022.
      I wanna capture a usb cam video. it works find but the thread for capturing cannot be stop.
      when I exit the app, thread.wait() cannot return after runing run() function ,even i already run stop().
      If I donot do anything , wait() works fine and can return.
      why wait() cannot return?

      mainwindow.cpp, two button, one for start , another for stop:

      #include "mainwindow.h"
      #include "ui_mainwindow.h"
      
      #include <QCamera>
      #include <QDebug>
      #include <QCameraDevice>
      #include <QMediaDevices>
      
      MainWindow::MainWindow(QWidget *parent)
          : QMainWindow(parent)
          , ui(new Ui::MainWindow)
      {
          ui->setupUi(this);
          connect(this,&MainWindow::sigStart,&m_cam,&CamOperator::run);
          connect(this,&MainWindow::sigStop,&m_cam,&CamOperator::stop);
      
          //
          qDebug() <<"ui:"<<QThread::currentThread();
      }
      
      MainWindow::~MainWindow()
      {
          delete ui;
      }
      
      void MainWindow::on_pushButton_clicked()
      {
          emit sigStart();
      }
      
      void MainWindow::on_pushButton_2_clicked()
      {
          emit sigStop();
      }
      
      

      wrapper for qcamera:

      #include "camoperator.h"
      #include <QDebug>
      #include <QImage>
      #include <QDateTime>
      #include <QTimer>
      
      #define T_DBG qDebug()
      #define T_ERR qDebug()
      
      CamOperator::CamOperator(QObject *parent)
          : QObject{parent}
      {
          moveToThread(&m_bgThread);
          m_bgThread.start();
      }
      
      CamOperator::~CamOperator()
      {
          stop();
      
          if(m_bgThread.isRunning()){
              T_DBG<<"stop cam...";
              m_bgThread.requestInterruption();
              m_bgThread.quit();
              if(1){
                  T_DBG<<"wait thread end...";
      
                  // 3000 right here, after run(), it cannot return anymore.
                  m_bgThread.wait();
              }
              T_DBG<<"thred end";
          }
      
      }
      
      void CamOperator::run()
      {
          auto cam = QMediaDevices::defaultVideoInput();
      
          T_DBG <<QThread::currentThread();
          if(cam.isNull()){
              T_ERR <<"no usb cam";
              goto fail;
          }
          m_camera = new QCamera(cam);
          m_captureSession.setCamera(m_camera);
          m_imageCapture = new QImageCapture;
          m_captureSession.setImageCapture(m_imageCapture);
          connect(m_imageCapture,&QImageCapture::imageCaptured,this,[=](int id,const QImage &i){
              emit sigImageReady(i);
          });
          connect(m_imageCapture,&QImageCapture::readyForCaptureChanged,this,[=](bool ready){
              if(ready){
                  m_imageCapture->capture();
                  //qDebug()<<"ready";
              }
          });
          emit sigErrorReport("openCamOk");
          T_DBG <<"start capture";
          m_camera->start();
          goto end;
      
      fail:
          emit sigErrorReport("openCamFail");
      end:
          T_DBG <<"start cap end";
      }
      
      void CamOperator::stop()
      {
          if(m_camera){
              m_camera->stop();
              disconnect(m_imageCapture);
              delete m_imageCapture;
              delete m_camera;
              m_camera = nullptr;
          }
          emit sigErrorReport("camClosed");
          T_DBG <<"stop end";
      }
      
      
      #ifndef CAMOPERATOR_H
      #define CAMOPERATOR_H
      
      #include <QThread>
      #include <QCamera>
      #include <QImageCapture>
      #include <QCameraDevice>
      #include <QMediaDevices>
      #include <QMediaCaptureSession>
      
      class ICameraWrapper;
      class CamOperator : public QObject
      {
          Q_OBJECT
      public:
          explicit CamOperator(QObject *parent = nullptr);
          ~CamOperator();
      
      signals:
          void sigErrorReport(const QString &);
          void sigImageReady(const QImage &);
      
      public slots:
          void run();
          void stop();
      
      private:
          QString m_camType;
          QCamera *m_camera{};
          QImageCapture *m_imageCapture;
          QMediaCaptureSession m_captureSession;
          QThread m_bgThread;
      };
      
      #endif // CAMOPERATOR_H
      
      
      Christian EhrlicherC Offline
      Christian EhrlicherC Offline
      Christian Ehrlicher
      Lifetime Qt Champion
      wrote last edited by
      #2

      @QtTester said in QThread cannot be stop after QCamera->start():

      m_captureSession

      This lives in the wrong thread since you don't pass a parent.
      Why a thread at all? Please follow the official examples when you really want a thread here.

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

      Q 1 Reply Last reply
      1
      • Christian EhrlicherC Christian Ehrlicher

        @QtTester said in QThread cannot be stop after QCamera->start():

        m_captureSession

        This lives in the wrong thread since you don't pass a parent.
        Why a thread at all? Please follow the official examples when you really want a thread here.

        Q Offline
        Q Offline
        QtTester
        wrote last edited by
        #3

        @Christian-Ehrlicher
        thanks for replying.
        I have not found any thread programing for QCamera/QMediaCaptureSession,
        the example in Examples\Qt-6.9.3\multimedia\camera\ use UI thread ?
        can you suggest some web-link?

        Pl45m4P jsulmJ 2 Replies Last reply
        0
        • Q QtTester

          @Christian-Ehrlicher
          thanks for replying.
          I have not found any thread programing for QCamera/QMediaCaptureSession,
          the example in Examples\Qt-6.9.3\multimedia\camera\ use UI thread ?
          can you suggest some web-link?

          Pl45m4P Offline
          Pl45m4P Offline
          Pl45m4
          wrote last edited by
          #4

          @QtTester said in QThread cannot be stop after QCamera->start():

          I have not found any thread programing for QCamera/QMediaCaptureSession,

          It's not dedicated to QCamera only. I think @Christian-Ehrlicher was referring to the general Qt Multithreading examples and documentation

          • https://doc.qt.io/qt-6/threads-technologies.html
          • https://doc.qt.io/qt-6/examples-threadandconcurrent.html

          If debugging is the process of removing software bugs, then programming must be the process of putting them in.

          ~E. W. Dijkstra

          1 Reply Last reply
          0
          • Q QtTester

            @Christian-Ehrlicher
            thanks for replying.
            I have not found any thread programing for QCamera/QMediaCaptureSession,
            the example in Examples\Qt-6.9.3\multimedia\camera\ use UI thread ?
            can you suggest some web-link?

            jsulmJ Offline
            jsulmJ Offline
            jsulm
            Lifetime Qt Champion
            wrote last edited by
            #5

            @QtTester And the question is: why do you need a thread?

            https://forum.qt.io/topic/113070/qt-code-of-conduct

            Q 1 Reply Last reply
            1
            • jsulmJ jsulm

              @QtTester And the question is: why do you need a thread?

              Q Offline
              Q Offline
              QtTester
              wrote last edited by
              #6

              @jsulm for not stucking the UI? I donot know whether it is appropriate to use a thread.

              JKSHJ 1 Reply Last reply
              0
              • Q QtTester

                @jsulm for not stucking the UI? I donot know whether it is appropriate to use a thread.

                JKSHJ Offline
                JKSHJ Offline
                JKSH
                Moderators
                wrote last edited by
                #7

                @QtTester said in QThread cannot be stop after QCamera->start():

                @jsulm for not stucking the UI? I donot know whether it is appropriate to use a thread.

                Please run and study the official Camera Example: https://doc.qt.io/qt-6/qtmultimedia-camera-example.html

                It shows that you don't need threads -- QCamera/QMediaCaptureSession does not block the UI.

                Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

                Q 1 Reply Last reply
                2
                • JKSHJ JKSH

                  @QtTester said in QThread cannot be stop after QCamera->start():

                  @jsulm for not stucking the UI? I donot know whether it is appropriate to use a thread.

                  Please run and study the official Camera Example: https://doc.qt.io/qt-6/qtmultimedia-camera-example.html

                  It shows that you don't need threads -- QCamera/QMediaCaptureSession does not block the UI.

                  Q Offline
                  Q Offline
                  QtTester
                  wrote last edited by
                  #8

                  @JKSH I read the code.
                  but what I am curious is : why qthread.wait() not return after qcamera.start() ?

                  Christian EhrlicherC 1 Reply Last reply
                  0
                  • Q QtTester

                    @JKSH I read the code.
                    but what I am curious is : why qthread.wait() not return after qcamera.start() ?

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

                    @QtTester said in QThread cannot be stop after QCamera->start():

                    why qthread.wait() not return after qcamera.start()

                    I already told you what you might did wrong

                    m_captureSession
                    

                    This lives in the wrong thread since you don't pass a parent.

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

                    Q 1 Reply Last reply
                    0
                    • Christian EhrlicherC Christian Ehrlicher

                      @QtTester said in QThread cannot be stop after QCamera->start():

                      why qthread.wait() not return after qcamera.start()

                      I already told you what you might did wrong

                      m_captureSession
                      

                      This lives in the wrong thread since you don't pass a parent.

                      Q Offline
                      Q Offline
                      QtTester
                      wrote last edited by
                      #10

                      @Christian-Ehrlicher
                      if i donot new the class, wait() works fine, event i call qcamera.start():

                      void CamOperator::run()
                      {
                          auto cam = QMediaDevices::defaultVideoInput();
                      
                          T_DBG <<QThread::currentThread();
                          if(cam.isNull()){
                              T_ERR <<"no usb cam";
                              goto fail;
                          }
                      
                          m_camera.setCameraDevice(cam);
                          m_captureSession.setCamera(&m_camera);
                          m_captureSession.setImageCapture(&m_imageCapture);
                          m_captureSession.setVideoSink(&m_vs);
                          connect(&m_imageCapture,&QImageCapture::imageCaptured,this,[=](int id,const QImage &i){
                              emit sigImageReady(i);
                          });
                          connect(&m_vs, &QVideoSink::videoFrameChanged, [&]( const QVideoFrame &frame ) {
                              m_imageCapture.capture();
                          });
                          emit sigErrorReport("openCamOk");
                          T_DBG <<"start capture";
                          m_camera.start();
                          goto end;
                      
                      fail:
                          emit sigErrorReport("openCamFail");
                      end:
                          T_DBG <<"start cap end";
                      }
                      

                      but if i new the class and pass parent,wait() won't return anymore, why the parent will stuck it?:

                      void CamOperator::run()
                      {
                          auto cam = QMediaDevices::defaultVideoInput();
                      
                          T_DBG <<QThread::currentThread();
                          if(cam.isNull()){
                              T_ERR <<"no usb cam";
                              goto fail;
                          }
                      
                          m_camera = new QCamera(cam,this);
                          m_camera->setCameraDevice(cam);
                          m_captureSession = new QMediaCaptureSession(this);
                          m_captureSession->setCamera(m_camera);
                          m_imageCapture = new QImageCapture(this);
                          m_captureSession->setImageCapture(m_imageCapture);
                          m_captureSession->setVideoSink(&m_vs);
                          connect(m_imageCapture,&QImageCapture::imageCaptured,this,[=](int id,const QImage &i){
                              emit sigImageReady(i);
                              //qDebug()<<"cap:"<<QThread::currentThread();
                          });
                          connect(&m_vs, &QVideoSink::videoFrameChanged, [&]( const QVideoFrame &frame ) {
                              m_imageCapture->capture();
                          });
                          emit sigErrorReport("openCamOk");
                          T_DBG <<"start capture";
                          m_camera->start();
                          goto end;
                      
                      fail:
                          emit sigErrorReport("openCamFail");
                      end:
                          T_DBG <<"start cap end";
                      }
                      
                      Pl45m4P 1 Reply Last reply
                      0
                      • Q QtTester

                        @Christian-Ehrlicher
                        if i donot new the class, wait() works fine, event i call qcamera.start():

                        void CamOperator::run()
                        {
                            auto cam = QMediaDevices::defaultVideoInput();
                        
                            T_DBG <<QThread::currentThread();
                            if(cam.isNull()){
                                T_ERR <<"no usb cam";
                                goto fail;
                            }
                        
                            m_camera.setCameraDevice(cam);
                            m_captureSession.setCamera(&m_camera);
                            m_captureSession.setImageCapture(&m_imageCapture);
                            m_captureSession.setVideoSink(&m_vs);
                            connect(&m_imageCapture,&QImageCapture::imageCaptured,this,[=](int id,const QImage &i){
                                emit sigImageReady(i);
                            });
                            connect(&m_vs, &QVideoSink::videoFrameChanged, [&]( const QVideoFrame &frame ) {
                                m_imageCapture.capture();
                            });
                            emit sigErrorReport("openCamOk");
                            T_DBG <<"start capture";
                            m_camera.start();
                            goto end;
                        
                        fail:
                            emit sigErrorReport("openCamFail");
                        end:
                            T_DBG <<"start cap end";
                        }
                        

                        but if i new the class and pass parent,wait() won't return anymore, why the parent will stuck it?:

                        void CamOperator::run()
                        {
                            auto cam = QMediaDevices::defaultVideoInput();
                        
                            T_DBG <<QThread::currentThread();
                            if(cam.isNull()){
                                T_ERR <<"no usb cam";
                                goto fail;
                            }
                        
                            m_camera = new QCamera(cam,this);
                            m_camera->setCameraDevice(cam);
                            m_captureSession = new QMediaCaptureSession(this);
                            m_captureSession->setCamera(m_camera);
                            m_imageCapture = new QImageCapture(this);
                            m_captureSession->setImageCapture(m_imageCapture);
                            m_captureSession->setVideoSink(&m_vs);
                            connect(m_imageCapture,&QImageCapture::imageCaptured,this,[=](int id,const QImage &i){
                                emit sigImageReady(i);
                                //qDebug()<<"cap:"<<QThread::currentThread();
                            });
                            connect(&m_vs, &QVideoSink::videoFrameChanged, [&]( const QVideoFrame &frame ) {
                                m_imageCapture->capture();
                            });
                            emit sigErrorReport("openCamOk");
                            T_DBG <<"start capture";
                            m_camera->start();
                            goto end;
                        
                        fail:
                            emit sigErrorReport("openCamFail");
                        end:
                            T_DBG <<"start cap end";
                        }
                        
                        Pl45m4P Offline
                        Pl45m4P Offline
                        Pl45m4
                        wrote last edited by Pl45m4
                        #11

                        @QtTester

                        I also don't understand why you are using ugly GOTO statements?!
                        They are bad in 99.9% of all situations, especially in event driven programs. While there are some extremly niche use cases to use them at all, yours is not one of them.

                        Just put the fail code where your jump instruction is... emit the signal and return.
                        Then you also don't need to jump to some end.


                        If debugging is the process of removing software bugs, then programming must be the process of putting them in.

                        ~E. W. Dijkstra

                        1 Reply Last reply
                        1

                        • Login

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