QThread interesting problem. Threads stop each other
-
I have below codes and two video stream produce frame and send back to mainwindow with signalling.
according to received signal and stream ID its sending the face detector and receiving the edited frame(box drawed).
Each frame work perfecly when I click the button. But when other stream thread requested the work , working thread stopping.
Only one Label pix updated other one is freezing.
I m really confused and cant solve the issue. Any help appriciated.
mainwindow.cpp
#include "mainwindow.h" #include "ui_mainwindow.h" #include <QDebug> #include "cvmatconverter.h" #include <QMessageBox> #include <QCloseEvent> // Include the QCloseEvent header MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) { ui->setupUi(this); //***THREADS**// thread_gstShowsources = new QThread; gstshowframe = new GstShowFrame; gstshowframe->moveToThread (thread_gstShowsources); thread_gstShowsources->start(); thread_stream_2 = new QThread; stream_2 = new Stream_2; stream_2->moveToThread(thread_stream_2); thread_stream_2->start(); thread_zmqreceiver = new QThread; zmqreceiver = new ZmqReceiver; zmqreceiver->moveToThread (thread_zmqreceiver); thread_zmqreceiver->start(); thread_faceDetector = new QThread; facedetector_scrfd = new FaceDetector; facedetector_scrfd->moveToThread(thread_faceDetector); thread_faceDetector->start(); QCoreApplication::processEvents(); //TOOLS //*** SIGNALS ** // connect (gstshowframe, &GstShowFrame::signal_1_frameChanged , this , &MainWindow::processFacesScrfd ); connect (stream_2, &Stream_2::signal_stream_2_frameChanged, this, &MainWindow::processFacesScrfd_2 ); //connect(zmqreceiver , &ZmqReceiver::sig_zmessagereceived , this , &MainWindow::update_zmqFrame_1); connect(facedetector_scrfd, &FaceDetector::frameScrfdProcessed, this, &MainWindow::update_frame_1); connect(facedetector_scrfd, &FaceDetector::frameScrfdProcessed_2, this, &MainWindow::update_frame_2); // Connect the started() signal connect(thread_gstShowsources, &QThread::started, this, []() { qDebug() << "Thread started******************************"; }); // Connect the finished() signal connect(thread_gstShowsources, &QThread::finished, this, []() { qDebug() << "*************************************Thread finished"; }); // Connect the terminated() signal connect(thread_gstShowsources, &QThread::destroyed, this, []() { qDebug() << "Thread terminated***************************"; }); } MainWindow::~MainWindow() { delete ui; } void MainWindow::closeEvent(QCloseEvent *event) { thread_gstShowsources->exit(); thread_zmqreceiver->exit(); thread_faceDetector->exit(); event->accept(); } void MainWindow::on_pushButton_clicked() { qDebug() << " src_1 aşlatıyorum" << Qt::endl; gstshowframe->requestWork (1 ,"/data/tappas_2023_4/shared_with_docker/caddebgdt_1min.mp4"); } void MainWindow::update_frame_1(int stream_id, cv::Mat &frame) { //qDebug() << "Updating label for stream " << stream_id << Qt::endl; if (stream_id == 1) { ui->label_src_1->setPixmap(ASM::cvMatToQPixmap(frame)); } else if (stream_id == 2) { ui->label_src_2->setPixmap(ASM::cvMatToQPixmap(frame)); } //ui->label_src_1->setPixmap(ASM::cvMatToQPixmap(frame)); qApp->processEvents(); } void MainWindow::update_zmqFrame_1(QImage image) { ui->label_src_2->setPixmap (QPixmap::fromImage(image.rgbSwapped())); qApp->processEvents (); } void MainWindow::on_pushButton_zmqStart_clicked() { qDebug() << " src_1 başlatıyorum" << Qt::endl; //gstshowframe_2->requestWork (2 ,"/data/tappas_2023_4/shared_with_docker/caddebgdt_1min.mp4");} } void MainWindow::on_pushButton_2_clicked() { stream_2->requestWork_2 (2 ,"/cadde2min_720p_2min.mp4"); } void MainWindow::processFacesScrfd(int stream_id , cv::Mat frame) { //qDebug() << "Sending scf to faceDetector" << Qt::endl; facedetector_scrfd->ProcessFrameFaces( stream_id , frame); } void MainWindow::processFacesScrfd_2(int stream_id , cv::Mat frame) { //qDebug() << "Sending scf to faceDetector" << Qt::endl; facedetector_scrfd->ProcessFrameFaces( stream_id , frame); } void MainWindow::update_frame_2(int stream_id, cv::Mat &frame) { switch (stream_id) { case 1: // Handle label_src_1 updates ui->label_src_1->setPixmap(ASM::cvMatToQPixmap(frame)); break; case 2: // Handle label_src_2 updates ui->label_src_2->setPixmap(ASM::cvMatToQPixmap(frame)); break; default: // Handle unhandled stream_id values break; } qApp->processEvents(); }
//----------------------------------------------- //----------------------------------------------- #include "facedetector.h" #include <chrono> #include <QFile> FaceDetector::FaceDetector(QObject *parent) : QObject(parent) { onnx_path = "/data/uiFilTest/assets/scrfd_10g_kps.onnx"; //QFile file(onnx_path); scrfd = new lite::cv::face::detect::SCRFD(onnx_path); } void FaceDetector::ProcessFrameFaces(int stream_id , cv::Mat &frame) { // Record the time before face detection auto iteration_start_time = std::chrono::high_resolution_clock::now(); std::vector<alp::types::BoxfWithLandmarks> detected_boxes; scrfd->detect(frame, detected_boxes); // Record the time after face detection auto iteration_end_time = std::chrono::high_resolution_clock::now(); auto elapsed_time_ms = std::chrono::duration_cast<std::chrono::milliseconds>( iteration_end_time - iteration_start_time) .count(); // Draw bounding boxes and landmarks lite::utils::draw_boxes_with_landmarks_inplace(frame, detected_boxes); if (stream_id == 1) { emit frameScrfdProcessed(stream_id, frame); } else if (stream_id == 2) { emit frameScrfdProcessed(stream_id, frame); } emit frameScrfdProcessed(stream_id , frame); }
#include "gstshowframe.h" #include "QtCore/qcoreapplication.h" #include <QDebug> #include <QImage> #include <QThread> GstShowFrame::GstShowFrame(QObject *parent) : QObject{parent} { } void GstShowFrame::requestWork(int stream_id , std::string stream) { qDebug() << "start video" << Qt::endl; startWork(stream_id , stream); } void GstShowFrame::startWork(int stream_id , const std::string stream = "/caddebgdt_1min.mp4") { cap_1.open(stream); if (!cap_1.isOpened()) { qDebug() << "Error opening video sources"; } qDebug() << "video Okundu - " << stream_id << Qt::endl; qDebug() << "Thread ID:" << QThread::currentThreadId() << "Processing frame for stream:" << stream_id; cv::Mat frame; // QTimer timer; while (!_abort) { cap_1 >> frame; // QImage image(frame.data, frame.cols, frame.rows, frame.step, // QImage::Format_RGB888); emit signal_1_frameChanged(stream_id , frame); // qDebug() << "Thread ID:" << QThread::currentThreadId() << " signal emited -> stream " << stream_id<< Qt::endl; }; }
//----------------------------------------------- //----------------------------------------------- #include "stream_2.h" #include "QtCore/qcoreapplication.h" #include <QDebug> #include <QImage> #include <QThread> Stream_2::Stream_2(QObject *parent) : QObject(parent) {} void Stream_2::requestWork_2(int stream_id, std::string stream) { qDebug() << "stream_2 started " << Qt::endl; startWork(stream_id, stream); } void Stream_2::startWork(int stream_id, const std::string stream) { cap_2.open(stream); if (!cap_2.isOpened()) { qDebug() << "Error opening video sources"; _abort = true; } qDebug() << "video Okundu - " << stream_id << Qt::endl; qDebug() << "Thread ID:" << QThread::currentThreadId() << "Processing frame for stream:" << stream_id; cv::Mat frame; // QTimer timer; while (!_abort) { cap_2 >> frame; emit signal_stream_2_frameChanged(stream_id, frame); } }
-
no one interested ?
-
@RahibeMeryem said in QThread interesting problem. Threads stop each other:
no one interested
No, please ask a different question ;-)
JK, just wait a litte more for people to answer... it's weekend and this topic was created less than 24h ago.
What I've noticed:
Why you setQt::DirectConnection
when connecting signals to yourfacedetector
, which was moved to a different thread before? -
@RahibeMeryem
Don't know about your whole program, it's not minimal. But when I notice- Using
processEvents()
, in multiple places. while (!_abort) ... emit signal...()
potential flooding with signals
those both concern me initially.
- Using