I'm working on a video capture script for Python in Raspbian (Raspberry Pi 2) and I'm having trouble using the Python bindings for v4l2, since I have no success on memory-maping the buffers.
What I need:
What I've tried:
What I've read:
My questions:
Here is my (slowly) working example with OpenCV:
import cv2
import time
video = cv2.VideoCapture(0)
print 'Starting video-capture test...'
t0 = time.time()
for i in xrange(100):
success, image = video.read()
ret, jpeg = cv2.imencode('.jpg',image)
t1 = time.time()
t = ( t1 - t0 ) / 100.0
fps = 1.0 / t
print 'Test finished. ' + str(t) + ' sec. per img.'
print str( fps ) + ' fps reached'
video.release()
And here what I've done with v4l2:
FRAME_COUNT = 5
import v4l2
import fcntl
import mmap
def xioctl( fd, request, arg):
r = 0
cond = True
while cond == True:
r = fcntl.ioctl(fd, request, arg)
cond = r == -1
#cond = cond and errno == 4
return r
class buffer_struct:
start = 0
length = 0
# Open camera driver
fd = open('/dev/video1','r+b')
BUFTYPE = v4l2.V4L2_BUF_TYPE_VIDEO_CAPTURE
MEMTYPE = v4l2.V4L2_MEMORY_MMAP
# Set format
fmt = v4l2.v4l2_format()
fmt.type = BUFTYPE
fmt.fmt.pix.width = 640
fmt.fmt.pix.height = 480
fmt.fmt.pix.pixelformat = v4l2.V4L2_PIX_FMT_MJPEG
fmt.fmt.pix.field = v4l2.V4L2_FIELD_NONE # progressive
xioctl(fd, v4l2.VIDIOC_S_FMT, fmt)
buffer_size = fmt.fmt.pix.sizeimage
print "buffer_size = " + str(buffer_size)
# Request buffers
req = v4l2.v4l2_requestbuffers()
req.count = 4
req.type = BUFTYPE
req.memory = MEMTYPE
xioctl(fd, v4l2.VIDIOC_REQBUFS, req)
if req.count < 2:
print "req.count < 2"
quit()
n_buffers = req.count
buffers = list()
for i in range(req.count):
buffers.append( buffer_struct() )
# Initialize buffers. What should I do here? This doesn't work at all.
# I've tried with USRPTR (pointers) but I know no way for that in Python.
for i in range(n_buffers):
buf = v4l2.v4l2_buffer()
buf.type = BUFTYPE
buf.memory = MEMTYPE
buf.index = i
xioctl(fd, v4l2.VIDIOC_QUERYBUF, buf)
buffers[i].length = buf.length
buffers[i].start = mmap.mmap(fd.fileno(), buf.length,
flags = mmap.PROT_READ,# | mmap.PROT_WRITE,
prot = mmap.MAP_SHARED,
offset = buf.m.offset )
I will appreciate any help or advice. Thanks a lot!
I found for myself the answer as part of the code in another question. It was not the main topic of the question, but in this source code you can see how he uses the mmap in Python (line 159). Furthermore I found that I didn't need the write permissions.