Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. QCamera::stop hangs or causes a crash. How to deinit the camera properly?
Qt 6.12 LTS is out! See what's new in the release blog

QCamera::stop hangs or causes a crash. How to deinit the camera properly?

Scheduled Pinned Locked Moved Unsolved General and Desktop
16 Posts 4 Posters 8.6k Views 3 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.
  • V Offline
    V Offline
    Violet Giraffe
    wrote on last edited by
    #7

    Here's the crash stack:

    https://snag.gy/wWpe6m.jpg

    Of course, the moment I decided I'm going to capture the stack of the freeze I lost the ability to reproduce it.

    kshegunovK 1 Reply Last reply
    0
    • V Violet Giraffe

      My program connects to the camera (QCamera::start()), receives one viewfinder frame (via a custom QAbstractVideoSurface sublcass with overridden present method), and then disconnects from the camera (by calling stop and then deleting the camera object).

      One of two things happen: either the stop call freezes indefinitely, or access violation occurs deep inside Qt multimedia after calling QCamera::~QCamera() (but not directly through the destructor; something goes wrong afterward in some event handler). This is on Windows. Here's the link to the project's repository for testing.

      What's the problem?

      I suspect stop() may be a non-blocking call and deleting the QCamera immediately is a mistake. I've tried calling unload after stop, but it didn't fix the problem. So how to delete QCamera properly and safely?

      T Offline
      T Offline
      t3685
      wrote on last edited by
      #8

      @Violet-Giraffe

      Hello,

      Are you deleting the QCamera object in slot connected to signal that was thrown by the camera?

      V 1 Reply Last reply
      0
      • V Violet Giraffe

        Here's the crash stack:

        https://snag.gy/wWpe6m.jpg

        Of course, the moment I decided I'm going to capture the stack of the freeze I lost the ability to reproduce it.

        kshegunovK Offline
        kshegunovK Offline
        kshegunov
        Moderators
        wrote on last edited by kshegunov
        #9

        @Violet-Giraffe

        It appears the event loop is crashing, I can't see any reference to your code in that trace (except the trivial QApplication::exec). However:

        _camera = std::make_shared<QCamera>(cameraInfo);
        

        Looks suspicious. Qt has its own ownership system for QObject subclasses, so this shared pointer could be deleting the camera based on you "not using" the camera anymore, while there's a scheduled event somewhere in the event loop still referencing the object. I suggest dropping that line and using a raw pointer (or better yet QPointer) to track the object's lifetime.

        Kind regards.

        Read and abide by the Qt Code of Conduct

        V 1 Reply Last reply
        0
        • T t3685

          @Violet-Giraffe

          Hello,

          Are you deleting the QCamera object in slot connected to signal that was thrown by the camera?

          V Offline
          V Offline
          Violet Giraffe
          wrote on last edited by
          #10

          @t3685
          I'm deleting it in a slot connected to QAbstractVideoSurface::present(). Now that I think about it, it may well be, in turn, called from QCamera. I will investigate.

          1 Reply Last reply
          0
          • kshegunovK kshegunov

            @Violet-Giraffe

            It appears the event loop is crashing, I can't see any reference to your code in that trace (except the trivial QApplication::exec). However:

            _camera = std::make_shared<QCamera>(cameraInfo);
            

            Looks suspicious. Qt has its own ownership system for QObject subclasses, so this shared pointer could be deleting the camera based on you "not using" the camera anymore, while there's a scheduled event somewhere in the event loop still referencing the object. I suggest dropping that line and using a raw pointer (or better yet QPointer) to track the object's lifetime.

            Kind regards.

            V Offline
            V Offline
            Violet Giraffe
            wrote on last edited by
            #11

            @kshegunov said:

            Qt has its own ownership system for QObject subclasses,

            It does have an ownership system, but not reference counting. Raw pointers are raw pointers. I might have to use deleteLater, though, but it's not documented in any QCamera samples I've seen.

            kshegunovK 1 Reply Last reply
            0
            • V Violet Giraffe

              @kshegunov said:

              Qt has its own ownership system for QObject subclasses,

              It does have an ownership system, but not reference counting. Raw pointers are raw pointers. I might have to use deleteLater, though, but it's not documented in any QCamera samples I've seen.

              kshegunovK Offline
              kshegunovK Offline
              kshegunov
              Moderators
              wrote on last edited by
              #12

              @Violet-Giraffe said:

              It does have an ownership system, but not reference counting.

              It has parent-child system instead; no need for reference counting, as there can't be QObject copying anyway. Additionally, Qt provides (as already mentioned) guarded pointers to QObjects, so reference counting becomes unnecessary. By giving a parent to a QObject you ensure the memory will be freed. And while it's generally possible to just delete a QObject @t3685's question is relevant - you can't do it from inside a slot. My advice is to post a deferred delete through QObject::deleteLater (and keep your camera pointer in a QPointer not STL shared one).

              Kind regards.

              Read and abide by the Qt Code of Conduct

              1 Reply Last reply
              0
              • SGaistS Offline
                SGaistS Offline
                SGaist
                Lifetime Qt Champion
                wrote on last edited by
                #13

                Hi,

                a slot connected to present ? Can you tell more about that ?

                In any case, deleting a camera from a QAbstractVideoSurface doesn't sound like a good idea. What happens usually is that your camera backend receives a QAbstractVideoSurface to paint images on.

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

                V 1 Reply Last reply
                0
                • SGaistS SGaist

                  Hi,

                  a slot connected to present ? Can you tell more about that ?

                  In any case, deleting a camera from a QAbstractVideoSurface doesn't sound like a good idea. What happens usually is that your camera backend receives a QAbstractVideoSurface to paint images on.

                  V Offline
                  V Offline
                  Violet Giraffe
                  wrote on last edited by
                  #14

                  @SGaist
                  Yes, I don't know the specific chain of events that lead to a crash, but I'm certain that deleting the QCamera object from a slot connected to present was the cause of the problem.
                  I didn't exactly fix it, instead I decided to keep the QCamera object and stop + unload it instead of stop + delete. Makes more sense since I know I always need to connect to the same camera, might as well avoid constructing it from scratch every time.

                  What I have is a custom QAbstractVideoSurface subclass with present(const QVideoFrame& frame) method overridden. It takes the frame, converts it to QImage and emits it in a signal. The image is then displayed and analyzed to take different actions. I hate having to reject the the native QCameraViewfinder widget entirely (which probably uses OpenGL for fast rendering) and use the slow QPainter::drawImage, but I didn't find any other way to intercept the viewfinder frames other than grab() from the QCameraViewfinder widget, which is also an odd method that I don't like.

                  1 Reply Last reply
                  0
                  • SGaistS Offline
                    SGaistS Offline
                    SGaist
                    Lifetime Qt Champion
                    wrote on last edited by
                    #15

                    What about QVideoProbe ?

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

                    1 Reply Last reply
                    0
                    • V Offline
                      V Offline
                      Violet Giraffe
                      wrote on last edited by
                      #16

                      Isn't implemented for QCamera on Windows.

                      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
                      • Unsolved