QCamera::stop hangs or causes a crash. How to deinit the camera properly?
-
No, that's a mistake. Good catch, thank you.
-
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.
-
Here's the crash stack:
Of course, the moment I decided I'm going to capture the stack of the freeze I lost the ability to reproduce it.
-
Hello,
Are you deleting the QCamera object in slot connected to signal that was thrown by the camera?
-
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 yetQPointer
) to track the object's lifetime.Kind regards.
-
@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. -
@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 toQObject
s, so reference counting becomes unnecessary. By giving a parent to aQObject
you ensure the memory will be freed. And while it's generally possible to justdelete
aQObject
@t3685's question is relevant - you can't do it from inside a slot. My advice is to post a deferred delete throughQObject::deleteLater
(and keep your camera pointer in aQPointer
not STL shared one).Kind regards.
-
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.
-
@SGaist
Yes, I don't know the specific chain of events that lead to a crash, but I'm certain that deleting theQCamera
object from a slot connected topresent
was the cause of the problem.
I didn't exactly fix it, instead I decided to keep the QCamera object andstop
+unload
it instead ofstop
+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 withpresent(const QVideoFrame& frame)
method overridden. It takes the frame, converts it toQImage
and emits it in a signal. The image is then displayed and analyzed to take different actions. I hate having to reject the the nativeQCameraViewfinder
widget entirely (which probably uses OpenGL for fast rendering) and use the slowQPainter::drawImage
, but I didn't find any other way to intercept the viewfinder frames other thangrab()
from theQCameraViewfinder
widget, which is also an odd method that I don't like. -
What about QVideoProbe ?
-
Isn't implemented for QCamera on Windows.