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. QCamera::stop hangs or causes a crash. How to deinit the camera properly?
Forum Updated to NodeBB v4.3 + New Features

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 5.7k 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 Violet Giraffe
    #1

    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?

    kshegunovK T 2 Replies 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?

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

      @Violet-Giraffe said:

      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).

      I don't have a windows to test, but the stack trace of the crash may be useful.

      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?

      If you're correct in your suspicion, you can delete the camera through an event, try: camera->deleteLater().

      Read and abide by the Qt Code of Conduct

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

        That doesn't explain stop hanging, though. Probably a lock of some kind.

        kshegunovK 1 Reply Last reply
        0
        • V Violet Giraffe

          That doesn't explain stop hanging, though. Probably a lock of some kind.

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

          @Violet-Giraffe said:

          That doesn't explain stop hanging, though. Probably a lock of some kind.

          It may be, it also might be a bug, or some idiosyncrasy of the Windows' backend. I have no reference for comparison, so I can't know.

          PS:
          Btw, you're intercepting the _displayWidget's paint event, but you're not stopping its propagation, is this intended?

          Read and abide by the Qt Code of Conduct

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

            No, that's a mistake. Good catch, thank you.

            kshegunovK 1 Reply Last reply
            0
            • V Violet Giraffe

              No, that's a mistake. Good catch, thank you.

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

              @Violet-Giraffe

              Good catch, thank you.

              No problem. Do consider interrupting the runtime when you get stop() to hang and extracting the stack. It may attract some better answers.

              Kind regards.

              Read and abide by the Qt Code of Conduct

              1 Reply Last reply
              0
              • 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 Extensions
                                  • Unsolved