Fix V4L2 mmap capture and service configuration
- capture.py: use mmap.mmap instead of non-existent os.mmap - capture.py: fix v4l2_fourcc() to pass 4 char arguments - camera-webui.service: add Group=video and PATH env var
This commit is contained in:
@@ -6,8 +6,9 @@ Wants=network-online.target
|
||||
[Service]
|
||||
Type=exec
|
||||
User=mikkeli
|
||||
Group=video
|
||||
WorkingDirectory=/home/mikkeli/dev/usb-camera-webui
|
||||
ExecStartPre=/usr/bin/python3 -c "import v4l2"
|
||||
Environment=PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
|
||||
ExecStart=/usr/bin/python3 -m camera.app --host 0.0.0.0 --port 8080
|
||||
Restart=on-failure
|
||||
RestartSec=5
|
||||
|
||||
+10
-6
@@ -1,16 +1,20 @@
|
||||
"""V4L2 MJPEG capture via the v4l2 Python library (mmap).
|
||||
"""V4L2 MJPEG capture via mmap buffers.
|
||||
|
||||
Uses memory-mapped buffers for efficient frame capture without subprocess
|
||||
overhead. Each frame is a complete JPEG image ready for MJPEG streaming.
|
||||
Opens /dev/video0 and uses memory-mapped V4L2 buffers for efficient frame
|
||||
capture. Each frame is a complete JPEG image ready for MJPEG streaming.
|
||||
"""
|
||||
|
||||
import fcntl
|
||||
import os
|
||||
import time
|
||||
import threading
|
||||
import mmap
|
||||
|
||||
import v4l2
|
||||
|
||||
# Fourcc for Motion JPEG
|
||||
MJPG = v4l2.v4l2_fourcc("M", "J", "P", "G")
|
||||
|
||||
# Global camera singleton
|
||||
_camera: "Capture | None" = None
|
||||
_camera_lock = threading.Lock()
|
||||
@@ -79,10 +83,10 @@ class Capture:
|
||||
fmt.type = v4l2.V4L2_BUF_TYPE_VIDEO_CAPTURE
|
||||
fmt.fmt.pix.width = self._width
|
||||
fmt.fmt.pix.height = self._height
|
||||
fmt.fmt.pix.pixelformat = v4l2.v4l2_fourcc("MJPG")
|
||||
fmt.fmt.pix.pixelformat = MJPG
|
||||
fmt.fmt.pix.field = v4l2.V4L2_FIELD_ANY
|
||||
_ioctl(self._fd, v4l2.VIDIOC_S_FMT, fmt)
|
||||
print(f"Format set: {fmt.fmt.pix.width}x{fmt.fmt.pix.height} {v4l2.v4l2_fourcc2str(fmt.fmt.pix.pixelformat)}")
|
||||
print(f"Format: {fmt.fmt.pix.width}x{fmt.fmt.pix.height} {v4l2.v4l2_fourcc2str(fmt.fmt.pix.pixelformat)}")
|
||||
|
||||
def _allocate_buffers(self) -> None:
|
||||
req = v4l2.v4l2_requestbuffers()
|
||||
@@ -101,7 +105,7 @@ class Capture:
|
||||
|
||||
length = buf.length
|
||||
offset = buf.m.offset
|
||||
data = os.mmap(0, length, os.PROT_READ, os.MAP_SHARED, self._fd, offset)
|
||||
data = mmap.mmap(self._fd, length, mmap.MAP_SHARED, mmap.PROT_READ, 0, offset)
|
||||
self._buffers.append({
|
||||
"index": i,
|
||||
"length": length,
|
||||
|
||||
Reference in New Issue
Block a user