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
10 Posts 5 Posters 121 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 Online
    Q Online
    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 Online
        Q Online
        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 Online
              Q Online
              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
                1
                • 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 Online
                  Q Online
                  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 Online
                      Q Online
                      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";
                      }
                      
                      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