RuntimeError: Unable to locate turbojpeg library automatically

What package and version are you using?

Please, describe the issues you are seeing?

Important note: this is not an issue when running the apps on the Amiga or on a Linux computer.
This is only relevant if you choose to develop by running the apps locally on a Windows or Mac computer.

When running the camera-streamer or virtual-joystick examples locally on a Windows (using WSL) or Mac computer, you may see an error:

 Traceback (most recent call last):
...
 RuntimeError: Unable to locate turbojpeg library automatically. You may specify the turbojpeg library path manually.
WARNING:kivy:stderr: RuntimeError: Unable to locate turbojpeg library automatically. You may specify the turbojpeg library path manually.
 e.g. jpeg = TurboJPEG(lib_path)
WARNING:kivy:stderr: e.g. jpeg = TurboJPEG(lib_path)
  • See bottom of post for full Traceback

It seems that the auto-discovery of the install path for pip install PyTurboJPEG is not reliable on a WSL or Mac OS. You have two options:

1. Follow instructions for alternative install methods for your local machine, detailed in their github readme and in the following issue:

This is resolved on WSL with:

sudo apt-get update -y
sudo apt-get install -y libturbojpeg

This is resolved on Mac with:

brew install jpeg-turbo

This is the preferred approach (see below), but does require a system level install which you may want to avoid (it’s usually nice to minimize system level installs).

2. Switch to opencv image decoding.

The advantage here is that the pip install opencv-python works for all OS, but the downside is that the image decoding is 1.5 -2x slower than PyTurboJpeg (see below).

You can see how this is done in this example pull request: Demonstrate OpenCV image decoding (remove PyTurboJpeg dependency) by Hackerman342 · Pull Request #7 · farm-ng/camera-streamer · GitHub

The key line in Python is:

img = cv2.imdecode(
    np.frombuffer(getattr(frame, view_name).image_data, dtype=np.uint8),
    cv2.IMREAD_UNCHANGED,
)

For reference

Decoding speed comparison

I compared the decoding time (only the 1-2 lines for decoding, nothing else) using opencv & numpy to PyTurboJpeg on the brain. What I saw was:

  • RGB:
    • Shape: (1080, 1920, 3)
    • PyTurboJpeg: 28.5 ms
    • OpenCV: 46.0 ms
  • greyscale):
    • Shape: (400, 640, 3
    • PyTurboJpeg: 4.1 ms
    • OpenCV: 5.8 ms

This shows there’s a notable benefit to using PyTurboJpeg for decoding, especially for RGB images.

Full Traceback:

 Traceback (most recent call last):
WARNING:kivy:stderr: Traceback (most recent call last):
   File "/home/kcoble/camera-streamer/src/main.py", line 156, in <module>
WARNING:kivy:stderr:   File "/home/kcoble/camera-streamer/src/main.py", line 156, in <module>
     CameraApp(args.address, args.port, args.stream_every_n).app_func()
WARNING:kivy:stderr:     CameraApp(args.address, args.port, args.stream_every_n).app_func()
   File "/home/kcoble/camera-streamer/src/main.py", line 50, in __init__
WARNING:kivy:stderr:   File "/home/kcoble/camera-streamer/src/main.py", line 50, in __init__
     self.image_decoder = TurboJPEG()
WARNING:kivy:stderr:     self.image_decoder = TurboJPEG()
   File "/home/kcoble/camera-streamer/venv/lib/python3.8/site-packages/turbojpeg.py", line 298, in __init__
WARNING:kivy:stderr:   File "/home/kcoble/camera-streamer/venv/lib/python3.8/site-packages/turbojpeg.py", line 298, in __init__
     self.__find_turbojpeg() if lib_path is None else lib_path)
WARNING:kivy:stderr:     self.__find_turbojpeg() if lib_path is None else lib_path)
   File "/home/kcoble/camera-streamer/venv/lib/python3.8/site-packages/turbojpeg.py", line 926, in __find_turbojpeg
WARNING:kivy:stderr:   File "/home/kcoble/camera-streamer/venv/lib/python3.8/site-packages/turbojpeg.py", line 926, in __find_turbojpeg
     raise RuntimeError(
WARNING:kivy:stderr:     raise RuntimeError(
 RuntimeError: Unable to locate turbojpeg library automatically. You may specify the turbojpeg library path manually.
WARNING:kivy:stderr: RuntimeError: Unable to locate turbojpeg library automatically. You may specify the turbojpeg library path manually.
 e.g. jpeg = TurboJPEG(lib_path)
WARNING:kivy:stderr: e.g. jpeg = TurboJPEG(lib_path)