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. OpenCV VideoCapture Failure from QThread
QtWS25 Last Chance

OpenCV VideoCapture Failure from QThread

Scheduled Pinned Locked Moved Solved General and Desktop
opencvvideocaptureqthreadcrashgui
22 Posts 4 Posters 7.6k 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.
  • R Offline
    R Offline
    rtavakko
    wrote on 15 Jun 2019, 21:43 last edited by
    #1

    Hi guys,

    I'm having a bit of a problem opening and reading video files using OpenCV's VideoCapture object from a QThread.

    If the two VideoCaptures are moved to the main GUI thread, I can use a QTimer to read frames every millisecond with no issues whatsoever.

    If placed in a QThread, I can open video files before the thread starts but once it is started, I get crashes with the message below:

    The program has unexpectedly finished.
    The process was ended forcefully.
    C:/Users/Roham/Documents/build-VidCap-Desktop_Qt_5_11_3_MinGW_32bit-Debug/debug/VidCap.exe crashed.

    The QThread run() function is written this way:

    while(true)
        {
            for(int i = 0; i < 2; i++)
            {
                if(!video[i].isOpened())
                {
                    video[i].release();
                }
                else
                {
                    if(!video[i].read(testMat[i]))
                    {
                        video[i].release();
                    }
                    else
                    {
                        cv::cvtColor(testMat[i],testMat[i],cv::COLOR_BGR2RGB);
                        imgOut[i] = QImage((uchar*)(testMat[i].data),testMat[i].cols,testMat[i].rows, QImage::Format_RGB888);
                        emit processedImage(i,imgOut[i]);
                    }
                }
            }
        }
    

    I use buttons from my form to trigger the file change event from the main GUI thread. The buttons end up calling this function in the QThread:

    void Test::load(const int &vid, const int &file)
    {
        switch(file)
        {
            case 0:
                video[vid].open(QDir::currentPath().toStdString()+"/vid0.mp4",cv::CAP_ANY);
                break;
            case 1:
                video[vid].open(QDir::currentPath().toStdString()+"/vid1.mp4",cv::CAP_ANY);
                break;
            case 2:
                video[vid].open(QDir::currentPath().toStdString()+"/vid2.mp4",cv::CAP_ANY);
                break;
        }
    }
    

    Is there something else I should be doing? Like stopping the thread temporarily when loading a new file? I've come across a couple of posts from others with the same issue, but it makes no sense to me why this would happen.

    Thanks!

    1 Reply Last reply
    0
    • S Offline
      S Offline
      SGaist
      Lifetime Qt Champion
      wrote on 16 Jun 2019, 21:15 last edited by
      #2

      Hi,

      Are you subclassing QThread ?

      Interested in AI ? www.idiap.ch
      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

      R 1 Reply Last reply 21 Jun 2019, 22:58
      1
      • S SGaist
        16 Jun 2019, 21:15

        Hi,

        Are you subclassing QThread ?

        R Offline
        R Offline
        rtavakko
        wrote on 21 Jun 2019, 22:58 last edited by rtavakko
        #3

        @SGaist Yes I am. I've been told this is not the correct way to use QThreads but other say its just a matter of choice. Should I try passing a QObject to a thread instead?

        Its worth mentioning that the problem is narrowed down to the .read() method of VideoCapture. Loading doesn't cause a crash. I tried using a lock and mutex right before reading a frame which seems to avoid a crash but the .read() method still hangs. Using mutex alone (locked before read, unlocked after) causes a crash as before.

        J 1 Reply Last reply 22 Jun 2019, 01:42
        0
        • R rtavakko
          21 Jun 2019, 22:58

          @SGaist Yes I am. I've been told this is not the correct way to use QThreads but other say its just a matter of choice. Should I try passing a QObject to a thread instead?

          Its worth mentioning that the problem is narrowed down to the .read() method of VideoCapture. Loading doesn't cause a crash. I tried using a lock and mutex right before reading a frame which seems to avoid a crash but the .read() method still hangs. Using mutex alone (locked before read, unlocked after) causes a crash as before.

          J Offline
          J Offline
          JKSH
          Moderators
          wrote on 22 Jun 2019, 01:42 last edited by
          #4

          @rtavakko said in OpenCV VideoCapture Failure from QThread:

          I've been told this is not the correct way to use QThreads but other say its just a matter of choice.

          Subclassing QThreads is a valid approach, but you must do it correctly.

          Anyway, it sounds like you are calling VideoCapture methods from multiple threads. Is that class thread-safe? Do you know if you are allowed to call its methods from multiple threads?

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

          R 1 Reply Last reply 22 Jun 2019, 04:09
          3
          • J JKSH
            22 Jun 2019, 01:42

            @rtavakko said in OpenCV VideoCapture Failure from QThread:

            I've been told this is not the correct way to use QThreads but other say its just a matter of choice.

            Subclassing QThreads is a valid approach, but you must do it correctly.

            Anyway, it sounds like you are calling VideoCapture methods from multiple threads. Is that class thread-safe? Do you know if you are allowed to call its methods from multiple threads?

            R Offline
            R Offline
            rtavakko
            wrote on 22 Jun 2019, 04:09 last edited by
            #5

            @JKSH I override the run function of the subclassed QThread object. I only call VideoCapture methods from a single QThread. These aren't thread-safe from what I've read online but even so I shouldn't have an issue if accessing them from one thread only unless there's something going on in the background that I don't know.

            The issue is that if I move the VideoCaptures to the main thread, the issue is fixed but I get crashes when they are part of the QThread.

            J 1 Reply Last reply 22 Jun 2019, 06:04
            0
            • R rtavakko
              22 Jun 2019, 04:09

              @JKSH I override the run function of the subclassed QThread object. I only call VideoCapture methods from a single QThread. These aren't thread-safe from what I've read online but even so I shouldn't have an issue if accessing them from one thread only unless there's something going on in the background that I don't know.

              The issue is that if I move the VideoCaptures to the main thread, the issue is fixed but I get crashes when they are part of the QThread.

              J Offline
              J Offline
              JKSH
              Moderators
              wrote on 22 Jun 2019, 06:04 last edited by
              #6

              @rtavakko said in OpenCV VideoCapture Failure from QThread:

              I only call VideoCapture methods from a single QThread.

              Important note: Just because you call something from within a QThread method, that does not mean the code runs in the related thread!

              Earlier, you said

              The buttons end up calling this function in the QThread:

              Well, Test::load() is running in the main thread, not your other thread.

              If you want to verify this yourself, add qDebug() << QThread::currentThread() into the top of main(), the top of your run() function, and the top of Test::load(). This will show you which thread is running each function.

              Read the QThread documentation carefully: https://doc.qt.io/qt-5/qthread.html. It says, "...a developer who wishes to invoke slots in the new thread must use the worker-object approach; new slots should not be implemented directly into a subclassed QThread.

              When you reimplemented QThread::run(), you used an infinite loop (while (true)). This means your thread does not have an event loop, which means you cannot "trigger" anything in that thread.

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

              R 1 Reply Last reply 22 Jun 2019, 19:25
              4
              • J JKSH
                22 Jun 2019, 06:04

                @rtavakko said in OpenCV VideoCapture Failure from QThread:

                I only call VideoCapture methods from a single QThread.

                Important note: Just because you call something from within a QThread method, that does not mean the code runs in the related thread!

                Earlier, you said

                The buttons end up calling this function in the QThread:

                Well, Test::load() is running in the main thread, not your other thread.

                If you want to verify this yourself, add qDebug() << QThread::currentThread() into the top of main(), the top of your run() function, and the top of Test::load(). This will show you which thread is running each function.

                Read the QThread documentation carefully: https://doc.qt.io/qt-5/qthread.html. It says, "...a developer who wishes to invoke slots in the new thread must use the worker-object approach; new slots should not be implemented directly into a subclassed QThread.

                When you reimplemented QThread::run(), you used an infinite loop (while (true)). This means your thread does not have an event loop, which means you cannot "trigger" anything in that thread.

                R Offline
                R Offline
                rtavakko
                wrote on 22 Jun 2019, 19:25 last edited by rtavakko
                #7

                @JKSH Thanks for the explanation. When a GUI button is pressed the thread is QThread(0x1922e9b0) and when the Test::load() is called, the thread is Test(0x197ded38) which is a bit confusing in terms of the names but looks like they are separate. I'm going to switch to what the documentation outlines and get back with the results.
                On this note, how do I re-implement the event loop or make the thread continuously run without overriding the run() functions?

                1 Reply Last reply
                0
                • Christian EhrlicherC Offline
                  Christian EhrlicherC Offline
                  Christian Ehrlicher
                  Lifetime Qt Champion
                  wrote on 22 Jun 2019, 21:24 last edited by
                  #8

                  @rtavakko said in OpenCV VideoCapture Failure from QThread:

                  On this note, how do I re-implement the event loop or make the thread continuously run without overriding the run() functions?

                  See the docs: https://doc.qt.io/qt-5/qthread.html#run

                  "... The default implementation simply calls exec()."

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

                  1 Reply Last reply
                  3
                  • R Offline
                    R Offline
                    rtavakko
                    wrote on 29 Jun 2019, 00:07 last edited by
                    #9

                    @JKSH I went back and noticed I had the qDebug() statement in the wrong place. You were correct about which thread a called method runs in. If the main thread calls a method in another thread, that method still runs in the main thread as the documentation says.

                    The issue was related to thread-safety as you suggested. Its also important to make sure we are not reading from a VideoCapture device that is in the process of loading a new video.

                    Here are my 'read' / 'load' methods for anyone having issues with this:

                    void Test::load(const int &vid, const int &file)
                    {
                        QMutexLocker lock(&mutex);
                    
                        loading[vid] = true;
                    
                        switch(file)
                        {
                            case 0:
                                loadFlag[vid] = video[vid].open(QDir::currentPath().toStdString()+"/vid0.mp4",cv::CAP_ANY);
                                break;
                            case 1:
                                loadFlag[vid] = video[vid].open(QDir::currentPath().toStdString()+"/vid1.mp4",cv::CAP_ANY);
                                break;
                            case 2:
                                loadFlag[vid] = video[vid].open(QDir::currentPath().toStdString()+"/vid2.mp4",cv::CAP_ANY);
                                break;
                        }
                        loading[vid] = false;
                    }
                    
                    bool Test::read(const int &vid)
                    {
                        loadFlag[vid] = video[vid].isOpened();
                    
                        if(!loadFlag)
                        {
                            video[vid].release();
                            return false;
                        }
                        else
                        {
                            QMutexLocker locker(&mutex);
                            readFlag[vid] = video[vid].read(readMat[vid]);
                    
                            if(!readFlag[vid])
                            {
                                video[vid].release();
                                return readFlag[vid];
                            }
                            else
                            {
                                if(!readMat[vid].empty())
                                {
                                    cv::cvtColor(readMat[vid],readMat[vid],cv::COLOR_BGR2RGB);
                                    imgOut[vid] = QImage(readMat[vid].data, readMat[vid].cols, readMat[vid].rows, QImage::Format_RGB888);
                                    return true;
                                }
                            }
                        }
                    }
                    

                    Also the run method in the QThread object:

                    void Test::run()
                    {
                        while(true)
                        {
                            for(int i = 0; i < 2; i++)
                            {
                                if(!loading[i])
                                {
                                    bool tmp = this->read(i);
                                    if(tmp)
                                    {
                                        emit processedImage(i,imgOut[i]);
                                    }
                                    else
                                    {
                                        //SH*T HAPPENED
                                    }
                                }
                            }
                        }
                    }
                    

                    I'm still a bit confused about where exec() would come in, the documentation is a little hazy to me. Any SAFE threads you guys could reference that clears up how I need to implement run() and exec() together?

                    Thanks a lot for all of your help with this. Much appreciated!

                    J 1 Reply Last reply 29 Jun 2019, 03:13
                    0
                    • R rtavakko
                      29 Jun 2019, 00:07

                      @JKSH I went back and noticed I had the qDebug() statement in the wrong place. You were correct about which thread a called method runs in. If the main thread calls a method in another thread, that method still runs in the main thread as the documentation says.

                      The issue was related to thread-safety as you suggested. Its also important to make sure we are not reading from a VideoCapture device that is in the process of loading a new video.

                      Here are my 'read' / 'load' methods for anyone having issues with this:

                      void Test::load(const int &vid, const int &file)
                      {
                          QMutexLocker lock(&mutex);
                      
                          loading[vid] = true;
                      
                          switch(file)
                          {
                              case 0:
                                  loadFlag[vid] = video[vid].open(QDir::currentPath().toStdString()+"/vid0.mp4",cv::CAP_ANY);
                                  break;
                              case 1:
                                  loadFlag[vid] = video[vid].open(QDir::currentPath().toStdString()+"/vid1.mp4",cv::CAP_ANY);
                                  break;
                              case 2:
                                  loadFlag[vid] = video[vid].open(QDir::currentPath().toStdString()+"/vid2.mp4",cv::CAP_ANY);
                                  break;
                          }
                          loading[vid] = false;
                      }
                      
                      bool Test::read(const int &vid)
                      {
                          loadFlag[vid] = video[vid].isOpened();
                      
                          if(!loadFlag)
                          {
                              video[vid].release();
                              return false;
                          }
                          else
                          {
                              QMutexLocker locker(&mutex);
                              readFlag[vid] = video[vid].read(readMat[vid]);
                      
                              if(!readFlag[vid])
                              {
                                  video[vid].release();
                                  return readFlag[vid];
                              }
                              else
                              {
                                  if(!readMat[vid].empty())
                                  {
                                      cv::cvtColor(readMat[vid],readMat[vid],cv::COLOR_BGR2RGB);
                                      imgOut[vid] = QImage(readMat[vid].data, readMat[vid].cols, readMat[vid].rows, QImage::Format_RGB888);
                                      return true;
                                  }
                              }
                          }
                      }
                      

                      Also the run method in the QThread object:

                      void Test::run()
                      {
                          while(true)
                          {
                              for(int i = 0; i < 2; i++)
                              {
                                  if(!loading[i])
                                  {
                                      bool tmp = this->read(i);
                                      if(tmp)
                                      {
                                          emit processedImage(i,imgOut[i]);
                                      }
                                      else
                                      {
                                          //SH*T HAPPENED
                                      }
                                  }
                              }
                          }
                      }
                      

                      I'm still a bit confused about where exec() would come in, the documentation is a little hazy to me. Any SAFE threads you guys could reference that clears up how I need to implement run() and exec() together?

                      Thanks a lot for all of your help with this. Much appreciated!

                      J Offline
                      J Offline
                      JKSH
                      Moderators
                      wrote on 29 Jun 2019, 03:13 last edited by JKSH
                      #10

                      @rtavakko said in OpenCV VideoCapture Failure from QThread:

                      I'm still a bit confused about where exec() would come in, the documentation is a little hazy to me. Any SAFE threads you guys could reference that clears up how I need to implement run() and exec() together?

                      The default implementation of QThread::run() is:

                      void QThread::run() {
                          this->exec(); // Starts an event loop in the thread
                      }
                      

                      If you want to reimplement run(), you have 2 options:

                      // Option 1: Run an event loop
                      void MyEventLoopThread::run() {
                          /* Add your custom initialization code here */
                      
                          this->exec(); // Starts an event loop in the thread
                      }
                      
                      // Option 2: Don't run an event loop; manually write an infinite loop
                      void MyPollingLoopThread::run() {
                          /* Add your custom initialization code here */
                      
                          while ( !this->isInterruptionRequested() ) // Starts an infinite loop in the thread
                          {
                              /* Add your custom looping code here */
                          }
                      

                      Notice that Option #1 is just like your main thread:

                      int main(int argc, char **argv) {
                          QApplication app(argc, argv);
                      
                          /* Add your custom initialization code here */
                      
                          app.exec(); // Starts an event loop in the main thread
                      }
                      

                      Finally, Option #1 and Option #2 cannot be combined. Your thread can have either an event loop (exec()) OR a polling loop (while (true)). It cannot have both.

                      • If you choose Option #1, your thread can receive signals.
                      • If you choose Option #2, your thread cannot receive signals.

                      Does this all make sense?

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

                      R 1 Reply Last reply 2 Jul 2019, 18:35
                      4
                      • J JKSH
                        29 Jun 2019, 03:13

                        @rtavakko said in OpenCV VideoCapture Failure from QThread:

                        I'm still a bit confused about where exec() would come in, the documentation is a little hazy to me. Any SAFE threads you guys could reference that clears up how I need to implement run() and exec() together?

                        The default implementation of QThread::run() is:

                        void QThread::run() {
                            this->exec(); // Starts an event loop in the thread
                        }
                        

                        If you want to reimplement run(), you have 2 options:

                        // Option 1: Run an event loop
                        void MyEventLoopThread::run() {
                            /* Add your custom initialization code here */
                        
                            this->exec(); // Starts an event loop in the thread
                        }
                        
                        // Option 2: Don't run an event loop; manually write an infinite loop
                        void MyPollingLoopThread::run() {
                            /* Add your custom initialization code here */
                        
                            while ( !this->isInterruptionRequested() ) // Starts an infinite loop in the thread
                            {
                                /* Add your custom looping code here */
                            }
                        

                        Notice that Option #1 is just like your main thread:

                        int main(int argc, char **argv) {
                            QApplication app(argc, argv);
                        
                            /* Add your custom initialization code here */
                        
                            app.exec(); // Starts an event loop in the main thread
                        }
                        

                        Finally, Option #1 and Option #2 cannot be combined. Your thread can have either an event loop (exec()) OR a polling loop (while (true)). It cannot have both.

                        • If you choose Option #1, your thread can receive signals.
                        • If you choose Option #2, your thread cannot receive signals.

                        Does this all make sense?

                        R Offline
                        R Offline
                        rtavakko
                        wrote on 2 Jul 2019, 18:35 last edited by
                        #11

                        @JKSH Thanks a lot for taking the time to explain. The concept makes sense. After this->exec() is run with the event loop approach, the thread object is listed for deletion and its run() method cannot be called again. Is that correct? If so, then the thread object has to be created every time?

                        J 1 Reply Last reply 3 Jul 2019, 00:04
                        0
                        • R rtavakko
                          2 Jul 2019, 18:35

                          @JKSH Thanks a lot for taking the time to explain. The concept makes sense. After this->exec() is run with the event loop approach, the thread object is listed for deletion and its run() method cannot be called again. Is that correct? If so, then the thread object has to be created every time?

                          J Offline
                          J Offline
                          JKSH
                          Moderators
                          wrote on 3 Jul 2019, 00:04 last edited by
                          #12

                          You're welcome.

                          @rtavakko said in OpenCV VideoCapture Failure from QThread:

                          After this->exec() is run with the event loop approach, the thread object is listed for deletion and its run() method cannot be called again. Is that correct? If so, then the thread object has to be created every time?

                          Nope, exec() does not mark anything for deletion.

                          You can certainly start() and quit() a thread with an event loop multiple times. (Note: Quit does nothing if your thread has no event loop)

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

                          R 1 Reply Last reply 6 Jul 2019, 12:50
                          4
                          • J JKSH
                            3 Jul 2019, 00:04

                            You're welcome.

                            @rtavakko said in OpenCV VideoCapture Failure from QThread:

                            After this->exec() is run with the event loop approach, the thread object is listed for deletion and its run() method cannot be called again. Is that correct? If so, then the thread object has to be created every time?

                            Nope, exec() does not mark anything for deletion.

                            You can certainly start() and quit() a thread with an event loop multiple times. (Note: Quit does nothing if your thread has no event loop)

                            R Offline
                            R Offline
                            rtavakko
                            wrote on 6 Jul 2019, 12:50 last edited by
                            #13

                            @JKSH That makes sense. I'll give that a try. Thanks again!

                            1 Reply Last reply
                            0
                            • R Offline
                              R Offline
                              rtavakko
                              wrote on 9 Nov 2019, 20:27 last edited by rtavakko 11 Sept 2019, 20:28
                              #14

                              Hey guys,

                              I'm still seeing this same crash happen when I load new videos into an OpenCV VideoCapture object. It is a lot less frequent, it happens when I test the GUI loading files quickly one after the other.

                              But what is a bit confusing is that I don't get any details about what goes wrong exactly (reading a few posts with this message I understand this is related to an invalid pointer being accessed somewhere). I've tried puting try / catch statements various places in my code to get something.

                              What I get from QT test when running the same test automatically and the crash happens is something like this:

                              A crash occurred in C:\Users\Roham\Desktop\Lyrha\Modules\build-MorphTest-Desktop_Qt_5_12_0_MinGW_64_bit-Release\release\tst_morphtesttest.exe.
                              Function time: 33587ms Total time: 34304ms
                              
                              Exception address: 0x0000000061b8afac
                              Exception code   : 0xc0000005
                              Nearby symbol    : ZN13QColorProfile8fromSRgbEv
                              
                              Stack:
                              #  1: ZN5QTest15toPrettyUnicodeEPKti() - 0x000000006edc2750
                              #  2: UnhandledExceptionFilter() - 0x00007fff41b0f490
                              #  3: memset() - 0x00007fff447a2fc0
                              #  4: _C_specific_handler() - 0x00007fff4478c640
                              #  5: _chkstk() - 0x00007fff447a10e0
                              #  6: RtlRaiseException() - 0x00007fff44769ef0
                              #  7: KiUserExceptionDispatcher() - 0x00007fff4479fe40
                              #  8: ZN13QColorProfile8fromSRgbEv() - 0x0000000061b1e470
                              #  9: ZN13QVulkanWindow11qt_metacallEN11QMetaObject4CallEiPPv() - 0x0000000061d1c190
                              # 10: ZN13QColorProfile8fromSRgbEv() - 0x0000000061b1e470
                              # 11: ZrsR11QDataStreamR8QPolygon() - 0x0000000061c29620
                              # 12: ZN18QRasterPaintEngine4clipERK11QVectorPathN2Qt13ClipOperationE() - 0x0000000061bd93d0
                              # 13: ZN8QPainter9drawImageERK6QRectFRK6QImageS2_6QFlagsIN2Qt19ImageConversionFlagEE() - 0x0000000061bf2660
                              # 14: Unable to obtain symbol
                              # 15: ZN7QWidget5eventEP6QEvent() - 0x0000000001425ba0
                              # 16: ZN19QApplicationPrivate13notify_helperEP7QObjectP6QEvent() - 0x00000000013e7b70
                              # 17: ZN12QApplication6notifyEP7QObjectP6QEvent() - 0x00000000013ee990
                              # 18: ZN16QCoreApplication20sendSpontaneousEventEP7QObjectP6QEvent() - 0x0000000068a674f0
                              # 19: ZN14QWidgetPrivate14sendPaintEventERK7QRegion() - 0x000000000141e0f0
                              # 20: ZN14QWidgetPrivate10drawWidgetEP12QPaintDeviceRK7QRegionRK6QPointiP8QPainterP19QWidgetBackingStore() - 0x000000000141e150
                              # 21: ZN14QWidgetPrivate22paintSiblingsRecursiveEP12QPaintDeviceRK5QListIP7QObjectEiRK7QRegionRK6QPointiP8QPainterP19QWidgetBackingStore() - 0x000000000141f220
                              # 22: ZN14QWidgetPrivate22paintSiblingsRecursiveEP12QPaintDeviceRK5QListIP7QObjectEiRK7QRegionRK6QPointiP8QPainterP19QWidgetBackingStore() - 0x000000000141f220
                              # 23: ZN14QWidgetPrivate22paintSiblingsRecursiveEP12QPaintDeviceRK5QListIP7QObjectEiRK7QRegionRK6QPointiP8QPainterP19QWidgetBackingStore() - 0x000000000141f220
                              # 24: ZN14QWidgetPrivate22paintSiblingsRecursiveEP12QPaintDeviceRK5QListIP7QObjectEiRK7QRegionRK6QPointiP8QPainterP19QWidgetBackingStore() - 0x000000000141f220
                              # 25: ZN14QWidgetPrivate10drawWidgetEP12QPaintDeviceRK7QRegionRK6QPointiP8QPainterP19QWidgetBackingStore() - 0x000000000141e150
                              # 26: ZN14QWidgetPrivate22paintSiblingsRecursiveEP12QPaintDeviceRK5QListIP7QObjectEiRK7QRegionRK6QPointiP8QPainterP19QWidgetBackingStore() - 0x000000000141f220
                              # 27: ZN14QWidgetPrivate10drawWidgetEP12QPaintDeviceRK7QRegionRK6QPointiP8QPainterP19QWidgetBackingStore() - 0x000000000141e150
                              # 28: ZN14QWidgetPrivate11repaint_sysERK7QRegion() - 0x00000000013f41f0
                              # 29: ZN14QWidgetPrivate11repaint_sysERK7QRegion() - 0x00000000013f41f0
                              # 30: ZN14QWidgetPrivate16syncBackingStoreEv() - 0x000000000140d160
                              # 31: ZN7QWidget5eventEP6QEvent() - 0x0000000001425ba0
                              # 32: ZN11QMainWindow5eventEP6QEvent() - 0x0000000001513a50
                              # 33: ZN19QApplicationPrivate13notify_helperEP7QObjectP6QEvent() - 0x00000000013e7b70
                              # 34: ZN12QApplication6notifyEP7QObjectP6QEvent() - 0x00000000013ee990
                              # 35: ZN16QCoreApplication15notifyInternal2EP7QObjectP6QEvent() - 0x0000000068a66cc0
                              # 36: ZN23QCoreApplicationPrivate16sendPostedEventsEP7QObjectiP11QThreadData() - 0x0000000068a6d370
                              # 37: qt_plugin_instance() - 0x000000006a8f6eb0
                              # 38: ZN28QEventDispatcherWin32Private14sendTimerEventEi() - 0x0000000068ac1680
                              # 39: CallWindowProcW() - 0x00007fff427c6030
                              # 40: DispatchMessageW() - 0x00007fff427c5bf0
                              # 41: ZN21QEventDispatcherWin3213processEventsE6QFlagsIN10QEventLoop17ProcessEventsFlagEE() - 0x0000000068ac0b60
                              # 42: qt_plugin_instance() - 0x000000006a8f6eb0
                              # 43: ZN16QCoreApplication13processEventsE6QFlagsIN10QEventLoop17ProcessEventsFlagEEi() - 0x0000000068a67250
                              # 44: ZN5QTest5qWaitEi() - 0x0000000068ab7a20
                              # 45: Unable to obtain symbol
                              # 46: Unable to obtain symbol
                              # 47: Unable to obtain symbol
                              # 48: Unable to obtain symbol
                              # 49: Unable to obtain symbol
                              # 50: Unable to obtain symbol
                              # 51: ZNK11QMetaMethod6invokeEP7QObjectN2Qt14ConnectionTypeE22QGenericReturnArgument16QGenericArgumentS5_S5_S5_S5_S5_S5_S5_S5_S5_() - 0x0000000068a74760
                              # 52: ZN5QTest5qInitEP7QObjectiPPc() - 0x000000006edc7590
                              # 53: ZN5QTest5qInitEP7QObjectiPPc() - 0x000000006edc7590
                              # 54: ZN5QTest5qInitEP7QObjectiPPc() - 0x000000006edc7590
                              # 55: ZN5QTest4qRunEv() - 0x000000006edca280
                              # 56: ZN5QTest5qExecEP7QObjectiPPc() - 0x000000006edca670
                              # 57: Unable to obtain symbol
                              # 58: Unable to obtain symbol
                              # 59: Unable to obtain symbol
                              # 60: BaseThreadInitThunk() - 0x00007fff44077bc0
                              # 61: RtlUserThreadStart() - 0x00007fff4476ceb0
                              
                              The program has unexpectedly finished.
                              The process was ended forcefully.
                              

                              Any tips on how I could try and narrow down the issue?

                              There are mentions of threads and QPainter but I'm sure the issue is somehow related to loading a new file but I'm not sure how to get more information.

                              Cheers!

                              1 Reply Last reply
                              0
                              • J Offline
                                J Offline
                                JKSH
                                Moderators
                                wrote on 10 Nov 2019, 08:11 last edited by
                                #15

                                @rtavakko Your stack trace says that the exception was thrown in QColorProfile::fromSRgb().

                                This is a private class and method that was removed in Qt 5.13 -- perhaps you could try to upgrade to Qt 5.13 (or even Qt 5.14 beta) and see if the crash still occurs?

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

                                R 1 Reply Last reply 10 Nov 2019, 14:29
                                1
                                • J JKSH
                                  10 Nov 2019, 08:11

                                  @rtavakko Your stack trace says that the exception was thrown in QColorProfile::fromSRgb().

                                  This is a private class and method that was removed in Qt 5.13 -- perhaps you could try to upgrade to Qt 5.13 (or even Qt 5.14 beta) and see if the crash still occurs?

                                  R Offline
                                  R Offline
                                  rtavakko
                                  wrote on 10 Nov 2019, 14:29 last edited by
                                  #16

                                  @JKSH Thank for the reply! Aaah so 'Nearby Symbol' is where it occured and 'Exception Code' is what the error was. For future debugging is there a way I could get the stack trace when running the project normally? Currently the only way I could get it was by using QT unit test to start the GUI application.

                                  I will try upgrading to QT 5.13. Any idea what could be inviting QColorProfile::fromSRgb() to the party?

                                  I get this warning a few times everytime I start the project:

                                  libpng warning: iCCP: known incorrect sRGB profile
                                  

                                  I looked around online and people said it wasn't really a big deal but it seems it is related to the method that caused the crash.

                                  Cheers!

                                  J 1 Reply Last reply 12 Nov 2019, 01:00
                                  0
                                  • R Offline
                                    R Offline
                                    rtavakko
                                    wrote on 11 Nov 2019, 17:10 last edited by
                                    #17

                                    Update on this. I got the same crash in Qt 5.13.2 (Mingw 7.3.0 64-bit). I got a new crash in Qt 5.14.0 (same test conditions and crash happens the same way as before):

                                    Exception address: 0x0000000061bc697c
                                    Exception code   : 0xc0000005
                                    Nearby symbol    : ZN12QColorTrcLut17fromTransferTableERK19QColorTransferTable
                                    
                                    Stack:
                                    #  1: ZN5QTest15toPrettyUnicodeEPKti() - 0x000000006edc27a0
                                    #  2: UnhandledExceptionFilter() - 0x00007ff9f924f490
                                    #  3: memset() - 0x00007ff9fbc82fc0
                                    #  4: _C_specific_handler() - 0x00007ff9fbc6c640
                                    #  5: _chkstk() - 0x00007ff9fbc810e0
                                    #  6: RtlRaiseException() - 0x00007ff9fbc49ef0
                                    #  7: KiUserExceptionDispatcher() - 0x00007ff9fbc7fe40
                                    #  8: ZN12QColorTrcLut17fromTransferTableERK19QColorTransferTable() - 0x0000000061b4b770
                                    #  9: ZN13QVulkanWindow11qt_metacallEN11QMetaObject4CallEiPPv() - 0x0000000061dbb980
                                    # 10: ZN12QColorTrcLut17fromTransferTableERK19QColorTransferTable() - 0x0000000061b4b770
                                    # 11: ZrsR11QDataStreamR8QPolygon() - 0x0000000061c60140
                                    # 12: ZN18QRasterPaintEngine4clipERK11QVectorPathN2Qt13ClipOperationE() - 0x0000000061c0ff20
                                    # 13: ZN8QPainter9drawImageERK6QRectFRK6QImageS2_6QFlagsIN2Qt19ImageConversionFlagEE() - 0x0000000061c29840
                                    # 14: Unable to obtain symbol
                                    # 15: ZN7QWidget5eventEP6QEvent() - 0x00000000012452f0
                                    # 16: ZN19QApplicationPrivate13notify_helperEP7QObjectP6QEvent() - 0x0000000001207ae0
                                    # 17: ZN12QApplication6notifyEP7QObjectP6QEvent() - 0x000000000120e7f0
                                    # 18: ZN16QCoreApplication20sendSpontaneousEventEP7QObjectP6QEvent() - 0x0000000068a7dc40
                                    # 19: ZN14QWidgetPrivate14sendPaintEventERK7QRegion() - 0x000000000123d310
                                    # 20: ZN14QWidgetPrivate10drawWidgetEP12QPaintDeviceRK7QRegionRK6QPoint6QFlagsINS_14DrawWidgetFlagEEP8QPainterP21QWidgetRepaintManager() - 0x000000000123d370
                                    # 21: ZN14QWidgetPrivate22paintSiblingsRecursiveEP12QPaintDeviceRK5QListIP7QObjectEiRK7QRegionRK6QPoint6QFlagsINS_14DrawWidgetFlagEEP8QPainterP21QWidgetRepaintManager() - 0x000000000123eb50
                                    # 22: ZN14QWidgetPrivate22paintSiblingsRecursiveEP12QPaintDeviceRK5QListIP7QObjectEiRK7QRegionRK6QPoint6QFlagsINS_14DrawWidgetFlagEEP8QPainterP21QWidgetRepaintManager() - 0x000000000123eb50
                                    # 23: ZN14QWidgetPrivate22paintSiblingsRecursiveEP12QPaintDeviceRK5QListIP7QObjectEiRK7QRegionRK6QPoint6QFlagsINS_14DrawWidgetFlagEEP8QPainterP21QWidgetRepaintManager() - 0x000000000123eb50
                                    # 24: ZN14QWidgetPrivate22paintSiblingsRecursiveEP12QPaintDeviceRK5QListIP7QObjectEiRK7QRegionRK6QPoint6QFlagsINS_14DrawWidgetFlagEEP8QPainterP21QWidgetRepaintManager() - 0x000000000123eb50
                                    # 25: ZN14QWidgetPrivate10drawWidgetEP12QPaintDeviceRK7QRegionRK6QPoint6QFlagsINS_14DrawWidgetFlagEEP8QPainterP21QWidgetRepaintManager() - 0x000000000123d370
                                    # 26: ZN14QWidgetPrivate22paintSiblingsRecursiveEP12QPaintDeviceRK5QListIP7QObjectEiRK7QRegionRK6QPoint6QFlagsINS_14DrawWidgetFlagEEP8QPainterP21QWidgetRepaintManager() - 0x000000000123eb50
                                    # 27: ZN14QWidgetPrivate10drawWidgetEP12QPaintDeviceRK7QRegionRK6QPoint6QFlagsINS_14DrawWidgetFlagEEP8QPainterP21QWidgetRepaintManager() - 0x000000000123d370
                                    # 28: ZNK14QWidgetPrivate24shouldDiscardSyncRequestEv() - 0x00000000012133a0
                                    # 29: ZNK14QWidgetPrivate24shouldDiscardSyncRequestEv() - 0x00000000012133a0
                                    # 30: ZN14QWidgetPrivate16syncBackingStoreEv() - 0x000000000123e9e0
                                    # 31: ZN7QWidget5eventEP6QEvent() - 0x00000000012452f0
                                    # 32: ZN11QMainWindow5eventEP6QEvent() - 0x0000000001338e70
                                    # 33: ZN19QApplicationPrivate13notify_helperEP7QObjectP6QEvent() - 0x0000000001207ae0
                                    # 34: ZN12QApplication6notifyEP7QObjectP6QEvent() - 0x000000000120e7f0
                                    # 35: ZN16QCoreApplication15notifyInternal2EP7QObjectP6QEvent() - 0x0000000068a7d410
                                    # 36: ZN23QCoreApplicationPrivate16sendPostedEventsEP7QObjectiP11QThreadData() - 0x0000000068a83440
                                    # 37: qt_plugin_instance() - 0x000000006a8fbe40
                                    # 38: ZN21QEventDispatcherWin3213processEventsE6QFlagsIN10QEventLoop17ProcessEventsFlagEE() - 0x0000000068ad8cb0
                                    # 39: qt_plugin_instance() - 0x000000006a8fbe40
                                    # 40: ZN16QCoreApplication13processEventsE6QFlagsIN10QEventLoop17ProcessEventsFlagEEi() - 0x0000000068a7d9a0
                                    # 41: ZN5QTest5qWaitEi() - 0x0000000068acfbe0
                                    # 42: Unable to obtain symbol
                                    # 43: Unable to obtain symbol
                                    # 44: Unable to obtain symbol
                                    # 45: Unable to obtain symbol
                                    # 46: Unable to obtain symbol
                                    # 47: Unable to obtain symbol
                                    # 48: ZNK11QMetaMethod6invokeEP7QObjectN2Qt14ConnectionTypeE22QGenericReturnArgument16QGenericArgumentS5_S5_S5_S5_S5_S5_S5_S5_S5_() - 0x0000000068a8b460
                                    # 49: ZN5QTest5qInitEP7QObjectiPPc() - 0x000000006edc88d0
                                    # 50: ZN5QTest5qInitEP7QObjectiPPc() - 0x000000006edc88d0
                                    # 51: ZN5QTest5qInitEP7QObjectiPPc() - 0x000000006edc88d0
                                    # 52: ZN5QTest4qRunEv() - 0x000000006edcb5c0
                                    # 53: ZN5QTest5qExecEP7QObjectiPPc() - 0x000000006edcb9b0
                                    # 54: Unable to obtain symbol
                                    # 55: Unable to obtain symbol
                                    # 56: Unable to obtain symbol
                                    # 57: BaseThreadInitThunk() - 0x00007ff9faab7bc0
                                    # 58: RtlUserThreadStart() - 0x00007ff9fbc4ceb0
                                    
                                    1 Reply Last reply
                                    0
                                    • R rtavakko
                                      10 Nov 2019, 14:29

                                      @JKSH Thank for the reply! Aaah so 'Nearby Symbol' is where it occured and 'Exception Code' is what the error was. For future debugging is there a way I could get the stack trace when running the project normally? Currently the only way I could get it was by using QT unit test to start the GUI application.

                                      I will try upgrading to QT 5.13. Any idea what could be inviting QColorProfile::fromSRgb() to the party?

                                      I get this warning a few times everytime I start the project:

                                      libpng warning: iCCP: known incorrect sRGB profile
                                      

                                      I looked around online and people said it wasn't really a big deal but it seems it is related to the method that caused the crash.

                                      Cheers!

                                      J Offline
                                      J Offline
                                      JKSH
                                      Moderators
                                      wrote on 12 Nov 2019, 01:00 last edited by
                                      #18

                                      @rtavakko said in OpenCV VideoCapture Failure from QThread:

                                      Aaah so 'Nearby Symbol' is where it occured and 'Exception Code' is what the error was.

                                      Yep. And the stack trace shows the calls leading up to the crash, in reverse order.

                                      • In Qt 5.12 you had: QVulkanWindow::qt_metacall(...) -> QColorProfile::fromSRgb() -> crash
                                      • In Qt 5.14 you had: QVulkanWindow::qt_metacall(...) -> QColorTrcLut::fromTransferTable() -> crash

                                      Normally, the function where the crash occured will be item #1 on the stack trace because it's the last one called. However, since you're running inside a test framework, it was able to "catch" the crash and do some more work to present the crash to you (starting from UserExceptionDispatcher())

                                      Any idea what could be inviting QColorProfile::fromSRgb() to the party?

                                      Judging by your stack trace, your system is in the middle of decoding or rendering the video when the crash occurs.

                                      For future debugging is there a way I could get the stack trace when running the project normally? Currently the only way I could get it was by using QT unit test to start the GUI application.

                                      You can just run your debugger without using Qt Test: https://doc.qt.io/qtcreator/creator-debugging.html It is useful for locating "simple" coding errors like trying to read beyond the last element of an array.

                                      However, in your situation, you get a memory access violation error (https://stackoverflow.com/questions/5303524/what-exactly-is-the-scope-of-access-violation-0xc0000005 ) when loading many files quickly but doesn't crash when loading slowly, is that right? In this situation, the debugger is less useful. I'm guessing that when you have many threads loading at the same time, one of the threads could be corrupting the memory used by another thread and this corruption is detected during the colour lookup (https://code.woboq.org/qt5/qtbase/src/gui/painting/qcolortrclut.cpp.html#_ZN12QColorTrcLut17fromTransferTableERK19QColorTransferTable ). The corruption was probably not caused by the colour lookup function itself.

                                      I don't know of a good way to debug threading issues in Windows. If you can build your project in Linux, Valgrind might help.

                                      libpng warning: iCCP: known incorrect sRGB profile
                                      

                                      I looked around online and people said it wasn't really a big deal but it seems it is related to the method that caused the crash.

                                      I don't think libpng is used to load videos. Is your program loading any images?

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

                                      R 1 Reply Last reply 12 Nov 2019, 03:01
                                      2
                                      • J JKSH
                                        12 Nov 2019, 01:00

                                        @rtavakko said in OpenCV VideoCapture Failure from QThread:

                                        Aaah so 'Nearby Symbol' is where it occured and 'Exception Code' is what the error was.

                                        Yep. And the stack trace shows the calls leading up to the crash, in reverse order.

                                        • In Qt 5.12 you had: QVulkanWindow::qt_metacall(...) -> QColorProfile::fromSRgb() -> crash
                                        • In Qt 5.14 you had: QVulkanWindow::qt_metacall(...) -> QColorTrcLut::fromTransferTable() -> crash

                                        Normally, the function where the crash occured will be item #1 on the stack trace because it's the last one called. However, since you're running inside a test framework, it was able to "catch" the crash and do some more work to present the crash to you (starting from UserExceptionDispatcher())

                                        Any idea what could be inviting QColorProfile::fromSRgb() to the party?

                                        Judging by your stack trace, your system is in the middle of decoding or rendering the video when the crash occurs.

                                        For future debugging is there a way I could get the stack trace when running the project normally? Currently the only way I could get it was by using QT unit test to start the GUI application.

                                        You can just run your debugger without using Qt Test: https://doc.qt.io/qtcreator/creator-debugging.html It is useful for locating "simple" coding errors like trying to read beyond the last element of an array.

                                        However, in your situation, you get a memory access violation error (https://stackoverflow.com/questions/5303524/what-exactly-is-the-scope-of-access-violation-0xc0000005 ) when loading many files quickly but doesn't crash when loading slowly, is that right? In this situation, the debugger is less useful. I'm guessing that when you have many threads loading at the same time, one of the threads could be corrupting the memory used by another thread and this corruption is detected during the colour lookup (https://code.woboq.org/qt5/qtbase/src/gui/painting/qcolortrclut.cpp.html#_ZN12QColorTrcLut17fromTransferTableERK19QColorTransferTable ). The corruption was probably not caused by the colour lookup function itself.

                                        I don't know of a good way to debug threading issues in Windows. If you can build your project in Linux, Valgrind might help.

                                        libpng warning: iCCP: known incorrect sRGB profile
                                        

                                        I looked around online and people said it wasn't really a big deal but it seems it is related to the method that caused the crash.

                                        I don't think libpng is used to load videos. Is your program loading any images?

                                        R Offline
                                        R Offline
                                        rtavakko
                                        wrote on 12 Nov 2019, 03:01 last edited by
                                        #19

                                        @JKSH Thanks for the detailed information, it'll definitely help with future bugs like this.

                                        So far, it seems to crash more frequently when I load files quickly but I also tried slowing down the test and it still happened with no real pattern.

                                        I have QMutexlockers in key areas where I load and read videos but after doing some more testing, it seems the crash happens only when I emit a signal containing an OpenCV matrix data pointer. I use this signal to display image results using a subclassed widget. If I don't emit the signal and use an OpenCV window to show an image, everything runs well no matter how fast I load videos. So I think there's something wrong in my handling of the sent pointer.

                                        //Show current image data
                                        void Display::updateImage(const uchar *imageData, int width, int height, int step)
                                        {
                                            if(imageData != nullptr)
                                            {
                                                displayImage = QImage(imageData, width, height, step, QImage::Format_RGBA8888);
                                                update();
                                            }
                                        }
                                        
                                        //Paint event for display object
                                        void Display::paintEvent(QPaintEvent*)
                                        {
                                            QPainter painter(this);
                                        
                                            painter.setRenderHint(QPainter::SmoothPixmapTransform,true);
                                            painter.setPen(QPen(Qt::red));
                                        
                                            painter.drawImage(rect(),displayImage); //Resize the image based on widget size and display it
                                        }
                                        

                                        I don't see what in here could be causing a crash specially given that I use a const pointer. Is there a way I could catch the exception when it happens if I can't get to the bottom of the issue? So far try / catch statements haven't helped.

                                        Cheers!

                                        J 1 Reply Last reply 12 Nov 2019, 05:41
                                        0
                                        • R rtavakko
                                          12 Nov 2019, 03:01

                                          @JKSH Thanks for the detailed information, it'll definitely help with future bugs like this.

                                          So far, it seems to crash more frequently when I load files quickly but I also tried slowing down the test and it still happened with no real pattern.

                                          I have QMutexlockers in key areas where I load and read videos but after doing some more testing, it seems the crash happens only when I emit a signal containing an OpenCV matrix data pointer. I use this signal to display image results using a subclassed widget. If I don't emit the signal and use an OpenCV window to show an image, everything runs well no matter how fast I load videos. So I think there's something wrong in my handling of the sent pointer.

                                          //Show current image data
                                          void Display::updateImage(const uchar *imageData, int width, int height, int step)
                                          {
                                              if(imageData != nullptr)
                                              {
                                                  displayImage = QImage(imageData, width, height, step, QImage::Format_RGBA8888);
                                                  update();
                                              }
                                          }
                                          
                                          //Paint event for display object
                                          void Display::paintEvent(QPaintEvent*)
                                          {
                                              QPainter painter(this);
                                          
                                              painter.setRenderHint(QPainter::SmoothPixmapTransform,true);
                                              painter.setPen(QPen(Qt::red));
                                          
                                              painter.drawImage(rect(),displayImage); //Resize the image based on widget size and display it
                                          }
                                          

                                          I don't see what in here could be causing a crash specially given that I use a const pointer. Is there a way I could catch the exception when it happens if I can't get to the bottom of the issue? So far try / catch statements haven't helped.

                                          Cheers!

                                          J Offline
                                          J Offline
                                          JKSH
                                          Moderators
                                          wrote on 12 Nov 2019, 05:41 last edited by JKSH 11 Dec 2019, 05:43
                                          #20

                                          @rtavakko said in OpenCV VideoCapture Failure from QThread:

                                          it seems the crash happens only when I emit a signal containing an OpenCV matrix data pointer

                                          I don't have much experience with OpenCV, but you might need to be extra careful when passing cv::mat across different threads: https://stackoverflow.com/questions/10657841/is-cvmat-thread-safe-atomic-assignment-refcounting

                                          I don't see what in here could be causing a crash specially given that I use a const pointer.

                                          The code you posted does not show how you use cv::mat or how you emit your signal.

                                          Is there a way I could catch the exception when it happens if I can't get to the bottom of the issue?

                                          Not really. Multithreading-related memory problems cause damage long before the access violation exception is generated.

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

                                          1 Reply Last reply
                                          3

                                          • Login

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