Hi,
I was not able to get it to work with the “tiscamera”, could it be that it is only for USB and Ethernet cameras (I forgot to say that I use a MIPI CSI2 camera with serialiser and deserialiser)
Nevertheless I found two other solutions
first solution directly in the terminal
v4l2-ctl -d /dev/video0 --set-ctrl=bypass_mode=0, --set-fmt-video=width=3856,height=2176,pixelformat=RG12 --stream-mmap --stream-to=- | gst-launch-1.0 filesrc location=/dev/stdin blocksize=$(expr 3872 * 2176 * 2) ! ‘video/x-raw,format=GRAY16_LE,width=3872,height=2176,framerate=30/1’ ! queue ! videoconvert ! xvimagesink
second solution with Python
(Python v4l2 webcam capture test using PlayStation 3 camera. More advanced script can be found here: https://github.com/eik-robo/zoidberg/blob/master/examples/purepy_video_capture.py · GitHub)
#!/usr/bin/env python3
from v4l2 import * # v4l2-python3
import fcntl
import mmap
import select
import time
import struct
import os
import cv2
import numpy as np
os.system('v4l2-ctl --device /dev/video0 --set-ctrl preferred_stride=7744')
vd = os.open('/dev/video0', os.O_RDWR, 0)
print(">> get device capabilities")
cp = v4l2_capability()
fcntl.ioctl(vd, VIDIOC_QUERYCAP, cp)
print("Driver:", "".join((chr(c) for c in cp.driver)))
print("Name:", "".join((chr(c) for c in cp.card)))
print("Is a video capture device?", bool(cp.capabilities & V4L2_CAP_VIDEO_CAPTURE))
print("Supports read() call?", bool(cp.capabilities & V4L2_CAP_READWRITE))
print("Supports streaming?", bool(cp.capabilities & V4L2_CAP_STREAMING))
print(">> device setup")
fmt = v4l2_format()
fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE
fcntl.ioctl(vd, VIDIOC_G_FMT, fmt) # get current settings
print("width:", fmt.fmt.pix.width, "height", fmt.fmt.pix.height)
print("pxfmt:", "V4L2_PIX_FMT_YUYV" if fmt.fmt.pix.pixelformat == V4L2_PIX_FMT_YUYV else fmt.fmt.pix.pixelformat)
print("bytesperline:", fmt.fmt.pix.bytesperline)
print("sizeimage:", fmt.fmt.pix.sizeimage)
fcntl.ioctl(vd, VIDIOC_S_FMT, fmt) # set whatever default settings we got before
print(">> init mmap capture")
req = v4l2_requestbuffers()
req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE
req.memory = V4L2_MEMORY_MMAP
req.count = 1 # nr of buffer frames
fcntl.ioctl(vd, VIDIOC_REQBUFS, req) # tell the driver that we want some buffers
print("req.count", req.count)
buffers = []
print(">>> VIDIOC_QUERYBUF, mmap, VIDIOC_QBUF")
for ind in range(req.count):
# setup a buffer
buf = v4l2_buffer()
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE
buf.memory = V4L2_MEMORY_MMAP
buf.index = ind
fcntl.ioctl(vd, VIDIOC_QUERYBUF, buf)
buf.buffer = mmap.mmap(vd, buf.length, mmap.MAP_SHARED, mmap.PROT_READ | mmap.PROT_WRITE, offset=buf.m.offset)
print("no {} buf {}",ind,repr(buf))
buffers.append(buf)
# queue the buffer for capture
fcntl.ioctl(vd, VIDIOC_QBUF, buf)
print(">> Start streaming")
buf_type = v4l2_buf_type(V4L2_BUF_TYPE_VIDEO_CAPTURE)
fcntl.ioctl(vd, VIDIOC_STREAMON, struct.pack('I', V4L2_BUF_TYPE_VIDEO_CAPTURE))#buf_type)
print(">> Capture image")
t0 = time.time()
max_t = 1
ready_to_read, ready_to_write, in_error = ([], [], [])
print(">>> select")
while len(ready_to_read) == 0 and time.time() - t0 < max_t:
ready_to_read, ready_to_write, in_error = select.select([vd], [], [], max_t)
print(">>> download buffers")
for _ in range(1000):
buf = buffers[_ % req.count]
fcntl.ioctl(vd, VIDIOC_DQBUF, buf) # get image from the driver queue
mm = buffers[buf.index].buffer
cv2.imshow('frame', np.reshape(np.frombuffer(mm, dtype=np.uint16, count=3872*2176), (2176,3872)))
cv2.waitKey(1)
fcntl.ioctl(vd, VIDIOC_QBUF, buf) # requeue the buffer
print(">> Stop streaming")
fcntl.ioctl(vd, VIDIOC_STREAMOFF, buf_type)
vd.close()
The only problem is that I can’t get the full 30fps with my camera.
Do you know anything I could improve?