2016-04-05 8 views
2

Ich arbeite an einem Video Capture-Skript für Python in Raspbian (Raspberry Pi 2) und ich habe Probleme mit der Python-Bindungen für v4l2, da ich keinen Erfolg auf Speicher- maping die Puffer.v4l2 Python - Streaming-Video - Mapping-Puffer

Was ich brauche:

  • Capture-Video von einem HD-Webcam (wird später zwei von ihnen zugleich sein).
  • Sie können das Video über WLAN streamen (Kompromiss zwischen Netzwerklast und Verarbeitungsgeschwindigkeit).
  • In der Zukunft können Filter auf das Bild vor dem Streaming angewendet werden (nicht obligatorisch).

Was ich versucht habe:

  • Verwenden OpenCV (cv2). Es ist sehr einfach zu bedienen, aber es fügt eine Menge Verarbeitungslast hinzu, da es die JPEG-Frames der Webcam in unformatierte Bilder umwandelt, und dann musste ich sie zurück in JPEG konvertieren, bevor sie über WLAN gesendet wurden.
  • Lesen Sie direkt von '/ dev/video0'. Es wäre toll, da die Webcam die Frames bereits komprimiert sendet und ich sie einfach lesen und senden kann, aber es scheint, dass meine Kamera das nicht unterstützt.
  • Verwenden Sie v4l2-Bindungen für Python. Dies ist jetzt die vielversprechendste Option, aber ich blieb stecken, als ich die Videopuffer zuordnen musste. Ich habe keine Möglichkeit gefunden, die "Memory Pointer/Mappings", die dieses Zeug zu benötigen scheint, zu überwinden.

Was ich gelesen habe:

Meine Fragen:

  1. Gibt es einen besseren Weg, dies zu tun? oder wenn nicht ...
  2. Könnte ich OpenCV sagen, das Bild nicht zu dekomprimieren? Es wäre schön, OpenCV zu verwenden, um zukünftige Erweiterungen anwenden zu können. Ich habe here gefunden, dass es nicht erlaubt ist.
  3. Wie konnte ich den Mapping-Schritt in Python auflösen? (? Any Arbeitsbeispiel)

Hier ist mein (langsam) Arbeitsbeispiel mit 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() 

Und hier, was ich mit v4l2 gemacht habe:

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) 

Ich werde schätzen jede Hilfe oder Beratung. Danke vielmals!

Antwort

-1

Ich fand für mich die Antwort als Teil des Codes in another question.Es war nicht das Hauptthema der Frage, aber in diesem source code können Sie sehen, wie er die mmap in Python verwendet (Zeile 159). Außerdem habe ich festgestellt, dass ich die Schreibrechte nicht benötigt habe.