Code suddenly stops at self.cam = QCamera() , PyQt5.9.2, Qt5.9.3, Python3.5
-
@JNBarchan
- input: cat /etc/group -> output (i am in the group video)
I just post this if i dont see a group i should be in:
root:x:0: daemon:x:1: bin:x:2: sys:x:3: adm:x:4:syslog,blz tty:x:5: disk:x:6: lp:x:7: mail:x:8: news:x:9: uucp:x:10: man:x:12: proxy:x:13: kmem:x:15: dialout:x:20: fax:x:21: voice:x:22: cdrom:x:24:blz floppy:x:25: tape:x:26: sudo:x:27:blz audio:x:29:pulse,blz dip:x:30:blz www-data:x:33: backup:x:34: operator:x:37: list:x:38: irc:x:39: src:x:40: gnats:x:41: shadow:x:42: utmp:x:43: video:x:44:blz sasl:x:45: plugdev:x:46:blz staff:x:50: games:x:60: users:x:100: nogroup:x:65534: systemd-journal:x:101: systemd-timesync:x:102: systemd-network:x:103: systemd-resolve:x:104: systemd-bus-proxy:x:105: input:x:106:blz crontab:x:107: syslog:x:108: netdev:x:109: messagebus:x:110: uuidd:x:111: mlocate:x:112: ssh:x:113: ssl-cert:x:114: lpadmin:x:115:blz lightdm:x:116: nopasswdlogin:x:117: ntp:x:118: avahi-autoipd:x:119: avahi:x:120: bluetooth:x:121: scanner:x:122:saned colord:x:123: pulse:x:124: pulse-access:x:125: rtkit:x:126: saned:x:127: whoopsie:x:128: gpio:x:999:blz i2c:x:998:blz spi:x:997:blz blz:x:1000: sambashare:x:129:blz
QCamera(0x72dbe3b0)
From the QCamera documentation: "QCamera::QCamera(const QByteArray &deviceName, QObject *parent = Q_NULLPTR) Construct a QCamera from deviceName and parent."
Correct me if i'm wrong but that means if i know the deviceName that i can just initialize the Camera with QCamera(0x72dbe3b0).
3)
gdb is a debug program which can be used for segmentation fault errors.@jsulm
4)
Input:ls -l /home/blz/Schreibtisch/qt5.py
Output:
-rwxrwxrwx 1 blz blz 1537 Dez 7 10:33 /home/blz/Schreibtisch/qt5.py
I guess that means that i have full accessibility to qt5.pyThanks for your help. I appreciate your feedback.
Greets
- input: cat /etc/group -> output (i am in the group video)
-
@Xenoshell 1. Well, the question is: what is the group of the camera device file?
2. You can use this code to see all the camera device names (http://doc.qt.io/qt-5/qcamera.html):QList<QCameraInfo> cameras = QCameraInfo::availableCameras(); foreach (const QCameraInfo &cameraInfo, cameras) { qDebug() << cameraInfo.deviceName(); }
- Yes, you can use GDB to get more information if your app crashes
- Everyone has full access to Schreibtisch/qt5.py. Not sure how is this related?
-
Nothing looks interesting in your groups. Never mind, it was only an idea of @jsulm's, maybe or maybe not relevant.
Correct me if i'm wrong but that means if i know the deviceName that i can just initialize the Camera with QCamera(0x72dbe3b0).
It's so wrong. Fortunately in C++ it won't compile, in Python I hope it will spit it back at you. You really need to understand why this is plain wrong in any language/circumstance, if you're new to programming. You must pass a string which has the value of a device name to
QCamera()
, e.g.QCamera("camera-device-name")
, or a device name picked up from aQCameraInfo.deviceName()
(which itself is a string).Please try @jsulm's suggestion of enumerating the available cameras you have. In Python it'll be like:
for cameraInfo in QCameraInfo.availableCameras(): print(cameraInfo.deviceName())
QString QCameraInfo::deviceName() const
Returns the device name of the camera
This is a unique ID to identify the camera and may not be human-readable.So a device name might come out like
abc1234
(I don't know 'coz I haven't got one to test). Then the actual Linux device will be/dev/abc1234
, or something like that. We want you tols -l
that, and look at its owner & group permissions, and see if you have access to it under your own user, notsudo
. This is what we mean about "permissions", not the permissions you list for/home/blz/Schreibtisch/qt5.py
. -
@JNBarchan, @jsulm
The output for the for-loop is:/dev/video0
Here the output is:
blz@blz-desktop:~$ ls -l /dev/video0 crw-rw----+ 1 root video 81, 0 Dez 11 10:55 /dev/video0
To me it looks like i dont have the permission to everything.
-
@Xenoshell Add yourself to the video group if it's not already the case
-
@Xenoshell
You can see if you're already a member ofvideo
group via executing commandgroups
.If your username is
blz
, I think you already are....If you are a member, it would then look like: as yourself, not root, you do have access to the camera device, hence you say it seems to "initially open", but then something else is happening which works as
root
but not as you.... You could temporarilysudo chmod 666 /dev/video0
, see if that helps, then revert tosudo chmod 660 /dev/video0
. -
@jsulm @JNBarchan ,
i am already member of the video group.
The camera device only opens if i use sudo. If i dont it just gets stuck at self.cam = QCamera().
After the commandsudo chmod 666 /dev/video0
i tried using qt5.py without sudo but it just got stuck.
So there has to be a group which i am not a member of that uses QCamera(). Am i at least right with this assumption? -
Ok i cant reproduce the gdb output anymore. It just stops at 1 and then somehow locks up and i have to relog again.
I somehow have this feeling that the code/the usb-camera use audio or at least try to use it. When i want to turn off the pi i always get the message that "Pulse Audio Sound System" is currently running and if i want to terminate it.
Tomorrow i will sit down and try to get the gdb output without sudo /with sudo and look what is possible.
Debugging can really be stressful... -
@jsulm, @JNBarchan
Here i am again, this is the new gdb output:(gdb) run qt5.py Starting program: /usr/bin/python3 qt5.py Cannot parse expression `.L1185 4@r4'. warning: Probes-based dynamic linker interface failed. Reverting to original interface. [Thread debugging using libthread_db enabled] Using host libthread_db library "/lib/arm-linux-gnueabihf/libthread_db.so.1". 1 [New Thread 0x72b39470 (LWP 4134)] 2 3 [New Thread 0x6de10470 (LWP 4139)] [Thread 0x6de10470 (LWP 4139) exited] [New Thread 0x6de10470 (LWP 4140)] [Thread 0x6de10470 (LWP 4140) exited]
At this output is libpulse.so and also libasound.so.2 i talked about in my post above. It could actually be that QCamera() tries to also initalise Audio but obviously i dont have any audiooutput plugged in and thats why it stops at QCamera
(gdb) bt #0 __libc_do_syscall () at ../sysdeps/unix/sysv/linux/arm/libc-do-syscall.S:46 #1 0x76f21c0a in __GI_ppoll (fds=0x7001a8, nfds=1, timeout=<optimized out>, sigmask=0x0) at ../sysdeps/unix/sysv/linux/ppoll.c:50 #2 0x73389e12 in pa_mainloop_poll () from /usr/lib/arm-linux-gnueabihf/libpulse.so.0 #3 0x7338a290 in pa_mainloop_iterate () from /usr/lib/arm-linux-gnueabihf/libpulse.so.0 #4 0x6de2888c in conf_pulse_hook_load_if_running () from /usr/lib/arm-linux-gnueabihf/alsa-lib/libasound_module_conf_pulse.so #5 0x6e01c9f2 in ?? () from /usr/lib/arm-linux-gnueabihf/libasound.so.2 Backtrace stopped: previous frame identical to this frame (corrupt stack?)
Here the info threads:
(gdb) info threads Id Target Id Frame * 1 Thread 0x76ff6300 (LWP 4204) "python3" __libc_do_syscall () at ../sysdeps/unix/sysv/linux/arm/libc-do-syscall.S:46 2 Thread 0x72b39470 (LWP 4206) "QXcbEventReader" 0x76f21b90 in poll () at ../sysdeps/unix/syscall-template.S:84
Can anyone tell me whats going on in those gdb outputs? Are they even important or are they just there and we cant really do anything with them?
-
@Xenoshell
Because you are using Python, not a standalone executable of your program compiled from C++, if you usegdb
you have togdb
the Python executable, not your app running as a Python script. This meansgdb
probably is not of any interest to you, per se, for general debugging of your app; though it may give us some clues in this particular case.To clarify, for your app script completely. Just run
gdb
against Python without any mention of yourqt5.py
script. For the record, here is my output under Ubuntu not Pi:jon@ubuntu:~$ gdb python3 Reading symbols from python3...(no debugging symbols found)...done. (gdb) run Starting program: /usr/bin/python3 [Thread debugging using libthread_db enabled] Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1". Python 3.5.3 (default, Nov 23 2017, 11:34:05) [GCC 6.3.0 20170406] on linux Type "help", "copyright", "credits" or "license" for more information. >>>
Does yours produce much the same? Does it only give the
libpulse
/libasound
if a certain line is in your Python script, and not if it is removed, then you'd have an idea what is related to what? I wish you'd show what that line is now, because we no longer know whether you are enumerating available cameras or opening a camera? -
@JNBarchan
This is the whole output:blz@blz-desktop:~$ gdb python3 GNU gdb (Ubuntu 7.11.1-0ubuntu1~16.5) 7.11.1 Copyright (C) 2016 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "arm-linux-gnueabihf". Type "show configuration" for configuration details. For bug reporting instructions, please see: <http://www.gnu.org/software/gdb/bugs/>. Find the GDB manual and other documentation resources online at: <http://www.gnu.org/software/gdb/documentation/>. For help, type "help". Type "apropos word" to search for commands related to "word"... Reading symbols from python3...Reading symbols from /usr/lib/debug/.build-id/d7/14ad8d8b52ca34a8a81f10b4917027977b05ca.debug...done. done. (gdb) run Starting program: /usr/bin/python3 Cannot parse expression `.L1185 4@r4'. warning: Probes-based dynamic linker interface failed. Reverting to original interface. [Thread debugging using libthread_db enabled] Using host libthread_db library "/lib/arm-linux-gnueabihf/libthread_db.so.1". Python 3.5.2 (default, Nov 23 2017, 16:37:01) [GCC 5.4.0 20160609] on linux Type "help", "copyright", "credits" or "license" for more information. >>>
My code always stops at self.cam = QCamera() otherwise it would also print 4 and not suddenly stop
As a reminder, here is my code:import sys from PyQt5 import QtCore , QtWidgets, QtGui, QtMultimedia, QtMultimediaWidgets from PyQt5.QtCore import QObject, pyqtSignal, pyqtSlot from PyQt5.QtWidgets import QApplication, QPushButton, QMainWindow from PyQt5.QtMultimedia import QCamera, QCameraInfo, QMediaObject, QCameraViewfinderSettings, QCameraImageCapture from PyQt5.QtMultimediaWidgets import QCameraViewfinder class Camera(QObject): def __init__(self, parent = QObject()): super(Camera, self).__init__(parent) print("3") self.cam = QCamera() print("4") self.caminfo = QCameraInfo(self.cam) self.camvfind = QCameraViewfinder() self.camvfindset = QCameraViewfinderSettings() self.cammode = self.cam.CaptureMode(2) self.camimgcap = QCameraImageCapture(self.cam) def iniCamera(self): #print(self.caminfo.description()) #print(self.caminfo.availableCameras()) for caminfo in QCameraInfo.availableCameras(): print(caminfo.deviceName()) if self.cam.isCaptureModeSupported(self.cammode): print("Capturemode supported") def startVid(self): self.camimgcap.CaptureDestination(2) self.camvfind.show() self.cam.setViewfinder(self.camvfind) self.cam.setCaptureMode(self.cammode) self.cam.start() if __name__ == '__main__': print("1") app = QtWidgets.QApplication(sys.argv) print("2") cam = Camera() print("4") cam.iniCamera() cam.startVid() sys.exit(app.exec_())
-
@Xenoshell
I asked earlier:Does it only give the libpulse/libasound if a certain line is in your Python script, and not if it is removed, then you'd have an idea what is related to what?
So, if I were you, under
gdb
, I'd try commenting in & commenting out theQCamera()
line, and report whether your debugger only shows thelibpulse
error if & only if you have that line in there. then you'd know for sure whetherQCamera()
has anything to do withlibpulse
....I'd also try
QCamera("video0")
orQCamera("/dev/video0")
or whatever it is, instead of plainQCamera()
. I'd probably also tryQCamera("rubbish")
. These are all things for you to play with to try to understand just what causes the problem/hang, it's up to you.... -
@JNBarchan
I commentedQCamera()
and obviously i also need to comment the stuff that is in correlation toself.cam
because otherwise i would get a simple error becauseself.cam
is not there. Then i also dont get the libpulse error, well tbh there is not much to compile because about half the code is commented.
I tried usingQCamera("/dev/video0)
and also video0, this results in the error:TypeError: arguments did not match any overloaded call: QCamera(QObject parent=None): argument 1 has unexpected type 'str' QCamera(QByteArray, QObject parent=None): argument 1 has unexpected type 'str' QCamera(QCameraInfo, QObject parent=None): argument 1 has unexpected type 'str' QCamera(QCamera.Position, QObject parent=None): argument 1 has unexpected type 'str'
I can follow you that this should be right but how are you supposed to initialize QCamera if you need the QCameraInfo or a QByteArray?
Are you supposed to initalize without anything -> find out the QByteArray -> initialize QCamera with the correct QByteArray?Thanks again for your help
-
@Xenoshell
For the way to invokeQCamera()
, sorry, I misremembered the constructor, and thought it took a string. It takes a byte array of the name instead. From Python, you'll usestr.encode()
, e.g."/dev/video0".encode()
.Maybe it's not a good idea to try to create an "empty"
QCamera()
. Try using a constructor which does take an actual camera. One of:- `QCamera(QCameraInfo.defaultCamera())
QCamera("/dev/video0".encode())
- One of the available cameras returned by the loop:
for caminfo in QCameraInfo.availableCameras(): print(caminfo.deviceName()) acam = QCamera(caminfo)
I hope one of the above works instead of the default constructor. Maybe only root can create the empty one (though have to say I'm dubious)....
Now that I think I understand what your code is intending to do, I believe you always intended
QCamera(QCameraInfo.defaultCamera())
. Don't forget the docs admonition:QCameraInfo QCameraInfo::defaultCamera()
Returns the default camera on the system.
The returned object should be checked using isNull() before being used, in case there is no default camera or no cameras at all.
See also availableCameras(). -
-
@Xenoshell
Then at this point I'm afraid I'm stumped.QCamera(QCameraInfo.defaultCamera())
should definitely not hang. I don't know what is going on in the Qt code which will cause something to do so unless run as root. (I just wonder whether something might be prompting for, say, root password to allow access, and that's why it hangs/goes black....)You need one of the experts who knows what the Qt code does to get you anywhere now, I think....
-
You can't without lots of chocolate...
Minimal PyQt5 example that shows a viewfinder using the default camera:
import sys from PyQt5.QtWidgets import QApplication from PyQt5.QtMultimedia import QCamera, QCameraInfo from PyQt5.QtMultimediaWidgets import QCameraViewfinder if __name__ == '__main__': app = QApplication(sys.argv) camera = QCamera(QCameraInfo.defaultCamera()); viewfinder = QCameraViewfinder() viewfinder.show() camera.setViewfinder(viewfinder); camera.start() sys.exit(app.exec_())
Does it work for you ?
-
@SGaist
Nope doesnt work. Its the same thing. Without sudo it doesnt do anything and with sudo it just locks up and i have to login again. I cant find a reason why the raspberry pi just locks up. For me thats the strangest thing to happen. I had my code once on Raspbian but now i am on Ubuntu Mate since i always got a segmentation fault on Raspbian. -
@SGaist
We have established that for the OPQCamera(QCameraInfo.defaultCamera())
--- or indeedQCamera(
anything-at-all-or-nothing)
--- hangs unless he runs it viasudo
. (The only thing I don't think he has clarified is whetherQCamera("nosuchcamera".decode())
succeeds returning an invalid camera object or also hangs --- but I suspect the latter.)What would be nice to know from an expert is: from the Qt source code, what does just a minimal
QCamera()
constructor actually do? It seems to invoke something in the OS/multimedia --- perhaps something which requires a permission --- but what??