Additional Information←
Below is more information about the Python DispmanX library, including
what's supported, how to install the necessary requirements (bcm_host.so
), and some
acknowledgements.
Python, OS and Device Version Support←
- OS Support:
- The latest versions of 32- and 64- bit Raspberry Pi OS are supported. As of the time of this writing, that's based on Debian Bullseye (11.x).
- Python Version
- The minimum version of Python supported is 3.9. That's the default version installed on the latest Raspberry Pi OS (Bullseye).
- Raspberry Pi Versions
-
This library should work on any version of the Pi, but I've specifically tested,
- Raspberry Pi 4 B
- Raspberry Pi 3 B+
- Raspberry Pi 3 B
- Raspberry Pi 2
- Raspberry Pi B
If you're using an older version of Python, Raspberry Pi OS, and/or a different OS entirely, you can always use Docker on your Pi. See the section on Docker and Compose below.
Fixing No displays found!
Exception←
If you have display(s) hooked up to your Raspberry Pi, but you run into an error that looks something like this,
>>> from dispmanx import DispmanX
>>> display = DispmanX()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/david/python-dispmanx/dispmanx/dispmanx.py", line 205, in __init__
self._display = self.get_default_display()
File "/home/david/python-dispmanx/dispmanx/dispmanx.py", line 421, in get_default_display
raise DispmanXRuntimeError("No displays found! (Are you using the vc4-kms-v3d driver?)")
dispmanx.exceptions.DispmanXRuntimeError: No displays found! (Are you using the vc4-kms-v3d driver?)
Then your Pi may be running in so-called "Full KMS" video mode. In order for
your Pi to run its video layer on top of DispmanX, you'll need to change a
configuration value in /boot/config.txt
to switch to "Fake FMS" mode. (Don't
let the word "fake" scare you.)
# Enable DRM VC4 V3D driver
dtoverlay=vc4-kms-v3d <- change to: dtoverlay=vc4-fkms-v3d
max_framebuffers=2
Afterwards, reboot. Alternatively, you can follow these commands to perform the operation manually,
# Modify the video driver: vc4-kms-v3d -> vc4-fkms-v3d
sudo sed -i 's/^dtoverlay=vc4-kms-v3d/dtoverlay=vc4-fkms-v3d/' /boot/config.txt
sudo reboot # Reboot your Pi
ctypes and bcm_host.so
←
While Python DispmanX is written completely in Python, it uses Python's included
ctypes library to perform "foreign function calls" to bcm_host.so
. In
short, it calls the C library included with Raspberry Pi OS to interface with
the DispmanX layer directly.
The library bcm_host.so
is available through the libraspberrypi0
Debian
package, which should have come installed on your Pi if you used Raspberry Pi
OS. If that's not available, you can always use Docker following the
instructions in the Docker and Compose section below.
Docker and Compose←
Both Docker and Docker Compose work great. They're actually how I run the library. Details below.
Using Docker←
If the version of Raspberry Pi OS that you're using isn't supported by this library or you're using a different operating system altogether, you can always use Docker. Docker is supported on both 32- and 64-bit architectures.
The base container for Debian Bullseye doesn't by default contain the necessary
libraspberrypi0
package as described above. So, you'll need to either add the
"Raspbian Repository", or use my
minimal Raspberry Pi OS base containers. Three variants
that will work are provided.
The device /dev/vchiq
needs to be exposed to container. For the Debian image,
you'll need to install pip yourself. Three images are listed in the table below.
Description | Image Name |
---|---|
Python 3.9 | dtcooper/raspberrypi-os:python3.9 |
Python 3.10 | dtcooper/raspberrypi-os:python3.10 |
Debian (Bullseye) | dtcooper/raspberrypi-os:bullseye |
For example to use the Python 3.9 container with a script called test.py
in
your current directory run this at the command line,
docker run -it \
-v "./test.py:/test.py" \
--device /dev/vchiq:/dev/vchiq \
dtcooper/raspberrypi-os:python3.9 \
bash
# Now in the container
pip install dispmanx[numpy]
python /test.py
Using Compose←
Using Docker Compose also works great. You'll need to similarly
expose the /dev/vchiq
device, however. Here's a sample docker-compose.yml
file,
services:
dispmanx:
#image: <Your image based on dtcooper/raspberrypi-os:python3.9>
devices:
- /dev/vchiq:/dev/vchiq
Acknowledgements←
Several projects were used as reference in the development of Python DispmanX. Some of the main ones are described below.
PyDispmanx←
First and foremost, let me acknowledge the great work Tim Clark put into PyDispmanx.
PyDispmanx is another Python library available that functions somewhat similarly. Honestly, it's great and I would recommend it! I owe a debt of gratitude to its author, for two reasons,
- First and foremost, showing me that interfacing with the Pi's DispmanX API via Python is possible; and
- Being available to peep into its source code.
While it's perhaps the best alternative to this project, some reasons I've chosen to re-write from scratch are:
- To provide a ctypes pure Python interface;
- To provide a more complete interface to DispmanX;
- To provide documentation on how to use the thing with popular Python graphics libraries;
- To publish regular, stable, and tested releases to PyPI;
- PyDispmanx appears to be an unstable work in progress. For example, by its own author's admission in the project README, he says "[he] probably wouldn't install this system wide yet"; and
- Writing code is fun!
raspidmx←
The Broadcom hardware interface library which provides the DispmanX APIs is very poorly documented. One of the first usable set of open source C programming language example programs were by a developer named Andrew Duncan. He calls the suite raspidmx. Andrew provided a set of "programs [that could] be used as a starting point for anyone wanting to make use of DispmanX."
Some of the common code from raspidmx is the underlying code that drives PyDispmanx. I owe a debt of gratitude to its author, since peeping into raspidmx's source tree is what helped figure out how to call the DispmanX APIs from Python.
picamera←
The picamera Python library interfaces with the
Pi's Camera Module. Its source code contains several parts
that interface with the Pi's APIs including the DispmanX layer contained in the
bcm_host.so
shared library. In particular picamera's source file
bcm_host.py
was used as inspiration for how to interact with
DispmanX via ctypes.
Project Roadmap←
- Publish package to PyPI
- Add API docs using MkDocs, Material for MkDocs, mkdocstrings
- Call destroy functions in bcm_host.h
- Support additional pixel types
- Allow multiple layers, and different displays
- Support custom dimensions and offsets – API supports it, but requires weird multiples of 16 or 32, as documented here. This requires testing, because anecdotally it seems to work with smaller multiples.
- Tests run over SSH onto my home pi — GitHub actions won't work, since they don't support DispmanX APIs